コード例 #1
0
        /// <summary>
        /// Gets the Cholesky decomposition of the matrix (L*L' = A), replacing its contents.
        /// </summary>
        /// <param name="isPosDef">True if <c>this</c> is positive definite, otherwise false.</param>
        /// <returns>The Cholesky decomposition L.  If <c>this</c> is positive semidefinite,
        /// then L will satisfy L*L' = A.
        /// Otherwise, L will only approximately satisfy L*L' = A.</returns>
        /// <remarks>
        /// <c>this</c> must be symmetric, but need not be positive definite.
        /// </remarks>
        public LowerTriangularMatrix CholeskyInPlace(out bool isPosDef)
        {
            LowerTriangularMatrix L = new LowerTriangularMatrix(rows, cols, data);

#if LAPACK
            isPosDef = Lapack.CholeskyInPlace(this);
#else
            isPosDef = L.SetToCholesky(this);
#endif
            return(L);
        }
コード例 #2
0
        public bool SetToCholesky(Matrix A)
        {
            A.CheckSymmetry(nameof(A));
#if LAPACK
            SetTo(A);
            bool isPosDef = Lapack.CholeskyInPlace(this);
#else
            CheckCompatible(A, nameof(A));

            bool isPosDef           = true;
            LowerTriangularMatrix L = this;
            // compute the Cholesky factor
            // Reference: Golub and van Loan (1996)
            for (int i = 0; i < A.Cols; i++)
            {
                // upper triangle
                for (int j = 0; j < i; j++)
                {
                    L[j, i] = 0;
                }
                // lower triangle
                for (int j = i; j < A.Rows; j++)
                {
                    double sum    = A[i, j];
                    int    index1 = i * cols;
                    int    index2 = j * cols;
                    for (int k = 0; k < i; k++)
                    {
                        //sum -= L[i, k] * L[j, k];
                        sum -= data[index1++] * data[index2++];
                    }
                    if (i == j)
                    {
                        // diagonal entry
                        if (sum <= 0)
                        {
                            isPosDef = false;
                            L[i, i]  = 0;
                        }
                        else
                        {
                            L[i, i] = System.Math.Sqrt(sum);
                        }
                    }
                    else
                    {
                        // off-diagonal entry
                        if (L[i, i] > 0)
                        {
                            L[j, i] = sum / L[i, i];
                        }
                        else
                        {
                            L[j, i] = 0;
                        }
                    }
                }
            }
            CheckLowerTriangular();
#endif
            return(isPosDef);
        }