7#include "double_insert_segment.hpp"
11namespace triqs_ctseg::moves {
13 double double_insert_segment::attempt() {
15 LOG(
"\n =================== ATTEMPT DOUBLE INSERT ================ \n");
19 int color_0 = rng(config.n_color());
20 int color_1 = rng(config.n_color() - 1);
21 if (color_1 >= color_0) ++color_1;
22 colors.assign({color_0, color_1});
23 LOG(
"Inserting at color ({}, {})", color_0, color_1);
26 for (
auto const &[i, color] : itertools::enumerate(colors)) {
27 auto &sl = config.seglists[color];
35 if (is_full_line(sl.back())) {
36 LOG(
"Full line, cannot insert. (color {})", color);
40 long seg_idx = rng(sl.size());
41 tau_left = sl[seg_idx].tau_cdag;
42 tau_right = sl[modulo(seg_idx + 1, sl.size())].tau_c;
47 LOG(
"Insertion window is tau_left = {}, tau_right = {} (color {})", tau_left, tau_right, color);
48 window_length[i] = tau_left - tau_right;
51 auto dt1 = tau_t::random(rng, window_length[i]);
52 auto dt2 = tau_t::random(rng, window_length[i]);
54 LOG(
"Insert_segment: generated equal times. Rejecting (color {})", color);
61 if (dt1 > dt2 and not sl.empty()) std::swap(dt1, dt2);
64 prop_seg[i] = segment_t{tau_left - dt1, tau_left - dt2};
65 LOG(
"Inserting segment with c at {}, cdag at {} (color {})", prop_seg[i].tau_c, prop_seg[i].tau_cdag, color);
69 double ln_trace_ratio = 0.0;
70 for (
auto const &[i, color] : itertools::enumerate(colors)) {
71 ln_trace_ratio += wdata.mu(color) * prop_seg[i].length();
73 for (
auto c : range(config.n_color())) {
74 if (c != color) ln_trace_ratio += -wdata.U(color, c) * overlap(config.seglists[c], prop_seg[i]);
76 ln_trace_ratio += K_overlap(config.seglists[c], prop_seg[i].tau_c, prop_seg[i].tau_cdag, wdata.K, color, c);
79 ln_trace_ratio += -real(wdata.K(
double(prop_seg[i].length()))(color, color));
83 ln_trace_ratio += -wdata.U(color_0, color_1) * overlap(prop_seg[1], prop_seg[0]);
85 std::vector<segment_t> seglist_temp = {prop_seg[1]};
86 ln_trace_ratio += K_overlap(seglist_temp, prop_seg[0].tau_c, prop_seg[0].tau_cdag, wdata.K, color_0, color_1);
89 double trace_ratio = std::exp(ln_trace_ratio);
93 auto &bl_0 = wdata.block_number[color_0];
94 auto &bl_1 = wdata.block_number[color_1];
95 auto &bl_idx_0 = wdata.index_in_block[color_0];
96 auto &bl_idx_1 = wdata.index_in_block[color_1];
97 is_same_block = bl_0 == bl_1;
100 auto &D = wdata.dets[bl_0];
101 if (wdata.offdiag_Delta) {
102 if (cdag_in_det(prop_seg[0].tau_cdag, D) or c_in_det(prop_seg[0].tau_c, D) or
103 cdag_in_det(prop_seg[1].tau_cdag, D) or c_in_det(prop_seg[1].tau_c, D)) {
104 LOG(
"One of the proposed times already exists in another line of the same block. Rejecting.");
107 if (prop_seg[0].tau_cdag == prop_seg[1].tau_cdag or prop_seg[0].tau_c == prop_seg[1].tau_c) {
108 LOG(
"Two identical times in inserted segments. Rejecting.");
113 auto tau_cdag_lower = prop_seg[0].tau_cdag > prop_seg[1].tau_cdag ? prop_seg[1].tau_cdag : prop_seg[0].tau_cdag;
114 auto tau_cdag_upper = prop_seg[0].tau_cdag < prop_seg[1].tau_cdag ? prop_seg[1].tau_cdag : prop_seg[0].tau_cdag;
115 auto tau_c_lower = prop_seg[0].tau_c > prop_seg[1].tau_c ? prop_seg[1].tau_c : prop_seg[0].tau_c;
116 auto tau_c_upper = prop_seg[0].tau_c < prop_seg[1].tau_c ? prop_seg[1].tau_c : prop_seg[0].tau_c;
118 auto idx_cdag_lower = prop_seg[0].tau_cdag > prop_seg[1].tau_cdag ? bl_idx_1 : bl_idx_0;
119 auto idx_cdag_upper = prop_seg[0].tau_cdag < prop_seg[1].tau_cdag ? bl_idx_1 : bl_idx_0;
120 auto idx_c_lower = prop_seg[0].tau_c > prop_seg[1].tau_c ? bl_idx_1 : bl_idx_0;
121 auto idx_c_upper = prop_seg[0].tau_c < prop_seg[1].tau_c ? bl_idx_1 : bl_idx_0;
122 det_ratio = D.try_insert2(det_lower_bound_x(D, tau_cdag_lower), det_lower_bound_x(D, tau_cdag_upper) + 1,
123 det_lower_bound_y(D, tau_c_lower) , det_lower_bound_y(D, tau_c_upper) + 1,
124 {tau_cdag_lower, idx_cdag_lower} , {tau_cdag_upper, idx_cdag_upper} ,
125 {tau_c_lower , idx_c_lower} , {tau_c_upper , idx_c_upper} );
128 auto &D_0 = wdata.dets[bl_0];
129 auto &D_1 = wdata.dets[bl_1];
130 if (wdata.offdiag_Delta) {
131 if (cdag_in_det(prop_seg[0].tau_cdag, D_0) or c_in_det(prop_seg[0].tau_c, D_0) or
132 cdag_in_det(prop_seg[1].tau_cdag, D_1) or c_in_det(prop_seg[1].tau_c, D_1)) {
133 LOG(
"One of the proposed times already exists in another line of the same block. Rejecting.");
137 auto det_ratio_0 = D_0.try_insert(det_lower_bound_x(D_0, prop_seg[0].tau_cdag),
138 det_lower_bound_y(D_0, prop_seg[0].tau_c),
139 {prop_seg[0].tau_cdag, bl_idx_0},
140 {prop_seg[0].tau_c, bl_idx_0});
141 auto det_ratio_1 = D_1.try_insert(det_lower_bound_x(D_1, prop_seg[1].tau_cdag),
142 det_lower_bound_y(D_1, prop_seg[1].tau_c),
143 {prop_seg[1].tau_cdag, bl_idx_1},
144 {prop_seg[1].tau_c, bl_idx_1});
145 det_ratio = det_ratio_0 * det_ratio_1;
149 double prop_ratio = 1.0;
150 for (
auto const &[i, color] : itertools::enumerate(colors)) {
151 auto &sl = config.seglists[color];
152 double current_number_intervals = std::max(
long(1),
long(sl.size()));
153 double future_number_segments = sl.size() + 1;
157 prop_ratio *= (current_number_intervals * window_length[i] * window_length[i] / (sl.empty() ? 1 : 2)) / future_number_segments;
161 LOG(
"trace_ratio = {}, prop_ratio = {}, det_ratio = {}", trace_ratio, prop_ratio, det_ratio);
163 double prod = trace_ratio * det_ratio * prop_ratio;
164 det_sign = (det_ratio > 0) ? 1.0 : -1.0;
166 return (std::isfinite(prod) ? prod : det_sign);
171 double double_insert_segment::accept() {
173 LOG(
"\n - - - - - ====> ACCEPT - - - - - - - - - - -\n");
175 double initial_sign = trace_sign(wdata);
176 LOG(
"Initial sign is {}. Initial configuration: {}", initial_sign, config);
180 wdata.dets[wdata.block_number[colors[0]]].complete_operation();
182 for (
auto const &color : colors)
183 wdata.dets[wdata.block_number[color]].complete_operation();
186 for (
auto const &[i, color] : itertools::enumerate(colors)) {
187 auto &sl = config.seglists[color];
188 sl.insert(std::upper_bound(sl.begin(), sl.end(), prop_seg[i]), prop_seg[i]);
192 if constexpr (print_logs or ctseg_debug) check_invariant(config, wdata);
194 double final_sign = trace_sign(wdata);
195 double sign_ratio = final_sign / initial_sign;
196 LOG(
"Final sign is {}", final_sign);
198 if (sign_ratio * det_sign == -1.0) wdata.minus_sign =
true;
200 LOG(
"Configuration is {}", config);
206 void double_insert_segment::reject() {
207 LOG(
"\n - - - - - ====> REJECT - - - - - - - - - - -\n");
209 wdata.dets[wdata.block_number[colors[0]]].reject_last_try();
211 for (
auto const &color : colors)
212 wdata.dets[wdata.block_number[color]].reject_last_try();
static tau_t beta()
tau_t at tau = beta
static tau_t zero()
$\tau = 0$