random - VHDL 的随机数有多好?

标签 random statistics vhdl

我正在使用来自 IEEE.math_real 的 VHDL 随机数,但这些生成的数字有多好?

.... 与 C 中的 rand(...) 进行比较。

是否进行过统计测试?

<小时/>

这是高斯分布的直方图。参数:

  • 随机源:由 math_real.Uniform(...) 生成的 2 个均匀分布 REAL 值
  • Box-Muller 变换
  • 使用 REAL 计算
  • 输出范围:0..4095 INTEGER
  • 102.400 次迭代

经典直方图 View :
NormalDistributedRandomValue 100Ki iterations; range 0..4095

作为点云:
NormalDistributedRandomValue 100Ki iterations; range 0..4095

<小时/>

这是均匀分布的直方图。参数:

  • 随机源:由 math_real.Uniform(...) 生成的均匀分布 REAL 值
  • 使用 REAL 计算
  • 输出范围:0..4095 INTEGER
  • 102.400 次迭代

经典直方图 View :
NormalDistributedRandomValue 100Ki iterations; range 0..4095

作为点云:
NormalDistributedRandomValue 100Ki iterations; range 0..4095

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 选择的常数似乎是众所周知的。正如用户1155120在评论中告知的那样,CLCG的随机属性已在"A Comparison of Four Pseudo Random Number Generators Implemented in Ada"中进行了分析。 .

基于此,VHDL 随机生成器似乎非常可靠,因此我希望您发现的抖动/异常值只是随机性的结果。

关于random - VHDL 的随机数有多好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35390597/

相关文章:

c# - 以这种特定方式随机排列数组?

python - scipy.stats.multivariate_normal 提高 `LinAlgError: singular matrix` 即使我的协方差矩阵是可逆的

hardware - 卷积编码器的终止与状态寄存器重置

arrays - 我可以同时访问数组的 2 个索引吗 VHDL

vector - 什么是 VHDL 中位向量的否定(不是)

带边界的 Android 随机日期生成器

java - 如何生成随机字母数字字符串

python - 生成随机二进制矩阵

python - 在Python中估计后验?

python - 使用 numpy/h5py 进行内存高效的 Benjamini-Hochberg FDR 校正