From f38f1a7c83fdfa9c5d69e43ddb223eed627f7bc0 Mon Sep 17 00:00:00 2001 From: Pablito Date: Wed, 20 Nov 2024 09:59:48 +0100 Subject: [PATCH 01/11] Implemented Lanczos Algorithm --- linear_algebra/Lanczos-algorithm.py | 34 +++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 linear_algebra/Lanczos-algorithm.py diff --git a/linear_algebra/Lanczos-algorithm.py b/linear_algebra/Lanczos-algorithm.py new file mode 100644 index 000000000000..4bdba1bce59b --- /dev/null +++ b/linear_algebra/Lanczos-algorithm.py @@ -0,0 +1,34 @@ +import numpy as np +def lanczos(A: np.ndarray) -> ([float], [float]): + """ + Implements the Lanczos algorithm for a symmetric matrix. + + Parameters: + ----------- + matrix : numpy.ndarray + Symmetric matrix of size (n, n). + + Returns: + -------- + alpha : [float] + List of diagonal elements of the resulting tridiagonal matrix. + beta : [float] + List of off-diagonal elements of the resulting tridiagonal matrix. + """ + n = A.shape[0] + V = np.zeros((n, n)) + V[:, 0] = np.random.randn(n) + V[:, 0] /= np.linalg.norm(V[:, 0]) + alpha = [] + beta = [] + for j in range(n): + w = np.dot(A, V[:, j]) + alpha.append(np.dot(w, V[:, j])) + if j == n - 1: + break + w -= alpha[j] * V[:, j] + if j > 0: + w -= beta[j - 1] * V[:, j - 1] + beta.append(np.linalg.norm(w)) + V[:, j + 1] = w / beta[j] + return alpha, beta \ No newline at end of file From ab246373e6bc725755858d6728144ed56caf4911 Mon Sep 17 00:00:00 2001 From: Nanoemm Date: Wed, 20 Nov 2024 09:00:17 +0000 Subject: [PATCH 02/11] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index f0a34a553946..50a34802b886 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -559,6 +559,7 @@ * [Test Knapsack](knapsack/tests/test_knapsack.py) ## Linear Algebra + * [Lanczos-Algorithm](linear_algebra/Lanczos-algorithm.py) * [Gaussian Elimination](linear_algebra/gaussian_elimination.py) * [Jacobi Iteration Method](linear_algebra/jacobi_iteration_method.py) * [Lu Decomposition](linear_algebra/lu_decomposition.py) From d470987ca8b417e435cc6f4d2f4fd2a2351e2fd5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 09:16:12 +0000 Subject: [PATCH 03/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- linear_algebra/Lanczos-algorithm.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/linear_algebra/Lanczos-algorithm.py b/linear_algebra/Lanczos-algorithm.py index 4bdba1bce59b..d8e9ea2915ed 100644 --- a/linear_algebra/Lanczos-algorithm.py +++ b/linear_algebra/Lanczos-algorithm.py @@ -1,20 +1,22 @@ import numpy as np + + def lanczos(A: np.ndarray) -> ([float], [float]): """ - Implements the Lanczos algorithm for a symmetric matrix. + Implements the Lanczos algorithm for a symmetric matrix. - Parameters: - ----------- - matrix : numpy.ndarray - Symmetric matrix of size (n, n). + Parameters: + ----------- + matrix : numpy.ndarray + Symmetric matrix of size (n, n). - Returns: - -------- - alpha : [float] - List of diagonal elements of the resulting tridiagonal matrix. - beta : [float] - List of off-diagonal elements of the resulting tridiagonal matrix. - """ + Returns: + -------- + alpha : [float] + List of diagonal elements of the resulting tridiagonal matrix. + beta : [float] + List of off-diagonal elements of the resulting tridiagonal matrix. + """ n = A.shape[0] V = np.zeros((n, n)) V[:, 0] = np.random.randn(n) @@ -31,4 +33,4 @@ def lanczos(A: np.ndarray) -> ([float], [float]): w -= beta[j - 1] * V[:, j - 1] beta.append(np.linalg.norm(w)) V[:, j + 1] = w / beta[j] - return alpha, beta \ No newline at end of file + return alpha, beta From 03a37ebacaba0cc16f9d5780f32a725e982b72ac Mon Sep 17 00:00:00 2001 From: Pablito Date: Wed, 20 Nov 2024 10:36:33 +0100 Subject: [PATCH 04/11] Modified file name to be lowercase and replaced - for _ Changed argument name A to a Changed variable name V to v Added specifications for beta and alpha Changed np.random.randn --- ...czos-algorithm.py => lanczos_algorithm.py} | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) rename linear_algebra/{Lanczos-algorithm.py => lanczos_algorithm.py} (56%) diff --git a/linear_algebra/Lanczos-algorithm.py b/linear_algebra/lanczos_algorithm.py similarity index 56% rename from linear_algebra/Lanczos-algorithm.py rename to linear_algebra/lanczos_algorithm.py index 4bdba1bce59b..601e8841f0f7 100644 --- a/linear_algebra/Lanczos-algorithm.py +++ b/linear_algebra/lanczos_algorithm.py @@ -1,5 +1,5 @@ import numpy as np -def lanczos(A: np.ndarray) -> ([float], [float]): +def lanczos(a: np.ndarray) -> tuple[list[float], list[float]]: """ Implements the Lanczos algorithm for a symmetric matrix. @@ -15,20 +15,21 @@ def lanczos(A: np.ndarray) -> ([float], [float]): beta : [float] List of off-diagonal elements of the resulting tridiagonal matrix. """ - n = A.shape[0] - V = np.zeros((n, n)) - V[:, 0] = np.random.randn(n) - V[:, 0] /= np.linalg.norm(V[:, 0]) - alpha = [] - beta = [] + n = a.shape[0] + v = np.zeros((n, n)) + rng = np.random.default_rng() + v[:, 0] = rng.standard_normal(n) + v[:, 0] /= np.linalg.norm(v[:, 0]) + alpha : list[float] = [] + beta : list[float] = [] for j in range(n): - w = np.dot(A, V[:, j]) - alpha.append(np.dot(w, V[:, j])) + w = np.dot(a, v[:, j]) + alpha.append(np.dot(w, v[:, j])) if j == n - 1: break - w -= alpha[j] * V[:, j] + w -= alpha[j] * v[:, j] if j > 0: - w -= beta[j - 1] * V[:, j - 1] + w -= beta[j - 1] * v[:, j - 1] beta.append(np.linalg.norm(w)) - V[:, j + 1] = w / beta[j] + v[:, j + 1] = w / beta[j] return alpha, beta \ No newline at end of file From baf934f4df11b5346baecc632519a5cad4a83b47 Mon Sep 17 00:00:00 2001 From: Nanoemm Date: Wed, 20 Nov 2024 09:38:31 +0000 Subject: [PATCH 05/11] updating DIRECTORY.md --- DIRECTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index 50a34802b886..04459c3f9a12 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -559,9 +559,9 @@ * [Test Knapsack](knapsack/tests/test_knapsack.py) ## Linear Algebra - * [Lanczos-Algorithm](linear_algebra/Lanczos-algorithm.py) * [Gaussian Elimination](linear_algebra/gaussian_elimination.py) * [Jacobi Iteration Method](linear_algebra/jacobi_iteration_method.py) + * [Lanczos Algorithm](linear_algebra/lanczos_algorithm.py) * [Lu Decomposition](linear_algebra/lu_decomposition.py) * Src * [Conjugate Gradient](linear_algebra/src/conjugate_gradient.py) From d2afa4cc8be0e13474d655f51c42d6f67929071e Mon Sep 17 00:00:00 2001 From: Pablito Date: Wed, 20 Nov 2024 10:43:25 +0100 Subject: [PATCH 06/11] Changed the structure to correspond with PEP8 convention. --- linear_algebra/lanczos_algorithm.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/linear_algebra/lanczos_algorithm.py b/linear_algebra/lanczos_algorithm.py index 601e8841f0f7..4d792d3b0e53 100644 --- a/linear_algebra/lanczos_algorithm.py +++ b/linear_algebra/lanczos_algorithm.py @@ -1,4 +1,6 @@ import numpy as np + + def lanczos(a: np.ndarray) -> tuple[list[float], list[float]]: """ Implements the Lanczos algorithm for a symmetric matrix. @@ -20,8 +22,8 @@ def lanczos(a: np.ndarray) -> tuple[list[float], list[float]]: rng = np.random.default_rng() v[:, 0] = rng.standard_normal(n) v[:, 0] /= np.linalg.norm(v[:, 0]) - alpha : list[float] = [] - beta : list[float] = [] + alpha: list[float] = [] + beta: list[float] = [] for j in range(n): w = np.dot(a, v[:, j]) alpha.append(np.dot(w, v[:, j])) @@ -32,4 +34,4 @@ def lanczos(a: np.ndarray) -> tuple[list[float], list[float]]: w -= beta[j - 1] * v[:, j - 1] beta.append(np.linalg.norm(w)) v[:, j + 1] = w / beta[j] - return alpha, beta \ No newline at end of file + return alpha, beta From 7977b61135234be89158df6726a02037cf307bab Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 09:44:15 +0000 Subject: [PATCH 07/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- linear_algebra/lanczos_algorithm.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/linear_algebra/lanczos_algorithm.py b/linear_algebra/lanczos_algorithm.py index 4d792d3b0e53..f59986da756e 100644 --- a/linear_algebra/lanczos_algorithm.py +++ b/linear_algebra/lanczos_algorithm.py @@ -3,20 +3,20 @@ def lanczos(a: np.ndarray) -> tuple[list[float], list[float]]: """ - Implements the Lanczos algorithm for a symmetric matrix. + Implements the Lanczos algorithm for a symmetric matrix. - Parameters: - ----------- - matrix : numpy.ndarray - Symmetric matrix of size (n, n). + Parameters: + ----------- + matrix : numpy.ndarray + Symmetric matrix of size (n, n). - Returns: - -------- - alpha : [float] - List of diagonal elements of the resulting tridiagonal matrix. - beta : [float] - List of off-diagonal elements of the resulting tridiagonal matrix. - """ + Returns: + -------- + alpha : [float] + List of diagonal elements of the resulting tridiagonal matrix. + beta : [float] + List of off-diagonal elements of the resulting tridiagonal matrix. + """ n = a.shape[0] v = np.zeros((n, n)) rng = np.random.default_rng() From 15c9dbc43a4edecaa39331687e379b7a3c85dfd1 Mon Sep 17 00:00:00 2001 From: Pablito Date: Tue, 3 Dec 2024 09:46:56 +0100 Subject: [PATCH 08/11] Implemented Legendre polynomial computation algorithm Added an algorithm that calculates the coefficients of the Legendre polynomial of degree n using the recurrence relation. --- maths/polynomials/legendre.py | 60 +++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 maths/polynomials/legendre.py diff --git a/maths/polynomials/legendre.py b/maths/polynomials/legendre.py new file mode 100644 index 000000000000..8bd3fdb56832 --- /dev/null +++ b/maths/polynomials/legendre.py @@ -0,0 +1,60 @@ +from numpy.polynomial import Polynomial +from math import factorial +import pytest + + +def legendre(n: int) -> list[float]: + """ + Compute the coefficients of the nth Legendre polynomial. + + The Legendre polynomials are solutions to Legendre's differential equation + and are widely used in physics and engineering. + + Parameters: + n (int): The order of the Legendre polynomial. + + Returns: + list[float]: Coefficients of the polynomial in ascending order of powers. + """ + p = (1 / (factorial(n) * (2 ** n))) * (Polynomial([-1, 0, 1]) ** n) + return p.deriv(n).coef.tolist() + + +def jsp(): + print(legendre(1)) + print(legendre(2)) + print(legendre(3)) + print(legendre(4)) + + +jsp() + + +def test_legendre_0(): + """Test the 0th Legendre polynomial.""" + assert legendre(0) == [1.0], "The 0th Legendre polynomial should be [1.0]" + + +def test_legendre_1(): + """Test the 1st Legendre polynomial.""" + assert legendre(1) == [0.0, 1.0], "The 1st Legendre polynomial should be [0.0, 1.0]" + + +def test_legendre_2(): + """Test the 2nd Legendre polynomial.""" + assert legendre(2) == [-0.5, 0.0, 1.5], "The 2nd Legendre polynomial should be [-0.5, 0.0, 1.5]" + + +def test_legendre_3(): + """Test the 3rd Legendre polynomial.""" + assert legendre(3) == [0.0, -1.5, 0.0, 2.5], "The 3rd Legendre polynomial should be [0.0, -1.5, 0.0, 2.5]" + + +def test_legendre_4(): + """Test the 4th Legendre polynomial.""" + assert legendre(4) == pytest.approx([0.375, 0.0, -3.75, 0.0, 4.375]) + "The 4th Legendre polynomial should be [0.375, 0.0, -3.75, 0.0, 4.375]" + + +if __name__ == '__main__': + pytest.main() From 06eec1e4f8818dff093a91e50a70577066bf0f37 Mon Sep 17 00:00:00 2001 From: Nanoemm Date: Tue, 3 Dec 2024 08:47:32 +0000 Subject: [PATCH 09/11] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 04459c3f9a12..02b149525484 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -720,6 +720,7 @@ * [Pollard Rho](maths/pollard_rho.py) * [Polynomial Evaluation](maths/polynomial_evaluation.py) * Polynomials + * [Legendre](maths/polynomials/legendre.py) * [Single Indeterminate Operations](maths/polynomials/single_indeterminate_operations.py) * [Power Using Recursion](maths/power_using_recursion.py) * [Prime Check](maths/prime_check.py) From 1d1eda96be67239c07f3f4e98d43ce8fe3fdc50b Mon Sep 17 00:00:00 2001 From: Pablito Date: Tue, 3 Dec 2024 09:59:56 +0100 Subject: [PATCH 10/11] Undo the commit --- maths/polynomials/legendre.py | 60 ----------------------------------- 1 file changed, 60 deletions(-) delete mode 100644 maths/polynomials/legendre.py diff --git a/maths/polynomials/legendre.py b/maths/polynomials/legendre.py deleted file mode 100644 index 8bd3fdb56832..000000000000 --- a/maths/polynomials/legendre.py +++ /dev/null @@ -1,60 +0,0 @@ -from numpy.polynomial import Polynomial -from math import factorial -import pytest - - -def legendre(n: int) -> list[float]: - """ - Compute the coefficients of the nth Legendre polynomial. - - The Legendre polynomials are solutions to Legendre's differential equation - and are widely used in physics and engineering. - - Parameters: - n (int): The order of the Legendre polynomial. - - Returns: - list[float]: Coefficients of the polynomial in ascending order of powers. - """ - p = (1 / (factorial(n) * (2 ** n))) * (Polynomial([-1, 0, 1]) ** n) - return p.deriv(n).coef.tolist() - - -def jsp(): - print(legendre(1)) - print(legendre(2)) - print(legendre(3)) - print(legendre(4)) - - -jsp() - - -def test_legendre_0(): - """Test the 0th Legendre polynomial.""" - assert legendre(0) == [1.0], "The 0th Legendre polynomial should be [1.0]" - - -def test_legendre_1(): - """Test the 1st Legendre polynomial.""" - assert legendre(1) == [0.0, 1.0], "The 1st Legendre polynomial should be [0.0, 1.0]" - - -def test_legendre_2(): - """Test the 2nd Legendre polynomial.""" - assert legendre(2) == [-0.5, 0.0, 1.5], "The 2nd Legendre polynomial should be [-0.5, 0.0, 1.5]" - - -def test_legendre_3(): - """Test the 3rd Legendre polynomial.""" - assert legendre(3) == [0.0, -1.5, 0.0, 2.5], "The 3rd Legendre polynomial should be [0.0, -1.5, 0.0, 2.5]" - - -def test_legendre_4(): - """Test the 4th Legendre polynomial.""" - assert legendre(4) == pytest.approx([0.375, 0.0, -3.75, 0.0, 4.375]) - "The 4th Legendre polynomial should be [0.375, 0.0, -3.75, 0.0, 4.375]" - - -if __name__ == '__main__': - pytest.main() From 65d271904f3fef1d7d53b553946fb18832a90eca Mon Sep 17 00:00:00 2001 From: Nanoemm Date: Tue, 3 Dec 2024 09:00:25 +0000 Subject: [PATCH 11/11] updating DIRECTORY.md --- DIRECTORY.md | 1 - 1 file changed, 1 deletion(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index 02b149525484..04459c3f9a12 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -720,7 +720,6 @@ * [Pollard Rho](maths/pollard_rho.py) * [Polynomial Evaluation](maths/polynomial_evaluation.py) * Polynomials - * [Legendre](maths/polynomials/legendre.py) * [Single Indeterminate Operations](maths/polynomials/single_indeterminate_operations.py) * [Power Using Recursion](maths/power_using_recursion.py) * [Prime Check](maths/prime_check.py)