From 8f314e99c603e360896ef6405c9a4556009059d0 Mon Sep 17 00:00:00 2001 From: Jay Prajapati Date: Sun, 13 Oct 2024 02:48:54 +0530 Subject: [PATCH 1/4] [Add] Kronecker Product --- matrix/kronecker_product.py | 75 +++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 matrix/kronecker_product.py diff --git a/matrix/kronecker_product.py b/matrix/kronecker_product.py new file mode 100644 index 000000000..fe31026f1 --- /dev/null +++ b/matrix/kronecker_product.py @@ -0,0 +1,75 @@ +# @Author : jay2219 +# @File : kronecker_product.py +# @Date : 13/10/2024 + +""" +Perform Kronecker product of two matrices. +https://en.wikipedia.org/wiki/Kronecker_product +""" + + +def is_2d(matrix: list[list[int]]) -> bool: + """ + >>> is_2d([]) + True + >>> is_2d([1, 2]) + False + >>> is_2d([[1, 2], [3, 4]]) + True + """ + + return all(isinstance(matrix, list) and (isinstance(i, list) for i in matrix)) + + +def kronecker_product( + matrix_a: list[list[int]], matrix_b: list[list[int]] +) -> list[list[int]]: + """ + :param matrix_a: A 2-D Matrix with dimension m x n + :param matrix_b: Another 2-D Matrix with dimension p x q + :return: Result of matrix_a ⊗ matrix_b + :raises ValueError: If the matrices are not 2-D. + + >>> kronecker_product([[1, 2]], [[5, 6], [7, 8]]) + [[5, 6, 10, 12], [7, 8, 14, 16]] + + >>> kronecker_product([[1, 2, 3], [4, 5, 6]], [[5, 6], [7, 8]]) + [[5, 6, 10, 12, 15, 18], [7, 8, 14, 16, 21, 24], [20, 24, 25, 30, 30, 36], [28, 32, 35, 40, 42, 48]] + + >>> kronecker_product([1, 2], [[5, 6], [7, 8]]) + Traceback (most recent call last): + ... + ValueError: Input matrices must be 2-D. + """ + + # Check if the input matrices are valid + if not all((is_2d(matrix_a), is_2d(matrix_b))): + raise ValueError("Input matrices must be 2-D.") + + if not matrix_a or not matrix_b: + return [] + + rows_matrix_a, cols_matrix_a = len(matrix_a), len(matrix_a[0]) + rows_matrix_b, cols_matrix_b = len(matrix_b), len(matrix_b[0]) + + # Resultant matrix dimensions + result = [ + [0] * (cols_matrix_a * cols_matrix_b) + for _ in range(rows_matrix_a * rows_matrix_b) + ] + + for r_index_a in range(rows_matrix_a): + for c_index_a in range(cols_matrix_a): + for r_index_b in range(rows_matrix_b): + for c_index_b in range(cols_matrix_b): + result[r_index_a * rows_matrix_b + r_index_b][ + c_index_a * cols_matrix_b + c_index_b + ] = ( + matrix_a[r_index_a][c_index_a] * matrix_b[r_index_b][c_index_b] + ) + + return result + +if __name__ == "__main__": + import doctest + doctest.testmod() From 370d5fdcd3cc9693ef1740604b9dd27040cb2652 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 12 Oct 2024 21:23:23 +0000 Subject: [PATCH 2/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- matrix/kronecker_product.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/matrix/kronecker_product.py b/matrix/kronecker_product.py index fe31026f1..81b234c6b 100644 --- a/matrix/kronecker_product.py +++ b/matrix/kronecker_product.py @@ -64,12 +64,12 @@ def kronecker_product( for c_index_b in range(cols_matrix_b): result[r_index_a * rows_matrix_b + r_index_b][ c_index_a * cols_matrix_b + c_index_b - ] = ( - matrix_a[r_index_a][c_index_a] * matrix_b[r_index_b][c_index_b] - ) + ] = matrix_a[r_index_a][c_index_a] * matrix_b[r_index_b][c_index_b] return result + if __name__ == "__main__": import doctest + doctest.testmod() From 16124fc63cc1ea1fe0e8585004c8ea90e8b84da5 Mon Sep 17 00:00:00 2001 From: Jay Prajapati Date: Sun, 13 Oct 2024 03:08:08 +0530 Subject: [PATCH 3/4] fix: failed tests --- matrix/kronecker_product.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/matrix/kronecker_product.py b/matrix/kronecker_product.py index 81b234c6b..9504f216f 100644 --- a/matrix/kronecker_product.py +++ b/matrix/kronecker_product.py @@ -33,8 +33,8 @@ def kronecker_product( >>> kronecker_product([[1, 2]], [[5, 6], [7, 8]]) [[5, 6, 10, 12], [7, 8, 14, 16]] - >>> kronecker_product([[1, 2, 3], [4, 5, 6]], [[5, 6], [7, 8]]) - [[5, 6, 10, 12, 15, 18], [7, 8, 14, 16, 21, 24], [20, 24, 25, 30, 30, 36], [28, 32, 35, 40, 42, 48]] + >>> kronecker_product([[1, 2], [4, 5]], [[5, 6], [7, 8]]) + [[5, 6, 10, 12], [7, 8, 14, 16], [20, 24, 25, 30], [28, 32, 35, 40]] >>> kronecker_product([1, 2], [[5, 6], [7, 8]]) Traceback (most recent call last): @@ -64,7 +64,9 @@ def kronecker_product( for c_index_b in range(cols_matrix_b): result[r_index_a * rows_matrix_b + r_index_b][ c_index_a * cols_matrix_b + c_index_b - ] = matrix_a[r_index_a][c_index_a] * matrix_b[r_index_b][c_index_b] + ] = ( + matrix_a[r_index_a][c_index_a] * matrix_b[r_index_b][c_index_b] + ) return result From 658c48493b7097bb51552ebb10ce76c4c5ea00af Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 12 Oct 2024 21:38:47 +0000 Subject: [PATCH 4/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- matrix/kronecker_product.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/matrix/kronecker_product.py b/matrix/kronecker_product.py index 9504f216f..f7c0e70f3 100644 --- a/matrix/kronecker_product.py +++ b/matrix/kronecker_product.py @@ -64,9 +64,7 @@ def kronecker_product( for c_index_b in range(cols_matrix_b): result[r_index_a * rows_matrix_b + r_index_b][ c_index_a * cols_matrix_b + c_index_b - ] = ( - matrix_a[r_index_a][c_index_a] * matrix_b[r_index_b][c_index_b] - ) + ] = matrix_a[r_index_a][c_index_a] * matrix_b[r_index_b][c_index_b] return result