![]() |
Object-oriented Scientific Computing Library: Version 0.910
|
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
Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).