Writing a program for generating random numbers involving a circle and a square, help please??

A circle of radius 1 is centered in a square target with sides of length 2. The are of the circle to the are of the square is pi/4, so if you throw darts at random, they will have an equal chance of hitting any part of the target. I know that the probability is pi/4, and that pi is 4 times the ratio of: # of throws inside the cirlce (this is divide>) ---------------------------------- total # of throws
What I am trying to accomplish is generating random coordinate pairs (x,y) using x = -1 + 2*rand(n,1)), and plotting pi as a function of the number n of throws by first: throwing 1 dart for the 1st estimate, and throwing 2 darts to get the second, 3 for the third, etc.
I have some coding but a student told me it was all wrong and to try asking on this website. help please!!!

3 Comments

Posting your code would be a more effective way of helping us help you.
Program is on a school computer, which I won't be able to access for a couple of days. I was trying to create a square matrix with some sort of circulant matrix inside, but got so confused, help please
You can just throw one more virtual dart each time.

Sign in to comment.

Answers (1)

You are generating your x- and y-values between -1 and 1, which means you're automatically sampling randomly within the square. That part is fine.
But like Walter suggests, you can just do one dart at a time. That is, you decide the maximum number of throws N you want to do and generate those N co-ordinates only once.
You need an in/out test for your circle and a way to calculate how your pi ratio evolves as the number of throws increases. You will end up with a N-length vector showing (in theory) progressive convergence on pi.
Functions that will help you achieve this are hypot and cumsum.
By the way, get in the habit of posting your code - especially if you think it's wrong. You are more likely to receive help if there's hard evidence that you are also trying to solve it on your own. =)

11 Comments

Here is some code that might help.
It is just I am having trouble adjusting it so fit my needs of 1) throwing 1 dart for the 1st estimate, and throwing 2 darts to get the second, 3 for the third, etc. and plotting pi as a function of n throws and (2) throwing 1 dart to get the first estimate, a second one and using the two darts thrown together to get the 2nd estimate, and throwing another one using those three to get a 3rd estimate
CODE:
function mycir = approxcir(n)
% Input: n = number of points to generate
% Default is n = 1e6
% Larger values of n should perform better
if nargin < 1
n = 1e6;
end
% Generate uniformly distributed points in
% [0, 1] x [0, 1]
xy = rand(n, 2);
% Compute distance from (0.5, 0.5)
r = sqrt((xy(:,1)-0.5).^2+(xy(:,2)-0.5).^2);
% Count fraction of points within 1/2 unit of (0.5, 0.5)
frac = sum(r <= 0.5) / n;
% Since square has side 1, circle has radius (1/2)
% and should have area of pi*(1/2)^2
% frac is approximately pi/4 so pi is approximately 4*frac
mypi = 4*frac;
Do not throw N *addition* darts to form the N'th estimate: just throw one _more_ dart to go from the (N-1)'st estimate to the N'th estimate.
You also need to fix your code so that you assign a value to the variable named on the left-hand side of the '=' in the 'function' statement.
If the problem says to use a circle of radius 1 inside a square of radius 2, why are you doing half that, when your original code (2*rand(n,2)-1) was correct? It makes it easier to test in/out, and you should use hypot instead of doing the squaring and square-rooting yourself.
Like I said before (and unless you've been specifically asked to write a function to estimate using 'n' random throws), you should generate your N random positions only ONCE, at the start of your program. Then you can use tests involving hypot(), and the cumsum() function, which will give you all your answers from 1:N in one call.
This is pretty much what Walter is saying, too. You must compute your next answer by building on the last. Otherwise every single answer draws from an unrelated data set, which does not quite have quite the same pseudorandom uniformity as using all the values you have collected from one or more calls to rand().
If you generate a new data set each time, then the chances that the estimate will be more accurate with each step is not as high as it would be if you add additional darts to the existing set.
Well, you might want to generate a new set each step, it depends on whether you want to observe the asymptotic behaviour of a random walk, or just to observe the decreasing variance with progressively larger samples ...
i.e. http://dl.dropbox.com/u/10495173/onesample.png vs http://dl.dropbox.com/u/10495173/independentsamples.png
Thank You so much for the feedback, I will post new code later when I gain access to my matlab at home, just to make sure I am generating good code.
eeek its not working at all!
function mycir = approxcir(n)
% Input: n = number of points to generate
% Default is n = 1e6
% Larger values of n should perform better
if nargin < 1
n = 1e6;
end
% Generate uniformly distributed points in
% [0, 1] x [0, 1]
xy = rand(n, 2);
% Compute distance from (1, 1)
r = sqrt((xy(:,1)-1).^2+(xy(:,2)-1).^2);
% Count fraction of points within 1/2 unit of (1, 1)
frac = sum(r <= 1) / n;
% Since square has side 1, circle has radius (1/2)
% and should have area of pi*(1)^2
% frac is approximately pi/4 so pi is approximately 4*frac
mypi = 4*frac;
You write,
% Count fraction of points within 1/2 unit of (1, 1)
frac = sum(r <= 1) / n;
but that code is for counting the fraction within 1 unit of (1,1)
What do you mean by "not working at all"? What happens when you run the code? Be more helpful in your description. Why are you computing distance to (1,1)? You have obviously decided to perform the experiment on only one quadrant of the circle/square, so why not centre it at (0,0) to make your code clearer? It makes no difference. Please look up the 'hypot' function in MatLab help. I've suggested it to you at least twice. I notice that your function's return value is 'mycir', but at the bottom where you do the calculation you put it into 'mypi'. The calculation itself looks fine. Works for me. I got pi = 3.14 with just 1000 random numbers.

Sign in to comment.

Asked:

on 17 Apr 2012

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!