rand 函数是不是在 MATLAB/Octave 中产生 0 或 1 的值?

Posted

技术标签:

【中文标题】rand 函数是不是在 MATLAB/Octave 中产生 0 或 1 的值?【英文标题】:Does the rand function ever produce values of 0 or 1 in MATLAB/Octave?rand 函数是否在 MATLAB/Octave 中产生 0 或 1 的值? 【发布时间】:2015-07-01 01:22:07 【问题描述】:

我正在寻找一个能够在01 之间生成随机值的函数,包括两者。我通过在八度音程中使用 rand() 函数生成了 120,000 个随机值,但没有一次将值 01 作为输出。 rand() 会产生这样的值吗?如果没有,我可以使用其他任何功能来达到预期的效果吗?

【问题讨论】:

【参考方案1】:

如果你在Octave 和MATLAB 中阅读了rand 的文档,它是(0,1) 之间的open 间隔,所以不,它不应该生成数字 0或 1。

不过,您或许可以生成一组随机整数,然后将这些值标准化,使它们位于[0,1] 之间。所以也许使用类似randi(MATLAB docs,Octave docs)的东西,它生成从1到给定最大值的整数值。有了这个,定义这个最大数,然后减 1 并除以这个偏移最大值,得到 [0,1] 之间的值:

max_num = 10000; %// Define maximum number
N = 1000; %// Define size of vector
out = (randi(max_num, N, 1) - 1) / (max_num - 1); %// Output

如果您希望它更像rand 但包括 0 和 1,请将 max_num 变量设置得非常大。

【讨论】:

不错的技巧 +1 :) 顺便说一句,我没有在文档中看到 open interval 部分。我错过了什么吗? @SanthanSalai - 在我的 MATLAB R2013a 文档中。我刚刚在 MathWorks 上查看了 MATLAB 文档,您确实是对的。 @SanthanSalai - 哦。感谢您的 +1 :) @rayryeng 尽管文档页面似乎出于某种原因删除了有关开放区间的详细信息,但它仍保留在帮助中(R2015a 中的help rand)。 @Rayryeng:非常感谢。这真的很有帮助:)【参考方案2】:

在数学上,如果您从闭区间 [0 1] 上的(连续)均匀分布中采样,则值为 0 和 1(实际上是任何值)概率严格为零

以编程方式

    如果您有一个随机生成器在 闭合 区间 [0 1] 上生成 double 类型的值,则获得值 0 或 1 的概率不为零,但它太小了,可以忽略

    如果随机生成器从 区间 (0, 1) 生成值,则获得值 0 或 1 的概率严格为零 .

所以概率要么严格为零,要么很小,可以忽略不计。因此,您不必担心:在任何一种情况下,出于实际目的,概率都为零。即使rand 属于上述类型 (1),因此 可以 产生 01,它产生它们的概率也会很小,以至于您“永远不会”看到这些值。

这听起来很奇怪吗?好吧,任何数字都会发生这种情况。你“永远不会”看到rand 输出正好是 1/4。有很多可能的输出,所有这些输出的可能性都相同,任何给定输出的概率几乎为零

【讨论】:

rand 不是从闭区间 [0,1] 中采样,而是从开区间 (0,1) 中采样。它永远不应该(不仅仅是非常罕见地)产生 1。 最好明确给出命中给定双值 (~1e-16) 的概率,而不是小到可以忽略 @mbschenkel 如果rand 输出all 现有double 值介于0 和@ 之间,概率将为~1e-16(由eps 给出) 987654333@ 概率相同。尽管这对于rand 来说是最理想的行为,但我们不能确定情况是否真的如此,除非它被记录在案 @LuisMendo 质疑rand 是否以相同的概率给出所有输出并没有真正意义,因为它是一个伪 RNG。 Mersenne Twister 通过了严格的随机性测试(例如 Diehard),并且对于所有 k @TasosPapastylianou 不知道 :-) 在我的情况下发生的事情是:我对这个答案表示赞成,这促使我重新阅读它,我不可避免地发现了一些可以改进的部分 【参考方案3】:

randopen 区间 (0,1) 生成数字,其中不包括 0 或 1,因此您永远不应该获得这些值。这在以前的版本中有更清楚的记录,但是它仍然在rand 的帮助文本中说明(输入help rand 而不是doc rand)。

但是,由于它产生双精度值,因此它实际产生的值的数量是有限的。精确的集合因使用的 RNG 算法而异。对于默认算法 Mersenne twister,可能的值都是 2^(-53) 的倍数,在开区间 (0,1) 内。 (有关其他生成器的信息,请参阅 doc RandStream.list,然后是“选择随机数生成器”)。

请注意,2^(-53) 是 eps/2。因此,相当于从闭区间[2^(-53), 1-2^(-53)],或者[eps/2, 1-eps/2]绘制。

您可以通过减去 eps/2 并除以 1-eps 来将此间隔缩放到 [0,1]。 (使用format hex 显示足够的精度以在位级别进行检查)。

所以x = (rand-eps/2)/(1-eps) 应该给你闭区间[0,1] 的值。

但我应该提醒一句:他们已经付出了很多努力来确保rand 的输出在(0,1) 内给出任何给定双精度的适当分布,我不认为你'如果您应用我建议的缩放比例,将在 [0,1] 上获得相同的好属性。我对浮点数学和 RNG 的了解不足以解释为什么,或者你可能会怎么做。

【讨论】:

是否记录了最小值是eps(1) 而不是eps(0)?对于eps(0),您的代码会生成负值。 @Daniel 我不确定您所说的“最低限度”是什么意思——最低限度是什么?我的回答是eps,根据定义是eps(1),而不是eps(0)——我没有建议在任何地方使用eps(0) rand 输出的最小值为eps(0) 时,您的代码将生成负值。 eps(0) 是最小的正双精度数,因此它可能由 rand 返回。不知道。 @Daniel 不,rand(使用 Mersenne Twister 算法时)返回的最小值是 2^(-53) 或 eps/2,正如我在回答中提到的那样。我在回答中提到的文档页面中记录了这一点。 "rand 的帮助文本中还是有说明的(type help rand)": 帮助中没有了(4.2.2),所以谜团依然存在,除非文档中提到的(0,1) 可以理解为 0 和 1 的 exclusive,这似乎很可能。【参考方案4】:

我刚试过这个:

octave:1> max(rand(10000000,1))
ans =  1.00000

octave:2> min(rand(10000000,1))
ans =    3.3788e-08

没有严格地给我0,所以要注意浮点运算。

编辑

尽管我说过,注意浮点运算我确实上当了。正如@eigenchris 指出的那样:

format long g
octave:1> a=max(rand(1000000,1))
a =    0.999999711020176

它产生一个接近的浮点数,不等于,正如@rayryeng 建议的那样,在更改精度后您现在可以看到。

【讨论】:

您可能想检查这是否真的是1.0,或者只是浮点数的四舍五入版本。 很好,不是 1 只是 Octave 的显示,我会修复答案 @brodroll - 尝试更改显示格式。执行format long g; 然后再次尝试运行代码。我已经运行了好几次,但我从来没有得到确切的1.0。这是我的 Octave 实例上的一次运行。顺便说一句 +1 为您的答案。 octave:1> format long g; octave:2> max(rand(100000000,1)) ans = 0.999999988570948 octave:3> format octave:4> ans ans = 1.00000 是的,做出了更改以供进一步参考和完成。感谢您的提醒!【参考方案5】:

虽然不是直接针对此处的问题,但我发现链接到此 SO 帖子 Octave - random generate number 很有帮助,该帖子有一个使用 r = rand > 0.5 生成 1 和 0 的衬线。

【讨论】:

以上是关于rand 函数是不是在 MATLAB/Octave 中产生 0 或 1 的值?的主要内容,如果未能解决你的问题,请参考以下文章

Octave / MATLAB 中的 deal() 函数有啥意义?

斐波纳契函数在matlab / octave中

如何在 Matlab/Octave `mexFunction`(不是 nrhs)中确定数组的大小

MATLAB 或 Octave 的自动缩进清理器? [关闭]

ILNumerics 等效于 MatLab/Octave 语句

MATLAB/Octave 不会缩短长数字