diff --git a/arithmetic_analysis/bisection.py b/arithmetic_analysis/bisection.py index 0ef691678702..1cf19db67ac8 100644 --- a/arithmetic_analysis/bisection.py +++ b/arithmetic_analysis/bisection.py @@ -25,9 +25,8 @@ def bisection(function: Callable[[float], float], a: float, b: float) -> float: return a elif function(b) == 0: return b - elif ( - function(a) * function(b) > 0 - ): # if none of these are root and they are both positive or negative, + elif function(a) * function(b) > 0: + # if none of these are root and they are both positive or negative, # then this algorithm can't find the root raise ValueError("could not find root in given interval.") else: @@ -48,8 +47,8 @@ def f(x: float) -> float: if __name__ == "__main__": - print(bisection(f, 1, 1000)) - import doctest doctest.testmod() + + print(bisection(f, 1, 1000)) diff --git a/arithmetic_analysis/gaussian_elimination.py b/arithmetic_analysis/gaussian_elimination.py index 51207686c12a..b6032e440393 100644 --- a/arithmetic_analysis/gaussian_elimination.py +++ b/arithmetic_analysis/gaussian_elimination.py @@ -10,7 +10,7 @@ def retroactive_resolution(coefficients: np.matrix, vector: np.array) -> np.array: """ This function performs a retroactive linear system resolution - for triangular matrix + for triangular matrix Examples: 2x1 + 2x2 - 1x3 = 5 2x1 + 2x2 = -1 diff --git a/arithmetic_analysis/intersection.py b/arithmetic_analysis/intersection.py index 204dd5d8a935..0af62cd1cf4c 100644 --- a/arithmetic_analysis/intersection.py +++ b/arithmetic_analysis/intersection.py @@ -46,4 +46,8 @@ def f(x: float) -> float: if __name__ == "__main__": + import doctest + + doctest.testmod() + print(intersection(f, 3, 3.5)) diff --git a/arithmetic_analysis/lu_decomposition.py b/arithmetic_analysis/lu_decomposition.py index 763ba60f32b7..e06ec5f439b1 100644 --- a/arithmetic_analysis/lu_decomposition.py +++ b/arithmetic_analysis/lu_decomposition.py @@ -1,17 +1,41 @@ -"""Lower-Upper (LU) Decomposition.""" - -# lower–upper (LU) decomposition - https://en.wikipedia.org/wiki/LU_decomposition import numpy -def LUDecompose(table): - # Table that contains our data - # Table has to be a square array so we need to check first +def lower_upper_decompose(table: list) -> (list, list): + """Lower–Upper (LU) decomposition - https://en.wikipedia.org/wiki/LU_decomposition + + Args: + table (list): Table that contains our data + + Raises: + ValueError: If table is not an square array. + + Returns: + (list, list): L, U. Lower and upper arrays. + + >>> lower_upper_decompose(numpy.array([[2, -2, 1], [0, 1, 2], [5, 3]])) + Traceback (most recent call last): + ... + ValueError: not enough values to unpack (expected 2, got 1) + >>> lower_upper_decompose(numpy.array([[2, -2], [0, 1], [5, 3]])) + Traceback (most recent call last): + ... + ValueError: Table should be square array. + >>> matrix = numpy.array([[2, -2, 1], [0, 1, 2], [5, 3, -1]]) + >>> lower_upper_decompose(matrix) + (array([[1. , 0. , 0. ], + [0. , 1. , 0. ], + [2.5, 8. , 1. ]]), array([[ 2. , -2. , 1. ], + [ 0. , 1. , 2. ], + [ 0. , 0. , -19.5]])) + """ + # table input has to be a square array so we need to check first rows, columns = numpy.shape(table) + if rows != columns: + raise ValueError("Table should be square array.") + L = numpy.zeros((rows, columns)) U = numpy.zeros((rows, columns)) - if rows != columns: - return [] for i in range(columns): for j in range(i): sum = 0 @@ -28,7 +52,11 @@ def LUDecompose(table): if __name__ == "__main__": - matrix = numpy.array([[2, -2, 1], [0, 1, 2], [5, 3, 1]]) - L, U = LUDecompose(matrix) + import doctest + + doctest.testmod() + + matrix = numpy.array([[2, -2, 1], [0, 1, 2], [5, 3, 3]]) + L, U = lower_upper_decompose(matrix) print(L) print(U) diff --git a/arithmetic_analysis/newton_forward_interpolation.py b/arithmetic_analysis/newton_forward_interpolation.py index d32e3efbd1f2..a83bef6ed8a6 100644 --- a/arithmetic_analysis/newton_forward_interpolation.py +++ b/arithmetic_analysis/newton_forward_interpolation.py @@ -20,7 +20,7 @@ def ucal(u, p): def main(): - n = int(input("enter the numbers of values: ")) + n = int(input("enter the numbers of values: ").strip()) y = [] for i in range(n): y.append([]) @@ -30,13 +30,13 @@ def main(): y[i][j] = 0 print("enter the values of parameters in a list: ") - x = list(map(int, input().split())) + x = list(map(int, input().strip().split())) print("enter the values of corresponding parameters: ") for i in range(n): - y[i][0] = float(input()) + y[i][0] = float(input().strip()) - value = int(input("enter the value to interpolate: ")) + value = int(input("enter the value to interpolate: ").strip()) u = (value - x[0]) / (x[1] - x[0]) # for calculating forward difference table diff --git a/arithmetic_analysis/newton_method.py b/arithmetic_analysis/newton_method.py index a9a94372671e..26ae205ab720 100644 --- a/arithmetic_analysis/newton_method.py +++ b/arithmetic_analysis/newton_method.py @@ -6,13 +6,14 @@ RealFunc = Callable[[float], float] # type alias for a real -> real function -# function is the f(x) and derivative is the f'(x) +# function: f(x) +# derivative: f'(x) def newton( function: RealFunc, derivative: RealFunc, starting_int: int, ) -> float: - """ + """Calculates one root of function by Newton's method starting at x0 = starting_point >>> newton(lambda x: x ** 3 - 2 * x - 5, lambda x: 3 * x ** 2 - 2, 3) 2.0945514815423474 >>> newton(lambda x: x ** 3 - 1, lambda x: 3 * x ** 2, -2) @@ -31,24 +32,33 @@ def newton( ... ZeroDivisionError: Could not find root """ - prev_guess = float(starting_int) + prev_guess = float(starting_int) # sets the starting point for the algorithm while True: try: + # Calculates the next point based on x = x0 - f(x) / f'(x) next_guess = prev_guess - function(prev_guess) / derivative(prev_guess) except ZeroDivisionError: raise ZeroDivisionError("Could not find root") from None + if abs(prev_guess - next_guess) < 10 ** -5: + # The algorithm stops when the difference between the last 2 guesses are + # less than the fixed presition of 10 ** -5 return next_guess prev_guess = next_guess -def f(x: float) -> float: - return (x ** 3) - (2 * x) - 5 +def main(): + def f(x: float) -> float: + return (x ** 3) - (2 * x) - 5 + def f1(x: float) -> float: + return 3 * (x ** 2) - 2 -def f1(x: float) -> float: - return 3 * (x ** 2) - 2 + print(newton(f, f1, 3)) if __name__ == "__main__": - print(newton(f, f1, 3)) + import doctest + + doctest.testmod() + main() diff --git a/arithmetic_analysis/newton_raphson.py b/arithmetic_analysis/newton_raphson.py index 948759a09a2a..a80f8c9213a9 100644 --- a/arithmetic_analysis/newton_raphson.py +++ b/arithmetic_analysis/newton_raphson.py @@ -8,8 +8,8 @@ from sympy import diff -def newton_raphson(func: str, a: int, precision: int = 10 ** -10) -> float: - """Finds root from the point 'a' onwards by Newton-Raphson method +def newton_raphson(func: str, x: int, precision: int = 10 ** -10) -> float: + """Finds root of func by Newton-Raphson method starting at x. >>> newton_raphson("sin(x)", 2) 3.1415926536808043 >>> newton_raphson("x**2 - 5*x +2", 0.4) @@ -19,22 +19,29 @@ def newton_raphson(func: str, a: int, precision: int = 10 ** -10) -> float: >>> newton_raphson("log(x)- 1", 2) 2.718281828458938 """ - x = a + while True: + # Evaluates f in x until it becomes "0" (the value given by the precision) + x = Decimal(x) - (Decimal(eval(func)) / Decimal(eval(str(diff(func))))) - # This number dictates the accuracy of the answer + # The next value of x. x_0 + f(x) / f'(x) + if abs(eval(func)) < precision: + # The algorithm stops when f(x) ~= 0 (precision) return float(x) # Let's Execute if __name__ == "__main__": - # Find root of trigonometric function - # Find value of pi - print(f"The root of sin(x) = 0 is {newton_raphson('sin(x)', 2)}") + import doctest + + doctest.testmod() + # Find root of trigonometric function (value of pi) + print(f"One root of sin(x) = 0 is {newton_raphson('sin(x)', 2)}") + # Find root of polynomial - print(f"The root of x**2 - 5*x + 2 = 0 is {newton_raphson('x**2 - 5*x + 2', 0.4)}") - # Find Square Root of 5 - print(f"The root of log(x) - 1 = 0 is {newton_raphson('log(x) - 1', 2)}") + print(f"One root of x**2 - 5*x + 2 = 0 is {newton_raphson('x**2 - 5*x + 2', 0.4)}") + # Exponential Roots - print(f"The root of exp(x) - 1 = 0 is {newton_raphson('exp(x) - 1', 0)}") + print(f"One root of log(x) - 1 = 0 is {newton_raphson('log(x) - 1', 2)}") + print(f"One root of exp(x) - 1 = 0 is {newton_raphson('exp(x) - 1', 0)}") diff --git a/arithmetic_analysis/secant_method.py b/arithmetic_analysis/secant_method.py index b05d44c627d8..1f36d560c970 100644 --- a/arithmetic_analysis/secant_method.py +++ b/arithmetic_analysis/secant_method.py @@ -13,9 +13,9 @@ def f(x): return 8 * x - 2 * exp(-x) -def SecantMethod(lower_bound, upper_bound, repeats): +def secant_method(lower_bound, upper_bound, repeats): """ - >>> SecantMethod(1, 3, 2) + >>> secant_method(1, 3, 2) 0.2139409276214589 """ x0 = lower_bound @@ -25,4 +25,4 @@ def SecantMethod(lower_bound, upper_bound, repeats): return x1 -print(f"The solution is: {SecantMethod(1, 3, 2)}") +print(f"The solution is: {secant_method(1, 3, 2)}")