diff --git a/digital_image_processing/morphological_operations/erosion_operation.py b/digital_image_processing/morphological_operations/erosion_operation.py index c2cde2ea6990..c0e1ef847237 100644 --- a/digital_image_processing/morphological_operations/erosion_operation.py +++ b/digital_image_processing/morphological_operations/erosion_operation.py @@ -21,6 +21,7 @@ def rgb2gray(rgb: np.array) -> np.array: def gray2binary(gray: np.array) -> np.array: """ Return binary image from gray image + >>> gray2binary(np.array([[127, 255, 0]])) array([[False, True, False]]) >>> gray2binary(np.array([[0]])) diff --git a/digital_image_processing/rotation/rotation.py b/digital_image_processing/rotation/rotation.py index 958d16fafb91..0f5e36ddd5be 100644 --- a/digital_image_processing/rotation/rotation.py +++ b/digital_image_processing/rotation/rotation.py @@ -10,12 +10,12 @@ def get_rotation( ) -> np.ndarray: """ Get image rotation - :param img: np.array + :param img: np.ndarray :param pt1: 3x2 list :param pt2: 3x2 list :param rows: columns image shape :param cols: rows image shape - :return: np.array + :return: np.ndarray """ matrix = cv2.getAffineTransform(pt1, pt2) return cv2.warpAffine(img, matrix, (rows, cols)) diff --git a/maths/average_median.py b/maths/average_median.py index cd1ec1574893..f24e525736b3 100644 --- a/maths/average_median.py +++ b/maths/average_median.py @@ -19,7 +19,9 @@ def median(nums: list) -> int | float: Returns: Median. """ - sorted_list = sorted(nums) + # The sorted function returns list[SupportsRichComparisonT@sorted] + # which does not support `+` + sorted_list: list[int] = sorted(nums) length = len(sorted_list) mid_index = length >> 1 return ( diff --git a/maths/euler_modified.py b/maths/euler_modified.py index 14bddadf4c53..d02123e1e2fb 100644 --- a/maths/euler_modified.py +++ b/maths/euler_modified.py @@ -5,7 +5,7 @@ def euler_modified( ode_func: Callable, y0: float, x0: float, step_size: float, x_end: float -) -> np.array: +) -> np.ndarray: """ Calculate solution at each step to an ODE using Euler's Modified Method The Euler Method is straightforward to implement, but can't give accurate solutions. diff --git a/maths/gaussian_error_linear_unit.py b/maths/gaussian_error_linear_unit.py index 7b5f875143b9..18384bb6c864 100644 --- a/maths/gaussian_error_linear_unit.py +++ b/maths/gaussian_error_linear_unit.py @@ -13,7 +13,7 @@ import numpy as np -def sigmoid(vector: np.array) -> np.array: +def sigmoid(vector: np.ndarray) -> np.ndarray: """ Mathematical function sigmoid takes a vector x of K real numbers as input and returns 1/ (1 + e^-x). @@ -25,7 +25,7 @@ def sigmoid(vector: np.array) -> np.array: return 1 / (1 + np.exp(-vector)) -def gaussian_error_linear_unit(vector: np.array) -> np.array: +def gaussian_error_linear_unit(vector: np.ndarray) -> np.ndarray: """ Implements the Gaussian Error Linear Unit (GELU) function diff --git a/maths/jaccard_similarity.py b/maths/jaccard_similarity.py index 32054414c0c2..6b6243458fa8 100644 --- a/maths/jaccard_similarity.py +++ b/maths/jaccard_similarity.py @@ -14,7 +14,11 @@ """ -def jaccard_similarity(set_a, set_b, alternative_union=False): +def jaccard_similarity( + set_a: set[str] | list[str] | tuple[str], + set_b: set[str] | list[str] | tuple[str], + alternative_union=False, +): """ Finds the jaccard similarity between two sets. Essentially, its intersection over union. @@ -37,41 +41,52 @@ def jaccard_similarity(set_a, set_b, alternative_union=False): >>> set_b = {'c', 'd', 'e', 'f', 'h', 'i'} >>> jaccard_similarity(set_a, set_b) 0.375 - >>> jaccard_similarity(set_a, set_a) 1.0 - >>> jaccard_similarity(set_a, set_a, True) 0.5 - >>> set_a = ['a', 'b', 'c', 'd', 'e'] >>> set_b = ('c', 'd', 'e', 'f', 'h', 'i') >>> jaccard_similarity(set_a, set_b) 0.375 + >>> set_a = ('c', 'd', 'e', 'f', 'h', 'i') + >>> set_b = ['a', 'b', 'c', 'd', 'e'] + >>> jaccard_similarity(set_a, set_b) + 0.375 + >>> set_a = ('c', 'd', 'e', 'f', 'h', 'i') + >>> set_b = ['a', 'b', 'c', 'd'] + >>> jaccard_similarity(set_a, set_b, True) + 0.2 + >>> set_a = {'a', 'b'} + >>> set_b = ['c', 'd'] + >>> jaccard_similarity(set_a, set_b) + Traceback (most recent call last): + ... + ValueError: Set a and b must either both be sets or be either a list or a tuple. """ if isinstance(set_a, set) and isinstance(set_b, set): - intersection = len(set_a.intersection(set_b)) + intersection_length = len(set_a.intersection(set_b)) if alternative_union: - union = len(set_a) + len(set_b) + union_length = len(set_a) + len(set_b) else: - union = len(set_a.union(set_b)) + union_length = len(set_a.union(set_b)) - return intersection / union + return intersection_length / union_length - if isinstance(set_a, (list, tuple)) and isinstance(set_b, (list, tuple)): + elif isinstance(set_a, (list, tuple)) and isinstance(set_b, (list, tuple)): intersection = [element for element in set_a if element in set_b] if alternative_union: - union = len(set_a) + len(set_b) - return len(intersection) / union + return len(intersection) / (len(set_a) + len(set_b)) else: - union = set_a + [element for element in set_b if element not in set_a] + # Cast set_a to list because tuples cannot be mutated + union = list(set_a) + [element for element in set_b if element not in set_a] return len(intersection) / len(union) - - return len(intersection) / len(union) - return None + raise ValueError( + "Set a and b must either both be sets or be either a list or a tuple." + ) if __name__ == "__main__": diff --git a/maths/newton_raphson.py b/maths/newton_raphson.py index 2c9cd1de95b0..f6b227b5c9c1 100644 --- a/maths/newton_raphson.py +++ b/maths/newton_raphson.py @@ -1,16 +1,20 @@ """ - Author: P Shreyas Shetty - Implementation of Newton-Raphson method for solving equations of kind - f(x) = 0. It is an iterative method where solution is found by the expression - x[n+1] = x[n] + f(x[n])/f'(x[n]) - If no solution exists, then either the solution will not be found when iteration - limit is reached or the gradient f'(x[n]) approaches zero. In both cases, exception - is raised. If iteration limit is reached, try increasing maxiter. - """ +Author: P Shreyas Shetty +Implementation of Newton-Raphson method for solving equations of kind +f(x) = 0. It is an iterative method where solution is found by the expression + x[n+1] = x[n] + f(x[n])/f'(x[n]) +If no solution exists, then either the solution will not be found when iteration +limit is reached or the gradient f'(x[n]) approaches zero. In both cases, exception +is raised. If iteration limit is reached, try increasing maxiter. +""" + import math as m +from collections.abc import Callable + +DerivativeFunc = Callable[[float], float] -def calc_derivative(f, a, h=0.001): +def calc_derivative(f: DerivativeFunc, a: float, h: float = 0.001) -> float: """ Calculates derivative at point a for function f using finite difference method @@ -18,7 +22,14 @@ def calc_derivative(f, a, h=0.001): return (f(a + h) - f(a - h)) / (2 * h) -def newton_raphson(f, x0=0, maxiter=100, step=0.0001, maxerror=1e-6, logsteps=False): +def newton_raphson( + f: DerivativeFunc, + x0: float = 0, + maxiter: int = 100, + step: float = 0.0001, + maxerror: float = 1e-6, + logsteps: bool = False, +) -> tuple[float, float, list[float]]: a = x0 # set the initial guess steps = [a] error = abs(f(a)) @@ -36,7 +47,7 @@ def newton_raphson(f, x0=0, maxiter=100, step=0.0001, maxerror=1e-6, logsteps=Fa if logsteps: # If logstep is true, then log intermediate steps return a, error, steps - return a, error + return a, error, [] if __name__ == "__main__": diff --git a/maths/qr_decomposition.py b/maths/qr_decomposition.py index a8414fbece87..670b49206aa7 100644 --- a/maths/qr_decomposition.py +++ b/maths/qr_decomposition.py @@ -1,7 +1,7 @@ import numpy as np -def qr_householder(a): +def qr_householder(a: np.ndarray): """Return a QR-decomposition of the matrix A using Householder reflection. The QR-decomposition decomposes the matrix A of shape (m, n) into an diff --git a/maths/sigmoid.py b/maths/sigmoid.py index 147588e8871f..cb45bde2702c 100644 --- a/maths/sigmoid.py +++ b/maths/sigmoid.py @@ -11,7 +11,7 @@ import numpy as np -def sigmoid(vector: np.array) -> np.array: +def sigmoid(vector: np.ndarray) -> np.ndarray: """ Implements the sigmoid function diff --git a/maths/tanh.py b/maths/tanh.py index ddab3e1ab717..38a369d9118d 100644 --- a/maths/tanh.py +++ b/maths/tanh.py @@ -12,12 +12,12 @@ import numpy as np -def tangent_hyperbolic(vector: np.array) -> np.array: +def tangent_hyperbolic(vector: np.ndarray) -> np.ndarray: """ Implements the tanh function Parameters: - vector: np.array + vector: np.ndarray Returns: tanh (np.array): The input numpy array after applying tanh.