// NA30 Newton Raphson method
// to solve non-lineer system of equation

import java.util.*;
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
import javax.swing.*;
//============= Tanımı gereken fonksiyon ================


class fa extends fi_xi
{
public double[] func(double x[])
{
//system of non-lineer equation	
double ff[]=new double[3];
ff[0]=10.0*x[0]-2.0*x[1]*x[1]+x[1]-2.0*x[2]-5;
ff[1]=8.0*x[1]*x[1]+4.0*x[2]*x[2]-9.0;
ff[1]=8.0*x[1]*x[2]+4.0;
return ff;
} 
}


public class NA30
{
// Roots of system of non-lineer equations
// By using Newton-Raphson Method


public static double[] newtond( fi_xi f,double x[])
{
//x vector of independent variables
//y vector of dependent variable
//dy derivative of vector of dependent variable
// derivative vector calculated by numerical derivatives
double ti=1.0;
int i,ii,jj;
int nmax=500;
double tolerance=1.0e-15;
int n=x.length;
double b[];
b=new double[n];
double dy[][];
dy=new double[n][n];
i=0;
for(i=0;i<n;i++)
{
b[i]=1.0;
}
while( i++ < nmax && Matrix.abs(b) > tolerance )
{
  for(ii=0;ii<n;ii++)
  {
    for(jj=0;jj<n;jj++)
    {
        dy[ii][jj]=derivative(f,x,ii,jj);
        
    }
  }
    b=Matrix.multiply(Matrix.divide(f.func(x),dy),-ti);

    System.out.println("turev:"+Matrix.toString(dy));
    System.out.println("fonksyon:"+Matrix.toString(f.func(x)));
    System.out.println(Matrix.toString(x));
    x=Matrix.add(x,b);
}
if(i >= nmax) JOptionPane.showMessageDialog(null,"Maximum number of iterations are exceeded \n"+
              " Results might not be valid","MAXIMUM NUMBER OF ITERATIONS ERROR",JOptionPane.WARNING_MESSAGE);
return x;
}

public static double derivative(fi_xi f,double x[],int denklem_ref,int x_ref)
{
double h0=0.0256;
int i,m;
int n=7;
double f1[];
f1=new double[x.length];
double f2[];
f2=new double[x.length];
double x1[];
x1=new double[x.length];
double x2[];
x2=new double[x.length];
for(i=0;i<x.length;i++)
{
x1[i]=x[i];
x2[i]=x[i];
}
//derivative of a simple function
double T[][];
T=new double[n][n];
double h[];
h=new double[n];
//vector<double> h(n,0);
for(i=0;i<n;i++)
{
  h[i]=0;
  for(int j=0;j<n;j++)
    T[i][j]=0;
}
h[0]=h0;
double r=0.5;
for( i=1;i<n;i++)
{
h[i]=h0*Math.pow(r,i);
}

for(i=0;i<n;i++)
{
x1[x_ref]+=h[i];
x2[x_ref]-=h[i];
f1=f.func(x1);
f2=f.func(x2);
T[i][0]=( f1[denklem_ref] - f2[denklem_ref])/(2.0*h[i]);
x1[x_ref]=x[x_ref];
x2[x_ref]=x[x_ref];
}
for(m=1;m<n;m++)
{
  for(i=0;i<n-m;i++)
  {
  T[i][m]=(h[i]*h[i]*T[i+1][m-1] - h[i+m]*h[i+m]*T[i][m-1])/(h[i]*h[i]
  - h[i+m]*h[i+m]);
  }
}
double xx=T[0][n-1];
return xx;
}

public static double[] verigir()
{
    String s=JOptionPane.showInputDialog("ENTER FIRST ROOT ESTIMATES WİTH ONE EMPTY SPPACE IN BETWEEN: ");        
    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();
     double [] x0=verigir();
     String s2="Newton raphson method withy the numerically calculated derivatives : ";
     double [] r1= newtond(f,x0);
     String s=" Root values  : \n"+Matrix.toStringT(r1)+"\n";
     s+="function values = "+Matrix.toStringT(f.func(r1));
     String s1="Finding roots of the multivariable non-lineer system of equations : ";
     JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE);
     System.exit(0);
     } 
}
