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