// SCO5 Newton Raphson metoduyla
// birden fazla değişkenli denklem sisteminin köklerini bulmak

import java.util.*;
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
import javax.swing.*;
//============= Tanımı gereken fonksiyon ================
abstract class fi_xi
{
  // multifunction multi independent variable
  // vector of dependent variables are returned
  // example f[0]=x[0]+sin(x[1])
  //         f[1]=x[0]*x[0]-x[1]
  // func(x) returns the value of f[0] and f[1]
  // as a two dimensional vector

  abstract double[] func(double x[]);
}

abstract class fij_xi
{
  // multifunction multi independent variable
  // for n independent variable n*n matrix of
  // dependent variables are returned
  // example f[0][0]=x[0]+Math.sin(x[1])   f[0][1]=x[0]-x[1]
  //         f[1][0]=x[0]*x[0]-x[1]        f[1][1]=Math.exp(x[0]+x[1]*x[1]
  // func(x) returns the value of f[0][0], f[0][1]
  //                              f[1][0], f[1][1]
  // as a two dimensional matrix
  abstract double[][] func(double x[]);
}

class fa extends fi_xi
{
public double[] func(double x[])
{
//çözümü istenen fonksiyonun türev fonksiyonları	
//çözümü istenen fonksiyon	
double ff[]=new double[2];
ff[0]=x[0]*x[0]+x[0]*x[1]-10.0;
ff[1]=x[1]+3.0*x[0]*x[1]*x[1]-57.0;
return ff;
} 
}

class fb extends fij_xi
{
public double[][] func(double x[])
{
//çözümü istenen fonksiyonun türev fonksiyonları	
double a[][]=new double[2][2];
a[0][0]=2.0*x[0]+x[1];
a[0][1]=x[0];
a[1][0]=3.0*x[1]*x[1];
a[1][1]=1.0+6.0*x[0]*x[1];
return a;
} 
}

public class FSCO5
{
// Newton Raphson Metodunu kullanarak denklem sisteminin köklerini bulmak	
// Bu metod denklem sistemi çözümü için Matrix.java programını
// kullanmaktadır.



public static double[] newton(fi_xi f,fij_xi df,double x[])
{
// lineer olmıyan denklem siteminin kökleri
// fj(xi)=0 lineer olmıyan denklem sistemi için çözüm matrisi 
// türev matrisi dfj/dxi de tanımlanacaktır
// Newton-Raphson metodu ile lineer olmıyan denklem sistemi çözümü 
//ti :önem katsayısı
//x bağımsız değişken vektörü
//y bağımlı değişken vektörü
//dy bağımlı değişkenin türev fonksiyonları vektörü
double ti=1.0;
int i;
int nmax=400;
double tolerance=1.0e-20;
int n=x.length;
double b[];
b=new double[n];
for(i=0;i<n;i++)
{
b[i]=1.0;
}
i=0;
while( i++ < nmax && Matrix.abs(b) > tolerance )
{ b=Matrix.multiply(Matrix.divide(f.func(x),df.func(x)),-1.0); 
  x=Matrix.add(x,b);
}
if(i >= nmax) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+
              " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE);
System.out.println();
return x;
}

public static double[] verigir()
{
    String s=JOptionPane.showInputDialog("kök tahmin değerlerini arada bir boşluk bırakarak giriniz: ");        
    StringTokenizer token=new StringTokenizer(s);
    int n=token.countTokens()-1;
    int m=n+1;
    double a[]=new double[m];
    int j=0;           
    while(token.hasMoreTokens())
    {
    Double ax=new Double(token.nextToken());
    a[j++]=ax.doubleValue();
    }
    return a; 
}

     public static void main (String args[])  
     {
	 fa f =new fa();
     fb df=new fb();
     double [] x0=verigir();
     double [] r= newton(f,df,x0);
     String s=" kök değerleri  : \n"+Matrix.toStringT(r);
     String s1="çok değişkenli Newton-Raphson metodu ile kök bulma : ";
     JOptionPane.showMessageDialog(null,s,s1,JOptionPane.PLAIN_MESSAGE);
     System.exit(0);
     } 
}