|
| 1 | +""" |
| 2 | +Kronecker Product of Two Matrices |
| 3 | +Implementation with type hints, doctests, and detailed Big-O complexity analysis. |
| 4 | +Reference: https://en.wikipedia.org/wiki/Kronecker_product |
| 5 | +""" |
| 6 | + |
| 7 | +from __future__ import annotations |
| 8 | + |
| 9 | + |
| 10 | +def kronecker_product( |
| 11 | + matrix_a: list[list[float | int]], matrix_b: list[list[float | int]] |
| 12 | +) -> list[list[float | int]]: |
| 13 | + """ |
| 14 | + Computes the Kronecker product (tensor product) of two matrices A and B. |
| 15 | +
|
| 16 | + If A is an m-by-n matrix and B is a p-by-q matrix, then the Kronecker product |
| 17 | + A (x) B is the (m*p)-by-(n*q) block matrix. |
| 18 | +
|
| 19 | + Time Complexity: O(m * n * p * q) where A is m x n and B is p x q. |
| 20 | + Space Complexity: O(m * n * p * q) for the output block matrix. |
| 21 | +
|
| 22 | + >>> kronecker_product([[1, 2], [3, 4]], [[0, 5], [6, 7]]) |
| 23 | + [[0, 5, 0, 10], [6, 7, 12, 14], [0, 15, 0, 20], [18, 21, 24, 28]] |
| 24 | +
|
| 25 | + >>> kronecker_product([[1, -1]], [[2], [3]]) |
| 26 | + [[2, -2], [3, -3]] |
| 27 | +
|
| 28 | + >>> kronecker_product([[1]], [[5, 6], [7, 8]]) |
| 29 | + [[5, 6], [7, 8]] |
| 30 | +
|
| 31 | + >>> kronecker_product([], [[1, 2]]) |
| 32 | + [] |
| 33 | +
|
| 34 | + >>> kronecker_product([[1, 2]], []) |
| 35 | + [] |
| 36 | + """ |
| 37 | + if not matrix_a or not matrix_b: |
| 38 | + return [] |
| 39 | + |
| 40 | + rows_a = len(matrix_a) |
| 41 | + cols_a = len(matrix_a[0]) |
| 42 | + rows_b = len(matrix_b) |
| 43 | + cols_b = len(matrix_b[0]) |
| 44 | + |
| 45 | + if cols_a == 0 or cols_b == 0: |
| 46 | + return [] |
| 47 | + |
| 48 | + result_rows = rows_a * rows_b |
| 49 | + result_cols = cols_a * cols_b |
| 50 | + result: list[list[float | int]] = [ |
| 51 | + [0 for _ in range(result_cols)] for _ in range(result_rows) |
| 52 | + ] |
| 53 | + |
| 54 | + for i in range(rows_a): |
| 55 | + for j in range(cols_a): |
| 56 | + for k in range(rows_b): |
| 57 | + for l_idx in range(cols_b): |
| 58 | + row_idx = i * rows_b + k |
| 59 | + col_idx = j * cols_b + l_idx |
| 60 | + result[row_idx][col_idx] = matrix_a[i][j] * matrix_b[k][l_idx] |
| 61 | + |
| 62 | + return result |
| 63 | + |
| 64 | + |
| 65 | +if __name__ == "__main__": |
| 66 | + import doctest |
| 67 | + |
| 68 | + doctest.testmod() |
0 commit comments