Matlab可调节精度基于几何概率计算pi

问题描述

写一个Matlab函数,满足:

输入:所需的精度
输出:该精度下的pi

使用基于下述几何概率的算法:
单位正方形中,有四分之一个单位圆;
在正方形中随机选择一个点,如果该点在四分之一圆中,表示“命中”,在其他位置表示“失误”。
四分之一的单位圆的面积,近似等于
== “命中”的次数 / 选择的次数 ==

补充

该函数应重复计算命中和失误的次数,重复不得少于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一下
1000个散点图分配在 单位正方形中可以把其中满足条件的点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)

error = 0.1error = 0.01
不同精度要求下pi的计算结果
顺便可以添加命令
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一下 老师 的代码,还是很快的!==

猜你喜欢

转载自blog.csdn.net/weixin_42398319/article/details/88863941
今日推荐