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