|
| 1 | +# @Author : jay2219 |
| 2 | +# @File : kronecker_product.py |
| 3 | +# @Date : 13/10/2024 |
| 4 | + |
| 5 | +""" |
| 6 | +Perform Kronecker product of two matrices. |
| 7 | +https://en.wikipedia.org/wiki/Kronecker_product |
| 8 | +""" |
| 9 | + |
| 10 | + |
| 11 | +def is_2d(matrix: list[list[int]]) -> bool: |
| 12 | + """ |
| 13 | + >>> is_2d([]) |
| 14 | + True |
| 15 | + >>> is_2d([1, 2]) |
| 16 | + False |
| 17 | + >>> is_2d([[1, 2], [3, 4]]) |
| 18 | + True |
| 19 | + """ |
| 20 | + |
| 21 | + return all(isinstance(matrix, list) and (isinstance(i, list) for i in matrix)) |
| 22 | + |
| 23 | + |
| 24 | +def kronecker_product( |
| 25 | + matrix_a: list[list[int]], matrix_b: list[list[int]] |
| 26 | +) -> list[list[int]]: |
| 27 | + """ |
| 28 | + :param matrix_a: A 2-D Matrix with dimension m x n |
| 29 | + :param matrix_b: Another 2-D Matrix with dimension p x q |
| 30 | + :return: Result of matrix_a ⊗ matrix_b |
| 31 | + :raises ValueError: If the matrices are not 2-D. |
| 32 | +
|
| 33 | + >>> kronecker_product([[1, 2]], [[5, 6], [7, 8]]) |
| 34 | + [[5, 6, 10, 12], [7, 8, 14, 16]] |
| 35 | +
|
| 36 | + >>> kronecker_product([[1, 2, 3], [4, 5, 6]], [[5, 6], [7, 8]]) |
| 37 | + [[5, 6, 10, 12, 15, 18], [7, 8, 14, 16, 21, 24], [20, 24, 25, 30, 30, 36], [28, 32, 35, 40, 42, 48]] |
| 38 | +
|
| 39 | + >>> kronecker_product([1, 2], [[5, 6], [7, 8]]) |
| 40 | + Traceback (most recent call last): |
| 41 | + ... |
| 42 | + ValueError: Input matrices must be 2-D. |
| 43 | + """ |
| 44 | + |
| 45 | + # Check if the input matrices are valid |
| 46 | + if not all((is_2d(matrix_a), is_2d(matrix_b))): |
| 47 | + raise ValueError("Input matrices must be 2-D.") |
| 48 | + |
| 49 | + if not matrix_a or not matrix_b: |
| 50 | + return [] |
| 51 | + |
| 52 | + rows_matrix_a, cols_matrix_a = len(matrix_a), len(matrix_a[0]) |
| 53 | + rows_matrix_b, cols_matrix_b = len(matrix_b), len(matrix_b[0]) |
| 54 | + |
| 55 | + # Resultant matrix dimensions |
| 56 | + result = [ |
| 57 | + [0] * (cols_matrix_a * cols_matrix_b) |
| 58 | + for _ in range(rows_matrix_a * rows_matrix_b) |
| 59 | + ] |
| 60 | + |
| 61 | + for r_index_a in range(rows_matrix_a): |
| 62 | + for c_index_a in range(cols_matrix_a): |
| 63 | + for r_index_b in range(rows_matrix_b): |
| 64 | + for c_index_b in range(cols_matrix_b): |
| 65 | + result[r_index_a * rows_matrix_b + r_index_b][ |
| 66 | + c_index_a * cols_matrix_b + c_index_b |
| 67 | + ] = ( |
| 68 | + matrix_a[r_index_a][c_index_a] * matrix_b[r_index_b][c_index_b] |
| 69 | + ) |
| 70 | + |
| 71 | + return result |
| 72 | + |
| 73 | +if __name__ == "__main__": |
| 74 | + import doctest |
| 75 | + doctest.testmod() |
0 commit comments