00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef O2SCL_GSL_RKCK_H
00025 #define O2SCL_GSL_RKCK_H
00026
00027 #include <o2scl/err_hnd.h>
00028 #include <o2scl/odestep.h>
00029
00030 #ifndef DOXYGENP
00031 namespace o2scl {
00032 #endif
00033
00034
00035
00036 template<class param_t, class func_t, class vec_t=ovector_view,
00037 class alloc_vec_t=ovector, class alloc_t=ovector_alloc> class gsl_rkck :
00038 public odestep<param_t,func_t,vec_t> {
00039
00040 protected:
00041
00042
00043
00044 alloc_vec_t k2, k3, k4, k5, k6, ytmp;
00045
00046
00047
00048 size_t ndim;
00049
00050
00051 alloc_t ao;
00052
00053
00054
00055
00056 double ah[5], b3[2], b4[3], b5[4], b6[5], ec[7];
00057 double b21, c1, c3, c4, c6;
00058
00059
00060 public:
00061
00062 gsl_rkck() {
00063 this->order=5;
00064
00065 ah[0]=1.0/5.0;
00066 ah[1]=3.0/10.0;
00067 ah[2]=3.0/5.0;
00068 ah[3]=1.0;
00069 ah[4]=7.0/8.0;
00070 b3[0]=3.0/40.0;
00071 b3[1]=9.0/40.0;
00072 b4[0]=3.0/10.0;
00073 b4[1]=-9.0/10.0;
00074 b4[2]=12.0/10.0;
00075 b5[0]=-11.0/54.0;
00076 b5[1]=5.0/2.0;
00077 b5[2]=-70.0/27.0;
00078 b5[3]=35.0/27.0;
00079 b6[0]=1631.0/55296.0;
00080 b6[1]=175.0/512.0;
00081 b6[2]=575.0/13824.0;
00082 b6[3]=44275.0/110592.0;
00083 b6[4]=253.0/4096.0;
00084 ec[0]=0.0;
00085 ec[1]=37.0/378.0-2825.0/27648.0;
00086 ec[2]=0.0;
00087 ec[3]=250.0/621.0-18575.0/48384.0;
00088 ec[4]=125.0/594.0-13525.0/55296.0;
00089 ec[5]=-277.0/14336.0;
00090 ec[6]=512.0/1771.0-1.0/4.0;
00091
00092 b21=1.0/5.0;
00093 c1=37.0/378.0;
00094 c3=250.0/621.0;
00095 c4=125.0/594.0;
00096 c6=512.0/1771.0;
00097
00098 ndim=0;
00099 }
00100
00101 virtual ~gsl_rkck() {
00102 if (ndim!=0) {
00103 ao.free(k2);
00104 ao.free(k3);
00105 ao.free(k4);
00106 ao.free(k5);
00107 ao.free(k6);
00108 ao.free(ytmp);
00109 }
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 virtual int step(double x, double h, size_t n, vec_t &y, vec_t &dydx,
00125 vec_t &yout, vec_t &yerr, vec_t &dydx_out, param_t &pa,
00126 func_t &derivs) {
00127
00128 int ret=0;
00129 size_t i;
00130
00131 if (ndim!=n) {
00132 if (ndim>0) {
00133 ao.free(k2);
00134 ao.free(k3);
00135 ao.free(k4);
00136 ao.free(k5);
00137 ao.free(k6);
00138 ao.free(ytmp);
00139 }
00140 ao.allocate(k2,n);
00141 ao.allocate(k3,n);
00142 ao.allocate(k4,n);
00143 ao.allocate(k5,n);
00144 ao.allocate(k6,n);
00145 ao.allocate(ytmp,n);
00146
00147 ndim=n;
00148 }
00149
00150 for (i=0;i<n;i++) {
00151 ytmp[i]=y[i]+b21*h*dydx[i];
00152 }
00153
00154 o2scl::error_update(ret,derivs(x+ah[0]*h,n,ytmp,k2,pa));
00155
00156 for (i=0;i<n;i++) {
00157 ytmp[i]=y[i]+h*(b3[0]*dydx[i]+b3[1]*k2[i]);
00158 }
00159
00160 o2scl::error_update(ret,derivs(x+ah[1]*h,n,ytmp,k3,pa));
00161
00162 for (i=0;i<n;i++) {
00163 ytmp[i]=y[i]+h*(b4[0]*dydx[i]+b4[1]*k2[i]+b4[2]*k3[i]);
00164 }
00165
00166 o2scl::error_update(ret,derivs(x+ah[2]*h,n,ytmp,k4,pa));
00167
00168 for (i=0;i<n;i++) {
00169 ytmp[i]=y[i]+h*(b5[0]*dydx[i]+b5[1]*k2[i]+b5[2]*k3[i]+
00170 b5[3]*k4[i]);
00171 }
00172
00173 o2scl::error_update(ret,derivs(x+ah[3]*h,n,ytmp,k5,pa));
00174
00175 for (i=0;i<n;i++) {
00176 ytmp[i]=y[i]+h*(b6[0]*dydx[i]+b6[1]*k2[i]+b6[2]*k3[i]+
00177 b6[3]*k4[i]+b6[4]*k5[i]);
00178 }
00179
00180 o2scl::error_update(ret,derivs(x+ah[4]*h,n,ytmp,k6,pa));
00181
00182 for (i=0;i<n;i++) {
00183 yerr[i]=h*(ec[1]*dydx[i]+ec[3]*k3[i]+ec[4]*k4[i]+ec[5]*k5[i]+
00184 ec[6]*k6[i]);
00185 }
00186
00187 for (i=0;i<n;i++) {
00188 dydx_out[i]=c1*dydx[i]+c3*k3[i]+c4*k4[i]+c6*k6[i];
00189
00190 yout[i]=y[i]+h*dydx_out[i];
00191 }
00192
00193 return ret;
00194 }
00195
00196 };
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 template<size_t N, class param_t, class func_t, class vec_t=ovector_view,
00210 class alloc_vec_t=ovector, class alloc_t=ovector_alloc>
00211 class gsl_rkck_fast :
00212 public odestep<param_t,func_t,vec_t> {
00213
00214 protected:
00215
00216
00217
00218 alloc_vec_t k2, k3, k4, k5, k6, ytmp;
00219
00220
00221
00222 alloc_t ao;
00223
00224
00225
00226
00227 double ah[5], b3[2], b4[3], b5[4], b6[5], ec[7];
00228 double b21, c1, c3, c4, c6;
00229
00230
00231 public:
00232
00233 gsl_rkck_fast() {
00234 this->order=5;
00235
00236 ah[0]=1.0/5.0;
00237 ah[1]=3.0/10.0;
00238 ah[2]=3.0/5.0;
00239 ah[3]=1.0;
00240 ah[4]=7.0/8.0;
00241 b3[0]=3.0/40.0;
00242 b3[1]=9.0/40.0;
00243 b4[0]=3.0/10.0;
00244 b4[1]=-9.0/10.0;
00245 b4[2]=12.0/10.0;
00246 b5[0]=-11.0/54.0;
00247 b5[1]=5.0/2.0;
00248 b5[2]=-70.0/27.0;
00249 b5[3]=35.0/27.0;
00250 b6[0]=1631.0/55296.0;
00251 b6[1]=175.0/512.0;
00252 b6[2]=575.0/13824.0;
00253 b6[3]=44275.0/110592.0;
00254 b6[4]=253.0/4096.0;
00255 ec[0]=0.0;
00256 ec[1]=37.0/378.0-2825.0/27648.0;
00257 ec[2]=0.0;
00258 ec[3]=250.0/621.0-18575.0/48384.0;
00259 ec[4]=125.0/594.0-13525.0/55296.0;
00260 ec[5]=-277.0/14336.0;
00261 ec[6]=512.0/1771.0-1.0/4.0;
00262
00263 b21=1.0/5.0;
00264 c1=37.0/378.0;
00265 c3=250.0/621.0;
00266 c4=125.0/594.0;
00267 c6=512.0/1771.0;
00268
00269 ao.allocate(k2,N);
00270 ao.allocate(k3,N);
00271 ao.allocate(k4,N);
00272 ao.allocate(k5,N);
00273 ao.allocate(k6,N);
00274 ao.allocate(ytmp,N);
00275
00276 }
00277
00278 virtual ~gsl_rkck_fast() {
00279
00280 ao.free(k2);
00281 ao.free(k3);
00282 ao.free(k4);
00283 ao.free(k5);
00284 ao.free(k6);
00285 ao.free(ytmp);
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 virtual int step(double x, double h, size_t n, vec_t &y, vec_t &dydx,
00304 vec_t &yout, vec_t &yerr, vec_t &dydx_out, param_t &pa,
00305 func_t &derivs) {
00306
00307 size_t i;
00308
00309 for (i=0;i<N;i++) {
00310 ytmp[i]=y[i]+b21*h*dydx[i];
00311 }
00312
00313 derivs(x+ah[0]*h,N,ytmp,k2,pa);
00314
00315 for (i=0;i<N;i++) {
00316 ytmp[i]=y[i]+h*(b3[0]*dydx[i]+b3[1]*k2[i]);
00317 }
00318
00319 derivs(x+ah[1]*h,N,ytmp,k3,pa);
00320
00321 for (i=0;i<N;i++) {
00322 ytmp[i]=y[i]+h*(b4[0]*dydx[i]+b4[1]*k2[i]+b4[2]*k3[i]);
00323 }
00324
00325 derivs(x+ah[2]*h,N,ytmp,k4,pa);
00326
00327 for (i=0;i<N;i++) {
00328 ytmp[i]=y[i]+h*(b5[0]*dydx[i]+b5[1]*k2[i]+b5[2]*k3[i]+
00329 b5[3]*k4[i]);
00330 }
00331
00332 derivs(x+ah[3]*h,N,ytmp,k5,pa);
00333
00334 for (i=0;i<N;i++) {
00335 ytmp[i]=y[i]+h*(b6[0]*dydx[i]+b6[1]*k2[i]+b6[2]*k3[i]+
00336 b6[3]*k4[i]+b6[4]*k5[i]);
00337 }
00338
00339 derivs(x+ah[4]*h,N,ytmp,k6,pa);
00340
00341 for (i=0;i<N;i++) {
00342 yerr[i]=h*(ec[1]*dydx[i]+ec[3]*k3[i]+ec[4]*k4[i]+ec[5]*k5[i]+
00343 ec[6]*k6[i]);
00344 }
00345
00346 for (i=0;i<N;i++) {
00347 dydx_out[i]=c1*dydx[i]+c3*k3[i]+c4*k4[i]+c6*k6[i];
00348 yout[i]=y[i]+h*dydx_out[i];
00349 }
00350
00351 return 0;
00352 }
00353
00354 };
00355
00356 #ifndef DOXYGENP
00357 }
00358 #endif
00359
00360 #endif