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

Does the rand function ever produce values of 0 or 1 in MATLAB/Octave?

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

我刚试过这个:

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 建议的那样,在更改精度后您现在可以看到。

如果你在Octave and 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 变量非常大。

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

以编程方式,

  1. 如果你有一个随机生成器在封闭区间[0 1]上产生double类型的值,得到值 0 或 1 不为零,但小到可以忽略不计

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

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

这听起来很奇怪吗?好吧,任何数字都会发生这种情况。你 "never" 也看到 rand 输出正好是 1/4。有如此多的可能输出,所有输出的可能性都相同,以至于 任何给定输出的概率几乎为零

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

但是,由于它产生双精度数,因此它实际产生的值数量有限。精确集因使用的 RNG 算法而异。对于默认算法 Mersenne twister,可能的值都是 2^(-53) 的倍数,在开区间 (0,1) 内。 (查看 doc RandStream.list,然后查看 "Choosing a Random Number Generator" 了解其他生成器的信息)。

注意 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 的了解不足以解释原因或您可能会采取的措施。

虽然不是直接针对这里的问题,但我发现 link 对这个 SO post Octave - random generate number 有帮助,它有一个衬垫使用 [=10 生成 1 和 0 =].