在半径很大 (10^9) 的球体内均匀分布粒子 - Matlab
Disribute particles uniformly inside a sphere with huge radius (10^9) - Matlab
我需要以下方面的帮助:
L2=10^9;
nP=10^6;
x(:,1)=L2.*rand(nP,1);
y(:,1)=L2.*rand(nP,1); % Select initial partice position randomly (only positive values) NS
z(:,1)= L2.*rand(nP,1);
for ip=1:nP
r1(ip,1)= sqrt(x(ip,1)^2 + y(ip,1)^2 + z(ip,1)^2); % distance from (0,0,0) for each iteration
while r1(ip,1)>=L2
x(ip,1)=L2.*rand(1,1);
y(ip,1)=L2.*rand(1,1); % Select initial partice position randomly (only positive values) NS
z(ip,1)=L2.*rand(1,1);
r1(ip,1)= sqrt(x(ip,1)^2 + y(ip,1)^2 + z(ip,1)^2);
end
end
我面临的问题是:
1) 由于半径 L2 非常大,当我将 L2 与 rand 相乘时,我得到的值非常接近盒子的边界(例如 10^8),我希望粒子均匀分布在整个盒子周围球体。
2) 同样在我 运行 while 命令之后,生成的分布不再均匀。
从概念上讲,这可以分三个阶段完成:
- 在单位球面上生成点;
- 缩放每个点以均匀填充球体内部;和
- 将它们重新缩放到所需的半径。
在实践中,这些步骤可以合并。
请注意,我不是 Matlab 用户,也没有它的副本,因此请将以下内容视为伪代码。
生成随机分布在 k 维球体表面的点的最简单和最通用的方法,同时避免 acceptance/rejection 方法,是生成 k 独立的标准法线,并根据其与原点的距离对每个结果点进行归一化。对于三个维度:
x = randn
y = randn
z = randn
scale_factor = 1 / sqrt(x^2 + y^2 + z^2)
x = x * scale_factor
y = y * scale_factor
z = z * scale_factor
要将点缩放到球体内部,您需要应用介于 0 和 1 之间的比例因子。但是,如果均匀缩放该因子,则结果将不会在三维上保持一致。请注意,半径为 1/2 的球体只有单位球体体积的 1/8,因此我们需要相应地调整比例因子,使预期的点数与体积成正比。 k维球体的正确比例因子是采用均匀 (0,1) 随机数的第 k 根(参见Wolfram 用于此原理的二维说明),因此在您的情况下,您希望使用立方根调整比例因子。把上面的scale_factor
改成:
scale_factor = (rand^(1/3)) / sqrt(x^2 + y^2 + z^2)
最后,要重新缩放到 L2
的实际所需半径,您实际想要的是:
scale_factor = L2 * (rand^(1/3)) / sqrt(x^2 + y^2 + z^2)
我需要以下方面的帮助:
L2=10^9;
nP=10^6;
x(:,1)=L2.*rand(nP,1);
y(:,1)=L2.*rand(nP,1); % Select initial partice position randomly (only positive values) NS
z(:,1)= L2.*rand(nP,1);
for ip=1:nP
r1(ip,1)= sqrt(x(ip,1)^2 + y(ip,1)^2 + z(ip,1)^2); % distance from (0,0,0) for each iteration
while r1(ip,1)>=L2
x(ip,1)=L2.*rand(1,1);
y(ip,1)=L2.*rand(1,1); % Select initial partice position randomly (only positive values) NS
z(ip,1)=L2.*rand(1,1);
r1(ip,1)= sqrt(x(ip,1)^2 + y(ip,1)^2 + z(ip,1)^2);
end
end
我面临的问题是:
1) 由于半径 L2 非常大,当我将 L2 与 rand 相乘时,我得到的值非常接近盒子的边界(例如 10^8),我希望粒子均匀分布在整个盒子周围球体。
2) 同样在我 运行 while 命令之后,生成的分布不再均匀。
从概念上讲,这可以分三个阶段完成:
- 在单位球面上生成点;
- 缩放每个点以均匀填充球体内部;和
- 将它们重新缩放到所需的半径。
在实践中,这些步骤可以合并。
请注意,我不是 Matlab 用户,也没有它的副本,因此请将以下内容视为伪代码。
生成随机分布在 k 维球体表面的点的最简单和最通用的方法,同时避免 acceptance/rejection 方法,是生成 k 独立的标准法线,并根据其与原点的距离对每个结果点进行归一化。对于三个维度:
x = randn
y = randn
z = randn
scale_factor = 1 / sqrt(x^2 + y^2 + z^2)
x = x * scale_factor
y = y * scale_factor
z = z * scale_factor
要将点缩放到球体内部,您需要应用介于 0 和 1 之间的比例因子。但是,如果均匀缩放该因子,则结果将不会在三维上保持一致。请注意,半径为 1/2 的球体只有单位球体体积的 1/8,因此我们需要相应地调整比例因子,使预期的点数与体积成正比。 k维球体的正确比例因子是采用均匀 (0,1) 随机数的第 k 根(参见Wolfram 用于此原理的二维说明),因此在您的情况下,您希望使用立方根调整比例因子。把上面的scale_factor
改成:
scale_factor = (rand^(1/3)) / sqrt(x^2 + y^2 + z^2)
最后,要重新缩放到 L2
的实际所需半径,您实际想要的是:
scale_factor = L2 * (rand^(1/3)) / sqrt(x^2 + y^2 + z^2)