Program Listing for File ldlt.hpp
↰ Return to documentation for file (include/nanoeigenpy/decompositions/ldlt.hpp
)
#pragma once
#include "nanoeigenpy/fwd.hpp"
#include "nanoeigenpy/eigen-base.hpp"
#include <Eigen/Cholesky>
namespace nanoeigenpy {
namespace nb = nanobind;
using namespace nb::literals;
template <typename MatrixType, typename MatrixOrVector>
MatrixOrVector solve(const Eigen::LDLT<MatrixType> &c,
const MatrixOrVector &vec) {
return c.solve(vec);
}
template <typename _MatrixType>
void exposeLDLT(nb::module_ m, const char *name) {
using MatrixType = _MatrixType;
using Solver = Eigen::LDLT<MatrixType>;
using Scalar = typename MatrixType::Scalar;
using VectorType = Eigen::Matrix<Scalar, -1, 1>;
if (check_registration_alias<Solver>(m)) {
return;
}
nb::class_<Solver>(
m, name,
"Robust Cholesky decomposition of a matrix with pivoting.\n\n"
"Perform a robust Cholesky decomposition of a positive semidefinite "
"or "
"negative semidefinite matrix $ A $ such that $ A = P^TLDL^*P $, "
"where "
"P is a permutation matrix, L is lower triangular with a unit "
"diagonal "
"and D is a diagonal matrix.\n\n"
"The decomposition uses pivoting to ensure stability, so that L will "
"have zeros in the bottom right rank(A) - n submatrix. Avoiding the "
"square root on D also stabilizes the computation.")
.def(nb::init<>(), "Default constructor.")
.def(nb::init<Eigen::DenseIndex>(), "size"_a,
"Default constructor with memory preallocation.")
.def(nb::init<const MatrixType &>(), "matrix"_a,
"Constructs a LLT factorization from a given matrix.")
.def(EigenBaseVisitor())
.def("isNegative", &Solver::isNegative,
"Returns true if the matrix is negative (semidefinite).")
.def("isPositive", &Solver::isPositive,
"Returns true if the matrix is positive (semidefinite).")
.def(
"matrixL", [](const Solver &c) -> MatrixType { return c.matrixL(); },
"Returns the lower triangular matrix L.")
.def(
"matrixU", [](const Solver &c) -> MatrixType { return c.matrixU(); },
"Returns the upper triangular matrix U.")
.def(
"vectorD", [](const Solver &c) -> VectorType { return c.vectorD(); },
"Returns the coefficients of the diagonal matrix D.")
.def("matrixLDLT", &Solver::matrixLDLT,
"Returns the LDLT decomposition matrix made of the lower matrix "
"L, the diagonal D, then the remaining part that corresponds to "
"A.",
nb::rv_policy::reference_internal)
.def(
"transpositionsP",
[](const Solver &c) -> MatrixType {
return c.transpositionsP() *
MatrixType::Identity(c.matrixL().rows(), c.matrixL().rows());
},
"Returns the permutation matrix P.")
.def(
"rankUpdate",
[](Solver &c, const VectorType &w, Scalar sigma) -> Solver & {
return c.rankUpdate(w, sigma);
},
"If LDL^* = A, then it becomes A + sigma * v v^*", "w"_a, "sigma"_a)
.def("adjoint", &Solver::adjoint,
"Returns the adjoint, that is, a reference to the decomposition "
"itself as if the underlying matrix is self-adjoint.",
nb::rv_policy::reference)
.def(
"compute",
[](Solver &c, const MatrixType &matrix) -> Solver & {
return c.compute(matrix);
},
"matrix"_a, "Computes the LDLT of given matrix.",
nb::rv_policy::reference)
.def("info", &Solver::info,
"NumericalIssue if the input contains INF or NaN values or "
"overflow occured. Returns Success otherwise.")
.def("rcond", &Solver::rcond,
"Returns an estimate of the reciprocal condition number of the "
"matrix.")
.def("reconstructedMatrix", &Solver::reconstructedMatrix,
"Returns the matrix represented by the decomposition, i.e., it "
"returns the product: L L^*. This function is provided for debug "
"purpose.")
.def(
"solve",
[](const Solver &c, const VectorType &b) -> VectorType {
return solve(c, b);
},
"b"_a,
"Returns the solution x of A x = b using the current "
"decomposition of A.")
.def(
"solve",
[](const Solver &c, const MatrixType &B) -> MatrixType {
return solve(c, B);
},
"B"_a,
"Returns the solution X of A X = B using the current "
"decomposition of A where B is a right hand side matrix.")
.def("setZero", &Solver::setZero, "Clear any existing decomposition.")
.def(IdVisitor());
}
} // namespace nanoeigenpy