28#include <fmt/ostream.h>
29#include <fmt/ranges.h>
30#include <itertools/itertools.hpp>
31#include <mpi/communicator.hpp>
42namespace triqs::mc_tools {
45 assert(std::abs(acc_probs_.back() - 1.0) < 1e-13);
48 current_ = std::ranges::lower_bound(acc_probs_, rng_()) - acc_probs_.begin();
49 assert(current_ < moves_.size());
52 return check_ratio(moves_[current_].
attempt());
56 for (
auto &m : moves_) m.clear_statistics();
60 for (
auto &m : moves_) m.collect_statistics(c);
64 for (
auto &m : moves_) m.calibrate(c);
68 std::map<std::string, double> res;
69 for (
auto const &[m, name] : itertools::zip(moves_, names_)) {
70 res.insert({name, m.acceptance_rate()});
71 auto tmp_map = m.get_acceptance_rates();
72 res.insert(tmp_map.begin(), tmp_map.end());
79 for (
auto const &[m, name] : itertools::zip(moves_, names_)) { str += m.get_statistics(name, prefix); }
85 for (
auto const &[m, name] : itertools::zip(moves_, names_)) { str += m.get_timings(name, prefix); }
89 template <DoubleOrComplex MCSignType>
void move_set<MCSignType>::initialize() {
91 probs_.resize(weights_.size());
92 acc_probs_.resize(weights_.size());
95 auto norm = std::accumulate(weights_.begin(), weights_.end(), 0.0);
96 std::transform(weights_.begin(), weights_.end(), probs_.begin(), [norm](
auto w) { return w / norm; });
99 std::partial_sum(probs_.begin(), probs_.end(), acc_probs_.begin());
102 template <DoubleOrComplex MCSignType>
double move_set<MCSignType>::check_ratio(MCSignType ratio) {
104 if constexpr (std::is_same_v<MCSignType, double>) {
105 if (std::isinf(ratio)) {
106 attempt_sign_ = (std::signbit(ratio) ? -1 : 1);
112 const auto abs_ratio = std::abs(ratio);
113 if (!std::isfinite(abs_ratio)) {
114 const auto cplx_ratio = std::complex<double>{ratio};
115 throw std::runtime_error(fmt::format(
"Error in move_set::check_ratio: Non-finite absolute ratio in move {}: ({},{})", names_[current_],
116 std::real(cplx_ratio), std::imag(cplx_ratio)));
120 attempt_sign_ = (abs_ratio > 1e-14 ? ratio / abs_ratio : 1);
Provides a set of MC moves.