Calculating π by Monte Carlo Integration


The Monte Carlo method is used to solve many complex problems for which an exact solution is not known. The name "Monte Carlo" refers to gambling, and in Monte Carlo methods many random outcomes, or guesses, are made and evaluated. π =3.14159..., the ratio of a circles diameter to its circumference, is numerically not exactly known. While there are far better ways to estimate π, I wrote this program to start learning C/C++ programming and play with Monte Carlo methods. It uses the relationship between π and the area of a circle, A=πr2. An elegant way to visualize this relationship is to imagine slicing a circle into smaller and smaller pieces, then rearranging these pieces into a rectangle. The area of the rectangle is equal to the area of the circle and is equal to its width multiplied by its length, or A=πr2.

If we set the radius to 1 then the area becomes equal to π. The trick with Monte Carlo integration is to find a function that includes your unknown function of interest, then guess values and evaluate if they are included in your function of interest. The fraction that are contained are proportional to the fraction of the area of the unknown function in your known functions area. I considered a quarter of a circle with a radius=1 that is included in a square with a side=1. Then random x, y coordinates are guessed and the distance from the center of the circle is determined by Pythagoreans' theorem, d=sqrt(x2+y2). If this distance is less than 1 they are in the quarter circle. The fraction in the circle vs. the square, or total, is multiplied by 4 to get the area of the whole circle and therefore π.

The following graph illustrates the diminishing returns in accuracy achived by increasing sample size. 12 independent points are plotted for each number of repititions. As sample size inceases the scatter diminishes and the π estimates rapidly approach a single value. But it becomes increasingly more difficult to "iron out" the remaining errors.


Beckman, Petr. A History of π (PI). 1973. St. Martin's Press. New York. is an entertaining read on math history pertaining to π as well as a dose of the authors political views. amazon.com Barnes&Noble

Download a ziped microsoft DOS/windows executable circle_pi.zip 26.8 KB
I also found that this executable, compiled for microsoft, also runs with wine on linux. Just download, unzip it, and type "wine circle_pi.exe" at the command line.

C++ Source Code:
//
// by Floyd Reed July 10, 2002
// after writing this I found a website 
// http://www.daimi.aau.dk/~u951581/pi/MonteCarlo/pimc.html
// that uses almost identical reasoning.  The only real difference
// is I used a quarter of a circle to make it easier to program.
//

#include <stdio.h>
#include <iostream.h>
#include <stdlib.h>	// required for rand function
#include <time.h>	// required for srand seed with time
#include <math.h>	// required for square root calculation

int main(int nNumberofArgs, char* pszArgs[])
{
	srand (time(NULL));		// uses time to seed random generator
	int nCArea = 0;
	int nGuess = 0;
	double dPi;
	cout << "CirclePi, version 2\n";
	cout << "This program attempts to calculate pi by a\n";
	cout << "  very inefficient 'guessing'  or 'Monte Carlo'\n";
	cout << "  method using the relationship between pi and\n";
	cout << "  the area of a circle.\n";
	cout << "Enter number of guesses to make, the more the\n";
	cout << "  better the estimate: ";
	cin >> nGuess;
	for (int nI=1; nI<=nGuess; nI++)
	{
		// generate x coordinate
		float fRandomx = rand();		// creates a random number, rand only returns integers so must convert to float to get 0 - 1 range
		float fTotalx = RAND_MAX;		// maximum value of random number
		float fX = fRandomx/fTotalx;	// crates a random zero to 1 fraction
		// generate y coordinate
		float fRandomy = rand();		// creates a random number, rand only returns integers so must convert to float to get 0 - 1 range
		float fTotaly = RAND_MAX;		// maximum value of random number
		float fY = fRandomy/fTotaly;	// crates a random zero to 1 fraction
		// calculate distance
		double dDistance = sqrt((fX*fX)+(fY*fY));	// distance from (0,0) equation
		//cout << "x=";   // you can "turn these on" to see all the calculations
		//cout << fX;
		//cout << "\ty=";
		//cout << fY;
		//cout << " \td=";
		//cout << fDistance;
		if (dDistance <= 1) {nCArea++;}		// counts distances within the quarter circle
		double dCArea = nCArea;
		double dI = nI;
		dPi = 4*dCArea/dI;
		//cout << " \tpi=";
		//cout << fPi;
		//cout << "\n";
	}
	cout << " = pi = \n";			// for some reason this prints after the printf command
	printf("\n%.6f", dPi);
	cout << "\n(I tried it for 1 billion - it took 4 minutes\n  and estimated pi as 3.141526)\nType 1 and return to close.";
	cin >> nGuess;
	return 0;
}



C Programming | Floyd's Home | MountainSmoke.com

Copyright: © Floyd A. Reed 1996-2003, all rights reserved.
URL: http://www.mountainsmoke.com/floyd/pi.htm
Contact: floyd@mountainsmoke.com
Revised: Tuesday February 11, 2003