class ff extends f_x
{
public double func(double x)
{  double y=0;
   if(x>=0 && x<=1) y=1.0;
	return y;}
}

public class legendre1
{   
public double alfa,beta,xl,xh;
public double x[];
public double z[];
public double y[];
public double b[]; //katsayılar matrisi;
public int m;   //eğri uydurma derecesi

public static double P(int k, double x)
{
 // Legendre polinomu  -1<=x<=1
if(k==0) return 1.0;
else if(k==1) return x;
else
{return ((2.0*k-1.0)*P((k-1),x)*x-P((k-2),x)*(double)(k-1))/(double)k;}
// end legendre polynomials
}

public  double q(int k, double z)
{  // dönüştürülmüş Legendre polinomu xl<= z <=xh
	double x=(z-beta)/alfa;
   return P(k,x);
}
public  double fak(f_x f,int k,double z)
    {   //integral fonksiyonu
	    double a=(2.0*k+1)/(xh-xl)*f.func(z)*q(k,z);
	    return a;
	}

public legendre1(f_x f,double xli,double xhi,int mi)
{setdata(f,xli,xhi,mi);}

public void setdata(f_x f,double xli,double xhi,int mi)
{  //z  xl, xh
      m=mi;
      xl=xli;
      xh=xhi;
      alfa=(xh-xl)/2.0;
      beta=(xh+xl)/2.0;
      b=new double[m+1];
      for(int j=0;j<=m;j++)
	  {b[j]=integral(f,xl,xh,30,j);}   
	  System.out.println("b=\n"+Matrix.toStringT(b));         
}
	  
public  double funcLegendre(double z)
{
    double x=(z-beta)/alfa;
    double ff=0;
    double pk=0;
    for(int j=0;j<=m;j++)
       {   pk=P(j,x);
	       ff+=b[j]*pk;
	   } 
    return ff;
}

public static double[][] Gauss_Legendre_Coefficients(double x1,double x2,int n)
{
	// calculates Gauss-Legendre coefficients
	double EPS=3.0e-15;
	int m,j,i;
	double z1,z,xm,xl,pp,p3,p2,p1;
    double a[][]=new double[2][n];//a[0][i]=x[i]   a[1][i]=w[i]
	m=(n+1)/2;
	xm=0.5*(x2+x1);
	xl=0.5*(x2-x1);
	for (i=1;i<=m;i++)  {
		z=Math.cos(Math.PI*((i-0.25)/(n+0.5)));
		do {
			p1=1.0;
			p2=0.0;
			for (j=1;j<=n;j++) {
				p3=p2;
				p2=p1;
				p1=((2.0*j-1.0)*z*p2-(j-1.0)*p3)/j;
			}
			pp=n*(z*p1-p2)/(z*z-1.0);
			z1=z;
			z=z1-p1/pp;
		} while (Math.abs(z-z1) > EPS);
		a[0][i-1]=xm-xl*z;
		a[0][n-i]=xm+xl*z;
		a[1][i-1]=2.0*xl/((1.0-z*z)*pp*pp);
		a[1][n-i]=a[1][i-1];
			}
return a;
}

public  double integral(f_x f,double xl,double xh,int n,int k)
{
// n : integral degree of polynomial
// This program calculates Gauss-Legendre coefficients in  [x1,x2] band
// and then calculates the integral in this band.
double a[][]=new double[2][n];
a=Gauss_Legendre_Coefficients(xl,xh,n);
//System.out.println("katsayılar matrisi : \n"+Matrix.toStringT(a));
double z=0;
for(int i=0;i<n;i++)
{ z+=a[1][i]*fak(f,k,a[0][i]);}
return z;
}

  public static void main(String args[]) 
  { 
   ff f=new ff();
   int n=200;//veri sayısı
   legendre1 l=new legendre1(f,-1.0,2.0,40);
   double z1[]=new double[n+1];
   double y[]=new double[n+1];
   double y1[]=new double[n+1];
   for(int i=0;i<=n;i++)
   {  z1[i]=l.xl+(l.xh-l.xl)/(double)n*i;
      y[i]=f.func(z1[i]);
      y1[i]=l.funcLegendre(z1[i]);
   }
   Plot p1=new Plot(z1,y1);
   p1.addData(z1,y);
   p1.plot();
  }
}
