MultiThreading – Monte Carlo method for Pi

After years of writing program in sequential, I have now started learning parallel programming techniques. Parallelism is nothing but multi-threading, almost every programming language supports this feature, C++, Java, Python, etc..

This blog is an attempt to implement Monte Carlo algorithm using parallel programming. In this algorithm, we consider a random point inside the square of 1 square units and try to determine if this point falls inside the circle of radius 1 unit. This action is autonomous, hence we execute this action in parallel.

Monte Carlo method is based on probability, the accuracy of the value is directly proportional to the number of times the autonomous action is performed. This leads to the next question, how many autonomous actions can be executed in parallel? The answer depends on the hardware, i.e., number of processor cores the machine has.

// Estimate the value of Pi using Monte-Carlo Method, using sequential program
package assignments;
public class Assignment101 {
public static void main(String[] args) {
int nThrows = 100000;
long startTime = System.currentTimeMillis();
double x = 0, y = 0;
int nSuccess = 0;
for (int i = 1; i <= nThrows; i++) {
x = Math.random();
y = Math.random();
if (x * x + y * y <= 1)
nSuccess++;
}
double value = 4.0 * nSuccess / nThrows;
long stopTime = System.currentTimeMillis();
System.out.println("Approx value:" + value);
System.out.println("Difference to exact value of pi: " + (value - Math.PI));
System.out.println("Error: " + (value - Math.PI) / Math.PI * 100 + " %");
System.out.println("Time Duration: " + (stopTime - startTime) + "ms");
}
}
// Estimate the value of Pi using Monte-Carlo Method, using parallel program
package assignments;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
class PiMonteCarlo {
AtomicInteger nAtomSuccess;
int nThrows;
double value;
class MonteCarlo implements Runnable {
@Override
public void run() {
double x = Math.random();
double y = Math.random();
if (x * x + y * y <= 1)
nAtomSuccess.incrementAndGet();
}
}
public PiMonteCarlo(int i) {
this.nAtomSuccess = new AtomicInteger(0);
this.nThrows = i;
this.value = 0;
}
public double getPi() {
int nProcessors = Runtime.getRuntime().availableProcessors();
ExecutorService executor = Executors.newWorkStealingPool(nProcessors);
for (int i = 1; i <= nThrows; i++) {
Runnable worker = new MonteCarlo();
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {
}
value = 4.0 * nAtomSuccess.get() / nThrows;
return value;
}
}
public class Assignment102 {
public static void main(String[] args) {
PiMonteCarlo PiVal = new PiMonteCarlo(100000);
long startTime = System.currentTimeMillis();
double value = PiVal.getPi();
long stopTime = System.currentTimeMillis();
System.out.println("Approx value:" + value);
System.out.println("Difference to exact value of pi: " + (value - Math.PI));
System.out.println("Error: " + (value - Math.PI) / Math.PI * 100 + " %");
System.out.println("Available processors: " + Runtime.getRuntime().availableProcessors());
System.out.println("Time Duration: " + (stopTime - startTime) + "ms");
}
}

Sources of knowledge:

Published by

Karthik

Software Developer and Linux enthusiast.

3 thoughts on “MultiThreading – Monte Carlo method for Pi”

  1. Hello Karthik, your blog is informative. Thank you. I am a newbie in Python and Monte Carlo and trying to write a code for Monte Carlo prediction of Pi using a text file containing x,y,z, and r (radius). I wrote the code but getting errors in it. Will you be able to help me figuring out where I am going wrong? Appreciate your help.
    f = open(‘test.txt’,’r+’)
    x = []
    y = []
    z = []
    radius = []
    for line in f:
    x.append(line[0])
    y.append(line[2])
    z.append(line[4])
    radius.append(line[6])

    def withinCircle(x,y):
    if(x**2+y**2<1):
    return True
    else:
    return False

    def main():
    circleArea = 0
    squareArea = 0
    math = 3.14159
    pi = 0
    for i in range(0,100000):
    x = random.random()
    y = random.random()
    if(withinCircle(x,y)==1):
    circleArea=circleArea+1
    squareArea=squareArea+1
    pi = 4.0*circleArea/squareArea
    print "Approximate value for pi: ", pi
    print "Difference to exact value of pi: ", pi-math
    print "Error: (approx-exact)/exact=", (pi-math)/math*100, "%"
    if __name__ == "__main__":
    main()

    Like

    1. I guess by now u have figured out the errors, but still i like to help you with your code.
      the first mistake is while reading a file, the line “for line in f:” actually fetches individual line one after the other. and the variable “line” is not an array but a string.
      for line in f:
      x.append(line)
      y.append(line)
      z.append(line)
      radius.append(line)

      But you want to read a block of 4 lines and store them, hence this is not an ideal.

      Second, U need to switch between x, y z, and radius in every loop.
      count=0
      for line in f:
      count += 1
      count = count % 4
      if count == 0: x.append(line)
      if count == 1: y.append(line)
      if count == 2: z.append(line)
      if count == 3: radius.append(line)

      this will read every four lines into four different array.

      Third, try to use parenthesis as much as possible to avoid confusion. the if condition in function withinCircle(x,y)
      if (x**2+y**2) < 1 :

      Fourth, boolean value True ; is not same as integer value 1, Change the if condition in main function to,
      if withinCircle(x,y) == True :

      Fifth, value of pi is calculated as an integer because the variables squareArea & circleArea are defied as integer; when u initialize a variable without decimal, it is defined as integer, in order to be defined as a float/double u need to initialize the variable with 0.0
      circleArea = 0.00

      finally looking at the program, i find that reading a file and storing the values to x,y, z and radius array is not required as you never used those values.

      here is the link to your corrected code, http://pastebin.com/q1wVAD5C

      Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.