/// <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); }
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); }