您可以比实际生成所有这些矩阵更直接地做到这一点,而且通过考虑最终输出的分布,这很容易做到。
由 N(0, .2) 分布的随机变量位于 .2 和 .3 之间的概率是 p ~= .092。
调用矩阵 X 的最终输出的随机变量,在其中执行 n (20) 次。然后要么(a)X 位于 0.2 和 0.3 之间并且你提前停止,要么(b)你在前 n-1 次抽签中没有抽到 0.2 和 0.3 之间的数字,所以你选择了你得到的任何东西第n次抽奖。
(b) 发生的概率就是 b=(1-p)^(n-1):在 [.2, .3] 之外绘制的独立事件,概率为 1-p,发生 n-1 次。因此 (a) 的概率是 1-b。
如果 (b) 发生了,您只需从中抽取一个数字normrnd
。如果 (a) 发生了,您需要一个正常变量的值,条件是它在 .2 和 .3 之间。一种方法是找到 .2 和 .3 的 cdf 值,从它们之间的范围均匀绘制,然后使用逆 cdf 取回原始数字。
执行此操作的代码:
mu = 0;
sigma = .2;
upper = .3;
lower = .2;
n = 20;
sz = 15;
cdf_upper = normcdf(upper, mu, sigma);
cdf_lower = normcdf(lower, mu, sigma);
p = cdf_upper - cdf_lower;
b = (1-p) ^ (n - 1);
results = zeros(sz, sz);
mask = rand(sz, sz) > b; % mask value 1 means case (a), 0 means case (b)
num_a = sum(mask(:));
cdf_vals = rand(num_a, 1) * p + cdf_lower;
results(mask) = norminv(cdf_vals, mu, sigma);
results(~mask) = normrnd(mu, sigma, sz^2 - num_a, 1);
如果您出于某种原因想直接模拟这个(这将涉及很多浪费的努力,但显然您不喜欢“统计的复杂性”——顺便说一下,这是概率,而不是统计),你可以生成第一个矩阵,然后仅替换不属于您所需范围的元素。例如:
mu = 0;
sigma = .2;
n = 10;
m = 10;
num_runs = 20;
lower = .2;
upper = .3;
result = normrnd(mu, sigma, n, m);
for i = 1 : (num_runs - 1)
to_replace = (result < lower) | (result > upper);
result(to_replace) = normrnd(mu, sigma, sum(to_replace(:)), 1);
end
为了证明这些是相同的,这里是对 1x1 矩阵执行 100,000 次的经验 CDF 图。(也就是说,我运行了这两个函数 100k 次并保存了结果,然后用于cdfplot
绘制 x 轴上的值与小于 y 轴上获得的值的部分。)
它们是相同的。(实际上,分布同一性的KS 检验给出的 p 值为 0.71。)但直接的方法是运行速度更快。