package signal.lib;
 
//     Methods for: locating collocation points,
//   evaluating Chebyshev Polynomials of degree N, evaluating the derivative of Chebyshev Polynomials of degree N,
//   obtaining the discrete Chebyshev coefficients, summing a discrete Chebyshev series in an efficient manner.
   
/**
   Implements methods associated with the Chebyshev Polynomials, Tk(x).
*/

  public final class chebyshevPolynomial {
  
  
// ----------------------------------------------------------------------------
// ---------- collocation points ----------------------------------------------
// ---------------------------------------------------------------------------- 
  
/** Returns CGL points in the order order 1,...,-1 */
  public static double xGLr(int i, int N) { return  Math.cos(i*Math.PI/N); } 
/** Returns CGL points in the order order order -1,...,1 */   
  public static double  xGL(int i, int N) { return -Math.cos(i*Math.PI/N); }     
  
// ----------------------------------------------------------------------------
// ---------- weights and normalizing factors ---------------------------------
// ---------------------------------------------------------------------------- 
  
/**  weights and normalizing factors, 1/Cj */
  public static double CJ(int m, int N) { if  (m==0 || m == N) return 0.5; else return 1.0; }  
  
  
// ----------------------------------------------------------------------------
// ---------- polynomials and derivatives -------------------------------------
// ----------------------------------------------------------------------------
  
/**  Returns the Chebyshev Polynomial of degree N */
    public static double T(double x, double N) { return Math.cos(N*Math.acos(x)); }
   
/**  Returns the derivative of the Chebyshev Polynomial of degree N */
    public static double Tp(double x, double N) { 
      double eps = 0.00001;
      if      (x<(-1+eps) && x>(1-eps)) return -N*N;       
      else if (x<(1+eps) && x>(1-eps))  return N*N;
      else            return -N*Math.sin(N*Math.acos(x))/Math.sqrt(1-x*x);
   } // Tp
   
   
// ----------------------------------------------------------------------------
// ---------- discrete coefficients and series summations ---------------------
// ----------------------------------------------------------------------------
   
/**  Given discrete function values u, the method returns the first N+1 discrete Chebyshev coefficients, ak */  
    public final static void chebyCoef(double[] u, double[] ak, int N) {
      double dx=(1.0/N), dxP=dx*Math.PI;  double sum2=0;
      for (int k=0; k<=N; k++ ) {
         sum2=0;
         for (int n=0; n<=N; n++ )  sum2 += u[n]*Math.cos(k*n*dxP);
         ak[k] = 2.0*dx*sum2;
      } // k
    } // chebyCoef
   
  
/** Evaluates the Chebyshev partial sum u += aN[k]*T(x,k) by Clenshaw's recurrence relation */
  public static double chebySeries(double coef[], double x) {

       double  b0, b1, b2, twox;
        int     i;
        b1 = 0.0;
        b0 = 0.0;
        b2 = 0.0;
        twox = 2.0*x;
        for (i=coef.length-1; i>=0; i--) {
            b2 = b1;
            b1 = b0;
            b0 = twox*b1 - b2 + coef[i];
        }
        return 0.5*(b0-b2);
        
   } // chebySeries
   
  
  } // chebyshevPolynomial

