0
$\begingroup$

Approximate $\pi$ using monte carlo method of radius 1. I use MATLAB to do this problem, here my code to find the approximation of $\pi$.

n = 10                      %numbers of samples
x = rand ([1 n]);           
y = rand ([1 n]);          
c = 0; s = 0;
for i = 1:n
    s = s+1;
    if x(i)^2 + y(i)^2 <=1   %inside circle
       c = c+1;
    else                    % else outside circle
end 
end

p = c/s
pi_approx = 4*p
err = pi - pi_approx

Here I see the same problem, but i want to use my code for solving my problem. I am stack to find the curve of error with different value of $n$, how to plot the curve ? anyone can complete this code ? (for $n = 10, 100, 1000, ...,10e8)$

Here the curve based on comment below with $n = 10.$^$(1:6)$ :

enter image description here

2 Answers 2

0

The error you obtained using monte carlo method is the statistical error, not the error you are calculating in the post.

For monte carlo method, the statistical error is $\eta = \frac{x\theta}{\sqrt{N}}$ where $x$ is the confidence coefficient, such as when 95% confidence level, $x=1.96$. $\theta $ is the std of your tally variable. $\theta$ here is not known exactly, we have to use a esitmated value and we can have $\theta = \sqrt{\frac{1}{N}\sum_{i=1}^{N}Z_i^2-\left( \frac{1}{N}\sum_{i=1}^{N}Z_i\right)^2}$ where $Z_i$ is the tally results, here is the estimated $\pi$ in your problem in ith mc sampling experiment.

So roughly we can see that with the $N$ increase the error is reducing, but only reduce by a fraction of the square root of $N$. It is kind of slow.

2

First of all you need to calculate the error for every n, so I suggest making a for loop around your current code, and save the error in a vector and then plot that vector against the n.

n = 10.^(1:8);
err = NaN(size(n));
for k=1:numel(n)
    x = rand ([1 n(k)]);
    y = rand ([1 n(k)]);
    c = 0; s = 0;
    for i = 1:n(k)
        s = s+1;
        if x(i)^2 + y(i)^2 <=1   %inside circle
            c = c+1;
        else                    % else outside circle
        end
    end
    p = c/s;
    pi_approx = 4*p;
    err(k) = pi - pi_approx;
end

plot(n,err,n,0*n)

To speed up things a bit I recommend vectorizing the code instead of using too many nested for loops. For checking the rate of convergence it is also worth looking at the data in a logarithmic plot:

n = 10.^(1:7);
err = NaN(size(n));
for k=1:numel(n)
    x = rand ([1 n(k)]);
    y = rand ([1 n(k)]);
    c = sum(x.^2 + y.^2 < 1);
    p = c / n(k);
    pi_approx = 4 * p;
    err(k) = pi - pi_approx;
end

subplot(1,2,1);
plot(n,err,n,0*n);
subplot(1,2,2);
loglog(n,abs(err))
  • 0
    the first code can not running, I got "error using rand" at command window of MATLLAB.2017-01-18
  • 0
    Then your original code probably didn't run either. It works fine on my computer.2017-01-18
  • 0
    do you get the same curve with me ? I post in my question2017-01-18
  • 0
    @Lin It looks roughly the same, but obviously it changes with every call of `rand`.2017-01-18