private void Solve(Matrix mat)
        {
            int nRows = mat.RowCount;
            int nCols = mat.ColumnCount;

            if (nRows != nCols)
            {
                throw new ArgumentOutOfRangeException("LU Decomposition only support square matrix");
            }
            int n = nRows;

            P         = SpecialMatrices.Eye(n);
            SwapTimes = 1;
            for (int i = 0; i < n; i++) //pivot
            {
                double max     = mat[i, i];
                int    max_row = i;
                for (int j = i; j < n; j++)
                {
                    if (mat[j, i] > max)
                    {
                        max     = mat[j, i];
                        max_row = j;
                    }
                }

                if (i != max_row)
                {
                    Utility.SwapRow(P.Values, i, max_row, nCols);
                    SwapTimes *= (-1);
                }
            }

            L = new Matrix(n);
            U = new Matrix(n);
            Matrix A = P * mat;

            for (int j = 0; j < n; j++)
            {
                L[j, j] = 1.0;
                for (int i = 0; i <= j; i++)
                {
                    double sum = 0.0;
                    for (int k = 0; k < i; k++)
                    {
                        sum += U[k, j] * L[i, k];
                    }
                    U[i, j] = A[i, j] - sum;
                }

                for (int i = j; i < n; i++)
                {
                    double sum = 0.0;
                    for (int k = 0; k < j; k++)
                    {
                        sum += U[k, j] * L[i, k];
                    }
                    L[i, j] = (A[i, j] - sum) / U[j, j];
                }
            }
        }
예제 #2
0
 /// <summary>
 /// 单位矩阵
 /// </summary>
 /// <param name="nRows">行数</param>
 /// <param name="nCols">列数</param>
 /// <returns></returns>
 public static Matrix Eye(int nRows, int nCols)
 {
     return(SpecialMatrices.Eye(nRows, nCols));
 }
예제 #3
0
        private void Solve(Matrix mat)
        {
            int nRows = mat.RowCount;
            int nCols = mat.ColumnCount;

            if (nRows < nCols)
            {
                throw new ArgumentOutOfRangeException("To make QR factorization,the rows count of matrix must greater than or equal columns count of it");
            }
            Q = SpecialMatrices.Eye(nRows, nRows);
            R = mat;
            int n = nCols;

            if (nRows == nCols)
            {
                n--;
            }
            double d, w;
            int    p, u, v;
            double alpha, t;

            double[] q = Q.Values;
            double[] r = R.Values;
            for (int k = 0; k < n; k++)
            {
                d = 0.0;
                u = k * nCols + k;
                for (int i = k; i < nRows; i++)
                {
                    v = i * nCols + k;
                    w = Math.Abs(r[v]);
                    if (w > d)
                    {
                        d = w;
                    }
                }

                alpha = 0.0;
                for (int i = k; i < nRows; i++)
                {
                    v      = i * nCols + k;
                    t      = r[v] / d;
                    alpha += t * t;
                }

                if (r[u] > 0.0)
                {
                    d = -d;
                }

                alpha = d * Math.Sqrt(alpha);
                if (Math.Abs(alpha) < eps)
                {
                    throw new Exception("QR Factorization unsolved");
                }

                d = Math.Sqrt(2.0 * alpha * (alpha - r[u]));
                if (d > eps)
                {
                    r[u] = (r[u] - alpha) / d;
                    for (int i = k + 1; i < nRows; i++)
                    {
                        R[i, k] /= d;
                    }

                    for (int j = 0; j < nRows; j++)
                    {
                        t = 0.0;
                        for (int m = k; m < nRows; m++)
                        {
                            t += R[m, k] * q[m * nRows + j];
                        }

                        for (int i = k; i < nRows; i++)
                        {
                            p     = i * nRows + j;
                            q[p] -= 2.0 * t * R[i, k];
                        }
                    }

                    for (int j = k + 1; j < nCols; j++)
                    {
                        t = 0.0;
                        for (int m = k; m < nRows; m++)
                        {
                            t += R[m, k] * R[m, j];
                        }

                        for (int i = k; i < nRows; i++)
                        {
                            R[i, j] -= 2.0 * t * R[i, k];
                        }
                    }

                    r[u] = alpha;
                    for (int i = k + 1; i < nRows; i++)
                    {
                        R[i, k] = 0.0;
                    }
                }
            }

            for (int i = 0; i < nRows - 1; i++)
            {
                for (int j = i + 1; j < nRows; j++)
                {
                    p = i * nRows + j;
                    u = j * nRows + i;
                    Utility.Swap(q, u, p);
                }
            }
        }