Monte Carlo 圆周率的近似值

Monte Carlo approximation of pi with a sphere

我正在尝试通过对半径为 1 的圆内的点 (x,y) 进行均匀随机抽样来估计 pi,然后计算球体中相应的 z 值。实际上只是一个四分之一圆来简化计算。然后我计算平均 z(它应该大约是整个球体体积的 1/8),然后我将它与 1x1x1 立方体的体积进行比较。它应该大约是 1/6 pi,但由于某些原因它不是。

这是我的matlab代码:

r = rand(1000,1);
theta = rand(1000, 1) * pi/2;
x = zeros(1000);
y = zeros(1000);
z = zeros(1000);
for i = 1:1000
    x(i) = r(i)^(0.5) * sin(theta(i));
    y(i) = r(i)^(0.5) * cos(theta(i));
    z(i) = (1.0 - x(i) * x(i) - y(i) * y(i))^0.5;
end

mean(z)(1) * 6

它一直说pi大约是4,这是胡说八道-即使我增加了样本数。你能解释一下吗,不管事实如何,我在对圆内的随机点进行采样时使用 pi 来确定角度,问题出在哪里?

除了您需要 pi 来调用基于弧度的三角函数之外,您的坐标也不正确。

为了参数化球体,您需要两个角度:thetaphi。您还可以使用逐元素数组操作来节省循环:

N = 1000;
theta = 90*rand(N,1);
phi = 90*rand(N,1);
r = rand(N,1);

%hide the hiding of pi
%%hide pi:
%theta = deg2rad(theta);
%phi = deg2rad(phi);

%x = r.*sind(theta).*cosd(phi); %needless
%y = r.*sind(theta).*sind(phi); %needless
z = r.*cosd(theta);

pi_approx_maybe=mean(z(:))*6;

如果 z 是一个数组(如果 thetaphi 来自 meshgrid 而不是 rand),那么你' d 需要 z(:) 来获得数组范围的平均值,否则结果将是一个向量。同样清楚的是,对于 z 组件,您甚至不需要方位角 (phi),只需要极角 (theta)。

这根本不是如何计算 pi 而不首先使用它。

其实这不是MC的工作方式:它有时需要失败,success/fail的比率会产生一个值。否则,如果你只有成功,那么你必须以某种方式'baked'计算中的搜索值...

这是通过采样单位立方体的体积:

来实现的方法(请耐心等待,我的 Matlab 已经生锈了)
shoots = 100000;
hits = 0;
for i = 1:shoots
    % Sample the whole unit cube
    x = rand();
    y = rand(); 
    z = rand();
    % Are we inside the sphere?
    r = x^2 + y^2 + z^2;
    if (r < 1)
        hits = hits + 1; % We're inside! it's a hit
    end;
end
ratio = hits/shoots; % This ratio is statistically ~ Volume(quarter sphere) / Volume(cube)
myPi = ratio * 3;

现在如果你真的想使用球体的表面,那么你需要在不知道它是球体的情况下对其进行采样

例如:

  • 采样单位立方体的三个外(不经过原点的三个)
  • normalize() 将点云带到所需的球体表面
  • 然后,对该网格进行三角剖分(哎哟)
  • 计算三角剖分的总面积(再次哎哟) ...并且您有四分之一球体表面的近似值 (pi*r²),因此可以直接得到 pi!