template struct StepperDopr5 : StepperBase { typedef D Dtype; VecDoub k2,k3,k4,k5,k6; VecDoub rcont1,rcont2,rcont3,rcont4,rcont5; VecDoub dydxnew; StepperDopr5(VecDoub_IO &yy, VecDoub_IO &dydxx, Doub &xx, const Doub atoll, const Doub rtoll, bool dens); void step(const Doub htry,D &derivs); void dy(const Doub h,D &derivs); void prepare_dense(const Doub h,D &derivs); Doub dense_out(const Int i, const Doub x, const Doub h); Doub error(); struct Controller { Doub hnext,errold; bool reject; Controller(); bool success(const Doub err, Doub &h); }; Controller con; }; template StepperDopr5::StepperDopr5(VecDoub_IO &yy,VecDoub_IO &dydxx,Doub &xx, const Doub atoll,const Doub rtoll,bool dens) : StepperBase(yy,dydxx,xx,atoll,rtoll,dens), k2(n),k3(n),k4(n),k5(n),k6(n), rcont1(n),rcont2(n),rcont3(n),rcont4(n),rcont5(n),dydxnew(n) { EPS=numeric_limits::epsilon(); } template StepperDopr5::Controller::Controller() : reject(false), errold(1.0e-4) {} template bool StepperDopr5::Controller::success(const Doub err,Doub &h) { static const Doub beta=0.0,alpha=0.2-beta*0.75,safe=0.9,minscale=0.2, maxscale=10.0; Doub scale; if (err <= 1.0) { if (err == 0.0) scale=maxscale; else { scale=safe*pow(err,-alpha)*pow(errold,beta); if (scalemaxscale) scale=maxscale; } if (reject) hnext=h*MIN(scale,1.0); else hnext=h*scale; errold=MAX(err,1.0e-4); reject=false; return true; } else { scale=MAX(safe*pow(err,-alpha),minscale); h *= scale; reject=true; return false; } } template Doub StepperDopr5::dense_out(const Int i,const Doub x,const Doub h) { Doub s=(x-xold)/h; Doub s1=1.0-s; return rcont1[i]+s*(rcont2[i]+s1*(rcont3[i]+s*(rcont4[i]+s1*rcont5[i]))); } template void StepperDopr5::dy(const Doub h,D &derivs) { static const Doub c2=0.2,c3=0.3,c4=0.8,c5=8.0/9.0,a21=0.2,a31=3.0/40.0, a32=9.0/40.0,a41=44.0/45.0,a42=-56.0/15.0,a43=32.0/9.0,a51=19372.0/6561.0, a52=-25360.0/2187.0,a53=64448.0/6561.0,a54=-212.0/729.0,a61=9017.0/3168.0, a62=-355.0/33.0,a63=46732.0/5247.0,a64=49.0/176.0,a65=-5103.0/18656.0, a71=35.0/384.0,a73=500.0/1113.0,a74=125.0/192.0,a75=-2187.0/6784.0, a76=11.0/84.0,e1=71.0/57600.0,e3=-71.0/16695.0,e4=71.0/1920.0, e5=-17253.0/339200.0,e6=22.0/525.0,e7=-1.0/40.0; VecDoub ytemp(n); Int i; for (i=0;i Doub StepperDopr5::error() { Doub err=0.0,sk; for (Int i=0;i void StepperDopr5::prepare_dense(const Doub h,D &derivs) { VecDoub ytemp(n); static const Doub d1=-12715105075.0/11282082432.0, d3=87487479700.0/32700410799.0, d4=-10690763975.0/1880347072.0, d5=701980252875.0/199316789632.0, d6=-1453857185.0/822651844.0, d7=69997945.0/29380423.0; for (Int i=0;i void StepperDopr5::step(const Doub htry,D &derivs) { Doub h=htry; for (;;) { dy(h,derivs); Doub err=error(); if (con.success(err,h)) break; if (abs(h) <= abs(x)*EPS) throw("stepsize underflow in StepperDopr5"); } if (dense) prepare_dense(h,derivs); dydx=dydxnew; y=yout; xold=x; x += (hdid=h); hnext=con.hnext; }