#include #include "nr.h" using namespace std; Vec_DP *x_p; Mat_DP *d_p; void NR::stifbs(Vec_IO_DP &y, Vec_IO_DP &dydx, DP &xx, const DP htry, const DP eps, Vec_I_DP &yscal, DP &hdid, DP &hnext, void derivs(const DP, Vec_I_DP &, Vec_O_DP &)) { const int KMAXX=7,IMAXX=KMAXX+1; const DP SAFE1=0.25,SAFE2=0.7,REDMAX=1.0e-5,REDMIN=0.7; const DP TINY=1.0e-30,SCALMX=0.1; bool exitflag=false; int i,iq,k,kk,km,reduct; static int first=1,kmax,kopt,nvold = -1; DP eps1,errmax,fact,h,red,scale,work,wrkmin,xest; static DP epsold = -1.0,xnew; static Vec_DP a(IMAXX); static Mat_DP alf(KMAXX,KMAXX); static int nseq_d[IMAXX]={2,6,10,14,22,34,50,70}; Vec_INT nseq(nseq_d,IMAXX); int nv=y.size(); d_p=new Mat_DP(nv,KMAXX); x_p=new Vec_DP(KMAXX); Vec_DP dfdx(nv),err(KMAXX),yerr(nv),ysav(nv),yseq(nv); Mat_DP dfdy(nv,nv); if (eps != epsold || nv != nvold) { hnext = xnew = -1.0e29; eps1=SAFE1*eps; a[0]=nseq[0]+1; for (k=0;k a[kopt]*alf[kopt-1][kopt]) break; kmax=kopt; } h=htry; for (i=0;i= kopt-1 || first)) { if (errmax < 1.0) { exitflag=true; break; } if (k == kmax || k == kopt+1) { red=SAFE2/err[km]; break; } else if (k == kopt && alf[kopt-1][kopt] < err[km]) { red=1.0/err[km]; break; } else if (kopt == kmax && alf[km][kmax-1] < err[km]) { red=alf[km][kmax-1]*SAFE2/err[km]; break; } else if (alf[km][kopt] < err[km]) { red=alf[km][kopt-1]/err[km]; break; } } } if (exitflag) break; red=MIN(red,REDMIN); red=MAX(red,REDMAX); h *= red; reduct=1; } xx=xnew; hdid=h; first=0; wrkmin=1.0e35; for (kk=0;kk<=km;kk++) { fact=MAX(err[kk],SCALMX); work=fact*a[kk+1]; if (work < wrkmin) { scale=fact; wrkmin=work; kopt=kk+1; } } hnext=h/scale; if (kopt >= k && kopt != kmax && !reduct) { fact=MAX(scale/alf[kopt-1][kopt],SCALMX); if (a[kopt+1]*fact <= wrkmin) { hnext=h/fact; kopt++; } } delete d_p; delete x_p; }