7#include "regroup_spin_segment.hpp"
9#include "../configuration.hpp"
12namespace triqs_ctseg::moves {
14 double regroup_spin_segment::attempt() {
16 LOG(
"\n =================== ATTEMPT REGROUP SPIN ================ \n");
19 prop_ratio = 1 / (double(config.Jperp_list.size()) + 1);
23 std::tie(idx_c_up, idx_cdag_dn, tau_up, prop_failed) = propose(0);
24 if (prop_failed)
return 0;
25 std::tie(idx_c_dn, idx_cdag_up, tau_dn, prop_failed) = propose(1);
26 if (prop_failed)
return 0;
30 auto &sl_up = config.seglists[0];
31 auto &sl_dn = config.seglists[1];
32 auto old_seg_up = sl_up[idx_c_up];
33 auto old_seg_dn = sl_dn[idx_c_dn];
34 auto new_seg_up = segment_t{tau_up, old_seg_up.tau_cdag};
35 auto new_seg_dn = segment_t{tau_dn, old_seg_dn.tau_cdag};
37 ln_trace_ratio += -wdata.U(0, 1)
38 * (overlap(new_seg_up, new_seg_dn) + overlap(old_seg_up, old_seg_dn)
39 - overlap(new_seg_up, old_seg_dn) - overlap(new_seg_dn, old_seg_up));
43 ln_trace_ratio -= real(wdata.K(
double(tau_up - old_seg_dn.tau_c))(0, 1));
44 ln_trace_ratio -= real(wdata.K(
double(tau_dn - old_seg_up.tau_c))(0, 1));
45 ln_trace_ratio += real(wdata.K(
double(tau_dn - tau_up))(0, 1));
46 ln_trace_ratio += real(wdata.K(
double(old_seg_up.tau_c - old_seg_dn.tau_c))(0, 1));
49 double trace_ratio = std::exp(ln_trace_ratio);
50 trace_ratio *= -real(wdata.Jperp(
double(tau_up - tau_dn))(0, 0)) / 2;
56 auto &D_up = wdata.dets[0];
57 det_ratio *= D_up.try_remove(det_lower_bound_x(D_up, sl_up[idx_cdag_up].tau_cdag),
58 det_lower_bound_y(D_up, sl_up[idx_c_up].tau_c));
61 auto &D_dn = wdata.dets[1];
62 det_ratio *= D_dn.try_remove(det_lower_bound_x(D_dn, sl_dn[idx_cdag_dn].tau_cdag),
63 det_lower_bound_y(D_dn, sl_dn[idx_c_dn].tau_c));
65 LOG(
"trace_ratio = {}, prop_ratio = {}, det_ratio = {}", trace_ratio, prop_ratio, det_ratio);
67 double prod = trace_ratio * det_ratio * prop_ratio;
68 det_sign = (det_ratio > 0) ? 1.0 : -1.0;
70 return (std::isfinite(prod) ? prod : det_sign);
75 double regroup_spin_segment::accept() {
77 LOG(
"\n - - - - - ====> ACCEPT - - - - - - - - - - -\n");
79 double initial_sign = trace_sign(wdata);
80 LOG(
"Initial sign is {}. Initial configuration: {}", initial_sign, config);
83 wdata.dets[0].complete_operation();
84 wdata.dets[1].complete_operation();
87 auto &sl_up = config.seglists[0];
88 auto &sl_dn = config.seglists[1];
91 sl_up[idx_c_up].tau_c = tau_up;
92 sl_dn[idx_c_dn].tau_c = tau_dn;
95 sl_up[idx_c_up].J_c =
true;
96 sl_dn[idx_cdag_dn].J_cdag =
true;
97 sl_dn[idx_c_dn].J_c =
true;
98 sl_up[idx_cdag_up].J_cdag =
true;
100 fix_ordering_first_last(sl_up);
101 fix_ordering_first_last(sl_dn);
104 config.Jperp_list.push_back(Jperp_line_t{tau_up, tau_dn});
107 double final_sign = trace_sign(wdata);
108 double sign_ratio = final_sign / initial_sign;
109 LOG(
"Final sign is {}", final_sign);
112 if constexpr (print_logs or ctseg_debug) check_invariant(config, wdata);
114 if (sign_ratio * det_sign == -1.0) wdata.minus_sign =
true;
115 LOG(
"Configuration is {}", config);
122 void regroup_spin_segment::reject() {
124 LOG(
"\n - - - - - ====> REJECT - - - - - - - - - - -\n");
125 wdata.dets[0].reject_last_try();
126 wdata.dets[1].reject_last_try();
131 std::tuple<long, long, tau_t, bool> regroup_spin_segment::propose(
int color) {
133 auto &sl = config.seglists[color];
134 int other_color = 1 - color;
135 auto &dsl = config.seglists[other_color];
138 if (sl.empty() or dsl.empty()) {
139 LOG(
"Line is empty, cannot regroup spin.");
142 if (is_full_line(sl[0]) or is_full_line(dsl[0])) {
143 LOG(
"Line is full, cannot regroup spin.");
149 auto idx_c = rng(sl.size());
150 LOG(
"Spin {}: regrouping c at position {}.", (color == 0) ?
"up" :
"down", idx_c);
152 LOG(
"Spin {}: cannot regroup because c is connected to a spin line.", (color == 0) ?
"up" :
"down");
156 auto tau_c = sl[idx_c].tau_c;
161 auto idx_left = (idx_c == 0) ? sl.size() - 1 : idx_c - 1;
162 auto wtau_left = sl[idx_left].tau_cdag;
163 auto wtau_right = sl[idx_c].tau_cdag;
164 if (idx_c == idx_left) {
170 auto cdag_list = cdag_in_window(wtau_left, wtau_right, dsl);
171 if (cdag_list.empty()) {
172 LOG(
"Spin {}: cannot regroup because there are no suitable cdag operators.", (color == 0) ?
"up" :
"down");
176 auto idx_cdag = cdag_list[rng(cdag_list.size())];
177 if (dsl[idx_cdag].J_cdag) {
178 LOG(
"Spin {}: cannot regroup because chosen cdag is connected to a spin line.", (color == 0) ?
"up" :
"down");
181 auto tau_c_new = dsl[idx_cdag].tau_cdag;
182 auto new_seg = segment_t{tau_c_new, sl[idx_c].tau_cdag};
183 LOG(
"Spin {}: moving c from {} to {}.", (color == 0) ?
"up" :
"down", tau_c, tau_c_new);
186 ln_trace_ratio += wdata.mu(color) * (double(new_seg.length()) - double(sl[idx_c].length()));
187 LOG(
"Spin {}: ln trace ratio = {}", (color == 0) ?
"up" :
"down", ln_trace_ratio);
188 for (
auto const &[c, slc] : itertools::enumerate(config.seglists)) {
190 ln_trace_ratio += -wdata.U(c, color) * overlap(slc, new_seg);
191 ln_trace_ratio -= -wdata.U(c, color) * overlap(slc, sl[idx_c]);
194 ln_trace_ratio += K_overlap(slc, tau_c_new,
true, wdata.K, c, color);
195 ln_trace_ratio -= K_overlap(slc, tau_c,
true, wdata.K, c, color);
198 if (wdata.has_Dt) ln_trace_ratio -= real(wdata.K(
double(tau_c_new - tau_c))(color, color));
201 auto window_length = double(wtau_left - wtau_right);
202 prop_ratio *= double(sl.size()) * cdag_list.size() / window_length;
204 return {idx_c, idx_cdag, tau_c_new,
false};
static tau_t beta()
tau_t at tau = beta
static tau_t zero()
$\tau = 0$