import java.awt.event.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.awt.image.*;
import javax.swing.*;
import java.util.Locale;
import java.text.*;
import java.util.*;
import javax.swing.table.*;

class differential1
{ 	 	
	 public differential1(double x0,double y0,double xn,double h)
	 {     
        fDEq ff=new fDEq();
        double r[][]= RK6(ff,x0,y0,xn,h);
        Plot pp=new Plot(r[0],r[1]);
	    pp.plot();
        Text.print(Text.T(r));
     }
     
     public static double[] enterdoublearray(String s)
     {
     String s1=JOptionPane.showInputDialog(s);        
     StringTokenizer token=new StringTokenizer(s1);
     int n=token.countTokens()-1;
     int m=n+1;
     double a[]=new double[m];
     int j=0;           
     while(token.hasMoreTokens())
     {
     Double ax=new Double(token.nextToken());
     a[j++]=ax.doubleValue();
     }
     return a;
     }
     
  public static double[][] RK6(f_xy f,double x0,double y0,double xn,double h)
  {
  // Runge-Kutta 6
  int n=(int)((xn-x0)/h);	  
  double a[][]=new double[2][n+1];
  int i=0;
  a[0][0]=x0;
  a[1][0]=y0;
  double k1,k2,k3,k4,k5,k6;
  for(double xx=x0;xx<xn;xx+=h)
   {a[0][i+1]=xx+h;
   k1=f.func(a[0][i],a[1][i]);
   k2=f.func(a[0][i]+0.25*h,a[1][i]+0.25*k1*h);
   k3=f.func(a[0][i]+0.25*h,a[1][i]+1.0/8.0*k1*h+1.0/8.0*k2*h);
   k4=f.func(a[0][i]+0.5*h,a[1][i]-0.5*k2*h+k3*h);
   k5=f.func(a[0][i]+3.0/4.0*h,a[1][i]+3.0/16.0*k1*h+9.0/16.0*k4*h);
   k6=f.func(a[0][i]+h,a[1][i]-3.0/7.0*k1*h+2.0/7.0*k2*h+12.0/7.0*k3*h-12.0/7.0*k4*h+8.0/7.0*k5*h);   
   a[1][i+1]=a[1][i]+(7.0*k1+32.0*k3+12.0*k4+32.0*k5+7*k6)/90.0*h;
   i++;
   }
  return a; 
  }
public static double[][] RKF6(f_xy f,double x0,double y0,double xn,double h,double eps)
  { 	  
  // Runge-Kutta Fehlberg 6 değişken stepli
  //eps bağıl hata
  double alfa;	  
  //double a[][]=new double[2][n+1];
  int i=0;
  //a[0][0]=x0;
  //a[1][0]=y0;
  double delta=h;
  double deltayeni=eps*y0;
  double k1,k2,k3,k4,k5,k6;
  Vector<Double> xi=new Vector<Double>();
  Vector<Double> yi=new Vector<Double>();
  double x,y,yp1_5,yp1_6,xeski,yeski;
  x=x0;
  y=y0;
  xeski=x;
  yeski=y;
  Double Xi=new Double(x);
  Double Yi=new Double(y);
  xi.add(Xi);
  yi.add(Yi);
  while((x+h)<=xn)
   {
   xeski=x;	
   yeski=y;   
   k1=f.func(x,y);
   k2=f.func(x+1.0/5.0*h,y+1.0/5.0*k1*h);
   k3=f.func(x+3.0/10.0*h,y+3.0/40.0*k1*h+9.0/40.0*k2*h);
   k4=f.func(x+3.0/5.0*h,y+3.0/10.0*k1*h-9.0/10.0*k2*h+6.0/5.0*k3*h);
   k5=f.func(x+h,y-11.0/54.0*k1*h+5.0/2.0*k2*h-70.0/27.0*k3*h+35/27.0*k4*h);
k6=f.func(x+7.0/8.0*h,y+1631.0/55296.0*k1*h+175.0/512.0*k2*h+575.0/13824.0*k3*h+44275.0/110592.0*k4*h+253.0/4096.0*k5*h);   
   yp1_5=y+(37.0/378.0*k1+250.0/621.0*k3+125.0/594.0*k4+512.0/1771.0*k6)*h;
   yp1_6=y+(2825.0/27648.0*k1+18575.0/48384.0*k3+13525.0/55296.0*k4+277.0/14336.0*k5+1.0/4.0*k6)*h;
   y=yp1_6;
   x=x+h;
   Xi=new Double(x);
   Yi=new Double(y);
   xi.add(Xi);
   yi.add(Yi);   
   delta=Math.abs(yp1_6-yp1_5);
   deltayeni=Math.abs(eps*yp1_6);
   if(delta<=deltayeni) alfa=0.2;
   else                 alfa=0.25;
   h=h*Math.pow((deltayeni/delta),alfa);
   i++;
   }
   if(x<xn)//son bir step daha
   {
   h=xn-x;
   k1=f.func(x,y);
   k2=f.func(x+1.0/5.0*h,y+1.0/5.0*k1*h);
   k3=f.func(x+3.0/10.0*h,y+3.0/40.0*k1*h+9.0/40.0*k2*h);
   k4=f.func(x+3.0/5.0*h,y+3.0/10.0*k1*h-9.0/10.0*k2*h+6.0/5.0*k3*h);
   k5=f.func(x+h,y-11.0/54.0*k1*h+5.0/2.0*k2*h-70.0/27.0*k3*h+35/27.0*k4*h);
   k6=f.func(x+7.0/8.0*h,y+1631.0/55296.0*k1*h+175.0/512.0*k2*h+575.0/13824.0*k3*h+44275.0/110592.0*k4*h+253.0/4096.0*k5*h);   
   yp1_5=y+(37.0/378.0*k1+250.0/621.0*k3+125.0/594.0*k4+512.0/1771.0*k6)*h;
   yp1_6=y+(2825.0/27648.0*k1+18575.0/48384.0*k3+13525.0/55296.0*k4+277.0/14336.0*k5+1.0/4.0*k6)*h;
   y=yp1_6;
   //System.out.println("x="+x+"h="+h+"y="+yp1_6);
   x=xn;
   Xi=new Double(x);
   Yi=new Double(y);
   xi.add(Xi);
   yi.add(Yi);
   i++;
   }
   //vektöre aktarılan değerleri double matrise aktar
   int n=i;
        double aa[][]=new double[2][n+1];
        Enumeration nx=xi.elements();
        Enumeration ny=yi.elements();
        for(i=0;i<=n;i++)
        {
	    //String ss1=(String)nx.nextElement();
	    //String ss2=(String)ny.nextElement();    
	    Double ax=(Double)nx.nextElement();
	    Double ay=(Double)ny.nextElement();
        aa[0][i]=ax.doubleValue();
        aa[1][i]=ay.doubleValue();  
        }
   return aa;
  }  
 }
