TRIQS/triqs_ctseg 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
regroup_segment.cpp
1// Copyright (c) 2022--present, The Simons Foundation
2// Copyright (c) 2022--present, Max Planck Institute for Polymer Research, Mainz, Germany
3// This file is part of TRIQS/ctseg and is licensed under the terms of GPLv3 or later.
4// SPDX-License-Identifier: GPL-3.0-or-later
5// See LICENSE in the root of this distribution for details.
6
7#include "regroup_segment.hpp"
8#include "../logs.hpp"
9
10namespace triqs_ctseg::moves {
11
12 double regroup_segment::attempt() {
13
14 LOG("\n =================== ATTEMPT REGROUP ================ \n");
15
16 // ------------ Choice of segment --------------
17 // Select color
18 color = rng(config.n_color());
19 auto &sl = config.seglists[color];
20 LOG("Regrouping at color {}", color);
21
22 // If no segments nothing to regroup
23 if (sl.empty()) {
24 LOG("Color is empty");
25 return 0;
26 }
27
28 // Select pair of segments (or cyclic segment) to regroup
29 making_full_line = sl.size() == 1;
30 if (making_full_line) {
31 if (is_full_line(sl[0])) {
32 LOG("Segment is full line");
33 return 0; // If segment is full line nothing to regroup
34 }
35 left_seg_idx = 0;
36 right_seg_idx = 0;
37 } else {
38 left_seg_idx = rng(sl.size());
39 right_seg_idx = (left_seg_idx == sl.size() - 1) ? 0 : left_seg_idx + 1;
40 }
41 left_seg = sl[left_seg_idx];
42 right_seg = sl[right_seg_idx];
43
44 if (left_seg.J_cdag or right_seg.J_c) {
45 LOG("At least one of the operators has spin line attached, cannot regroup.");
46 return 0;
47 }
48
49 LOG("Regroup at positions {} and {}: removing c at {}, cdag at {}", left_seg_idx, right_seg_idx, right_seg.tau_c,
50 left_seg.tau_cdag);
51
52 // ------------ Trace ratio -------------
53
54 auto inserted_seg = segment_t{left_seg.tau_cdag, right_seg.tau_c}; // "antisegment" : careful with order of c, cdag
55 double ln_trace_ratio = wdata.mu(color) * inserted_seg.length();
56
57 for (auto c : range(config.n_color())) {
58 if (c != color) { ln_trace_ratio += -wdata.U(color, c) * overlap(config.seglists[c], inserted_seg); }
59 if (wdata.has_Dt) {
60 ln_trace_ratio -= K_overlap(config.seglists[c], right_seg.tau_c, left_seg.tau_cdag, wdata.K, color, c);
61 }
62 }
63 if (wdata.has_Dt)
64 ln_trace_ratio -=
65 real(wdata.K(double(right_seg.tau_c - left_seg.tau_cdag))(color, color)); // Correct double counting
66
67 double trace_ratio = std::exp(ln_trace_ratio);
68
69 // ------------ Det ratio ---------------
70 // We remove a cdag (first index) from the left segment and a c (second index) from the right segment.
71 auto bl = wdata.block_number[color];
72 auto &D = wdata.dets[bl];
73 auto det_ratio = D.try_remove(det_lower_bound_x(D, left_seg.tau_cdag), //
74 det_lower_bound_y(D, right_seg.tau_c));
75
76 // ------------ Proposition ratio ------------
77
78 double future_number_segments = making_full_line ? 1 : sl.size() - 1;
79 double current_number_intervals = sl.size();
80 // Length of future segment
81 auto new_seg_len = (making_full_line ? tau_t::beta() : left_seg.tau_c - right_seg.tau_cdag);
82
83 // T direct = 1/current_number_intervals
84 // T inverse = 1/ future_number_segments / len_of_new_seg ^2 * (2 iif !full line)
85 double prop_ratio =
86 current_number_intervals / (future_number_segments * new_seg_len * new_seg_len / (making_full_line ? 1 : 2));
87
88 LOG("trace_ratio = {}, prop_ratio = {}, det_ratio = {}", trace_ratio, prop_ratio, det_ratio);
89
90 det_sign = (det_ratio > 0) ? 1.0 : -1.0;
91 double prod = trace_ratio * det_ratio * prop_ratio;
92
93 return (std::isfinite(prod)) ? prod : det_sign;
94 }
95
96 //--------------------------------------------------
97
98 double regroup_segment::accept() {
99
100 LOG("\n - - - - - ====> ACCEPT - - - - - - - - - - -\n");
101
102 double initial_sign = trace_sign(wdata);
103 LOG("Initial sign is {}. Initial configuration: {}", initial_sign, config);
104
105 // Update the dets
106 wdata.dets[wdata.block_number[color]].complete_operation();
107
108 // Regroup segments
109 auto &sl = config.seglists[color];
110 if (making_full_line) {
111 sl[left_seg_idx] = segment_t{tau_t::beta(), tau_t::zero()};
112 } else {
113 // Update the left segment
114 sl[left_seg_idx] = segment_t{left_seg.tau_c, right_seg.tau_cdag, left_seg.J_c, right_seg.J_cdag};
115 // Remove the right segment
116 sl.erase(sl.begin() + right_seg_idx);
117 }
118
119 double final_sign = trace_sign(wdata);
120 double sign_ratio = final_sign / initial_sign;
121 LOG("Final sign is {}", final_sign);
122
123 // Check invariant
124 if constexpr (print_logs or ctseg_debug) check_invariant(config, wdata);
125
126 if (sign_ratio * det_sign == -1.0) wdata.minus_sign = true;
127 LOG("Configuration is {}", config);
128
129 return sign_ratio;
130 }
131
132 //--------------------------------------------------
133 void regroup_segment::reject() {
134 LOG("\n - - - - - ====> REJECT - - - - - - - - - - -\n");
135 wdata.dets[wdata.block_number[color]].reject_last_try();
136 }
137
138} // namespace triqs_ctseg::moves
static tau_t beta()
tau_t at tau = beta
Definition tau_t.hpp:67
static tau_t zero()
$\tau = 0$
Definition tau_t.hpp:70