예제 #1
0
        private Matrix Solve(Matrix Mat)
        {
            int nRows = Mat.RowCount;
            int nCols = Mat.ColumnCount;

            if (nRows != nCols)
            {
                throw new ArgumentOutOfRangeException("HessenBerg matrix must be derived from a square matrix");
            }
            Matrix H = Mat;

            for (int k = 1; k < nCols - 1; k++)
            {
                double max   = 0.0;
                int    i_max = 0;
                for (int j = k; j < nCols; j++)
                {
                    double t = H[j, k - 1];
                    if (Math.Abs(t) > Math.Abs(max))
                    {
                        max   = t;
                        i_max = j;
                    }
                }

                if (max != 0.0)
                {
                    if (i_max != k)
                    {
                        for (int j = k - 1; j < nCols; j++)
                        {
                            int u = i_max * nCols + j;
                            int v = k * nCols + j;
                            U.Swap(H.Values, u, v);
                        }
                        U.SwapColumn(H.Values, i_max, k, nRows, nCols);
                    }

                    for (i_max = k + 1; i_max < nCols; i_max++)
                    {
                        double t = H[i_max, k - 1] / max;
                        H[i_max, k - 1] = 0.0;
                        for (int j = k; j < nCols; j++)
                        {
                            H[i_max, j] -= t * H[k, j];
                        }

                        for (int j = 0; j < nCols; j++)
                        {
                            H[j, k] += t * H[j, i_max];
                        }
                    }
                }
            }
            return(H);
        }
        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];
                }
            }
        }
예제 #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);
                }
            }
        }