Program Listing for File partial-piv-lu.hpp
↰ Return to documentation for file (include/nanoeigenpy/decompositions/partial-piv-lu.hpp
)
#pragma once
#include "nanoeigenpy/fwd.hpp"
#include <Eigen/LU>
namespace nanoeigenpy {
namespace nb = nanobind;
using namespace nb::literals;
template <typename MatrixType, typename MatrixOrVector>
MatrixOrVector solve(const Eigen::PartialPivLU<MatrixType> &c,
const MatrixOrVector &vec) {
return c.solve(vec);
}
template <typename _MatrixType>
void exposePartialPivLU(nb::module_ m, const char *name) {
using MatrixType = _MatrixType;
using Solver = Eigen::PartialPivLU<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,
"LU decomposition of a matrix with partial pivoting, and "
"related features. \n\n"
"This class represents a LU decomposition of a square "
"invertible matrix, with partial pivoting: the matrix "
"A is decomposed as A = PLU where L is unit-lower-triangular, "
"U is upper-triangular, and P is a permutation matrix.\n\n"
"Typically, partial pivoting LU decomposition is only considered "
"numerically stable for square invertible matrices. Thus LAPACK's "
"dgesv and dgesvx require the matrix to be square and invertible. "
"The present class does the same. It will assert that the matrix is "
"square, but it won't (actually it can't) check that the matrix is "
"invertible: it is your task to check that you only use this "
"decomposition on invertible matrices.\n\n"
"The guaranteed safe alternative, working for all matrices, is the "
"full pivoting LU decomposition, provided by class FullPivLU.\n\n"
"This is not a rank-revealing LU decomposition. Many features are "
"intentionally absent from this class, such as rank computation. If "
"you need these features, use class FullPivLU.\n\n"
"This LU decomposition is suitable to invert invertible matrices. "
"It is what MatrixBase::inverse() uses in the general case. On the "
"other hand, it is not suitable to determine whether a given matrix "
"is invertible.\n\n"
"The data of the LU decomposition can be directly accessed through "
"the methods matrixLU(), permutationP().")
.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 LU factorization from a given matrix.")
.def(
"compute",
[](Solver &c, const MatrixType &matrix) -> Solver & {
return c.compute(matrix);
},
"matrix"_a, "Computes the LU of given matrix.",
nb::rv_policy::reference)
.def("matrixLU", &Solver::matrixLU,
"Returns the LU decomposition matrix: the upper-triangular part is "
"U, the "
"unit-lower-triangular part is L (at least for square matrices; in "
"the non-square "
"case, special care is needed, see the documentation of class "
"FullPivLU).",
nb::rv_policy::reference_internal)
.def("permutationP", &Solver::permutationP,
"Returns the permutation matrix P in the decomposition A = P^{-1} L "
"U Q^{-1}.",
nb::rv_policy::reference_internal)
.def("rcond", &Solver::rcond,
"Returns an estimate of the reciprocal condition number of the "
"matrix.")
.def(
"inverse", [](const Solver &c) -> MatrixType { return c.inverse(); },
"Returns the inverse of the matrix associated with the LU "
"decomposition.")
.def("determinant", &Solver::determinant,
"Returns the determinant of the underlying matrix from the "
"current factorization.")
.def("reconstructedMatrix", &Solver::reconstructedMatrix,
"Returns the matrix represented by the decomposition,"
"i.e., it returns the product: P^{-1} L U."
"This function is provided for debug purpose.")
.def("rows", &Solver::rows, "Returns the number of rows of the matrix.")
.def("cols", &Solver::cols, "Returns the number of cols of the matrix.")
.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(IdVisitor());
}
} // namespace nanoeigenpy