dcstep() static private method

static private dcstep ( double &stx, double &fx, double &dx, double &sty, double &fy, double &dy, double &stp, double fp, double dp, bool &brackt, double stpmin, double stpmax ) : void
stx double
fx double
dx double
sty double
fy double
dy double
stp double
fp double
dp double
brackt bool
stpmin double
stpmax double
return void
Example #1
0
        private unsafe ConjugateGradientCode cvsmod(ref double f, double[] s, ref double stp, ref int info,
                                                    ref int nfev, double[] wa, ref double dginit, ref double dgout)
        {
            int n = NumberOfVariables;

            double[] x = Solution;

            if (info == 1)
            {
                goto L321;
            }

            infoc = 1;

            if (stp <= 0) // Check the input parameters for errors
            {
                return(ConjugateGradientCode.StepSize);
            }

            // Compute the initial gradient in the search direction
            // and check that S is a descent direction.

            if (dginit >= 0)
            {
                throw new LineSearchFailedException(0, "The search direction is not a descent direction.");
            }

            // Initialize local variables
            brackt = false;
            stage1 = true;
            nfev   = 0;
            finit  = f;
            dgtest = ftol * dginit;
            width  = stpmax - stpmin;
            width1 = width / 0.5;

            for (int j = 0; j < x.Length; ++j)
            {
                wa[j] = x[j];
            }

            // The variables STX, FX, DGX contain the values of the step,
            //   function, and directional derivative at the best step.
            // The variables STY, FY, DGY contain the value of the step,
            //   function, and derivative at the other endpoint of the interval
            //   of uncertainty.
            // The variables STP, F, DG contain the values of the step,
            //   function, and derivative at the current step.

            stx = 0;
            fx  = finit;
            dgx = dginit;
            sty = 0;
            fy  = finit;
            dgy = dginit;


L30:        // Start of iteration.

            // Set the minimum and maximum steps to correspond
            // to the present interval of uncertainty.

            if (brackt)
            {
                stmin = Math.Min(stx, sty);
                stmax = Math.Max(stx, sty);
            }
            else
            {
                stmin = stx;
                stmax = stp + 4 * (stp - stx);
            }

            // Force the step to be within
            // the bounds STPMAX and STPMIN.

            stp = Math.Max(stp, stpmin);
            stp = Math.Min(stp, stpmax);

            // If an unusual termination is to occur then
            // let STP be the lowest point obtained so far.

            if (brackt && (stp <= stmin || stp >= stmax) || nfev >= maxfev - 1 ||
                infoc == 0 || brackt && stmax - stmin <= xtol * stmax)
            {
                stp = stx;
            }

            // Evaluate the function and gradient at STP
            // and compute the directional derivative.

            for (int j = 0; j < s.Length; ++j)
            {
                x[j] = wa[j] + stp * s[j];
            }

            // Fetch function and gradient
            f = Function(x);
            g = Gradient(x);

            info = 0;
            nfev++;
            dg2 = 0;

            for (int j = 0; j < g.Length; ++j)
            {
                dg2 += g[j] * s[j];
            }

            ftest1 = finit + stp * dgtest;

            if ((brackt && (stp <= stmin || stp >= stmax)) || infoc == 0)
            {
                return(ConjugateGradientCode.RoundingErrors);
            }

            if (stp == stpmax && f <= ftest1 && dg2 <= dgtest)
            {
                return(ConjugateGradientCode.StepHigh);
            }

            if (stp == stpmin && (f > ftest1 || dg2 >= dgtest))
            {
                return(ConjugateGradientCode.StepLow);
            }

            if (nfev >= maxfev)
            {
                return(ConjugateGradientCode.MaximumEvaluations);
            }

            if (brackt && stmax - stmin <= xtol * stmax)
            {
                return(ConjugateGradientCode.Precision);
            }


            // More's code has been modified so that at least one new
            //  function value is computed during the line search (enforcing
            //  at least one interpolation is not easy, since the code may
            //  override an interpolation)

            if (f <= ftest1 && Math.Abs(dg2) <= gtol * (-dginit) && nfev > 1)
            {
                info  = 1;
                dgout = dg2;
                return(ConjugateGradientCode.Success);
            }


L321:

            // In the first stage we seek a step for which the modified
            // function has a nonpositive value and nonnegative derivative.
            if (stage1 && f <= ftest1 && dg2 >= Math.Min(ftol, gtol) * dginit)
            {
                stage1 = false;
            }

            // A modified function is used to predict the step only if
            // we have not obtained a step for which the modified function
            // has a nonpositive function value and nonnegative derivative,
            // and if a lower function value has been obtained but the
            // decrease is not sufficient.

            if (stage1 && f <= fx && f > ftest1)
            {
                // Define the modified function and derivative values
                double fm   = f - stp * dgtest;
                double fxm  = fx - stx * dgtest;
                double fym  = fy - sty * dgtest;
                double dgm  = dg2 - dgtest;
                double dgxm = dgx - dgtest;
                double dgym = dgy - dgtest;

                // Call CSTEPM to update the interval of
                // uncertainty and to compute the new step.

                BoundedBroydenFletcherGoldfarbShanno.dcstep(ref stx, ref fxm, ref dgxm,
                                                            ref sty, ref fym, ref dgym, ref stp, fm, dgm, ref brackt, stpmin, stpmax);

                // Reset the function and gradient values for f.
                fx  = fxm + stx * dgtest;
                fy  = fym + sty * dgtest;
                dgx = dgxm + dgtest;
                dgy = dgym + dgtest;
            }
            else
            {
                // Call CSTEPM to update the interval of
                // uncertainty and to compute the new step.
                BoundedBroydenFletcherGoldfarbShanno.dcstep(ref stx, ref fx, ref dgx,
                                                            ref sty, ref fy, ref dgy, ref stp, f, dg2, ref brackt, stpmin, stpmax);
            }

            // Force a sufficient decrease in the
            // size of the interval of uncertainty.

            if (brackt)
            {
                if ((Math.Abs(sty - stx)) >= 0.66 * width1)
                {
                    stp = stx + 0.5 * (sty - stx);
                }

                width1 = width;
                width  = Math.Abs(sty - stx);
            }

            goto L30;
        }