-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathinsert.cpp
173 lines (144 loc) · 6.67 KB
/
insert.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*******************************************************************************
*
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
*
* Copyright (C) 2014, P. Seth, I. Krivenko, M. Ferrero and O. Parcollet
*
* TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* TRIQS. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
#include "./insert.hpp"
namespace triqs_cthyb {
histogram *move_insert_c_cdag::add_histo(std::string const &name, histo_map_t *histos) {
if (!histos) return nullptr;
auto new_histo = histos->insert({name, {.0, config.beta(), 100}});
return &(new_histo.first->second);
}
move_insert_c_cdag::move_insert_c_cdag(int block_index, int block_size, std::string const &block_name, qmc_data &data,
mc_tools::random_generator &rng, histo_map_t *histos)
: data(data),
config(data.config),
rng(rng),
block_index(block_index),
block_size(block_size),
histo_proposed(add_histo("insert_length_proposed_" + block_name, histos)),
histo_accepted(add_histo("insert_length_accepted_" + block_name, histos)) {}
mc_weight_t move_insert_c_cdag::attempt() {
#ifdef EXT_DEBUG
std::cerr << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl;
std::cerr << "In config " << config.get_id() << std::endl;
std::cerr << "* Attempt for move_insert_c_cdag (block " << block_index << ")" << std::endl;
#endif
// Pick up the value of alpha and choose the operators
auto rs1 = rng(block_size), rs2 = rng(block_size);
op1 = op_desc{block_index, rs1, true, data.linindex[std::make_pair(block_index, rs1)]};
op2 = op_desc{block_index, rs2, false, data.linindex[std::make_pair(block_index, rs2)]};
// Choice of times for insertion. Find the time as double and them put them on the grid.
tau1 = data.tau_seg.get_random_pt(rng);
tau2 = data.tau_seg.get_random_pt(rng);
#ifdef EXT_DEBUG
std::cerr << "* Proposing to insert:" << std::endl;
std::cerr << op1 << " at " << tau1 << std::endl;
std::cerr << op2 << " at " << tau2 << std::endl;
#endif
// record the length of the proposed insertion
dtau = double(tau2 - tau1);
if (histo_proposed) *histo_proposed << dtau;
// Insert the operators op1 and op2 at time tau1, tau2
// 1- In the very exceptional case where the insert has failed because an operator is already sitting here
// (cf std::map doc for insert return), we reject the move.
// 2- If ok, we store the iterator to the inserted operators for later removal in reject if necessary
try {
data.imp_trace.try_insert(tau1, op1);
data.imp_trace.try_insert(tau2, op2);
} catch (rbt_insert_error const &) {
std::cerr << "Insert error : recovering ... " << std::endl;
data.imp_trace.cancel_insert();
return 0;
}
// Computation of det ratio
auto &det = data.dets[block_index];
int det_size = det.size();
// Find the position for insertion in the determinant
// NB : the determinant stores the C in decreasing time order.
int num_c_dag, num_c;
for (num_c_dag = 0; num_c_dag < det_size; ++num_c_dag) {
if (det.get_x(num_c_dag).first < tau1) break;
}
for (num_c = 0; num_c < det_size; ++num_c) {
if (det.get_y(num_c).first < tau2) break;
}
// Insert in the det. Returns the ratio of dets (Cf det_manip doc).
auto det_ratio = det.try_insert(num_c_dag, num_c, {tau1, op1.inner_index}, {tau2, op2.inner_index});
// proposition probability
mc_weight_t t_ratio = std::pow(block_size * config.beta() / double(det.size() + 1), 2);
// For quick abandon
double random_number = rng.preview();
if (random_number == 0.0) return 0;
double p_yee = std::abs(t_ratio * det_ratio / data.atomic_weight);
// computation of the new trace after insertion
std::tie(new_atomic_weight, new_atomic_reweighting) = data.imp_trace.compute(p_yee, random_number);
if (new_atomic_weight == 0.0) {
#ifdef EXT_DEBUG
std::cerr << "atomic_weight == 0" << std::endl;
#endif
return 0;
}
auto atomic_weight_ratio = new_atomic_weight / data.atomic_weight;
if (!isfinite(atomic_weight_ratio))
TRIQS_RUNTIME_ERROR << "trace_ratio not finite " << new_atomic_weight << " " << data.atomic_weight << " "
<< new_atomic_weight / data.atomic_weight << " in config " << config.get_id();
mc_weight_t p = atomic_weight_ratio * det_ratio;
#ifdef EXT_DEBUG
std::cerr << "Atomic ratio: " << atomic_weight_ratio << '\t';
std::cerr << "Det ratio: " << det_ratio << '\t';
std::cerr << "Prefactor: " << t_ratio << '\t';
std::cerr << "Weight: " << p * t_ratio << std::endl;
std::cerr << "p_yee * newtrace: " << p_yee * new_atomic_weight << std::endl;
#endif
if (!isfinite(p * t_ratio))
TRIQS_RUNTIME_ERROR << "p * t_ratio not finite p : " << p << " t_ratio : " << t_ratio << " in config " << config.get_id();
return p * t_ratio;
}
mc_weight_t move_insert_c_cdag::accept() {
// insert in the tree
data.imp_trace.confirm_insert();
// insert in the configuration
config.insert(tau1, op1);
config.insert(tau2, op2);
config.finalize();
// insert in the determinant
data.dets[block_index].complete_operation();
data.update_sign();
data.atomic_weight = new_atomic_weight;
data.atomic_reweighting = new_atomic_reweighting;
if (histo_accepted) *histo_accepted << dtau;
#ifdef EXT_DEBUG
std::cerr << "* Move move_insert_c_cdag accepted" << std::endl;
std::cerr << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
check_det_sequence(data.dets[block_index], config.get_id());
#endif
return data.current_sign / data.old_sign;
}
void move_insert_c_cdag::reject() {
config.finalize();
data.imp_trace.cancel_insert();
data.dets[block_index].reject_last_try();
#ifdef EXT_DEBUG
std::cerr << "* Move move_insert_c_cdag rejected" << std::endl;
std::cerr << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
check_det_sequence(data.dets[block_index], config.get_id());
#endif
}
}