package comp599.a1.numerical;



/**
 * TODO: finish this class!
 * @author kry
 */
public class RK implements Integrator {
    
    @Override
    public String getName() {
        return "Runge Kuta";
    }
    
    //constructor method for ForwardEuler
    public RK(){
    	
    }
    
    @Override
    /** 
     * Advances the system at t by h 
     * @param y The state at time h
     * @param n The dimension of the state (i.e., y.length)
     * @param t The current time (in case the derivs function is time dependent)
     * @param h The step size
     * @param yout  The state of the system at time t+h
     * @param derivs The object which computes the derivative of the system state
     */
    public void step(double[] y, int n, double t, double h, double[] yout, Function derivs) {
    	double[] dydt;
    	double[] k1;
    	double[] k2=new double[y.length];
    	double[] k3= new double[y.length];
    	double[] k4= new double[y.length];
    	dydt= new double[y.length];
    	derivs.derivs(t, y, dydt);
    	k1=(double[])dydt.clone(); 
    	dydt= new double[y.length];
    	for(int i=0; i< k1.length; i++){
    		k2[i]=y[i]+k1[i]*h/2;
    	}
    	derivs.derivs(t, k2, dydt);
    	k2=(double[])dydt.clone();  //k2 
    	dydt= new double[y.length];
    	for(int i=0; i< k1.length; i++){
    		k3[i]=y[i]+k2[i]*h/2;
    	}
    	derivs.derivs(t,k3,dydt);
    	k3=(double[])dydt.clone();  //k3
    	dydt= new double[y.length];
    	for(int i=0; i< k1.length; i++){
    		k4[i]=y[i]+k3[i]*h;
    	}
    	derivs.derivs(t,k4,dydt);
    	k4=(double[])dydt.clone();  //k4
    	for(int i=0; i< k1.length; i++){
    		yout[i]=y[i]+k1[i]*h/6+k2[i]*h/3+k3[i]*h/3+k4[i]*h/6;
    	}
    }
    
    
    
    // a little method to add two arrays
    public double[] addArrays(double[] a1,double[] a2){
    	double[] retArr= new double[a1.length];
    	for(int i=0; i< retArr.length; i++){
    		retArr[i]=a1[i]+a2[i];
    	}
    	return retArr;
    }
    
    
}
