Пример #1
0
        //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));
        }
Пример #2
0
        // 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));
        }