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);
    }
}
Example #2
0
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;
}