TRIQS/triqs_cthyb 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
insert.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 "./insert.hpp"
23
24namespace triqs_cthyb {
25
26 histogram *move_insert_c_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_insert_c_cdag::move_insert_c_cdag(int block_index, int block_size, std::string const &block_name, qmc_data &data,
33 mc_tools::random_generator &rng, histo_map_t *histos)
34 : data(data),
35 config(data.config),
36 rng(rng),
37 block_index(block_index),
38 block_size(block_size),
39 histo_proposed(add_histo("insert_length_proposed_" + block_name, histos)),
40 histo_accepted(add_histo("insert_length_accepted_" + block_name, histos)) {}
41
42 mc_weight_t move_insert_c_cdag::attempt() {
43
44#ifdef EXT_DEBUG
45 std::cerr << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl;
46 std::cerr << "In config " << config.get_id() << std::endl;
47 std::cerr << "* Attempt for move_insert_c_cdag (block " << block_index << ")" << std::endl;
48#endif
49
50 // Pick up the value of alpha and choose the operators
51 auto rs1 = rng(block_size), rs2 = rng(block_size);
52 op1 = op_desc{block_index, rs1, true, data.linindex[std::make_pair(block_index, rs1)]};
53 op2 = op_desc{block_index, rs2, false, data.linindex[std::make_pair(block_index, rs2)]};
54
55 // Choice of times for insertion. Find the time as double and them put them on the grid.
56 tau1 = data.tau_seg.get_random_pt(rng);
57 tau2 = data.tau_seg.get_random_pt(rng);
58
59#ifdef EXT_DEBUG
60 std::cerr << "* Proposing to insert:" << std::endl;
61 std::cerr << op1 << " at " << tau1 << std::endl;
62 std::cerr << op2 << " at " << tau2 << std::endl;
63#endif
64
65 // record the length of the proposed insertion
66 dtau = double(tau2 - tau1);
67 if (histo_proposed) *histo_proposed << dtau;
68
69 // Insert the operators op1 and op2 at time tau1, tau2
70 // 1- In the very exceptional case where the insert has failed because an operator is already sitting here
71 // (cf std::map doc for insert return), we reject the move.
72 // 2- If ok, we store the iterator to the inserted operators for later removal in reject if necessary
73 try {
74 data.imp_trace.try_insert(tau1, op1);
75 data.imp_trace.try_insert(tau2, op2);
76 } catch (rbt_insert_error const &) {
77 std::cerr << "Insert error : recovering ... " << std::endl;
78 data.imp_trace.cancel_insert();
79 return 0;
80 }
81
82 // Computation of det ratio
83 auto &det = data.dets[block_index];
84 int det_size = det.size();
85
86 // Find the position for insertion in the determinant
87 // NB : the determinant stores the C in decreasing time order.
88 int num_c_dag, num_c;
89 for (num_c_dag = 0; num_c_dag < det_size; ++num_c_dag) {
90 if (det.get_x(num_c_dag).first < tau1) break;
91 }
92 for (num_c = 0; num_c < det_size; ++num_c) {
93 if (det.get_y(num_c).first < tau2) break;
94 }
95
96 // Insert in the det. Returns the ratio of dets (Cf det_manip doc).
97 auto det_ratio = det.try_insert(num_c_dag, num_c, {tau1, op1.inner_index}, {tau2, op2.inner_index});
98
99 // proposition probability
100 mc_weight_t t_ratio = std::pow(block_size * config.beta() / double(det.size() + 1), 2);
101
102 // For quick abandon
103 double random_number = rng.preview();
104 if (random_number == 0.0) return 0;
105 double p_yee = std::abs(t_ratio * det_ratio / data.atomic_weight);
106
107 // computation of the new trace after insertion
108 std::tie(new_atomic_weight, new_atomic_reweighting) = data.imp_trace.compute(p_yee, random_number);
109 if (new_atomic_weight == 0.0) {
110#ifdef EXT_DEBUG
111 std::cerr << "atomic_weight == 0" << std::endl;
112#endif
113 return 0;
114 }
115 auto atomic_weight_ratio = new_atomic_weight / data.atomic_weight;
116 if (!isfinite(atomic_weight_ratio))
117 TRIQS_RUNTIME_ERROR << "(insert) trace_ratio not finite " << new_atomic_weight << " " << data.atomic_weight << " "
118 << new_atomic_weight / data.atomic_weight << " in config " << config.get_id();
119
120 mc_weight_t p = atomic_weight_ratio * det_ratio;
121
122#ifdef EXT_DEBUG
123 std::cerr << "Atomic ratio: " << atomic_weight_ratio << '\t';
124 std::cerr << "Det ratio: " << det_ratio << '\t';
125 std::cerr << "Prefactor: " << t_ratio << '\t';
126 std::cerr << "Weight: " << p * t_ratio << std::endl;
127 std::cerr << "p_yee * newtrace: " << p_yee * new_atomic_weight << std::endl;
128#endif
129
130 if (!isfinite(p * t_ratio)) {
131 std::cerr << "Insert move info:\n";
132 std::cerr << "Atomic ratio: " << atomic_weight_ratio << '\t';
133 std::cerr << "Det ratio: " << det_ratio << '\t';
134 std::cerr << "Prefactor: " << t_ratio << '\t';
135 std::cerr << "Weight: " << p * t_ratio << std::endl;
136 std::cerr << "p_yee * newtrace: " << p_yee * new_atomic_weight << std::endl;
137
138 TRIQS_RUNTIME_ERROR << "(insert) p * t_ratio not finite p : " << p << " t_ratio : " << t_ratio << " in config " << config.get_id();
139 }
140 return p * t_ratio;
141 }
142
143 mc_weight_t move_insert_c_cdag::accept() {
144
145 // insert in the tree
146 data.imp_trace.confirm_insert();
147
148 // insert in the configuration
149 config.insert(tau1, op1);
150 config.insert(tau2, op2);
151 config.finalize();
152
153 // insert in the determinant
154 data.dets[block_index].complete_operation();
155 data.update_sign();
156 data.atomic_weight = new_atomic_weight;
157 data.atomic_reweighting = new_atomic_reweighting;
158 if (histo_accepted) *histo_accepted << dtau;
159
160#ifdef EXT_DEBUG
161 std::cerr << "* Move move_insert_c_cdag accepted" << std::endl;
162 std::cerr << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
163 check_det_sequence(data.dets[block_index], config.get_id());
164#endif
165
166 return data.current_sign / data.old_sign;
167 }
168
169 void move_insert_c_cdag::reject() {
170
171 config.finalize();
172 data.imp_trace.cancel_insert();
173 data.dets[block_index].reject_last_try();
174
175#ifdef EXT_DEBUG
176 std::cerr << "* Move move_insert_c_cdag rejected" << std::endl;
177 std::cerr << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
178 check_det_sequence(data.dets[block_index], config.get_id());
179#endif
180 }
181}