mirror of https://github.com/Qiskit/qiskit-aer.git
Add templates to RngEngine class (#690)
* Add templates to RngEngine class * Use 64-bit mersenne twister rng engine
This commit is contained in:
parent
5828c51d91
commit
7816fa0102
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
upgrade:
|
||||
- |
|
||||
Change the RNG engine for simulators from 32-bit Mersenne twister to
|
||||
64-bit Mersenne twister engine.
|
|
@ -18,117 +18,85 @@
|
|||
#include <cstdint>
|
||||
#include <random>
|
||||
|
||||
#include "framework/types.hpp"
|
||||
|
||||
namespace AER {
|
||||
|
||||
/***************************************************************************/ /**
|
||||
*
|
||||
* RngEngine Class
|
||||
*
|
||||
* Objects of this class are used to generate random numbers for backends.
|
||||
*These
|
||||
* are used to decide outcomes of measurements and resets, and for implementing
|
||||
* noise.
|
||||
*
|
||||
******************************************************************************/
|
||||
//============================================================================
|
||||
// RngEngine Class
|
||||
//
|
||||
// Objects of this class are used to generate random numbers for backends.
|
||||
// These are used to decide outcomes of measurements and resets, and for
|
||||
// implementing noise.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
class RngEngine {
|
||||
public:
|
||||
/**
|
||||
* Generate a uniformly distributed pseudo random real in the half-open
|
||||
* interval [a,b)
|
||||
* @param a closed lower bound on interval
|
||||
* @param b open upper bound on interval
|
||||
* @return the generated double
|
||||
*/
|
||||
double rand(double a, double b);
|
||||
|
||||
/**
|
||||
* Generate a uniformly distributed pseudo random real in the half-open
|
||||
* interval [0,b)
|
||||
* @param b open upper bound on interval
|
||||
* @return the generated double
|
||||
*/
|
||||
inline double rand(double b) { return rand(0, b); };
|
||||
//-----------------------------------------------------------------------
|
||||
// Constructors
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Generate a uniformly distributed pseudo random real in the half-open
|
||||
* interval [0,1)
|
||||
* @return the generated double
|
||||
*/
|
||||
inline double rand() { return rand(0, 1); };
|
||||
// Default constructor initialize RNG engine with a random seed
|
||||
RngEngine() { set_random_seed(); }
|
||||
|
||||
/**
|
||||
* Generate a uniformly distributed pseudo random integer in the closed
|
||||
* interval [a,b]
|
||||
* @param a lower bound on interval
|
||||
* @param b upper bound on interval
|
||||
* @return the generated integer
|
||||
*/
|
||||
int_t rand_int(int_t a, int_t b);
|
||||
uint_t rand_int(uint_t a, uint_t b);
|
||||
// Seeded constructor initialize RNG engine with a fixed seed
|
||||
explicit RngEngine(size_t seed) { set_seed(seed); }
|
||||
|
||||
/**
|
||||
* Generate a pseudo random integer from a a discrete distribution
|
||||
* constructed from an input vector of probabilities for [0,..,n-1]
|
||||
* where n is the lenght of the vector. If this vector is not normalized
|
||||
* it will be scaled when it is converted to a discrete_distribution
|
||||
* @param probs the vector of probabilities
|
||||
* @return the generated integer
|
||||
*/
|
||||
uint_t rand_int(const std::vector<double> &probs);
|
||||
//-----------------------------------------------------------------------
|
||||
// Set fixed or random seed for RNG
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Default constructor initialize RNG engine with a random seed
|
||||
*/
|
||||
RngEngine() {
|
||||
// Set random seed for the RNG engine
|
||||
void set_random_seed() {
|
||||
std::random_device rd;
|
||||
rng.seed(rd());
|
||||
};
|
||||
|
||||
/**
|
||||
* Seeded constructor initialize RNG engine with a fixed seed
|
||||
* @param seed integer to use as seed for mt19937 engine
|
||||
*/
|
||||
explicit RngEngine(uint_t seed) { rng.seed(seed); };
|
||||
|
||||
set_seed(rd());
|
||||
}
|
||||
|
||||
// Set a fixed seed for the RNG engine
|
||||
void set_seed(uint_t seed) { rng.seed(seed); };
|
||||
void set_seed(size_t seed) { rng.seed(seed); }
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Sampling methods
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
// Generate a uniformly distributed pseudo random real in the half-open
|
||||
// interval [a,b)
|
||||
double rand(double a, double b) {
|
||||
return std::uniform_real_distribution<double>(a, b)(rng);
|
||||
}
|
||||
|
||||
// Generate a uniformly distributed pseudo random real in the half-open
|
||||
// interval [0,b)
|
||||
double rand(double b) {
|
||||
return rand(double(0), b);
|
||||
};
|
||||
|
||||
// Generate a uniformly distributed pseudo random real in the half-open
|
||||
// interval [0,1)
|
||||
double rand() {return rand(0, 1); };
|
||||
|
||||
// Generate a uniformly distributed pseudo random integer in the closed
|
||||
// interval [a,b]
|
||||
template <typename Integer,
|
||||
typename = std::enable_if_t<std::is_integral<Integer>::value>>
|
||||
Integer rand_int(Integer a, Integer b) {
|
||||
return std::uniform_int_distribution<Integer>(a, b)(rng);
|
||||
}
|
||||
|
||||
// Generate a pseudo random integer from a a discrete distribution
|
||||
// constructed from an input vector of probabilities for [0,..,n-1]
|
||||
// where n is the lenght of the vector. If this vector is not normalized
|
||||
// it will be scaled when it is converted to a discrete_distribution
|
||||
template <typename Float,
|
||||
typename = std::enable_if_t<std::is_floating_point<Float>::value>>
|
||||
size_t rand_int(const std::vector<Float> &probs) {
|
||||
return std::discrete_distribution<size_t>(probs.begin(), probs.end())(rng);
|
||||
}
|
||||
|
||||
private:
|
||||
std::mt19937 rng; // Mersenne twister rng engine
|
||||
std::mt19937_64 rng; // Mersenne twister rng engine
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* RngEngine Methods
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
double RngEngine::rand(double a, double b) {
|
||||
double p = std::uniform_real_distribution<double>(a, b)(rng);
|
||||
return p;
|
||||
}
|
||||
|
||||
// randomly distributed integers in [a,b]
|
||||
int_t RngEngine::rand_int(int_t a, int_t b) {
|
||||
int_t n = std::uniform_int_distribution<int_t>(a, b)(rng);
|
||||
return n;
|
||||
}
|
||||
|
||||
uint_t RngEngine::rand_int(uint_t a, uint_t b) {
|
||||
int_t n = std::uniform_int_distribution<uint_t>(a, b)(rng);
|
||||
return n;
|
||||
}
|
||||
|
||||
// randomly distributed integers from vector
|
||||
uint_t RngEngine::rand_int(const std::vector<double> &probs) {
|
||||
uint_t n = std::discrete_distribution<uint_t>(probs.begin(), probs.end())(rng);
|
||||
return n;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
} // End namespace QISKIT
|
||||
} // End namespace AER
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue