Last active
September 28, 2015 22:38
-
-
Save mcrisc/1506606 to your computer and use it in GitHub Desktop.
Estimates the value of PI (parallel implementation)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #coding: utf-8 | |
| # Estimates the value of PI | |
| # Based on example described at http://code.google.com/edu/parallel/mapreduce-tutorial.html#Basics | |
| # Author: Marcelo Criscuolo (Jaú), with | |
| # invaluable contributions from Rafael Giusti (Argentino) | |
| import math | |
| from datetime import datetime | |
| from multiprocessing import Pool, cpu_count | |
| RADIUS = 80000000 # the bigger the number, more precise is the estimation | |
| try: | |
| PROCESSES = cpu_count() + 1 | |
| except: | |
| PROCESSES = 3 | |
| SQ_RADIUS = RADIUS ** 2 | |
| def estimate_area(initial_y, final_y): | |
| x = RADIUS | |
| y = initial_y | |
| area_section = 0 | |
| while y < final_y: | |
| sq_y = y ** 2 | |
| while (sq_y + (x ** 2)) > SQ_RADIUS: | |
| x -= 1 | |
| area_section += x | |
| y += 1 | |
| return area_section | |
| def main(): | |
| t0 = datetime.now() | |
| pool = Pool(processes=PROCESSES) | |
| results = [] | |
| begin = 0 | |
| end = 0 | |
| batch_size = RADIUS // (2 * PROCESSES) # 2 batches per process | |
| while end < RADIUS: | |
| begin = end | |
| end += batch_size | |
| if end > RADIUS: | |
| end = RADIUS | |
| results.append(pool.apply_async(estimate_area, (begin, end))) | |
| pool.close() | |
| pool.join() | |
| area_section = sum(r.get() for r in results) # summing up partial areas | |
| area_circle = 4 * area_section | |
| area_square = (2 * RADIUS) ** 2 | |
| pi = 4.0 * area_circle / area_square | |
| t1 = datetime.now() | |
| error = abs(pi - math.pi) | |
| decimal_places = abs(math.trunc(math.log10(error))) | |
| print '{:.52f} \t estimated (correct decimal places: {:d})'.format(pi, decimal_places) | |
| print '{:.52f} \t math.pi'.format(math.pi) | |
| print '{:.52f} \t error'.format(error) | |
| print '{:>54s} \t elapsed time'.format((t1 - t0)) | |
| if __name__ == '__main__': | |
| main() |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
RADIUS = 10 ** 9 3.1415926535897646942885330645367503166198730468750000 estimated (correct decimal places: 13) 3.1415926535897931159979634685441851615905761718750000 math.pi 0.0000000000000284217094304040074348449707031250000000 error 1:21:51.196000 elapsed time