C#,码海拾贝(54)——求“非线性方程组“一组实根的“拟牛顿法“之C#源代码

using System;

namespace Zhou.CSharp.Algorithm
{
    public delegate double delFunction_x(double x);
    public delegate double delFunction_xa(double[] x);
    public delegate double delFunction_x_y(double x, double y);
    public delegate double delFunction_x_ya(double x, double[] y);
    public delegate double delFunction_xa_ya(double[] x, double[] y);

    /// <summary>
    /// 求解非线性方程组的类 NLEquations
    /// 原作 周长发
    /// 改编 深度混淆
    /// </summary>
    public static partial class NLEquations
    {
 

        /// <summary>
        /// 求非线性方程组一组实根的拟牛顿法
        /// 计算方程左端函数f(x)值及其偏导数值
        /// double Func(double[] x, double[] y)
        /// </summary>
        /// <param name="Func">计算方程左端函数</param>
        /// <param name="n">方程的个数,也是未知数的个数</param>
        /// <param name="x">一维数组,长度为n,存放一组初值x0, x1, …, xn-1, 返回时存放方程组的一组实根</param>
        /// <param name="t">控制h大小的变量,0<t<1</param>
        /// <param name="h">增量初值</param>
        /// <param name="nMaxIt">迭代次数</param>
        /// <param name="eps">控制精度</param>
        /// <return>bool 型,求解是否成功</return>
        public static bool GetRootsetNewton(delFunction_xa_ya Func, int n, double[] x, double t, double h, int nMaxIt, double eps)
        {
            int i, j, r;
            double am, z, beta, d;

            double[] y = new double[n];

            // 构造矩阵
            Matrix mtxCoef = new Matrix(n, n);
            Matrix mtxConst = new Matrix(n, 1);
            double[] a = mtxCoef.GetData();
            double[] b = mtxConst.GetData();

            // 迭代求解
            r = nMaxIt;
            am = 1.0 + eps;
            while (am >= eps)
            {
                Func(x, b);

                am = 0.0;
                for (i = 0; i <= n - 1; i++)
                {
                    z = Math.Abs(b[i]);
                    if (z > am)
                    {
                        am = z;
                    }
                }

                if (am >= eps)
                {
                    r = r - 1;
                    if (r == 0)
                    {
                        return false;
                    }

                    for (j = 0; j <= n - 1; j++)
                    {
                        z = x[j];
                        x[j] = x[j] + h;

                        Func(x, y);

                        for (i = 0; i <= n - 1; i++)
                        {
                            a[i * n + j] = y[i];
                        }
                        x[j] = z;
                    }

                    // 调用全选主元高斯消元法
                    Matrix mtxResult = new Matrix();
                    if (!LEquations.GetRootsetGauss(mtxCoef, mtxConst, mtxResult))
                    {
                        return false;
                    }

                    mtxConst.SetValue(mtxResult);
                    b = mtxConst.GetData();

                    beta = 1.0;
                    for (i = 0; i <= n - 1; i++)
                    {
                        beta = beta - b[i];
                    }
                    if (Math.Abs(beta) < float.Epsilon)
                    {
                        return false;
                    }

                    d = h / beta;
                    for (i = 0; i <= n - 1; i++)
                    {
                        x[i] = x[i] - d * b[i];
                    }
                    h = t * h;
                }
            }

            // 是否在有效迭代次数内达到精度
            return (nMaxIt > r);
        }
 

}

}

猜你喜欢

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