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"); | |
} | |
} |
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()
LikeLike
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 value1
, Change the if condition in main function to,if withinCircle(x,y) == True :
Fifth, value of
pi
is calculated as an integer because the variablessquareArea
&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 with0.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
LikeLike
Thank you very much Karthik. That helps much. Yeah, I had figured out few errors but not all. It makes more sense now with the explanation. Thank you very much.
LikeLiked by 1 person