15#include <nanobind/eigen/sparse.h>
16#include <nanobind/nanobind.h>
17#include <nanobind/stl/complex.h>
18#include <nanobind/stl/optional.h>
20namespace nb = nanobind;
21using namespace nb::literals;
25static void declare_diagonalizer_eigen(nb::module_ &m, std::string
const &type_name) {
26 std::string pyclass_name =
"DiagonalizerEigen" + type_name;
28 pyclass.def(nb::init<FloatType>(),
"float_type"_a = FloatType::FLOAT64)
30 nb::overload_cast<
const Eigen::SparseMatrix<T, Eigen::RowMajor> &,
double>(
35static void declare_diagonalizer_feast(nb::module_ &m, std::string
const &type_name) {
36 std::string pyclass_name =
"DiagonalizerFeast" + type_name;
39 pyclass.def(nb::init<int, FloatType>(),
"m0"_a,
"float_type"_a = FloatType::FLOAT64)
41 nb::overload_cast<
const Eigen::SparseMatrix<T, Eigen::RowMajor> &,
double>(
44 nb::overload_cast<
const Eigen::SparseMatrix<T, Eigen::RowMajor> &,
45 std::optional<real_t>, std::optional<real_t>,
double>(
50static void declare_diagonalizer_lapacke_evd(nb::module_ &m, std::string
const &type_name) {
51 std::string pyclass_name =
"DiagonalizerLapackeEvd" + type_name;
53 pyclass_name.c_str());
54 pyclass.def(nb::init<FloatType>(),
"float_type"_a = FloatType::FLOAT64)
56 nb::overload_cast<
const Eigen::SparseMatrix<T, Eigen::RowMajor> &,
double>(
61static void declare_diagonalizer_lapacke_evr(nb::module_ &m, std::string
const &type_name) {
62 std::string pyclass_name =
"DiagonalizerLapackeEvr" + type_name;
64 pyclass_name.c_str());
65 pyclass.def(nb::init<FloatType>(),
"float_type"_a = FloatType::FLOAT64)
67 nb::overload_cast<
const Eigen::SparseMatrix<T, Eigen::RowMajor> &,
double>(
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;
80 std::optional<real_t> min_eigenvalue, std::optional<real_t> max_eigenvalue,
82 std::vector<T> systems;
83 systems.reserve(pylist.size());
84 for (auto h : pylist) {
85 systems.push_back(nb::cast<T>(h));
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]);
92 "systems"_a,
"diagonalizer"_a,
"min_eigenvalue"_a = nb::none(),
93 "max_eigenvalue"_a = nb::none(),
"rtol"_a = 1e-6);
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");
106 declare_diagonalize<SystemAtom<double>>(m,
"SystemAtomReal");
107 declare_diagonalize<SystemAtom<std::complex<double>>>(m,
"SystemAtomComplex");
109 declare_diagonalize<SystemPair<double>>(m,
"SystemPairReal");
110 declare_diagonalize<SystemPair<std::complex<double>>>(m,
"SystemPairComplex");
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)