void ML_multi_Powell::mnbrak(double& ax, double& bx, double& cx, double& fa, double& fb, double& fc, ptr_eval_1_func f ) { const double GOLD = 1.618034, GLIMIT = 100.0, TINY = 1.0e-20; double ulim, u, r, q, fu; fa = (this->*f)(ax); fb = (this->*f)(bx); if (fb > fa) { SWAP(ax, bx); SWAP(fb, fa); } cx = bx + GOLD*(bx - ax); fc = (this->*f)(cx); while (fb > fc) { r = (bx - ax)*(fb - fc); q = (bx - cx)*(fb - fa); u = bx - ((bx - cx)*q - (bx - ax)*r) / (2.0*SIGN(MAX(std::abs(q - r), TINY), q - r)); ulim = bx + GLIMIT*(cx - bx); if ((bx - u)*(u - cx) > 0.0) { fu = (this->*f)(u); if (fu < fc) { ax = bx; bx = u; fa = fb; fb = fu; return; } else if (fu > fb) { cx = u; fc = fu; return; } u = cx + GOLD*(cx - bx); fu = (this->*f)(u); } else if ((cx - u)*(u - ulim) > 0.0) { fu = (this->*f)(u); if (fu < fc) { shft3(bx, cx, u, u + GOLD*(u - cx)); shft3(fb, fc, fu, (this->*f)(u)); } } else if ((u - ulim)*(ulim - cx) >= 0.0) { u = ulim; fu = (this->*f)(u); } else { u = cx + GOLD*(cx - bx); fu = (this->*f)(u); } shft3(ax, bx, cx, u); shft3(fa, fb, fc, fu); } }
void CostFunction::mnbrack(real &ax, real &bx, real &cx, real &fa, real &fb, real &fc) { const real GOLD=1.618034, GLIMIT=100.0, TINY=1.0e-20; real ulim,u,r,q,fu; fa = f1dim(ax); fb = f1dim(bx); if (fb > fa) { SWAP(ax, bx); SWAP(fb, fa); } cx = bx+GOLD*(bx-ax); fc = f1dim(cx); while (fb > fc) { r = (bx - ax)*(fb - fc); q = (bx - cx)*(fb - fa); u = bx - ((bx-cx)*q-(bx-ax)*r)/ (2.0*SIGN(MAX(fabs(q-r), TINY), q-r)); ulim = bx + GLIMIT*(cx-bx); if ((bx-u)*(u-cx) > 0.0) { fu = f1dim(u); if (fu < fc) { ax = bx; bx = u; fa = fb; fb = fu; return; } else if (fu > fb) { cx = u; fc = fu; return; } u = cx + GOLD*(cx-bx); fu = f1dim(u); } else if ((cx-u)*(u-ulim) > 0.0) { fu = f1dim(u); if (fu < fc) { shft3(bx,cx,u,u+GOLD*(u-cx)); shft3(fb,fc,fu,f1dim(u)); } } else if ((u-ulim)*(ulim-cx) >= 0.0) { u = ulim; fu = f1dim(u); } else { u = cx + GOLD*(cx-bx); fu = f1dim(u); } shft3(ax,bx,cx,u); shft3(fa,fb,fc,fu); } }
double ML_multi_Powell::brent(const double ax, const double bx, const double cx, ptr_eval_1_func f, const double tol, double& xmin ) { const int ITMAX = 100; const double CGOLD = 0.3819660; const double ZEPS = std::numeric_limits<double>::epsilon()*1.0e-3; int iter; double a, b, d = 0.0, etemp, fu, fv, fw, fx; double p, q, r, tol1, tol2, u, v, w, x, xm; double e = 0.0; a = (ax < cx ? ax : cx); b = (ax > cx ? ax : cx); x = w = v = bx; fw = fv = fx = (this->*f)(x); for (iter = 0; iter < ITMAX; ++iter) { xm = 0.5*(a + b); tol2 = 2.0*(tol1 = tol*std::abs(x) + ZEPS); if (std::abs(x - xm) <= (tol2 - 0.5*(b - a))) { xmin = x; return(fx); } if (std::abs(e) > 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 = std::abs(q); etemp = e; e = d; if (std::abs(p) >= std::abs(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 = (std::abs(d) >= tol1 ? x + d : x + SIGN(tol1, d)); fu = (this->*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; } } } std::cerr << "brent(): exceeded iteration limit " << ITMAX << std::endl; assert(false); xmin = x; return fx; }