32#include <boost/operators.hpp>
36#include <unordered_map>
38namespace triqs::hilbert_space {
46 template <
typename HS,
typename T,
bool BasedOnMap>
class state {};
62 template <
typename HS,
typename T,
bool BasedOnMap>
auto make_zero_state(state<HS, T, BasedOnMap>
const &phi) {
63 return state<HS, T, BasedOnMap>{phi.get_hilbert()};
87 template <
typename HS,
typename T>
class state<HS, T, true> : boost::additive<state<HS, T, true>>, boost::multiplicative<state<HS, T, true>, T> {
96 using amplitude_t = std::unordered_map<fock_state_t, value_type>;
120 [[nodiscard]]
int size()
const {
return hs_ptr_->size(); }
123 [[nodiscard]]
int nterms()
const {
return map_.size(); }
155 for (
auto const &[f, b_f] : phi.map_) {
156 auto [it, inserted] = map_.insert({f, b_f});
157 if (!inserted) it->second += b_f;
173 for (
auto const &[f, b_f] : phi.map_) {
174 auto [it, inserted] = map_.insert({f, -b_f});
175 if (!inserted) it->second -= b_f;
191 for (
auto &[f, a_f] : map_) { a_f *= x; }
223 for (
auto const &[f, b_f] : phi.map_) {
225 if (psi.map_.count(f) == 1) res += conj(b_f) * psi.map_.at(f);
240 template <
typename F>
friend void foreach (
state const &psi, F lambda) {
241 const_cast<state &
>(psi).prune();
242 for (
auto const &[f, a_f] : psi.map_) lambda(f, a_f);
257 for (
auto it = map_.begin(); it != map_.end();) {
259 if (is_zero(it->second)) {
268 const hilbert_space_t *hs_ptr_;
292 template <
typename HS,
typename T>
class state<HS, T, false> : boost::additive<state<HS, T, false>>, boost::multiplicative<state<HS, T, false>, T> {
325 [[nodiscard]]
int size()
const {
return hs_ptr_->size(); }
429 template <
typename F>
friend void foreach (
state const &psi, F lambda) {
430 const auto dim = psi.size();
431 for (
size_t i = 0; i < dim; ++i) lambda(i, psi(i));
450 const hilbert_space_t *hs_ptr_;
465 template <
typename HS,
typename T,
bool BasedOnMap> std::ostream &
operator<<(std::ostream &sout, state<HS, T, BasedOnMap>
const &psi) {
466 bool something_written =
false;
467 auto const &hs = psi.get_hilbert();
469 foreach (psi, [&sout, hs, &something_written](
int i,
auto a_f_i) {
471 if (!is_zero(a_f_i)) {
472 sout <<
" +(" << a_f_i <<
")"
473 <<
"|" << hs.get_fock_state(i) <<
">";
474 something_written =
true;
478 if (!something_written) sout << 0;
500 template <
typename TargetState,
typename OriginalState> TargetState
project(OriginalState
const &psi,
hilbert_space const &proj_hs) {
501 TargetState proj_psi(proj_hs);
502 auto const &hs = psi.get_hilbert();
503 foreach (psi, [&](
int i,
auto a_f_i) { proj_psi(hs.get_fock_state(i)) = a_f_i; });
524 template <
typename TargetState,
typename OriginalState> TargetState
project(OriginalState
const &psi,
sub_hilbert_space const &proj_hs) {
525 TargetState proj_psi(proj_hs);
526 auto const &hs = psi.get_hilbert();
527 foreach (psi, [&](
int i,
auto a_f_i) {
528 auto f = hs.get_fock_state(i);
Backward-compatibility umbrella header pulling in the nda array library.
Fermionic Hilbert (Fock) space generated by a fundamental operator set.
state & operator/=(value_type x)
Division assignment operator to divide by a scalar .
HS hilbert_space_t
Type of the Hilbert (Fock) space this state belongs to.
nda::vector< value_type > amplitude_t
Container type for amplitudes.
void set_hilbert(hilbert_space_t const &new_hs)
Set the Hilbert (Fock) space for this state.
friend value_type dot_product(state const &phi, state const &psi)
Calculate the dot product of two states .
state(hilbert_space_t const &hs, fock_state_t f)
Construct a new many-body state .
state & operator+=(state const &phi)
Addition assignment operator to add another state .
state & operator*=(value_type x)
Multiplication assignment operator to multiply a scalar .
hilbert_space_t const & get_hilbert() const
Get the Hilbert (Fock) space the current state belongs to.
amplitude_t & amplitudes()
Get the amplitudes as an nda::vector.
state & operator-=(state const &phi)
Subtraction assignment operator to subtract another state .
state(hilbert_space_t const &hs)
Construct a new many-body state .
int size() const
Get the dimension of the associated Hilbert (Fock) space, i.e. .
value_type & operator()(int i)
Get the amplitude for a given index .
value_type const & operator()(int i) const
Get the amplitude for a given index .
state()
Default constructor for a dummy state that does not belong to any Hilbert (Fock) space.
amplitude_t const & amplitudes() const
Get the amplitudes as an nda::vector.
T value_type
Value type of the amplitudes (either real or complex).
T value_type
Value type of the amplitudes (either real or complex).
int nterms() const
Get the number of non-vanishing amplitudes in the state.
state & operator*=(value_type x)
Multiplication assignment operator to multiply a scalar .
state()
Default constructor for a dummy state that does not belong to any Hilbert (Fock) space.
friend value_type dot_product(state const &phi, state const &psi)
Calculate the dot product of two states .
value_type const & operator()(fock_state_t f) const
Get the amplitude for a given Fock state .
state & operator-=(state const &phi)
Subtraction assignment operator to subtract another state .
void set_hilbert(hilbert_space_t const &new_hs)
Set the Hilbert (Fock) space for this state.
state & operator+=(state const &phi)
Addition assignment operator to add another state .
HS hilbert_space_t
Type of the Hilbert (Fock) space this state belongs to.
state(hilbert_space_t const &hs)
Construct a new many-body state .
int size() const
Get the dimension of the associated Hilbert (Fock) space, i.e. .
std::unordered_map< fock_state_t, value_type > amplitude_t
Container type for amplitudes.
state & operator/=(value_type x)
Division assignment operator to divide by a scalar .
state(hilbert_space_t const &hs, fock_state_t f)
Construct a new many-body state .
value_type & operator()(fock_state_t f)
Get the amplitude for a given Fock state .
hilbert_space_t const & get_hilbert() const
Get the Hilbert (Fock) space the current state belongs to.
Subspace of a fermionic Hilbert (Fock) space.
auto get_state_index(fock_state_t f) const
Get the index of a given Fock state within this subspace.
bool has_state(fock_state_t f) const
Check if a given Fock state belongs to this subspace.
auto make_zero_state(state< HS, T, BasedOnMap > const &phi)
Create a zero state in the same Hilbert (Fock) space as the given state.
std::ostream & operator<<(std::ostream &sout, state< HS, T, BasedOnMap > const &psi)
Write a triqs::hilbert_space::state<HS, T, true> or a triqs::hilbert_space::state<HS,...
uint64_t fock_state_t
Integer type representing a fermionic fock state .
TargetState project(OriginalState const &psi, hilbert_space const &proj_hs)
Project a state to a new Hilbert (Fock) space .
I conj(I const &x)
Complex conjugate of an integral value.
bool is_zero(I const &x)
Exact zero check for integral values.
Provides a class to represent Hilbert (Fock) spaces.
Numeric helpers overloaded for various types.