一个正态/指数随机数生成器和直方图类






4.73/5 (9投票s)
2002年9月9日
4分钟阅读

280855

8188
一个具有正态或指数分布的快速随机生成器 + 一个直方图类
引言
随机变量生成器
本文介绍了一个用于生成随机变量(即正态分布和指数分布)的快速生成器。该算法出自 George Marsaglia 和 Wai Wan Tsang 在 [1] 中的工作。以下是他们论文的摘要:
我们提供了一个新版本的 Ziggurat 方法,用于生成给定递减密度函数的随机变量。它比原始方法更快、更简单,例如,在 400MHz 的 PC 机上,C 语言版本每秒可以生成 1500 万个正态或指数分布的随机变量。它使用了两个表,整数 ki 和实数 wi。大约 99% 的情况下,所需的 x 值通过以下方式生成:生成一个随机的 32 位整数 j,设 i 为 j 的最右边 8 位形成的索引。如果 j < ki,则返回 x = j . wi。
他们完成了 99.9% 的工作,我只是将他们的 C 代码封装在一个类包装器中。
直方图
为了说明这个生成器,我们还提供了一个名为 THistogram
的模板类。
一点数学背景
正态分布在概率和统计学中占有重要地位,这主要是因为中心极限定理,它是连接这两个学科的基本定理之一。
正态分布也称为高斯分布,以卡尔·弗里德里希·高斯的名字命名,他是最早使用该分布的人之一。
网上有很多关于正态分布的教程和演示小程序,所以我在这里不深入探讨数学细节。您可以在 概率和统计学虚拟实验室 找到一个非常好的网站。
用于计算均值、方差和其他统计特性的算法取自《数值分析》(见 [2])。
使用生成器
CRandomGenerator
提供了两种类型的随机变量:正态分布和指数分布。它们由两个 static
函数 RNOR
和 REXP
计算。
- 标准正态变量
float var = CRandomGenerator::RNOR();
您还可以修改生成器的均值和标准差。float fMean=...; float fSdev=...; float var = CRandomGenerator::RNOR(fMean, fSdev);
- 指数分布变量
float var = CRandomGenerator::REXP();
初始化生成器
与任何随机数生成器一样,它需要用一个“种子”进行初始化。传统上,人们使用当前时间来播种生成器。这在 CRandomGenerator
的默认构造函数中是隐式完成的,所以您需要在您的应用程序线程中使用该生成器之前,构建一个且仅一个 CRandomGenerator
对象。在 CWinApp::InitInstance
函数中这样做是个好主意。
CWinApp::InitInstance
{
...
// build a CRandomGenerator to seed the generator
CRandomGenerator randn;
}
使用直方图
THistogram
是一个模板化的直方图类。
模板参数
T
,输入数据类型:可以是float
或double
。TOut
,结果数据类型:可以是float
或double
,默认设置为double
。
Characteristics
直方图的特点是:
- 一个区域,由最小和最大谱值定义(参见
Get/SetMinSpectrum
,Get/SetMaxSpectrum
)。 - 一个步长(参见
GetStep
)。
计算直方图
您可以通过不同的方式向直方图提供数据:
- 提供一组数据
vector< float > vData; ... // computing the data // Creating an histogram with 101 regions THistogram< float > histo(101); // Computing the histogram, min and max values are automatically computed... histo.Compute( vData , true /* compute min, max */);
- 用一组数据更新
vector< float > vData; ... // updating the histogram histo.Update( vData );
- 用单个数据项更新
float fData; ... // updating the histogram histo.Update( fData );
- 计算数据集的统计特性:您可以使用
static
方法GetMoments
来计算数据集的矩(均值、标准差、方差等)。float fMean, fAdev, fSdev, fVar, fSkew,fKurt; // Computing successively the mean, absolute mean, // standard deviation, variance, skewness and kurtosis THistogram<float,float>::GetMoments(vData, fAdev, fSdev,fVar, fSkew, fKurt);
该方法在演示中用于比较CRandomGenerator
生成的正态分布和理论概率密度函数。
检索结果
- 使用
GetHistogram
获取直方图结果。 - 通过调用
GetNormalizedHistogram
获取归一化的直方图(使其面积为 1)。 - 可以使用
GetLeftContainers
和GetCenterContainers
访问区域的坐标。用于生成图表的代码如下所示:
vector < double > vDistribution ( histo.GetNormalizedHistogram() ); vector < double > vLeftPositions ( histo.GetLeftContainers() ); CPGLLine2D* pLine; ... pLine->SetDatas(vLeftPositions, vDistributions);
演示应用程序
演示应用程序显示了正态分布和指数分布。红线代表随机值的直方图,蓝线代表理论概率密度函数。
演示应用程序中有两个项目:
HistogramDemo
使用 Plot Graphic Library 进行可视化。关于 PGL 的另一篇文章可以在 这里找到。您需要 GDI+ 二进制文件才能使演示应用程序正常工作!(gdiplus.dll)HistogramMatlab
使用 Matlab 引擎进行可视化。您需要安装 Matlab 才能使演示应用程序正常工作!
请注意,源代码使用 Doxygen 语法进行了文档化。
参考文献
- [1] Ziggurat 方法生成随机变量,George Marsaglia 和 Wai Wan Tsang,Journal of Statistical Software,第 05 卷,第 08 期。
- [2] C 语言中的数值分析,第 14 章。
更新历史
- 2002年11月26日
- 在
CRandomGenerator
中添加了理论分布。 - 添加了直方图面积计算。
- 修正了归一化直方图,添加了。
- 在
- 2002年9月13日
- 添加了一个使用 Matlab 的新演示项目。
- 2002年9月11日
- 修正了演示项目并在演示中添加了二进制文件。
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。