pairinteraction
A Rydberg Interaction Calculator
Diagonalizer.py.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2024 Pairinteraction Developers
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
5
14
15#include <nanobind/eigen/sparse.h>
16#include <nanobind/nanobind.h>
17#include <nanobind/stl/complex.h>
18#include <nanobind/stl/optional.h>
19
20namespace nb = nanobind;
21using namespace nb::literals;
22using namespace pairinteraction;
23
24template <typename T>
25static void declare_diagonalizer_eigen(nb::module_ &m, std::string const &type_name) {
26 std::string pyclass_name = "DiagonalizerEigen" + type_name;
27 nb::class_<DiagonalizerEigen<T>, DiagonalizerInterface<T>> pyclass(m, pyclass_name.c_str());
28 pyclass.def(nb::init<FloatType>(), "float_type"_a = FloatType::FLOAT64)
29 .def("eigh",
30 nb::overload_cast<const Eigen::SparseMatrix<T, Eigen::RowMajor> &, double>(
31 &DiagonalizerEigen<T>::eigh, nb::const_));
32}
33
34template <typename T>
35static void declare_diagonalizer_feast(nb::module_ &m, std::string const &type_name) {
36 std::string pyclass_name = "DiagonalizerFeast" + type_name;
37 using real_t = typename DiagonalizerFeast<T>::real_t;
38 nb::class_<DiagonalizerFeast<T>, DiagonalizerInterface<T>> pyclass(m, pyclass_name.c_str());
39 pyclass.def(nb::init<int, FloatType>(), "m0"_a, "float_type"_a = FloatType::FLOAT64)
40 .def("eigh",
41 nb::overload_cast<const Eigen::SparseMatrix<T, Eigen::RowMajor> &, double>(
42 &DiagonalizerFeast<T>::eigh, nb::const_))
43 .def("eigh",
44 nb::overload_cast<const Eigen::SparseMatrix<T, Eigen::RowMajor> &,
45 std::optional<real_t>, std::optional<real_t>, double>(
46 &DiagonalizerFeast<T>::eigh, nb::const_));
47}
48
49template <typename T>
50static void declare_diagonalizer_lapacke_evd(nb::module_ &m, std::string const &type_name) {
51 std::string pyclass_name = "DiagonalizerLapackeEvd" + type_name;
52 nb::class_<DiagonalizerLapackeEvd<T>, DiagonalizerInterface<T>> pyclass(m,
53 pyclass_name.c_str());
54 pyclass.def(nb::init<FloatType>(), "float_type"_a = FloatType::FLOAT64)
55 .def("eigh",
56 nb::overload_cast<const Eigen::SparseMatrix<T, Eigen::RowMajor> &, double>(
58}
59
60template <typename T>
61static void declare_diagonalizer_lapacke_evr(nb::module_ &m, std::string const &type_name) {
62 std::string pyclass_name = "DiagonalizerLapackeEvr" + type_name;
63 nb::class_<DiagonalizerLapackeEvr<T>, DiagonalizerInterface<T>> pyclass(m,
64 pyclass_name.c_str());
65 pyclass.def(nb::init<FloatType>(), "float_type"_a = FloatType::FLOAT64)
66 .def("eigh",
67 nb::overload_cast<const Eigen::SparseMatrix<T, Eigen::RowMajor> &, double>(
69}
70
71template <typename T>
72static void declare_diagonalize(nb::module_ &m, std::string const &type_name) {
73 std::string pyclass_name = "diagonalize" + type_name;
74 using real_t = typename T::real_t;
75 using scalar_t = typename T::scalar_t;
76 m.def(
77 pyclass_name.c_str(),
78 [](nb::list pylist, // NOLINT
79 const DiagonalizerInterface<scalar_t> &diagonalizer,
80 std::optional<real_t> min_eigenvalue, std::optional<real_t> max_eigenvalue,
81 double rtol) {
82 std::vector<T> systems;
83 systems.reserve(pylist.size());
84 for (auto h : pylist) {
85 systems.push_back(nb::cast<T>(h));
86 }
87 diagonalize(systems, diagonalizer, min_eigenvalue, max_eigenvalue, rtol);
88 for (size_t i = 0; i < systems.size(); ++i) {
89 pylist[i] = nb::cast(systems[i]);
90 }
91 },
92 "systems"_a, "diagonalizer"_a, "min_eigenvalue"_a = nb::none(),
93 "max_eigenvalue"_a = nb::none(), "rtol"_a = 1e-6);
94}
95
96void bind_diagonalizer(nb::module_ &m) {
97 declare_diagonalizer_eigen<double>(m, "Real");
98 declare_diagonalizer_eigen<std::complex<double>>(m, "Complex");
99 declare_diagonalizer_feast<double>(m, "Real");
100 declare_diagonalizer_feast<std::complex<double>>(m, "Complex");
101 declare_diagonalizer_lapacke_evd<double>(m, "Real");
102 declare_diagonalizer_lapacke_evd<std::complex<double>>(m, "Complex");
103 declare_diagonalizer_lapacke_evr<double>(m, "Real");
104 declare_diagonalizer_lapacke_evr<std::complex<double>>(m, "Complex");
105
106 declare_diagonalize<SystemAtom<double>>(m, "SystemAtomReal");
107 declare_diagonalize<SystemAtom<std::complex<double>>>(m, "SystemAtomComplex");
108
109 declare_diagonalize<SystemPair<double>>(m, "SystemPairReal");
110 declare_diagonalize<SystemPair<std::complex<double>>>(m, "SystemPairComplex");
111}
void bind_diagonalizer(nb::module_ &m)
void diagonalize(std::initializer_list< std::reference_wrapper< Derived > > systems, const DiagonalizerInterface< typename Derived::scalar_t > &diagonalizer, std::optional< typename Derived::real_t > min_eigenenergy={}, std::optional< typename Derived::real_t > max_eigenenergy={}, double rtol=1e-6)
Definition: diagonalize.cpp:17