Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix minor typing errors in maths/ #8959

Merged
merged 10 commits into from
Aug 15, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -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]]))
Expand Down
4 changes: 2 additions & 2 deletions digital_image_processing/rotation/rotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
4 changes: 3 additions & 1 deletion maths/average_median.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down
2 changes: 1 addition & 1 deletion maths/euler_modified.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions maths/gaussian_error_linear_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand All @@ -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

Expand Down
45 changes: 30 additions & 15 deletions maths/jaccard_similarity.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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__":
Expand Down
33 changes: 22 additions & 11 deletions maths/newton_raphson.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
"""
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
"""
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))
Expand All @@ -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__":
Expand Down
2 changes: 1 addition & 1 deletion maths/qr_decomposition.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion maths/sigmoid.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions maths/tanh.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down