91 uint64_t d_mask, dag_mask, d_count_mask, dag_count_mask;
131 : subspaces_(subspaces), hmap_(std::move(hmap)) {
137 if (op1.dagger != op2.dagger) return op2.dagger;
138 return op1.dagger ? (fops[op1.indices] > fops[op2.indices]) : (fops[op1.indices] < fops[op2.indices]);
143 for (
auto const &term : op) {
145 auto monomial = term.monomial;
146 auto coef = term.coef;
149 int n = monomial.size();
153 for (
int i = 1; i < n; ++i) {
154 if (greater(monomial[i - 1], monomial[i])) {
156 swap(monomial[i - 1], monomial[i]);
167 static const bool check_issue819 = std::getenv(
"CHECK_ISSUE819");
168 if (check_issue819 && term.coef != coef)
169 TRIQS_RUNTIME_ERROR <<
"ERROR: The Atom-Diag result of this model is affected by issue 819 (https://github.com/TRIQS/triqs/issues/819).\n"
170 "If you have solved the same model with release 2.2.0, 2.2.1 or 3.0.0 of TRIQS the result was incorrect.";
173 std::vector<int> dag, ndag;
174 uint64_t d_mask = 0, dag_mask = 0;
175 for (
auto const &canonical_op : monomial) {
176 (canonical_op.dagger ? dag : ndag).push_back(fops[canonical_op.indices]);
177 (canonical_op.dagger ? dag_mask : d_mask) |= (uint64_t(1) << fops[canonical_op.indices]);
181 auto compute_count_mask = [](std::vector<int>
const &d) {
183 bool is_on = (d.size() % 2 == 1);
184 for (
int i = 0; i < 64; ++i) {
185 if (std::ranges::find(d, i) != d.end())
188 mask |= (uint64_t(1) << i);
192 uint64_t d_count_mask = compute_count_mask(ndag), dag_count_mask = compute_count_mask(dag);
193 terms_.push_back(one_term_t{
coeff_t(coef), d_mask, dag_mask, d_count_mask, dag_count_mask});
263 template <
typename S,
typename... Args> S
operator()(S
const &psi, Args &&...args)
const {
265 S target_st = get_target_st(psi);
266 auto const &hs = psi.get_hilbert();
268 using amplitude_t =
typename S::value_type;
270 for (
int i = 0; i < terms_.size(); ++i) {
272 foreach (psi, [M, &target_st, hs, ... args = std::forward<Args>(args)](
int j,
typename S::value_type amplitude) {
274 if ((f2 & M.d_mask) != M.d_mask)
return;
276 if (((f2 ^ M.dag_mask) & M.dag_mask) != M.dag_mask)
return;
278 auto sign_is_minus = parity_number_of_bits((f2 & M.d_count_mask) ^ (f3 & M.dag_count_mask));
280 auto ind = target_st.get_hilbert().get_state_index(f3);
281 target_st(ind) += amplitude * apply_if_possible(M.coeff, args...) * (sign_is_minus ? -amplitude_t(1) : amplitude_t(1));