10 template <
class functor>
12 double& hdid,
double& hnext, functor& derivs){
14 container yerr(y.size()), ytemp(y.size());
18 RKTry(y, dydx, x, h, ytemp, yerr, derivs);
21 for (
int i=0; i<y.size(); i++) errmax=std::max(errmax, fabs(yerr[i]/
yscal[i]));
24 if (errmax <= 1.1)
break;
27 if ((x+h) == x) std::cerr<<
"stepsize underflow in rkqs"<<std::endl;
29 if (errmax < 0.5) hnext=h*fmin(
SAFETY*pow(errmax,
PGROW), 5);
34 for (
int i=0; i<y.size();i++) y[i] = ytemp[i];
42 template <
class functor>
46 static constexpr
double as[] = {0, 0.2, 0.3, 0.6, 1.0, 0.875};
48 static constexpr
double cs[] = {37.0/378.0, 0.0, 250.0/621.0, 125.0/594.0, 0.0, 512.0/1771.0};
50 static constexpr
double dc[] = {cs[0]-2825.0/27648.0, 0.0, cs[2]-18575.0/48384.0, cs[3]-13525.0/55296.0, -277.00/14336.0, cs[5]-0.25};
51 static constexpr
double bs[6][6] =
52 {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
53 {0.2, 0.0, 0.0, 0.0, 0.0, 0.0},
54 {3.0/40.0, 9.0/40.0, 0.0, 0.0, 0.0, 0.0},
55 {0.3, -0.9, 1.2, 0.0, 0.0, 0.0},
56 {-11.0/54.0, 2.5, -70.0/27.0, 35.0/27.0, 0.0, 0.0},
57 {1631.0/55296.0, 175.0/512.0, 575.0/13824.0, 44275.0/110592.0, 253.0/4096.0, 0.0}};
64 for (
int i=0; i<N; i++)
yt[i] = y[i] + h*bs[1][0]*k0[i];
65 derivs(x+as[1]*h,
yt.begin(),
k1.begin(),
nullptr);
69 for (
int i=0; i<N; i++)
yt[i] = y[i] + h*(bs[2][0]*k0[i]+bs[2][1]*
k1[i]);
70 derivs(x+as[2]*h,
yt.begin(),
k2.begin(),
nullptr);
74 for (
int i=0; i<N; i++)
yt[i] = y[i] + h*(bs[3][0]*k0[i]+bs[3][1]*
k1[i]+bs[3][2]*
k2[i]);
75 derivs(x+as[3]*h,
yt.begin(),
k3.begin(),
nullptr);
79 for (
int i=0; i<N; i++)
yt[i] = y[i] + h*(bs[4][0]*k0[i]+bs[4][1]*
k1[i]+bs[4][2]*
k2[i]+bs[4][3]*
k3[i]);
80 derivs(x+as[4]*h,
yt.begin(),
k4.begin(),
nullptr);
84 for (
int i=0;i<N;i++)
yt[i] = y[i] + h*(bs[5][0]*k0[i]+bs[5][1]*
k1[i]+bs[5][2]*
k2[i]+bs[5][3]*
k3[i]+bs[5][4]*
k4[i]);
85 derivs(x+as[5]*h,
yt.begin(),
k5.begin(),
nullptr);
90 for (
int i=0;i<N;i++) yout[i] = y[i] + h*(cs[0]*k0[i]+cs[2]*
k2[i]+cs[3]*
k3[i]+cs[5]*
k5[i]);
93 for (
int i=0; i<N; i++) yerr[i] = h*(dc[0]*dydx[i]+dc[2]*
k2[i]+dc[3]*
k3[i]+dc[4]*
k4[i]+dc[5]*
k5[i]);
102 template <
class functor>
110 derivs(
xt,y.begin(),
dydx.begin(),
nullptr);
118 ht = std::min(ht, hmax);
119 ht = std::max(ht, hmin);
121 if (hdid == ht) ++
nok;
else ++
nbad;
148 template <
class functor,
class AfterStep>
151 Step(x,y,derivs, t_stop-x);
152 after_step(x, y.begin());
static constexpr double PGROW
void RKStep(container &y, container &dydx, double &x, double htry, double &hdid, double &hnext, functor &derivs)
void resize(int new_size)
static constexpr double PSHRNK
static constexpr double SAFETY
void Step_to(double t_stop, double &x, container &y, functor &derivs, AfterStep &after_step)
void Step(double &x, container &y, functor &derivs, double hmax=1e20, double hmin=1e-6)
void RKTry(container &y, container &dydx, double &x, double h, container &yout, container &yerr, functor &derivs)
std::vector< double > container