#include #include #include "nr.h" using namespace std; namespace { inline void shft3(DP &a, DP &b, DP &c, const DP d) { a=b; b=c; c=d; } } DP NR::brent(const DP ax, const DP bx, const DP cx, DP f(const DP), const DP tol, DP &xmin) { const int ITMAX=100; const DP CGOLD=0.3819660; const DP ZEPS=numeric_limits::epsilon()*1.0e-3; int iter; DP a,b,d=0.0,etemp,fu,fv,fw,fx; DP p,q,r,tol1,tol2,u,v,w,x,xm; DP e=0.0; a=(ax < cx ? ax : cx); b=(ax > cx ? ax : cx); x=w=v=bx; fw=fv=fx=f(x); for (iter=0;iter tol1) { r=(x-w)*(fx-fv); q=(x-v)*(fx-fw); p=(x-v)*q-(x-w)*r; q=2.0*(q-r); if (q > 0.0) p = -p; q=fabs(q); etemp=e; e=d; if (fabs(p) >= fabs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x)) d=CGOLD*(e=(x >= xm ? a-x : b-x)); else { d=p/q; u=x+d; if (u-a < tol2 || b-u < tol2) d=SIGN(tol1,xm-x); } } else { d=CGOLD*(e=(x >= xm ? a-x : b-x)); } u=(fabs(d) >= tol1 ? x+d : x+SIGN(tol1,d)); fu=f(u); if (fu <= fx) { if (u >= x) a=x; else b=x; shft3(v,w,x,u); shft3(fv,fw,fx,fu); } else { if (u < x) a=u; else b=u; if (fu <= fw || w == x) { v=w; w=u; fv=fw; fw=fu; } else if (fu <= fv || v == x || v == w) { v=u; fv=fu; } } } nrerror("Too many iterations in brent"); xmin=x; return fx; }