Skip to content

Add matrix_multiplication #10045

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 94 commits into from
Oct 17, 2023
Merged
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
7672d1a
added laplacian_filter file
ojas-wani Oct 5, 2023
642af23
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 5, 2023
5e6100c
updated laplacian.py
ojas-wani Oct 5, 2023
3819098
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 5, 2023
5a5a84d
updated laplacian_py
ojas-wani Oct 5, 2023
2cbbe3a
Merge branch 'laplacian-filter' of https://github.com/ojas-wani/Pytho…
ojas-wani Oct 5, 2023
f233a54
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 5, 2023
19a7879
updated laplacian_filter.py
ojas-wani Oct 5, 2023
d8040f5
Merge branch 'laplacian-filter' of https://github.com/ojas-wani/Pytho…
ojas-wani Oct 5, 2023
6c5b418
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 5, 2023
ea541e6
updated laplacian_filter.py
ojas-wani Oct 5, 2023
86dc5a9
Merge branch 'laplacian-filter' of https://github.com/ojas-wani/Pytho…
ojas-wani Oct 5, 2023
de92d3d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 5, 2023
8325b64
updated laplacian_filter.py
ojas-wani Oct 5, 2023
e6fda58
Merge branch 'laplacian-filter' of https://github.com/ojas-wani/Pytho…
ojas-wani Oct 5, 2023
cccf2a9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 5, 2023
5f9331a
required changes to laplacian file
ojas-wani Oct 5, 2023
35f8b7a
changed laplacian_filter.py
ojas-wani Oct 5, 2023
aa0da39
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 5, 2023
d451d62
changed laplacian_filter.py
ojas-wani Oct 5, 2023
dabd6c9
Merge branch 'laplacian-filter' of https://github.com/ojas-wani/Pytho…
ojas-wani Oct 5, 2023
4a118f3
changed laplacian_filter.py
ojas-wani Oct 5, 2023
39b3363
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 5, 2023
8656afd
changed laplacian_filter.py
ojas-wani Oct 5, 2023
552a873
Merge branch 'laplacian-filter' of https://github.com/ojas-wani/Pytho…
ojas-wani Oct 5, 2023
641c063
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 5, 2023
2fd6024
changed laplacian_filter.py
ojas-wani Oct 5, 2023
667055a
changed laplacian_filter.py
ojas-wani Oct 5, 2023
0d83b21
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 5, 2023
2af89bc
updated laplacian_filter.py
ojas-wani Oct 5, 2023
b2e2308
Merge branch 'laplacian-filter' of https://github.com/ojas-wani/Pytho…
ojas-wani Oct 5, 2023
1c72a65
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 5, 2023
0ce40a2
update laplacian_filter.py
ojas-wani Oct 5, 2023
34942b3
Merge branch 'laplacian-filter' of https://github.com/ojas-wani/Pytho…
ojas-wani Oct 5, 2023
891da5e
update laplacian_filter.py
ojas-wani Oct 5, 2023
f52f3b5
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 5, 2023
24d265b
update laplacian_filter.py
ojas-wani Oct 5, 2023
435efe6
changed laplacian_filter.py
ojas-wani Oct 5, 2023
e36fa6a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 5, 2023
84c0273
changed laplacian_filter.py
ojas-wani Oct 5, 2023
9550244
Merge branch 'laplacian-filter' of https://github.com/ojas-wani/Pytho…
ojas-wani Oct 5, 2023
3718979
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 5, 2023
e30c558
changed laplacian_filter.py
ojas-wani Oct 5, 2023
5824fcb
Merge branch 'laplacian-filter' of https://github.com/ojas-wani/Pytho…
ojas-wani Oct 5, 2023
1bcbd84
changed laplacian_filter.py
ojas-wani Oct 5, 2023
532e385
changed laplacian_filter.py
ojas-wani Oct 5, 2023
b1b6219
add matrix_multiplication.py
ojas-wani Oct 7, 2023
84adad8
Merge branch 'master' into laplacian-filter
ojas-wani Oct 7, 2023
44cd487
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 7, 2023
ab314c6
update matrix_multiplication
ojas-wani Oct 7, 2023
2cf9090
update matrix_multiplication
ojas-wani Oct 7, 2023
2e4151c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 7, 2023
9765fea
make changes
ojas-wani Oct 7, 2023
fbe1dfc
Merge branch 'laplacian-filter' of https://github.com/ojas-wani/Pytho…
ojas-wani Oct 7, 2023
8bd1970
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 7, 2023
2502119
update
ojas-wani Oct 7, 2023
37a5dab
Merge branch 'laplacian-filter' of https://github.com/ojas-wani/Pytho…
ojas-wani Oct 7, 2023
909331b
update
ojas-wani Oct 7, 2023
e05b524
updates
ojas-wani Oct 7, 2023
39d0871
resolve conflict
ojas-wani Oct 7, 2023
5203d8b
add doctest
ojas-wani Oct 7, 2023
620ba2c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 7, 2023
c6c5cfd
make changes
ojas-wani Oct 7, 2023
aa7e917
Merge branch 'laplacian-filter' of https://github.com/ojas-wani/Pytho…
ojas-wani Oct 7, 2023
8bfeeb2
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 7, 2023
bf6d95a
update laplacian.py
ojas-wani Oct 7, 2023
e42fafc
add doctests
ojas-wani Oct 7, 2023
d87b51f
more doctest added
ojas-wani Oct 7, 2023
ac92bef
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 7, 2023
1422b87
try to resolve ruff error
ojas-wani Oct 7, 2023
21f6956
try to reslve ruff error
ojas-wani Oct 7, 2023
f4db7d9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 7, 2023
cc0b4aa
update doctest
ojas-wani Oct 7, 2023
22c19e3
Merge branch 'laplacian-filter' of https://github.com/ojas-wani/Pytho…
ojas-wani Oct 7, 2023
d4e7c77
attemp - resolve ruff error
ojas-wani Oct 7, 2023
057a2b4
resolve build error
ojas-wani Oct 7, 2023
7340528
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 7, 2023
8ef6244
resolve build issue
ojas-wani Oct 7, 2023
9d8c6f1
Merge branch 'laplacian-filter' of https://github.com/ojas-wani/Pytho…
ojas-wani Oct 7, 2023
9a486c9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 7, 2023
306bba0
update build
ojas-wani Oct 7, 2023
09674b1
doctest update
ojas-wani Oct 7, 2023
09aca9f
update doctest
ojas-wani Oct 7, 2023
7b31464
update doctest
ojas-wani Oct 7, 2023
46837d0
update doctest
ojas-wani Oct 7, 2023
87e37dd
fix ruff error
ojas-wani Oct 7, 2023
5a044dd
file location changed
ojas-wani Oct 8, 2023
d7fc696
Delete digital_image_processing/filters/laplacian_filter.py
cclauss Oct 8, 2023
5650d8b
Create laplacian_filter.py
cclauss Oct 17, 2023
a3052c2
Update matrix_multiplication_recursion.py
cclauss Oct 17, 2023
7d28a5c
Update matrix_multiplication_recursion.py
cclauss Oct 17, 2023
b72b27f
Update matrix_multiplication_recursion.py
cclauss Oct 17, 2023
25131f6
Update matrix_multiplication_recursion.py
cclauss Oct 17, 2023
278149b
Update matrix_multiplication_recursion.py
cclauss Oct 17, 2023
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
180 changes: 180 additions & 0 deletions matrix/matrix_multiplication_recursion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# @Author : ojas-wani
# @File : matrix_multiplication_recursion.py
# @Date : 10/06/2023


"""
Perform matrix multiplication using a recursive algorithm.
https://en.wikipedia.org/wiki/Matrix_multiplication
"""
# type Matrix = list[list[int]] # psf/black currenttly fails on this line
Matrix = list[list[int]]

Choose a reason for hiding this comment

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

Variable and function names should follow the snake_case naming convention. Please update the following name accordingly: Matrix

Choose a reason for hiding this comment

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

Variable and function names should follow the snake_case naming convention. Please update the following name accordingly: Matrix


matrix_1_to_4 = [
[1, 2],
[3, 4],
]

matrix_5_to_8 = [
[5, 6],
[7, 8],
]

matrix_5_to_9_high = [
[5, 6],
[7, 8],
[9],
]

matrix_5_to_9_wide = [
[5, 6],
[7, 8, 9],
]

matrix_count_up = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
]

matrix_unordered = [
[5, 8, 1, 2],
[6, 7, 3, 0],
[4, 5, 9, 1],
[2, 6, 10, 14],
]
matrices = (
matrix_1_to_4,
matrix_5_to_8,
matrix_5_to_9_high,
matrix_5_to_9_wide,
matrix_count_up,
matrix_unordered,
)


def is_square(matrix: Matrix) -> bool:
"""
>>> is_square([])
True
>>> is_square(matrix_1_to_4)
True
>>> is_square(matrix_5_to_9_high)
False
"""
len_matrix = len(matrix)
return all(len(row) == len_matrix for row in matrix)


def matrix_multiply(matrix_a: Matrix, matrix_b: Matrix) -> Matrix:
"""
>>> matrix_multiply(matrix_1_to_4, matrix_5_to_8)
[[19, 22], [43, 50]]
"""
return [
[sum(a * b for a, b in zip(row, col)) for col in zip(*matrix_b)]
for row in matrix_a
]


def matrix_multiply_recursive(matrix_a: Matrix, matrix_b: Matrix) -> Matrix:
"""
:param matrix_a: A square Matrix.
:param matrix_b: Another square Matrix with the same dimensions as matrix_a.
:return: Result of matrix_a * matrix_b.
:raises ValueError: If the matrices cannot be multiplied.

>>> matrix_multiply_recursive([], [])
[]
>>> matrix_multiply_recursive(matrix_1_to_4, matrix_5_to_8)
[[19, 22], [43, 50]]
>>> matrix_multiply_recursive(matrix_count_up, matrix_unordered)
[[37, 61, 74, 61], [105, 165, 166, 129], [173, 269, 258, 197], [241, 373, 350, 265]]
>>> matrix_multiply_recursive(matrix_1_to_4, matrix_5_to_9_wide)
Traceback (most recent call last):
...
ValueError: Invalid matrix dimensions
>>> matrix_multiply_recursive(matrix_1_to_4, matrix_5_to_9_high)
Traceback (most recent call last):
...
ValueError: Invalid matrix dimensions
>>> matrix_multiply_recursive(matrix_1_to_4, matrix_count_up)
Traceback (most recent call last):
...
ValueError: Invalid matrix dimensions
"""
if not matrix_a or not matrix_b:
return []
if not all(
(len(matrix_a) == len(matrix_b), is_square(matrix_a), is_square(matrix_b))
):
raise ValueError("Invalid matrix dimensions")

# Initialize the result matrix with zeros
result = [[0] * len(matrix_b[0]) for _ in range(len(matrix_a))]

# Recursive multiplication of matrices
def multiply(
i_loop: int,
j_loop: int,
k_loop: int,
matrix_a: Matrix,
matrix_b: Matrix,
result: Matrix,
) -> None:
"""
:param matrix_a: A square Matrix.
:param matrix_b: Another square Matrix with the same dimensions as matrix_a.
:param result: Result matrix
:param i: Index used for iteration during multiplication.
:param j: Index used for iteration during multiplication.
:param k: Index used for iteration during multiplication.
>>> 0 > 1 # Doctests in inner functions are never run
True
"""
if i_loop >= len(matrix_a):
return
if j_loop >= len(matrix_b[0]):
return multiply(i_loop + 1, 0, 0, matrix_a, matrix_b, result)
if k_loop >= len(matrix_b):
return multiply(i_loop, j_loop + 1, 0, matrix_a, matrix_b, result)
result[i_loop][j_loop] += matrix_a[i_loop][k_loop] * matrix_b[k_loop][j_loop]
return multiply(i_loop, j_loop, k_loop + 1, matrix_a, matrix_b, result)

# Perform the recursive matrix multiplication
multiply(0, 0, 0, matrix_a, matrix_b, result)
return result


if __name__ == "__main__":
from doctest import testmod

failure_count, test_count = testmod()
if not failure_count:
matrix_a = matrices[0]
for matrix_b in matrices[1:]:
print("Multiplying:")
for row in matrix_a:
print(row)
print("By:")
for row in matrix_b:
print(row)
print("Result:")
try:
result = matrix_multiply_recursive(matrix_a, matrix_b)
for row in result:
print(row)
assert result == matrix_multiply(matrix_a, matrix_b)
except ValueError as e:
print(f"{e!r}")
print()
matrix_a = matrix_b

print("Benchmark:")
from functools import partial
from timeit import timeit

mytimeit = partial(timeit, globals=globals(), number=100_000)
for func in ("matrix_multiply", "matrix_multiply_recursive"):
print(f"{func:>25}(): {mytimeit(f'{func}(matrix_count_up, matrix_unordered)')}")