7#include "split_spin_segment.hpp"
12namespace triqs_ctseg::moves {
14 double split_spin_segment::attempt() {
16 LOG(
"\n =================== ATTEMPT SPLIT SPIN ================ \n");
20 auto &jl = config.Jperp_list;
23 LOG(
"No bosonic lines!");
27 line_idx = rng(jl.size());
28 auto &line = jl[line_idx];
29 LOG(
"Splitting S_plus at {}, S_minus at {}", line.tau_Splus, line.tau_Sminus);
32 prop_ratio = jl.size();
36 std::tie(idx_c_up, idx_cdag_dn, tau_up) = propose(0);
37 std::tie(idx_c_dn, idx_cdag_up, tau_dn) = propose(1);
41 auto &sl_up = config.seglists[0];
42 auto &sl_dn = config.seglists[1];
43 auto old_seg_up = sl_up[idx_c_up];
44 auto old_seg_dn = sl_dn[idx_c_dn];
45 auto new_seg_up = segment_t{tau_up, old_seg_up.tau_cdag};
46 auto new_seg_dn = segment_t{tau_dn, old_seg_dn.tau_cdag};
48 ln_trace_ratio += -wdata.U(0, 1)
49 * (overlap(new_seg_up, new_seg_dn) + overlap(old_seg_up, old_seg_dn) -
50 overlap(new_seg_up, old_seg_dn) - overlap(new_seg_dn, old_seg_up));
54 ln_trace_ratio -= real(wdata.K(
double(tau_up - old_seg_dn.tau_c))(0, 1));
55 ln_trace_ratio -= real(wdata.K(
double(tau_dn - old_seg_up.tau_c))(0, 1));
56 ln_trace_ratio += real(wdata.K(
double(tau_dn - tau_up))(0, 1));
57 ln_trace_ratio += real(wdata.K(
double(old_seg_up.tau_c - old_seg_dn.tau_c))(0, 1));
60 double trace_ratio = std::exp(ln_trace_ratio);
61 trace_ratio /= -real(wdata.Jperp(
double(line.tau_Splus - line.tau_Sminus))(0, 0)) / 2;
67 auto &D_up = wdata.dets[0];
68 det_ratio *= D_up.try_insert(det_lower_bound_x(D_up, sl_up[idx_cdag_up].tau_cdag),
69 det_lower_bound_y(D_up, tau_up),
70 {sl_up[idx_cdag_up].tau_cdag, 0}, {tau_up, 0});
73 auto &D_dn = wdata.dets[1];
75 D_dn.try_insert(det_lower_bound_x(D_dn, sl_dn[idx_cdag_dn].tau_cdag), det_lower_bound_y(D_dn, tau_dn),
76 {sl_dn[idx_cdag_dn].tau_cdag, 0}, {tau_dn, 0});
78 LOG(
"trace_ratio = {}, prop_ratio = {}, det_ratio = {}", trace_ratio, prop_ratio, det_ratio);
80 double prod = trace_ratio * det_ratio * prop_ratio;
81 det_sign = (det_ratio > 0) ? 1.0 : -1.0;
83 return (std::isfinite(prod) ? prod : det_sign);
88 double split_spin_segment::accept() {
90 LOG(
"\n - - - - - ====> ACCEPT - - - - - - - - - - -\n");
92 double initial_sign = trace_sign(wdata);
93 LOG(
"Initial sign is {}. Initial configuration: {}", initial_sign, config);
96 wdata.dets[0].complete_operation();
97 wdata.dets[1].complete_operation();
100 auto &sl_up = config.seglists[0];
101 auto &sl_dn = config.seglists[1];
103 sl_up[idx_c_up].tau_c = tau_up;
104 sl_dn[idx_c_dn].tau_c = tau_dn;
107 sl_up[idx_c_up].J_c =
false;
108 sl_up[idx_cdag_up].J_cdag =
false;
109 sl_dn[idx_c_dn].J_c =
false;
110 sl_dn[idx_cdag_dn].J_cdag =
false;
112 fix_ordering_first_last(sl_up);
113 fix_ordering_first_last(sl_dn);
116 auto &jl = config.Jperp_list;
117 jl.erase(begin(jl) + line_idx);
120 double final_sign = trace_sign(wdata);
121 double sign_ratio = final_sign / initial_sign;
122 LOG(
"Final sign is {}", final_sign);
125 if constexpr (print_logs or ctseg_debug) check_invariant(config, wdata);
127 if (sign_ratio * det_sign == -1.0) wdata.minus_sign =
true;
129 LOG(
"Configuration is {}", config);
135 void split_spin_segment::reject() {
137 LOG(
"\n - - - - - ====> REJECT - - - - - - - - - - -\n");
138 wdata.dets[0].reject_last_try();
139 wdata.dets[1].reject_last_try();
144 std::tuple<long, long, tau_t> split_spin_segment::propose(
int color) {
146 auto &line = config.Jperp_list[line_idx];
147 int other_color = 1 - color;
148 auto &sl = config.seglists[color];
149 auto &dsl = config.seglists[other_color];
155 long idx_c = lower_bound(sl, (color == 0 ? line.tau_Sminus : line.tau_Splus)) - sl.cbegin();
156 auto tau_c = sl[idx_c].tau_c;
166 auto idx_left = (idx_c == 0) ? sl.size() - 1 : idx_c - 1;
167 auto wtau_left = sl[idx_left].tau_cdag;
168 auto wtau_right = sl[idx_c].tau_cdag;
169 if (idx_c == idx_left) {
173 tau_t window_length = wtau_left - wtau_right;
176 auto dt = tau_t::random(rng, window_length);
177 auto tau_c_new = sl[idx_left].tau_cdag - dt;
179 LOG(
"Spin {}: moving c at position {} from {} to {}.", (color == 0) ?
"up" :
"down", idx_c, tau_c, tau_c_new);
180 auto new_seg = segment_t{tau_c_new, sl[idx_c].tau_cdag};
183 ln_trace_ratio += wdata.mu(color) * (double(new_seg.length()) - double(sl[idx_c].length()));
184 for (
auto const &[c, slc] : itertools::enumerate(config.seglists)) {
186 ln_trace_ratio += -wdata.U(c, color) * overlap(slc, new_seg);
187 ln_trace_ratio -= -wdata.U(c, color) * overlap(slc, sl[idx_c]);
190 ln_trace_ratio += K_overlap(slc, tau_c_new,
true, wdata.K, c, color);
191 ln_trace_ratio -= K_overlap(slc, tau_c,
true, wdata.K, c, color);
194 if (wdata.has_Dt) ln_trace_ratio -= real(wdata.K(
double(tau_c_new - tau_c))(color, color));
199 prop_ratio *= window_length / (double(sl.size()) * cdag_in_window(wtau_left, wtau_right, dsl).size());
201 return {idx_c, idx_cdag, tau_c_new};
static tau_t epsilon()
Get epsilon, defined as $\epsilon = \beta /N_max$.
static tau_t beta()
tau_t at tau = beta
static tau_t zero()
$\tau = 0$