我正在使用来自IEEE.math_real
的VHDL随机数,但这些生成的数字有多好?
....让我们说与C中的rand(...)
进行比较。
有统计测试吗?
这是高斯分布的直方图。参数:
math_real.Uniform(...)
这是均匀分布的直方图。参数:
math_real.Uniform(...)
Gnuplot拟合f(x)=m*x+b
的结果:
m = -0.0000343906
b = 25.0704
在我看来,两个直方图都有很高的抖动。
答案 0 :(得分: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&#39; Ecuyer在&#34; Communications发表 ACM,&#34;第一卷。 31,不。 1988年6月6日,第742-774页。 该算法基于两者的组合 用于32位的乘法线性同余生成器 平台。
b)在第一次调用UNIFORM之前,种子值 (SEED1,SEED2)必须初始化为该范围内的值 分别为[1,2147483562]和[1,21447483398]。该 每次调用UNIFORM后都会修改种子值。
c)这个随机数发生器可以移植32位 计算机,每个计算机的周期为~2.30584 *(10 ** 18) 一组种子价值。
d)有关算法的光谱测试的信息,请参阅 L&#39; Ecuyer的文章。
L&#39; ecuyer论文是"Efficient and portable combined random number generators",由用户1155120在评论中给出。
所以使用Wichmann / Hill / Schrage / Bratley等人Combined Linear Congruential Generator (CLCG)。 al。的方法(参见L&#39; ecuyer paper),以避免在使用32位整数实现时出现整数溢出。
看来,为CLCG选择的常数是众所周知的,基于我可以通过快速搜索找到的Wiki和其他参考文献。当user1155120在评论中通知时,已在"A Comparison of Four Pseudo Random Number Generators Implemented in Ada"中分析了CLCG的随机属性。
基于此,似乎VHDL随机发生器非常可靠,所以我认为你发现的抖动/异常值只是随机性的结果。