Exemple #1
0
        public static int QRPTDecomp(PZMath_matrix A, PZMath_vector tau, PZMath_permutation p, out int signum, PZMath_vector norm)
        {
            int M = A.RowCount;
            int N = A.ColumnCount;
            signum = 0;

            if (tau.Size != System.Math.Min(M, N))
            {
                PZMath_errno.ERROR("size of tau must be MIN(M,N)", PZMath_errno.PZMath_EBADLEN);
            }
            else if (p.Size != N)
            {
                PZMath_errno.ERROR("permutation size must be N", PZMath_errno.PZMath_EBADLEN);
            }
            else if (norm.Size != N)
            {
                PZMath_errno.ERROR("norm size must be N", PZMath_errno.PZMath_EBADLEN);
            }
            else
            {
                int i;

                signum = 1;

                p.Init();  /* set to identity */

                /* Compute column norms and store in workspace */

                for (i = 0; i < N; i++)
                {
                    PZMath_vector c = A.Column(i);
                    double x = PZMath_blas.Dnrm2(c);
                    norm[i] = x;
                }

                for (i = 0; i < System.Math.Min(M, N); i++)
                {
                    /* Bring the column of largest norm into the pivot position */

                    double max_norm = norm[i];
                    int j;
                    int kmax = i;

                    for (j = i + 1; j < N; j++)
                    {
                        double x = norm[j];

                        if (x > max_norm)
                        {
                            max_norm = x;
                            kmax = j;
                        }
                    }

                    if (kmax != i)
                    {
                        A.SwapColumns(i, kmax);
                        p.Swap(i, kmax);
                        norm.Swap(i, kmax);
                        signum = - signum;
                    }

                    /* Compute the Householder transformation to reduce the j-th
                       column of the matrix to a multiple of the j-th unit vector */
                {
                    PZMath_vector c_full = A.Column(i);
                    PZMath_vector c = c_full.SubVector(i, M - i);

                    double tau_i = HouseholderTransform(c);
                    tau[i] = tau_i;

                    /* Apply the transformation to the remaining columns */

                    if (i + 1 < N)
                    {
                        PZMath_matrix m = A.Submatrix(i, i + 1, M - i, N - (i + 1));
                        HouseholderHM (tau_i, c, m);
                    }
                }

                    /* Update the norms of the remaining columns too */
                    if (i + 1 < M)
                    {
                        for (j = i + 1; j < N; j++)
                        {
                            double x = norm[j];

                            if (x > 0.0)
                            {
                                double y = 0;
                                double temp= A[i, j] / x;

                                if (System.Math.Abs(temp) >= 1)
                                    y = 0.0;
                                else
                                    y = x * System.Math.Sqrt(1 - temp * temp);

                                /* recompute norm to prevent loss of accuracy */
                                if (System.Math.Abs(y / x) < System.Math.Sqrt(20.0) * PZMath_machine.PZMath_SQRT_DBL_EPSILON)
                                {
                                    PZMath_vector c_full = A.Column(j);
                                    PZMath_vector c = c_full.SubVector(i + 1, M - (i + 1));
                                    y = PZMath_blas.Dnrm2(c);
                                }
                                norm[j] = y;
                            }
                        }
                    }
                }
            }
            return PZMath_errno.PZMath_SUCCESS;
        }
Exemple #2
0
        // These functions factorize the square matrix A into the LU decomposition PA = LU.
        // On output the diagonal and upper triangular part of the input matrix A contain the matrix U.
        // The lower triangular part of the input matrix (excluding the diagonal) contains L.
        // The diagonal elements of L are unity, and are not stored.
        // The permutation matrix P is encoded in the permutation p.
        // The j-th column of the matrix P is given by the k-th column of the identity matrix,
        // where k = p_j the j-th element of the permutation vector.
        // The sign of the permutation is given by signum.
        // It has the value (-1)^n, where n is the number of interchanges in the permutation.
        // The algorithm used in the decomposition is Gaussian Elimination with partial pivoting
        // (Golub & Van Loan, Matrix Computations, Algorithm 3.4.1).
        public static int LUDecomp(PZMath_matrix A, PZMath_permutation p, out int signum)
        {
            if (A.ColumnCount != A.RowCount)
            {
                PZMath_errno.ERROR("PZMath_linalg::LUDecomp(), LU decomposition requires square matrix", PZMath_errno.PZMath_ENOTSQR);
                signum = 1;
                return PZMath_errno.PZMath_ENOTSQR;
            }
            else if (p.Size != A.ColumnCount)
            {
                PZMath_errno.ERROR("PZMath_linalg::LUDecomp(), permutation length must match matrix size", PZMath_errno.PZMath_EBADLEN);
                signum = 1;
                return PZMath_errno.PZMath_EBADLEN;
            }
            else
            {
                int N = A.ColumnCount;
                int i, j, k;

                signum = 1;
                p.Init();

                for (j = 0; j < N - 1; j++)
                {
                    /* Find maximum in the j-th column */
                    double ajj;
                    double max = System.Math.Abs(A[j, j]);
                    int i_pivot = j;

                    for (i = j + 1; i < N; i++)
                    {
                        double aij = System.Math.Abs(A[i, j]);

                        if (aij > max)
                        {
                            max = aij;
                            i_pivot = i;
                        }
                    }

                    if (i_pivot != j)
                    {
                        A.SwapRows(j, i_pivot);
                        p.Swap(j, i_pivot);
                        signum = -(signum);
                    }

                    ajj = A[j, j];

                    if (ajj != 0.0)
                    {
                        for (i = j + 1; i < N; i++)
                        {
                            double aij = A[i, j] / ajj;
                            A[i, j] = aij;

                            for (k = j + 1; k < N; k++)
                            {
                                double aik = A[i, k];
                                double ajk = A[j, k];
                                A[i, k] = aik - aij * ajk;
                            }
                        }
                    }
                }

                return PZMath_errno.PZMath_SUCCESS;
            }
        }