TRIQS/TRIQS 4.0.0
Researching Interacting Quantum Systems
Loading...
Searching...
No Matches
triqs::hilbert_space::imperative_operator< HS, T, UseMap >

#include <triqs/hilbert_space/imperative_operator.hpp>

Detailed Description

template<typename HS, typename T = double, bool UseMap = false>
class triqs::hilbert_space::imperative_operator< HS, T, UseMap >

Representation of a many-body operator acting on many-body states.

Constructed from a triqs::operators::many_body_operator_generic, an imperative_operator stores a precomputed bitmask representation of every monomial \( \hat{m}_i \) that appears in the operator. Following the conventions of triqs::operators::many_body_operator_generic and triqs::hilbert_space::fundamental_operator_set, the source operator is written as

\[ \hat{O} = \sum_i a_i \, \hat{m}_i, \qquad \hat{m}_i = \hat{c}^{\dagger}_{\alpha_{i_1}} \cdots \hat{c}^{\dagger}_{\alpha_{i_{n_i}}}\, \hat{c}_{\alpha_{j_1}} \cdots \hat{c}_{\alpha_{j_{m_i}}}, \]

with real or complex coefficients \( a_i \) and single particle state indices \( \alpha_k \) drawn from the supplied fundamental operator set \( A = \{ \alpha_k \}_{k=0}^{N-1} \) ( \( N \leq 64 \)). Each \( \alpha_k \) is identified with its position \( k \) in \( A \), which is used as a bit position; a Fock basis state is encoded as a 64-bit integer (see triqs::hilbert_space::fock_state_t) via \( \lvert n_0 n_1 \dots n_{N-1} \rangle \leftrightarrow \sum_k n_k\, 2^k \), with the convention \( \lvert n_0 \dots n_{N-1} \rangle = (\hat{c}^{\dagger}_{\alpha_0})^{n_0} \cdots (\hat{c}^{\dagger}_{\alpha_{N-1}})^{n_{N-1}} \lvert 0 \rangle \).

At construction, each monomial \( \hat{m}_i \) is reordered to the canonical form above (creation operators on the left with \( \alpha_{i_1} < \dots < \alpha_{i_{n_i}} \), annihilation operators on the right with \(\alpha_{j_1} > \dots > \alpha_{j_{m_i}} \), matching the ordering of triqs::operators::canonical_ops_t), absorbing the appropriate fermionic sign into the coefficient \( a_i \). It is then stored as four 64-bit masks:

  • dag_mask — bit \( i_a \) is set if \( \hat{m}_i \) contains \( \hat{c}^{\dagger}_{\alpha_{i_a}} \),
  • d_mask — bit \( j_b \) is set if \( \hat{m}_i \) contains \( \hat{c}_{\alpha_{j_b}} \),
  • dag_count_mask, d_count_mask — precomputed parity masks that, when AND'ed with a Fock state and combined through XOR, yield the fermionic sign without rescanning the canonical order at apply time.

If UseMap is false, the operator acts within a single Hilbert (Fock) space (see triqs::hilbert_space::hilbert_space).

If UseMap is true, the operator acts across a fixed set of invariant subspaces (see triqs::hilbert_space::sub_hilbert_space) and the user must supply a connection map how the operator maps subspaces to one another.

Template Parameters
HSHilbert space type.
TCoefficient type.
UseMapWhether a connection map between invariant subspaces is used.

Definition at line 86 of file imperative_operator.hpp.

Public Types

using coeff_t = T
 Coefficient type (might be a callable type).
using hilbert_map_t = std::vector<int>
 Map between subspace indices (only used when UseMap = true).

Public Member Functions

 imperative_operator ()=default
 Default constructor creates a zero imperative operator with no terms.
 imperative_operator (triqs::operators::many_body_operator_generic< coeff_t > const &op, fundamental_operator_set const &fops, hilbert_map_t hmap=hilbert_map_t(), std::vector< sub_hilbert_space > const *subspaces=nullptr)
 Construct an imperative_operator from a triqs::operators::many_body_operator_generic and a triqs::hilbert_space::fundamental_operator_set.
bool is_empty () const
 Check whether the imperative operator has no terms.
template<typename S, typename... Args>
operator() (S const &psi, Args &&...1) const
 Apply the operator to a many-body state \( \lvert \psi \rangle \) and return the resulting state.
template<typename F>
void update (F f)
 Apply a callable object to each coefficient of the operator.

Constructor & Destructor Documentation

◆ imperative_operator()

template<typename HS, typename T = double, bool UseMap = false>
triqs::hilbert_space::imperative_operator< HS, T, UseMap >::imperative_operator ( triqs::operators::many_body_operator_generic< coeff_t > const & op,
fundamental_operator_set const & fops,
hilbert_map_t hmap = hilbert_map_t(),
std::vector< sub_hilbert_space > const * subspaces = nullptr )
inline

Construct an imperative_operator from a triqs::operators::many_body_operator_generic and a triqs::hilbert_space::fundamental_operator_set.

The monomials of the given operator are normalized to the order induced by the fundamental operator set, picking up the appropriate fermionic sign, and converted to a compact bitmask representation in which each canonical operator is identified with a bit position from the fundamental operator set.

When UseMap = true, the operator additionally acts across invariant Hilbert subspaces and a connection map describing how the operator maps subspaces to one another must be supplied through hmap and subspaces. When UseMap = false, hmap must be empty and subspaces must be nullptr; an internal error is raised otherwise.

Note
Preconditions for the UseMap = true case (not checked at construction time):
  • subspaces must be non-null and the pointed-to vector must outlive the constructed operator.
  • Every hmap[i] is either -1 (subspace annihilated by op) or a valid index into *subspaces.
  • hmap.size() must cover every subspace index of any state subsequently passed to operator()().
Parameters
opSource many-body operator.
fopsFundamental operator set; must contain all single particle state indices that appear in the operator.
hmapMap of subspace-to-subspace connections generated by op (only used when UseMap = true). hmap[i] = j means the i-th subspace is mapped to the j-th subspace; hmap[i] = -1 means it is annihilated.
subspacesPointer to the vector of all Hilbert subspaces referenced by hmap (only used when UseMap = true).

Definition at line 129 of file imperative_operator.hpp.

Member Function Documentation

◆ is_empty()

template<typename HS, typename T = double, bool UseMap = false>
bool triqs::hilbert_space::imperative_operator< HS, T, UseMap >::is_empty ( ) const
inlinenodiscard

Check whether the imperative operator has no terms.

Returns
True if the operator contains no monomials, false otherwise.

Definition at line 214 of file imperative_operator.hpp.

◆ operator()()

template<typename HS, typename T = double, bool UseMap = false>
template<typename S, typename... Args>
S triqs::hilbert_space::imperative_operator< HS, T, UseMap >::operator() ( S const & psi,
Args &&... args ) const
inline

Apply the operator to a many-body state \( \lvert \psi \rangle \) and return the resulting state.

The input state is expanded over the occupation number basis of its Hilbert (Fock) space \(\mathcal{F}^{(m)} \),

\[ \lvert \psi \rangle = \sum_{f \in \mathcal{F}^{(m)}} b_f \lvert f \rangle, \]

where \( \lvert f \rangle \) are the basis Fock states and \( b_f \) the corresponding amplitudes. Applying \( \hat{O} = \sum_i a_i \hat{m}_i \) to \( \lvert \psi \rangle \) yields

\[ \hat{O} \lvert \psi \rangle = \sum_{f} \sum_{i} a_i \, b_f \, \hat{m}_i \lvert f \rangle = \sum_{f'} b'_{f'} \lvert f' \rangle = \lvert \psi' \rangle \; , \]

so the task reduces to evaluating \( \hat{m}_i \lvert f \rangle \) for every monomial \( \hat{m}_i \) and every basis state \( \lvert f \rangle \) with non-zero amplitude \( b_f \), and accumulating the resulting contributions into the amplitudes \( b'_{f'} \) of the target state.

For a given monomial and Fock state, the action \( \hat{m}_i \lvert f \rangle = s_{i,f} \lvert f' \rangle \) (with sign \( s_{i,f} \in \{ -1, 0, +1 \} \)) reduces to a handful of bitwise operations on the precomputed masks:

  • if any annihilation site is unoccupied in \( \lvert f \rangle \) the term vanishes ( \( s_{i,f} = 0 \)); otherwise clear those bits,
  • if any creation site is already occupied in the intermediate state the term again vanishes; otherwise set those bits to obtain \( \lvert f' \rangle \),
  • read off the fermionic sign \( s_{i,f} = \pm 1 \) from the parity of the relevant bits of \( \lvert f \rangle \) and \( \lvert f' \rangle \) combined with the precomputed d_count_mask and dag_count_mask.

The contribution \( s_{i,f} \, a_i \, b_f \) is then accumulated into the amplitude \( b'_{f'} \) at the basis index of \( \lvert f' \rangle \) in the target state, so that after looping over all monomials and all non-zero amplitudes of \( \lvert \psi \rangle \) the target state holds \( b'_{f'} = \sum_{i, f} s_{i,f} \, a_i \, b_f \, \delta_{f', \hat{m}_i f} \).

The optional extra arguments are forwarded to each coefficient of the operator, making this overload useful when T is itself a callable (e.g. for parametric or time-dependent operators). For ordinary scalar coefficients the arguments are simply ignored.

Template Parameters
SMany-body state type.
ArgsTypes of the optional extra arguments forwarded to the coefficients.
Parameters
psiInitial many-body state \( \lvert \psi \rangle \).
argsOptional arguments forwarded to each coefficient of the operator (only meaningful when T is a callable).
Returns
Resulting many-body state \( \hat{O} \lvert \psi \rangle = \lvert \psi' \rangle \).

Definition at line 263 of file imperative_operator.hpp.

◆ update()

template<typename HS, typename T = double, bool UseMap = false>
template<typename F>
void triqs::hilbert_space::imperative_operator< HS, T, UseMap >::update ( F f)
inline

Apply a callable object to each coefficient of the operator.

The callable is invoked once per stored monomial term and receives the coefficient by mutable reference, allowing in-place modification.

Template Parameters
FCallable type.
Parameters
fCallable object applied to each coefficient of the operator.

Definition at line 206 of file imperative_operator.hpp.


The documentation for this class was generated from the following file: