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

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).

Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads.