TRIQS/TRIQS 4.0.0
Researching Interacting Quantum Systems
Loading...
Searching...
No Matches
random_generator.hpp
Go to the documentation of this file.
1// Copyright (c) 2013-2018 Commissariat à l'énergie atomique et aux énergies alternatives (CEA)
2// Copyright (c) 2013-2018 Centre national de la recherche scientifique (CNRS)
3// Copyright (c) 2018-2020 Simons Foundation
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You may obtain a copy of the License at
16// https://www.gnu.org/licenses/gpl-3.0.txt
17//
18// Authors: Michel Ferrero, Olivier Parcollet, Nils Wentzell
19
24
25#pragma once
26
27#include <h5/h5.hpp>
28
29#include <cassert>
30#include <cmath>
31#include <concepts>
32#include <cstdint>
33#include <iostream>
34#include <memory>
35#include <string>
36#include <sstream>
37#include <utility>
38#include <vector>
39
40namespace triqs::mc_tools {
41
46
72 private:
73 // RNG concept defines the interface for RNGs.
74 struct rng_concept {
75 virtual ~rng_concept() = default;
76 virtual double operator()() = 0;
77 virtual void refill(std::vector<double> &) = 0;
78 virtual std::ostream &to_ostream(std::ostream &) const = 0;
79 virtual std::istream &from_istream(std::istream &) = 0;
80 };
81
82 // RNG model implements the RNG concept by calling the appropriate methods of the type erased object.
83 template <typename T> struct rng_model : public rng_concept {
84 T rng_;
85 rng_model(T rng) : rng_{std::move(rng)} {}
86 double operator()() override { return rng_(); }
87 void refill(std::vector<double> &buffer) override {
88 for (auto &x : buffer) x = rng_();
89 }
90 std::ostream &to_ostream(std::ostream &os) const override {
91 os << rng_.engine();
92 return os;
93 }
94 std::istream &from_istream(std::istream &is) override {
95 is >> rng_.engine();
96 return is;
97 }
98 };
99
100 public:
102 static constexpr std::uint32_t default_seed = 198;
103
106
119 random_generator(std::string name, std::uint32_t seed, std::size_t buffer_size = 1000);
120
123
126
129
131 [[nodiscard]] std::string name() const { return name_; }
132
140 template <typename T>
141 requires(std::integral<T>)
142 T operator()(T i) {
143 return (i == 1 ? 0 : static_cast<T>(std::floor(i * this->operator()())));
144 }
145
150 [[nodiscard]] double preview() {
151 if (idx_ > buffer_.size() - 1) refill();
152 return buffer_[idx_];
153 }
154
159 double operator()() {
160 if (idx_ > buffer_.size() - 1) refill();
161 return buffer_[idx_++];
162 }
163
169 double operator()(double b) { return b * (this->operator()()); }
170
178 double operator()(double a, double b) {
179 assert(b > a);
180 return a + (b - a) * (this->operator()());
181 }
182
184 [[nodiscard]] static std::string hdf5_format() { return "random_generator"; }
185
193 friend void h5_write(h5::group g, std::string const &name, random_generator const &rng) {
194 auto gr = g.create_group(name);
195 h5::write_hdf5_format(gr, rng); // NOLINT (downcasting to base class)
196 h5::write(gr, "name", rng.name_);
197 h5::write(gr, "buffer", rng.buffer_);
198 h5::write(gr, "idx", rng.idx_);
199 std::ostringstream os;
200 rng.ptr_->to_ostream(os);
201 h5::write(gr, "rng", os.str());
202 }
203
211 friend void h5_read(h5::group g, std::string const &name, random_generator &rng) {
212 auto gr = g.open_group(name);
213 h5::assert_hdf5_format(gr, rng); // NOLINT (downcasting to base class)
214 h5::read(gr, "name", rng.name_);
215 h5::read(gr, "buffer", rng.buffer_);
216 h5::read(gr, "idx", rng.idx_);
217 rng.initialize_rng(rng.name_, default_seed);
218 std::string rng_state;
219 h5::read(gr, "rng", rng_state);
220 std::istringstream is{rng_state};
221 rng.ptr_->from_istream(is);
222 }
223
224 private:
225 // Refill the buffer.
226 void refill() {
227 ptr_->refill(buffer_);
228 idx_ = 0;
229 }
230
231 // Initialize the RNG.
232 void initialize_rng(std::string const &name, std::uint32_t seed);
233
234 private:
235 std::unique_ptr<rng_concept> ptr_;
236 size_t idx_{0};
237 std::vector<double> buffer_;
238 std::string name_;
239 };
240
246 [[nodiscard]] std::string random_generator_names(std::string const &sep = " ");
247
249 [[nodiscard]] std::vector<std::string> random_generator_names_list();
250
252
253} // namespace triqs::mc_tools
double operator()(double b)
Generate a random sample from the uniform distribution defined on the interval .
random_generator()
Default constructor uses the mt19937 engine with the default seed.
double operator()()
Generate a random sample from the uniform distribution defined on the interval .
random_generator(random_generator const &)=delete
Deleted copy constructor.
std::string name() const
Get the name of the underlying RNG.
static std::string hdf5_format()
Get the HDF5 format tag.
friend void h5_write(h5::group g, std::string const &name, random_generator const &rng)
Write the RNG object to HDF5.
random_generator & operator=(random_generator &&)=default
Default move assignment operator.
random_generator(random_generator &&)=default
Default move constructor.
double operator()(double a, double b)
Generate a random sample from the uniform distribution defined on the interval .
friend void h5_read(h5::group g, std::string const &name, random_generator &rng)
Read the RNG object from HDF5.
double preview()
Look ahead at the next value that will be generated when the generator is called.
static constexpr std::uint32_t default_seed
Default seed for the underlying RNG.
std::string random_generator_names(std::string const &sep)
Get a string containing the names of all available RNGs.
std::vector< std::string > random_generator_names_list()
Get a list of all available RNG names.