//======================================================
// Numerical Analysis package in java
// example to show utilisation of integration (integral)
// and differentiation (derivative) functions
//Derivative formulas
// Dr. Turhan Coban
// =====================================================
import java.io.*;

class f1 extends f_x
{ double func(double x)
  {return Math.log(1.0+x*x)/Math.sqrt(1-x*x);}
}

class NA81D
{	
public static double derivative(f_x f,double x)
{
double h0=0.001;
int i,m;
int n=7;
double T[][]=new double[n][n];
double h[];
h=new double[n];
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++)  {T[i][0]=dfdx(f,x,h[i]);}
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 dfdx_richardson(f_x f,double x)
{
double h0=0.01;
double h=h0;
int i,m;
int n=10;
double T[][]=new double[n][n];
for(i=0;i<n;i++)  {T[i][0]=dfdx(f,x,h);h/=2.0;}
for(m=1;m<n;m++)
{ for(i=0;i<n-m;i++)
  {T[i][m]=(4.0/3.0*T[i+1][m-1]-1.0/3.0*T[i][m-1]);}
}
double xx=T[0][n-1];
return xx;
}


public static double dfdx(f_x f,double x)
{ double h=0.00001;
  return dfdx(f,x,h);
}
	
public static double dfdx(f_x f,double x,double h)
{ double hh=1.0/h; 
  return (-f.func(x+2.0*h)+8.0*f.func(x+h)-8.0*f.func(x-h)+f.func(x-2.0*h))/12.0*hh;
}

public static double d2fdx2(f_x f,double x)
{ double h=0.00001;
  return d2fdx2(f,x,h);
}

public static double d2fdx2(f_x f,double x,double h)
{
  double hh=1.0/h; 
	return (-f.func(x+2.0*h)+16.0*f.func(x+h)-30.0*f.func(x)+16.0*f.func(x-h)-f.func(x-2.0*h))/(12.0)*hh*hh;}

public static double d3fdx3(f_x f,double x)
{ double h=0.00001;
  return d3fdx3(f,x,h);}

public static double d3fdx3(f_x f,double x,double h)
{  double hh=1.0/h;
	return (-f.func(x+3.0*h)+8.0*f.func(x+2.0*h)-13.0*f.func(x+h)+13.0*f.func(x-h)-8.0*f.func(x-2.0*h)+f.func(x-3.0*h))/(8.0)*hh*hh*hh;}

  public static void main(String args[]) 
  {
  f1 b1=new f1();
  double X[]=new double[181];
  double Y[]=new double[181];
  double YP[]=new double[181];
  double dh=0.001;
  double x=0;
  for(int i=0;i<181;i++)
  {   
	  X[i]=0.005*i;
	  Y[i]=b1.func(X[i]);
	  YP[i]=dfdx(b1,X[i],dh);
      System.out.println("i="+i+"x="+X[i]+" f(x)="+Y[i]+" f'(x)="+YP[i]);
  }
  Plot pp=new Plot(X,Y);
  pp.addData(X,YP);
  pp.plot(); 
  }
}
