import java.io.*;
//E.K:K: Chebyshev ortogonal polinomlari kullanarak eğri uydurma

class SCO11I
{   
	public static double fi(double x,int equation_ref)
	{	
	double T[]=new double[equation_ref+1];
	T[0]=1.0;
	if(equation_ref>=1) T[1]=x;	
	for(int i=2;i<=equation_ref;i++) {T[i]=2.0*x*T[i-1]-T[i-2];
    System.out.println("T["+i+"]="+T[i]);}
	return T[equation_ref];
	}	
	  
public static double[] EKKChebyshev(double xi[],double yi[],int n)
{
    int nn=xi.length;
	double xminimum=9.99e50;
    double xmaximum=-9.99e50;	
    double x1=0;      
	      for(int j=0;j<nn;j++)
          { if(xi[j]>xmaximum) xmaximum=xi[j];
            if(xi[j]<xminimum) xminimum=xi[j];
          } 
     if(xmaximum==xminimum) {System.out.println("wrong data setdefinition");}
     double x[]=new double[nn];
     // 0<=x<=1 arasinda değer dönüşümü uygula 
     for(int j=0;j<nn;j++)
     {x[j]=(2.0*xi[j]-xminimum-xmaximum)/(xmaximum-xminimum);
     System.out.println("x"+j+"]="+x[j]);}                
     int i=0,j,k=0;
     int np1=n+1;
     double C[]=new double[np1];
     double A,B;
     double fx=0;
     double wk=1.0;
	 for(j=0;j<nn;j++)
     {
	   if(j==0 && k==0) wk=1.0/nn;
       else             wk=2.0/nn;
	 A=0.0;B=0;    
     for(k=0;k<n;k++) 
      {fx=fi(x[k],j);A+=wk*yi[k]*fx;}
     C[j]=A; 
     System.out.println("A="+A+"C["+j+"]="+C[j]);   
     }
double max=0;
for(i=0;i<n+1;i++)
 if(Math.abs(C[i]) > max) max = Math.abs(C[i]);
for(i=0;i<n+1;i++)
 if((Math.abs(C[i]/max) > 0) && (Math.abs(C[i]/max) < 1.0e-100)) C[i]=0;
return C;
}

public static double funcEKKChebyshev(double E[],double xi[],double x)
{
    int nn=xi.length;
	double xminimum=9.99e50;
    double xmaximum=-9.99e50;	
    double x1=0;      
	      for(int j=0;j<nn;j++)
          { if(xi[j]>xmaximum) xmaximum=xi[j];
            if(xi[j]<xminimum) xminimum=xi[j];
          } 
    if(xmaximum==xminimum) {System.out.println("wrong data setdefinition");}
    double xx=(2.0*x-xminimum-xmaximum)/(xmaximum-xminimum);
int n=E.length;
double ff=0;
if(n!=0.0)
  { 
  for(int i=0;i<n;i++)
   {ff+=E[i]*fi(xx,i);}
  } 
return ff;
}

public static double[][]  funcEKKChebyshev(double xi[],double yi[],int polinomkatsayisi,int aradegersayisi)
 {
	//aradegersayisi:  x--o--o--x--o--o--x zincirinde x deneysel noktalar ise
	// ara değer sayısı 2 dir
	 int n=xi.length;
	int nn=(n-1)*(aradegersayisi+1)+1;
	double z[][]=new double[2][nn];
    double E[]=EKKChebyshev(xi,yi,polinomkatsayisi);	
    double dx=0;
    int k=0;
    int i;
    for(i=0;i<(n-1);i++)
       {z[0][k]=xi[i];z[1][k]=funcEKKChebyshev(E,xi,z[0][k]);k++;
       for(int j=0;j<aradegersayisi;j++) 
       {dx=(xi[i+1]-xi[i])/((double)aradegersayisi+1.0);
       z[0][k]=z[0][k-1]+dx;z[1][k]=funcEKKChebyshev(E,xi,z[0][k]);k++;}
       }
       z[0][k]=xi[i];z[1][k]=funcEKKChebyshev(E,xi,z[0][k]);
    return z;
 } 
 
  public static void main(String args[]) throws IOException
  {
  double x[]={1,2,3,4,5};
  double y[]={1,4,9,16,25};
  //double x[]={0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0};
  //double y[]={0.0,0.099833,0.1986693,0.2955202,0.38941834,0.479425,0.5646424,0.6442176,0.717356,0.783326,0.84147};

  double z[][]=funcEKKChebyshev(x,y,2,8);
  Text.print(Text.T(z),"Chebyschev ortogonal en küçük kareler yöntemi eğri uydurma");
  System.out.println("E.K.K.\n"+Matrix.toStringT(z)); 
  
  Plot pp=new Plot(x,y);
  pp.setPlabel("Chebyschev ortogonal polinomları kullanarak en küçük kareler yöntemi ile eğri uydurma");
  pp.setPlotType(0,20); 
  pp.addData(z[0],z[1]);
  pp.plot();
  }
}