diff --git a/week10/calc_pi.py b/week10/calc_pi.py index 64b7085..2767aff 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 @@ -43,7 +45,7 @@ def command(): 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() 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..8c8cc7d --- /dev/null +++ b/week10/calc_pi_np.py @@ -0,0 +1,83 @@ +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 + + """ + 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): + """ + 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.random.rand(points,2) + within_circle = point_in_circle(array) + + # 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_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() + 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