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

class f1 extends f_x
{
public double func(double x) 
{
//çözümü istenen fonksiyon	
double ff;
ff=Math.exp(x);
return ff; //minimum değil maxsimum istendiğinden - ile çarptık
}
}

class SCO11I
{   
	public static double Ti(double x,int equation_ref)
	{//Chebysev fonksiyonu	
	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[] xi(double a,double b,int N)
{
   int nn=N+1;
   double x[]=new double[nn];
   double t[]=new double[nn];
   for(int k=0;k<nn;k++)
     {t[k]=Math.cos((2.0*N+1-2.0*k)*Math.PI/(2.0*N+2.0));
      x[k]=(b-a)/2.0*t[k]+(a+b)/2.0;
     }
   return x;              
}
	  
public static double[] Chebyshev(double a,double b,f_x f,int N)
{   //a b arası eşit aralıklı noktalar
    int nn=N+1;
    System.out.println("N="+N);  
    int k,j;
    double d=Math.PI/(2.0*N+2);
    double x[]=new double[nn];
    double t[]=new double[nn];
    double y[]=new double[nn];
     // -1<=x<=1 arasinda değer dönüşümü uygula 
    for(k=0;k<nn;k++)
     {t[k]=Math.cos((2.0*N+1-2.0*k)*Math.PI/(2.0*N+2.0));
      x[k]=(b-a)/2.0*t[k]+(a+b)/2.0;
      y[k]=f.func(x[k]);     
      //System.out.println("t"+k+"="+t[k]+"x"+k+"="+x[k]+"y"+k+"="+y[k]);
     }                
     double C[]=new double[nn];
	 double z=0;
     for(k=0;k<nn;k++)
        { z+=y[k];}
     C[0]=z/(N+1);
     //System.out.println("C"+0+"="+C[0]);         
     for(j=1;j<=N;j++)
     {z=0;
      for(k=0;k<=N;k++)
      { z+=y[k]*Ti(t[k],j);}
     C[j]=2.0*z/(N+1);
     } 
     return C;
}

public static double funcChebyshev(double C[],double a,double b,double x)
{
    double t=2.0*(x-a)/(b-a)-1;
    //System.out.println("t="+t);
    int n=C.length;
    double ff=0;
    if(n!=0.0)
    {  for(int i=0;i<n;i++)
       {ff+=C[i]*Ti(t,i);}
    } 
    return ff;
}

public static double[][]  funcChebyshev(double a,double b,f_x f,int polinomkatsayisi,int verisayisi)
 {
  int n=verisayisi+1;
  double z[][]=new double[2][n];
  double C[]=Chebyshev(a,b,f,polinomkatsayisi);
  double dx=(b-a)/(double)verisayisi;
  z[0][0]=a;
  for(int i=0;i<=verisayisi;i++)
     {if(i==0) z[0][i]=a;
      else z[0][i]=z[0][i-1]+dx;
	     z[1][i]=funcChebyshev(C,a,b,z[0][i]);     
     //System.out.println("dx="+dx+"i = "+i+"x="+z[0][i]+"y="+z[1][i]);
     }
    return z;
 } 
 
  public static void main(String args[]) throws IOException
  {
  f1 ff=new f1();
  double a=0;
  double b=2.0;
  double z[][]=funcChebyshev(a,b,ff,20,10);
  Text.print(Text.T(z),"Chebyschev ortogonal en küçük kareler yöntemi eğri uydurma");
  System.out.println("dx=\n"+Matrix.toStringT(xi(a,b,10)));
  }
}