//public double lastXx = 1.0; private double[] LineMinimize(IDiffFunction function, double[] initial, double[] direction) { // make a 1-dim function along the direction line // THIS IS A HACK (but it's the NRiC peoples' hack) CGMinimizer.OneDimDiffFunction oneDim = new CGMinimizer.OneDimDiffFunction(function, initial, direction); // do a 1-dim line min on this function //Double Ax = new Double(0.0); //Double Xx = new Double(1.0); //Double Bx = new Double(0.0); // bracket the extreme pt double guess = 0.01; //log.info("Current "+oneDim.valueAt(0)+" nudge "+(oneDim.smallestZeroPositiveLocation()*1e-2)+" "+oneDim.valueAt(oneDim.smallestZeroPositiveLocation()*1e-5)); if (!silent) { log.Info("["); } CGMinimizer.Triple bracketing = Mnbrak(new CGMinimizer.Triple(0, guess, 0), oneDim); if (!silent) { log.Info("]"); } double ax = bracketing.a; double xx = bracketing.b; double bx = bracketing.c; //lastXx = xx; // CHECK FOR END OF WORLD if (!(ax <= xx && xx <= bx) && !(bx <= xx && xx <= ax)) { log.Info("Bad bracket order!"); } //log.info("Bracketing found: "+arrayToString(oneDim.vectorOf(ax),3)+" "+arrayToString(oneDim.vectorOf(xx),3)+" "+arrayToString(oneDim.vectorOf(bx),3)); // find the extreme pt if (!silent) { log.Info("<"); } double xmin = Dbrent(oneDim, ax, xx, bx); if (!silent) { log.Info(">"); } // return the full vector //log.info("Went "+xmin+" during lineMinimize"); return(oneDim.VectorOf(xmin)); }
// end class OneDimDiffFunction // constants private static CGMinimizer.Triple Mnbrak(CGMinimizer.Triple abc, CGMinimizer.OneDimDiffFunction function) { // inputs double ax = abc.a; double fa = function.ValueAt(ax); double bx = abc.b; double fb = function.ValueAt(bx); if (fb > fa) { // swap double temp = fa; fa = fb; fb = temp; temp = ax; ax = bx; bx = temp; } // guess cx double cx = bx + Gold * (bx - ax); double fc = function.ValueAt(cx); // loop until we get a bracket while (fb > fc) { double r = (bx - ax) * (fb - fc); double q = (bx - cx) * (fb - fa); double u = bx - ((bx - cx) * q - (bx - ax) * r) / (2.0 * Sign(Fmax(Fabs(q - r), Tiny), q - r)); double fu; double ulim = bx + Glimit * (cx - bx); if ((bx - u) * (u - cx) > 0.0) { fu = function.ValueAt(u); if (fu < fc) { //Ax = new Double(bx); //Bx = new Double(u); //Cx = new Double(cx); //log.info("\nReturning3: a="+bx+" ("+fb+") b="+u+"("+fu+") c="+cx+" ("+fc+")"); return(new CGMinimizer.Triple(bx, u, cx)); } else { if (fu > fb) { //Cx = new Double(u); //Ax = new Double(ax); //Bx = new Double(bx); //log.info("\nReturning2: a="+ax+" ("+fa+") b="+bx+"("+fb+") c="+u+" ("+fu+")"); return(new CGMinimizer.Triple(ax, bx, u)); } } u = cx + Gold * (cx - bx); fu = function.ValueAt(u); } else { if ((cx - u) * (u - ulim) > 0.0) { fu = function.ValueAt(u); if (fu < fc) { bx = cx; cx = u; u = cx + Gold * (cx - bx); fb = fc; fc = fu; fu = function.ValueAt(u); } } else { if ((u - ulim) * (ulim - cx) >= 0.0) { u = ulim; fu = function.ValueAt(u); } else { u = cx + Gold * (cx - bx); fu = function.ValueAt(u); } } } ax = bx; bx = cx; cx = u; fa = fb; fb = fc; fc = fu; } //log.info("\nReturning: a="+ax+" ("+fa+") b="+bx+"("+fb+") c="+cx+" ("+fc+")"); return(new CGMinimizer.Triple(ax, bx, cx)); }