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