Ejemplo n.º 1
0
static void Main(){
	complex I=new complex(0,1); 								 //complex i
	complex a=0.01+0.01*I; 										 //start value
	cvector ya=new cvector(0.100333+0.099666*I,0.999983-0.01*I); //function values of a (from WolframAlpha)
	complex b=2*PI+2*PI*I;			 							 //end value
	complex h=0.1+0.1*I;			 							 //step size
	double acc=1e-3;											 //accuracy	
	double eps=1e-3;											 //accuracy	
	var xs=new List<complex>();	
	var ys=new List<cvector>();	

	cvector y=ode.rk23(F,a,ya,b,acc:acc,eps:eps,h:h,xlist:xs,ylist:ys);	//solving the ODE

	Error.WriteLine("Exam project #5: Generalize the ODE solver of your choice to solve ODE with complex-valued functions of complex variable along a straight line between the given start- and end-point.\n");
	Error.WriteLine($"accuracy: acc={acc} eps={eps}");
	Error.WriteLine($"npoints={xs.Count}");
	Error.WriteLine($"start point:	a={a}, end point: b={b}");
	Error.WriteLine($"end point:	b={b}");
	Error.WriteLine($"Function values at start point: y0(a)={ya[0]} 	y1(a)={ya[1]}");
	Error.WriteLine($"Function values at end point:   y0(b)={y[0]}  	y1(b)={y[1]}");
	Error.WriteLine($"Expected values at end point:	sin(b)={sin(b)}  cos(b)={cos(b)}");
	if(approx(y[0],sin(b),acc,eps) && approx(y[1],cos(b),acc,eps))
		Error.WriteLine("test passed");
	else
	Error.WriteLine("test failed");

	Error.WriteLine("\nThough the result is very close to the expected result, I can't seem to be able to get it quite right.\n");

	for(int i=0;i<xs.Count;i++){ //for making plots
		WriteLine($"{(xs[i]).Re} {(xs[i]).Im} {(ys[i][0]).Re} {(ys[i][0]).Im} {(ys[i][1]).Re} {(ys[i][1]).Im} {abs(ys[i][0])} {abs(ys[i][1])}");
	}
}//Main
Ejemplo n.º 2
0
public static cvector[] rkstep23(Func<complex,cvector,cvector> F, complex x, cvector y, complex h)
{// Embedded Runge-Kutta stepper of the order 2-3
	cvector k0 = F(x,y);
	cvector k1 = F(x+h/2, y+(h/2)*k0);
	cvector k2 = F(x+3*h/4, y+(3*h/4)*k1);
	cvector ka = (2*k0+3*k1+4*k2)/9;
	cvector kb = k1;
	cvector yh = y+ka*h;
	cvector err = (ka-kb)*h;
	cvector[] result={yh,err};
	return result;
}//rkstep23
Ejemplo n.º 3
0
}//rk23

public static cvector driver(Func<complex,cvector,cvector> F, complex a, cvector ya, complex b, double acc, double eps, complex h, List<complex> xlist, List<cvector> ylist, int limit, Func<Func<complex,cvector,cvector>,complex,cvector,complex,cvector[]> stepper){
	int nsteps=0;
	if(xlist!=null) {xlist.Clear(); xlist.Add(a);}
	if(ylist!=null) {ylist.Clear(); ylist.Add(ya);}		
	do{
		if(abs(a)>abs(b)) return ya; //making sure we have a proper interval

		complex I=new complex(0,1);	//complex i
		/* enforce that a straight line is taken between a and b */
		double relength=b.Re-a.Re;
		double imlength=b.Im-a.Im;
		double realres=h.Re/relength;
		double imres=h.Re/imlength;
		if(realres<imres) h=realres*relength+realres*imlength*I; 
		else h=imres*relength+imres*imlength*I; 

		/* stop when adding the step means overstepping the interval end value*/
		if(abs(a+h)>=abs(b)) return ya;	
		if(a.Re+h.Re>=b.Re) return ya; 
		if(a.Im+h.Im>=b.Im) return ya; 

		/* stop if the number of steps becomes larger than the limit */
		if(nsteps>limit){
			Error.Write($"ode.driver: nsteps>{limit}\n");
			return ya;
			}
		
		cvector[] trial=stepper(F,a,ya,h);	//calling rkstep23.cs (calculates the step to be taken)
		cvector yh=trial[0];				//function values
		double er=trial[1].norm();			//error
		double tol=(yh.norm()*eps+acc)*Sqrt(abs(h/(b-a)));	//tolerance
		
		complex hnew=h*min(pow(tol/er,0.25)*0.95,2); //eq. 40 (the adjusted step)
		int ok=1;
		if(er>tol) ok=0; 
		/* updating the x- and y-lists */
		if(ok==1){ 
			a+=h; ya=yh; h=hnew; nsteps++;
			if(xlist!=null) xlist.Add(a); 
			if(ylist!=null) ylist.Add(ya);
		}
		/* if precision has not been reached, adjust step size and try again */
		else{h=hnew;} //Error.WriteLine($"driver: bad step at {a}"); }
	}while(true);
	}//driver23
Ejemplo n.º 4
0
public static cvector rk23(Func<complex,cvector,cvector> F, complex a, cvector ya, complex b, complex h, double acc, double eps, List<complex> xlist=null, List<cvector> ylist=null, int limit=999){
	return driver(F,a,ya,b,acc,eps,h,xlist,ylist,limit,rkstep23);
}//rk23
Ejemplo n.º 5
0
public cvector map(System.Func<complex,complex>f){
	cvector v=new cvector(size);
	for(int i=0;i<size;i++)v[i]=f(this[i]);
	return v;
	}
Ejemplo n.º 6
0
public complex dot(cvector o){
	complex sum=0;
	for(int i=0;i<size;i++)sum+=this[i]*o[i];
	return sum;
	}
Ejemplo n.º 7
0
public static cvector operator/(cvector v, complex a){
	cvector r=new cvector(v.size);
	for(int i=0;i<v.size;i++)r[i]=v[i]/a;
	return r; }
Ejemplo n.º 8
0
public static cvector operator-(cvector v, cvector u){
	cvector r=new cvector(v.size);
	for(int i=0;i<r.size;i++)r[i]=v[i]-u[i];
	return r; }
Ejemplo n.º 9
0
public static cvector operator*(cvector v, double a){
	cvector r=new cvector(v.size);
	for(int i=0;i<v.size;i++) r[i]=a*v[i].Re+a*v[i].Im*I;
	return r; }
Ejemplo n.º 10
0
public bool approx(cvector o){
	for(int i=0;i<size;i++)
		if(!approx(this[i],o[i]))return false;
	return true;
	}
Ejemplo n.º 11
0
public static bool approx(cvector a,cvector b,double acc=1e-9,double eps=1e-9){
	if(a.size!=b.size)return false;
	for(int i=0;i<a.size;i++)
		if(!approx(a[i],b[i],acc,eps))return false;
	return true;
}
Ejemplo n.º 12
0
public cvector copy(){
	cvector b=new cvector(this.size);
	for(int i=0;i<this.size;i++)b[i]=this[i];
	return b;
}