VHDL的随机数有多好?

5
我正在使用VHDL的随机数,来自IEEE.math_real,但是这些生成的数字有多好呢?与C中的rand(...)相比如何?是否进行了统计测试?
下面是高斯分布的直方图。参数如下:
- 随机源:由math_real.Uniform(...)生成的2个均匀分布的实数值 - Box-Muller变换 - 使用REAL计算 - 输出范围:0..4095整数 - 102.400次迭代
经典的直方图视图: NormalDistributedRandomValue 100Ki iterations; range 0..4095 作为点云: NormalDistributedRandomValue 100Ki iterations; range 0..4095 下面是均匀分布的直方图。参数如下:
- 随机源:由math_real.Uniform(...)生成的均匀分布的实数值 - 使用REAL计算 - 输出范围:0..4095整数 - 102.400次迭代
经典的直方图视图: NormalDistributedRandomValue 100Ki iterations; range 0..4095 作为点云: NormalDistributedRandomValue 100Ki iterations; range 0..4095 f(x)=m*x+b的Gnuplot拟合结果:
m = -0.0000343906
b = 25.0704

在我看来,这两个直方图都有很高的抖动。

3
亲爱的点踩者,如果您能留下一个给出点踩原因的评论,那将非常好,这样问题就可以得到改进。 - Morten Zilmer
可能有趣的是进行卡方检验,以查看抖动/异常值是否在合理范围内。 - Morten Zilmer
在Gnuplot中是否可以进行这样的测试?我还在等待我的均匀分布完成... 我目前的测试显示重心不在2048处。 - Paebbels
@MortenZilmer 我添加了均匀分布的直方图并拟合了m*x+b。我将尝试对第一张图片进行高斯拟合。你对VHDL生成的dat文件感兴趣吗? - Paebbels
当迭代次数增加时,它是否会变得更平滑? - Martin Zabel
@MartinZabel 不,我测试了1k、10k、100k和1M次迭代。所展示的图像是基于100k次迭代的。Gnuplot将高斯分布的平均值拟合为2068而不是2048。 - Paebbels
1个回答

2
IEEE.math_real.UNIFORM 的实现方式为:
procedure UNIFORM(variable SEED1,SEED2:inout POSITIVE;variable X:out REAL) is
  ...
  variable Z, K: INTEGER;
  variable TSEED1 : INTEGER := INTEGER'(SEED1);
  variable TSEED2 : INTEGER := INTEGER'(SEED2);
begin
  ...

  K := TSEED1 / 53668;
  TSEED1 := 40014 * (TSEED1 - K * 53668) - K * 12211;
  if TSEED1 < 0  then
    TSEED1 := TSEED1 + 2147483563;
  end if;

  K := TSEED2 / 52774;
  TSEED2 := 40692 * (TSEED2 - K * 52774) - K * 3791;
  if TSEED2 < 0  then
    TSEED2 := TSEED2 + 2147483399;
  end if;

  Z := TSEED1 - TSEED2;
  if Z < 1 then
    Z := Z + 2147483562;
  end if;

  SEED1 := POSITIVE'(TSEED1);
  SEED2 := POSITIVE'(TSEED2);
  X :=  REAL(Z) * 4.656613e-10;
end UNIFORM;

通过以下实现描述:
a) 此函数的语义由Pierre L'Ecuyer在1988年6月发表的“ACM通信”第31卷第6期第742-774页的算法描述。该算法基于32位平台上两个乘法线性同余生成器的组合。
b) 在第一次调用UNIFORM之前,种子值(SEED1、SEED2)必须初始化为范围内的值[1, 2147483562]和[1, 2147483398]。每次调用UNIFORM后,种子值都会被修改。
c) 此随机数生成器适用于32位计算机,并且每组种子值的周期为~2.30584 *(10 ** 18)。
d) 有关算法的频谱测试的信息,请参阅L'Ecuyer文章。
L'ecuyer论文是“Efficient and portable combined random number generators”,由用户user1155120在评论中提供。
因此,它是使用Wichmann / Hill / Schrage / Bratley等人的方法(请参见L'ecuyer论文)实现的组合线性同余生成器(CLCG),以避免使用32位整数时出现整数溢出。
根据维基百科和其他我能够快速搜索到的参考资料,似乎已经选择了CLCG的常量。正如用户user1155120在评论中所述,CLCG的随机属性已在“A Comparison of Four Pseudo Random Number Generators Implemented in Ada”中进行了分析。
基于此,似乎VHDL随机生成器非常可靠,因此我预计您发现的抖动/异常值仅是随机性的结果。

1
VHDL的随机数有多好?你认为它们“相当可靠”和“所以我认为”吗?至于高斯抖动,用什么方法将REAL输出量化为4048值整数?在math_real包声明中提到了1988年ACM [L'ECUYER]论文。它已经在Ada中进行了测试。 - user1155120
感谢提供L'ecuyers原始论文和测试论文的参考资料,我已经更新了答案,包括这些内容并跳过了我的假设。 - Morten Zilmer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接