C#, Numerical Calculation - Calculation Method and Source Program of Frprmn

 

using System;

namespace Legalsoft.Truffer
{
    public class Frprmn : Dlinemethod
    {
        private int iter { get; set; }
        private double fret { get; set; }
        private double ftol { get; set; }

        public Frprmn(RealValueFunWithDiff funcd, double ftoll = 3.0e-8) : base(funcd)
        {
            this.ftol = ftoll;
        }

        public double[] minimize(double[] pp)
        {
            const int ITMAX = 200;
            const double EPS = 1.0e-18;
            const double GTOL = 1.0e-8;

            int n = pp.Length;
            //p = pp;
            p = Globals.CopyFrom(pp);
            double[] g = new double[n];
            double[] h = new double[n];
            //xi.resize(n);
            xi = new double[n];
            double fp = func.funk(p);
            func.df(p, xi);
            for (int j = 0; j < n; j++)
            {
                g[j] = -xi[j];
                xi[j] = h[j] = g[j];
            }
            for (int its = 0; its < ITMAX; its++)
            {
                iter = its;
                fret = linmin();
                if (2.0 * Math.Abs(fret - fp) <= ftol * (Math.Abs(fret) + Math.Abs(fp) + EPS))
                {
                    return p;
                }
                fp = fret;
                func.df(p, xi);
                double test = 0.0;
                double den = Math.Max(Math.Abs(fp), 1.0);
                for (int j = 0; j < n; j++)
                {
                    double temp = Math.Abs(xi[j]) * Math.Max(Math.Abs(p[j]), 1.0) / den;
                    if (temp > test)
                    {
                        test = temp;
                    }
                }
                if (test < GTOL)
                {
                    return p;
                }
                double dgg = 0.0;
                double gg = 0.0;
                for (int j = 0; j < n; j++)
                {
                    gg += g[j] * g[j];
                    // dgg += xi[j]*xi[j];
                    dgg += (xi[j] + g[j]) * xi[j];
                }
                //if (gg == 0.0)
                if (Math.Abs(gg) <= float.Epsilon)
                {
                    return p;
                }
                double gam = dgg / gg;
                for (int j = 0; j < n; j++)
                {
                    g[j] = -xi[j];
                    xi[j] = h[j] = g[j] + gam * h[j];
                }
            }
            throw new Exception("Too many iterations in frprmn");
        }
    }
}
 

Guess you like

Origin blog.csdn.net/beijinghorn/article/details/132219001