7#include "insert_spin_segment.hpp"
11namespace triqs_ctseg::moves {
13 insert_spin_segment::insert_spin_segment(work_data_t &data_, configuration_t &config_,
14 triqs::mc_tools::random_generator &rng_)
15 : wdata(data_), config(config_), rng(rng_) {
16 ALWAYS_EXPECTS(config.n_color() == 2,
"spin add/remove move only implemented for n_color == 2, got {}",
22 double insert_spin_segment::attempt() {
24 ALWAYS_EXPECTS((config.n_color() == 2),
25 "Insert spin segment only implemented for n_color = 2, but here n_color = {}", config.n_color());
27 LOG(
"\n =================== ATTEMPT INSERT SPIN ================ \n");
32 orig_color = rng(config.n_color());
33 auto &sl = config.seglists[orig_color];
34 LOG(
"Inserting spin: splitting at color {}", orig_color);
37 LOG(
"ABORT : Empty line, cannot insert spin.");
41 dest_color = (orig_color == 0) ? 1 : 0;
42 auto &dsl = config.seglists[dest_color];
45 prop_seg_idx = rng(sl.size());
46 prop_seg = sl[prop_seg_idx];
49 splitting_full_line = is_full_line(prop_seg);
50 if (splitting_full_line) LOG(
"Inserting spin from full line.");
52 auto dt1 = tau_t::random(rng, prop_seg.length());
53 auto dt2 = tau_t::random(rng, prop_seg.length());
56 LOG(
"ABORT : Generated equal times");
61 if (dt1 > dt2 and not splitting_full_line) std::swap(dt1, dt2);
63 tau_left = prop_seg.tau_c - dt1;
64 tau_right = prop_seg.tau_c - dt2;
65 spin_seg = segment_t{tau_left, tau_right,
true,
true};
66 LOG(
"Inserting spins in segment at position {}, at tau_left = {}, tau_right = {}", prop_seg_idx, tau_left,
69 if (not is_insertable_into(spin_seg, dsl)) {
70 LOG(
"ABORT : Space is occupied on other line.");
76 double ln_trace_ratio = (wdata.mu(dest_color) - wdata.mu(orig_color)) * spin_seg.length();
78 for (
auto [c, slist] : itertools::enumerate(config.seglists)) {
80 ln_trace_ratio += K_overlap(slist, spin_seg.tau_cdag, spin_seg.tau_c, wdata.K, orig_color, c);
81 ln_trace_ratio += K_overlap(slist, spin_seg.tau_c, spin_seg.tau_cdag, wdata.K, dest_color, c);
84 auto Kl = wdata.K(
double(spin_seg.length()));
85 ln_trace_ratio -= real(Kl(orig_color, orig_color));
86 ln_trace_ratio -= real(Kl(dest_color, dest_color));
87 ln_trace_ratio += 2 * real(Kl(orig_color, dest_color));
89 double trace_ratio = std::exp(ln_trace_ratio);
90 trace_ratio *= -(real(wdata.Jperp(
double(spin_seg.length()))(0, 0)) / 2);
102 double prop_ratio = (double(config.n_color()) * sl.size() * prop_seg.length() * prop_seg.length() / 2)
103 /
double(config.Jperp_list.size() + 1);
105 LOG(
"trace_ratio = {}, prop_ratio = {}, det_ratio = {}", trace_ratio, prop_ratio, det_ratio);
107 double prod = trace_ratio * det_ratio * prop_ratio;
108 det_sign = (det_ratio > 0) ? 1.0 : -1.0;
109 return (std::isfinite(prod) ? prod : det_sign);
114 double insert_spin_segment::accept() {
116 LOG(
"\n - - - - - ====> ACCEPT - - - - - - - - - - -\n");
118 auto &sl = config.seglists[orig_color];
119 auto &dsl = config.seglists[dest_color];
122 if (splitting_full_line) {
123 sl[prop_seg_idx] = segment_t{tau_right, tau_left,
true,
true};
125 auto new_seg_left = segment_t{prop_seg.tau_c, tau_left, prop_seg.J_c,
true};
126 auto new_seg_right = segment_t{tau_right, prop_seg.tau_cdag,
true, prop_seg.J_cdag};
128 sl[prop_seg_idx] = new_seg_left;
131 bool insert_at_front = is_cyclic(prop_seg) and not is_cyclic(new_seg_right);
132 sl.insert(begin(sl) + (insert_at_front ? 0 : prop_seg_idx + 1), new_seg_right);
136 dsl.insert(std::upper_bound(begin(dsl), end(dsl), spin_seg), spin_seg);
139 auto &jl = config.Jperp_list;
141 jl.push_back(Jperp_line_t{spin_seg.tau_c, spin_seg.tau_cdag});
143 jl.push_back(Jperp_line_t{spin_seg.tau_cdag, spin_seg.tau_c});
146 if constexpr (print_logs or ctseg_debug) check_invariant(config, wdata);
147 LOG(
"Configuration is {}", config);
153 void insert_spin_segment::reject() { LOG(
"\n - - - - - ====> REJECT - - - - - - - - - - -\n"); }