39namespace triqs::operators::utils {
56 template <
typename T>
using dict2_t = std::map<std::tuple<indices_t, indices_t>, T>;
59 template <
typename T>
using dict4_t = std::map<std::tuple<indices_t, indices_t, indices_t, indices_t>, T>;
90 for (
auto const &term : h) {
91 auto const &coef = term.coef;
92 auto const &m = term.monomial;
95 if (!(m[0].dagger && !m[1].dagger)) {
96 if (!ignore_irrelevant)
TRIQS_RUNTIME_ERROR <<
"extract_h_dict: monomial is not of the form C^+(i) C(j)";
98 h_dict.insert({std::make_tuple(m[0].indices, m[1].indices), coef});
101 if (!ignore_irrelevant)
TRIQS_RUNTIME_ERROR <<
"extract_h_dict: monomial must have 2 operators";
133 for (
auto const &term : h) {
134 auto const &coef = term.coef;
135 auto const &m = term.monomial;
138 if (!(m[0].dagger && m[1].dagger && !m[2].dagger && !m[3].dagger) || (m[0].indices != m[3].indices) || (m[1].indices != m[2].indices)) {
139 if (!ignore_irrelevant)
TRIQS_RUNTIME_ERROR <<
"extract_U_dict2: monomial is not of the form C^+(i) C^+(j) C(j) C(i)";
141 U_dict.insert({std::make_tuple(m[0].indices, m[1].indices), coef});
142 U_dict.insert({std::make_tuple(m[1].indices, m[0].indices), coef});
145 if (!ignore_irrelevant)
TRIQS_RUNTIME_ERROR <<
"extract_U_dict2: monomial must have 4 operators";
177 for (
auto const &term : h) {
178 T
const &coef = term.coef;
179 auto const &m = term.monomial;
182 if (!(m[0].dagger && m[1].dagger && !m[2].dagger && !m[3].dagger)) {
183 if (!ignore_irrelevant)
TRIQS_RUNTIME_ERROR <<
"extract_U_dict4: monomial is not of the form C^+(i) C^+(j) C(l) C(k)";
185 U_dict.insert({std::make_tuple(m[0].indices, m[1].indices, m[3].indices, m[2].indices), T(0.5) * coef});
186 U_dict.insert({std::make_tuple(m[1].indices, m[0].indices, m[2].indices, m[3].indices), T(0.5) * coef});
187 U_dict.insert({std::make_tuple(m[0].indices, m[1].indices, m[2].indices, m[3].indices), T(-0.5) * coef});
188 U_dict.insert({std::make_tuple(m[1].indices, m[0].indices, m[3].indices, m[2].indices), T(-0.5) * coef});
191 if (!ignore_irrelevant)
TRIQS_RUNTIME_ERROR <<
"extract_U_dict4: monomial must have 4 operators";
216 template <
typename T =
double,
typename D, std::
size_t R = std::tuple_size_v<
typename D::key_type>>
221 auto indices_to_linear = [&fs](indices_t
const &indices) {
223 TRIQS_RUNTIME_ERROR <<
"dict_to_matrix: key [" << format_indices(indices) <<
"] of dict not in fundamental_operator_set/gf_struct";
228 auto arr = nda::zeros<T>(nda::stdutil::make_initialized_array<R>(fs.
size()));
229 for (
auto const &[key, value] : dict) std::apply([&](
auto const &...ks) ->
auto & {
return arr(indices_to_linear(ks)...); }, key) = T(value);
247 template <
typename D, std::
size_t R = std::tuple_size_v<
typename D::key_type>>
249 for (
auto const &[key, value] : dict) {
268 for (
auto const &term : h) {
269 if (term.monomial.size() == len) h_filtered += term;
312 template <
typename T>
314 bool ignore_irrelevant =
false) {
316 auto bl_mat = nda::array<nda::matrix<T>, 1>(n_bl);
317 for (
auto bl : range(n_bl)) {
319 bl_mat[bl] = nda::zeros<T>(bl_size, bl_size);
322 auto name_to_bl = [&](
auto &bl_name) {
328 for (
auto const &term : h) {
329 auto const &m = term.monomial;
330 T
const &coef = term.coef;
332 if (m.size() == 2 and m[0].dagger and not m[1].dagger and m[0].indices[0] == m[1].indices[0] and m[0].indices.size() == 2
333 and m[1].indices.size() == 2) {
334 auto bl_name = std::get<std::string>(m[0].indices[0]);
335 auto op1_idx = std::get<long>(m[0].indices[1]);
336 auto op2_idx = std::get<long>(m[1].indices[1]);
338 bl_mat[name_to_bl(bl_name)](op1_idx, op2_idx) = coef;
340 if (!ignore_irrelevant)
TRIQS_RUNTIME_ERROR <<
"block_matrix_from_op: Operator term is not of the form 'coeff * c_dag{bl,i} * c_{bl,j}'";
362 EXPECTS(bl_mat.size() ==
gf_struct.size());
364 for (
long bl = 0;
auto const &[bl_name, bl_size] :
gf_struct) {
365 EXPECTS(bl_mat[bl].shape() == (std::array{bl_size, bl_size}));
366 for (
auto [i, j] : itertools::product_range(bl_size, bl_size)) h += bl_mat[bl](i, j) *
c_dag(bl_name, i) *
c(bl_name, j);
auto cend()
Get a const iterator past the last block.
gf_struct_t gf_struct() const
Get the block structure.
auto cbegin()
Get a const iterator to the first block.
Backward-compatibility umbrella header pulling in the nda array library.
Class representing a fundamental operator set.
triqs::hilbert_space::indices_t indices_t
Index type to represent a single .
bool has_indices(indices_t const &alpha) const
Check if a given is in the set.
auto size() const
Get the number of single particle state indices in the set.
Generic many-body operator.
Compiler / platform glue and the dcomplex alias (must be included before any Boost header).
std::vector< std::pair< std::string, long > > gf_struct_t
Type describing the structure of a block Green's function.
std::string format_indices(indices_t const &alpha, std::string_view sep, std::string_view prefix, std::string_view suffix)
String representation of a single particle state index .
many_body_operator_generic< T > c_dag(IndexTypes... indices)
Create a creation operator .
many_body_operator_generic< T > c(IndexTypes... indices)
Create an annihilation operator .
#define TRIQS_RUNTIME_ERROR
Throw a triqs::runtime_error with the current source location.
Provides a fundamental operator set class.
Provides generic many-body operators.