C#,码海拾贝(25)——求解“三对角线方程组”的“追赶法”之C#源代码

C#,码海拾贝(25)——求解“三对角线方程组”的“追赶法”之C#源代码_第1张图片

追赶法的优点是对三对角、五对角、七对角等矩阵线性方程组求解的快速有效办法,而三对角矩阵在有限差分格式中出现的太多了,除此之外,其在物理、工程等领域也都会用到三对角求解的追赶法。
追赶法的基本思想与高斯消元法及三角分解法相同,只是由于系数中出现了大量的零,计算中可将它们撇开,从而使得计算公式简化,大大减少了计算量。这是一种特殊的稀疏矩阵,非零元素集中分布在主对角线及其相邻两条对角线上,称为三对角矩阵。
追赶法只是针对系数矩阵为三对角阵的方程组,因此是一种特殊的方程组。此方法效率较高,不过不适用于一般的线性方程组。
方程组,又称联立方程。把若干个方程合在一起研究,使其中的未知数同时满足每一个方程的一组方程。能同时满足方程组中每个方程的未知数的值,称为方程组的“解”。求出它所有解的过程称为“解方程组”。
方程组,又称联立方程,是两个或两个以上含有多个未知数的方程联立得到的组合。未知数的值称为方程组的,求方程组根的过程称为“解方程组”。一般在方程式的左边加大括号标注。

C#,码海拾贝(25)——求解“三对角线方程组”的“追赶法”之C#源代码_第2张图片

using System;

namespace Zhou.CSharp.Algorithm
{
    ///


    /// 求解线性方程组的类 LEquations
    /// 原作 周长发
    /// 改编 深度混淆
    ///

    public static partial class LEquations
    {


        ///


        /// 求解三对角线方程组的追赶法
        ///

        /// 指定的系数矩阵
        /// 指定的常数矩阵
        /// Matrix对象,返回方程组解矩阵
        /// bool 型,方程组求解是否成功
        public static bool GetRootsetTriDiagonal(Matrix mtxLECoef, Matrix mtxLEConst, Matrix mtxResult)
        {
            int k, j;
            double s;

            // 将常数矩阵赋给解矩阵
            mtxResult.SetValue(mtxLEConst);
            double[] pDataConst = mtxResult.GetData();

            int n = mtxLECoef.GetNumColumns();
            if (mtxLECoef.GetNumRows() != n)
            {
                return false;
            }

            // 为系数矩阵对角线数组分配内存
            double[] pDiagData = new double[3 * n - 2];

            // 构造系数矩阵对角线元素数组
            k = j = 0;
            if (k == 0)
            {
                pDiagData[j++] = mtxLECoef.GetElement(k, k);
                pDiagData[j++] = mtxLECoef.GetElement(k, k + 1);
            }
            for (k = 1; k < n - 1; ++k)
            {
                pDiagData[j++] = mtxLECoef.GetElement(k, k - 1);
                pDiagData[j++] = mtxLECoef.GetElement(k, k);
                pDiagData[j++] = mtxLECoef.GetElement(k, k + 1);
            }
            if (k == n - 1)
            {
                pDiagData[j++] = mtxLECoef.GetElement(k, k - 1);
                pDiagData[j++] = mtxLECoef.GetElement(k, k);
            }

            // 求解
            for (k = 0; k <= n - 2; k++)
            {
                j = 3 * k;
                s = pDiagData[j];

                // 求解失败
                if (Math.Abs(s) < float.Epsilon) //  Math.Abs(s) + 1.0 == 1.0)
                {
                    return false;
                }

                pDiagData[j + 1] = pDiagData[j + 1] / s;
                pDataConst[k] = pDataConst[k] / s;
                pDiagData[j + 3] = pDiagData[j + 3] - pDiagData[j + 2] * pDiagData[j + 1];
                pDataConst[k + 1] = pDataConst[k + 1] - pDiagData[j + 2] * pDataConst[k];
            }

            s = pDiagData[3 * n - 3];
            if (Math.Abs(s) < float.Epsilon)//  s == 0.0)
            {
                return false;
            }

            // 调整
            pDataConst[n - 1] = pDataConst[n - 1] / s;
            for (k = n - 2; k >= 0; k--)
            {
                pDataConst[k] = pDataConst[k] - pDiagData[3 * k + 1] * pDataConst[k + 1];
            }
            return true;
        }
 

    }
}

你可能感兴趣的:(C#数值计算,Numerical,Recipes,c#,算法,开发语言)