TRIQS/triqs_ctseg 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
double_remove_segment.cpp
1// Copyright (c) 2025--present, The Simons Foundation
2// Copyright (c) 2025--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 "double_remove_segment.hpp"
8#include "../logs.hpp"
9
10namespace triqs_ctseg::moves {
11
12 double double_remove_segment::attempt() {
13
14 LOG("\n =================== ATTEMPT DOUBLE REMOVE ================ \n");
15
16 // ------------ Choice of segments --------------
17 // Select removal colors
18 int color_0 = rng(config.n_color());
19 int color_1 = rng(config.n_color() - 1);
20 if (color_1 >= color_0) ++color_1; // little trick to select another color
21 colors.assign({color_0, color_1});
22 LOG("Removing at color ({}, {})", color_0, color_1);
23
24 // For each color, perform a single remove
25 for (auto const &[i, color] : itertools::enumerate(colors)) {
26 auto &sl = config.seglists[color];
27
28 // If color is empty, nothing to remove
29 if (sl.empty()) {
30 LOG("Empty line, cannot remove. (color {})", color);
31 return 0;
32 }
33
34 // Select segment to remove
35 prop_seg_idx[i] = rng(sl.size());
36 prop_seg[i] = sl[prop_seg_idx[i]];
37 if (is_full_line(prop_seg[i])) {
38 LOG("Cannot remove full line. (color {})", color);
39 return 0;
40 }
41 if (prop_seg[i].J_c or prop_seg[i].J_cdag) {
42 LOG("Segment has spin line attached, cannot remove. (color {})", color);
43 return 0;
44 }
45
46 LOG("Removing segment at position {} : c at {}, cdag at {} (color {})", prop_seg_idx[i], prop_seg[i].tau_c, prop_seg[i].tau_cdag, color);
47 } // color
48
49 // ------------ Trace ratio -------------
50 // Same as double insert, up to the sign
51 double ln_trace_ratio = 0.0;
52 for (auto const &[i, color] : itertools::enumerate(colors)) {
53 ln_trace_ratio += -wdata.mu(color) * prop_seg[i].length();
54 for (auto c : range(config.n_color())) {
55 if (c != color) ln_trace_ratio -= -wdata.U(color, c) * overlap(config.seglists[c], prop_seg[i]);
56 if (wdata.has_Dt)
57 ln_trace_ratio -= K_overlap(config.seglists[c], prop_seg[i].tau_c, prop_seg[i].tau_cdag, wdata.K, color, c);
58 }
59 if (wdata.has_Dt) ln_trace_ratio -= real(wdata.K(double(prop_seg[i].length()))(color, color));
60 } // color
61
62 // Overlap between the removed segments
63 ln_trace_ratio += -wdata.U(color_0, color_1) * overlap(prop_seg[1], prop_seg[0]);
64 if (wdata.has_Dt) {
65 std::vector<segment_t> seglist_temp = {prop_seg[1]}; // trick for using K_overlap on a single segment
66 ln_trace_ratio += K_overlap(seglist_temp, prop_seg[0].tau_c, prop_seg[0].tau_cdag, wdata.K, color_0, color_1);
67 }
68
69 double trace_ratio = std::exp(ln_trace_ratio);
70
71 // ------------ Det ratio ---------------
72 auto &bl_0 = wdata.block_number[color_0];
73 auto &bl_1 = wdata.block_number[color_1];
74 is_same_block = bl_0 == bl_1;
75 double det_ratio;
76 if (is_same_block) { // remove two rows and columns on the same block
77 auto &D = wdata.dets[bl_0];
78 det_ratio = D.try_remove2(det_lower_bound_x(D, prop_seg[0].tau_cdag),
79 det_lower_bound_x(D, prop_seg[1].tau_cdag),
80 det_lower_bound_y(D, prop_seg[0].tau_c),
81 det_lower_bound_y(D, prop_seg[1].tau_c));
82 }
83 else { // remove on different blocks
84 auto &D_0 = wdata.dets[bl_0];
85 auto &D_1 = wdata.dets[bl_1];
86 auto det_ratio_0 = D_0.try_remove(det_lower_bound_x(D_0, prop_seg[0].tau_cdag),
87 det_lower_bound_y(D_0, prop_seg[0].tau_c));
88 auto det_ratio_1 = D_1.try_remove(det_lower_bound_x(D_1, prop_seg[1].tau_cdag),
89 det_lower_bound_y(D_1, prop_seg[1].tau_c));
90 det_ratio = det_ratio_0 * det_ratio_1;
91 }
92
93 // ------------ Proposition ratio ------------
94 double prop_ratio = 1.0;
95 for (auto const &[i, color] : itertools::enumerate(colors)) {
96 auto &sl = config.seglists[color];
97 double current_number_segments = sl.size();
98 double future_number_intervals = std::max(1, int(sl.size()) - 1);
99 // Insertion window for the reverse move double_insert_segment
100 // initialise at (beta,0)
101 auto tau_left = tau_t::beta(), tau_right = tau_t::zero();
102 if (current_number_segments != 1) {
103 // Find left, right, with cyclicity
104 tau_right = sl[modulo(prop_seg_idx[i] + 1, sl.size())].tau_c;
105 tau_left = sl[modulo(prop_seg_idx[i] - 1, sl.size())].tau_cdag;
106 }
107 auto window_length = double(tau_left - tau_right);
108
109 prop_ratio *= current_number_segments /
110 (future_number_intervals * window_length * window_length / (current_number_segments == 1 ? 1 : 2));
111 }
112 LOG("trace_ratio = {}, prop_ratio = {}, det_ratio = {}", trace_ratio, prop_ratio, det_ratio);
113
114 det_sign = (det_ratio > 0) ? 1.0 : -1.0;
115 double prod = trace_ratio * det_ratio * prop_ratio;
116
117 return (std::isfinite(prod)) ? prod : det_sign;
118 }
119
120 //--------------------------------------------------
121
122 double double_remove_segment::accept() {
123
124 LOG("\n - - - - - ====> ACCEPT - - - - - - - - - - -\n");
125
126 double initial_sign = trace_sign(wdata);
127 LOG("Initial sign is {}. Initial configuration: {}", initial_sign, config);
128
129 // Update the dets
130 if (is_same_block)
131 wdata.dets[wdata.block_number[colors[0]]].complete_operation();
132 else
133 for (auto const &color : colors)
134 wdata.dets[wdata.block_number[color]].complete_operation();
135
136 // Remove the segments
137 for (auto const &[i, color] : itertools::enumerate(colors)) {
138 auto &sl = config.seglists[color];
139 sl.erase(sl.begin() + prop_seg_idx[i]);
140 }
141
142 double final_sign = trace_sign(wdata);
143 double sign_ratio = initial_sign / final_sign;
144 LOG("Final sign is {}", final_sign);
145
146 // Check invariant
147 if constexpr (print_logs or ctseg_debug) check_invariant(config, wdata);
148
149 if (sign_ratio * det_sign == -1.0) wdata.minus_sign = true;
150
151 LOG("Configuration is {}", config);
152
153 return sign_ratio;
154 }
155
156 //--------------------------------------------------
157 void double_remove_segment::reject() {
158 LOG("\n - - - - - ====> REJECT - - - - - - - - - - -\n");
159 if (is_same_block)
160 wdata.dets[wdata.block_number[colors[0]]].reject_last_try();
161 else
162 for (auto const &color : colors)
163 wdata.dets[wdata.block_number[color]].reject_last_try();
164 }
165
166} // 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