22#include "./global.hpp"
24namespace triqs_cthyb {
26 move_global::move_global(std::string
const &name, indices_map_t
const &substitution_map, qmc_data &data, mc_tools::random_generator &rng)
31 substitute_c(data.linindex.size()),
32 substitute_c_dag(data.linindex.size()),
36 auto const &fops = data.h_diag.get_fops();
39 std::vector<std::pair<int, int>> lin_to_block_inner(data.linindex.size());
40 for (
auto const &l : data.linindex) lin_to_block_inner[l.second] = l.first;
43 for (
int lin = 0; lin < lin_to_block_inner.size(); ++lin) {
44 int new_lin, new_block, new_inner;
47 auto it = std::find_if(std::begin(substitution_map), std::end(substitution_map),
48 [&fops, lin](indices_map_t::value_type
const &kv) {
return fops[kv.first] == lin; });
51 new_lin = (it != std::end(substitution_map)) ? fops[it->second] : lin;
52 std::tie(new_block, new_inner) = lin_to_block_inner[new_lin];
56 affected_blocks.insert(lin_to_block_inner[lin].first);
57 affected_blocks.insert(new_block);
60 substitute_c[lin] = op_desc{new_block, new_inner,
false, new_lin};
61 substitute_c_dag[lin] = op_desc{new_block, new_inner,
true, new_lin};
64 if (identity) std::cerr <<
"WARNING: global move '" << name <<
"' changes no operator indices, therefore is useless." << std::endl;
67 mc_weight_t move_global::attempt() {
70 std::cerr <<
">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl;
71 std::cerr <<
"In config " << config.get_id() << std::endl;
72 std::cerr <<
"* Attempt for move move_global (" << name <<
")" << std::endl;
76 for (
auto const &o : data.config) {
77 auto const &tau = o.first;
78 auto const &old_op = o.second;
79 auto const &new_op = (old_op.dagger ? substitute_c_dag : substitute_c)[old_op.linear_index];
80 if (old_op.linear_index != new_op.linear_index) updated_ops.emplace(tau, new_op);
84 std::cerr << updated_ops.size() <<
" out of " << data.config.size() <<
" operators can be changed" << std::endl;
88 if (!updated_ops.size())
return 0;
92 int n_no_update = rng(updated_ops.size());
94 for (
int i = 0; i < n_no_update; ++i) {
95 auto it = std::begin(updated_ops);
96 std::advance(it, rng(updated_ops.size()));
97 updated_ops.erase(it);
101 std::cerr << updated_ops.size() <<
" operators will actually be changed" << std::endl;
105 for (
auto block_index : affected_blocks) {
106 x[block_index].clear();
107 y[block_index].clear();
110 for (
auto const &o : data.config) {
111 auto const &tau = o.first;
112 auto it = updated_ops.find(tau);
113 auto const &new_op = it == updated_ops.end() ? o.second : it->second;
114 (new_op.dagger ? x : y)[new_op.block_index].emplace_back(tau, new_op.inner_index);
117 for (
auto block_index : affected_blocks) {
119 if (x[block_index].size() != y[block_index].size())
return 0;
123 mc_weight_t det_ratio = 1;
124 for (
auto block_index : affected_blocks) {
125 auto &det = data.dets[block_index];
126 mc_weight_t block_det_ratio = det.try_refill(x[block_index], y[block_index]);
127 if (block_det_ratio == .0) {
129 std::cerr <<
"block_det_ratio[" << block_index <<
"] = 0" << std::endl;
133 det_ratio *= block_det_ratio;
137 double random_number = rng.preview();
138 if (random_number == 0.0)
return 0;
139 double p_yee = std::abs(det_ratio / data.atomic_weight);
141 data.imp_trace.try_replace(updated_ops);
144 std::tie(new_atomic_weight, new_atomic_reweighting) = data.imp_trace.compute(p_yee, random_number);
145 if (new_atomic_weight == 0.0) {
147 std::cerr <<
"trace == 0" << std::endl;
151 auto atomic_weight_ratio = new_atomic_weight / data.atomic_weight;
152 if (!isfinite(atomic_weight_ratio))
153 TRIQS_RUNTIME_ERROR <<
"atomic_weight_ratio not finite " << new_atomic_weight <<
" " << data.atomic_weight <<
" "
154 << new_atomic_weight / data.atomic_weight <<
" in config " << config.get_id();
156 mc_weight_t p = atomic_weight_ratio * det_ratio;
159 std::cerr <<
"Trace ratio: " << atomic_weight_ratio <<
'\t';
160 std::cerr <<
"Det ratio: " << det_ratio <<
'\t';
161 std::cerr <<
"p_yee: " << p_yee << std::endl;
162 std::cerr <<
"Weight: " << p << std::endl;
168 mc_weight_t move_global::accept() {
170 for (
auto const &o : updated_ops) data.config.replace(o.first, o.second);
173 for (
auto block_index : affected_blocks) data.dets[block_index].complete_operation();
176 data.atomic_weight = new_atomic_weight;
177 data.atomic_reweighting = new_atomic_reweighting;
179 data.imp_trace.confirm_replace();
182 std::cerr <<
"* Move move_global '" << name <<
"' accepted" << std::endl;
183 std::cerr <<
"<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
184 for (
int block_index : affected_blocks) check_det_sequence(data.dets[block_index], config.get_id());
187 return data.current_sign / data.old_sign;
190 void move_global::reject() {
193 data.imp_trace.cancel_replace();
194 for (
auto block_index : affected_blocks) data.dets[block_index].reject_last_try();
197 std::cerr <<
"* Move move_global '" << name <<
"' rejected" << std::endl;
198 std::cerr <<
"<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
199 for (
int block_index : affected_blocks) check_det_sequence(data.dets[block_index], config.get_id());