您的位置:首页 > 编程语言 > C语言/C++

基于 intel MKL 的高性能随机数生成器

2017-04-20 14:07 1051 查看
这个类基于 intel Math Kernel Library 的随机数生成器,可以生成平均分布的 int/float/double。保持接口与 C++11 一致,即:对于 int,生成范围是 [a, b];对于 float 与 double,生成范围是 [a, b)。

不需要每次去初始化种子。只需要随时调用即可,每次调用都可以得到不同的随机数。

代码如下(编译时需要指定 -std=c++11):

#ifndef RANDOM_NUMBER_CLASS_H
#define RANDOM_NUMBER_CLASS_H

#include <mkl.h>

template<typename Type>
class Random
{
public:
Random();
Random(const Random&) = delete;
Random(Random&&) = delete;
Random& operator=(const Random&) = delete;
Random& operator=(Random&&) = delete;
~Random();
Type operator()(Type left, Type right);
private:
VSLStreamStatePtr stream;
};

// creates and initializes a random stream
// use Mersenne-Twister pseudorandom number generator: VSL_BRNG_MT19937
// use time counter on CPU instruction level (ASM): __rdtsc()
// __rdtsc() returns the CPU time stamp
template<typename Type>
inline Random<Type>::Random()
{
vslNewStream(&stream, VSL_BRNG_MT19937, __rdtsc());
}

// deletes the random stream
template<typename Type>
inline Random<Type>::~Random()
{
vslDeleteStream(&stream);
}

// template specialization: int
// randomly return an int in the section [left, right]
template<>
inline int Random<int>::operator()(int left, int right)
{
int retValue;
viRngUniform(VSL_RNG_METHOD_UNIFORM_STD, stream, 1, &retValue, left, right + 1);
return retValue;
}

// template specialization: float
// randomly return a float in the section [left, right)
template<>
inline float Random<float>::operator()(float left, float right)
{
float retValue;
vsRngUniform(VSL_RNG_METHOD_UNIFORM_STD, stream, 1, &retValue, left, right);
return retValue;
}

// template specialization: double
// randomly return a double in the section [left, right)
template<>
inline double Random<double>::operator()(double left, double right)
{
double retValue;
vdRngUniform(VSL_RNG_METHOD_UNIFORM_STD, stream, 1, &retValue, left, right);
return retValue;
}

#endif // !RANDOM_NUMBER_CLASS_H


使用方法非常简单。以随机生成 int 为例:

Random<int> rand;
int ival = rand(0, 9); // 生成一个在区间 [0, 9] 内的随机数,0 和 9 都包括在内


在循环中使用时也无需再考虑初始化种子的问题,直接使用即可。例如:

Random<int> rand;
for(int i = 0; i < 10; ++i)
std::cout << rand(0, 9) << std::endl; // 每次输出一个 [0, 9] 区间内的随机整数,无需考虑种子问题


同一个对象可以对不同的区间重复使用,直到此对象析构。例如:

Random<int> rand;
int ival1 = rand(0, 9); // 生成一个 [0, 9] 区间内的随机整数
int ival2 = rand(10, 19); // 生成一个 [10, 19] 区间内的随机整数


转载请注明本文地址 http://blog.csdn.net/luozhen07/article/details/70257856
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  随机数 C++ MKL