example_Ode.txt

The following source file shows some calc::Ode functions applied with calc::Cpx variables. Initially, a test function along with its first and and second derivatives are defined (fn(x), dfn(x), ddfn(x)). Parameters are set indicating the integration interval and the accuracy of the intergration. The calc::Ode objects are given initial values of fn(x) and dfn(x) at the start of the boundary. The second derivative is supplied to the calc::Ode objects through the call back function fnOde(dy,y,x). The solution of the test function fn(x) evaluated at the upper bound along with its derivative are produced as output overwriting the initial conditions in the y array by the call to Ode::eval().

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 

Generated on Wed Jul 19 09:23:35 2006 for CalcLib by  doxygen 1.4.7