Accord.Math.Optimization.BoundedBroydenFletcherGoldfarbShanno.dcsrch C# (CSharp) Method

dcsrch() private static method

private static dcsrch ( double f, double g, double &stp, double ftol, double gtol, double xtol, double stpmin, double stpmax, string &task, int isave, int _isave_offset, double dsave, int _dsave_offset ) : void
f double
g double
stp double
ftol double
gtol double
xtol double
stpmin double
stpmax double
task string
isave int
_isave_offset int
dsave double
_dsave_offset int
return void
        private static void dcsrch(double f, double g, ref double stp, double ftol,
        double gtol, double xtol, double stpmin, double stpmax, ref string task,
        int[] isave, int _isave_offset, double[] dsave, int _dsave_offset)
        {

            bool brackt = false;
            int stage = 0;
            double finit = 0.0d;
            double ftest = 0.0d;
            double fm = 0.0d;
            double fx = 0.0d;
            double fxm = 0.0d;
            double fy = 0.0d;
            double fym = 0.0d;
            double ginit = 0.0d;
            double gtest = 0.0d;
            double gm = 0.0d;
            double gx = 0.0d;
            double gxm = 0.0d;
            double gy = 0.0d;
            double gym = 0.0d;
            double stx = 0.0d;
            double sty = 0.0d;
            double stmin = 0.0d;
            double stmax = 0.0d;
            double width = 0.0d;
            double width1 = 0.0d;

            if ((task.StartsWith("START", StringComparison.OrdinalIgnoreCase)))
            {
                // 
                //  Check the input arguments for errors.
                // 
                if ((stp < stpmin))
                {
                    task = "ERROR: STP .LT. STPMIN";
                }
                if ((stp > stpmax))
                {
                    task = "ERROR: STP .GT. STPMAX";
                }
                if ((g >= 0.0))
                {
                    task = "ERROR: INITIAL G .GE. ZERO";
                }
                if ((ftol < 0.0))
                {
                    task = "ERROR: FTOL .LT. ZERO";
                }
                if ((gtol < 0.0))
                {
                    task = "ERROR: GTOL .LT. ZERO";
                }
                if ((xtol < 0.0))
                {
                    task = "ERROR: XTOL .LT. ZERO";
                }
                if ((stpmin < 0.0))
                {
                    task = "ERROR: STPMIN .LT. ZERO";
                }
                if ((stpmax < stpmin))
                {
                    task = "ERROR: STPMAX .LT. STPMIN";
                }
                // 
                // c        Exit if there are errors on input.
                // 
                if ((task.StartsWith("ERROR", StringComparison.OrdinalIgnoreCase)))
                {
                    return;
                }

                // 
                // Initialize local variables.
                // 
                brackt = false;
                stage = 1;
                finit = f;
                ginit = g;
                gtest = (ftol * ginit);
                width = (stpmax - stpmin);
                width1 = (width / 0.5);

                // 
                // The variables stx, fx, gx contain the values of the step, 
                // function, and derivative at the best step. 
                // The variables sty, fy, gy contain the value of the step, 
                // function, and derivative at sty.
                // The variables stp, f, g contain the values of the step, 
                // function, and derivative at stp.
                // 
                stx = 0.0;
                fx = finit;
                gx = ginit;
                sty = 0.0;
                fy = finit;
                gy = ginit;
                stmin = 0.0;
                stmax = (stp + (4.0 * stp));
                task = "FG";
                goto L1000;
            }
            else
            {
                // 
                // Restore local variables.
                // 
                if ((isave[(1 - (1)) + _isave_offset] == 1))
                {
                    brackt = true;
                }
                else
                {
                    brackt = false;
                }
                stage = isave[(2 - (1)) + _isave_offset];
                ginit = dsave[(1 - (1)) + _dsave_offset];
                gtest = dsave[(2 - (1)) + _dsave_offset];
                gx = dsave[(3 - (1)) + _dsave_offset];
                gy = dsave[(4 - (1)) + _dsave_offset];
                finit = dsave[(5 - (1)) + _dsave_offset];
                fx = dsave[(6 - (1)) + _dsave_offset];
                fy = dsave[(7 - (1)) + _dsave_offset];
                stx = dsave[(8 - (1)) + _dsave_offset];
                sty = dsave[(9 - (1)) + _dsave_offset];
                stmin = dsave[(10 - (1)) + _dsave_offset];
                stmax = dsave[(11 - (1)) + _dsave_offset];
                width = dsave[(12 - (1)) + _dsave_offset];
                width1 = dsave[(13 - (1)) + _dsave_offset];
            }

            // 
            // c     If psi(stp) <= 0 and f'(stp) >= 0 for some step, then the
            // c     algorithm enters the second stage.
            // 
            ftest = (finit + (stp * gtest));
            if ((((stage == 1) && (f <= ftest)) && (g >= 0.0)))
            {
                stage = 2;
            }

            // 
            // c     Test for warnings.
            // 
            if ((brackt && (((stp <= stmin) || (stp >= stmax)))))
            {
                task = "WARNING: ROUNDING ERRORS PREVENT PROGRESS";
            }
            if ((brackt && ((stmax - stmin) <= (xtol * stmax))))
            {
                task = "WARNING: XTOL TEST SATISFIED";
            }
            if ((((stp == stpmax) && (f <= ftest)) && (g <= gtest)))
            {
                task = "WARNING: STP = STPMAX";
            }
            if (((stp == stpmin) && (((f > ftest) || (g >= gtest)))))
            {
                task = "WARNING: STP = STPMIN";
            }

            // 
            // c     Test for convergence.
            // 
            if (((f <= ftest) && (System.Math.Abs(g) <= (gtol * ((-(ginit)))))))
            {
                task = "CONVERGENCE";
            }
            // 
            // c     Test for termination.
            // 
            if (((task.StartsWith("WARN", StringComparison.OrdinalIgnoreCase)) ||
                (task.StartsWith("CONV", StringComparison.OrdinalIgnoreCase))))
            {
                goto L1000;
            }

            // 
            // c     A modified function is used to predict the step during the
            // c     first stage if a lower function value has been obtained but 
            // c     the decrease is not sufficient.
            // 
            if ((((stage == 1) && (f <= fx)) && (f > ftest)))
            {
                // 
                // c        Define the modified function and derivative values.
                // 
                fm = (f - (stp * gtest));
                fxm = (fx - (stx * gtest));
                fym = (fy - (sty * gtest));
                gm = (g - gtest);
                gxm = (gx - gtest);
                gym = (gy - gtest);

                // 
                // Call dcstep to update stx, sty, and to compute the new step.
                // 
                dcstep(ref stx, ref fxm, ref gxm, ref sty, ref fym, ref gym,
                    ref stp, fm, gm, ref brackt, stmin, stmax);

                // 
                // Reset the function and derivative values for f.
                // 
                fx = (fxm + (stx * gtest));
                fy = (fym + (sty * gtest));
                gx = (gxm + gtest);
                gy = (gym + gtest);
                // 
            }
            else
            {
                // 
                // Call dcstep to update stx, sty, and to compute the new step.
                // 
                dcstep(ref stx, ref fx, ref gx, ref sty, ref fy, ref gy,
                    ref stp, f, g, ref brackt, stmin, stmax);
            }

            // 
            // c     Decide if a bisection step is needed.
            // 
            if (brackt)
            {
                if ((System.Math.Abs((sty - stx)) >= (0.6600000000000000310862446895043831318617 * width1)))
                {
                    stp = (stx + (0.5 * ((sty - stx))));
                }
                width1 = width;
                width = System.Math.Abs((sty - stx));
            }
            // 
            // c     Set the minimum and maximum steps allowed for stp.
            // 
            if (brackt)
            {
                stmin = System.Math.Min(stx, sty);
                stmax = System.Math.Max(stx, sty);
            }
            else
            {
                stmin = (stp + (1.100000000000000088817841970012523233891 * ((stp - stx))));
                stmax = (stp + (4.0 * ((stp - stx))));
            }

            // 
            // c     Force the step to be within the bounds stpmax and stpmin.
            // 
            stp = System.Math.Max(stp, stpmin);
            stp = System.Math.Min(stp, stpmax);
            // 
            // c     If further progress is not possible, let stp be the best
            // c     point obtained during the search.
            // 
            if (((brackt && (((stp <= stmin) || (stp >= stmax)))) || ((brackt && ((stmax - stmin) <= (xtol * stmax))))))
            {
                stp = stx;
            }
            // 
            // c     Obtain another function and derivative.
            // 
            task = "FG";

        // 
        L1000:

            // 
            // c     Save local variables.
            // 
            if (brackt)
            {
                isave[(1 - (1)) + _isave_offset] = 1;
            }
            else
            {
                isave[(1 - (1)) + _isave_offset] = 0;
            }

            isave[(2 - (1)) + _isave_offset] = stage;
            dsave[(1 - (1)) + _dsave_offset] = ginit;
            dsave[(2 - (1)) + _dsave_offset] = gtest;
            dsave[(3 - (1)) + _dsave_offset] = gx;
            dsave[(4 - (1)) + _dsave_offset] = gy;
            dsave[(5 - (1)) + _dsave_offset] = finit;
            dsave[(6 - (1)) + _dsave_offset] = fx;
            dsave[(7 - (1)) + _dsave_offset] = fy;
            dsave[(8 - (1)) + _dsave_offset] = stx;
            dsave[(9 - (1)) + _dsave_offset] = sty;
            dsave[(10 - (1)) + _dsave_offset] = stmin;
            dsave[(11 - (1)) + _dsave_offset] = stmax;
            dsave[(12 - (1)) + _dsave_offset] = width;
            dsave[(13 - (1)) + _dsave_offset] = width1;
        }