| 22 | namespace cudaq { |
| 23 | |
| 24 | void bindComplexMatrix(nanobind::module_ &mod) { |
| 25 | nanobind::class_<complex_matrix>( |
| 26 | mod, "ComplexMatrix", |
| 27 | "The :class:`ComplexMatrix` is a thin wrapper around a " |
| 28 | "matrix of complex<double> elements.") |
| 29 | .def( |
| 30 | "__init__", |
| 31 | [](complex_matrix *self, nanobind::object b) { |
| 32 | auto arr = nanobind::cast<nanobind::ndarray<>>(b); |
| 33 | if (arr.ndim() != 2) |
| 34 | throw std::runtime_error("ComplexMatrix requires a 2D array"); |
| 35 | if (arr.shape(0) == 0 || arr.shape(1) == 0) |
| 36 | throw std::runtime_error("Matrix dimensions must be non-zero."); |
| 37 | |
| 38 | new (self) complex_matrix(arr.shape(0), arr.shape(1)); |
| 39 | |
| 40 | // Stride-aware element-wise copy so both row-major (C) and |
| 41 | // column-major (Fortran) layouts are handled correctly. |
| 42 | // nanobind strides are counted in elements, not bytes. |
| 43 | auto *dest = self->get_data(complex_matrix::order::row_major); |
| 44 | auto *src = static_cast<std::complex<double> *>(arr.data()); |
| 45 | auto stride0 = arr.stride(0); |
| 46 | auto stride1 = arr.stride(1); |
| 47 | for (size_t i = 0; i < arr.shape(0); ++i) |
| 48 | for (size_t j = 0; j < arr.shape(1); ++j) |
| 49 | dest[i * arr.shape(1) + j] = src[i * stride0 + j * stride1]; |
| 50 | }, |
| 51 | "Create a :class:`ComplexMatrix` from a buffer of data, such as a " |
| 52 | "numpy.ndarray.") |
| 53 | .def( |
| 54 | "to_numpy", |
| 55 | [](complex_matrix &op) { return detail::cmat_to_numpy(op); }, |
| 56 | "Convert to a NumPy array.") |
| 57 | .def( |
| 58 | "num_rows", [](complex_matrix &m) { return m.rows(); }, |
| 59 | "Returns the number of rows in the matrix.") |
| 60 | .def( |
| 61 | "num_columns", [](complex_matrix &m) { return m.cols(); }, |
| 62 | "Returns the number of columns in the matrix.") |
| 63 | .def( |
| 64 | "__getitem__", |
| 65 | [](complex_matrix &m, std::size_t i, std::size_t j) { |
| 66 | return m(i, j); |
| 67 | }, |
| 68 | "Return the matrix element at i, j.") |
| 69 | .def( |
| 70 | "__getitem__", |
| 71 | [](complex_matrix &m, std::tuple<std::size_t, std::size_t> rowCol) { |
| 72 | return m(std::get<0>(rowCol), std::get<1>(rowCol)); |
| 73 | }, |
| 74 | "Return the matrix element at i, j.") |
| 75 | .def("minimal_eigenvalue", &complex_matrix::minimal_eigenvalue, |
| 76 | "Return the lowest eigenvalue for this :class:`ComplexMatrix`.") |
| 77 | .def( |
| 78 | "dump", [](const complex_matrix &self) { self.dump(); }, |
| 79 | "Prints the matrix to the standard output.") |
| 80 | .def( |
| 81 | "__eq__", |