Skip to content

Commit da1e7b3

Browse files
committed
decompositions: add LLT
1 parent 0f67ee9 commit da1e7b3

File tree

3 files changed

+105
-0
lines changed

3 files changed

+105
-0
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ SET(${PROJECT_NAME}_SOLVERS_HEADERS
9090
SET(${PROJECT_NAME}_DECOMPOSITIONS_HEADERS
9191
include/eigenpy/decompositions/decompositions.hpp
9292
include/eigenpy/decompositions/EigenSolver.hpp
93+
include/eigenpy/decompositions/LLT.hpp
9394
include/eigenpy/decompositions/SelfAdjointEigenSolver.hpp
9495
)
9596

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright 2020 INRIA
3+
*/
4+
5+
#ifndef __eigenpy_decomposition_llt_hpp__
6+
#define __eigenpy_decomposition_llt_hpp__
7+
8+
#include <boost/python.hpp>
9+
#include <Eigen/Core>
10+
#include <Eigen/Cholesky>
11+
12+
#include "eigenpy/utils/scalar-name.hpp"
13+
14+
namespace eigenpy
15+
{
16+
17+
template<typename _MatrixType>
18+
struct LLTSolverVisitor
19+
: public boost::python::def_visitor< LLTSolverVisitor<_MatrixType> >
20+
{
21+
22+
typedef _MatrixType MatrixType;
23+
typedef typename MatrixType::Scalar Scalar;
24+
typedef typename MatrixType::RealScalar RealScalar;
25+
typedef Eigen::Matrix<Scalar,Eigen::Dynamic,1,MatrixType::Options> VectorType;
26+
typedef Eigen::LLT<MatrixType> Solver;
27+
28+
template<class PyClass>
29+
void visit(PyClass& cl) const
30+
{
31+
namespace bp = boost::python;
32+
cl
33+
.def(bp::init<>("Default constructor"))
34+
.def(bp::init<Eigen::DenseIndex>(bp::arg("size"),
35+
"Default constructor with memory preallocation"))
36+
.def(bp::init<MatrixType>(bp::arg("matrix"),
37+
"Constructs a LLT factorization from a given matrix."))
38+
39+
.def("matrixL",&matrixL,bp::arg("self"),
40+
"Returns the lower triangular matrix L.")
41+
.def("matrixU",&matrixU,bp::arg("self"),
42+
"Returns the upper triangular matrix U.")
43+
.def("matrixLLT",&Solver::matrixLLT,bp::arg("self"),
44+
"Returns the LLT decomposition matrix.",
45+
bp::return_value_policy<bp::return_by_value>())
46+
47+
.def("rankUpdate",(Solver (Solver::*)(const VectorType &, const RealScalar &))&Solver::template rankUpdate<VectorType>,
48+
bp::args("self","vector","sigma"))
49+
50+
.def("adjoint",&Solver::adjoint,bp::arg("self"),
51+
"Returns the adjoint, that is, a reference to the decomposition itself as if the underlying matrix is self-adjoint.",
52+
bp::return_value_policy<bp::reference_existing_object>())
53+
54+
.def("compute",(Solver & (Solver::*)(const Eigen::EigenBase<MatrixType> & matrix))&Solver::compute,
55+
bp::args("self","matrix"),
56+
"Computes the LLT of given matrix.",
57+
bp::return_value_policy<bp::reference_existing_object>())
58+
59+
.def("info",&Solver::info,bp::arg("self"),
60+
"NumericalIssue if the input contains INF or NaN values or overflow occured. Returns Success otherwise.")
61+
62+
.def("rcond",&Solver::rcond,bp::arg("self"),
63+
"Returns an estimate of the reciprocal condition number of the matrix.")
64+
.def("reconstructedMatrix",&Solver::reconstructedMatrix,bp::arg("self"),
65+
"Returns the matrix represented by the decomposition, i.e., it returns the product: L L^*. This function is provided for debug purpose.")
66+
.def("solve",&solve<VectorType>,bp::args("self","b"),
67+
"Returns the solution x of A x = b using the current decomposition of A.")
68+
;
69+
}
70+
71+
static void expose()
72+
{
73+
static const std::string classname = "LLT" + scalar_name<Scalar>::shortname();
74+
expose(classname);
75+
}
76+
77+
static void expose(const std::string & name)
78+
{
79+
namespace bp = boost::python;
80+
bp::class_<Solver>(name.c_str(),
81+
"Standard Cholesky decomposition (LL^T) of a matrix and associated features.\n\n"
82+
"This class performs a LL^T Cholesky decomposition of a symmetric, positive definite matrix A such that A = LL^* = U^*U, where L is lower triangular.\n\n"
83+
"While the Cholesky decomposition is particularly useful to solve selfadjoint problems like D^*D x = b, for that purpose, we recommend the Cholesky decomposition without square root which is more stable and even faster. Nevertheless, this standard Cholesky decomposition remains useful in many other situations like generalised eigen problems with hermitian matrices.",
84+
bp::no_init)
85+
.def(LLTSolverVisitor());
86+
}
87+
88+
private:
89+
90+
static MatrixType matrixL(const Solver & self) { return self.matrixL(); }
91+
static MatrixType matrixU(const Solver & self) { return self.matrixU(); }
92+
93+
template<typename VectorType>
94+
static VectorType solve(const Solver & self, const VectorType & vec)
95+
{
96+
return self.solve(vec);
97+
}
98+
};
99+
100+
} // namespace eigenpy
101+
102+
#endif // ifndef __eigenpy_decomposition_llt_hpp__

src/decompositions/decompositions.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include "eigenpy/decompositions/EigenSolver.hpp"
99
#include "eigenpy/decompositions/SelfAdjointEigenSolver.hpp"
10+
#include "eigenpy/decompositions/LLT.hpp"
1011

1112
namespace eigenpy
1213
{
@@ -17,6 +18,7 @@ namespace eigenpy
1718

1819
EigenSolverVisitor<Eigen::MatrixXd>::expose("EigenSolver");
1920
SelfAdjointEigenSolverVisitor<Eigen::MatrixXd>::expose("SelfAdjointEigenSolver");
21+
LLTSolverVisitor<Eigen::MatrixXd>::expose("LLT");
2022

2123
{
2224
using namespace Eigen;

0 commit comments

Comments
 (0)