2014-01-20 80 views
2

我想在MATLAB中创建一个计算R^n中的n球体积的函数。为此,我使用Monte-Carlo方法在n立方体中随机生成点,然后使用n球内的点与所有生成点相乘的比率乘以n立方体的体积。这里是我迄今为止产生的代码:使用Monte-Carlo方法计算n球的体积

function [ approximate_volume ] = MonteCarloHypersphereVolume(radius, dimension, number_of_generations) 
%MonteCarloHypersphereVolume Computes the volume of a 
%'dimension'-dimensional hypersphere by the Monte Carlo method 

number_within_sphere = 0; 
parfor i = 1 : number_of_generations 
    randoms = zeros(1, dimension); 
    for j = 1 : dimension 
     randoms(j) = randi(radius * 2) - radius; 
    end 

    if sum(randoms .^ 2) <= radius^2 
     number_within_sphere = number_within_sphere + 1; 
    end 
end 

approximate_volume = (number_within_sphere/number_of_generations) * (2*radius)^dimension; 

end 

但是,这看起来是非常不准确的;根据维基百科,单位10球的数量应该是:V_10 = pi^5/5! = 2.5502,但是当运行1000000次迭代的函数时,它返回11.0067,确实多次运行它总是返回一个大约为11的值,这比它应该高得多?

此外,有没有办法使用GPGPU编程来提高此功能的性能?除了number_within_sphere的数据依赖性外,它似乎很容易并行化?

+2

我可以使用R来验证一般的方法应该工作。你使用了什么“半径”?你知道['randi'](http://www.mathworks.de/de/help/matlab/ref/randi.html)返回*整数*吗?你可能更喜欢['rand'](http://www.mathworks.de/de/help/matlab/ref/rand.html),你可以对它进行矢量化处理以放弃你的'for'循环。 – MvG

+0

你的循环也不需要依赖'radius'。 'number_within_sphere'可以计算一个单位的n球。不要问两个单独的问题是个好主意。 – horchler

回答

2

您必须使用rand而不是randi以连续均匀分布对每个维度进行采样。即,更换线

randoms(j) = randi(radius * 2) - radius; 

通过

randoms(j) = rand*radius*2 - radius; 
2

这种方法不结垢,由于n-单元时二维球的体积与所述n维立方体的体积[-1的比率, 1]^n趋于零指数快速(并且因此单位立方体内的几乎每个随机点将在单位球外部;例如,对于n = 30,立方体的体积大约是5 * 10^13倍大比球的体积)。

相反应该然而在这里使用的多项式复杂蒙特卡洛算法寻找如所述的,例如一个凸体的体积,在

http://www.cs.berkeley.edu/~sinclair/cs294/n16.pdf

在它被写下来的形式,一个已经假定n维球的体积为 的公式(我们需要知道文本中B_0的体积)。 然而,人们可能会采取一系列具有类似属性的增加立方体(第一个立方体是单位球中的一个立方体,最后一个是[-1,1]),而不是像文中那样增加同心球的顺序,^n,并且连续立方体的边之间的比率是(至多)1 + 1/n),凸体K是单位球,并且然后可以使用相同的算法来找到单位球的体积。