【问题标题】:Achieve same random numbers in numpy as matlab在 numpy 中实现与 matlab 相同的随机数
【发布时间】:2016-11-22 12:41:47
【问题描述】:

我想知道如何在 numpy 中生成与在 MATLAB 中相同的随机(正态分布)数。

作为我在 MATLAB 中执行此操作的示例

RandStream.setGlobalStream(RandStream('mt19937ar','seed',1));
rand
ans =
    0.417022004702574

现在我可以用 numpy 重现这个:

import numpy as np
np.random.seed(1)
np.random.rand()
0.417022004702574

这很好,但是当我使用正态分布执行此操作时,我会得到不同的数字。

RandStream.setGlobalStream(RandStream('mt19937ar','seed',1));
randn
ans =
    -0.649013765191241

还有 numpy

import numpy as np
np.random.seed(1)
np.random.randn()
1.6243453636632417

这两个函数在他们的文档中都说它们来自标准正态分布,但给我的结果却不同。知道如何调整我的 python/numpy 以获得与 MATLAB 相同的数字。

因为有人将此标记为重复: 正如我在开头和结尾所写的那样,这是关于正态分布的。 正如我写的均匀分布工作正常,这是关于正态分布。 链接线程中的答案都没有帮助正态分布。

【问题讨论】:

标签: matlab numpy


【解决方案1】:

我的猜测是 matlab 和 numpy 可能会使用不同的方法来获得随机数的正态分布(以某种方式从统一数中获得)。

您可以通过编写 box-muller 方法自己生成随机数来避免这个问题。对于python,

import numpy as np

# Box-muller normal distribution, note needs pairs of random numbers as input
def randn_from_rand(rand):

    assert rand.size == 2

    #Use box-muller to get normally distributed random numbers
    randn = np.zeros(2)
    randn[0] = np.sqrt(-2.*np.log(rand[0]))*np.cos(2*np.pi*rand[1])
    randn[1] = np.sqrt(-2.*np.log(rand[0]))*np.sin(2*np.pi*rand[1])

    return randn


np.random.seed(1)
r = np.random.rand(2)
print(r, randn_from_rand(r))

给出,

(array([ 0.417022  ,  0.72032449]), array([-0.24517852, -1.29966152]))

对于matlab,

% Box-muller normal distribution, note needs pairs of random numbers as input
function randn = randn_from_rand(rand)

    %Use box-muller to get normally distributed random numbers
    randn(1) = sqrt(-2*log(rand(1)))*cos(2*pi*rand(2));
    randn(2) = sqrt(-2*log(rand(1)))*sin(2*pi*rand(2));

我们称之为

RandStream.setGlobalStream(RandStream('mt19937ar','seed',1));
r = [rand, rand]
rn = randn_from_rand(r)

有答案,

r =
    0.4170    0.7203
rn =
   -0.2452   -1.2997

注意,你可以检查输出是正态分布的,对于python,

import matplotlib.pyplot as plt

ra = []
np.random.seed(1)
for i in range(1000000):
    rand = np.random.rand(2)
    ra.append(randn_from_rand(rand))


plt.hist(np.array(ra).ravel(),100)
plt.show()

给出,

【讨论】:

  • 感谢您的回答。但我无法更改 MATLAB 代码。看起来 MATLAB 正在使用 ziggurat,我将尝试在 python 中重新实现。
  • 我认为除非您的实现完全相同,否则您可能无法获得可重现的随机数,根据此链接github.com/numpy/numpy/issues/5810,MATLAB 的代码是专有的,这表明它可能并不简单。你能不能简单地在 MATLAB 中重新定义 randn 并使用相同的代码?
猜你喜欢
  • 2014-09-24
  • 2022-01-06
  • 1970-01-01
  • 1970-01-01
  • 2020-11-03
  • 2018-09-23
  • 2011-06-13
  • 2014-04-08
相关资源
最近更新 更多