C#,码海拾贝(23)——求解“复系数线性方程组“的“全选主元高斯消去法“之C#源代码

C#,码海拾贝(23)——求解“复系数线性方程组“的“全选主元高斯消去法“之C#源代码_第1张图片

using System;

namespace Zhou.CSharp.Algorithm
{
    ///


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

    public static partial class LEquations
    {
            ///
        /// 复系数方程组的全选主元高斯消去法
        ///

        /// 指定的系数矩阵
        /// 指定的常数矩阵
        /// 系数矩阵的虚部矩阵
        /// 常数矩阵的虚部矩阵
        /// Matrix对象,返回方程组解矩阵的实部矩阵
        /// Matrix对象,返回方程组解矩阵的虚部矩阵
        /// bool 型,方程组求解是否成功
        public static bool GetRootsetGauss(Matrix mtxLECoef, Matrix mtxLEConst, Matrix mtxCoefImag, Matrix mtxConstImag, Matrix mtxResult, Matrix mtxResultImag)
        {
            int r, k, i, j, nIs = 0, u, v;
            double p, q, s, d;

            // 方程组的属性,将常数矩阵赋给解矩阵
            mtxResult.SetValue(mtxLEConst);
            mtxResultImag.SetValue(mtxConstImag);
            double[] pDataCoef = mtxLECoef.GetData();
            double[] pDataConst = mtxResult.GetData();
            double[] pDataCoefImag = mtxCoefImag.GetData();
            double[] pDataConstImag = mtxResultImag.GetData();
            int n = mtxLECoef.GetNumColumns();
            int m = mtxLEConst.GetNumColumns();

            // 临时缓冲区,存放变换的列数
            int[] pnJs = new int[n];

            // 消元
            for (k = 0; k <= n - 2; k++)
            {
                d = 0.0;
                for (i = k; i <= n - 1; i++)
                {
                    for (j = k; j <= n - 1; j++)
                    {
                        u = i * n + j;
                        p = pDataCoef[u] * pDataCoef[u] + pDataCoefImag[u] * pDataCoefImag[u];
                        if (p > d)
                        {
                            d = p;
                            pnJs[k] = j;
                            nIs = i;
                        }
                    }
                }

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

                if (nIs != k)
                {
                    for (j = k; j <= n - 1; j++)
                    {
                        u = k * n + j;
                        v = nIs * n + j;
                        p = pDataCoef[u];
                        pDataCoef[u] = pDataCoef[v];
                        pDataCoef[v] = p;
                        p = pDataCoefImag[u];
                        pDataCoefImag[u] = pDataCoefImag[v];
                        pDataCoefImag[v] = p;
                    }

                    p = pDataConst[k];
                    pDataConst[k] = pDataConst[nIs];
                    pDataConst[nIs] = p;
                    p = pDataConstImag[k];
                    pDataConstImag[k] = pDataConstImag[nIs];
                    pDataConstImag[nIs] = p;
                }

                if (pnJs[k] != k)
                {
                    for (i = 0; i <= n - 1; i++)
                    {
                        u = i * n + k;
                        v = i * n + pnJs[k];
                        p = pDataCoef[u];
                        pDataCoef[u] = pDataCoef[v];
                        pDataCoef[v] = p;
                        p = pDataCoefImag[u];
                        pDataCoefImag[u] = pDataCoefImag[v];
                        pDataCoefImag[v] = p;
                    }
                }

                v = k * n + k;
                for (j = k + 1; j <= n - 1; j++)
                {
                    u = k * n + j;
                    p = pDataCoef[u] * pDataCoef[v];
                    q = -pDataCoefImag[u] * pDataCoefImag[v];
                    s = (pDataCoef[v] - pDataCoefImag[v]) * (pDataCoef[u] + pDataCoefImag[u]);
                    pDataCoef[u] = (p - q) / d;
                    pDataCoefImag[u] = (s - p - q) / d;
                }

                p = pDataConst[k] * pDataCoef[v];
                q = -pDataConstImag[k] * pDataCoefImag[v];
                s = (pDataCoef[v] - pDataCoefImag[v]) * (pDataConst[k] + pDataConstImag[k]);
                pDataConst[k] = (p - q) / d;
                pDataConstImag[k] = (s - p - q) / d;

                for (i = k + 1; i <= n - 1; i++)
                {
                    u = i * n + k;
                    for (j = k + 1; j <= n - 1; j++)
                    {
                        v = k * n + j;
                        r = i * n + j;
                        p = pDataCoef[u] * pDataCoef[v];
                        q = pDataCoefImag[u] * pDataCoefImag[v];
                        s = (pDataCoef[u] + pDataCoefImag[u]) * (pDataCoef[v] + pDataCoefImag[v]);
                        pDataCoef[u] = pDataCoef[u] - p + q;
                        pDataCoefImag[u] = pDataCoefImag[u] - s + p + q;
                    }

                    p = pDataCoef[u] * pDataConst[k];
                    q = pDataCoefImag[u] * pDataConstImag[k];
                    s = (pDataCoef[u] + pDataCoefImag[u]) * (pDataConst[k] + pDataConstImag[k]);
                    pDataConst[i] = pDataConst[i] - p + q;
                    pDataConstImag[i] = pDataConstImag[i] - s + p + q;
                }
            }

            u = (n - 1) * n + n - 1;
            d = pDataCoef[u] * pDataCoef[u] + pDataCoefImag[u] * pDataCoefImag[u];

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

            // 求解
            p = pDataCoef[u] * pDataConst[n - 1]; q = -pDataCoefImag[u] * pDataConstImag[n - 1];
            s = (pDataCoef[u] - pDataCoefImag[u]) * (pDataConst[n - 1] + pDataConstImag[n - 1]);
            pDataConst[n - 1] = (p - q) / d; pDataConstImag[n - 1] = (s - p - q) / d;

            for (i = n - 2; i >= 0; i--)
            {
                for (j = i + 1; j <= n - 1; j++)
                {
                    u = i * n + j;
                    p = pDataCoef[u] * pDataConst[j];
                    q = pDataCoefImag[u] * pDataConstImag[j];
                    s = (pDataCoef[u] + pDataCoefImag[u]) * (pDataConst[j] + pDataConstImag[j]);
                    pDataConst[i] = pDataConst[i] - p + q;
                    pDataConstImag[i] = pDataConstImag[i] - s + p + q;
                }
            }

            // 调整位置
            pnJs[n - 1] = n - 1;
            for (k = n - 1; k >= 0; k--)
            {
                if (pnJs[k] != k)
                {
                    p = pDataConst[k];
                    pDataConst[k] = pDataConst[pnJs[k]];
                    pDataConst[pnJs[k]] = p;
                    p = pDataConstImag[k];
                    pDataConstImag[k] = pDataConstImag[pnJs[k]];
                    pDataConstImag[pnJs[k]] = p;
                }
            }

            return true;
        }
    }
}
 

你可能感兴趣的:(C#数值计算,Numerical,Recipes,c#,算法,数学建模)