eigenpy 3.12.0
Bindings between Numpy and Eigen using Boost.Python
Loading...
Searching...
No Matches
SparseQR.hpp
1/*
2 * Copyright 2025 INRIA
3 */
4
5#ifndef __eigenpy_decompositions_sparse_qr_hpp__
6#define __eigenpy_decompositions_sparse_qr_hpp__
7
8#include <Eigen/SparseQR>
9#include <Eigen/Core>
10
11#include "eigenpy/eigenpy.hpp"
12#include "eigenpy/decompositions/sparse/SparseSolverBase.hpp"
13#include "eigenpy/utils/scalar-name.hpp"
14
15namespace eigenpy {
16
17template <typename SparseQRType>
19 : public boost::python::def_visitor<
20 SparseQRMatrixQTransposeReturnTypeVisitor<SparseQRType>> {
21 typedef typename SparseQRType::Scalar Scalar;
22 typedef Eigen::SparseQRMatrixQTransposeReturnType<SparseQRType>
23 QTransposeType;
24 typedef Eigen::VectorXd VectorXd;
25 typedef Eigen::MatrixXd MatrixXd;
26
27 template <class PyClass>
28 void visit(PyClass& cl) const {
29 cl.def(bp::init<const SparseQRType&>(bp::args("self", "qr")))
30 .def(
31 "__matmul__",
32 +[](QTransposeType& self, const MatrixXd& other) -> MatrixXd {
33 return MatrixXd(self * other);
34 },
35 bp::args("self", "other"))
36
37 .def(
38 "__matmul__",
39 +[](QTransposeType& self, const VectorXd& other) -> VectorXd {
40 return VectorXd(self * other);
41 },
42 bp::args("self", "other"));
43 }
44
45 static void expose() {
46 static const std::string classname = "SparseQRMatrixQTransposeReturnType_" +
47 scalar_name<Scalar>::shortname();
48 expose(classname);
49 }
50
51 static void expose(const std::string& name) {
52 bp::class_<QTransposeType>(
53 name.c_str(), "Eigen SparseQRMatrixQTransposeReturnType", bp::no_init)
56 }
57};
58
59template <typename SparseQRType>
61 : public boost::python::def_visitor<
62 SparseQRMatrixQReturnTypeVisitor<SparseQRType>> {
63 typedef typename SparseQRType::Scalar Scalar;
64 typedef Eigen::SparseQRMatrixQTransposeReturnType<SparseQRType>
65 QTransposeType;
66 typedef Eigen::SparseQRMatrixQReturnType<SparseQRType> QType;
67 typedef typename SparseQRType::QRMatrixType QRMatrixType;
68 typedef Eigen::VectorXd VectorXd;
69 typedef Eigen::MatrixXd MatrixXd;
70
71 template <class PyClass>
72 void visit(PyClass& cl) const {
73 cl.def(bp::init<const SparseQRType&>(bp::args("self", "qr")))
74 .def(
75 "__matmul__",
76 +[](QType& self, const MatrixXd& other) -> MatrixXd {
77 return MatrixXd(self * other);
78 },
79 bp::args("self", "other"))
80
81 .def(
82 "__matmul__",
83 +[](QType& self, const VectorXd& other) -> VectorXd {
84 return VectorXd(self * other);
85 },
86 bp::args("self", "other"))
87
88 .def("rows", &QType::rows)
89 .def("cols", &QType::cols)
90
91 .def(
92 "adjoint",
93 +[](const QType& self) -> QTransposeType { return self.adjoint(); })
94
95 .def(
96 "transpose",
97 +[](const QType& self) -> QTransposeType {
98 return self.transpose();
99 })
100
101 .def(
102 "toSparse",
103 +[](QType& self) -> QRMatrixType {
104 Eigen::Index m = self.rows();
105 MatrixXd I = MatrixXd::Identity(m, m);
106 MatrixXd Q_dense = self * I;
107 return Q_dense.sparseView();
108 },
109 bp::arg("self"),
110 "Convert the Q matrix to a sparse matrix representation.");
111 }
112
113 static void expose() {
114 static const std::string classname =
115 "SparseQRMatrixQReturnType_" + scalar_name<Scalar>::shortname();
116 expose(classname);
117 }
118
119 static void expose(const std::string& name) {
120 bp::class_<QType>(name.c_str(), "Eigen SparseQRMatrixQReturnType",
121 bp::no_init)
123 .def(IdVisitor<QType>());
124 }
125};
126
127template <typename SparseQRType>
129 : public boost::python::def_visitor<SparseQRVisitor<SparseQRType>> {
130 typedef typename SparseQRType::MatrixType MatrixType;
131
132 typedef typename MatrixType::Scalar Scalar;
133 typedef typename MatrixType::RealScalar RealScalar;
134 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1, MatrixType::Options>
135 DenseVectorXs;
136 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic,
137 MatrixType::Options>
138 DenseMatrixXs;
139
140 typedef typename SparseQRType::QRMatrixType QRMatrixType;
141 typedef Eigen::SparseQRMatrixQReturnType<SparseQRType> QType;
142
143 template <class PyClass>
144 void visit(PyClass& cl) const {
145 cl.def(bp::init<>(bp::arg("self"), "Default constructor"))
146 .def(bp::init<MatrixType>(
147 bp::args("self", "mat"),
148 "Construct a QR factorization of the matrix mat."))
149
150 .def("cols", &SparseQRType::cols, bp::arg("self"),
151 "Returns the number of columns of the represented matrix. ")
152 .def("rows", &SparseQRType::rows, bp::arg("self"),
153 "Returns the number of rows of the represented matrix. ")
154
155 .def("compute", &SparseQRType::compute, bp::args("self", "matrix"),
156 "Compute the symbolic and numeric factorization of the input "
157 "sparse matrix. "
158 "The input matrix should be in column-major storage. ")
159 .def("analyzePattern", &SparseQRType::analyzePattern,
160 bp::args("self", "mat"),
161 "Compute the column permutation to minimize the fill-in.")
162 .def("factorize", &SparseQRType::factorize, bp::args("self", "matrix"),
163 "Performs a numeric decomposition of a given matrix.\n"
164 "The given matrix must has the same sparcity than the matrix on "
165 "which the symbolic decomposition has been performed.")
166
167 .def("colsPermutation", &SparseQRType::colsPermutation, bp::arg("self"),
168 "Returns a reference to the column matrix permutation PTc such "
169 "that Pr A PTc = LU.",
170 bp::return_value_policy<bp::copy_const_reference>())
171
172 .def("info", &SparseQRType::info, bp::arg("self"),
173 "NumericalIssue if the input contains INF or NaN values or "
174 "overflow occured. Returns Success otherwise.")
175 .def("lastErrorMessage", &SparseQRType::lastErrorMessage,
176 bp::arg("self"), "Returns a string describing the type of error. ")
177
178 .def("rank", &SparseQRType::rank, bp::arg("self"),
179 "Returns the number of non linearly dependent columns as "
180 "determined "
181 "by the pivoting threshold. ")
182
183 .def(
184 "matrixQ",
185 +[](const SparseQRType& self) -> QType { return self.matrixQ(); },
186 "Returns an expression of the matrix Q as products of sparse "
187 "Householder reflectors.")
188 .def(
189 "matrixR",
190 +[](const SparseQRType& self) -> const QRMatrixType& {
191 return self.matrixR();
192 },
193 "Returns a const reference to the \b sparse upper triangular "
194 "matrix "
195 "R of the QR factorization.",
196 bp::return_value_policy<bp::copy_const_reference>())
197
198 .def("setPivotThreshold", &SparseQRType::setPivotThreshold,
199 bp::args("self", "thresh"),
200 "Set the threshold used for a diagonal entry to be an acceptable "
201 "pivot.")
202
204 }
205
206 static void expose() {
207 static const std::string classname =
208 "SparseQR_" + scalar_name<Scalar>::shortname();
209 expose(classname);
210 }
211
212 static void expose(const std::string& name) {
213 bp::class_<SparseQRType, boost::noncopyable>(
214 name.c_str(),
215 "Sparse left-looking QR factorization with numerical column pivoting. "
216 "This class implements a left-looking QR decomposition of sparse "
217 "matrices "
218 "with numerical column pivoting. When a column has a norm less than a "
219 "given "
220 "tolerance it is implicitly permuted to the end. The QR factorization "
221 "thus "
222 "obtained is given by A*P = Q*R where R is upper triangular or "
223 "trapezoidal. \n\n"
224 "P is the column permutation which is the product of the fill-reducing "
225 "and the "
226 "numerical permutations. \n\n"
227 "Q is the orthogonal matrix represented as products of Householder "
228 "reflectors. \n\n"
229 "R is the sparse triangular or trapezoidal matrix. The later occurs "
230 "when A is rank-deficient. \n\n",
231 bp::no_init)
232 .def(SparseQRVisitor())
234 }
235};
236
237} // namespace eigenpy
238
239#endif // ifndef __eigenpy_decompositions_sparse_qr_hpp__
void expose()
Call the expose function of a given type T.
Definition expose.hpp:23
Add the Python method id to retrieving a unique id for a given object exposed with Boost....
Definition id.hpp:18