Skip to content

jacobi_iteration_method.py the use of vector operations, which reduces the calculation time by dozens of times #8938

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Sep 11, 2023
Merged
Changes from 9 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
33 changes: 31 additions & 2 deletions arithmetic_analysis/jacobi_iteration_method.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
def jacobi_iteration_method(
coefficient_matrix: NDArray[float64],
constant_matrix: NDArray[float64],
init_val: list[int],
init_val: list[float],
iterations: int,
) -> list[float]:
"""
Expand Down Expand Up @@ -115,6 +115,20 @@ def jacobi_iteration_method(

strictly_diagonally_dominant(table)

"""
denom - a list of values along the diagonal
val - values of the last column of the table array

masks - boolean mask of all strings without diagonal
elements array coefficient_matrix

ttt - coefficient_matrix array values without diagonal elements
ind - column indexes for each row without diagonal elements
arr - list obtained by column indexes from the list init_val
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There shouldn't be such a long comment in the middle of the algorithm. Instead of writing a block comment explaining what each variable does, why not just make the variable names clearer? You could also just add comments to individual lines.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected.
Double - At the very bottom, I wrote about performance tests with a large array (answered your message).


the code below uses vectorized operations based on
the previous algorithm on loopss:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why comment out the old code? Why not just delete it?

Copy link
Contributor Author

@quant12345 quant12345 Aug 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected.

At the very bottom, I wrote about performance tests with a large array (answered your message).

Copy link
Contributor Author

@quant12345 quant12345 Aug 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just in case, I am attaching the jacobi_simple_two.py file, in which you can run the algorithms once by specifying the array size n = 256 # array size 'coefficient_matrix'. I am attaching data for array sizes of 256 and 500 and the difference only increases 54 and 56 times faster.

n = 256 # array size 'coefficient_matrix'

time_old 0:00:14.445305
time_new 0:00:00.264163
difference in time 54.68469389300262
True

n = 500 # array size 'coefficient_matrix'

time_old 0:01:53.208590
time_new 0:00:01.997707
difference in time 56.66922360714822

Yes, with 'coefficient_matrix' 1000 x 1000 the difference is reduced, but it's still huge. At the same time, the calculation time of the old algorithm is almost 13 minutes. And if you make an array of 2000 x 2000, then the old calculation time of the old algorithm will be approximately: two hours. Need more proof?

n = 1000 # array size 'coefficient_matrix'

time_old 0:12:53.569692
time_new 0:00:17.256253
difference in time 44.828392841454956

jacobi_simple_two.py.tar.gz


# Iterates the whole matrix for given number of times
for _ in range(iterations):
new_val = []
Expand All @@ -130,8 +144,23 @@ def jacobi_iteration_method(
temp = (temp + val) / denom
new_val.append(temp)
init_val = new_val
"""

denom = np.diag(coefficient_matrix)
val = table[:, -1]
masks = ~np.eye(coefficient_matrix.shape[0], dtype=bool)
ttt = coefficient_matrix[masks].reshape(-1, rows - 1)
i_row, i_col = np.where(masks)
ind = i_col.reshape(-1, rows - 1)

# Iterates the whole matrix for given number of times
for _ in range(iterations):
arr = np.take(init_val, ind)
temp = np.sum((-1) * ttt * arr, axis=1)
new_val = (temp + val) / denom
init_val = new_val

return [float(i) for i in new_val]
return new_val.tolist()


# Checks if the given matrix is strictly diagonally dominant
Expand Down