1010#include < htool/hmatrix/hmatrix.hpp>
1111#include < htool/hmatrix/hmatrix_output.hpp>
1212#include < htool/hmatrix/linalg/add_hmatrix_vector_product.hpp>
13+ #include < htool/hmatrix/linalg/factorization.hpp>
1314#include < htool/hmatrix/utils/recompression.hpp>
15+ #include < htool/matrix/matrix_view.hpp>
1416
1517#ifdef HAVE_MPI
1618# include " ../misc/wrapper_mpi.hpp"
@@ -53,6 +55,44 @@ void declare_HMatrix(py::module &m, const std::string &className) {
5355 py_class.def (" get_target_cluster" , &HMatrix<CoefficientPrecision, CoordinatePrecision>::get_target_cluster, py::return_value_policy::reference_internal);
5456 py_class.def (" get_source_cluster" , &HMatrix<CoefficientPrecision, CoordinatePrecision>::get_source_cluster, py::return_value_policy::reference_internal);
5557
58+ py_class.def (" lu_factorization" , [](HMatrix<CoefficientPrecision, CoordinatePrecision> &hmatrix) {
59+ htool::lu_factorization (hmatrix);
60+ });
61+ py_class.def (" cholesky_factorization" , [](HMatrix<CoefficientPrecision, CoordinatePrecision> &hmatrix, char UPLO ) {
62+ htool::cholesky_factorization (UPLO , hmatrix);
63+ });
64+ py_class.def (" lu_solve" , [](const Class &self, char trans, const py::array_t <CoefficientPrecision, py::array::f_style> &input) {
65+ std::vector<ssize_t > shape;
66+ if (input.ndim () == 1 ) {
67+ shape = {input.shape ()[0 ]};
68+ } else if (input.ndim () == 2 ) {
69+ shape = {input.shape ()[0 ], input.shape ()[1 ]};
70+ } else {
71+ throw std::runtime_error (" Wrong dimension for HMatrix-LU input" ); // LCOV_EXCL_LINE
72+ }
73+ py::array_t <CoefficientPrecision, py::array::f_style> result (shape);
74+ std::copy_n (input.data (), input.size (), result.mutable_data ());
75+ htool::MatrixView<CoefficientPrecision> output_view (result.shape ()[0 ], input.ndim () == 1 ? 1 : result.shape ()[1 ], result.mutable_data ());
76+ htool::lu_solve (trans, self, output_view);
77+ return result;
78+ });
79+
80+ py_class.def (" cholesky_solve" , [](const Class &self, char UPLO , const py::array_t <CoefficientPrecision, py::array::f_style> &input) {
81+ std::vector<ssize_t > shape;
82+ if (input.ndim () == 1 ) {
83+ shape = {input.shape ()[0 ]};
84+ } else if (input.ndim () == 2 ) {
85+ shape = {input.shape ()[0 ], input.shape ()[1 ]};
86+ } else {
87+ throw std::runtime_error (" Wrong dimension for HMatrix-Cholesky input" ); // LCOV_EXCL_LINE
88+ }
89+ py::array_t <CoefficientPrecision, py::array::f_style> result (shape);
90+ std::copy_n (input.data (), input.size (), result.mutable_data ());
91+ htool::MatrixView<CoefficientPrecision> output_view (result.shape ()[0 ], input.ndim () == 1 ? 1 : result.shape ()[1 ], result.mutable_data ());
92+ htool::cholesky_solve (UPLO , self, output_view);
93+ return result;
94+ });
95+
5696 m.def (" recompression" , &htool::recompression<CoefficientPrecision, CoordinatePrecision, std::function<void (LowRankMatrix<CoefficientPrecision> &)>>);
5797 m.def (" recompression" , [](HMatrix<CoefficientPrecision, CoordinatePrecision> &hmatrix) { recompression (hmatrix); });
5898 m.def (" openmp_recompression" , &htool::openmp_recompression<CoefficientPrecision, CoordinatePrecision, std::function<void (LowRankMatrix<CoefficientPrecision> &)>>);
@@ -69,14 +109,33 @@ void declare_HMatrix(py::module &m, const std::string &className) {
69109 py::array_t <CoefficientPrecision, py::array::f_style> result (self.get_target_cluster ().get_size ());
70110 std::fill_n (result.mutable_data (), self.get_target_cluster ().get_size (), CoefficientPrecision (0 ));
71111
72- htool::Matrix<CoefficientPrecision> dense_mat (self.get_target_cluster ().get_size (), self.get_source_cluster ().get_size ());
73- copy_to_dense_in_user_numbering (self, dense_mat.data ());
74112 char trans = ' N' ;
75113 htool::add_hmatrix_vector_product (trans, CoefficientPrecision (1 ), self, input.data (), CoefficientPrecision (0 ), result.mutable_data ());
76114
77115 return result;
78116 },
79117 " in" _a);
118+
119+ py_class.def (
120+ " __matmul__" , [](const Class &self, const py::array_t <CoefficientPrecision, py::array::f_style> input) {
121+ if (input.ndim () != 2 ) {
122+ throw std::runtime_error (" Wrong dimension for HMatrix-matrix product" ); // LCOV_EXCL_LINE
123+ }
124+ if (input.shape ()[0 ] != self.get_source_cluster ().get_size ()) {
125+ throw std::runtime_error (" Wrong size for HMatrix-matrix product" ); // LCOV_EXCL_LINE
126+ }
127+ py::array_t <CoefficientPrecision, py::array::f_style> result ({input.shape ()[0 ], input.shape ()[1 ]});
128+ std::fill_n (result.mutable_data (), input.shape ()[0 ] * input.shape ()[1 ], CoefficientPrecision (0 ));
129+
130+ htool::MatrixView<const CoefficientPrecision> input_view (input.shape ()[0 ], input.shape ()[1 ], input.data ());
131+ htool::MatrixView<CoefficientPrecision> output_view (input.shape ()[0 ], input.shape ()[1 ], result.mutable_data ());
132+ char transa = ' N' ;
133+ char transb = ' N' ;
134+ htool::add_hmatrix_matrix_product (transa, transb, CoefficientPrecision (1 ), self, input_view, CoefficientPrecision (0 ), output_view);
135+
136+ return result;
137+ },
138+ " in" _a);
80139}
81140
82141#endif
0 commit comments