I recently sawthis video that explained how to calculate pi, and attempted to build a Python simulation. In theory, it works, but it is much too slow, and I have no idea why.
In theoutput, you can see that the program starts off with hundreds of collisions calculated per second, but quickly slows down to only 40-50 per second, and when I leave it alone for a prolonged amount of time, it decreases to a measly 2 calculations!Here is my code:
#importsfrom time import time, sleepfrom fractions import Fraction#set variablesp = [Fraction(8, 1), Fraction(10, 1)]m = [1, 1]v = [Fraction(0, 1), Fraction(-1, 1)]collisions = 0time_interval = 1#mainprint("The π Calculator\n\nCredits:\nOriginal formula discovered by Gregory Galperin\nSimulation by Te Du\n")sleep(1)m[1] = 100 ** int(input("How many digits would you like to calculate? "))start_time = time()prev_time = start_timewhile not (v[0] <= v[1] and v[0] >= 0): if time() - prev_time >= time_interval: try: print("Seconds elapsed: " + str(time() - start_time) + "\nCollisions: " + str(collisions)) except ValueError: prev_time = time() + 1000000000 time_interval = 2 - (time() - prev_time) prev_time = time() try: wall_to_one = p[0] / -v[0] except ZeroDivisionError: wall_to_one = 0 one_to_two = (p[1] - p[0]) / (v[0] - v[1]) collisions += 1 if one_to_two <= 0 or (0 < wall_to_one and wall_to_one < one_to_two): p[0] += v[0] * wall_to_one p[1] += v[1] * wall_to_one v[0] *= -1 else: p[0] += v[0] * one_to_two p[1] += v[1] * one_to_two v = [Fraction(m[0] - m[1], m[1] + m[0]) * v[0] + Fraction(2 * m[1], m[1] + m[0]) * v[1], Fraction(2 * m[0], m[1] + m[0]) * v[0] + Fraction(m[1] - m[0], m[1] + m[0]) * v[1]]#cleanupdel p, m, v, wall_to_one, one_to_two, start_time, prev_time, time_interval#printing piprint("π: " + str(collisions))- What is the
except ValueError:block for? Why would any of the numbers that you print cause a value error?Barmar– Barmar2024-09-21 18:24:15 +00:00CommentedSep 21, 2024 at 18:24 - 1Calculations with arbitrary-precision numbers slow down as the number of digits increase. Addition and subtraction are O(n), while multiplication and division are O(n^2).Barmar– Barmar2024-09-21 18:26:10 +00:00CommentedSep 21, 2024 at 18:26
- That is for if the collision count gets too big. Since now that prev_time is greater than time(), it will never call print() again and raise an error. (if you haven't learned already, I don't do things the normal way)meowdog011011– meowdog0110112024-09-21 18:28:17 +00:00CommentedSep 21, 2024 at 18:28
- thanks @Barmar for the info, but is there any way I can speed this up?meowdog011011– meowdog0110112024-09-21 18:30:07 +00:00CommentedSep 21, 2024 at 18:30
- Probably not if you need all those digits of precision. This is why we use floating point for ordinary numeric calculations. It's much faster, but not as precise.Barmar– Barmar2024-09-21 18:31:45 +00:00CommentedSep 21, 2024 at 18:31
Related questions
Related questions
