mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-01-31 06:33:44 +00:00
fix(mypy): type annotations for linear algebra algorithms (#4317)
* fix(mypy): type annotations for linear algebra algorithms * refactor: remove linear algebra directory from mypy exclude
This commit is contained in:
parent
20c7518028
commit
8c2986026b
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
|
@ -23,7 +23,7 @@ jobs:
|
||||||
python -m pip install mypy pytest-cov -r requirements.txt
|
python -m pip install mypy pytest-cov -r requirements.txt
|
||||||
# FIXME: #4052 fix mypy errors in the exclude directories and remove them below
|
# FIXME: #4052 fix mypy errors in the exclude directories and remove them below
|
||||||
- run: mypy --ignore-missing-imports
|
- run: mypy --ignore-missing-imports
|
||||||
--exclude '(data_structures|digital_image_processing|dynamic_programming|graphs|linear_algebra|maths|matrix|other|project_euler|scripts|searches|strings*)/$' .
|
--exclude '(data_structures|digital_image_processing|dynamic_programming|graphs|maths|matrix|other|project_euler|scripts|searches|strings*)/$' .
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: pytest --doctest-modules --ignore=project_euler/ --ignore=scripts/ --cov-report=term-missing:skip-covered --cov=. .
|
run: pytest --doctest-modules --ignore=project_euler/ --ignore=scripts/ --cov-report=term-missing:skip-covered --cov=. .
|
||||||
- if: ${{ success() }}
|
- if: ${{ success() }}
|
||||||
|
|
|
@ -3,10 +3,12 @@ Resources:
|
||||||
- https://en.wikipedia.org/wiki/Conjugate_gradient_method
|
- https://en.wikipedia.org/wiki/Conjugate_gradient_method
|
||||||
- https://en.wikipedia.org/wiki/Definite_symmetric_matrix
|
- https://en.wikipedia.org/wiki/Definite_symmetric_matrix
|
||||||
"""
|
"""
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
def _is_matrix_spd(matrix: np.array) -> bool:
|
def _is_matrix_spd(matrix: np.ndarray) -> bool:
|
||||||
"""
|
"""
|
||||||
Returns True if input matrix is symmetric positive definite.
|
Returns True if input matrix is symmetric positive definite.
|
||||||
Returns False otherwise.
|
Returns False otherwise.
|
||||||
|
@ -38,10 +40,11 @@ def _is_matrix_spd(matrix: np.array) -> bool:
|
||||||
eigen_values, _ = np.linalg.eigh(matrix)
|
eigen_values, _ = np.linalg.eigh(matrix)
|
||||||
|
|
||||||
# Check sign of all eigenvalues.
|
# Check sign of all eigenvalues.
|
||||||
return np.all(eigen_values > 0)
|
# np.all returns a value of type np.bool_
|
||||||
|
return bool(np.all(eigen_values > 0))
|
||||||
|
|
||||||
|
|
||||||
def _create_spd_matrix(dimension: np.int64) -> np.array:
|
def _create_spd_matrix(dimension: int) -> Any:
|
||||||
"""
|
"""
|
||||||
Returns a symmetric positive definite matrix given a dimension.
|
Returns a symmetric positive definite matrix given a dimension.
|
||||||
|
|
||||||
|
@ -64,11 +67,11 @@ def _create_spd_matrix(dimension: np.int64) -> np.array:
|
||||||
|
|
||||||
|
|
||||||
def conjugate_gradient(
|
def conjugate_gradient(
|
||||||
spd_matrix: np.array,
|
spd_matrix: np.ndarray,
|
||||||
load_vector: np.array,
|
load_vector: np.ndarray,
|
||||||
max_iterations: int = 1000,
|
max_iterations: int = 1000,
|
||||||
tol: float = 1e-8,
|
tol: float = 1e-8,
|
||||||
) -> np.array:
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
Returns solution to the linear system np.dot(spd_matrix, x) = b.
|
Returns solution to the linear system np.dot(spd_matrix, x) = b.
|
||||||
|
|
||||||
|
@ -141,6 +144,8 @@ def conjugate_gradient(
|
||||||
|
|
||||||
# Update number of iterations.
|
# Update number of iterations.
|
||||||
iterations += 1
|
iterations += 1
|
||||||
|
if iterations > max_iterations:
|
||||||
|
break
|
||||||
|
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ Overview:
|
||||||
|
|
||||||
import math
|
import math
|
||||||
import random
|
import random
|
||||||
|
from typing import Collection, Optional, Union, overload
|
||||||
|
|
||||||
|
|
||||||
class Vector:
|
class Vector:
|
||||||
|
@ -45,7 +46,7 @@ class Vector:
|
||||||
TODO: compare-operator
|
TODO: compare-operator
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, components=None):
|
def __init__(self, components: Optional[Collection[float]] = None) -> None:
|
||||||
"""
|
"""
|
||||||
input: components or nothing
|
input: components or nothing
|
||||||
simple constructor for init the vector
|
simple constructor for init the vector
|
||||||
|
@ -54,7 +55,7 @@ class Vector:
|
||||||
components = []
|
components = []
|
||||||
self.__components = list(components)
|
self.__components = list(components)
|
||||||
|
|
||||||
def set(self, components):
|
def set(self, components: Collection[float]) -> None:
|
||||||
"""
|
"""
|
||||||
input: new components
|
input: new components
|
||||||
changes the components of the vector.
|
changes the components of the vector.
|
||||||
|
@ -65,13 +66,13 @@ class Vector:
|
||||||
else:
|
else:
|
||||||
raise Exception("please give any vector")
|
raise Exception("please give any vector")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self) -> str:
|
||||||
"""
|
"""
|
||||||
returns a string representation of the vector
|
returns a string representation of the vector
|
||||||
"""
|
"""
|
||||||
return "(" + ",".join(map(str, self.__components)) + ")"
|
return "(" + ",".join(map(str, self.__components)) + ")"
|
||||||
|
|
||||||
def component(self, i):
|
def component(self, i: int) -> float:
|
||||||
"""
|
"""
|
||||||
input: index (start at 0)
|
input: index (start at 0)
|
||||||
output: the i-th component of the vector.
|
output: the i-th component of the vector.
|
||||||
|
@ -81,22 +82,22 @@ class Vector:
|
||||||
else:
|
else:
|
||||||
raise Exception("index out of range")
|
raise Exception("index out of range")
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self) -> int:
|
||||||
"""
|
"""
|
||||||
returns the size of the vector
|
returns the size of the vector
|
||||||
"""
|
"""
|
||||||
return len(self.__components)
|
return len(self.__components)
|
||||||
|
|
||||||
def euclidLength(self):
|
def euclidLength(self) -> float:
|
||||||
"""
|
"""
|
||||||
returns the euclidean length of the vector
|
returns the euclidean length of the vector
|
||||||
"""
|
"""
|
||||||
summe = 0
|
summe: float = 0
|
||||||
for c in self.__components:
|
for c in self.__components:
|
||||||
summe += c ** 2
|
summe += c ** 2
|
||||||
return math.sqrt(summe)
|
return math.sqrt(summe)
|
||||||
|
|
||||||
def __add__(self, other):
|
def __add__(self, other: "Vector") -> "Vector":
|
||||||
"""
|
"""
|
||||||
input: other vector
|
input: other vector
|
||||||
assumes: other vector has the same size
|
assumes: other vector has the same size
|
||||||
|
@ -109,7 +110,7 @@ class Vector:
|
||||||
else:
|
else:
|
||||||
raise Exception("must have the same size")
|
raise Exception("must have the same size")
|
||||||
|
|
||||||
def __sub__(self, other):
|
def __sub__(self, other: "Vector") -> "Vector":
|
||||||
"""
|
"""
|
||||||
input: other vector
|
input: other vector
|
||||||
assumes: other vector has the same size
|
assumes: other vector has the same size
|
||||||
|
@ -122,7 +123,15 @@ class Vector:
|
||||||
else: # error case
|
else: # error case
|
||||||
raise Exception("must have the same size")
|
raise Exception("must have the same size")
|
||||||
|
|
||||||
def __mul__(self, other):
|
@overload
|
||||||
|
def __mul__(self, other: float) -> "Vector":
|
||||||
|
...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def __mul__(self, other: "Vector") -> float:
|
||||||
|
...
|
||||||
|
|
||||||
|
def __mul__(self, other: Union[float, "Vector"]) -> Union[float, "Vector"]:
|
||||||
"""
|
"""
|
||||||
mul implements the scalar multiplication
|
mul implements the scalar multiplication
|
||||||
and the dot-product
|
and the dot-product
|
||||||
|
@ -132,20 +141,20 @@ class Vector:
|
||||||
return Vector(ans)
|
return Vector(ans)
|
||||||
elif isinstance(other, Vector) and (len(self) == len(other)):
|
elif isinstance(other, Vector) and (len(self) == len(other)):
|
||||||
size = len(self)
|
size = len(self)
|
||||||
summe = 0
|
summe: float = 0
|
||||||
for i in range(size):
|
for i in range(size):
|
||||||
summe += self.__components[i] * other.component(i)
|
summe += self.__components[i] * other.component(i)
|
||||||
return summe
|
return summe
|
||||||
else: # error case
|
else: # error case
|
||||||
raise Exception("invalid operand!")
|
raise Exception("invalid operand!")
|
||||||
|
|
||||||
def copy(self):
|
def copy(self) -> "Vector":
|
||||||
"""
|
"""
|
||||||
copies this vector and returns it.
|
copies this vector and returns it.
|
||||||
"""
|
"""
|
||||||
return Vector(self.__components)
|
return Vector(self.__components)
|
||||||
|
|
||||||
def changeComponent(self, pos, value):
|
def changeComponent(self, pos: int, value: float) -> None:
|
||||||
"""
|
"""
|
||||||
input: an index (pos) and a value
|
input: an index (pos) and a value
|
||||||
changes the specified component (pos) with the
|
changes the specified component (pos) with the
|
||||||
|
@ -156,7 +165,7 @@ class Vector:
|
||||||
self.__components[pos] = value
|
self.__components[pos] = value
|
||||||
|
|
||||||
|
|
||||||
def zeroVector(dimension):
|
def zeroVector(dimension: int) -> Vector:
|
||||||
"""
|
"""
|
||||||
returns a zero-vector of size 'dimension'
|
returns a zero-vector of size 'dimension'
|
||||||
"""
|
"""
|
||||||
|
@ -165,7 +174,7 @@ def zeroVector(dimension):
|
||||||
return Vector([0] * dimension)
|
return Vector([0] * dimension)
|
||||||
|
|
||||||
|
|
||||||
def unitBasisVector(dimension, pos):
|
def unitBasisVector(dimension: int, pos: int) -> Vector:
|
||||||
"""
|
"""
|
||||||
returns a unit basis vector with a One
|
returns a unit basis vector with a One
|
||||||
at index 'pos' (indexing at 0)
|
at index 'pos' (indexing at 0)
|
||||||
|
@ -177,7 +186,7 @@ def unitBasisVector(dimension, pos):
|
||||||
return Vector(ans)
|
return Vector(ans)
|
||||||
|
|
||||||
|
|
||||||
def axpy(scalar, x, y):
|
def axpy(scalar: float, x: Vector, y: Vector) -> Vector:
|
||||||
"""
|
"""
|
||||||
input: a 'scalar' and two vectors 'x' and 'y'
|
input: a 'scalar' and two vectors 'x' and 'y'
|
||||||
output: a vector
|
output: a vector
|
||||||
|
@ -192,7 +201,7 @@ def axpy(scalar, x, y):
|
||||||
return x * scalar + y
|
return x * scalar + y
|
||||||
|
|
||||||
|
|
||||||
def randomVector(N, a, b):
|
def randomVector(N: int, a: int, b: int) -> Vector:
|
||||||
"""
|
"""
|
||||||
input: size (N) of the vector.
|
input: size (N) of the vector.
|
||||||
random range (a,b)
|
random range (a,b)
|
||||||
|
@ -200,7 +209,7 @@ def randomVector(N, a, b):
|
||||||
random integer components between 'a' and 'b'.
|
random integer components between 'a' and 'b'.
|
||||||
"""
|
"""
|
||||||
random.seed(None)
|
random.seed(None)
|
||||||
ans = [random.randint(a, b) for i in range(N)]
|
ans = [random.randint(a, b) for _ in range(N)]
|
||||||
return Vector(ans)
|
return Vector(ans)
|
||||||
|
|
||||||
|
|
||||||
|
@ -222,7 +231,7 @@ class Matrix:
|
||||||
operator - _ implements the matrix-subtraction
|
operator - _ implements the matrix-subtraction
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, matrix, w, h):
|
def __init__(self, matrix: list[list[float]], w: int, h: int) -> None:
|
||||||
"""
|
"""
|
||||||
simple constructor for initializing
|
simple constructor for initializing
|
||||||
the matrix with components.
|
the matrix with components.
|
||||||
|
@ -231,7 +240,7 @@ class Matrix:
|
||||||
self.__width = w
|
self.__width = w
|
||||||
self.__height = h
|
self.__height = h
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self) -> str:
|
||||||
"""
|
"""
|
||||||
returns a string representation of this
|
returns a string representation of this
|
||||||
matrix.
|
matrix.
|
||||||
|
@ -246,7 +255,7 @@ class Matrix:
|
||||||
ans += str(self.__matrix[i][j]) + "|\n"
|
ans += str(self.__matrix[i][j]) + "|\n"
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
def changeComponent(self, x, y, value):
|
def changeComponent(self, x: int, y: int, value: float) -> None:
|
||||||
"""
|
"""
|
||||||
changes the x-y component of this matrix
|
changes the x-y component of this matrix
|
||||||
"""
|
"""
|
||||||
|
@ -255,7 +264,7 @@ class Matrix:
|
||||||
else:
|
else:
|
||||||
raise Exception("changeComponent: indices out of bounds")
|
raise Exception("changeComponent: indices out of bounds")
|
||||||
|
|
||||||
def component(self, x, y):
|
def component(self, x: int, y: int) -> float:
|
||||||
"""
|
"""
|
||||||
returns the specified (x,y) component
|
returns the specified (x,y) component
|
||||||
"""
|
"""
|
||||||
|
@ -264,13 +273,13 @@ class Matrix:
|
||||||
else:
|
else:
|
||||||
raise Exception("changeComponent: indices out of bounds")
|
raise Exception("changeComponent: indices out of bounds")
|
||||||
|
|
||||||
def width(self):
|
def width(self) -> int:
|
||||||
"""
|
"""
|
||||||
getter for the width
|
getter for the width
|
||||||
"""
|
"""
|
||||||
return self.__width
|
return self.__width
|
||||||
|
|
||||||
def height(self):
|
def height(self) -> int:
|
||||||
"""
|
"""
|
||||||
getter for the height
|
getter for the height
|
||||||
"""
|
"""
|
||||||
|
@ -303,7 +312,15 @@ class Matrix:
|
||||||
else:
|
else:
|
||||||
raise Exception("matrix is not square")
|
raise Exception("matrix is not square")
|
||||||
|
|
||||||
def __mul__(self, other):
|
@overload
|
||||||
|
def __mul__(self, other: float) -> "Matrix":
|
||||||
|
...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def __mul__(self, other: Vector) -> Vector:
|
||||||
|
...
|
||||||
|
|
||||||
|
def __mul__(self, other: Union[float, Vector]) -> Union[Vector, "Matrix"]:
|
||||||
"""
|
"""
|
||||||
implements the matrix-vector multiplication.
|
implements the matrix-vector multiplication.
|
||||||
implements the matrix-scalar multiplication
|
implements the matrix-scalar multiplication
|
||||||
|
@ -312,7 +329,7 @@ class Matrix:
|
||||||
if len(other) == self.__width:
|
if len(other) == self.__width:
|
||||||
ans = zeroVector(self.__height)
|
ans = zeroVector(self.__height)
|
||||||
for i in range(self.__height):
|
for i in range(self.__height):
|
||||||
summe = 0
|
summe: float = 0
|
||||||
for j in range(self.__width):
|
for j in range(self.__width):
|
||||||
summe += other.component(j) * self.__matrix[i][j]
|
summe += other.component(j) * self.__matrix[i][j]
|
||||||
ans.changeComponent(i, summe)
|
ans.changeComponent(i, summe)
|
||||||
|
@ -330,7 +347,7 @@ class Matrix:
|
||||||
]
|
]
|
||||||
return Matrix(matrix, self.__width, self.__height)
|
return Matrix(matrix, self.__width, self.__height)
|
||||||
|
|
||||||
def __add__(self, other):
|
def __add__(self, other: "Matrix") -> "Matrix":
|
||||||
"""
|
"""
|
||||||
implements the matrix-addition.
|
implements the matrix-addition.
|
||||||
"""
|
"""
|
||||||
|
@ -345,7 +362,7 @@ class Matrix:
|
||||||
else:
|
else:
|
||||||
raise Exception("matrix must have the same dimension!")
|
raise Exception("matrix must have the same dimension!")
|
||||||
|
|
||||||
def __sub__(self, other):
|
def __sub__(self, other: "Matrix") -> "Matrix":
|
||||||
"""
|
"""
|
||||||
implements the matrix-subtraction.
|
implements the matrix-subtraction.
|
||||||
"""
|
"""
|
||||||
|
@ -361,19 +378,21 @@ class Matrix:
|
||||||
raise Exception("matrix must have the same dimension!")
|
raise Exception("matrix must have the same dimension!")
|
||||||
|
|
||||||
|
|
||||||
def squareZeroMatrix(N):
|
def squareZeroMatrix(N: int) -> Matrix:
|
||||||
"""
|
"""
|
||||||
returns a square zero-matrix of dimension NxN
|
returns a square zero-matrix of dimension NxN
|
||||||
"""
|
"""
|
||||||
ans = [[0] * N for i in range(N)]
|
ans: list[list[float]] = [[0] * N for _ in range(N)]
|
||||||
return Matrix(ans, N, N)
|
return Matrix(ans, N, N)
|
||||||
|
|
||||||
|
|
||||||
def randomMatrix(W, H, a, b):
|
def randomMatrix(W: int, H: int, a: int, b: int) -> Matrix:
|
||||||
"""
|
"""
|
||||||
returns a random matrix WxH with integer components
|
returns a random matrix WxH with integer components
|
||||||
between 'a' and 'b'
|
between 'a' and 'b'
|
||||||
"""
|
"""
|
||||||
random.seed(None)
|
random.seed(None)
|
||||||
matrix = [[random.randint(a, b) for j in range(W)] for i in range(H)]
|
matrix: list[list[float]] = [
|
||||||
|
[random.randint(a, b) for _ in range(W)] for _ in range(H)
|
||||||
|
]
|
||||||
return Matrix(matrix, W, H)
|
return Matrix(matrix, W, H)
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
|
|
||||||
def points_to_polynomial(coordinates: list[list[int]]) -> str:
|
def points_to_polynomial(coordinates: list[list[int]]) -> str:
|
||||||
"""
|
"""
|
||||||
coordinates is a two dimensional matrix: [[x, y], [x, y], ...]
|
coordinates is a two dimensional matrix: [[x, y], [x, y], ...]
|
||||||
|
@ -55,12 +52,12 @@ def points_to_polynomial(coordinates: list[list[int]]) -> str:
|
||||||
|
|
||||||
if check == 1:
|
if check == 1:
|
||||||
count_of_line = 0
|
count_of_line = 0
|
||||||
matrix = []
|
matrix: list[list[float]] = []
|
||||||
# put the x and x to the power values in a matrix
|
# put the x and x to the power values in a matrix
|
||||||
while count_of_line < x:
|
while count_of_line < x:
|
||||||
count_in_line = 0
|
count_in_line = 0
|
||||||
a = coordinates[count_of_line][0]
|
a = coordinates[count_of_line][0]
|
||||||
count_line: list[int] = []
|
count_line: list[float] = []
|
||||||
while count_in_line < x:
|
while count_in_line < x:
|
||||||
count_line.append(a ** (x - (count_in_line + 1)))
|
count_line.append(a ** (x - (count_in_line + 1)))
|
||||||
count_in_line += 1
|
count_in_line += 1
|
||||||
|
@ -69,7 +66,7 @@ def points_to_polynomial(coordinates: list[list[int]]) -> str:
|
||||||
|
|
||||||
count_of_line = 0
|
count_of_line = 0
|
||||||
# put the y values into a vector
|
# put the y values into a vector
|
||||||
vector: list[int] = []
|
vector: list[float] = []
|
||||||
while count_of_line < x:
|
while count_of_line < x:
|
||||||
vector.append(coordinates[count_of_line][1])
|
vector.append(coordinates[count_of_line][1])
|
||||||
count_of_line += 1
|
count_of_line += 1
|
||||||
|
@ -96,14 +93,14 @@ def points_to_polynomial(coordinates: list[list[int]]) -> str:
|
||||||
# make solutions
|
# make solutions
|
||||||
solution: list[str] = []
|
solution: list[str] = []
|
||||||
while count < x:
|
while count < x:
|
||||||
solution.append(vector[count] / matrix[count][count])
|
solution.append(str(vector[count] / matrix[count][count]))
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
solved = "f(x)="
|
solved = "f(x)="
|
||||||
|
|
||||||
while count < x:
|
while count < x:
|
||||||
remove_e: list[str] = str(solution[count]).split("E")
|
remove_e: list[str] = solution[count].split("E")
|
||||||
if len(remove_e) > 1:
|
if len(remove_e) > 1:
|
||||||
solution[count] = remove_e[0] + "*10^" + remove_e[1]
|
solution[count] = remove_e[0] + "*10^" + remove_e[1]
|
||||||
solved += "x^" + str(x - (count + 1)) + "*" + str(solution[count])
|
solved += "x^" + str(x - (count + 1)) + "*" + str(solution[count])
|
||||||
|
|
|
@ -2,8 +2,11 @@ import numpy as np
|
||||||
|
|
||||||
|
|
||||||
def power_iteration(
|
def power_iteration(
|
||||||
input_matrix: np.array, vector: np.array, error_tol=1e-12, max_iterations=100
|
input_matrix: np.ndarray,
|
||||||
) -> [float, np.array]:
|
vector: np.ndarray,
|
||||||
|
error_tol: float = 1e-12,
|
||||||
|
max_iterations: int = 100,
|
||||||
|
) -> tuple[float, np.ndarray]:
|
||||||
"""
|
"""
|
||||||
Power Iteration.
|
Power Iteration.
|
||||||
Find the largest eignevalue and corresponding eigenvector
|
Find the largest eignevalue and corresponding eigenvector
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
"""
|
"""
|
||||||
https://en.wikipedia.org/wiki/Rayleigh_quotient
|
https://en.wikipedia.org/wiki/Rayleigh_quotient
|
||||||
"""
|
"""
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
def is_hermitian(matrix: np.array) -> bool:
|
def is_hermitian(matrix: np.ndarray) -> bool:
|
||||||
"""
|
"""
|
||||||
Checks if a matrix is Hermitian.
|
Checks if a matrix is Hermitian.
|
||||||
>>> import numpy as np
|
>>> import numpy as np
|
||||||
|
@ -24,7 +26,7 @@ def is_hermitian(matrix: np.array) -> bool:
|
||||||
return np.array_equal(matrix, matrix.conjugate().T)
|
return np.array_equal(matrix, matrix.conjugate().T)
|
||||||
|
|
||||||
|
|
||||||
def rayleigh_quotient(A: np.array, v: np.array) -> float:
|
def rayleigh_quotient(A: np.ndarray, v: np.ndarray) -> Any:
|
||||||
"""
|
"""
|
||||||
Returns the Rayleigh quotient of a Hermitian matrix A and
|
Returns the Rayleigh quotient of a Hermitian matrix A and
|
||||||
vector v.
|
vector v.
|
||||||
|
@ -43,7 +45,9 @@ def rayleigh_quotient(A: np.array, v: np.array) -> float:
|
||||||
array([[3.]])
|
array([[3.]])
|
||||||
"""
|
"""
|
||||||
v_star = v.conjugate().T
|
v_star = v.conjugate().T
|
||||||
return (v_star.dot(A).dot(v)) / (v_star.dot(v))
|
v_star_dot = v_star.dot(A)
|
||||||
|
assert isinstance(v_star_dot, np.ndarray)
|
||||||
|
return (v_star_dot.dot(v)) / (v_star.dot(v))
|
||||||
|
|
||||||
|
|
||||||
def tests() -> None:
|
def tests() -> None:
|
||||||
|
|
|
@ -12,7 +12,7 @@ from .lib import Matrix, Vector, axpy, squareZeroMatrix, unitBasisVector, zeroVe
|
||||||
|
|
||||||
|
|
||||||
class Test(unittest.TestCase):
|
class Test(unittest.TestCase):
|
||||||
def test_component(self):
|
def test_component(self) -> None:
|
||||||
"""
|
"""
|
||||||
test for method component
|
test for method component
|
||||||
"""
|
"""
|
||||||
|
@ -21,28 +21,28 @@ class Test(unittest.TestCase):
|
||||||
self.assertEqual(x.component(2), 3)
|
self.assertEqual(x.component(2), 3)
|
||||||
_ = Vector()
|
_ = Vector()
|
||||||
|
|
||||||
def test_str(self):
|
def test_str(self) -> None:
|
||||||
"""
|
"""
|
||||||
test for toString() method
|
test for toString() method
|
||||||
"""
|
"""
|
||||||
x = Vector([0, 0, 0, 0, 0, 1])
|
x = Vector([0, 0, 0, 0, 0, 1])
|
||||||
self.assertEqual(str(x), "(0,0,0,0,0,1)")
|
self.assertEqual(str(x), "(0,0,0,0,0,1)")
|
||||||
|
|
||||||
def test_size(self):
|
def test_size(self) -> None:
|
||||||
"""
|
"""
|
||||||
test for size()-method
|
test for size()-method
|
||||||
"""
|
"""
|
||||||
x = Vector([1, 2, 3, 4])
|
x = Vector([1, 2, 3, 4])
|
||||||
self.assertEqual(len(x), 4)
|
self.assertEqual(len(x), 4)
|
||||||
|
|
||||||
def test_euclidLength(self):
|
def test_euclidLength(self) -> None:
|
||||||
"""
|
"""
|
||||||
test for the eulidean length
|
test for the eulidean length
|
||||||
"""
|
"""
|
||||||
x = Vector([1, 2])
|
x = Vector([1, 2])
|
||||||
self.assertAlmostEqual(x.euclidLength(), 2.236, 3)
|
self.assertAlmostEqual(x.euclidLength(), 2.236, 3)
|
||||||
|
|
||||||
def test_add(self):
|
def test_add(self) -> None:
|
||||||
"""
|
"""
|
||||||
test for + operator
|
test for + operator
|
||||||
"""
|
"""
|
||||||
|
@ -52,7 +52,7 @@ class Test(unittest.TestCase):
|
||||||
self.assertEqual((x + y).component(1), 3)
|
self.assertEqual((x + y).component(1), 3)
|
||||||
self.assertEqual((x + y).component(2), 4)
|
self.assertEqual((x + y).component(2), 4)
|
||||||
|
|
||||||
def test_sub(self):
|
def test_sub(self) -> None:
|
||||||
"""
|
"""
|
||||||
test for - operator
|
test for - operator
|
||||||
"""
|
"""
|
||||||
|
@ -62,7 +62,7 @@ class Test(unittest.TestCase):
|
||||||
self.assertEqual((x - y).component(1), 1)
|
self.assertEqual((x - y).component(1), 1)
|
||||||
self.assertEqual((x - y).component(2), 2)
|
self.assertEqual((x - y).component(2), 2)
|
||||||
|
|
||||||
def test_mul(self):
|
def test_mul(self) -> None:
|
||||||
"""
|
"""
|
||||||
test for * operator
|
test for * operator
|
||||||
"""
|
"""
|
||||||
|
@ -72,19 +72,19 @@ class Test(unittest.TestCase):
|
||||||
self.assertEqual(str(x * 3.0), "(3.0,6.0,9.0)")
|
self.assertEqual(str(x * 3.0), "(3.0,6.0,9.0)")
|
||||||
self.assertEqual((a * b), 0)
|
self.assertEqual((a * b), 0)
|
||||||
|
|
||||||
def test_zeroVector(self):
|
def test_zeroVector(self) -> None:
|
||||||
"""
|
"""
|
||||||
test for the global function zeroVector(...)
|
test for the global function zeroVector(...)
|
||||||
"""
|
"""
|
||||||
self.assertTrue(str(zeroVector(10)).count("0") == 10)
|
self.assertTrue(str(zeroVector(10)).count("0") == 10)
|
||||||
|
|
||||||
def test_unitBasisVector(self):
|
def test_unitBasisVector(self) -> None:
|
||||||
"""
|
"""
|
||||||
test for the global function unitBasisVector(...)
|
test for the global function unitBasisVector(...)
|
||||||
"""
|
"""
|
||||||
self.assertEqual(str(unitBasisVector(3, 1)), "(0,1,0)")
|
self.assertEqual(str(unitBasisVector(3, 1)), "(0,1,0)")
|
||||||
|
|
||||||
def test_axpy(self):
|
def test_axpy(self) -> None:
|
||||||
"""
|
"""
|
||||||
test for the global function axpy(...) (operation)
|
test for the global function axpy(...) (operation)
|
||||||
"""
|
"""
|
||||||
|
@ -92,7 +92,7 @@ class Test(unittest.TestCase):
|
||||||
y = Vector([1, 0, 1])
|
y = Vector([1, 0, 1])
|
||||||
self.assertEqual(str(axpy(2, x, y)), "(3,4,7)")
|
self.assertEqual(str(axpy(2, x, y)), "(3,4,7)")
|
||||||
|
|
||||||
def test_copy(self):
|
def test_copy(self) -> None:
|
||||||
"""
|
"""
|
||||||
test for the copy()-method
|
test for the copy()-method
|
||||||
"""
|
"""
|
||||||
|
@ -100,7 +100,7 @@ class Test(unittest.TestCase):
|
||||||
y = x.copy()
|
y = x.copy()
|
||||||
self.assertEqual(str(x), str(y))
|
self.assertEqual(str(x), str(y))
|
||||||
|
|
||||||
def test_changeComponent(self):
|
def test_changeComponent(self) -> None:
|
||||||
"""
|
"""
|
||||||
test for the changeComponent(...)-method
|
test for the changeComponent(...)-method
|
||||||
"""
|
"""
|
||||||
|
@ -109,43 +109,43 @@ class Test(unittest.TestCase):
|
||||||
x.changeComponent(1, 1)
|
x.changeComponent(1, 1)
|
||||||
self.assertEqual(str(x), "(0,1,0)")
|
self.assertEqual(str(x), "(0,1,0)")
|
||||||
|
|
||||||
def test_str_matrix(self):
|
def test_str_matrix(self) -> None:
|
||||||
A = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
|
A = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
|
||||||
self.assertEqual("|1,2,3|\n|2,4,5|\n|6,7,8|\n", str(A))
|
self.assertEqual("|1,2,3|\n|2,4,5|\n|6,7,8|\n", str(A))
|
||||||
|
|
||||||
def test_determinate(self):
|
def test_determinate(self) -> None:
|
||||||
"""
|
"""
|
||||||
test for determinate()
|
test for determinate()
|
||||||
"""
|
"""
|
||||||
A = Matrix([[1, 1, 4, 5], [3, 3, 3, 2], [5, 1, 9, 0], [9, 7, 7, 9]], 4, 4)
|
A = Matrix([[1, 1, 4, 5], [3, 3, 3, 2], [5, 1, 9, 0], [9, 7, 7, 9]], 4, 4)
|
||||||
self.assertEqual(-376, A.determinate())
|
self.assertEqual(-376, A.determinate())
|
||||||
|
|
||||||
def test__mul__matrix(self):
|
def test__mul__matrix(self) -> None:
|
||||||
A = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]], 3, 3)
|
A = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]], 3, 3)
|
||||||
x = Vector([1, 2, 3])
|
x = Vector([1, 2, 3])
|
||||||
self.assertEqual("(14,32,50)", str(A * x))
|
self.assertEqual("(14,32,50)", str(A * x))
|
||||||
self.assertEqual("|2,4,6|\n|8,10,12|\n|14,16,18|\n", str(A * 2))
|
self.assertEqual("|2,4,6|\n|8,10,12|\n|14,16,18|\n", str(A * 2))
|
||||||
|
|
||||||
def test_changeComponent_matrix(self):
|
def test_changeComponent_matrix(self) -> None:
|
||||||
A = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
|
A = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
|
||||||
A.changeComponent(0, 2, 5)
|
A.changeComponent(0, 2, 5)
|
||||||
self.assertEqual("|1,2,5|\n|2,4,5|\n|6,7,8|\n", str(A))
|
self.assertEqual("|1,2,5|\n|2,4,5|\n|6,7,8|\n", str(A))
|
||||||
|
|
||||||
def test_component_matrix(self):
|
def test_component_matrix(self) -> None:
|
||||||
A = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
|
A = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
|
||||||
self.assertEqual(7, A.component(2, 1), 0.01)
|
self.assertEqual(7, A.component(2, 1), 0.01)
|
||||||
|
|
||||||
def test__add__matrix(self):
|
def test__add__matrix(self) -> None:
|
||||||
A = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
|
A = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
|
||||||
B = Matrix([[1, 2, 7], [2, 4, 5], [6, 7, 10]], 3, 3)
|
B = Matrix([[1, 2, 7], [2, 4, 5], [6, 7, 10]], 3, 3)
|
||||||
self.assertEqual("|2,4,10|\n|4,8,10|\n|12,14,18|\n", str(A + B))
|
self.assertEqual("|2,4,10|\n|4,8,10|\n|12,14,18|\n", str(A + B))
|
||||||
|
|
||||||
def test__sub__matrix(self):
|
def test__sub__matrix(self) -> None:
|
||||||
A = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
|
A = Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]], 3, 3)
|
||||||
B = Matrix([[1, 2, 7], [2, 4, 5], [6, 7, 10]], 3, 3)
|
B = Matrix([[1, 2, 7], [2, 4, 5], [6, 7, 10]], 3, 3)
|
||||||
self.assertEqual("|0,0,-4|\n|0,0,0|\n|0,0,-2|\n", str(A - B))
|
self.assertEqual("|0,0,-4|\n|0,0,0|\n|0,0,-2|\n", str(A - B))
|
||||||
|
|
||||||
def test_squareZeroMatrix(self):
|
def test_squareZeroMatrix(self) -> None:
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
"|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|" + "\n|0,0,0,0,0|\n",
|
"|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|" + "\n|0,0,0,0,0|\n",
|
||||||
str(squareZeroMatrix(5)),
|
str(squareZeroMatrix(5)),
|
||||||
|
|
|
@ -11,8 +11,6 @@ projection(45) = [[0.27596319193541496, 0.446998331800279],
|
||||||
reflection(45) = [[0.05064397763545947, 0.893996663600558],
|
reflection(45) = [[0.05064397763545947, 0.893996663600558],
|
||||||
[0.893996663600558, 0.7018070490682369]]
|
[0.893996663600558, 0.7018070490682369]]
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from math import cos, sin
|
from math import cos, sin
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user