00001
00002
00003
00004
00005
00006
00007 #ifndef CALC_ODE_H
00008 #define CALC_ODE_H
00009
00010
00011
00012
00013
00014 #include "Base.h"
00015
00016
00017
00018
00019
00020 namespace calc {
00021
00022
00023
00024
00030
00031
00042 class OdeErr:public Err {
00043
00044 public:
00045
00046
00047
00049 enum ERR_ENUM {
00050 INIT=0,
00051 MEMORY,
00052 LOOP,
00053 STEP,
00054 ERR_CNT
00055 };
00056
00057
00058
00065 OdeErr(enum OdeErr::ERR_ENUM indErr):
00066 Err() {
00067 const char* const CLASS_NAME="Ode";
00068 const char* const ERR_STR[ERR_CNT]={
00069 "object initialization error",
00070 "memory allocation error",
00071 "maximum loop count exceeded",
00072 "complete underflow of integration step size",
00073 };
00074 setError(indErr,CLASS_NAME,ERR_STR[indErr]);
00075 }
00076 };
00077
00078
00079
00080
00081
00083
00100 template <typename xType, typename yType>
00101 class Ode:public Base {
00102
00103 public:
00104
00105
00106
00108 enum VTYPE {
00109 CURRENT=0 ,
00110 MAXIMUM ,
00111 VARIABLE ,
00112 VTYPE_CNT ,
00113 };
00114
00115
00116
00117
00118 Ode(void (&pFn)(yType*,yType*,xType), xType dEps, int nVar);
00119 Ode(const Ode &od);
00120 ~Ode(void);
00121
00122
00123
00124 yType *eval (yType *y, xType x1, xType x2, xType dx) throw (OdeErr);
00125 bool setEpsilon (xType dEps);
00126 bool setCount (int nMaximum);
00127
00147 void getDerivative(yType *dy, yType *y, xType x) const {(*pFn)(dy,y,x);}
00154 xType getError(void) const {return yEps;}
00168 int getCount(enum Ode<xType,yType>::VTYPE vType) const
00169 {return ((!nogo)&&(vType>=0)&&(vType<VTYPE_CNT)?nCount[vType]:-1);}
00170
00172 static const int DEF_LOOP_MAX=10000;
00174 static const int STEP_CNT=6;
00175
00176 private:
00177
00178
00179
00180 virtual void varInit (void);
00181
00182 bool varAlloc (int nVar);
00183 bool checkIt (void);
00184 void advanceIt (void);
00185
00186
00187
00188 void (*pFn)(yType*,yType*,xType);
00190 xType yEps;
00191 xType xCur;
00192 xType dxCur;
00193 xType dxOld;
00194 xType dxNew;
00195 xType *yScl;
00196 yType *yMid;
00197 yType *yCur;
00198 yType *yErr;
00199 yType *yEst;
00200 yType *dyInc[STEP_CNT];
00202 int nCount[VTYPE_CNT];
00204 static const xType SCALE_MIN;
00205 static const xType ADJUST_LO;
00206 static const xType ADJUST_HI;
00207 static const xType SCALE_LO;
00208 static const xType SCALE_HI;
00209
00210 static const double ADJUST_MIN;
00211 static const double ADJUST_MAX;
00212 static const double PADDING;
00213 };}
00214
00215
00216
00218 template <typename xType, typename yType>
00219 const xType calc::Ode<xType,yType>::SCALE_MIN=1.0e-20;
00221 template <typename xType, typename yType>
00222 const xType calc::Ode<xType,yType>::ADJUST_LO=7000.0;
00224 template <typename xType, typename yType>
00225 const xType calc::Ode<xType,yType>::ADJUST_HI=1.0e-04;
00227 template <typename xType, typename yType>
00228 const xType calc::Ode<xType,yType>::SCALE_LO=(-0.25);
00230 template <typename xType, typename yType>
00231 const xType calc::Ode<xType,yType>::SCALE_HI=(-0.20);
00232
00234 template <typename xType, typename yType>
00235 const double calc::Ode<xType,yType>::ADJUST_MIN=0.1;
00237 template <typename xType, typename yType>
00238 const double calc::Ode<xType,yType>::ADJUST_MAX=5.0;
00240 template <typename xType, typename yType>
00241 const double calc::Ode<xType,yType>::PADDING=0.9;
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 #endif
00254
00255
00256
00257
00258
00259 #include "Ode.cpp"
00260
00261