class ff
{
   public double func(double x)
   {
   return Math.sin(Math.PI*x);	   
   }	
	
}

//to approximate the solution to the parabolic partial differential equation
// d(u)dt=alfa*alfa*d2(u)/dx2,  0<

public class PDE_Parabolic_Forward_Finite_Difference
{
double alfa;
double k;
double h;
double A[][];
double w[];
double ww[];
double x[];
int m;
int N;
double delta;
ff f;

    public  PDE_Parabolic_Forward_Finite_Difference(int mm,int NN,double aalfa,double kk,double hh,ff fe)
    {
	  f=fe;
	  m=mm;    
	  k=kk;
	  h=hh;
	  alfa=aalfa;
	  N=NN;
	  delta=alfa*alfa*k/(h*h);
	  //System.out.println(delta);
	    
	    System.out.println("delta = "+delta);
	     w=new double[m]; 
	     w[m-1]=w[0]=0.0;
	     ww=new double[m-2];
	     double dt=0.1;
	     double ii=1.0;
	     for(int i=1;i<m-1;i++)
	     {w[i]=f.func(ii*dt);
	     //System.out.println(w[i]);
	     ii++;}
	     
	     A=new double[m-2][m-2];
	     for(int i=0;i<m-2;i++)
	     {
		 A[i][i]=(1.0-2.0*delta);
		 } 
	     for(int i=1;i<m-2;i++)
	     {
		 A[i][i-1]=delta;    
		 }
		 for(int i=1;i<m-2;i++)
	     {
		 A[i-1][i]=delta;    
		 }
	     
		 int yy=0;
		 for(int i=1;i<=m-2;i++)
		 {ww[yy]=w[i];yy++;}
	  
		 for(int j=0;j<N;j++)
	     {
		  ww=multiply(A,ww);
		  System.out.println(Matrix.toString(ww)); 
         }
	  
	  }
	  
	  
	  public  double[] multiply(double[][] left,double[] right)
      {
      //multiplication of one matrix with one vector
        int ii,jj,i,j,k;
        int m1=left[0].length;
        int n1=left.length;
        int m2=right.length;
        double[] b;
        b=new double[m2];
         if(n1 != m2)
         {
         System.out.println("inner matrix dimensions must agree");
          for(ii=0;ii<n1;ii++)
          {
            b[ii]=0;
          }
          return b;
         }
            for(i=0;i<m1;i++)
            {
                b[i]=0;
                for(k=0;k<n1;k++)
	            b[i]+=left[i][k]*right[k];
            }
               return b;
            //end of multiply of a matrix and a vector
       }


    public double exactsolution(double x,double t)
    {
	return Math.exp(-Math.PI*Math.PI*t)*Math.sin(Math.PI*x);
	}

	
	 public static void main(String args[])
	 {
	 ff f=new ff();	 
	 double h=0.01;
	 double k=0.005;
	 double alfa=1.0;
	 int m=11;
	 int N=20;
	  	new PDE_Parabolic_Forward_Finite_Difference(m,N,alfa,k,h,f); 
		 
     }





















}