| 66 | } |
| 67 | |
| 68 | void AddMatrixToPython(pybind11::module& m) |
| 69 | { |
| 70 | //here we add the dense matrix |
| 71 | auto matrix_binder = CreateMatrixInterface< DenseMatrix<double> >(m,"Matrix"); |
| 72 | matrix_binder.def(py::init<const DenseMatrix<double>::size_type, const DenseMatrix<double>::size_type>()); |
| 73 | matrix_binder.def(py::init( [](py::buffer b){ |
| 74 | py::buffer_info info = b.request(); |
| 75 | KRATOS_ERROR_IF( info.format != py::format_descriptor<double>::value ) << "Expected a double array\n"; |
| 76 | KRATOS_ERROR_IF( info.ndim != 2 ) << "Buffer dimension of 2 is required, got: " << info.ndim << std::endl; |
| 77 | DenseMatrix<double> matrix = DenseMatrix<double>(info.shape[0], info.shape[1]); |
| 78 | std::array<std::size_t,2> strides {info.strides[0] / static_cast<std::size_t>(info.itemsize), |
| 79 | info.strides[1] / static_cast<std::size_t>(info.itemsize)}; |
| 80 | |
| 81 | for( int i=0; i<info.shape[0]; ++i ) { |
| 82 | for( int j=0; j<info.shape[1]; ++j ) { |
| 83 | matrix(i,j) = static_cast<double *>(info.ptr)[i * strides[0] + j * strides[1]]; |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | return matrix; |
| 88 | })); |
| 89 | |
| 90 | matrix_binder.def(py::init([](const py::list& input){ |
| 91 | std::size_t num_rows = input.size(); |
| 92 | if( num_rows == 0 || ( (num_rows == 1) && (py::len(input[0]) == 0) ) ) |
| 93 | return DenseMatrix<double>(0,0); |
| 94 | else{ |
| 95 | std::size_t num_cols = py::len(input[0]); |
| 96 | DenseMatrix<double>matrix = DenseMatrix<double>(num_rows, num_cols); |
| 97 | for(std::size_t i = 0; i < num_rows; i++){ |
| 98 | const auto row = py::cast<py::list>(input[i]); |
| 99 | KRATOS_ERROR_IF( py::len(row) != num_cols ) << "Wrong size of a row " << i << "! Expected " << num_cols << ", got " << py::len(row) << std::endl;; |
| 100 | for(std::size_t j = 0; j < num_cols; j++){ |
| 101 | matrix(i,j) = py::cast<double>(row[j]); |
| 102 | } |
| 103 | } |
| 104 | return matrix; |
| 105 | } |
| 106 | })); |
| 107 | |
| 108 | matrix_binder.def(py::init<const DenseMatrix<double>::size_type, const DenseMatrix<double>::size_type, const DenseMatrix<double>::value_type >()); |
| 109 | matrix_binder.def("fill", [](DenseMatrix<double>& self, const typename DenseMatrix<double>::value_type value) { noalias(self) = DenseMatrix<double>(self.size1(),self.size2(),value); }); |
| 110 | matrix_binder.def("fill_identity", [](DenseMatrix<double>& self) { noalias(self) = IdentityMatrix(self.size1()); }); |
| 111 | matrix_binder.def("transpose", [](DenseMatrix<double>& self) { return Matrix(trans(self)); }); |
| 112 | matrix_binder.def(py::init<const DenseMatrix<double>& >()); |
| 113 | matrix_binder.def("__mul__", [](const DenseMatrix<double>& m1, const Vector& v){ return Vector(prod(m1,v));}, py::is_operator()); |
| 114 | matrix_binder.def("__mul__", [](const DenseMatrix<double>& m1, const array_1d<double,3>& v){ if(m1.size2() != 3) KRATOS_ERROR << "matrix size2 is not 3!" << std::endl; return Vector(prod(m1,v));}, py::is_operator()); |
| 115 | matrix_binder.def_buffer( [](DenseMatrix<double>& self)-> py::buffer_info{ |
| 116 | return py::buffer_info( |
| 117 | self.data().begin(), |
| 118 | sizeof(double), |
| 119 | py::format_descriptor<double>::format(), |
| 120 | 2, |
| 121 | {self.size1(),self.size2()}, |
| 122 | {sizeof(double)*self.size2(), |
| 123 | sizeof(double) } |
| 124 | ); |
| 125 | }); |
no test coverage detected