Skip to content

Commit c3d1ff0

Browse files
eviltyphacclaussgithub-actionspoyea
authored
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 <[email protected]> * updating DIRECTORY.md * Update arithmetic_analysis/jacobi_iteration_method.py Co-authored-by: Christian Clauss <[email protected]> * Update arithmetic_analysis/jacobi_iteration_method.py Co-authored-by: Christian Clauss <[email protected]> * Update arithmetic_analysis/jacobi_iteration_method.py Co-authored-by: Christian Clauss <[email protected]> * Update arithmetic_analysis/jacobi_iteration_method.py Co-authored-by: Christian Clauss <[email protected]> * Update arithmetic_analysis/jacobi_iteration_method.py Co-authored-by: Christian Clauss <[email protected]> * Update arithmetic_analysis/jacobi_iteration_method.py Co-authored-by: Christian Clauss <[email protected]> * Update jacobi_iteration_method.py * Update jacobi_iteration_method.py * Update jacobi_iteration_method.py * fix styles Co-authored-by: Christian Clauss <[email protected]> Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Co-authored-by: John Law <[email protected]>
1 parent 0b8d6d7 commit c3d1ff0

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed

Diff for: DIRECTORY.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* [Gaussian Elimination](https://github.com/TheAlgorithms/Python/blob/master/arithmetic_analysis/gaussian_elimination.py)
55
* [In Static Equilibrium](https://github.com/TheAlgorithms/Python/blob/master/arithmetic_analysis/in_static_equilibrium.py)
66
* [Intersection](https://github.com/TheAlgorithms/Python/blob/master/arithmetic_analysis/intersection.py)
7+
* [Jacobi Iteration Method](https://github.com/TheAlgorithms/Python/blob/master/arithmetic_analysis/jacobi_iteration_method.py)
78
* [Lu Decomposition](https://github.com/TheAlgorithms/Python/blob/master/arithmetic_analysis/lu_decomposition.py)
89
* [Newton Forward Interpolation](https://github.com/TheAlgorithms/Python/blob/master/arithmetic_analysis/newton_forward_interpolation.py)
910
* [Newton Method](https://github.com/TheAlgorithms/Python/blob/master/arithmetic_analysis/newton_method.py)

Diff for: arithmetic_analysis/jacobi_iteration_method.py

+163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
"""
2+
Jacobi Iteration Method - https://en.wikipedia.org/wiki/Jacobi_method
3+
"""
4+
from __future__ import annotations
5+
6+
import numpy as np
7+
8+
9+
# Method to find solution of system of linear equations
10+
def jacobi_iteration_method(
11+
coefficient_matrix: np.ndarray,
12+
constant_matrix: np.ndarray,
13+
init_val: list,
14+
iterations: int,
15+
) -> list[float]:
16+
"""
17+
Jacobi Iteration Method:
18+
An iterative algorithm to determine the solutions of strictly diagonally dominant
19+
system of linear equations
20+
21+
4x1 + x2 + x3 = 2
22+
x1 + 5x2 + 2x3 = -6
23+
x1 + 2x2 + 4x3 = -4
24+
25+
x_init = [0.5, -0.5 , -0.5]
26+
27+
Examples:
28+
29+
>>> coefficient = np.array([[4, 1, 1], [1, 5, 2], [1, 2, 4]])
30+
>>> constant = np.array([[2], [-6], [-4]])
31+
>>> init_val = [0.5, -0.5, -0.5]
32+
>>> iterations = 3
33+
>>> jacobi_iteration_method(coefficient, constant, init_val, iterations)
34+
[0.909375, -1.14375, -0.7484375]
35+
36+
37+
>>> coefficient = np.array([[4, 1, 1], [1, 5, 2]])
38+
>>> constant = np.array([[2], [-6], [-4]])
39+
>>> init_val = [0.5, -0.5, -0.5]
40+
>>> iterations = 3
41+
>>> jacobi_iteration_method(coefficient, constant, init_val, iterations)
42+
Traceback (most recent call last):
43+
...
44+
ValueError: Coefficient matrix dimensions must be nxn but received 2x3
45+
46+
>>> coefficient = np.array([[4, 1, 1], [1, 5, 2], [1, 2, 4]])
47+
>>> constant = np.array([[2], [-6]])
48+
>>> init_val = [0.5, -0.5, -0.5]
49+
>>> iterations = 3
50+
>>> jacobi_iteration_method(coefficient, constant, init_val, iterations)
51+
Traceback (most recent call last):
52+
...
53+
ValueError: Coefficient and constant matrices dimensions must be nxn and nx1 but
54+
received 3x3 and 2x1
55+
56+
>>> coefficient = np.array([[4, 1, 1], [1, 5, 2], [1, 2, 4]])
57+
>>> constant = np.array([[2], [-6], [-4]])
58+
>>> init_val = [0.5, -0.5]
59+
>>> iterations = 3
60+
>>> jacobi_iteration_method(coefficient, constant, init_val, iterations)
61+
Traceback (most recent call last):
62+
...
63+
ValueError: Number of initial values must be equal to number of rows in coefficient
64+
matrix but received 2 and 3
65+
66+
>>> coefficient = np.array([[4, 1, 1], [1, 5, 2], [1, 2, 4]])
67+
>>> constant = np.array([[2], [-6], [-4]])
68+
>>> init_val = [0.5, -0.5, -0.5]
69+
>>> iterations = 0
70+
>>> jacobi_iteration_method(coefficient, constant, init_val, iterations)
71+
Traceback (most recent call last):
72+
...
73+
ValueError: Iterations must be at least 1
74+
"""
75+
76+
rows1, cols1 = coefficient_matrix.shape
77+
rows2, cols2 = constant_matrix.shape
78+
79+
if rows1 != cols1:
80+
raise ValueError(
81+
f"Coefficient matrix dimensions must be nxn but received {rows1}x{cols1}"
82+
)
83+
84+
if cols2 != 1:
85+
raise ValueError(f"Constant matrix must be nx1 but received {rows2}x{cols2}")
86+
87+
if rows1 != rows2:
88+
raise ValueError(
89+
f"""Coefficient and constant matrices dimensions must be nxn and nx1 but
90+
received {rows1}x{cols1} and {rows2}x{cols2}"""
91+
)
92+
93+
if len(init_val) != rows1:
94+
raise ValueError(
95+
f"""Number of initial values must be equal to number of rows in coefficient
96+
matrix but received {len(init_val)} and {rows1}"""
97+
)
98+
99+
if iterations <= 0:
100+
raise ValueError("Iterations must be at least 1")
101+
102+
table = np.concatenate((coefficient_matrix, constant_matrix), axis=1)
103+
104+
rows, cols = table.shape
105+
106+
strictly_diagonally_dominant(table)
107+
108+
# Iterates the whole matrix for given number of times
109+
for i in range(iterations):
110+
new_val = []
111+
for row in range(rows):
112+
temp = 0
113+
for col in range(cols):
114+
if col == row:
115+
denom = table[row][col]
116+
elif col == cols - 1:
117+
val = table[row][col]
118+
else:
119+
temp += (-1) * table[row][col] * init_val[col]
120+
temp = (temp + val) / denom
121+
new_val.append(temp)
122+
init_val = new_val
123+
124+
return [float(i) for i in new_val]
125+
126+
127+
# Checks if the given matrix is strictly diagonally dominant
128+
def strictly_diagonally_dominant(table: np.ndarray) -> bool:
129+
"""
130+
>>> table = np.array([[4, 1, 1, 2], [1, 5, 2, -6], [1, 2, 4, -4]])
131+
>>> strictly_diagonally_dominant(table)
132+
True
133+
134+
>>> table = np.array([[4, 1, 1, 2], [1, 5, 2, -6], [1, 2, 3, -4]])
135+
>>> strictly_diagonally_dominant(table)
136+
Traceback (most recent call last):
137+
...
138+
ValueError: Coefficient matrix is not strictly diagonally dominant
139+
"""
140+
141+
rows, cols = table.shape
142+
143+
is_diagonally_dominant = True
144+
145+
for i in range(0, rows):
146+
sum = 0
147+
for j in range(0, cols - 1):
148+
if i == j:
149+
continue
150+
else:
151+
sum += table[i][j]
152+
153+
if table[i][i] <= sum:
154+
raise ValueError("Coefficient matrix is not strictly diagonally dominant")
155+
156+
return is_diagonally_dominant
157+
158+
159+
# Test Cases
160+
if __name__ == "__main__":
161+
import doctest
162+
163+
doctest.testmod()

0 commit comments

Comments
 (0)