写一个Matlab函数,满足:
使用基于下述几何概率的算法:
单位正方形中,有四分之一个单位圆;
在正方形中随机选择一个点,如果该点在四分之一圆中,表示“命中”,在其他位置表示“失误”。
四分之一的单位圆的面积,近似等于
== “命中”的次数 / 选择的次数 ==
该函数应重复计算命中和失误的次数,重复不得少于1000次 ,并且多个pi的估算值在指定精度内,则返回pi的估算值。
(相对)误差的计算方法:
== |估计值 - 实际值| / 实际值==
计算次数N = 10n,
n>=3 N>=1000.
正方形的面积为1*1
四分之一 单位圆的面积为1/4 * pi
如果要使用几何概率的方法,必须借助随机数生成函数 rand()
rand()的用法:
>>>rand(5)
r =
0.8147 0.0975 0.1576 0.1419 0.6557
0.9058 0.2785 0.9706 0.4218 0.0357
0.1270 0.5469 0.9572 0.9157 0.8491
0.9134 0.9575 0.4854 0.7922 0.9340
0.6324 0.9649 0.8003 0.9595 0.6787
用该方法产生2N个随机数(N个作横坐标,N个作纵坐标)
** rand(N,2) **
在单位长度的正方形内生成N个随机的散点:
N = 1e3;
A = rand(N,2);
x = A(:,1);
y = A(:,2);
plot(x, y,'*');
或者也可以写成:
N = 1e3;
x = rand(1,N);
y = rand (1,N);
plot(x, y,'*');
figure一下
可以把其中满足条件的点pick出来:
要求满足的条件即:x2+y2 <= 1;
按照要求计算即可
function my_pi = mypi( error )
% based on posibility to figure Pi
% input: error: related error = abs(mypi - pi_exact)/pi_exact
% output : my_pi is a value in the error that you ask for
% && shows the points in plot that you can understand the Algorithm obviously.
% by Zhaoziqi
close all
for n = 3:10
N = 10^n;
x = rand(1,N);
y = rand (1,N);
point = 0;
hold on
for i =1:N
if(x(i)^2+y(i)^2<=1)
point = point + 1;
end
end
mypi_tem = point/N *4;
if (abs(mypi_tem-pi)/pi <=error)
my_pi = mypi_tem;
break
end
end
for i =1:N
if(x(i)^2+y(i)^2<=1)
point = point + 1;
plot(x(i), y(i),'x');
else
plot(x(i), y(i),'*');
end
end
end
测试:
>>> mypi(0.1)
>>> mypi(0.01)
顺便可以添加命令
tic 和 toc
测量所用的时间,这里不再赘述
【3月30日更新内容】
考虑到求pi的方式十分多样,我们上面使用的几何方法是一种,收敛很慢、精度不高的方法。
下面贴上我对几种不同方法求pi的简单对比
代码不难只需要修改几个参数,我就不再赘述
只贴上结果的对比:
优化计算方法的关键是减少for循环;
function ap_pi = mypi(ac)
s = 10;
rng(s);
N = 1:3*1000; %保证精度的条件下的最大执行次数
hit = 0; %落在四分之一圆周内的次数
x = rand(2, N(end)); %正方形内随机选择一个点
error = zeros(1, 3); %误差
radius = x(1, :) .^ 2 + x(2, :) .^ 2;
wi = radius < 1;
pi_tmp = 4 * cumsum(wi) ./ N;
pi_tmp_3 = reshape(pi_tmp, 3, length(N)/3);
errs = abs(pi_tmp_3 - pi) < 0.001;
for i = 1:length(N)
if (sum(errs(:, i)) == 3)
disp(i)
disp(pi_tmp_3(:, i))
break
end
end
== copy一下 老师 的代码,还是很快的!==