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 Cash-Karp embedded Runge-Kutta formula (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   /** \brief Cash-Karp embedded Runge-Kutta formula (GSL) without
00379       memory allocation and error checking
00380 
00381       This a fast version of \ref gsl_rk8pd, which is a stepper for a
00382       fixed number of ODEs. It ignores the error values returned by
00383       the \c derivs argument. The argument \c n to step() must always
00384       be equal to the template parameter \c N, and the vector
00385       parameters to step must have space allocated for at least \c N
00386       elements. No error checking is performed to ensure that this is
00387       the case.
00388   */
00389   template<size_t N, class param_t, class func_t, class vec_t, 
00390     class alloc_vec_t, class alloc_t> class gsl_rk8pd_fast : 
00391   public odestep<param_t,func_t,vec_t> {
00392     
00393   protected:
00394     
00395     /// \name Storage for the intermediate steps
00396     //@{
00397     alloc_vec_t k2, k3, k4, k5, k6, k7, ytmp;
00398     alloc_vec_t k8, k9, k10, k11, k12, k13;
00399     //@}
00400     
00401     /// Memory allocator for objects of type \c alloc_vec_t
00402     alloc_t ao;
00403 
00404     /** \name Storage for the coefficients
00405      */
00406     //@{
00407     double Abar[13], A[12], ah[10], b21, b3[2], b4[3], b5[4], b6[5];
00408     double b7[6], b8[7], b9[8], b10[9], b11[10], b12[11], b13[12];
00409     //@}
00410       
00411   public:
00412 
00413     gsl_rk8pd_fast() {
00414       this->order=8;
00415 
00416       Abar[0]=14005451.0/335480064.0;
00417       Abar[1]=0.0;
00418       Abar[2]=0.0;
00419       Abar[3]=0.0;
00420       Abar[4]=0.0;
00421       Abar[5]=-59238493.0/1068277825.0;
00422       Abar[6]=181606767.0/758867731.0;
00423       Abar[7]=561292985.0/797845732.0;
00424       Abar[8]=-1041891430.0/1371343529.0;
00425       Abar[9]=760417239.0/1151165299.0;
00426       Abar[10]=118820643.0/751138087.0;
00427       Abar[11]=-528747749.0/2220607170.0;
00428       Abar[12]=1.0/4.0;
00429 
00430       A[0]=13451932.0/455176623.0;
00431       A[1]=0.0;
00432       A[2]=0.0;
00433       A[3]=0.0;
00434       A[4]=0.0;
00435       A[5]=-808719846.0/976000145.0;
00436       A[6]=1757004468.0/5645159321.0;
00437       A[7]=656045339.0/265891186.0;
00438       A[8]=-3867574721.0/1518517206.0;
00439       A[9]=465885868.0/322736535.0;
00440       A[10]=53011238.0/667516719.0;
00441       A[11]=2.0/45.0;
00442 
00443       ah[0]=1.0/18.0;
00444       ah[1]=1.0/12.0;
00445       ah[2]=1.0/8.0;
00446       ah[3]=5.0/16.0;
00447       ah[4]=3.0/8.0;
00448       ah[5]=59.0/400.0;
00449       ah[6]=93.0/200.0;
00450       ah[7]=5490023248.0/9719169821.0;
00451       ah[8]=13.0/20.0;
00452       ah[9]=1201146811.0/1299019798.0;
00453       
00454       b21=1.0/18.0;
00455 
00456       b3[0]=1.0/48.0;
00457       b3[1]=1.0/16.0;
00458 
00459       b4[0]=1.0/32.0;
00460       b4[1]=0.0;
00461       b4[2]=3.0/32.0;
00462 
00463       b5[0]=5.0/16.0;
00464       b5[1]=0.0;
00465       b5[2]=-75.0/64.0;
00466       b5[3]=75.0/64.0;
00467 
00468       b6[0]=3.0/80.0;
00469       b6[1]=0.0;
00470       b6[2]=0.0;
00471       b6[3]=3.0/16.0;
00472       b6[4]=3.0/20.0;
00473 
00474       b7[0]=29443841.0/614563906.0;
00475       b7[1]=0.0;
00476       b7[2]=0.0;
00477       b7[3]=77736538.0/692538347.0;
00478       b7[4]=-28693883.0/1125000000.0;
00479       b7[5]=23124283.0/1800000000.0;
00480 
00481       b8[0]=16016141.0/946692911.0;
00482       b8[1]=0.0;
00483       b8[2]=0.0;
00484       b8[3]=61564180.0/158732637.0;
00485       b8[4]=22789713.0/633445777.0;
00486       b8[5]=545815736.0/2771057229.0;
00487       b8[6]=-180193667.0/1043307555.0;
00488 
00489       b9[0]=39632708.0/573591083.0;
00490       b9[1]=0.0;
00491       b9[2]=0.0;
00492       b9[3]=-433636366.0/683701615.0;
00493       b9[4]=-421739975.0/2616292301.0;
00494       b9[5]=100302831.0/723423059.0;
00495       b9[6]=790204164.0/839813087.0;
00496       b9[7]=800635310.0/3783071287.0;
00497 
00498       b10[0]=246121993.0/1340847787.0;
00499       b10[1]=0.0;
00500       b10[2]=0.0;
00501       b10[3]=-37695042795.0/15268766246.0;
00502       b10[4]=-309121744.0/1061227803.0;
00503       b10[5]=-12992083.0/490766935.0;
00504       b10[6]=6005943493.0/2108947869.0;
00505       b10[7]=393006217.0/1396673457.0;
00506       b10[8]=123872331.0/1001029789.0;
00507 
00508       b11[0]=-1028468189.0/846180014.0;
00509       b11[1]=0.0;
00510       b11[2]=0.0;
00511       b11[3]=8478235783.0/508512852.0;
00512       b11[4]=1311729495.0/1432422823.0;
00513       b11[5]=-10304129995.0/1701304382.0;
00514       b11[6]=-48777925059.0/3047939560.0;
00515       b11[7]=15336726248.0/1032824649.0;
00516       b11[8]=-45442868181.0/3398467696.0;
00517       b11[9]=3065993473.0/597172653.0;
00518 
00519       b12[0]=185892177.0/718116043.0;
00520       b12[1]=0.0;
00521       b12[2]=0.0;
00522       b12[3]=-3185094517.0/667107341.0;
00523       b12[4]=-477755414.0/1098053517.0;
00524       b12[5]=-703635378.0/230739211.0;
00525       b12[6]=5731566787.0/1027545527.0;
00526       b12[7]=5232866602.0/850066563.0;
00527       b12[8]=-4093664535.0/808688257.0;
00528       b12[9]=3962137247.0/1805957418.0;
00529       b12[10]=65686358.0/487910083.0;
00530 
00531       b13[0]=403863854.0/491063109.0;
00532       b13[1]=0.0;
00533       b13[2]=0.0;
00534       b13[3]=-5068492393.0/434740067.0;
00535       b13[4]=-411421997.0/543043805.0;
00536       b13[5]=652783627.0/914296604.0;
00537       b13[6]=11173962825.0/925320556.0;
00538       b13[7]=-13158990841.0/6184727034.0;
00539       b13[8]=3936647629.0/1978049680.0;
00540       b13[9]=-160528059.0/685178525.0;
00541       b13[10]=248638103.0/1413531060.0;
00542       b13[11]=0;
00543 
00544       ao.allocate(k2,N);
00545       ao.allocate(k3,N);
00546       ao.allocate(k4,N);
00547       ao.allocate(k5,N);
00548       ao.allocate(k6,N);
00549       ao.allocate(k7,N);
00550       ao.allocate(k8,N);
00551       ao.allocate(k9,N);
00552       ao.allocate(k10,N);
00553       ao.allocate(k11,N);
00554       ao.allocate(k12,N);
00555       ao.allocate(k13,N);
00556       ao.allocate(ytmp,N);
00557 
00558     }
00559       
00560     virtual ~gsl_rk8pd_fast() {
00561 
00562       ao.free(k2);
00563       ao.free(k3);
00564       ao.free(k4);
00565       ao.free(k5);
00566       ao.free(k6);
00567       ao.free(k7);
00568       ao.free(k8);
00569       ao.free(k9);
00570       ao.free(k10);
00571       ao.free(k11);
00572       ao.free(k12);
00573       ao.free(k13);
00574       ao.free(ytmp);
00575     }
00576 
00577     /** 
00578         \brief Perform an integration step
00579 
00580         Given initial value of the n-dimensional function in \c y and
00581         the derivative in \c dydx (which must generally be computed
00582         beforehand) at the point \c x, take a step of size \c h giving
00583         the result in \c yout, the uncertainty in \c yerr, and the new
00584         derivative in \c dydx_out using function \c derivs to
00585         calculate derivatives. The parameters \c yout and \c y and the
00586         parameters \c dydx_out and \c dydx may refer to the same
00587         object.
00588 
00589         \note The value of the parameter \c n must be equal to 
00590         the template parameter \c N.
00591     */
00592     virtual int step(double x, double h, size_t n, vec_t &y, vec_t &dydx, 
00593                      vec_t &yout, vec_t &yerr, vec_t &dydx_out, param_t &pa, 
00594                      func_t &derivs) {
00595       size_t i;
00596       
00597       for (i=0;i<N;i++) {
00598         ytmp[i]=y[i]+b21*h*dydx[i];
00599       }
00600         
00601       derivs(x+ah[0]*h,N,ytmp,k2,pa);
00602 
00603       for (i=0;i<N;i++) {
00604         ytmp[i]=y[i]+h*(b3[0]*dydx[i]+b3[1]*k2[i]);
00605       }
00606       
00607       derivs(x+ah[1]*h,N,ytmp,k3,pa);
00608       
00609       for (i=0;i<N;i++) {
00610         ytmp[i]=y[i]+h*(b4[0]*dydx[i]+b4[2]*k3[i]);
00611       }
00612 
00613       derivs(x+ah[2]*h,N,ytmp,k4,pa);
00614 
00615       for (i=0;i<N;i++) {
00616         ytmp[i]=y[i]+h*(b5[0]*dydx[i]+b5[2]*k3[i]+b5[3]*k4[i]);
00617       }
00618       
00619       derivs(x+ah[3]*h,N,ytmp,k5,pa);
00620       
00621       for (i=0;i<N;i++) {
00622         ytmp[i]=y[i]+h*(b6[0]*dydx[i]+b6[3]*k4[i]+b6[4]*k5[i]);
00623       }
00624       
00625       derivs(x+ah[4]*h,N,ytmp,k6,pa);
00626       
00627       for (i=0;i<N;i++) {
00628         ytmp[i]=y[i]+h*(b7[0]*dydx[i]+b7[3]*k4[i]+b7[4]*k5[i]+b7[5]*k6[i]);
00629       }
00630       
00631       derivs(x+ah[5]*h,N,ytmp,k7,pa);
00632       
00633       for (i=0;i<N;i++) {
00634         ytmp[i]=y[i]+h*(b8[0]*dydx[i]+b8[3]*k4[i]+b8[4]*k5[i]+b8[5]*k6[i]+
00635                         b8[6]*k7[i]);
00636       }
00637       
00638       derivs(x+ah[6]*h,N,ytmp,k8,pa);
00639       
00640       for (i=0;i<N;i++) {
00641         ytmp[i]=y[i]+h*(b9[0]*dydx[i]+b9[3]*k4[i]+b9[4]*k5[i]+b9[5]*k6[i]+
00642                         b9[6]*k7[i]+b9[7]*k8[i]);
00643       }
00644       
00645       derivs(x+ah[7]*h,N,ytmp,k9,pa);
00646       
00647       for (i=0;i<N;i++) {
00648         ytmp[i]=y[i]+h*(b10[0]*dydx[i]+b10[3]*k4[i]+b10[4]*k5[i]+
00649                         b10[5]*k6[i]+b10[6]*k7[i]+b10[7]*k8[i]+
00650                         b10[8]*k9[i]);
00651       }
00652 
00653       derivs(x+ah[8]*h,N,ytmp,k10,pa);
00654       
00655       for (i=0;i<N;i++) {
00656         ytmp[i]=y[i]+h*(b11[0]*dydx[i]+b11[3]*k4[i]+b11[4]*k5[i]+
00657                         b11[5]*k6[i]+b11[6]*k7[i]+b11[7]*k8[i]+
00658                         b11[8]*k9[i]+b11[9]*k10[i]);
00659       }
00660 
00661       derivs(x+ah[9]*h,N,ytmp,k11,pa);
00662       
00663       for (i=0;i<N;i++) {
00664         ytmp[i]=y[i]+h*(b12[0]*dydx[i]+b12[3]*k4[i]+b12[4]*k5[i]+
00665                         b12[5]*k6[i]+b12[6]*k7[i]+b12[7]*k8[i]+
00666                         b12[8]*k9[i]+b12[9]*k10[i]+b12[10]*k11[i]);
00667       }
00668       
00669       derivs(x+h,N,ytmp,k12,pa);
00670       
00671       for (i=0;i<N;i++) {
00672         ytmp[i]=y[i]+h*(b13[0]*dydx[i]+b13[3]*k4[i]+b13[4]*k5[i]+
00673                         b13[5]*k6[i]+b13[6]*k7[i]+b13[7]*k8[i]+
00674                         b13[8]*k9[i]+b13[9]*k10[i]+b13[10]*k11[i]+
00675                         b13[11]*k12[i]);
00676       }
00677 
00678       derivs(x+h,N,ytmp,k13,pa);
00679 
00680       // final sum
00681 
00682       for (i=0;i<N;i++) {
00683         double ksum8= Abar[0]*dydx[i]+Abar[5]*k6[i]+Abar[6]*k7[i]+
00684           Abar[7]*k8[i]+Abar[8]*k9[i]+Abar[9]*k10[i]+
00685           Abar[10]*k11[i]+Abar[11]*k12[i]+Abar[12]*k13[i];
00686 
00687         yout[i]=y[i]+h*ksum8;
00688       }
00689       
00690       for (i=0;i<N;i++) {
00691 
00692         double ksum8=Abar[0]*dydx[i]+Abar[5]*k6[i]+Abar[6]*k7[i]+
00693           Abar[7]*k8[i]+Abar[8]*k9[i]+Abar[9]*k10[i]+
00694           Abar[10]*k11[i]+Abar[11]*k12[i]+Abar[12]*k13[i];
00695         double ksum7=A[0]*dydx[i]+A[5]*k6[i]+A[6]*k7[i]+A[7]*k8[i]+
00696           A[8]*k9[i]+A[9]*k10[i]+A[10]*k11[i]+A[11]*k12[i];
00697         
00698         yerr[i]=h*(ksum7-ksum8);
00699       }
00700 
00701       derivs(x+h,N,yout,dydx_out,pa);
00702       
00703       return 0;
00704     }
00705     
00706   };
00707 
00708 #ifndef DOXYGENP
00709 }
00710 #endif
00711 
00712 #endif

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