diff --git a/CMakeLists.txt b/CMakeLists.txt index fe859582faa995cff49c742fec3cfdc482f5e690..89d3ad7e784d46f4e150935828711a90623b6af1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -142,7 +142,8 @@ set(${PROJECT_NAME}_DECOMPOSITIONS_SPARSE_CHOLMOD_HEADERS set(${PROJECT_NAME}_DECOMPOSITIONS_SPARSE_HEADERS include/eigenpy/decompositions/sparse/LLT.hpp include/eigenpy/decompositions/sparse/LDLT.hpp - include/eigenpy/decompositions/sparse/SimplicialCholesky.hpp) + include/eigenpy/decompositions/sparse/SimplicialCholesky.hpp + include/eigenpy/decompositions/sparse/SparseSolverBase.hpp) if(BUILD_WITH_CHOLMOD_SUPPORT) list(APPEND ${PROJECT_NAME}_DECOMPOSITIONS_SPARSE_HEADERS diff --git a/include/eigenpy/decompositions/sparse/SimplicialCholesky.hpp b/include/eigenpy/decompositions/sparse/SimplicialCholesky.hpp index 3bbdd18020b5f938bfbec6c3aea9ab57dbf4a3a3..ad109140b08eeb79e8705ce419086203bd6a6721 100644 --- a/include/eigenpy/decompositions/sparse/SimplicialCholesky.hpp +++ b/include/eigenpy/decompositions/sparse/SimplicialCholesky.hpp @@ -7,6 +7,7 @@ #include "eigenpy/eigenpy.hpp" #include "eigenpy/eigen/EigenBase.hpp" +#include "eigenpy/decompositions/sparse/SparseSolverBase.hpp" #include <Eigen/SparseCholesky> @@ -37,6 +38,7 @@ struct SimplicialCholeskyVisitor "problems having the same structure.") .def(EigenBaseVisitor<Solver>()) + .def(SparseSolverBaseVisitor<Solver>()) .def("matrixL", &matrixL, bp::arg("self"), "Returns the lower triangular matrix L.") @@ -74,33 +76,17 @@ struct SimplicialCholeskyVisitor "scale=1.", bp::return_self<>()) - .def("solve", &solve<DenseVectorXs>, bp::args("self", "b"), - "Returns the solution x of A x = b using the current " - "decomposition of A.") - .def("solve", &solve<DenseMatrixXs>, bp::args("self", "B"), - "Returns the solution X of A X = B using the current " - "decomposition of A where B is a right hand side matrix.") - .def("permutationP", &Solver::permutationP, bp::arg("self"), "Returns the permutation P.", bp::return_value_policy<bp::copy_const_reference>()) .def("permutationPinv", &Solver::permutationPinv, bp::arg("self"), "Returns the inverse P^-1 of the permutation P.", - bp::return_value_policy<bp::copy_const_reference>()) - - .def("solve", &solve<MatrixType>, bp::args("self", "B"), - "Returns the solution X of A X = B using the current " - "decomposition of A where B is a right hand side matrix."); + bp::return_value_policy<bp::copy_const_reference>()); } private: static MatrixType matrixL(const Solver &self) { return self.matrixL(); } static MatrixType matrixU(const Solver &self) { return self.matrixU(); } - - template <typename MatrixOrVector> - static MatrixOrVector solve(const Solver &self, const MatrixOrVector &vec) { - return self.solve(vec); - } }; } // namespace eigenpy diff --git a/include/eigenpy/decompositions/sparse/SparseSolverBase.hpp b/include/eigenpy/decompositions/sparse/SparseSolverBase.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2afc1b917d1060ef037f5186f3b885f340cfc87d --- /dev/null +++ b/include/eigenpy/decompositions/sparse/SparseSolverBase.hpp @@ -0,0 +1,54 @@ +/* + * Copyright 2024 INRIA + */ + +#ifndef __eigenpy_decomposition_sparse_sparse_solver_base_hpp__ +#define __eigenpy_decomposition_sparse_sparse_solver_base_hpp__ + +#include "eigenpy/eigenpy.hpp" +#include "eigenpy/eigen/EigenBase.hpp" + +#include <Eigen/SparseCholesky> + +namespace eigenpy { + +template <typename SimplicialDerived> +struct SparseSolverBaseVisitor + : public boost::python::def_visitor< + SparseSolverBaseVisitor<SimplicialDerived> > { + typedef SimplicialDerived Solver; + + typedef typename SimplicialDerived::MatrixType MatrixType; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + + typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1, MatrixType::Options> + DenseVectorXs; + typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, + MatrixType::Options> + DenseMatrixXs; + + template <class PyClass> + void visit(PyClass &cl) const { + cl.def("solve", &solve<DenseVectorXs>, bp::args("self", "b"), + "Returns the solution x of A x = b using the current " + "decomposition of A.") + .def("solve", &solve<DenseMatrixXs>, bp::args("self", "B"), + "Returns the solution X of A X = B using the current " + "decomposition of A where B is a right hand side matrix.") + + .def("solve", &solve<MatrixType>, bp::args("self", "B"), + "Returns the solution X of A X = B using the current " + "decomposition of A where B is a right hand side matrix."); + } + + private: + template <typename MatrixOrVector> + static MatrixOrVector solve(const Solver &self, const MatrixOrVector &vec) { + return self.solve(vec); + } +}; + +} // namespace eigenpy + +#endif // ifndef __eigenpy_decomposition_sparse_sparse_solver_base_hpp__ diff --git a/include/eigenpy/decompositions/sparse/cholmod/CholmodBase.hpp b/include/eigenpy/decompositions/sparse/cholmod/CholmodBase.hpp index bca0e7f19838cfc77eae9bc89a3cfefd14c6701c..9df15099ee9b361614d4fa576702ee6ec5412f9b 100644 --- a/include/eigenpy/decompositions/sparse/cholmod/CholmodBase.hpp +++ b/include/eigenpy/decompositions/sparse/cholmod/CholmodBase.hpp @@ -7,6 +7,7 @@ #include "eigenpy/eigenpy.hpp" #include "eigenpy/eigen/EigenBase.hpp" +#include "eigenpy/decompositions/sparse/SparseSolverBase.hpp" #include <Eigen/CholmodSupport> @@ -23,12 +24,6 @@ struct CholmodBaseVisitor typedef MatrixType CholMatrixType; typedef typename MatrixType::StorageIndex StorageIndex; - typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1, MatrixType::Options> - DenseVectorXs; - typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, - MatrixType::Options> - DenseMatrixXs; - template <class PyClass> void visit(PyClass &cl) const { cl.def("analyzePattern", &Solver::analyzePattern, @@ -38,6 +33,7 @@ struct CholmodBaseVisitor "problems having the same structure.") .def(EigenBaseVisitor<Solver>()) + .def(SparseSolverBaseVisitor<Solver>()) .def("compute", (Solver & (Solver::*)(const MatrixType &matrix)) & Solver::compute, @@ -70,24 +66,7 @@ struct CholmodBaseVisitor "are transformed by the following linear model: d_ii = offset + " "d_ii.\n" "The default is the identity transformation with offset=0.", - bp::return_self<>()) - - .def("solve", &solve<DenseVectorXs>, bp::args("self", "b"), - "Returns the solution x of A x = b using the current " - "decomposition of A.") - .def("solve", &solve<DenseMatrixXs>, bp::args("self", "B"), - "Returns the solution X of A X = B using the current " - "decomposition of A where B is a right hand side matrix.") - - .def("solve", &solve<MatrixType>, bp::args("self", "B"), - "Returns the solution X of A X = B using the current " - "decomposition of A where B is a right hand side matrix."); - } - - private: - template <typename MatrixOrVector> - static MatrixOrVector solve(const Solver &self, const MatrixOrVector &vec) { - return self.solve(vec); + bp::return_self<>()); } };