7#include "move_segment.hpp"
10namespace triqs_ctseg::moves {
12 double move_segment::attempt() {
14 LOG(
"\n =================== ATTEMPT MOVE ================ \n");
18 origin_color = rng(config.n_color());
19 LOG(
"Moving from color {}", origin_color);
22 dest_color = rng(config.n_color() - 1);
23 if (dest_color >= origin_color) ++dest_color;
24 LOG(
"Moving to color {}", dest_color);
27 auto const &origin_bl = wdata.block_number[origin_color];
28 auto const &destination_bl = wdata.block_number[dest_color];
29 auto const &idx_dest = wdata.index_in_block[dest_color];
30 if (origin_bl == destination_bl) {
31 LOG(
"Reject: colors are within the same block.");
36 flipped = (rng(2) == 0);
40 sl = flip(config.seglists[origin_color]);
41 dsl = flip(config.seglists[dest_color]);
42 LOG(
"Moving antisegment.");
44 sl = config.seglists[origin_color];
45 dsl = config.seglists[dest_color];
50 LOG(
"Nothing to move!");
55 origin_index = rng(sl.size());
56 origin_segment = sl[origin_index];
57 LOG(
"Moving segment at position {}", origin_index);
60 if (origin_segment.J_c or origin_segment.J_cdag) {
61 LOG(
"Segment has spin line attached: cannot move.");
66 if (not is_insertable_into(origin_segment, dsl)) {
67 LOG(
"Space is occupied in destination color.");
72 dest_index = std::upper_bound(dsl.begin(), dsl.end(), origin_segment) - dsl.cbegin();
73 LOG(
"Moving to position {}", dest_index);
77 double ln_trace_ratio =
78 (flipped ? -1 : 1) * (wdata.mu(dest_color) - wdata.mu(origin_color)) * double(origin_segment.length());
80 for (
auto const &[c, slist] : itertools::enumerate(config.seglists)) {
81 if (c != dest_color && c != origin_color) {
82 ln_trace_ratio += -wdata.U(dest_color, c) * overlap(slist, origin_segment) * (flipped ? -1 : 1);
83 ln_trace_ratio -= -wdata.U(origin_color, c) * overlap(slist, origin_segment) * (flipped ? -1 : 1);
88 auto tau_c = origin_segment.tau_c;
89 auto tau_cdag = origin_segment.tau_cdag;
90 if (flipped) std::swap(tau_c, tau_cdag);
92 for (
auto const &[c, slist] : itertools::enumerate(config.seglists)) {
93 ln_trace_ratio += K_overlap(slist, tau_c, tau_cdag, wdata.K, dest_color, c);
94 ln_trace_ratio -= K_overlap(slist, tau_c, tau_cdag, wdata.K, origin_color, c);
97 auto Kl = wdata.K(
double(origin_segment.length()));
98 ln_trace_ratio -= real(Kl(origin_color, origin_color));
99 ln_trace_ratio -= real(Kl(dest_color, dest_color));
100 ln_trace_ratio += 2 * real(Kl(origin_color, dest_color));
102 double trace_ratio = std::exp(ln_trace_ratio);
107 double det_ratio = 1;
108 auto seg = (flipped ? flip(origin_segment) : origin_segment);
109 auto &D_dest = wdata.dets[destination_bl];
110 auto &D_orig = wdata.dets[origin_bl];
111 if (wdata.offdiag_Delta) {
112 if (cdag_in_det(seg.tau_cdag, D_dest) or c_in_det(seg.tau_c, D_dest)) {
113 LOG(
"Proposed times already exist in destination block.");
117 if (not is_full_line(origin_segment))
118 det_ratio = D_dest.try_insert(det_lower_bound_x(D_dest, seg.tau_cdag), det_lower_bound_y(D_dest, seg.tau_c),
119 {seg.tau_cdag, idx_dest}, {seg.tau_c, idx_dest})
120 * D_orig.try_remove(det_lower_bound_x(D_orig, seg.tau_cdag), det_lower_bound_y(D_orig, seg.tau_c));
124 double prop_ratio =
double(sl.size()) / (dsl.size() + 1);
126 LOG(
"trace_ratio = {}, prop_ratio = {}, det_ratio = {}", trace_ratio, prop_ratio, det_ratio);
128 double prod = trace_ratio * det_ratio * prop_ratio;
129 det_sign = (det_ratio > 0) ? 1.0 : -1.0;
130 return (std::isfinite(prod) ? prod : det_sign);
135 double move_segment::accept() {
137 LOG(
"\n - - - - - ====> ACCEPT - - - - - - - - - - -\n");
139 double initial_sign = trace_sign(wdata);
140 LOG(
"Initial sign is {}. Initial configuration: {}", initial_sign, config);
143 auto const &origin_bl = wdata.block_number[origin_color];
144 auto const &destination_bl = wdata.block_number[dest_color];
145 wdata.dets[origin_bl].complete_operation();
146 wdata.dets[destination_bl].complete_operation();
149 dsl.insert(begin(dsl) + dest_index, origin_segment);
152 sl.erase(begin(sl) + origin_index);
155 config.seglists[origin_color] = flip(sl);
156 config.seglists[dest_color] = flip(dsl);
158 config.seglists[origin_color] = std::move(sl);
159 config.seglists[dest_color] = std::move(dsl);
163 double final_sign = trace_sign(wdata);
164 double sign_ratio = final_sign / initial_sign;
165 LOG(
"Final sign is {}", final_sign);
168 if constexpr (print_logs or ctseg_debug) check_invariant(config, wdata);
170 if (sign_ratio * det_sign == -1.0) wdata.minus_sign =
true;
172 LOG(
"Configuration is {}", config);
178 void move_segment::reject() {
179 LOG(
"\n - - - - - ====> REJECT - - - - - - - - - - -\n");
180 auto const &origin_bl = wdata.block_number[origin_color];
181 auto const &destination_bl = wdata.block_number[dest_color];
182 wdata.dets[origin_bl].reject_last_try();
183 wdata.dets[destination_bl].reject_last_try();