00001 00002 #include "Cpx.h" // complex variable definitions 00003 #include "Ode.h" // differential equation objects 00004 00005 using namespace std; // standard C++ library namespace 00006 using namespace calc; // CalcLib namespace 00007 00008 typedef Cpx<float> CPXf; // alias for <yType> 00009 00010 // test function data 00011 const CPXf C1(-1.0f,-1.0f); // test function constant 00012 const CPXf C2(-1.0f, 1.0f); // test function constant 00013 CPXf fn(float x) {return sin(C2*x)*C1;} // test function 00014 CPXf dfn(float x) {return cos(C2*x)*C1*C2;} // test function 1st derivative 00015 CPXf ddfn(float x) {return -sin(C2*x)*C1*C2*C2;} // test function 2nd derivative 00016 00017 // 2nd derivative callback function 00018 void fnOde(CPXf *dy, CPXf *y, float x) // derivative identifier function 00019 { 00020 dy[0]=y[1]; // 0th derivative in dy is 1st derivative in y 00021 dy[1]=ddfn(x); // 1st derivative in dy is derived function ddfn(x) 00022 } 00023 00024 // results print function 00025 void results(ostream &ostr, const char *cDat, CPXf cpf, int nCnt) 00026 { 00027 ostr<<" "<<cDat<<" = "; // print out title 00028 cpf.stream(ostr)<<" ("<<nCnt<<" steps)"; // print data values 00029 ostr<<endl; // end the text line 00030 } 00031 00032 int main(void) 00033 { 00034 // set parameters 00035 const int nVar=2; // integration array count 00036 const float xLo =0.0f; // integration lower bound 00037 const float xHi =0.25f*Base::PI; // integration upper bound 00038 const float yError=0.05f; // integration error 00039 const CPXf y0=fn(xHi); // final answer 00040 CPXf y1[2],y4[2],y8[2]; // evaluation arrays 00041 00042 // initialize data 00043 Ode<float,CPXf> ode1(fnOde,yError,nVar); // initialize differential equation objects 00044 Ode<float,CPXf> ode4=ode1; // initialize differential equation objects 00045 Ode<float,CPXf> ode8=ode4; // initialize differential equation objects 00046 y1[0]=y4[0]=y8[0]= fn(xLo); // set evaluation array[0] at start value 00047 y1[1]=y4[1]=y8[1]=dfn(xLo); // set evaluation array[1] at start derivative 00048 00049 // evaluate ordinary differential equation 00050 try { 00051 ode1.eval(y1,xLo,xHi,(xHi-xLo)/1.0f); // integrate from xLo to xHi in about 1 step 00052 ode4.eval(y4,xLo,xHi,(xHi-xLo)/4.0f); // integrate from xLo to xHi in about 4 steps 00053 ode8.eval(y8,xLo,xHi,(xHi-xLo)/8.0f); // integrate from xLo to xHi in about 8 steps 00054 } 00055 catch(OdeErr& odeErr) {cout<<odeErr<<endl; return 1;} 00056 catch(...) {cout<<"Unknown execution error..."<<endl; return 1;} 00057 00058 // print out evaluations comparing the functions 00059 cout.precision(5); 00060 cout.setf(ios::showpoint,ios::showpoint); 00061 cout<<endl<<" calc::Ode Class Example Application"<<endl<<endl; 00062 cout<<" exact evaluation of fn(x) fn(x) = "; y0.stream(cout)<<" (exact)"<<endl; 00063 results(cout,"Runge-Kutta estimate of fn(x) ode1(x)",y1[0],ode1.getCount(ode1.CURRENT)); 00064 results(cout,"Runge-Kutta estimate of fn(x) ode4(x)",y4[0],ode4.getCount(ode4.CURRENT)); 00065 results(cout,"Runge-Kutta estimate of fn(x) ode8(x)",y8[0],ode8.getCount(ode8.CURRENT)); 00066 cout<<endl<<flush; 00067 00068 return 0; 00069 } 00070
The following output file shows the approximate agreement among the test function fn(x), the calc::Ode objects (ode1,ode4,ode8) applying different initial step sizes (1,4,8). To start initial calculations, the calc::Ode object should have a step size supplied (guessed) by the user. The calc::Ode objects use variable step sizes and monitor the increment values based on the supplied error limit. As shown in the output (8 steps to 3 steps), calc::Ode objects lower the suggested step size quickly if the one supplied is too high. From the output data, only one step is needed for the desired accuracy.
00001 00002 calc::Ode Class Example Application 00003 00004 exact evaluation of fn(x) fn(x) = 1.5509+i0.32240 (exact) 00005 Runge-Kutta estimate of fn(x) ode1(x) = 1.5509+i0.32231 (1 steps) 00006 Runge-Kutta estimate of fn(x) ode4(x) = 1.5509+i0.32238 (2 steps) 00007 Runge-Kutta estimate of fn(x) ode8(x) = 1.5509+i0.32239 (3 steps) 00008
1.4.7