29#include <fmt/ostream.h>
32#include <itertools/itertools.hpp>
43namespace triqs::operators {
47 using hilbert_space::fundamental_operator_set;
50#define MAX_MONOMIAL_SIZE 4
54 fmt::print(sout,
"c{}{}", (op.
dagger ?
"_dag" :
""), format_indices(op.
indices,
",",
"(",
")"));
59 return m1.size() != m2.size() ? m1.size() < m2.size() : std::ranges::lexicographical_compare(m1, m2);
63 for (
auto const &
c : m) { os <<
'*' <<
c; }
76 std::array<long, MAX_MONOMIAL_SIZE> op_indices{};
80 object h5_monomial_dtype() {
81 object mono_obj = H5Tcreate(H5T_COMPOUND,
sizeof(h5_monomial));
82 H5Tinsert(mono_obj,
"is_real", HOFFSET(h5_monomial, is_real), H5T_NATIVE_INT);
83 H5Tinsert(mono_obj,
"re", HOFFSET(h5_monomial, re), H5T_NATIVE_DOUBLE);
84 H5Tinsert(mono_obj,
"im", HOFFSET(h5_monomial, im), H5T_NATIVE_DOUBLE);
85 std::array<h5::hsize_t, 1> array_dim{MAX_MONOMIAL_SIZE};
86 h5::object array_tid = H5Tarray_create(H5T_NATIVE_LONG, 1, array_dim.data());
87 H5Tinsert(mono_obj,
"op_indices", HOFFSET(h5_monomial, op_indices), array_tid);
101 std::vector<h5_monomial> datavec;
103 for (
auto const &m : op.monomials_) {
104 if (m.first.size() > MAX_MONOMIAL_SIZE)
105 TRIQS_RUNTIME_ERROR <<
" h5 writing many_body_operator : unexpected monomial with more than " << MAX_MONOMIAL_SIZE <<
"operators !";
106 h5_monomial y = {.is_real = m.second.is_real(), .re =
real(m.second), .im =
imag(m.second), .op_indices = {0, 0, 0, 0}};
108 for (
auto const &c_cdag_op : m.first) {
109 long c_number = fops[c_cdag_op.indices] + 1;
110 y.op_indices[i++] = (c_cdag_op.dagger ? c_number : -c_number);
112 datavec.push_back(y);
119 object dt = h5_monomial_dtype();
122 std::array<hsize_t, 1> dim{datavec.size()};
123 object dspace = H5Screate_simple(1, dim.data(),
nullptr);
126 object ds = g.create_dataset(name.c_str(), dt, dspace);
129 herr_t status = H5Dwrite(ds, dt, H5S_ALL, H5S_ALL, H5P_DEFAULT, datavec.data());
130 if (status < 0)
TRIQS_RUNTIME_ERROR <<
"Error writing the many_body_operator " << op <<
" in the group" << g.name();
133 h5::write_attribute(ds,
"fundamental_operator_set", fops);
134 write_hdf5_format(ds, op);
144 dataset ds = g.open_dataset(name);
147 h5::dataspace dspace = H5Dget_space(ds);
150 std::array<hsize_t, 1> dims_out{};
151 int ndims = H5Sget_simple_extent_dims(dspace, dims_out.data(),
nullptr);
153 TRIQS_RUNTIME_ERROR <<
"h5 : Trying to read many_body_operator. Rank mismatch : the array stored in the hdf5 file has rank = " << ndims;
156 object dt = h5_monomial_dtype();
159 std::vector<h5_monomial> datavec(dims_out[0]);
161 herr_t status = H5Dread(ds, h5_monomial_dtype(), dspace, H5S_ALL, H5P_DEFAULT, datavec.data());
162 if (status < 0)
TRIQS_RUNTIME_ERROR <<
"Error reading the many_body_operator " << op <<
" from the group" << g.name();
165 h5::read_attribute(ds,
"fundamental_operator_set", fops);
169 auto r_fops = fops.data();
171 for (
auto const &mon : datavec) {
173 for (
long i : mon.op_indices) {
175 monomial.push_back({.dagger = (i > 0), .indices = r_fops[std::abs(i) - 1]});
178 op.monomials_.insert({monomial, s});
Class representing a fundamental operator set.
friend void h5_read(h5::group g, std::string const &name, many_body_operator &op, hilbert_space::fundamental_operator_set &fops)
friend void h5_write(h5::group g, std::string const &name, many_body_operator const &op, hilbert_space::fundamental_operator_set const &fops)
Type that can represent either a real or a complex number.
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 > real(many_body_operator_generic< T > const &op)
Get a copy of the given operator with the imaginary parts of all monomial coefficients set to zero.
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.
many_body_operator_generic< T > imag(many_body_operator_generic< T > const &op)
Get a copy of the given operator with the real parts of all monomial coefficients set to zero.
bool operator<(monomial_t const &m1, monomial_t const &m2)
Less-than comparison operator for triqs::operators::monomial_t.
many_body_operator_generic< T > c(IndexTypes... indices)
Create an annihilation operator .
std::ostream & operator<<(std::ostream &sout, canonical_ops_t const &op)
Write a triqs::operators::canonical_ops_t to a std::ostream.
#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.
Second quantization creation/annihilation operator.
indices_t indices
Single particle state index .
bool dagger
True for creation ( ), false for annihilation ( ) operators.
Provides a type that decides at runtime whether it is real or complex.