From 4ab17c338dc2157028144cc16c47c5e7891df9f5 Mon Sep 17 00:00:00 2001 From: David Scobie Date: Wed, 16 Dec 2020 19:41:51 +0000 Subject: [PATCH 1/3] modifying calc_pi and line profiler --- week10/calc_pi.py | 6 ++-- week10/calc_pi_np.py | 77 ++++++++++++++++++++++++++++++++++++++++ week10/performance.ipynb | 13 +++++++ 3 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 week10/calc_pi_np.py create mode 100644 week10/performance.ipynb diff --git a/week10/calc_pi.py b/week10/calc_pi.py index 64b7085..8140931 100644 --- a/week10/calc_pi.py +++ b/week10/calc_pi.py @@ -29,7 +29,9 @@ def calculate_pi(): """ within_circle = [point_in_circle(random.random(), random.random()) for _ in range(points)] + print(within_circle) return 4 * sum(within_circle)/points + return calculate_pi @@ -40,10 +42,10 @@ def command(): parser = argparse.ArgumentParser(description="Calculates an approximate value of PI and how long it takes", formatter_class=argparse.ArgumentDefaultsHelpFormatter) - parser.add_argument('--npoints', '-np', default=10_000, type=int, help="Number of random points to use") + parser.add_argument('--npoints', '-np', default=10, type=int, help="Number of random points to use") parser.add_argument('--number', '-n', default=100, type=int, help="Number of times to execute the calculations") parser.add_argument('--repeat', '-r', default=5, type=int, help="How many times to repeat the timer") - + # parser.print_help() arguments = parser.parse_args() calc_pi = calculate_pi_timeit(arguments.npoints) diff --git a/week10/calc_pi_np.py b/week10/calc_pi_np.py new file mode 100644 index 0000000..090340b --- /dev/null +++ b/week10/calc_pi_np.py @@ -0,0 +1,77 @@ +import argparse +import math +import random +import timeit +import numpy as np + +from utils import format_time + +def point_in_circle(array, radius=1): + """ + Checks whether a point (x, y) is part of a circle with a set radius. + + example + ------- + >>> point_in_circle(0, 0) + True + + """ + r = math.sqrt(array[0] ** 2 + array[1] ** 2) + return r <= radius + +def calculate_pi_timeit(points): + """ + Wrapper function to build calculate_pi with a particular number of points + and returns the function to be timed. + """ + def calculate_pi(): + """ + Calculates an approximated value of pi by the Monte Carlo method. + """ + array=np.zeros(2) + within_circle = [point_in_circle([random.random(), random.random()]) + for _ in range(points)] + print(within_circle) + return 4 * sum(within_circle)/points + + return calculate_pi + + # array=np.zeros(2) + # for _ in range(points): + # array[0]=random.random() + # array[1]=random.random() + # within_circle = point_in_circle(array) + # print(within_circle) + # if within_circle == True: + # within_circle=1 + # else: + # within_circle=0 + # # print(within_circle) + # return 4 * sum(within_circle)/points + # return calculate_pi + + +def command(): + """ + entry point of the script to accept arguments + """ + + parser = argparse.ArgumentParser(description="Calculates an approximate value of PI and how long it takes", + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument('--npoints', '-np', default=10, type=int, help="Number of random points to use") + parser.add_argument('--number', '-n', default=100, type=int, help="Number of times to execute the calculations") + parser.add_argument('--repeat', '-r', default=5, type=int, help="How many times to repeat the timer") + # parser.print_help() + arguments = parser.parse_args() + + + + calc_pi = calculate_pi_timeit(arguments.npoints) + print(f"pi = {calc_pi()} (with {arguments.npoints})") + result = timeit.repeat(calc_pi, number=arguments.number, repeat=arguments.repeat) + best = min(result) / arguments.number + print(f"{arguments.number} loops, best of {arguments.repeat}: {format_time(best)} per loop") + + +if __name__ == '__main__': + command() diff --git a/week10/performance.ipynb b/week10/performance.ipynb new file mode 100644 index 0000000..a760311 --- /dev/null +++ b/week10/performance.ipynb @@ -0,0 +1,13 @@ +def sum_of_lists(N): + total = 0 + for i in range(5): + L = [j ^ (j >> i) for j in range(N)] + # j >> i == j // 2 ** i (shift j bits i places to the right) + # j ^ i -> bitwise exclusive or; j's bit doesn't change if i's = 0, changes to complement if i's = 1 + total += sum(L) + return total + +print(sum_of_lists(5)) +%prun sum_of_lists(10_000_000) +%load_ext line_profiler +%lprun -f sum_of_lists sum_of_lists(10_000_000) \ No newline at end of file From 1c4f68136d264956a1ce7c15608de8fa63a6c442 Mon Sep 17 00:00:00 2001 From: David Scobie Date: Thu, 17 Dec 2020 10:08:41 +0000 Subject: [PATCH 2/3] more attempts on using numpy --- week10/calc_pi.py | 2 +- week10/calc_pi_np.py | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/week10/calc_pi.py b/week10/calc_pi.py index 8140931..1860e01 100644 --- a/week10/calc_pi.py +++ b/week10/calc_pi.py @@ -29,7 +29,7 @@ def calculate_pi(): """ within_circle = [point_in_circle(random.random(), random.random()) for _ in range(points)] - print(within_circle) + # print(within_circle) return 4 * sum(within_circle)/points return calculate_pi diff --git a/week10/calc_pi_np.py b/week10/calc_pi_np.py index 090340b..8c8cc7d 100644 --- a/week10/calc_pi_np.py +++ b/week10/calc_pi_np.py @@ -16,7 +16,13 @@ def point_in_circle(array, radius=1): True """ - r = math.sqrt(array[0] ** 2 + array[1] ** 2) + squared = np.square(array) + + added= squared[:, 0] + squared[:, 1] + + r=np.sqrt(added) + # r = np.sqrt(np.square(array).sum(axis=1)) + return r <= radius def calculate_pi_timeit(points): @@ -28,10 +34,10 @@ def calculate_pi(): """ Calculates an approximated value of pi by the Monte Carlo method. """ - array=np.zeros(2) - within_circle = [point_in_circle([random.random(), random.random()]) - for _ in range(points)] - print(within_circle) + array = np.random.rand(points,2) + within_circle = point_in_circle(array) + + # print(within_circle) return 4 * sum(within_circle)/points return calculate_pi @@ -58,7 +64,7 @@ def command(): parser = argparse.ArgumentParser(description="Calculates an approximate value of PI and how long it takes", formatter_class=argparse.ArgumentDefaultsHelpFormatter) - parser.add_argument('--npoints', '-np', default=10, type=int, help="Number of random points to use") + parser.add_argument('--npoints', '-np', default=10_000, type=int, help="Number of random points to use") parser.add_argument('--number', '-n', default=100, type=int, help="Number of times to execute the calculations") parser.add_argument('--repeat', '-r', default=5, type=int, help="How many times to repeat the timer") # parser.print_help() From 4ace6d840bd5901ff810f3ea46e63481bcacd015 Mon Sep 17 00:00:00 2001 From: David Scobie Date: Thu, 17 Dec 2020 12:28:59 +0000 Subject: [PATCH 3/3] making changes --- week10/calc_pi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/week10/calc_pi.py b/week10/calc_pi.py index 1860e01..2767aff 100644 --- a/week10/calc_pi.py +++ b/week10/calc_pi.py @@ -42,7 +42,7 @@ def command(): parser = argparse.ArgumentParser(description="Calculates an approximate value of PI and how long it takes", formatter_class=argparse.ArgumentDefaultsHelpFormatter) - parser.add_argument('--npoints', '-np', default=10, type=int, help="Number of random points to use") + parser.add_argument('--npoints', '-np', default=10_000, type=int, help="Number of random points to use") parser.add_argument('--number', '-n', default=100, type=int, help="Number of times to execute the calculations") parser.add_argument('--repeat', '-r', default=5, type=int, help="How many times to repeat the timer") # parser.print_help()