TRIQS/triqs_cthyb 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
double_remove.cpp
1/*******************************************************************************
2 *
3 * TRIQS: a Toolbox for Research in Interacting Quantum Systems
4 *
5 * Copyright (C) 2014, P. Seth, I. Krivenko, M. Ferrero and O. Parcollet
6 *
7 * TRIQS is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later
10 * version.
11 *
12 * TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 * details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * TRIQS. If not, see <http://www.gnu.org/licenses/>.
19 *
20 ******************************************************************************/
21
22#include "./double_remove.hpp"
23
24namespace triqs_cthyb {
25
26 histogram *move_remove_c_c_cdag_cdag::add_histo(std::string const &name, histo_map_t *histos) {
27 if (!histos) return nullptr;
28 auto new_histo = histos->insert({name, {.0, config.beta(), 100}});
29 return &(new_histo.first->second);
30 }
31
32 move_remove_c_c_cdag_cdag::move_remove_c_c_cdag_cdag(int block_index1, int block_index2, int block_size1, int block_size2,
33 std::string const &block_name1, std::string const &block_name2, qmc_data &data,
34 mc_tools::random_generator &rng, histo_map_t *histos)
35 : data(data),
36 config(data.config),
37 rng(rng),
38 block_index1(block_index1),
39 block_index2(block_index2),
40 block_size1(block_size1),
41 block_size2(block_size2),
42 histo_proposed1(add_histo("double_remove_length_proposed_" + block_name1, histos)),
43 histo_proposed2(add_histo("double_remove_length_proposed_" + block_name2, histos)),
44 histo_accepted1(add_histo("double_remove_length_accepted_" + block_name1, histos)),
45 histo_accepted2(add_histo("double_remove_length_accepted_" + block_name2, histos)) {}
46
47 mc_weight_t move_remove_c_c_cdag_cdag::attempt() {
48
49#ifdef EXT_DEBUG
50 std::cerr << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl;
51 std::cerr << "In config " << config.get_id() << std::endl;
52 std::cerr << "* Attempt for move_remove_c_c_cdag_cdag (blocks " << block_index1 << ", " << block_index2 << ")" << std::endl;
53#endif
54
55 auto &det1 = data.dets[block_index1];
56 auto &det2 = data.dets[block_index2];
57 det_scalar_t det_ratio;
58
59 // Pick two pairs of C, Cdagger to remove at random
60 // Remove the operators from the traces
61 int det1_size = det1.size();
62 int det2_size = det2.size();
63 if (block_index1 == block_index2) {
64 if (det1_size < 2) return 0; // det does not contain two operators
65 } else {
66 if ((det1_size == 0) || (det2_size == 0)) return 0; // one of two dets is empty
67 }
68 int num_c_dag1 = rng(det1_size), num_c1 = rng(det1_size);
69 int num_c_dag2 = rng(det2_size), num_c2 = rng(det2_size);
70 if ((block_index1 == block_index2) && ((num_c_dag1 == num_c_dag2) || (num_c1 == num_c2))) return 0; // picked the same operator twice
71
72#ifdef EXT_DEBUG
73 std::cerr << "* Proposing to remove: ";
74 std::cerr << num_c_dag1 << "-th Cdag(" << block_index1 << ",...), ";
75 std::cerr << num_c1 << "-th C(" << block_index1 << ",...)" << std::endl;
76 std::cerr << " and ";
77 std::cerr << num_c_dag2 << "-th Cdag(" << block_index2 << ",...), ";
78 std::cerr << num_c2 << "-th C(" << block_index2 << ",...)" << std::endl;
79#endif
80
81 // now mark 2 nodes for deletion
82 tau1 = data.imp_trace.try_delete(num_c1, block_index1, false);
83 tau2 = data.imp_trace.try_delete(num_c_dag1, block_index1, true);
84 tau3 = data.imp_trace.try_delete(num_c2, block_index2, false);
85 tau4 = data.imp_trace.try_delete(num_c_dag2, block_index2, true);
86
87 dtau1 = double(tau2 - tau1);
88 dtau2 = double(tau4 - tau3);
89 if (histo_proposed1) {
90 *histo_proposed1 << dtau1;
91 *histo_proposed2 << dtau2;
92 }
93
94 if (block_index1 == block_index2) {
95 det_ratio = det1.try_remove2(num_c_dag1, num_c_dag2, num_c1, num_c2);
96 } else { // block_index1 != block_index2
97 auto det_ratio1 = det1.try_remove(num_c_dag1, num_c1);
98 auto det_ratio2 = det2.try_remove(num_c_dag2, num_c2);
99 det_ratio = det_ratio1 * det_ratio2;
100 }
101
102 // proposition probability
103 mc_weight_t t_ratio;
104 // Note: Must use the size of the det before the try_delete!
105 if (block_index1 == block_index2) {
106 // Here, we use the fact that the two cdag/c proposed to be removed in the det can be at the same
107 // positions in the det, and thus remove prob is NOT (detsize+2)*(detsize+1)
108 t_ratio = std::pow(block_size1 * config.beta() / double(det1_size), 4);
109 } else {
110 t_ratio = std::pow(block_size1 * config.beta() / double(det1_size), 2) * std::pow(block_size2 * config.beta() / double(det2_size), 2);
111 }
112
113 // For quick abandon
114 double random_number = rng.preview();
115 if (random_number == 0.0) return 0;
116 double p_yee = std::abs(det_ratio / t_ratio / data.atomic_weight);
117
118 // recompute the trace
119 std::tie(new_atomic_weight, new_atomic_reweighting) = data.imp_trace.compute(p_yee, random_number);
120 if (new_atomic_weight == 0.0) {
121#ifdef EXT_DEBUG
122 std::cerr << "atomic_weight == 0" << std::endl;
123#endif
124 return 0;
125 }
126 auto atomic_weight_ratio = new_atomic_weight / data.atomic_weight;
127 if (!isfinite(atomic_weight_ratio))
128 TRIQS_RUNTIME_ERROR << "atomic_weight_ratio not finite " << new_atomic_weight << " " << data.atomic_weight << " "
129 << new_atomic_weight / data.atomic_weight << " in config " << config.get_id();
130
131 mc_weight_t p = atomic_weight_ratio * det_ratio;
132
133#ifdef EXT_DEBUG
134 std::cerr << "Trace ratio: " << atomic_weight_ratio << '\t';
135 std::cerr << "Det ratio: " << det_ratio << '\t';
136 std::cerr << "Prefactor: " << t_ratio << '\t';
137 std::cerr << "Weight: " << p / t_ratio << std::endl;
138#endif
139
140 if (!isfinite(p)) TRIQS_RUNTIME_ERROR << "(remove) p not finite :" << p << " in config " << config.get_id();
141 if (!isfinite(p / t_ratio))
142 TRIQS_RUNTIME_ERROR << "p / t_ratio not finite p : " << p << " t_ratio : " << t_ratio << " in config " << config.get_id();
143 return p / t_ratio;
144 }
145
146 mc_weight_t move_remove_c_c_cdag_cdag::accept() {
147
148 // remove from the tree
149 data.imp_trace.confirm_delete();
150
151 // remove from the configuration
152 config.erase(tau1);
153 config.erase(tau2);
154 config.erase(tau3);
155 config.erase(tau4);
156 config.finalize();
157
158 // remove from the determinants
159 if (block_index1 == block_index2) {
160 data.dets[block_index1].complete_operation();
161 } else {
162 data.dets[block_index1].complete_operation();
163 data.dets[block_index2].complete_operation();
164 }
165 data.update_sign();
166
167 data.atomic_weight = new_atomic_weight;
168 data.atomic_reweighting = new_atomic_reweighting;
169
170 if (histo_accepted1) {
171 *histo_accepted1 << dtau1;
172 *histo_accepted2 << dtau2;
173 }
174
175#ifdef EXT_DEBUG
176 std::cerr << "* Move move_remove_c_c_cdag_cdag accepted" << std::endl;
177 std::cerr << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
178 check_det_sequence(data.dets[block_index1], config.get_id());
179 check_det_sequence(data.dets[block_index2], config.get_id());
180#endif
181
182 return data.current_sign / data.old_sign;
183 }
184
185 void move_remove_c_c_cdag_cdag::reject() {
186
187 config.finalize();
188 data.imp_trace.cancel_delete();
189 // remove from the determinants
190 if (block_index1 == block_index2) {
191 data.dets[block_index1].reject_last_try();
192 } else {
193 data.dets[block_index1].reject_last_try();
194 data.dets[block_index2].reject_last_try();
195 }
196
197#ifdef EXT_DEBUG
198 std::cerr << "* Move move_remove_c_c_cdag_cdag rejected" << std::endl;
199 std::cerr << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
200 check_det_sequence(data.dets[block_index1], config.get_id());
201 check_det_sequence(data.dets[block_index2], config.get_id());
202#endif
203 }
204}