mirror of
https://hub.njuu.cf/TheAlgorithms/Python.git
synced 2023-10-11 13:06:12 +08:00
Add Jacobi Iteration Method (#5113)
* Added Jacobi Iteration Method Added this method in arithmetic_analysis folder. This method is used to solve system of linear equations. * Added comments * Added reference link * Update jacobi_iteration_method.py * Changes for codespell test * Update jacobi_iteration_method.py * Update jacobi_iteration_method.py * Update arithmetic_analysis/jacobi_iteration_method.py Co-authored-by: Christian Clauss <cclauss@me.com> * updating DIRECTORY.md * Update arithmetic_analysis/jacobi_iteration_method.py Co-authored-by: Christian Clauss <cclauss@me.com> * Update arithmetic_analysis/jacobi_iteration_method.py Co-authored-by: Christian Clauss <cclauss@me.com> * Update arithmetic_analysis/jacobi_iteration_method.py Co-authored-by: Christian Clauss <cclauss@me.com> * Update arithmetic_analysis/jacobi_iteration_method.py Co-authored-by: Christian Clauss <cclauss@me.com> * Update arithmetic_analysis/jacobi_iteration_method.py Co-authored-by: Christian Clauss <cclauss@me.com> * Update arithmetic_analysis/jacobi_iteration_method.py Co-authored-by: Christian Clauss <cclauss@me.com> * Update jacobi_iteration_method.py * Update jacobi_iteration_method.py * Update jacobi_iteration_method.py * fix styles Co-authored-by: Christian Clauss <cclauss@me.com> Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Co-authored-by: John Law <johnlaw.po@gmail.com>
This commit is contained in:
parent
0b8d6d70ce
commit
c3d1ff0ebd
@ -4,6 +4,7 @@
|
||||
* [Gaussian Elimination](https://github.com/TheAlgorithms/Python/blob/master/arithmetic_analysis/gaussian_elimination.py)
|
||||
* [In Static Equilibrium](https://github.com/TheAlgorithms/Python/blob/master/arithmetic_analysis/in_static_equilibrium.py)
|
||||
* [Intersection](https://github.com/TheAlgorithms/Python/blob/master/arithmetic_analysis/intersection.py)
|
||||
* [Jacobi Iteration Method](https://github.com/TheAlgorithms/Python/blob/master/arithmetic_analysis/jacobi_iteration_method.py)
|
||||
* [Lu Decomposition](https://github.com/TheAlgorithms/Python/blob/master/arithmetic_analysis/lu_decomposition.py)
|
||||
* [Newton Forward Interpolation](https://github.com/TheAlgorithms/Python/blob/master/arithmetic_analysis/newton_forward_interpolation.py)
|
||||
* [Newton Method](https://github.com/TheAlgorithms/Python/blob/master/arithmetic_analysis/newton_method.py)
|
||||
|
163
arithmetic_analysis/jacobi_iteration_method.py
Normal file
163
arithmetic_analysis/jacobi_iteration_method.py
Normal file
@ -0,0 +1,163 @@
|
||||
"""
|
||||
Jacobi Iteration Method - https://en.wikipedia.org/wiki/Jacobi_method
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
# Method to find solution of system of linear equations
|
||||
def jacobi_iteration_method(
|
||||
coefficient_matrix: np.ndarray,
|
||||
constant_matrix: np.ndarray,
|
||||
init_val: list,
|
||||
iterations: int,
|
||||
) -> list[float]:
|
||||
"""
|
||||
Jacobi Iteration Method:
|
||||
An iterative algorithm to determine the solutions of strictly diagonally dominant
|
||||
system of linear equations
|
||||
|
||||
4x1 + x2 + x3 = 2
|
||||
x1 + 5x2 + 2x3 = -6
|
||||
x1 + 2x2 + 4x3 = -4
|
||||
|
||||
x_init = [0.5, -0.5 , -0.5]
|
||||
|
||||
Examples:
|
||||
|
||||
>>> coefficient = np.array([[4, 1, 1], [1, 5, 2], [1, 2, 4]])
|
||||
>>> constant = np.array([[2], [-6], [-4]])
|
||||
>>> init_val = [0.5, -0.5, -0.5]
|
||||
>>> iterations = 3
|
||||
>>> jacobi_iteration_method(coefficient, constant, init_val, iterations)
|
||||
[0.909375, -1.14375, -0.7484375]
|
||||
|
||||
|
||||
>>> coefficient = np.array([[4, 1, 1], [1, 5, 2]])
|
||||
>>> constant = np.array([[2], [-6], [-4]])
|
||||
>>> init_val = [0.5, -0.5, -0.5]
|
||||
>>> iterations = 3
|
||||
>>> jacobi_iteration_method(coefficient, constant, init_val, iterations)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: Coefficient matrix dimensions must be nxn but received 2x3
|
||||
|
||||
>>> coefficient = np.array([[4, 1, 1], [1, 5, 2], [1, 2, 4]])
|
||||
>>> constant = np.array([[2], [-6]])
|
||||
>>> init_val = [0.5, -0.5, -0.5]
|
||||
>>> iterations = 3
|
||||
>>> jacobi_iteration_method(coefficient, constant, init_val, iterations)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: Coefficient and constant matrices dimensions must be nxn and nx1 but
|
||||
received 3x3 and 2x1
|
||||
|
||||
>>> coefficient = np.array([[4, 1, 1], [1, 5, 2], [1, 2, 4]])
|
||||
>>> constant = np.array([[2], [-6], [-4]])
|
||||
>>> init_val = [0.5, -0.5]
|
||||
>>> iterations = 3
|
||||
>>> jacobi_iteration_method(coefficient, constant, init_val, iterations)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: Number of initial values must be equal to number of rows in coefficient
|
||||
matrix but received 2 and 3
|
||||
|
||||
>>> coefficient = np.array([[4, 1, 1], [1, 5, 2], [1, 2, 4]])
|
||||
>>> constant = np.array([[2], [-6], [-4]])
|
||||
>>> init_val = [0.5, -0.5, -0.5]
|
||||
>>> iterations = 0
|
||||
>>> jacobi_iteration_method(coefficient, constant, init_val, iterations)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: Iterations must be at least 1
|
||||
"""
|
||||
|
||||
rows1, cols1 = coefficient_matrix.shape
|
||||
rows2, cols2 = constant_matrix.shape
|
||||
|
||||
if rows1 != cols1:
|
||||
raise ValueError(
|
||||
f"Coefficient matrix dimensions must be nxn but received {rows1}x{cols1}"
|
||||
)
|
||||
|
||||
if cols2 != 1:
|
||||
raise ValueError(f"Constant matrix must be nx1 but received {rows2}x{cols2}")
|
||||
|
||||
if rows1 != rows2:
|
||||
raise ValueError(
|
||||
f"""Coefficient and constant matrices dimensions must be nxn and nx1 but
|
||||
received {rows1}x{cols1} and {rows2}x{cols2}"""
|
||||
)
|
||||
|
||||
if len(init_val) != rows1:
|
||||
raise ValueError(
|
||||
f"""Number of initial values must be equal to number of rows in coefficient
|
||||
matrix but received {len(init_val)} and {rows1}"""
|
||||
)
|
||||
|
||||
if iterations <= 0:
|
||||
raise ValueError("Iterations must be at least 1")
|
||||
|
||||
table = np.concatenate((coefficient_matrix, constant_matrix), axis=1)
|
||||
|
||||
rows, cols = table.shape
|
||||
|
||||
strictly_diagonally_dominant(table)
|
||||
|
||||
# Iterates the whole matrix for given number of times
|
||||
for i in range(iterations):
|
||||
new_val = []
|
||||
for row in range(rows):
|
||||
temp = 0
|
||||
for col in range(cols):
|
||||
if col == row:
|
||||
denom = table[row][col]
|
||||
elif col == cols - 1:
|
||||
val = table[row][col]
|
||||
else:
|
||||
temp += (-1) * table[row][col] * init_val[col]
|
||||
temp = (temp + val) / denom
|
||||
new_val.append(temp)
|
||||
init_val = new_val
|
||||
|
||||
return [float(i) for i in new_val]
|
||||
|
||||
|
||||
# Checks if the given matrix is strictly diagonally dominant
|
||||
def strictly_diagonally_dominant(table: np.ndarray) -> bool:
|
||||
"""
|
||||
>>> table = np.array([[4, 1, 1, 2], [1, 5, 2, -6], [1, 2, 4, -4]])
|
||||
>>> strictly_diagonally_dominant(table)
|
||||
True
|
||||
|
||||
>>> table = np.array([[4, 1, 1, 2], [1, 5, 2, -6], [1, 2, 3, -4]])
|
||||
>>> strictly_diagonally_dominant(table)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: Coefficient matrix is not strictly diagonally dominant
|
||||
"""
|
||||
|
||||
rows, cols = table.shape
|
||||
|
||||
is_diagonally_dominant = True
|
||||
|
||||
for i in range(0, rows):
|
||||
sum = 0
|
||||
for j in range(0, cols - 1):
|
||||
if i == j:
|
||||
continue
|
||||
else:
|
||||
sum += table[i][j]
|
||||
|
||||
if table[i][i] <= sum:
|
||||
raise ValueError("Coefficient matrix is not strictly diagonally dominant")
|
||||
|
||||
return is_diagonally_dominant
|
||||
|
||||
|
||||
# Test Cases
|
||||
if __name__ == "__main__":
|
||||
import doctest
|
||||
|
||||
doctest.testmod()
|
Loading…
Reference in New Issue
Block a user