Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@
## Linear Algebra
* [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)
Expand Down Expand Up @@ -719,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)
Expand Down
37 changes: 37 additions & 0 deletions linear_algebra/lanczos_algorithm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import numpy as np


def lanczos(a: np.ndarray) -> tuple[list[float], list[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))
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]))
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
60 changes: 60 additions & 0 deletions maths/polynomials/legendre.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from numpy.polynomial import Polynomial
from math import factorial
import pytest


def legendre(n: int) -> list[float]:

Check failure on line 6 in maths/polynomials/legendre.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (I001)

maths/polynomials/legendre.py:1:1: I001 Import block is un-sorted or un-formatted
"""
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]"

Check failure on line 45 in maths/polynomials/legendre.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

maths/polynomials/legendre.py:45:89: E501 Line too long (100 > 88)


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]"

Check failure on line 50 in maths/polynomials/legendre.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

maths/polynomials/legendre.py:50:89: E501 Line too long (110 > 88)


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()
Loading