C#, Numerical Calculation - Calculation method and source program of Parabolic Interpolation and Brent's Method (Parabolic Interpolation and Brent's Method)

 

using System;

namespace Legalsoft.Truffer
{     /// <summary>     /// Parabolic Interpolation and Brent's Method     /// Parabolic Interpolation and Brent's Method     /// </summary>     public class Brent : Bracketmethod     {         public double xmin { get; set; }         public double fmin { get; set; }         public double tol { get; set; }








        public Brent(double toll = 3.0e-8)
        {
            this.tol = toll;
        }

        public double minimize(UniVarRealValueFun func)
        {
            const int ITMAX = 100;
            const double CGOLD = 0.3819660;
            double ZEPS = float.Epsilon * 0.001;
            double d = 0.0;
            double e = 0.0;
            double a = (ax < cx ? ax : cx);
            double b = (ax > cx ? ax : cx);
            double x = bx;
            double w = bx;
            double v = bx;
            double fx = func.funk(x);
            double fw = fx;
            double fv = fx;
            for (int iter = 0; iter < ITMAX; iter++)
            {
                double xm = 0.5 * (a + b);
                double tol1 = tol * Math.Abs(x) + ZEPS;
                double tol2 = 2.0 * (tol1);
                if (Math.Abs(x - xm) <= (tol2 - 0.5 * (b - a)))
                {
                    fmin = fx;
                    return xmin = x;
                }
                if (Math.Abs(e) > tol1)
                {
                    double r = (x - w) * (fx - fv);
                    double q = (x - v) * (fx - fw);
                    double p = (x - v) * q - (x - w) * r;
                    q = 2.0 * (q - r);
                    if (q > 0.0)
                    {
                        p = -p;
                    }
                    q = Math.Abs(q);
                    double etemp = e;
                    e = d;
                    if (Math.Abs(p) >= Math.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;
                        double uu = x + d;
                        if (uu - a < tol2 || b - uu < tol2)
                        {
                            d = Globals.SIGN(tol1, xm - x);
                        }
                    }
                }
                else
                {
                    d = CGOLD * (e = (x >= xm ? a - x : b - x));
                }
                double u = (Math.Abs(d) >= tol1 ? x + d : x + Globals.SIGN(tol1, d));
                double fu = func.funk(u);
                if (fu <= fx)
                {
                    if (u >= x)
                    {
                        a = x;
                    }
                    else
                    {
                        b = x;
                    }
                    shft3(ref v, ref w, ref x, u);
                    shft3(ref fv, ref fw, ref 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;
                    }
                }
            }
            throw new Exception("Too many iterations in brent");
        }
    }
}
 

Supongo que te gusta

Origin blog.csdn.net/beijinghorn/article/details/132128414
Recomendado
Clasificación