35#include <itertools/itertools.hpp>
40#include <initializer_list>
46namespace triqs::atom_diag {
49 using namespace triqs::hilbert_space;
50 using namespace triqs::arrays;
54 template <
bool C>
struct atom_diag_worker;
94 using scalar_t = std::conditional_t<Complex, std::complex<double>,
double>;
141 [[nodiscard]]
static std::string
hdf5_format() {
return "atom_diag::eigensystem_t"; }
151 auto gr = g.create_group(name);
164 auto gr = g.open_group(name);
209 os <<
"Operator block matrix:\n"
210 <<
" n_blocks = " << op_mat.n_blocks() <<
"\n";
211 for (
auto bidx : range(op_mat.n_blocks())) {
212 auto &m = op_mat.block_mat[bidx];
213 auto b2 = op_mat.connection(bidx);
215 <<
"blocks (" << bidx <<
", " << b2 <<
") "
216 <<
"size (" << first_dim(m) <<
", " << second_dim(m) <<
") " << op_mat.block_mat[bidx] <<
"\n";
325 int get_subspace_dim(
int sp_index)
const {
return eigensystems[sp_index].eigenvalues.size(); }
344 C2PY_IGNORE std::vector<fock_state_t>
const &
get_fock_states(
int sp_index)
const {
return sub_hilbert_spaces[sp_index].get_all_fock_states(); }
352 C2PY_PROPERTY_GET(fock_states) std::vector<std::vector<fock_state_t>>
get_fock_states()
const {
353 std::vector<std::vector<fock_state_t>> fock_states(
n_subspaces());
354 for (
auto i : range(
n_subspaces())) fock_states[i] = sub_hilbert_spaces[i].get_all_fock_states();
365 matrix<scalar_t>
const &
get_unitary_matrix(
int sp_index)
const {
return eigensystems[sp_index].unitary_matrix; }
401 return range{first_eigenstate_of_subspace[sp_index], first_eigenstate_of_subspace[sp_index] +
get_subspace_dim(sp_index)};
405 C2PY_IGNORE std::vector<eigensystem_t>
const &
get_eigensystems()
const {
return eigensystems; }
414 double get_eigenvalue(
int sp_index,
int i)
const {
return eigensystems[sp_index].eigenvalues[i]; }
422 C2PY_PROPERTY_GET(energies) std::vector<std::vector<double>>
get_energies()
const;
430 C2PY_PROPERTY_GET(quantum_numbers) std::vector<std::vector<quantum_number_t>>
const &
get_quantum_numbers()
const {
return quantum_numbers; }
433 C2PY_PROPERTY_GET(gs_energy)
double get_gs_energy()
const {
return gs_energy; }
462 long c_connection(
int op_linear_index,
int sp_index)
const {
return annihilation_connection(op_linear_index, sp_index); }
479 long cdag_connection(
int op_linear_index,
int sp_index)
const {
return creation_connection(op_linear_index, sp_index); }
492 matrix_t const &
c_matrix(
int op_linear_index,
int sp_index)
const {
return c_matrices[op_linear_index][sp_index]; }
505 matrix_t const &
cdag_matrix(
int op_linear_index,
int sp_index)
const {
return cdag_matrices[op_linear_index][sp_index]; }
541 [[nodiscard]]
static std::string
hdf5_format() {
return Complex ?
"AtomDiagComplex" :
"AtomDiagReal"; }
544 friend struct atom_diag_worker<Complex>;
545 friend std::ostream &operator<< <Complex>(std::ostream &os,
atom_diag const &ss);
550 void fill_first_eigenstate_of_subspace();
551 void compute_vacuum();
557 std::vector<sub_hilbert_space> sub_hilbert_spaces;
558 std::vector<eigensystem_t> eigensystems;
559 matrix<long> creation_connection;
560 matrix<long> annihilation_connection;
561 std::vector<std::vector<matrix_t>> cdag_matrices;
562 std::vector<std::vector<matrix_t>> c_matrices;
563 double gs_energy{0.0};
564 long vacuum_subspace_index{-1};
566 std::vector<std::vector<quantum_number_t>> quantum_numbers;
567 std::vector<int> first_eigenstate_of_subspace;
friend void h5_read(h5::group fg, std::string const &subgroup_name, this_t &g)
Read a block Green's function from HDF5.
friend void h5_write(h5::group fg, std::string const &subgroup_name, this_t const &g)
Write a block Green's function to HDF5.
friend std::ostream & operator<<(std::ostream &out, this_t const &)
Write a Green's function to an output stream.
Backward-compatibility umbrella header pulling in the nda array library.
Lightweight exact diagonalization solver for finite fermionic Hamiltonians.
fops_data_t const & get_fops_as_data() const
Get the data of the fundamental operator set used at construction.
long c_connection(int op_linear_index, int sp_index) const
Get the target subspace of the annihilation operator acting on subspace .
fundamental_operator_set const & get_fops() const
Get the fundamental operator set used at construction.
long get_vacuum_subspace_index() const
Get the index of the invariant subspace containing the vacuum state.
atom_diag(many_body_op_t const &h, fundamental_operator_set const &fops, int n_min, int n_max)
Diagonalize a Hamiltonian restricted to a particle-number window.
atom_diag(many_body_op_t const &h, fundamental_operator_set const &fops, std::vector< many_body_op_t > const &qn_vector)
Reduce a Hamiltonian to a block-diagonal form using user-supplied quantum numbers,...
int get_full_hilbert_space_dim() const
Get the dimension of the full Hilbert space.
matrix< scalar_t > matrix_t
Dense matrix type with scalar entries of type scalar_t.
static std::string hdf5_format()
Get the HDF5 format tag ("AtomDiagReal" or "AtomDiagComplex").
std::vector< eigensystem_t > const & get_eigensystems() const
Get the eigensystems of all invariant subspaces.
operators::many_body_operator get_h_atomic_as_mbop() const
Get the Hamiltonian used at construction as a generic many-body operator.
std::vector< fock_state_t > const & get_fock_states(int sp_index) const
Get the Fock states spanning invariant subspace .
std::pair< int, matrix_t > get_matrix_element_of_monomial(operators::monomial_t const &op_vec, int B) const
Get the matrix representation of a monomial operator restricted to source subspace .
matrix_t const & cdag_matrix(int op_linear_index, int sp_index) const
Get the matrix block of the creation operator acting on subspace .
triqs::operators::many_body_operator_generic< scalar_t > many_body_op_t
Many-body operator type compatible with scalar_t.
std::vector< std::vector< double > > get_energies() const
Get all eigenvalues grouped by invariant subspace.
std::vector< std::vector< quantum_number_t > > const & get_quantum_numbers() const
Get the values of all quantum-number operators, grouped by invariant subspace.
matrix_t const & c_matrix(int op_linear_index, int sp_index) const
Get the matrix block of the annihilation operator acting on subspace .
many_body_op_t const & get_h_atomic() const
Get the Hamiltonian used at construction, with its native scalar type.
long cdag_connection(int op_linear_index, int sp_index) const
Get the target subspace of the creation operator acting on subspace .
atom_diag()=default
Default constructor leaves the solver in an uninitialized state.
full_hilbert_space_state_t const & get_vacuum_state() const
Get the vacuum state as a vector in the full Hilbert space.
atom_diag(many_body_op_t const &h, fundamental_operator_set const &fops)
Reduce a Hamiltonian to a block-diagonal form using auto-partitioning, then diagonalize the blocks.
triqs::hilbert_space::fundamental_operator_set::data_t fops_data_t
Data type of a fundamental operator set.
std::vector< int > get_subspace_dims() const
Get the dimensions of all invariant subspaces.
std::vector< std::vector< fock_state_t > > get_fock_states() const
Get the Fock states of every invariant subspace.
vector< scalar_t > full_hilbert_space_state_t
State vector type of the full Hilbert space.
bool operator==(atom_diag const &rhs) const =default
Default equal-to operator compares all data members.
range index_range_of_subspace(int sp_index) const
Get the range of full-Hilbert-space indices corresponding to subspace .
atom_diag(many_body_op_t const &h, fundamental_operator_set const &fops, many_body_op_t const &hyb)
Reduce a Hamiltonian to a block-diagonal form using auto-partitioning refined by a hybridization term...
int get_subspace_dim(int sp_index) const
Get the dimension of invariant subspace .
atom_diag(many_body_op_t const &h, fundamental_operator_set const &fops, std::initializer_list< many_body_op_t > const &init_lst)
Initializer-list overload of atom_diag(many_body_op_t const &, fundamental_operator_set const &,...
std::vector< matrix_t > block_matrix_t
Block-diagonal matrix type, one dense block per invariant subspace.
std::conditional_t< Complex, std::complex< double >, double > scalar_t
Scalar type of the matrix elements: double or std::complex<double>.
matrix< scalar_t > const & get_unitary_matrix(int sp_index) const
Get the unitary matrix mapping the Fock basis of subspace to its eigenbasis.
double get_eigenvalue(int sp_index, int i) const
Get the eigenvalue of the Hamiltonian.
class hilbert_space const & get_full_hilbert_space() const
Get the full Hilbert space over which the diagonalization problem is defined.
double get_gs_energy() const
Get the ground-state energy, i.e. the minimum eigenvalue across all invariant subspaces.
std::vector< matrix< scalar_t > > get_unitary_matrices() const
Get the unitary matrices for every invariant subspace.
op_block_mat_t get_op_mat(many_body_op_t const &op) const
Get the block-matrix representation of a generic many-body operator.
int n_subspaces() const
Get the number of invariant subspaces produced by the chosen partitioning scheme.
int flatten_subspace_index(int sp_index, int i) const
Map a subspace-local pair to its linear index in the full Hilbert space.
Class representing a fundamental operator set.
std::vector< indices_t > data_t
Container type to store .
triqs::hilbert_space::indices_t indices_t
Index type to represent a single .
Fermionic Hilbert (Fock) space generated by a fundamental operator set.
Generic many-body operator.
fundamental_operator_set::indices_t indices_t
Index type used by the fundamental operator set associated with the diagonalization problem.
double quantum_number_t
Type used to store quantum-number values. Quantum-number operators are Hermitian, so their eigenvalue...
many_body_operator_generic< real_or_complex > many_body_operator
Many-body operator with real or complex coefficients (see triqs::operators::many_body_operator_generi...
std::vector< canonical_ops_t > monomial_t
Type used to represent a monomial of canonical second quantization operators.
Provides a fundamental operator set class.
Provides a class to represent Hilbert (Fock) spaces.
Common macros used in TRIQS.
Provides generic many-body operators.
Eigensystem of a single invariant subspace of the Hamiltonian .
friend void h5_write(h5::group g, std::string const &name, eigensystem_t const &es)
Write an eigensystem to HDF5.
static std::string hdf5_format()
Get the HDF5 format tag.
matrix_t unitary_matrix
Unitary matrix mapping the Fock basis to the eigenbasis.
vector< double > eigenvalues
Eigenvalues sorted in ascending order.
friend void h5_read(h5::group g, std::string const &name, eigensystem_t &es)
Read an eigensystem from HDF5.
bool operator==(eigensystem_t const &) const =default
Default equal-to operator compares the eigenvalues and unitary matrix.
friend void mpi_broadcast(eigensystem_t &es, mpi::communicator c={}, int root=0)
Broadcast an eigensystem to all ranks of an MPI communicator.
Block-matrix representation of an operator that respects the block structure of the Hamiltonian.
std::vector< matrix_t > block_mat
Vector of dense matrix blocks describing the action in the eigenbasis.
op_block_mat_t(int n_blocks)
Construct an empty block-matrix representation for a problem with the given number of subspaces.
array< long, 1 > connection
Array of subspace-to-subspace connections induced by the operator.
int n_blocks() const
Number of invariant subspaces.
friend std::ostream & operator<<(std::ostream &os, op_block_mat_t const &op_mat)
Pretty-print the block matrix to a stream.