gsl_rk8pd.h

00001 /*
00002   -------------------------------------------------------------------
00003   
00004   Copyright (C) 2006, 2007, Andrew W. Steiner
00005   
00006   This file is part of O2scl.
00007   
00008   O2scl is free software; you can redistribute it and/or modify
00009   it under the terms of the GNU General Public License as published by
00010   the Free Software Foundation; either version 3 of the License, or
00011   (at your option) any later version.
00012   
00013   O2scl is distributed in the hope that it will be useful,
00014   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016   GNU General Public License for more details.
00017   
00018   You should have received a copy of the GNU General Public License
00019   along with O2scl. If not, see <http://www.gnu.org/licenses/>.
00020 
00021   -------------------------------------------------------------------
00022 */
00023 
00024 #ifndef O2SCL_GSL_RK8PD_H
00025 #define O2SCL_GSL_RK8PD_H
00026 
00027 #include <o2scl/vec_arith.h>
00028 #include <o2scl/odestep.h>
00029 
00030 #ifndef DOXYGENP
00031 namespace o2scl {
00032 #endif
00033 
00034   /** \brief Embedded Runge-Kutta Prince-Dormand ODE stepper (GSL)
00035    */
00036   template<class param_t, class func_t, class vec_t, class alloc_vec_t,
00037     class alloc_t> class gsl_rk8pd : 
00038   public odestep<param_t,func_t,vec_t> {
00039 
00040   protected:
00041   
00042     /// \name Storage for the intermediate steps
00043     //@{
00044     alloc_vec_t k2, k3, k4, k5, k6, k7, ytmp;
00045     alloc_vec_t k8, k9, k10, k11, k12, k13;
00046     //@}
00047     
00048     /// Size of allocated vectors
00049     size_t ndim;
00050 
00051     /// Memory allocator for objects of type \c alloc_vec_t
00052     alloc_t ao;
00053 
00054     /** \name Storage for the coefficients
00055      */
00056     //@{
00057     double Abar[13], A[12], ah[10], b21, b3[2], b4[3], b5[4], b6[5];
00058     double b7[6], b8[7], b9[8], b10[9], b11[10], b12[11], b13[12];
00059     //@}
00060       
00061   public:
00062 
00063     gsl_rk8pd() {
00064       this->order=8;
00065 
00066       Abar[0]=14005451.0/335480064.0;
00067       Abar[1]=0.0;
00068       Abar[2]=0.0;
00069       Abar[3]=0.0;
00070       Abar[4]=0.0;
00071       Abar[5]=-59238493.0/1068277825.0;
00072       Abar[6]=181606767.0/758867731.0;
00073       Abar[7]=561292985.0/797845732.0;
00074       Abar[8]=-1041891430.0/1371343529.0;
00075       Abar[9]=760417239.0/1151165299.0;
00076       Abar[10]=118820643.0/751138087.0;
00077       Abar[11]=-528747749.0/2220607170.0;
00078       Abar[12]=1.0/4.0;
00079 
00080       A[0]=13451932.0/455176623.0;
00081       A[1]=0.0;
00082       A[2]=0.0;
00083       A[3]=0.0;
00084       A[4]=0.0;
00085       A[5]=-808719846.0/976000145.0;
00086       A[6]=1757004468.0/5645159321.0;
00087       A[7]=656045339.0/265891186.0;
00088       A[8]=-3867574721.0/1518517206.0;
00089       A[9]=465885868.0/322736535.0;
00090       A[10]=53011238.0/667516719.0;
00091       A[11]=2.0/45.0;
00092 
00093       ah[0]=1.0/18.0;
00094       ah[1]=1.0/12.0;
00095       ah[2]=1.0/8.0;
00096       ah[3]=5.0/16.0;
00097       ah[4]=3.0/8.0;
00098       ah[5]=59.0/400.0;
00099       ah[6]=93.0/200.0;
00100       ah[7]=5490023248.0/9719169821.0;
00101       ah[8]=13.0/20.0;
00102       ah[9]=1201146811.0/1299019798.0;
00103       
00104       b21=1.0/18.0;
00105 
00106       b3[0]=1.0/48.0;
00107       b3[1]=1.0/16.0;
00108 
00109       b4[0]=1.0/32.0;
00110       b4[1]=0.0;
00111       b4[2]=3.0/32.0;
00112 
00113       b5[0]=5.0/16.0;
00114       b5[1]=0.0;
00115       b5[2]=-75.0/64.0;
00116       b5[3]=75.0/64.0;
00117 
00118       b6[0]=3.0/80.0;
00119       b6[1]=0.0;
00120       b6[2]=0.0;
00121       b6[3]=3.0/16.0;
00122       b6[4]=3.0/20.0;
00123 
00124       b7[0]=29443841.0/614563906.0;
00125       b7[1]=0.0;
00126       b7[2]=0.0;
00127       b7[3]=77736538.0/692538347.0;
00128       b7[4]=-28693883.0/1125000000.0;
00129       b7[5]=23124283.0/1800000000.0;
00130 
00131       b8[0]=16016141.0/946692911.0;
00132       b8[1]=0.0;
00133       b8[2]=0.0;
00134       b8[3]=61564180.0/158732637.0;
00135       b8[4]=22789713.0/633445777.0;
00136       b8[5]=545815736.0/2771057229.0;
00137       b8[6]=-180193667.0/1043307555.0;
00138 
00139       b9[0]=39632708.0/573591083.0;
00140       b9[1]=0.0;
00141       b9[2]=0.0;
00142       b9[3]=-433636366.0/683701615.0;
00143       b9[4]=-421739975.0/2616292301.0;
00144       b9[5]=100302831.0/723423059.0;
00145       b9[6]=790204164.0/839813087.0;
00146       b9[7]=800635310.0/3783071287.0;
00147 
00148       b10[0]=246121993.0/1340847787.0;
00149       b10[1]=0.0;
00150       b10[2]=0.0;
00151       b10[3]=-37695042795.0/15268766246.0;
00152       b10[4]=-309121744.0/1061227803.0;
00153       b10[5]=-12992083.0/490766935.0;
00154       b10[6]=6005943493.0/2108947869.0;
00155       b10[7]=393006217.0/1396673457.0;
00156       b10[8]=123872331.0/1001029789.0;
00157 
00158       b11[0]=-1028468189.0/846180014.0;
00159       b11[1]=0.0;
00160       b11[2]=0.0;
00161       b11[3]=8478235783.0/508512852.0;
00162       b11[4]=1311729495.0/1432422823.0;
00163       b11[5]=-10304129995.0/1701304382.0;
00164       b11[6]=-48777925059.0/3047939560.0;
00165       b11[7]=15336726248.0/1032824649.0;
00166       b11[8]=-45442868181.0/3398467696.0;
00167       b11[9]=3065993473.0/597172653.0;
00168 
00169       b12[0]=185892177.0/718116043.0;
00170       b12[1]=0.0;
00171       b12[2]=0.0;
00172       b12[3]=-3185094517.0/667107341.0;
00173       b12[4]=-477755414.0/1098053517.0;
00174       b12[5]=-703635378.0/230739211.0;
00175       b12[6]=5731566787.0/1027545527.0;
00176       b12[7]=5232866602.0/850066563.0;
00177       b12[8]=-4093664535.0/808688257.0;
00178       b12[9]=3962137247.0/1805957418.0;
00179       b12[10]=65686358.0/487910083.0;
00180 
00181       b13[0]=403863854.0/491063109.0;
00182       b13[1]=0.0;
00183       b13[2]=0.0;
00184       b13[3]=-5068492393.0/434740067.0;
00185       b13[4]=-411421997.0/543043805.0;
00186       b13[5]=652783627.0/914296604.0;
00187       b13[6]=11173962825.0/925320556.0;
00188       b13[7]=-13158990841.0/6184727034.0;
00189       b13[8]=3936647629.0/1978049680.0;
00190       b13[9]=-160528059.0/685178525.0;
00191       b13[10]=248638103.0/1413531060.0;
00192       b13[11]=0.0;
00193 
00194       ndim=0;
00195     }
00196       
00197     virtual ~gsl_rk8pd() {
00198       if (ndim!=0) {
00199         ao.free(k2);
00200         ao.free(k3);
00201         ao.free(k4);
00202         ao.free(k5);
00203         ao.free(k6);
00204         ao.free(k7);
00205         ao.free(k8);
00206         ao.free(k9);
00207         ao.free(k10);
00208         ao.free(k11);
00209         ao.free(k12);
00210         ao.free(k13);
00211         ao.free(ytmp);
00212       }
00213     }
00214 
00215     /** 
00216         \brief Perform an integration step
00217 
00218         Given initial value of the n-dimensional function in \c y and
00219         the derivative in \c dydx (which must generally be computed
00220         beforehand) at the point \c x, take a step of size \c h giving
00221         the result in \c yout, the uncertainty in \c yerr, and the new
00222         derivative in \c dydx_out using function \c derivs to
00223         calculate derivatives. The parameters \c yout and \c y and the
00224         parameters \c dydx_out and \c dydx may refer to the same
00225         object.
00226     */
00227     virtual int step(double x, double h, size_t n, vec_t &y, vec_t &dydx, 
00228                      vec_t &yout, vec_t &yerr, vec_t &dydx_out, param_t &pa, 
00229                      func_t &derivs) {
00230         
00231       int ret=0;
00232       size_t i;
00233       
00234       if (ndim!=n) {
00235         if (ndim>0) {
00236           ao.free(k2);
00237           ao.free(k3);
00238           ao.free(k4);
00239           ao.free(k5);
00240           ao.free(k6);
00241           ao.free(k7);
00242           ao.free(k8);
00243           ao.free(k9);
00244           ao.free(k10);
00245           ao.free(k11);
00246           ao.free(k12);
00247           ao.free(k13);
00248           ao.free(ytmp);
00249         }
00250         ao.allocate(k2,n);
00251         ao.allocate(k3,n);
00252         ao.allocate(k4,n);
00253         ao.allocate(k5,n);
00254         ao.allocate(k6,n);
00255         ao.allocate(k7,n);
00256         ao.allocate(k8,n);
00257         ao.allocate(k9,n);
00258         ao.allocate(k10,n);
00259         ao.allocate(k11,n);
00260         ao.allocate(k12,n);
00261         ao.allocate(k13,n);
00262         ao.allocate(ytmp,n);
00263 
00264         ndim=n;
00265       }
00266 
00267       for (i=0;i<n;i++) {
00268         ytmp[i]=y[i]+b21*h*dydx[i];
00269       }
00270         
00271       error_update(ret,derivs(x+ah[0]*h,n,ytmp,k2,pa));
00272 
00273       for (i=0;i<n;i++) {
00274         ytmp[i]=y[i]+h*(b3[0]*dydx[i]+b3[1]*k2[i]);
00275       }
00276       
00277       error_update(ret,derivs(x+ah[1]*h,n,ytmp,k3,pa));
00278       
00279       for (i=0;i<n;i++) {
00280         ytmp[i]=y[i]+h*(b4[0]*dydx[i]+b4[2]*k3[i]);
00281       }
00282 
00283       error_update(ret,derivs(x+ah[2]*h,n,ytmp,k4,pa));
00284 
00285       for (i=0;i<n;i++) {
00286         ytmp[i]=y[i]+h*(b5[0]*dydx[i]+b5[2]*k3[i]+b5[3]*k4[i]);
00287       }
00288       
00289       error_update(ret,derivs(x+ah[3]*h,n,ytmp,k5,pa));
00290       
00291       for (i=0;i<n;i++) {
00292         ytmp[i]=y[i]+h*(b6[0]*dydx[i]+b6[3]*k4[i]+b6[4]*k5[i]);
00293       }
00294       
00295       error_update(ret,derivs(x+ah[4]*h,n,ytmp,k6,pa));
00296       
00297       for (i=0;i<n;i++) {
00298         ytmp[i]=y[i]+h*(b7[0]*dydx[i]+b7[3]*k4[i]+b7[4]*k5[i]+b7[5]*k6[i]);
00299       }
00300       
00301       error_update(ret,derivs(x+ah[5]*h,n,ytmp,k7,pa));
00302       
00303       for (i=0;i<n;i++) {
00304         ytmp[i]=y[i]+h*(b8[0]*dydx[i]+b8[3]*k4[i]+b8[4]*k5[i]+b8[5]*k6[i]+
00305                    b8[6]*k7[i]);
00306       }
00307 
00308       error_update(ret,derivs(x+ah[6]*h,n,ytmp,k8,pa));
00309       
00310       for (i=0;i<n;i++) {
00311         ytmp[i]=y[i]+h*(b9[0]*dydx[i]+b9[3]*k4[i]+b9[4]*k5[i]+b9[5]*k6[i]+
00312                    b9[6]*k7[i]+b9[7]*k8[i]);
00313       }
00314 
00315       error_update(ret,derivs(x+ah[7]*h,n,ytmp,k9,pa));
00316       
00317       for (i=0;i<n;i++) {
00318         ytmp[i]=y[i]+h*(b10[0]*dydx[i]+b10[3]*k4[i]+b10[4]*k5[i]+
00319                         b10[5]*k6[i]+b10[6]*k7[i]+b10[7]*k8[i]+
00320                         b10[8]*k9[i]);
00321       }
00322 
00323       error_update(ret,derivs(x+ah[8]*h,n,ytmp,k10,pa));
00324       
00325       for (i=0;i<n;i++) {
00326         ytmp[i]=y[i]+h*(b11[0]*dydx[i]+b11[3]*k4[i]+b11[4]*k5[i]+
00327                         b11[5]*k6[i]+b11[6]*k7[i]+b11[7]*k8[i]+
00328                         b11[8]*k9[i]+b11[9]*k10[i]);
00329       }
00330 
00331       error_update(ret,derivs(x+ah[9]*h,n,ytmp,k11,pa));
00332       
00333       for (i=0;i<n;i++) {
00334         ytmp[i]=y[i]+h*(b12[0]*dydx[i]+b12[3]*k4[i]+b12[4]*k5[i]+
00335                         b12[5]*k6[i]+b12[6]*k7[i]+b12[7]*k8[i]+
00336                         b12[8]*k9[i]+b12[9]*k10[i]+b12[10]*k11[i]);
00337       }
00338 
00339       error_update(ret,derivs(x+h,n,ytmp,k12,pa));
00340       
00341       for (i=0;i<n;i++) {
00342         ytmp[i]=y[i]+h*(b13[0]*dydx[i]+b13[3]*k4[i]+b13[4]*k5[i]+
00343                         b13[5]*k6[i]+b13[6]*k7[i]+b13[7]*k8[i]+
00344                         b13[8]*k9[i]+b13[9]*k10[i]+b13[10]*k11[i]+
00345                         b13[11]*k12[i]);
00346       }
00347 
00348       error_update(ret,derivs(x+h,n,ytmp,k13,pa));
00349 
00350       // final sum
00351 
00352       for (i=0;i<n;i++) {
00353         double ksum8=Abar[0]*dydx[i]+Abar[5]*k6[i]+Abar[6]*k7[i]+
00354           Abar[7]*k8[i]+Abar[8]*k9[i]+Abar[9]*k10[i]+
00355           Abar[10]*k11[i]+Abar[11]*k12[i]+Abar[12]*k13[i];
00356 
00357         yout[i]=y[i]+h*ksum8;
00358       }
00359       
00360       for (i=0;i<n;i++) {
00361 
00362         double ksum8=Abar[0]*dydx[i]+Abar[5]*k6[i]+Abar[6]*k7[i]+
00363           Abar[7]*k8[i]+Abar[8]*k9[i]+Abar[9]*k10[i]+
00364           Abar[10]*k11[i]+Abar[11]*k12[i]+Abar[12]*k13[i];
00365         double ksum7=A[0]*dydx[i]+A[5]*k6[i]+A[6]*k7[i]+A[7]*k8[i]+
00366           A[8]*k9[i]+A[9]*k10[i]+A[10]*k11[i]+A[11]*k12[i];
00367         
00368         yerr[i]=h*(ksum7-ksum8);
00369       }
00370       
00371       error_update(ret,derivs(x+h,n,yout,dydx_out,pa));
00372       
00373       return ret;
00374     }
00375     
00376   };
00377   
00378   /** 
00379       \brief Faster embedded Runge-Kutta Prince-Dormand ODE stepper 
00380       (GSL)
00381 
00382       This a fast version of \ref gsl_rk8pd, which is a stepper for a
00383       fixed number of ODEs. It ignores the error values returned by
00384       the \c derivs argument. The argument \c n to step() should
00385       always be equal to the template parameter \c N, and the vector
00386       parameters to step must have space allocated for at least \c N
00387       elements. No error checking is performed to ensure that this is
00388       the case.
00389   */
00390   template<size_t N, class param_t, class func_t, class vec_t, 
00391     class alloc_vec_t, class alloc_t> class gsl_rk8pd_fast : 
00392   public odestep<param_t,func_t,vec_t> {
00393     
00394   protected:
00395     
00396     /// \name Storage for the intermediate steps
00397     //@{
00398     alloc_vec_t k2, k3, k4, k5, k6, k7, ytmp;
00399     alloc_vec_t k8, k9, k10, k11, k12, k13;
00400     //@}
00401     
00402     /// Memory allocator for objects of type \c alloc_vec_t
00403     alloc_t ao;
00404 
00405     /** \name Storage for the coefficients
00406      */
00407     //@{
00408     double Abar[13], A[12], ah[10], b21, b3[2], b4[3], b5[4], b6[5];
00409     double b7[6], b8[7], b9[8], b10[9], b11[10], b12[11], b13[12];
00410     //@}
00411       
00412   public:
00413 
00414     gsl_rk8pd_fast() {
00415       this->order=8;
00416 
00417       Abar[0]=14005451.0/335480064.0;
00418       Abar[1]=0.0;
00419       Abar[2]=0.0;
00420       Abar[3]=0.0;
00421       Abar[4]=0.0;
00422       Abar[5]=-59238493.0/1068277825.0;
00423       Abar[6]=181606767.0/758867731.0;
00424       Abar[7]=561292985.0/797845732.0;
00425       Abar[8]=-1041891430.0/1371343529.0;
00426       Abar[9]=760417239.0/1151165299.0;
00427       Abar[10]=118820643.0/751138087.0;
00428       Abar[11]=-528747749.0/2220607170.0;
00429       Abar[12]=1.0/4.0;
00430 
00431       A[0]=13451932.0/455176623.0;
00432       A[1]=0.0;
00433       A[2]=0.0;
00434       A[3]=0.0;
00435       A[4]=0.0;
00436       A[5]=-808719846.0/976000145.0;
00437       A[6]=1757004468.0/5645159321.0;
00438       A[7]=656045339.0/265891186.0;
00439       A[8]=-3867574721.0/1518517206.0;
00440       A[9]=465885868.0/322736535.0;
00441       A[10]=53011238.0/667516719.0;
00442       A[11]=2.0/45.0;
00443 
00444       ah[0]=1.0/18.0;
00445       ah[1]=1.0/12.0;
00446       ah[2]=1.0/8.0;
00447       ah[3]=5.0/16.0;
00448       ah[4]=3.0/8.0;
00449       ah[5]=59.0/400.0;
00450       ah[6]=93.0/200.0;
00451       ah[7]=5490023248.0/9719169821.0;
00452       ah[8]=13.0/20.0;
00453       ah[9]=1201146811.0/1299019798.0;
00454       
00455       b21=1.0/18.0;
00456 
00457       b3[0]=1.0/48.0;
00458       b3[1]=1.0/16.0;
00459 
00460       b4[0]=1.0/32.0;
00461       b4[1]=0.0;
00462       b4[2]=3.0/32.0;
00463 
00464       b5[0]=5.0/16.0;
00465       b5[1]=0.0;
00466       b5[2]=-75.0/64.0;
00467       b5[3]=75.0/64.0;
00468 
00469       b6[0]=3.0/80.0;
00470       b6[1]=0.0;
00471       b6[2]=0.0;
00472       b6[3]=3.0/16.0;
00473       b6[4]=3.0/20.0;
00474 
00475       b7[0]=29443841.0/614563906.0;
00476       b7[1]=0.0;
00477       b7[2]=0.0;
00478       b7[3]=77736538.0/692538347.0;
00479       b7[4]=-28693883.0/1125000000.0;
00480       b7[5]=23124283.0/1800000000.0;
00481 
00482       b8[0]=16016141.0/946692911.0;
00483       b8[1]=0.0;
00484       b8[2]=0.0;
00485       b8[3]=61564180.0/158732637.0;
00486       b8[4]=22789713.0/633445777.0;
00487       b8[5]=545815736.0/2771057229.0;
00488       b8[6]=-180193667.0/1043307555.0;
00489 
00490       b9[0]=39632708.0/573591083.0;
00491       b9[1]=0.0;
00492       b9[2]=0.0;
00493       b9[3]=-433636366.0/683701615.0;
00494       b9[4]=-421739975.0/2616292301.0;
00495       b9[5]=100302831.0/723423059.0;
00496       b9[6]=790204164.0/839813087.0;
00497       b9[7]=800635310.0/3783071287.0;
00498 
00499       b10[0]=246121993.0/1340847787.0;
00500       b10[1]=0.0;
00501       b10[2]=0.0;
00502       b10[3]=-37695042795.0/15268766246.0;
00503       b10[4]=-309121744.0/1061227803.0;
00504       b10[5]=-12992083.0/490766935.0;
00505       b10[6]=6005943493.0/2108947869.0;
00506       b10[7]=393006217.0/1396673457.0;
00507       b10[8]=123872331.0/1001029789.0;
00508 
00509       b11[0]=-1028468189.0/846180014.0;
00510       b11[1]=0.0;
00511       b11[2]=0.0;
00512       b11[3]=8478235783.0/508512852.0;
00513       b11[4]=1311729495.0/1432422823.0;
00514       b11[5]=-10304129995.0/1701304382.0;
00515       b11[6]=-48777925059.0/3047939560.0;
00516       b11[7]=15336726248.0/1032824649.0;
00517       b11[8]=-45442868181.0/3398467696.0;
00518       b11[9]=3065993473.0/597172653.0;
00519 
00520       b12[0]=185892177.0/718116043.0;
00521       b12[1]=0.0;
00522       b12[2]=0.0;
00523       b12[3]=-3185094517.0/667107341.0;
00524       b12[4]=-477755414.0/1098053517.0;
00525       b12[5]=-703635378.0/230739211.0;
00526       b12[6]=5731566787.0/1027545527.0;
00527       b12[7]=5232866602.0/850066563.0;
00528       b12[8]=-4093664535.0/808688257.0;
00529       b12[9]=3962137247.0/1805957418.0;
00530       b12[10]=65686358.0/487910083.0;
00531 
00532       b13[0]=403863854.0/491063109.0;
00533       b13[1]=0.0;
00534       b13[2]=0.0;
00535       b13[3]=-5068492393.0/434740067.0;
00536       b13[4]=-411421997.0/543043805.0;
00537       b13[5]=652783627.0/914296604.0;
00538       b13[6]=11173962825.0/925320556.0;
00539       b13[7]=-13158990841.0/6184727034.0;
00540       b13[8]=3936647629.0/1978049680.0;
00541       b13[9]=-160528059.0/685178525.0;
00542       b13[10]=248638103.0/1413531060.0;
00543       b13[11]=0;
00544 
00545       ao.allocate(k2,N);
00546       ao.allocate(k3,N);
00547       ao.allocate(k4,N);
00548       ao.allocate(k5,N);
00549       ao.allocate(k6,N);
00550       ao.allocate(k7,N);
00551       ao.allocate(k8,N);
00552       ao.allocate(k9,N);
00553       ao.allocate(k10,N);
00554       ao.allocate(k11,N);
00555       ao.allocate(k12,N);
00556       ao.allocate(k13,N);
00557       ao.allocate(ytmp,N);
00558 
00559     }
00560       
00561     virtual ~gsl_rk8pd_fast() {
00562 
00563       ao.free(k2);
00564       ao.free(k3);
00565       ao.free(k4);
00566       ao.free(k5);
00567       ao.free(k6);
00568       ao.free(k7);
00569       ao.free(k8);
00570       ao.free(k9);
00571       ao.free(k10);
00572       ao.free(k11);
00573       ao.free(k12);
00574       ao.free(k13);
00575       ao.free(ytmp);
00576     }
00577 
00578     /** 
00579         \brief Perform an integration step
00580 
00581         Given initial value of the n-dimensional function in \c y and
00582         the derivative in \c dydx (which must generally be computed
00583         beforehand) at the point \c x, take a step of size \c h giving
00584         the result in \c yout, the uncertainty in \c yerr, and the new
00585         derivative in \c dydx_out using function \c derivs to
00586         calculate derivatives. The parameters \c yout and \c y and the
00587         parameters \c dydx_out and \c dydx may refer to the same
00588         object.
00589 
00590         \note The value of the parameter \c n should be equal to 
00591         the template parameter \c N.
00592     */
00593     virtual int step(double x, double h, size_t n, vec_t &y, vec_t &dydx, 
00594                      vec_t &yout, vec_t &yerr, vec_t &dydx_out, param_t &pa, 
00595                      func_t &derivs) {
00596       size_t i;
00597       
00598       for (i=0;i<N;i++) {
00599         ytmp[i]=y[i]+b21*h*dydx[i];
00600       }
00601         
00602       derivs(x+ah[0]*h,N,ytmp,k2,pa);
00603 
00604       for (i=0;i<N;i++) {
00605         ytmp[i]=y[i]+h*(b3[0]*dydx[i]+b3[1]*k2[i]);
00606       }
00607       
00608       derivs(x+ah[1]*h,N,ytmp,k3,pa);
00609       
00610       for (i=0;i<N;i++) {
00611         ytmp[i]=y[i]+h*(b4[0]*dydx[i]+b4[2]*k3[i]);
00612       }
00613 
00614       derivs(x+ah[2]*h,N,ytmp,k4,pa);
00615 
00616       for (i=0;i<N;i++) {
00617         ytmp[i]=y[i]+h*(b5[0]*dydx[i]+b5[2]*k3[i]+b5[3]*k4[i]);
00618       }
00619       
00620       derivs(x+ah[3]*h,N,ytmp,k5,pa);
00621       
00622       for (i=0;i<N;i++) {
00623         ytmp[i]=y[i]+h*(b6[0]*dydx[i]+b6[3]*k4[i]+b6[4]*k5[i]);
00624       }
00625       
00626       derivs(x+ah[4]*h,N,ytmp,k6,pa);
00627       
00628       for (i=0;i<N;i++) {
00629         ytmp[i]=y[i]+h*(b7[0]*dydx[i]+b7[3]*k4[i]+b7[4]*k5[i]+b7[5]*k6[i]);
00630       }
00631       
00632       derivs(x+ah[5]*h,N,ytmp,k7,pa);
00633       
00634       for (i=0;i<N;i++) {
00635         ytmp[i]=y[i]+h*(b8[0]*dydx[i]+b8[3]*k4[i]+b8[4]*k5[i]+b8[5]*k6[i]+
00636                         b8[6]*k7[i]);
00637       }
00638       
00639       derivs(x+ah[6]*h,N,ytmp,k8,pa);
00640       
00641       for (i=0;i<N;i++) {
00642         ytmp[i]=y[i]+h*(b9[0]*dydx[i]+b9[3]*k4[i]+b9[4]*k5[i]+b9[5]*k6[i]+
00643                         b9[6]*k7[i]+b9[7]*k8[i]);
00644       }
00645       
00646       derivs(x+ah[7]*h,N,ytmp,k9,pa);
00647       
00648       for (i=0;i<N;i++) {
00649         ytmp[i]=y[i]+h*(b10[0]*dydx[i]+b10[3]*k4[i]+b10[4]*k5[i]+
00650                         b10[5]*k6[i]+b10[6]*k7[i]+b10[7]*k8[i]+
00651                         b10[8]*k9[i]);
00652       }
00653 
00654       derivs(x+ah[8]*h,N,ytmp,k10,pa);
00655       
00656       for (i=0;i<N;i++) {
00657         ytmp[i]=y[i]+h*(b11[0]*dydx[i]+b11[3]*k4[i]+b11[4]*k5[i]+
00658                         b11[5]*k6[i]+b11[6]*k7[i]+b11[7]*k8[i]+
00659                         b11[8]*k9[i]+b11[9]*k10[i]);
00660       }
00661 
00662       derivs(x+ah[9]*h,N,ytmp,k11,pa);
00663       
00664       for (i=0;i<N;i++) {
00665         ytmp[i]=y[i]+h*(b12[0]*dydx[i]+b12[3]*k4[i]+b12[4]*k5[i]+
00666                         b12[5]*k6[i]+b12[6]*k7[i]+b12[7]*k8[i]+
00667                         b12[8]*k9[i]+b12[9]*k10[i]+b12[10]*k11[i]);
00668       }
00669       
00670       derivs(x+h,N,ytmp,k12,pa);
00671       
00672       for (i=0;i<N;i++) {
00673         ytmp[i]=y[i]+h*(b13[0]*dydx[i]+b13[3]*k4[i]+b13[4]*k5[i]+
00674                         b13[5]*k6[i]+b13[6]*k7[i]+b13[7]*k8[i]+
00675                         b13[8]*k9[i]+b13[9]*k10[i]+b13[10]*k11[i]+
00676                         b13[11]*k12[i]);
00677       }
00678 
00679       derivs(x+h,N,ytmp,k13,pa);
00680 
00681       // final sum
00682 
00683       for (i=0;i<N;i++) {
00684         double ksum8= Abar[0]*dydx[i]+Abar[5]*k6[i]+Abar[6]*k7[i]+
00685           Abar[7]*k8[i]+Abar[8]*k9[i]+Abar[9]*k10[i]+
00686           Abar[10]*k11[i]+Abar[11]*k12[i]+Abar[12]*k13[i];
00687 
00688         yout[i]=y[i]+h*ksum8;
00689       }
00690       
00691       for (i=0;i<N;i++) {
00692 
00693         double ksum8=Abar[0]*dydx[i]+Abar[5]*k6[i]+Abar[6]*k7[i]+
00694           Abar[7]*k8[i]+Abar[8]*k9[i]+Abar[9]*k10[i]+
00695           Abar[10]*k11[i]+Abar[11]*k12[i]+Abar[12]*k13[i];
00696         double ksum7=A[0]*dydx[i]+A[5]*k6[i]+A[6]*k7[i]+A[7]*k8[i]+
00697           A[8]*k9[i]+A[9]*k10[i]+A[10]*k11[i]+A[11]*k12[i];
00698         
00699         yerr[i]=h*(ksum7-ksum8);
00700       }
00701 
00702       derivs(x+h,N,yout,dydx_out,pa);
00703       
00704       return 0;
00705     }
00706     
00707   };
00708 
00709 #ifndef DOXYGENP
00710 }
00711 #endif
00712 
00713 #endif

Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.

Project hosting provided by SourceForge.net Logo, O2scl Sourceforge Project Page