6#include "./lazy_det_operation.hpp"
14 template <
typename Vec,
typename Value>
long lower_bound(
int count, Vec
const &vec, Value
const &value) {
26 TRIQS_ASSERT(first >= 0);
31 long get_c_lower_bound(det_t
const *d, c_t
const &c) {
32 return lower_bound(d->size(), [d](
int n) { return d->get_x(n); }, c);
36 long get_cdag_lower_bound(det_t
const *d, cdag_t
const &cdag) {
37 return lower_bound(d->size(), [d](
int n) { return d->get_y(n); }, cdag);
41 static double parity_sort(
auto begin,
auto end) {
42 std::size_t n_swaps = insertion_sort(begin, end);
43 return (n_swaps % 2 == 0) ? 1.0 : -1.0;
46 g_tau_scalar_t lazy_det_operation_t::one_block::execute_try_insert(det_t *d) {
48 if (c_lst.size() != cdag_lst.size()) TRIQS_RUNTIME_ERROR <<
"Trying to insert unequal number of c and c_dag operators into block!";
50 long const c_count = c_lst.size();
53 double prefactor = 1.0;
58 }
else if (c_count == 1) {
60 long const pos_c = get_c_lower_bound(d, c_lst[0]);
61 long const pos_cdag = get_cdag_lower_bound(d, cdag_lst[0]);
62 if ((pos_c + pos_cdag) % 2) prefactor *= -1.0;
63 return d->try_insert(pos_c, pos_cdag, c_lst[0], cdag_lst[0]) * prefactor;
67 prefactor *= parity_sort(c_lst.begin(), c_lst.end());
68 prefactor *= parity_sort(cdag_lst.begin(), cdag_lst.end());
71 std::vector<long> pos_c(c_count);
72 std::vector<long> pos_cdag(c_count);
73 for (
long i = 0; i < c_count; ++i) {
74 pos_c[i] = i + get_c_lower_bound(d, c_lst[i]);
75 pos_cdag[i] = i + get_cdag_lower_bound(d, cdag_lst[i]);
76 if ((pos_c[i] + pos_cdag[i]) % 2) prefactor *= -1.0;
79 return d->try_insert_k(pos_c, pos_cdag, c_lst, cdag_lst) * prefactor;
83 g_tau_scalar_t lazy_det_operation_t::one_block::execute_try_remove(det_t *d) {
85 if (c_lst.size() != cdag_lst.size()) TRIQS_RUNTIME_ERROR <<
"Trying to remove unequal number of c and c_dag operators from block!";
87 long const c_count =
static_cast<long>(c_lst.size());
90 double prefactor = 1.0;
95 }
else if (c_count == 1) {
97 long const pos_c = get_c_lower_bound(d, c_lst[0]);
98 long const pos_cdag = get_cdag_lower_bound(d, cdag_lst[0]);
99 if ((pos_c + pos_cdag) % 2) prefactor *= -1.0;
100 return d->try_remove(pos_c, pos_cdag) * prefactor;
104 prefactor *= parity_sort(c_lst.begin(), c_lst.end());
105 prefactor *= parity_sort(cdag_lst.begin(), cdag_lst.end());
108 std::vector<long> pos_c(c_count);
109 std::vector<long> pos_cdag(c_count);
110 for (
long i = 0; i < c_count; ++i) {
111 pos_c[i] = get_c_lower_bound(d, c_lst[i]);
112 pos_cdag[i] = get_cdag_lower_bound(d, cdag_lst[i]);
113 if ((pos_c[i] + pos_cdag[i]) % 2) prefactor *= -1.0;
117 return d->try_remove_k(pos_c, pos_cdag) * prefactor;
121 g_tau_scalar_t lazy_det_operation_t::one_block::execute_try_change_col_row(det_t *d) {
123 if (c_lst.size() != cdag_lst.size()) TRIQS_RUNTIME_ERROR <<
"Trying to remove unequal number of c and c_dag operators from block!";
125 long const c_count =
static_cast<long>(c_lst.size());
128 if (c_count == 0)
return 1.0;
131 std::vector<long> pos_c(c_count);
132 std::vector<long> pos_cdag(c_count);
133 for (
int i = 0; i < c_count; ++i) {
134 pos_c[i] = get_c_lower_bound(d, c_lst[i]);
135 pos_cdag[i] = get_cdag_lower_bound(d, cdag_lst[i]);
141 c_lst[0].s = 1 - c_lst[0].s;
142 cdag_lst[0].s = 1 - cdag_lst[0].s;
143 return d->try_change_col_row(pos_c[0], pos_cdag[0], c_lst[0], cdag_lst[0]);
144 default: TRIQS_RUNTIME_ERROR <<
"Not implemented";
return 0;