C#,数值计算——一维极小化例程的基类(Base class for one-dimensional minimization routines)的计算方法与源程序

1 基类功能概要

Given a function or functor func, and given distinct initial points ax and
bx, this routine searches in the downhill direction(defined by the
function as evaluated at the initial points) and returns new points ax, bx,
cx that bracket a minimum of the function.Also returned are the function
values at the three points, fa, fb, and fc.
 

给定一个函数或函子func,并给定不同的初始点ax和bx,此例程在下坡方向上搜索(由在初始点处评估的函数)并返回新的点ax、bx、bz,cx,包含函数的最小值。返回的还有函数fa、fb和fc三个点的值。

2 基类C#代码

using System;

namespace Legalsoft.Truffer
{
    /// <summary>
    /// 一维极小化例程的基类
    /// Base class for one-dimensional minimization routines.
    /// Provides a routine to
    /// bracket a minimum and several utility functions.
    /// </summary>
    public class Bracketmethod
    {
        public double ax;
        public double bx;
        public double cx;
        public double fa;
        public double fb;
        public double fc;

        /// <summary>
        /// Given a function or functor func, and given distinct initial points ax and
        /// bx, this routine searches in the downhill direction(defined by the
        /// function as evaluated at the initial points) and returns new points ax, bx,
        /// cx that bracket a minimum of the function.Also returned are the function
        /// values at the three points, fa, fb, and fc.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        public void bracket(double a, double b, UniVarRealValueFun func)
        {
            const double GOLD = 1.618034;
            const double GLIMIT = 100.0;
            const double TINY = 1.0e-20;
            ax = a;
            bx = b;
            double fu;
            fa = func.funk(ax);
            fb = func.funk(bx);
            if (fb > fa)
            {
                Globals.SWAP(ref ax, ref bx);
                Globals.SWAP(ref fb, ref fa);
            }
            cx = bx + GOLD * (bx - ax);
            fc = func.funk(cx);
            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 * Globals.SIGN(Math.Max(Math.Abs(q - r), TINY), q - r));
                double ulim = bx + GLIMIT * (cx - bx);
                if ((bx - u) * (u - cx) > 0.0)
                {
                    fu = func.funk(u);
                    if (fu < fc)
                    {
                        ax = bx;
                        bx = u;
                        fa = fb;
                        fb = fu;
                        return;
                    }
                    else if (fu > fb)
                    {
                        cx = u;
                        fc = fu;
                        return;
                    }
                    u = cx + GOLD * (cx - bx);
                    fu = func.funk(u);
                }
                else if ((cx - u) * (u - ulim) > 0.0)
                {
                    fu = func.funk(u);
                    if (fu < fc)
                    {
                        shft3(ref bx, ref cx, ref u, u + GOLD * (u - cx));
                        shft3(ref fb, ref fc, ref fu, func.funk(u));
                    }
                }
                else if ((u - ulim) * (ulim - cx) >= 0.0)
                {
                    u = ulim;
                    fu = func.funk(u);
                }
                else
                {
                    u = cx + GOLD * (cx - bx);
                    fu = func.funk(u);
                }
                shft3(ref ax, ref bx, ref cx, u);
                shft3(ref fa, ref fb, ref fc, fu);
            }
        }

        public void shft2(ref double a, ref double b, double c)
        {
            a = b;
            b = c;
        }

        public void shft3(ref double a, ref double b, ref double c, double d)
        {
            a = b;
            b = c;
            c = d;
        }

        public void mov3(ref double a, ref double b, ref double c, double d, double e, double f)
        {
            a = d;
            b = e;
            c = f;
        }
    }
}
 

猜你喜欢

转载自blog.csdn.net/beijinghorn/article/details/132128400