Skip to content

Commit 34fb771

Browse files
committed
eigenvalues: Tridiagonalization
1 parent 63ce2fb commit 34fb771

File tree

7 files changed

+128
-8
lines changed

7 files changed

+128
-8
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ set(${PROJECT_NAME}_DECOMPOSITIONS_HEADERS
240240
include/eigenpy/decompositions/GeneralizedSelfAdjointEigenSolver.hpp
241241
include/eigenpy/decompositions/HessenbergDecomposition.hpp
242242
include/eigenpy/decompositions/RealQZ.hpp
243+
include/eigenpy/decompositions/Tridiagonalization.hpp
243244
include/eigenpy/decompositions/RealSchur.hpp
244245
include/eigenpy/decompositions/ComplexEigenSolver.hpp
245246
include/eigenpy/decompositions/ComplexSchur.hpp
@@ -336,6 +337,7 @@ set(${PROJECT_NAME}_DECOMPOSITIONS_SOURCES
336337
src/decompositions/fullpivlu-solver.cpp
337338
src/decompositions/hessenberg-decomposition.cpp
338339
src/decompositions/real-qz.cpp
340+
src/decompositions/tridiagonalization.cpp
339341
src/decompositions/real-schur.cpp
340342
src/decompositions/partialpivlu-solver.cpp
341343
src/decompositions/minres-solver.cpp

include/eigenpy/decompositions/RealSchur.hpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,20 @@ namespace eigenpy {
1616

1717
template <typename _MatrixType>
1818
struct RealSchurVisitor
19-
: public boost::python::def_visitor<
20-
RealSchurVisitor<_MatrixType>> {
19+
: public boost::python::def_visitor<RealSchurVisitor<_MatrixType>> {
2120
typedef _MatrixType MatrixType;
2221
typedef typename MatrixType::Scalar Scalar;
2322
typedef Eigen::RealSchur<MatrixType> Solver;
2423

2524
template <class PyClass>
2625
void visit(PyClass& cl) const {
27-
cl.def(bp::init<Eigen::DenseIndex>(
28-
bp::arg("size"), "Default constructor. "))
26+
cl.def(
27+
bp::init<Eigen::DenseIndex>(bp::arg("size"), "Default constructor. "))
2928
.def(bp::init<MatrixType, bp::optional<bool>>(
3029
bp::args("matrix", "computeU"),
3130
"Constructor; computes real Schur decomposition of given matrix. "))
3231

33-
.def("compute",
34-
&RealSchurVisitor::compute_proxy<MatrixType>,
32+
.def("compute", &RealSchurVisitor::compute_proxy<MatrixType>,
3533
bp::args("self", "matrix"),
3634
"Computes Schur decomposition of given matrix. ",
3735
bp::return_self<>())
@@ -45,8 +43,7 @@ struct RealSchurVisitor
4543

4644
.def("computeFromHessenberg",
4745
(Solver & (Solver::*)(const MatrixType& matrixH,
48-
const MatrixType& matrixQ,
49-
bool)) &
46+
const MatrixType& matrixQ, bool)) &
5047
Solver::computeFromHessenberg,
5148
bp::args("self", "matrixH", "matrixQ", "computeU"),
5249
"Compute Schur decomposition from a given Hessenberg matrix. ",
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright 2020 INRIA
3+
*/
4+
5+
#ifndef __eigenpy_decompositions_tridiagonalization_hpp__
6+
#define __eigenpy_decompositions_tridiagonalization_hpp__
7+
8+
#include <Eigen/Core>
9+
#include <Eigen/Eigenvalues>
10+
11+
#include "eigenpy/eigen-to-python.hpp"
12+
#include "eigenpy/eigenpy.hpp"
13+
#include "eigenpy/utils/scalar-name.hpp"
14+
15+
namespace eigenpy {
16+
17+
template <typename _MatrixType>
18+
struct TridiagonalizationVisitor
19+
: public boost::python::def_visitor<TridiagonalizationVisitor<_MatrixType>> {
20+
typedef _MatrixType MatrixType;
21+
typedef typename MatrixType::Scalar Scalar;
22+
typedef Eigen::Tridiagonalization<MatrixType> Solver;
23+
24+
template <class PyClass>
25+
void visit(PyClass& cl) const {
26+
cl.def(
27+
bp::init<Eigen::DenseIndex>(bp::arg("size"), "Default constructor. "))
28+
.def(bp::init<MatrixType>(
29+
bp::arg("matrix"),
30+
"Constructor; computes tridiagonal decomposition of given matrix. "))
31+
32+
.def("compute", &TridiagonalizationVisitor::compute_proxy<MatrixType>,
33+
bp::args("self", "matrix"),
34+
"Computes tridiagonal decomposition of given matrix. ",
35+
bp::return_self<>())
36+
.def("compute",
37+
(Solver &
38+
(Solver::*)(const Eigen::EigenBase<MatrixType>& matrix)) &
39+
Solver::compute,
40+
bp::args("self", "matrix"),
41+
"Computes tridiagonal decomposition of given matrix. ", bp::return_self<>())
42+
43+
.def("diagonal", &Solver::diagonal, bp::arg("self"),
44+
"Returns the diagonal of the tridiagonal matrix T in the decomposition. ")
45+
46+
.def("householderCoefficients", &Solver::householderCoefficients,
47+
bp::arg("self"), "Returns the Householder coefficients. ")
48+
49+
.def("matrixQ", &Solver::matrixQ,
50+
bp::arg("self"), "Returns the unitary matrix Q in the decomposition. ")
51+
.def("matrixT", &Solver::matrixT,
52+
bp::arg("self"), "Returns the unitary matrix T in the decomposition. ")
53+
54+
.def("packedMatrix", &Solver::packedMatrix, bp::arg("self"),
55+
"Returns the internal representation of the decomposition. ",
56+
bp::return_value_policy<bp::copy_const_reference>())
57+
58+
.def("subDiagonal", &Solver::subDiagonal, bp::arg("self"),
59+
"Returns the subdiagonal of the tridiagonal matrix T in the decomposition.");
60+
}
61+
62+
static void expose() {
63+
static const std::string classname =
64+
"TridiagonalizationVisitor" + scalar_name<Scalar>::shortname();
65+
expose(classname);
66+
}
67+
68+
static void expose(const std::string& name) {
69+
bp::class_<Solver>(name.c_str(), bp::no_init)
70+
.def(TridiagonalizationVisitor())
71+
.def(IdVisitor<Solver>());
72+
}
73+
74+
private:
75+
template <typename MatrixType>
76+
static Solver& compute_proxy(Solver& self, const Eigen::EigenBase<MatrixType>& matrix) {
77+
return self.compute(matrix);
78+
}
79+
};
80+
81+
} // namespace eigenpy
82+
83+
#endif // ifndef __eigenpy_decompositions_tridiagonalization_hpp__

src/decompositions/decompositions.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ void exposeGeneralizedSelfAdjointEigenSolver();
1515
void exposeHessenbergDecomposition();
1616
void exposeRealQZ();
1717
void exposeRealSchur();
18+
void exposeTridiagonalization();
1819
void exposeComplexEigenSolver();
1920
void exposeComplexSchur();
2021
void exposeLLTSolver();
@@ -41,6 +42,7 @@ void exposeDecompositions() {
4142
exposeHessenbergDecomposition();
4243
exposeRealQZ();
4344
exposeRealSchur();
45+
exposeTridiagonalization();
4446
exposeComplexEigenSolver();
4547
exposeComplexSchur();
4648
exposeLLTSolver();
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
/*
3+
* Copyright 2024 INRIA
4+
*/
5+
6+
#include "eigenpy/decompositions/Tridiagonalization.hpp"
7+
8+
namespace eigenpy {
9+
void exposeTridiagonalization() {
10+
using namespace Eigen;
11+
TridiagonalizationVisitor<MatrixXd>::expose("Tridiagonalization");
12+
}
13+
} // namespace eigenpy

unittest/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ add_python_eigenpy_lib_unit_test("py-real-qz" "unittest/python/test_real_qz.py")
164164
add_python_eigenpy_lib_unit_test("py-real-schur"
165165
"unittest/python/test_real_schur.py")
166166

167+
add_python_eigenpy_lib_unit_test("py-tridiagonalization"
168+
"unittest/python/test_tridiagonalization.py")
169+
167170
add_python_eigenpy_lib_unit_test("py-LLT" "unittest/python/test_LLT.py")
168171

169172
add_python_eigenpy_lib_unit_test("py-LDLT" "unittest/python/test_LDLT.py")
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import numpy as np
2+
3+
import eigenpy
4+
5+
dim = 100
6+
rng = np.random.default_rng()
7+
A = rng.random((dim, dim))
8+
9+
tri = eigenpy.Tridiagonalization(A)
10+
11+
# Q = tri.matrixQ()
12+
# print("Q")
13+
# print(Q)
14+
# Q_conj = Q.conj().T
15+
16+
# T = tri.matrixT()
17+
# print("T")
18+
# print(T)
19+
20+
# assert eigenpy.is_approx(A, Q @ T @ Q_conj)

0 commit comments

Comments
 (0)