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

class f1 extends f_x
{
  double func(double x)
  {return x*Math.sqrt(x);}
}


class integ14
{
public static double adaptive_boole_integral(f_x ff,double a,double b)
{return adaptive_boole_integral(ff,a,b,1.0e-15,2);}

public static double adaptive_boole_integral(f_x ff,double a,double b,double eps)
{return adaptive_boole_integral(ff,a,b,eps,2);}

public static double adaptive_boole_integral(f_x ff,double a,double b,int MAX_ITERATION)
{return adaptive_boole_integral(ff,a,b,1.0e-12,MAX_ITERATION);}

public static double adaptive_boole_integral(f_x ff,double a,double b,double eps,int MAX_ITERATION)
{   int i;
    double h=(b-a);
    double h3=h/8.0;
	double x[]=new double[9];
    double f[]=new double[9];
    for(i=0;i<9;i+=2) {x[i]=a+i*h3;f[i]=ff.func(x[i]);}
	double sum=h*(7.0*f[0]+32.0*f[2]+12.0*f[4]+32.0*f[6]+7.0*f[8])/90.0; 
	System.out.println("sum="+sum);
	double Q=sum;
    Q=boole(ff,x,f,sum,eps,0,MAX_ITERATION,Q);
    return Q;	
}
	
public static double boole(f_x ff,double x[],double f[],double sum,double eps,int k,int MAX_ITERATION,double Q)
{       //Newton-cotes integral 3 points
        //adaptive boole  rule
        double m = (x[8]+x[0])/2; 
        double h = (x[8]-x[0]);
        double h1= h/2.0;  
        double h3= h/8.0;    
        int p,i;
        double x1[]=new double[9];
        double f1[]=new double[9];
        double x2[]=new double[9];
        double f2[]=new double[9];
        k++;
        for(i=1;i<9;i+=2) {x[i]=x[0]+i*h3;f[i]=ff.func(x[i]); }
        double mll=x[2]; 
        double mrr=x[6]; 
        double i1=h*(7.0*f[0]+32.0*f[2]+12.0*f[4]+32.0*f[6]+7.0*f[8])/90.0;        
        double sum1=h1*(7.0*f[0]+32.0*f[1]+12.0*f[2]+32.0*f[3]+7.0*f[4])/90.0; 
        double sum2=h1*(7.0*f[4]+32.0*f[5]+12.0*f[6]+32.0*f[7]+7.0*f[8])/90.0; 
        double i2=sum1+sum2;
        //i1 = (16.0*i2 - i1)/15.0; 
        //System.out.println("h="+h+"h1="+h1+"i1="+i1+"i2="+i2+"is="+Q);
        double di=Math.abs(i1-i2);
        if (  ((Q + di) == Q) || (mll <= x[0]) || (x[8]<=mrr))
        {
        if (((m <= x[0]) || (x[8]<=m)))
        { System.out.println("istenilen toleransa ulaşılamadı delta i = "+di);}
        Q=i1;  
        }
        else
        {  
        x1[0]=x[0];f1[0]=f[0];
        x1[2]=x[1];f1[2]=f[1];
        x1[4]=x[2];f1[4]=f[2];
        x1[6]=x[3];f1[6]=f[3];
        x1[8]=x[4];f1[8]=f[4];
        
        x2[0]=x[4];f2[0]=f[4];
        x2[2]=x[5];f2[2]=f[5];
        x2[4]=x[6];f2[4]=f[6];
        x2[6]=x[7];f1[6]=f[7];
        x2[8]=x[8];f1[8]=f[8];      
        
        //if(1.0/127.0*Math.abs(sum1+sum2-sum)<eps || k>MAX_ITERATION) Q+=sum1+sum2;
        Q=boole(ff,x1,f1,sum1,eps,k,MAX_ITERATION,Q)+boole(ff,x2,f2,sum2,eps,k,MAX_ITERATION,Q);
        //System.out.println("Q="+Q+"h="+h+"h1="+h1+"sum="+(sum1+sum2)+"sum1="+sum1+"sum2="+sum2);
        }
        return Q;
}

  public static void main(String args[]) throws IOException
  {
  f1 b1=new f1();
  System.out.println("integral of class         f1 : "+adaptive_boole_integral(b1,0.0,1.0));
}
}
