VHDL 的随机数有多好?
How good are VHDL's random numbers?
我正在使用来自 IEEE.math_real
的 VHDL 随机数,但这些生成的数字有多好?
.....比方说与来自 C.
的 rand(...)
相比
有统计检验吗?
这是高斯分布的直方图。参数:
- 随机源:
math_real.Uniform(...)
生成的 2 个均匀分布的 REAL 值
- Box-Muller 变换
- 使用实数计算
- 输出范围:0..4095 INTEGER
- 102.400 次迭代
经典直方图视图:
作为点云:
这是一个均匀分布的直方图。参数:
- 随机源:
math_real.Uniform(...)
生成的均匀分布 REAL 值
- 使用实数计算
- 输出范围:0..4095 INTEGER
- 102.400 次迭代
经典直方图视图:
作为点云:
f(x)=m*x+b
的 Gnuplot 拟合结果:
m = -0.0000343906
b = 25.0704
在我看来,两个直方图都有很高的抖动。
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) The semantics for this function are described by the
algorithm published by Pierre L'Ecuyer in "Communications
of the ACM," vol. 31, no. 6, June 1988, pp. 742-774.
The algorithm is based on the combination of two
multiplicative linear congruential generators for 32-bit
platforms.
b) Before the first call to UNIFORM, the seed values
(SEED1, SEED2) have to be initialized to values in the range
[1, 2147483562] and [1, 2147483398] respectively. The
seed values are modified after each call to UNIFORM.
c) This random number generator is portable for 32-bit
computers, and it has a period of ~2.30584*(10**18) for each
set of seed values.
d) For information on spectral tests for the algorithm, refer
to the L'Ecuyer article.
L'ecuyer 论文是 "Efficient and portable combined random number generators",由 user1155120 在评论中给出。
所以它是 Combined Linear Congruential Generator (CLCG) 使用 Wichmann/Hill/Schrage/Bratley 等。 al. 的方法(参见 L'ecuyer 论文)在使用 32 位整数实现时避免整数溢出。
根据 Wiki 和我可以通过快速搜索找到的其他参考资料,为 CLCG 选择的常量似乎是众所周知的。正如 user1155120 在评论中告知的那样,CLCG 的随机属性已在 "A Comparison of Four Pseudo Random Number Generators Implemented in Ada".
中进行了分析
基于此,VHDL 随机生成器似乎非常可靠,所以我希望您发现的 jitter/outliers 只是随机性的结果。
我正在使用来自 IEEE.math_real
的 VHDL 随机数,但这些生成的数字有多好?
.....比方说与来自 C.
的rand(...)
相比
有统计检验吗?
这是高斯分布的直方图。参数:
- 随机源:
math_real.Uniform(...)
生成的 2 个均匀分布的 REAL 值
- Box-Muller 变换
- 使用实数计算
- 输出范围:0..4095 INTEGER
- 102.400 次迭代
经典直方图视图:
作为点云:
这是一个均匀分布的直方图。参数:
- 随机源:
math_real.Uniform(...)
生成的均匀分布 REAL 值
- 使用实数计算
- 输出范围:0..4095 INTEGER
- 102.400 次迭代
经典直方图视图:
作为点云:
f(x)=m*x+b
的 Gnuplot 拟合结果:
m = -0.0000343906
b = 25.0704
在我看来,两个直方图都有很高的抖动。
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) The semantics for this function are described by the algorithm published by Pierre L'Ecuyer in "Communications of the ACM," vol. 31, no. 6, June 1988, pp. 742-774. The algorithm is based on the combination of two multiplicative linear congruential generators for 32-bit platforms.
b) Before the first call to UNIFORM, the seed values (SEED1, SEED2) have to be initialized to values in the range [1, 2147483562] and [1, 2147483398] respectively. The seed values are modified after each call to UNIFORM.
c) This random number generator is portable for 32-bit computers, and it has a period of ~2.30584*(10**18) for each set of seed values.
d) For information on spectral tests for the algorithm, refer to the L'Ecuyer article.
L'ecuyer 论文是 "Efficient and portable combined random number generators",由 user1155120 在评论中给出。
所以它是 Combined Linear Congruential Generator (CLCG) 使用 Wichmann/Hill/Schrage/Bratley 等。 al. 的方法(参见 L'ecuyer 论文)在使用 32 位整数实现时避免整数溢出。
根据 Wiki 和我可以通过快速搜索找到的其他参考资料,为 CLCG 选择的常量似乎是众所周知的。正如 user1155120 在评论中告知的那样,CLCG 的随机属性已在 "A Comparison of Four Pseudo Random Number Generators Implemented in Ada".
中进行了分析基于此,VHDL 随机生成器似乎非常可靠,所以我希望您发现的 jitter/outliers 只是随机性的结果。