def test_pi_3dp_lower_accuracy(self): """Checking the calculation on lower accuracy : 3 dp.""" print("Test of Pi calculation with 3 dp") PiUtility.init_pi(AlgorithmType.BBP, 3) my_pi = PiUtility.pi() self.assertAlmostEqual(my_pi, mpf(3.14159265358), 3) print("=======================")
def test_pi_10dp_precision(self): """Checking if the results repeat under the same conditions.""" print("Test of Pi calculation with 10 decimal precision [repeat]") PiUtility.init_pi(AlgorithmType.BBP, 10) my_pi = PiUtility.pi() self.assertAlmostEqual(my_pi, mpf(3.14159265358), 10) print("=======================")
def test_pi_10dp_accuracy(self): """Checking the accuracy of the calculation : 10 dp.""" print("Test of Pi calculation with 10 decimal precision") PiUtility.init_pi(AlgorithmType.BBP, 10) my_pi = PiUtility.pi() self.assertAlmostEqual(my_pi, mpf(3.14159265358), 10) print("=======================")
def test_alpha_5dp_precision(self): """Checking the accuracy of the calculation : 5 dp.""" print("Test of alpha calculation with 5 dp") PiUtility.init_pi(PiAlgorithmType.BBP, 12) alpha = AlgorithmRunner.calculate_alpha(AlphaAlgorithmType.Newton, 5) self.assertTrue( almosteq(alpha, mpmathify("2.3098814600", strings=True), 1e-5)) print("=======================")
def test_alpha_10dp_precision(self): """Checking if the results repeat under the same conditions.""" print("Test of alpha calculation with 10 decimal precision [repeat]") PiUtility.init_pi(PiAlgorithmType.BBP, 12) alpha = AlgorithmRunner.calculate_alpha(AlphaAlgorithmType.Newton, 10) self.assertTrue( almosteq(alpha, mpmathify("2.3098814600", strings=True), 1e-10)) print("=======================")
def test_pi_20dp_higher_accuracy(self): """Checking the calculation on higher accuracy : 20 dp.""" print("Test of Pi calculation with 20 dp") PiUtility.init_pi(AlgorithmType.BBP, 20) my_pi = PiUtility.pi() self.assertTrue( almosteq(my_pi, mpmathify("3.141592653589793238462", strings=True), 1e-20)) print("=======================")
def __constants_calculated(cls, conditions): if (PiUtility.pi() == 0 or cls.__alpha == 0 or conditions.get_precision() != cls.__precision or conditions.get_approximation_algorithm() != cls.__approximation_algorithm or conditions.get_pi_algorithm() != PiUtility.get_algorithm()): return False return True
def test_pi_negative_precision(self): """Checking the return value if the precision is negative. Return: Zero """ print("Test of Pi calculation with negative decimal precision") PiUtility.init_pi(AlgorithmType.BBP, -2) my_pi = PiUtility.pi() self.assertEqual(my_pi, mpf(0)) print("=======================")
def test_alpha_negative_precision(self): """Checking the return value if the precision is negative. Return: The calculation result must be the same as initial value which is 2.5. The test checks the return value against 2.5 """ print("Test of alpha calculation with negative precision.") PiUtility.init_pi(PiAlgorithmType.BBP, -2) alpha = AlgorithmRunner.calculate_alpha(AlphaAlgorithmType.Newton, -2) self.assertEqual(alpha, mpf(2.5)) print("=======================")
def calculate_overlapping_length(cls, coaster_radius, conditions): """Calculates the length of the overlapping segment. It uses alpha calculator class to find the length of the overlapping segment so that the overlapping area would be half of the area of a coaster Args: coaster_radius: The radius of each coaster. A mp float. conditions: The conditions of the calculation. A CalculationCondition object. Returns: The length of the overlapping segment in the form of a result object. """ try: # We only recalculate alpha and Pi if the conditions has been changed if not cls.__constants_calculated(conditions): # We initialize the pi value before starting the calculations PiUtility.init_pi(conditions.get_pi_algorithm(), conditions.get_precision() + int(5)) cls.__precision = conditions.get_precision() cls.__approximation_algorithm = conditions.get_approximation_algorithm( ) cls.__alpha = AlgorithmRunner.calculate_alpha( cls.__approximation_algorithm, cls.__precision) cls.__alpha_over_two = cls.__alpha / mpf(2) print("Alpha with the precision of", cls.__precision, "is:", nstr(cls.__alpha, cls.__precision + 1)) except CalculationException as err: raise err # formula is : l = 2R(1 - cos(alpha/2)) print( "\nCalculation of overlapping length for the radius of {} started." .format(coaster_radius)) radius = mpf(coaster_radius) overlapping_length = mpf(2) * radius * (mpf(1) - cos(cls.__alpha_over_two)) print("\nOverlapping length calculated at {} decimal places as {}". format(cls.__precision, overlapping_length)) result = Result(radius, conditions, overlapping_length, cls.__alpha, PiUtility.pi()) return result
def calculate(cls, precision): """Calculates alpha. Args: precision: the desired precision of the calculation Returns: The result of the calculation which is the approximation of alpha angle. """ # We calculate pi/2 only once before starting the calculations cls.__pi_over_two = PiUtility.pi() / mpf(2) # Setting the decimal places mp.dps = precision + 6 # Initial value for newton approximation algorithm alpha = cls.__INITIAL_VALUE calculated_decimal_places = 1 # The formula is: # alpha_n+1 = alpha_n - [(alpha_n - sin(alpha_n) - (pi/2)) / (1 - cos(alpha_n))] for iter_num in range(0, precision): alpha = cls.__calculate_next_alpha(alpha) if iter_num >= 1: # The convergence is quadratic, hence the number of # iterations based on the specified precision can be checked as follows calculated_decimal_places += 3 * (2**(iter_num - 1)) if calculated_decimal_places >= precision: break return alpha