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 <cstdint>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
#include "framework/types.hpp"
|
|
||||||
|
|
||||||
namespace AER {
|
namespace AER {
|
||||||
|
|
||||||
/***************************************************************************/ /**
|
//============================================================================
|
||||||
*
|
// RngEngine Class
|
||||||
* RngEngine Class
|
//
|
||||||
*
|
// Objects of this class are used to generate random numbers for backends.
|
||||||
* Objects of this class are used to generate random numbers for backends.
|
// These are used to decide outcomes of measurements and resets, and for
|
||||||
*These
|
// implementing noise.
|
||||||
* are used to decide outcomes of measurements and resets, and for implementing
|
//
|
||||||
* noise.
|
//============================================================================
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
class RngEngine {
|
class RngEngine {
|
||||||
public:
|
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
|
// Constructors
|
||||||
* interval [0,b)
|
//-----------------------------------------------------------------------
|
||||||
* @param b open upper bound on interval
|
|
||||||
* @return the generated double
|
|
||||||
*/
|
|
||||||
inline double rand(double b) { return rand(0, b); };
|
|
||||||
|
|
||||||
/**
|
// Default constructor initialize RNG engine with a random seed
|
||||||
* Generate a uniformly distributed pseudo random real in the half-open
|
RngEngine() { set_random_seed(); }
|
||||||
* interval [0,1)
|
|
||||||
* @return the generated double
|
|
||||||
*/
|
|
||||||
inline double rand() { return rand(0, 1); };
|
|
||||||
|
|
||||||
/**
|
// Seeded constructor initialize RNG engine with a fixed seed
|
||||||
* Generate a uniformly distributed pseudo random integer in the closed
|
explicit RngEngine(size_t seed) { set_seed(seed); }
|
||||||
* 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);
|
|
||||||
|
|
||||||
/**
|
//-----------------------------------------------------------------------
|
||||||
* Generate a pseudo random integer from a a discrete distribution
|
// Set fixed or random seed for RNG
|
||||||
* 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 random seed for the RNG engine
|
||||||
* Default constructor initialize RNG engine with a random seed
|
void set_random_seed() {
|
||||||
*/
|
|
||||||
RngEngine() {
|
|
||||||
std::random_device rd;
|
std::random_device rd;
|
||||||
rng.seed(rd());
|
set_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 a fixed seed for the RNG engine
|
// 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:
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue