LCOV - code coverage report
Current view: top level - bindings/basis - Basis.py.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 75 76 98.7 %
Date: 2026-10-14 13:16:16 Functions: 13 17 76.5 %

          Line data    Source code
       1             : // SPDX-FileCopyrightText: 2024 PairInteraction Developers
       2             : // SPDX-License-Identifier: LGPL-3.0-or-later
       3             : 
       4             : #include "./Basis.py.hpp"
       5             : 
       6             : #include "pairinteraction/basis/Basis.hpp"
       7             : #include "pairinteraction/basis/BasisAtom.hpp"
       8             : #include "pairinteraction/basis/BasisAtomCreator.hpp"
       9             : #include "pairinteraction/basis/BasisPair.hpp"
      10             : #include "pairinteraction/basis/BasisPairCreator.hpp"
      11             : #include "pairinteraction/database/Database.hpp"
      12             : #include "pairinteraction/interfaces/SorterBuilderInterface.hpp"
      13             : #include "pairinteraction/ket/KetAtom.hpp"
      14             : #include "pairinteraction/ket/KetPair.hpp"
      15             : 
      16             : #include <nanobind/eigen/sparse.h>
      17             : #include <nanobind/nanobind.h>
      18             : #include <nanobind/stl/complex.h>
      19             : #include <nanobind/stl/shared_ptr.h>
      20             : #include <nanobind/stl/string.h>
      21             : #include <nanobind/stl/vector.h>
      22             : 
      23             : namespace nb = nanobind;
      24             : using namespace pairinteraction;
      25             : 
      26             : template <typename T>
      27           8 : static void declare_basis(nb::module_ &m, std::string const &type_name) {
      28           8 :     std::string pyclass_name = "Basis" + type_name;
      29             :     using scalar_t = typename Basis<T>::scalar_t;
      30           8 :     nb::class_<Basis<T>, SorterBuilderInterface> pyclass(m, pyclass_name.c_str());
      31           8 :     pyclass.def("get_kets", &Basis<T>::get_kets)
      32           8 :         .def("get_ket", &Basis<T>::get_ket)
      33           8 :         .def("get_state", &Basis<T>::get_state)
      34           8 :         .def("get_number_of_states", &Basis<T>::get_number_of_states)
      35           8 :         .def("get_number_of_kets", &Basis<T>::get_number_of_kets)
      36           8 :         .def("has_quantum_number", &Basis<T>::has_quantum_number)
      37           8 :         .def("has_energy", &Basis<T>::has_energy)
      38           8 :         .def("is_sorted_by_energy", &Basis<T>::is_sorted_by_energy)
      39           8 :         .def("get_quantum_number", &Basis<T>::get_quantum_number)
      40           8 :         .def("get_energy", &Basis<T>::get_energy)
      41           8 :         .def("get_coefficients", &Basis<T>::get_coefficients)
      42           8 :         .def("copy_with_coefficients", &Basis<T>::copy_with_coefficients)
      43           8 :         .def("get_sorter", &Basis<T>::get_sorter)
      44          16 :         .def("get_indices_of_blocks", &Basis<T>::get_indices_of_blocks)
      45           8 :         .def("transformed",
      46           8 :              [](const Basis<T> &self,
      47             :                 const Eigen::SparseMatrix<scalar_t, Eigen::RowMajor> &transformation) {
      48           0 :                  return self.transformed(transformation);
      49             :              })
      50           8 :         .def("transformed",
      51           8 :              nb::overload_cast<const Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic> &>(
      52             :                  &Basis<T>::transformed, nb::const_))
      53           8 :         .def("canonicalized", &Basis<T>::canonicalized)
      54           8 :         .def("is_canonical", &Basis<T>::is_canonical)
      55           8 :         .def("merge", &Basis<T>::merge);
      56           8 : }
      57             : 
      58             : template <typename T>
      59           4 : static void declare_basis_atom(nb::module_ &m, std::string const &type_name) {
      60           4 :     std::string pyclass_name = "BasisAtom" + type_name;
      61           4 :     nb::class_<BasisAtom<T>, Basis<BasisAtom<T>>> pyclass(m, pyclass_name.c_str());
      62           4 :     pyclass.def("get_matrix_elements", &BasisAtom<T>::get_matrix_elements);
      63           4 : }
      64             : 
      65             : template <typename T>
      66           4 : static void declare_basis_atom_creator(nb::module_ &m, std::string const &type_name) {
      67           4 :     std::string pyclass_name = "BasisAtomCreator" + type_name;
      68           8 :     nb::class_<BasisAtomCreator<T>> pyclass(m, pyclass_name.c_str());
      69             :     // keep_alive because the creator stores a reference to the database
      70          12 :     pyclass.def(nb::init<Database &>(), nb::keep_alive<1, 2>())
      71           4 :         .def("set_species", &BasisAtomCreator<T>::set_species)
      72           4 :         .def("restrict_energy", &BasisAtomCreator<T>::restrict_energy)
      73           4 :         .def("restrict_quantum_number", &BasisAtomCreator<T>::restrict_quantum_number)
      74           4 :         .def("set_quantum_number_standard_deviation_factor",
      75           4 :              &BasisAtomCreator<T>::set_quantum_number_standard_deviation_factor)
      76           4 :         .def("add_ket", &BasisAtomCreator<T>::add_ket)
      77           8 :         .def("create", &BasisAtomCreator<T>::create, nb::call_guard<nb::gil_scoped_release>());
      78           4 : }
      79             : 
      80             : template <typename T>
      81           4 : static void declare_basis_pair(nb::module_ &m, std::string const &type_name) {
      82           4 :     std::string pyclass_name = "BasisPair" + type_name;
      83           4 :     nb::class_<BasisPair<T>, Basis<BasisPair<T>>> pyclass(m, pyclass_name.c_str());
      84           4 :     pyclass.def("get_matrix_elements", &BasisPair<T>::get_matrix_elements)
      85           4 :         .def("get_basis1", &BasisPair<T>::get_basis1)
      86           4 :         .def("get_basis2", &BasisPair<T>::get_basis2);
      87           4 : }
      88             : 
      89             : template <typename T>
      90           4 : static void declare_basis_pair_creator(nb::module_ &m, std::string const &type_name) {
      91           4 :     std::string pyclass_name = "BasisPairCreator" + type_name;
      92           8 :     nb::class_<BasisPairCreator<T>> pyclass(m, pyclass_name.c_str());
      93             :     pyclass
      94          12 :         .def(nb::init<std::shared_ptr<const BasisAtom<T>>, std::shared_ptr<const BasisAtom<T>>>())
      95           4 :         .def("restrict_energy", &BasisPairCreator<T>::restrict_energy)
      96           4 :         .def("restrict_quantum_number_m", &BasisPairCreator<T>::restrict_quantum_number_m)
      97           4 :         .def("restrict_parity_under_inversion",
      98           4 :              &BasisPairCreator<T>::restrict_parity_under_inversion)
      99           4 :         .def("restrict_parity_under_permutation",
     100           4 :              &BasisPairCreator<T>::restrict_parity_under_permutation)
     101           8 :         .def("create", &BasisPairCreator<T>::create, nb::call_guard<nb::gil_scoped_release>());
     102           4 : }
     103             : 
     104           2 : void bind_basis(nb::module_ &m) {
     105           2 :     declare_basis<BasisAtom<double>>(m, "BasisAtomReal");
     106           2 :     declare_basis<BasisAtom<std::complex<double>>>(m, "BasisAtomComplex");
     107           2 :     declare_basis_atom<double>(m, "Real");
     108           2 :     declare_basis_atom<std::complex<double>>(m, "Complex");
     109           2 :     declare_basis_atom_creator<double>(m, "Real");
     110           2 :     declare_basis_atom_creator<std::complex<double>>(m, "Complex");
     111             : 
     112           2 :     declare_basis<BasisPair<double>>(m, "BasisPairReal");
     113           2 :     declare_basis<BasisPair<std::complex<double>>>(m, "BasisPairComplex");
     114           2 :     declare_basis_pair<double>(m, "Real");
     115           2 :     declare_basis_pair<std::complex<double>>(m, "Complex");
     116           2 :     declare_basis_pair_creator<double>(m, "Real");
     117           2 :     declare_basis_pair_creator<std::complex<double>>(m, "Complex");
     118           2 : }

Generated by: LCOV version 1.16