import javax.swing.*;

public class B_spline_p
{ // degree p B-spline interpolation
  public double x[],y[];
  public int p,n,m;      // degree of polynomial
  public double alpha;  // power factor p=1 linear relation
  double v[];
  double N[][];
  public double minimum(double xi[])
  {double min=1.0e200;
   for(int i=0;i<n;i++)
   {if(xi[i]<min) min=xi[i];}
   return min;
  }
  public double maximum(double xi[])
  {
   double max=-1.0e200;
   for(int i=0;i<n;i++)
   {if(xi[i]>max) max=xi[i];}
   return max;
  }
  public double average(int i1,int i2,int p,double ti[])
  {
  double avg=0;
  for(int i=i1;i<=i2;i++)
  {avg+=ti[i];}
  return avg/p;	  
  }
  
  public B_spline_p(double xi[],double yi[],int pi,double alphai)
  {
  double L=0;
  x=xi;
  y=yi;
  p=pi;
  alpha=alphai;
  n=xi.length;
  m=n+p+1;
  double minx=minimum(xi);
  double maxx=maximum(xi);

  N=new double[m][p+1];

  double t[]=new double[n];
  double LK[]=new double[n];
  for(int i=1;i< n;i++)
  {L+=Math.pow(((xi[i]-xi[i-1])*(xi[i]-xi[i-1])+(yi[i]-yi[i-1])*(yi[i]-yi[i-1])),alpha);
   LK[i]=L;
  }
  for(int i=1;i< n;i++)
  {LK[i]=LK[i]/L;
   t[i]=minx+LK[i]*(maxx-minx);
  }
  v=new double[m];
  for(int i=0;i<=p;i++)
  {v[i]=minx;}
  for(int j=0;j<(m-2*p-2);j++)
  {v[j+p+1]=average(j,(j+p-1),p,t);}
  for(int i=m-p-1;i<m;i++)
  {v[i]=maxx;} 
  System.out.println("minx="+minx+"maxx="+maxx);  
  System.out.println(Matrix.toString(v));
  }
  
  public void Nip(double u)
  {
	  System.out.println("m="+m);
  for(int i=0;i<m-1;i++)
  { boolean b=u>=v[i] && u<=v[i+1];
	if(b) N[i][0]=1.0;
    else N[i][0]=0.0;
   System.out.println("u="+u+"b="+b+"i="+i+"p="+0+"N="+N[i][0]+"vi="+v[i]+"vi+1="+v[i+1]);
  }
  for(int i=0;i<m-1;i++)
  {
  for(int pi=1;pi<p;pi++)
  {N[i][pi]=(u-v[i])/(v[i+pi-1]-v[i])*N[i][pi-1]+(v[i+pi]-u)/(v[i+pi]-v[i+1])*N[i+1][pi-1];
   System.out.println("i="+i+"p="+pi+N[i][pi]); 
  }
  }
  System.out.println(Matrix.toString(N)); 
  }
  
  public static void main(String arg[])
  {double x[]={1,2,3,4,5};
   double y[]={1,4,9,16,25};
   B_spline_p bp=new B_spline_p(x,y,3,1.0);
   bp.Nip(1.5);
  }

}