From a342617cac067f04c7b2c178fb06cbbcde733eaa Mon Sep 17 00:00:00 2001 From: wuyudi Date: Thu, 2 Jul 2020 03:50:03 +0000 Subject: [PATCH 01/19] Update matrix_operation.py --- matrix/matrix_operation.py | 89 +++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 31 deletions(-) diff --git a/matrix/matrix_operation.py b/matrix/matrix_operation.py index 307e8b6ba32e..449b9c508b73 100644 --- a/matrix/matrix_operation.py +++ b/matrix/matrix_operation.py @@ -4,36 +4,43 @@ def add(matrix_a, matrix_b): + ''' + >>> add([[1,2],[3,4]],[[2,3],[4,5]]) + [[3, 5], [7, 9]] + ''' if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): rows, cols = _verify_matrix_sizes(matrix_a, matrix_b) - matrix_c = [] - for i in range(rows[0]): - list_1 = [] - for j in range(cols[0]): - val = matrix_a[i][j] + matrix_b[i][j] - list_1.append(val) - matrix_c.append(list_1) + matrix_c = [[matrix_a[i][j] + matrix_b[i][j] + for j in range(cols[0])] for i in range(rows[0])] return matrix_c def subtract(matrix_a, matrix_b): + ''' + >>> subtract([[1,2],[3,4]],[[2,3],[4,5]]) + [[-1, -1], [-1, -1]] + ''' if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): rows, cols = _verify_matrix_sizes(matrix_a, matrix_b) - matrix_c = [] - for i in range(rows[0]): - list_1 = [] - for j in range(cols[0]): - val = matrix_a[i][j] - matrix_b[i][j] - list_1.append(val) - matrix_c.append(list_1) + matrix_c = [ + [matrix_a[i][j] - matrix_b[i][j] for j in range(cols[0])] + for i in range(rows[0])] return matrix_c def scalar_multiply(matrix, n): + ''' + >>> scalar_multiply([[1,2],[3,4]],5) + [[5, 10], [15, 20]] + ''' return [[x * n for x in row] for row in matrix] def multiply(matrix_a, matrix_b): + ''' + >>> multiply([[1,2],[3,4]],[[5,5],[7,5]]) + [[19, 15], [43, 35]] + ''' if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): matrix_c = [] rows, cols = _verify_matrix_sizes(matrix_a, matrix_b) @@ -48,7 +55,7 @@ def multiply(matrix_a, matrix_b): for j in range(cols[1]): val = 0 for k in range(cols[1]): - val = val + matrix_a[i][k] * matrix_b[k][j] + val += matrix_a[i][k] * matrix_b[k][j] list_1.append(val) matrix_c.append(list_1) return matrix_c @@ -59,30 +66,42 @@ def identity(n): :param n: dimension for nxn matrix :type n: int :return: Identity matrix of shape [n, n] + >>> identity(3) + [[1, 0, 0], [0, 1, 0], [0, 0, 1]] """ n = int(n) return [[int(row == column) for column in range(n)] for row in range(n)] def transpose(matrix, return_map=True): + ''' + >>> transpose([[1,2],[3,4]]) # doctest: +ELLIPSIS + >> transpose([[1,2],[3,4]], return_map=False) + [[1, 3], [2, 4]] + ''' if _check_not_integer(matrix): if return_map: return map(list, zip(*matrix)) else: - # mt = [] - # for i in range(len(matrix[0])): - # mt.append([row[i] for row in matrix]) - # return mt return [[row[i] for row in matrix] for i in range(len(matrix[0]))] def minor(matrix, row, column): - minor = matrix[:row] + matrix[row + 1 :] - minor = [row[:column] + row[column + 1 :] for row in minor] + ''' + >>> minor([[1, 2], [3, 4]], 1, 1) + [[1]] + ''' + minor = matrix[:row] + matrix[row + 1:] + minor = [row[:column] + row[column + 1:] for row in minor] return minor def determinant(matrix): + ''' + >>> determinant([[1, 2], [3, 4]]) + -2 + ''' if len(matrix) == 1: return matrix[0][0] @@ -93,11 +112,17 @@ def determinant(matrix): def inverse(matrix): + ''' + >>> inverse([[1, 2], [3, 4]]) + [[-2.0, 1.0], [1.5, -0.5]] + >>> inverse([[1, 1], [1, 1]]) + ''' + # https://stackoverflow.com/questions/20047519/python-doctests-test-for-none det = determinant(matrix) if det == 0: return None - matrix_minor = [[] for _ in range(len(matrix))] + matrix_minor = [[] for _ in matrix] for i in range(len(matrix)): for j in range(len(matrix)): matrix_minor[i].append(determinant(minor(matrix, i, j))) @@ -134,21 +159,23 @@ def _verify_matrix_sizes(matrix_a, matrix_b): def main(): matrix_a = [[12, 10], [3, 9]] matrix_b = [[3, 4], [7, 4]] - matrix_c = [[11, 12, 13, 14], [21, 22, 23, 24], [31, 32, 33, 34], [41, 42, 43, 44]] + matrix_c = [[11, 12, 13, 14], [21, 22, 23, 24], + [31, 32, 33, 34], [41, 42, 43, 44]] matrix_d = [[3, 0, 2], [2, 0, -2], [0, 1, 1]] print( - "Add Operation, %s + %s = %s \n" - % (matrix_a, matrix_b, (add(matrix_a, matrix_b))) + f"Add Operation, {matrix_a} +{matrix_b} = {add(matrix_a, matrix_b)} \n" ) print( - "Multiply Operation, %s * %s = %s \n" - % (matrix_a, matrix_b, multiply(matrix_a, matrix_b)) + f"Multiply Operation, {matrix_a} * {matrix_b}", + f"= {multiply(matrix_a, matrix_b)} \n" ) - print("Identity: %s \n" % identity(5)) - print("Minor of {} = {} \n".format(matrix_c, minor(matrix_c, 1, 2))) - print("Determinant of {} = {} \n".format(matrix_b, determinant(matrix_b))) - print("Inverse of {} = {}\n".format(matrix_d, inverse(matrix_d))) + print(f"Identity: {identity(5)}\n") + print(f"Minor of {matrix_c} = {minor(matrix_c, 1, 2)} \n") + print(f"Determinant of {matrix_b} = {determinant(matrix_b)} \n") + print(f"Inverse of {matrix_d} = {inverse(matrix_d)}\n") if __name__ == "__main__": + import doctest + doctest.testmod() main() From 8817e260a2e0b8a0b2a0a12e143e41965686b345 Mon Sep 17 00:00:00 2001 From: wuyudi Date: Thu, 2 Jul 2020 04:15:14 +0000 Subject: [PATCH 02/19] Update matrix_operation.py --- matrix/matrix_operation.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/matrix/matrix_operation.py b/matrix/matrix_operation.py index 449b9c508b73..f1e832c2815a 100644 --- a/matrix/matrix_operation.py +++ b/matrix/matrix_operation.py @@ -9,9 +9,8 @@ def add(matrix_a, matrix_b): [[3, 5], [7, 9]] ''' if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): - rows, cols = _verify_matrix_sizes(matrix_a, matrix_b) - matrix_c = [[matrix_a[i][j] + matrix_b[i][j] - for j in range(cols[0])] for i in range(rows[0])] + matrix_c = [[i+j for i, j in zip(m, n)] + for m, n in zip(matrix_a, matrix_b)] return matrix_c @@ -21,10 +20,8 @@ def subtract(matrix_a, matrix_b): [[-1, -1], [-1, -1]] ''' if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): - rows, cols = _verify_matrix_sizes(matrix_a, matrix_b) - matrix_c = [ - [matrix_a[i][j] - matrix_b[i][j] for j in range(cols[0])] - for i in range(rows[0])] + matrix_c = [[i-j for i, j in zip(m, n)] + for m, n in zip(matrix_a, matrix_b)] return matrix_c From 0ea57fd5cb44cfe0bae5a9f923ff919061e445a5 Mon Sep 17 00:00:00 2001 From: wuyudi Date: Thu, 2 Jul 2020 04:34:36 +0000 Subject: [PATCH 03/19] Update matrix_operation.py --- matrix/matrix_operation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix/matrix_operation.py b/matrix/matrix_operation.py index f1e832c2815a..eaab9e0e126b 100644 --- a/matrix/matrix_operation.py +++ b/matrix/matrix_operation.py @@ -9,7 +9,7 @@ def add(matrix_a, matrix_b): [[3, 5], [7, 9]] ''' if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): - matrix_c = [[i+j for i, j in zip(m, n)] + matrix_c = [[i + j for i, j in zip(m, n)] for m, n in zip(matrix_a, matrix_b)] return matrix_c @@ -20,7 +20,7 @@ def subtract(matrix_a, matrix_b): [[-1, -1], [-1, -1]] ''' if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): - matrix_c = [[i-j for i, j in zip(m, n)] + matrix_c = [[i - j for i, j in zip(m, n)] for m, n in zip(matrix_a, matrix_b)] return matrix_c From 3f1eee68ceb51678704234108c548a8f396a7a90 Mon Sep 17 00:00:00 2001 From: wuyudi Date: Thu, 2 Jul 2020 04:51:15 +0000 Subject: [PATCH 04/19] use yapf to format the code --- matrix/matrix_operation.py | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/matrix/matrix_operation.py b/matrix/matrix_operation.py index eaab9e0e126b..b41cc0c2c4eb 100644 --- a/matrix/matrix_operation.py +++ b/matrix/matrix_operation.py @@ -45,8 +45,7 @@ def multiply(matrix_a, matrix_b): if cols[0] != rows[1]: raise ValueError( f"Cannot multiply matrix of dimensions ({rows[0]},{cols[0]}) " - f"and ({rows[1]},{cols[1]})" - ) + f"and ({rows[1]},{cols[1]})") for i in range(rows[0]): list_1 = [] for j in range(cols[1]): @@ -104,7 +103,7 @@ def determinant(matrix): res = 0 for x in range(len(matrix)): - res += matrix[0][x] * determinant(minor(matrix, 0, x)) * (-1) ** x + res += matrix[0][x] * determinant(minor(matrix, 0, x)) * (-1)**x return res @@ -124,10 +123,9 @@ def inverse(matrix): for j in range(len(matrix)): matrix_minor[i].append(determinant(minor(matrix, i, j))) - cofactors = [ - [x * (-1) ** (row + col) for col, x in enumerate(matrix_minor[row])] - for row in range(len(matrix)) - ] + cofactors = [[ + x * (-1)**(row + col) for col, x in enumerate(matrix_minor[row]) + ] for row in range(len(matrix))] adjugate = transpose(cofactors) return scalar_multiply(adjugate, 1 / det) @@ -148,24 +146,21 @@ def _verify_matrix_sizes(matrix_a, matrix_b): if shape[0] != shape[2] or shape[1] != shape[3]: raise ValueError( f"operands could not be broadcast together with shape " - f"({shape[0], shape[1]}), ({shape[2], shape[3]})" - ) + f"({shape[0], shape[1]}), ({shape[2], shape[3]})") return [shape[0], shape[2]], [shape[1], shape[3]] def main(): matrix_a = [[12, 10], [3, 9]] matrix_b = [[3, 4], [7, 4]] - matrix_c = [[11, 12, 13, 14], [21, 22, 23, 24], - [31, 32, 33, 34], [41, 42, 43, 44]] + matrix_c = [[11, 12, 13, 14], [21, 22, 23, 24], [31, 32, 33, 34], + [41, 42, 43, 44]] matrix_d = [[3, 0, 2], [2, 0, -2], [0, 1, 1]] print( f"Add Operation, {matrix_a} +{matrix_b} = {add(matrix_a, matrix_b)} \n" ) - print( - f"Multiply Operation, {matrix_a} * {matrix_b}", - f"= {multiply(matrix_a, matrix_b)} \n" - ) + print(f"Multiply Operation, {matrix_a} * {matrix_b}", + f"= {multiply(matrix_a, matrix_b)} \n") print(f"Identity: {identity(5)}\n") print(f"Minor of {matrix_c} = {minor(matrix_c, 1, 2)} \n") print(f"Determinant of {matrix_b} = {determinant(matrix_b)} \n") From 589f967baf946581f70c18e5fe83eba02ca24ba2 Mon Sep 17 00:00:00 2001 From: wuyudi Date: Thu, 2 Jul 2020 05:19:21 +0000 Subject: [PATCH 05/19] recover the error check --- matrix/matrix_operation.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/matrix/matrix_operation.py b/matrix/matrix_operation.py index b41cc0c2c4eb..db6ceb4790ac 100644 --- a/matrix/matrix_operation.py +++ b/matrix/matrix_operation.py @@ -9,6 +9,7 @@ def add(matrix_a, matrix_b): [[3, 5], [7, 9]] ''' if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): + _verify_matrix_sizes(matrix_a, matrix_b) matrix_c = [[i + j for i, j in zip(m, n)] for m, n in zip(matrix_a, matrix_b)] return matrix_c @@ -20,6 +21,7 @@ def subtract(matrix_a, matrix_b): [[-1, -1], [-1, -1]] ''' if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): + _verify_matrix_sizes(matrix_a, matrix_b) matrix_c = [[i - j for i, j in zip(m, n)] for m, n in zip(matrix_a, matrix_b)] return matrix_c @@ -45,7 +47,8 @@ def multiply(matrix_a, matrix_b): if cols[0] != rows[1]: raise ValueError( f"Cannot multiply matrix of dimensions ({rows[0]},{cols[0]}) " - f"and ({rows[1]},{cols[1]})") + f"and ({rows[1]},{cols[1]})" + ) for i in range(rows[0]): list_1 = [] for j in range(cols[1]): @@ -103,7 +106,7 @@ def determinant(matrix): res = 0 for x in range(len(matrix)): - res += matrix[0][x] * determinant(minor(matrix, 0, x)) * (-1)**x + res += matrix[0][x] * determinant(minor(matrix, 0, x)) * (-1) ** x return res @@ -123,9 +126,10 @@ def inverse(matrix): for j in range(len(matrix)): matrix_minor[i].append(determinant(minor(matrix, i, j))) - cofactors = [[ - x * (-1)**(row + col) for col, x in enumerate(matrix_minor[row]) - ] for row in range(len(matrix))] + cofactors = [ + [x * (-1) ** (row + col) for col, x in enumerate(matrix_minor[row])] + for row in range(len(matrix)) + ] adjugate = transpose(cofactors) return scalar_multiply(adjugate, 1 / det) @@ -146,21 +150,24 @@ def _verify_matrix_sizes(matrix_a, matrix_b): if shape[0] != shape[2] or shape[1] != shape[3]: raise ValueError( f"operands could not be broadcast together with shape " - f"({shape[0], shape[1]}), ({shape[2], shape[3]})") + f"({shape[0], shape[1]}), ({shape[2], shape[3]})" + ) return [shape[0], shape[2]], [shape[1], shape[3]] def main(): matrix_a = [[12, 10], [3, 9]] matrix_b = [[3, 4], [7, 4]] - matrix_c = [[11, 12, 13, 14], [21, 22, 23, 24], [31, 32, 33, 34], - [41, 42, 43, 44]] + matrix_c = [[11, 12, 13, 14], [21, 22, 23, 24], + [31, 32, 33, 34], [41, 42, 43, 44]] matrix_d = [[3, 0, 2], [2, 0, -2], [0, 1, 1]] print( f"Add Operation, {matrix_a} +{matrix_b} = {add(matrix_a, matrix_b)} \n" ) - print(f"Multiply Operation, {matrix_a} * {matrix_b}", - f"= {multiply(matrix_a, matrix_b)} \n") + print( + f"Multiply Operation, {matrix_a} * {matrix_b}", + f"= {multiply(matrix_a, matrix_b)} \n" + ) print(f"Identity: {identity(5)}\n") print(f"Minor of {matrix_c} = {minor(matrix_c, 1, 2)} \n") print(f"Determinant of {matrix_b} = {determinant(matrix_b)} \n") From 71d4f1791faffc0fbb0eef97ee4dd234714968d5 Mon Sep 17 00:00:00 2001 From: wuyudi Date: Thu, 2 Jul 2020 05:45:40 +0000 Subject: [PATCH 06/19] add typing hint --- matrix/matrix_operation.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/matrix/matrix_operation.py b/matrix/matrix_operation.py index db6ceb4790ac..8b75e523476d 100644 --- a/matrix/matrix_operation.py +++ b/matrix/matrix_operation.py @@ -2,8 +2,10 @@ function based version of matrix operations, which are just 2D arrays """ +from typing import List, Tuple -def add(matrix_a, matrix_b): + +def add(matrix_a: List[list], matrix_b: List[list]) -> List[list]: ''' >>> add([[1,2],[3,4]],[[2,3],[4,5]]) [[3, 5], [7, 9]] @@ -15,7 +17,7 @@ def add(matrix_a, matrix_b): return matrix_c -def subtract(matrix_a, matrix_b): +def subtract(matrix_a: List[list], matrix_b: List[list]) -> List[list]: ''' >>> subtract([[1,2],[3,4]],[[2,3],[4,5]]) [[-1, -1], [-1, -1]] @@ -27,7 +29,7 @@ def subtract(matrix_a, matrix_b): return matrix_c -def scalar_multiply(matrix, n): +def scalar_multiply(matrix: List[list], n: int) -> List[list]: ''' >>> scalar_multiply([[1,2],[3,4]],5) [[5, 10], [15, 20]] @@ -35,7 +37,7 @@ def scalar_multiply(matrix, n): return [[x * n for x in row] for row in matrix] -def multiply(matrix_a, matrix_b): +def multiply(matrix_a: List[list], matrix_b: List[list]) -> List[list]: ''' >>> multiply([[1,2],[3,4]],[[5,5],[7,5]]) [[19, 15], [43, 35]] @@ -60,7 +62,7 @@ def multiply(matrix_a, matrix_b): return matrix_c -def identity(n): +def identity(n: int) -> List[list]: """ :param n: dimension for nxn matrix :type n: int @@ -72,7 +74,7 @@ def identity(n): return [[int(row == column) for column in range(n)] for row in range(n)] -def transpose(matrix, return_map=True): +def transpose(matrix: List[list], return_map=True) -> List[list]: ''' >>> transpose([[1,2],[3,4]]) # doctest: +ELLIPSIS List[list]: ''' >>> minor([[1, 2], [3, 4]], 1, 1) [[1]] @@ -96,7 +98,7 @@ def minor(matrix, row, column): return minor -def determinant(matrix): +def determinant(matrix: List[list]) -> int: ''' >>> determinant([[1, 2], [3, 4]]) -2 @@ -110,7 +112,7 @@ def determinant(matrix): return res -def inverse(matrix): +def inverse(matrix: List[list]) -> List[list]: ''' >>> inverse([[1, 2], [3, 4]]) [[-2.0, 1.0], [1.5, -0.5]] @@ -134,17 +136,18 @@ def inverse(matrix): return scalar_multiply(adjugate, 1 / det) -def _check_not_integer(matrix): +def _check_not_integer(matrix: List[list]) -> bool: if not isinstance(matrix, int) and not isinstance(matrix[0], int): return True raise TypeError("Expected a matrix, got int/list instead") -def _shape(matrix): +def _shape(matrix: List[list]) -> list: return list((len(matrix), len(matrix[0]))) -def _verify_matrix_sizes(matrix_a, matrix_b): +def _verify_matrix_sizes( + matrix_a: List[list], matrix_b: List[list]) -> Tuple[list]: shape = _shape(matrix_a) shape += _shape(matrix_b) if shape[0] != shape[2] or shape[1] != shape[3]: From 4eea042d38fa15d6d29783cf5905f3931839fba6 Mon Sep 17 00:00:00 2001 From: wuyudi Date: Thu, 2 Jul 2020 14:39:35 +0800 Subject: [PATCH 07/19] Update matrix/matrix_operation.py Co-authored-by: Christian Clauss --- matrix/matrix_operation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix/matrix_operation.py b/matrix/matrix_operation.py index 8b75e523476d..4700843e80f7 100644 --- a/matrix/matrix_operation.py +++ b/matrix/matrix_operation.py @@ -74,7 +74,7 @@ def identity(n: int) -> List[list]: return [[int(row == column) for column in range(n)] for row in range(n)] -def transpose(matrix: List[list], return_map=True) -> List[list]: +def transpose(matrix: List[list], return_map: bool=True) -> List[list]: ''' >>> transpose([[1,2],[3,4]]) # doctest: +ELLIPSIS Date: Thu, 2 Jul 2020 14:39:56 +0800 Subject: [PATCH 08/19] Update matrix/matrix_operation.py Co-authored-by: Christian Clauss --- matrix/matrix_operation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix/matrix_operation.py b/matrix/matrix_operation.py index 4700843e80f7..898060861eaf 100644 --- a/matrix/matrix_operation.py +++ b/matrix/matrix_operation.py @@ -165,7 +165,7 @@ def main(): [31, 32, 33, 34], [41, 42, 43, 44]] matrix_d = [[3, 0, 2], [2, 0, -2], [0, 1, 1]] print( - f"Add Operation, {matrix_a} +{matrix_b} = {add(matrix_a, matrix_b)} \n" + f"Add Operation, {matrix_a} + {matrix_b} = {add(matrix_a, matrix_b)} \n" ) print( f"Multiply Operation, {matrix_a} * {matrix_b}", From 8e632133031f90a0dfe29c3d3dfaba4341ed5258 Mon Sep 17 00:00:00 2001 From: wuyudi Date: Thu, 2 Jul 2020 14:40:07 +0800 Subject: [PATCH 09/19] Update matrix/matrix_operation.py Co-authored-by: Christian Clauss --- matrix/matrix_operation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix/matrix_operation.py b/matrix/matrix_operation.py index 898060861eaf..ec797e3d7e99 100644 --- a/matrix/matrix_operation.py +++ b/matrix/matrix_operation.py @@ -171,7 +171,7 @@ def main(): f"Multiply Operation, {matrix_a} * {matrix_b}", f"= {multiply(matrix_a, matrix_b)} \n" ) - print(f"Identity: {identity(5)}\n") + print(f"Identity: {identity(5)}\n") print(f"Minor of {matrix_c} = {minor(matrix_c, 1, 2)} \n") print(f"Determinant of {matrix_b} = {determinant(matrix_b)} \n") print(f"Inverse of {matrix_d} = {inverse(matrix_d)}\n") From 445f861c3ba587623b02a7493aebc79f9b0b3e1b Mon Sep 17 00:00:00 2001 From: wuyudi Date: Thu, 2 Jul 2020 14:40:17 +0800 Subject: [PATCH 10/19] Update matrix/matrix_operation.py Co-authored-by: Christian Clauss --- matrix/matrix_operation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix/matrix_operation.py b/matrix/matrix_operation.py index ec797e3d7e99..17d6aed610d7 100644 --- a/matrix/matrix_operation.py +++ b/matrix/matrix_operation.py @@ -1,5 +1,5 @@ """ -function based version of matrix operations, which are just 2D arrays +Functions for 2D matrix operations """ from typing import List, Tuple From b620689ec7d4fd1429ef0c5a09412f3cd6b70601 Mon Sep 17 00:00:00 2001 From: wuyudi Date: Thu, 2 Jul 2020 06:54:51 +0000 Subject: [PATCH 11/19] add float doctest --- matrix/matrix_operation.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/matrix/matrix_operation.py b/matrix/matrix_operation.py index 17d6aed610d7..3e9dffa9493e 100644 --- a/matrix/matrix_operation.py +++ b/matrix/matrix_operation.py @@ -9,6 +9,8 @@ def add(matrix_a: List[list], matrix_b: List[list]) -> List[list]: ''' >>> add([[1,2],[3,4]],[[2,3],[4,5]]) [[3, 5], [7, 9]] + >>> add([[1.2,2.4],[3,4]],[[2,3],[4,5]]) + [[3.2, 5.4], [7, 9]] ''' if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): _verify_matrix_sizes(matrix_a, matrix_b) @@ -21,6 +23,8 @@ def subtract(matrix_a: List[list], matrix_b: List[list]) -> List[list]: ''' >>> subtract([[1,2],[3,4]],[[2,3],[4,5]]) [[-1, -1], [-1, -1]] + >>> subtract([[1,2.5],[3,4]],[[2,3],[4,5.5]]) + [[-1, -0.5], [-1, -1.5]] ''' if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): _verify_matrix_sizes(matrix_a, matrix_b) @@ -33,6 +37,8 @@ def scalar_multiply(matrix: List[list], n: int) -> List[list]: ''' >>> scalar_multiply([[1,2],[3,4]],5) [[5, 10], [15, 20]] + >>> scalar_multiply([[1.4,2.3],[3,4]],5) + [[7.0, 11.5], [15, 20]] ''' return [[x * n for x in row] for row in matrix] @@ -41,6 +47,8 @@ def multiply(matrix_a: List[list], matrix_b: List[list]) -> List[list]: ''' >>> multiply([[1,2],[3,4]],[[5,5],[7,5]]) [[19, 15], [43, 35]] + >>> multiply([[1,2.5],[3,4.5]],[[5,5],[7,5]]) + [[22.5, 17.5], [46.5, 37.5]] ''' if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): matrix_c = [] @@ -74,7 +82,7 @@ def identity(n: int) -> List[list]: return [[int(row == column) for column in range(n)] for row in range(n)] -def transpose(matrix: List[list], return_map: bool=True) -> List[list]: +def transpose(matrix: List[list], return_map: bool = True) -> List[list]: ''' >>> transpose([[1,2],[3,4]]) # doctest: +ELLIPSIS int: ''' >>> determinant([[1, 2], [3, 4]]) -2 + >>> determinant([[1.5, 2.5], [3, 4]]) + -1.5 ''' if len(matrix) == 1: return matrix[0][0] From 14a074904426e88466a596f51bee7ed126b30ddf Mon Sep 17 00:00:00 2001 From: vinayak Date: Thu, 2 Jul 2020 14:50:38 +0530 Subject: [PATCH 12/19] black formated --- matrix/matrix_operation.py | 55 +++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/matrix/matrix_operation.py b/matrix/matrix_operation.py index 3e9dffa9493e..5e8eb9ef4bd0 100644 --- a/matrix/matrix_operation.py +++ b/matrix/matrix_operation.py @@ -6,50 +6,48 @@ def add(matrix_a: List[list], matrix_b: List[list]) -> List[list]: - ''' + """ >>> add([[1,2],[3,4]],[[2,3],[4,5]]) [[3, 5], [7, 9]] >>> add([[1.2,2.4],[3,4]],[[2,3],[4,5]]) [[3.2, 5.4], [7, 9]] - ''' + """ if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): _verify_matrix_sizes(matrix_a, matrix_b) - matrix_c = [[i + j for i, j in zip(m, n)] - for m, n in zip(matrix_a, matrix_b)] + matrix_c = [[i + j for i, j in zip(m, n)] for m, n in zip(matrix_a, matrix_b)] return matrix_c def subtract(matrix_a: List[list], matrix_b: List[list]) -> List[list]: - ''' + """ >>> subtract([[1,2],[3,4]],[[2,3],[4,5]]) [[-1, -1], [-1, -1]] >>> subtract([[1,2.5],[3,4]],[[2,3],[4,5.5]]) [[-1, -0.5], [-1, -1.5]] - ''' + """ if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): _verify_matrix_sizes(matrix_a, matrix_b) - matrix_c = [[i - j for i, j in zip(m, n)] - for m, n in zip(matrix_a, matrix_b)] + matrix_c = [[i - j for i, j in zip(m, n)] for m, n in zip(matrix_a, matrix_b)] return matrix_c def scalar_multiply(matrix: List[list], n: int) -> List[list]: - ''' + """ >>> scalar_multiply([[1,2],[3,4]],5) [[5, 10], [15, 20]] >>> scalar_multiply([[1.4,2.3],[3,4]],5) [[7.0, 11.5], [15, 20]] - ''' + """ return [[x * n for x in row] for row in matrix] def multiply(matrix_a: List[list], matrix_b: List[list]) -> List[list]: - ''' + """ >>> multiply([[1,2],[3,4]],[[5,5],[7,5]]) [[19, 15], [43, 35]] >>> multiply([[1,2.5],[3,4.5]],[[5,5],[7,5]]) [[22.5, 17.5], [46.5, 37.5]] - ''' + """ if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): matrix_c = [] rows, cols = _verify_matrix_sizes(matrix_a, matrix_b) @@ -83,12 +81,12 @@ def identity(n: int) -> List[list]: def transpose(matrix: List[list], return_map: bool = True) -> List[list]: - ''' + """ >>> transpose([[1,2],[3,4]]) # doctest: +ELLIPSIS >> transpose([[1,2],[3,4]], return_map=False) [[1, 3], [2, 4]] - ''' + """ if _check_not_integer(matrix): if return_map: return map(list, zip(*matrix)) @@ -97,22 +95,22 @@ def transpose(matrix: List[list], return_map: bool = True) -> List[list]: def minor(matrix: List[list], row: int, column: int) -> List[list]: - ''' + """ >>> minor([[1, 2], [3, 4]], 1, 1) [[1]] - ''' - minor = matrix[:row] + matrix[row + 1:] - minor = [row[:column] + row[column + 1:] for row in minor] + """ + minor = matrix[:row] + matrix[row + 1 :] + minor = [row[:column] + row[column + 1 :] for row in minor] return minor def determinant(matrix: List[list]) -> int: - ''' + """ >>> determinant([[1, 2], [3, 4]]) -2 >>> determinant([[1.5, 2.5], [3, 4]]) -1.5 - ''' + """ if len(matrix) == 1: return matrix[0][0] @@ -123,11 +121,11 @@ def determinant(matrix: List[list]) -> int: def inverse(matrix: List[list]) -> List[list]: - ''' + """ >>> inverse([[1, 2], [3, 4]]) [[-2.0, 1.0], [1.5, -0.5]] >>> inverse([[1, 1], [1, 1]]) - ''' + """ # https://stackoverflow.com/questions/20047519/python-doctests-test-for-none det = determinant(matrix) if det == 0: @@ -156,8 +154,7 @@ def _shape(matrix: List[list]) -> list: return list((len(matrix), len(matrix[0]))) -def _verify_matrix_sizes( - matrix_a: List[list], matrix_b: List[list]) -> Tuple[list]: +def _verify_matrix_sizes(matrix_a: List[list], matrix_b: List[list]) -> Tuple[list]: shape = _shape(matrix_a) shape += _shape(matrix_b) if shape[0] != shape[2] or shape[1] != shape[3]: @@ -171,15 +168,12 @@ def _verify_matrix_sizes( def main(): matrix_a = [[12, 10], [3, 9]] matrix_b = [[3, 4], [7, 4]] - matrix_c = [[11, 12, 13, 14], [21, 22, 23, 24], - [31, 32, 33, 34], [41, 42, 43, 44]] + matrix_c = [[11, 12, 13, 14], [21, 22, 23, 24], [31, 32, 33, 34], [41, 42, 43, 44]] matrix_d = [[3, 0, 2], [2, 0, -2], [0, 1, 1]] - print( - f"Add Operation, {matrix_a} + {matrix_b} = {add(matrix_a, matrix_b)} \n" - ) + print(f"Add Operation, {matrix_a} + {matrix_b} = {add(matrix_a, matrix_b)} \n") print( f"Multiply Operation, {matrix_a} * {matrix_b}", - f"= {multiply(matrix_a, matrix_b)} \n" + f"= {multiply(matrix_a, matrix_b)} \n", ) print(f"Identity: {identity(5)}\n") print(f"Minor of {matrix_c} = {minor(matrix_c, 1, 2)} \n") @@ -189,5 +183,6 @@ def main(): if __name__ == "__main__": import doctest + doctest.testmod() main() From fdf4235324d95a20ee3c9f57aa8a0364cbbed737 Mon Sep 17 00:00:00 2001 From: wuyudi Date: Thu, 2 Jul 2020 09:47:27 +0000 Subject: [PATCH 13/19] Update searching_in_sorted_matrix.py --- matrix/searching_in_sorted_matrix.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/matrix/searching_in_sorted_matrix.py b/matrix/searching_in_sorted_matrix.py index 3897ffb1d9c6..f1b7a3820561 100644 --- a/matrix/searching_in_sorted_matrix.py +++ b/matrix/searching_in_sorted_matrix.py @@ -1,14 +1,26 @@ -def search_in_a_sorted_matrix(mat, m, n, key): +from typing import List + + +def search_in_a_sorted_matrix( + mat: List[list], m: int, n: int, key: int) -> None: + ''' + >>> search_in_a_sorted_matrix(\ + [[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 5) + Key 5 found at row- 1 column- 2 + >>> search_in_a_sorted_matrix(\ + [[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 21) + Key 21 not found + ''' i, j = m - 1, 0 while i >= 0 and j < n: if key == mat[i][j]: - print("Key {} found at row- {} column- {}".format(key, i + 1, j + 1)) + print(f"Key {key} found at row- {i + 1} column- {j + 1}") return if key < mat[i][j]: i -= 1 else: j += 1 - print("Key %s not found" % (key)) + print(f"Key {key} not found") def main(): @@ -19,4 +31,6 @@ def main(): if __name__ == "__main__": + import doctest + doctest.testmod() main() From 6e57706de5298ceb339ceda670baf4ca6a72f7e6 Mon Sep 17 00:00:00 2001 From: wuyudi Date: Thu, 2 Jul 2020 09:55:15 +0000 Subject: [PATCH 14/19] recover this file --- matrix/searching_in_sorted_matrix.py | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/matrix/searching_in_sorted_matrix.py b/matrix/searching_in_sorted_matrix.py index f1b7a3820561..3897ffb1d9c6 100644 --- a/matrix/searching_in_sorted_matrix.py +++ b/matrix/searching_in_sorted_matrix.py @@ -1,26 +1,14 @@ -from typing import List - - -def search_in_a_sorted_matrix( - mat: List[list], m: int, n: int, key: int) -> None: - ''' - >>> search_in_a_sorted_matrix(\ - [[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 5) - Key 5 found at row- 1 column- 2 - >>> search_in_a_sorted_matrix(\ - [[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 21) - Key 21 not found - ''' +def search_in_a_sorted_matrix(mat, m, n, key): i, j = m - 1, 0 while i >= 0 and j < n: if key == mat[i][j]: - print(f"Key {key} found at row- {i + 1} column- {j + 1}") + print("Key {} found at row- {} column- {}".format(key, i + 1, j + 1)) return if key < mat[i][j]: i -= 1 else: j += 1 - print(f"Key {key} not found") + print("Key %s not found" % (key)) def main(): @@ -31,6 +19,4 @@ def main(): if __name__ == "__main__": - import doctest - doctest.testmod() main() From 556139888bfbbb1f6b12672e87b0cf12862074d3 Mon Sep 17 00:00:00 2001 From: wuyudi Date: Thu, 2 Jul 2020 13:03:04 +0000 Subject: [PATCH 15/19] f-string, typing hint , doctest --- matrix/matrix_operation.py | 210 ++++++------------------------------- 1 file changed, 32 insertions(+), 178 deletions(-) diff --git a/matrix/matrix_operation.py b/matrix/matrix_operation.py index 5e8eb9ef4bd0..996805d4e231 100644 --- a/matrix/matrix_operation.py +++ b/matrix/matrix_operation.py @@ -1,188 +1,42 @@ -""" -Functions for 2D matrix operations -""" - -from typing import List, Tuple - - -def add(matrix_a: List[list], matrix_b: List[list]) -> List[list]: - """ - >>> add([[1,2],[3,4]],[[2,3],[4,5]]) - [[3, 5], [7, 9]] - >>> add([[1.2,2.4],[3,4]],[[2,3],[4,5]]) - [[3.2, 5.4], [7, 9]] - """ - if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): - _verify_matrix_sizes(matrix_a, matrix_b) - matrix_c = [[i + j for i, j in zip(m, n)] for m, n in zip(matrix_a, matrix_b)] - return matrix_c - - -def subtract(matrix_a: List[list], matrix_b: List[list]) -> List[list]: - """ - >>> subtract([[1,2],[3,4]],[[2,3],[4,5]]) - [[-1, -1], [-1, -1]] - >>> subtract([[1,2.5],[3,4]],[[2,3],[4,5.5]]) - [[-1, -0.5], [-1, -1.5]] - """ - if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): - _verify_matrix_sizes(matrix_a, matrix_b) - matrix_c = [[i - j for i, j in zip(m, n)] for m, n in zip(matrix_a, matrix_b)] - return matrix_c - - -def scalar_multiply(matrix: List[list], n: int) -> List[list]: - """ - >>> scalar_multiply([[1,2],[3,4]],5) - [[5, 10], [15, 20]] - >>> scalar_multiply([[1.4,2.3],[3,4]],5) - [[7.0, 11.5], [15, 20]] - """ - return [[x * n for x in row] for row in matrix] - - -def multiply(matrix_a: List[list], matrix_b: List[list]) -> List[list]: - """ - >>> multiply([[1,2],[3,4]],[[5,5],[7,5]]) - [[19, 15], [43, 35]] - >>> multiply([[1,2.5],[3,4.5]],[[5,5],[7,5]]) - [[22.5, 17.5], [46.5, 37.5]] - """ - if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): - matrix_c = [] - rows, cols = _verify_matrix_sizes(matrix_a, matrix_b) - - if cols[0] != rows[1]: - raise ValueError( - f"Cannot multiply matrix of dimensions ({rows[0]},{cols[0]}) " - f"and ({rows[1]},{cols[1]})" - ) - for i in range(rows[0]): - list_1 = [] - for j in range(cols[1]): - val = 0 - for k in range(cols[1]): - val += matrix_a[i][k] * matrix_b[k][j] - list_1.append(val) - matrix_c.append(list_1) - return matrix_c - - -def identity(n: int) -> List[list]: - """ - :param n: dimension for nxn matrix - :type n: int - :return: Identity matrix of shape [n, n] - >>> identity(3) - [[1, 0, 0], [0, 1, 0], [0, 0, 1]] - """ - n = int(n) - return [[int(row == column) for column in range(n)] for row in range(n)] - - -def transpose(matrix: List[list], return_map: bool = True) -> List[list]: - """ - >>> transpose([[1,2],[3,4]]) # doctest: +ELLIPSIS - >> transpose([[1,2],[3,4]], return_map=False) - [[1, 3], [2, 4]] - """ - if _check_not_integer(matrix): - if return_map: - return map(list, zip(*matrix)) +from typing import List + + +def search_in_a_sorted_matrix( + mat: List[list], m: int, n: int, key: int or float) -> None: + ''' + >>> search_in_a_sorted_matrix(\ + [[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 5) + Key 5 found at row- 1 column- 2 + >>> search_in_a_sorted_matrix(\ + [[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 21) + Key 21 not found + >>> search_in_a_sorted_matrix(\ + [[2.1, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 2.1) + Key 2.1 found at row- 1 column- 1 + >>> search_in_a_sorted_matrix(\ + [[2.1, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 2.2) + Key 2.2 not found + ''' + i, j = m - 1, 0 + while i >= 0 and j < n: + if key == mat[i][j]: + print(f"Key {key} found at row- {i + 1} column- {j + 1}") + return + if key < mat[i][j]: + i -= 1 else: - return [[row[i] for row in matrix] for i in range(len(matrix[0]))] - - -def minor(matrix: List[list], row: int, column: int) -> List[list]: - """ - >>> minor([[1, 2], [3, 4]], 1, 1) - [[1]] - """ - minor = matrix[:row] + matrix[row + 1 :] - minor = [row[:column] + row[column + 1 :] for row in minor] - return minor - - -def determinant(matrix: List[list]) -> int: - """ - >>> determinant([[1, 2], [3, 4]]) - -2 - >>> determinant([[1.5, 2.5], [3, 4]]) - -1.5 - """ - if len(matrix) == 1: - return matrix[0][0] - - res = 0 - for x in range(len(matrix)): - res += matrix[0][x] * determinant(minor(matrix, 0, x)) * (-1) ** x - return res - - -def inverse(matrix: List[list]) -> List[list]: - """ - >>> inverse([[1, 2], [3, 4]]) - [[-2.0, 1.0], [1.5, -0.5]] - >>> inverse([[1, 1], [1, 1]]) - """ - # https://stackoverflow.com/questions/20047519/python-doctests-test-for-none - det = determinant(matrix) - if det == 0: - return None - - matrix_minor = [[] for _ in matrix] - for i in range(len(matrix)): - for j in range(len(matrix)): - matrix_minor[i].append(determinant(minor(matrix, i, j))) - - cofactors = [ - [x * (-1) ** (row + col) for col, x in enumerate(matrix_minor[row])] - for row in range(len(matrix)) - ] - adjugate = transpose(cofactors) - return scalar_multiply(adjugate, 1 / det) - - -def _check_not_integer(matrix: List[list]) -> bool: - if not isinstance(matrix, int) and not isinstance(matrix[0], int): - return True - raise TypeError("Expected a matrix, got int/list instead") - - -def _shape(matrix: List[list]) -> list: - return list((len(matrix), len(matrix[0]))) - - -def _verify_matrix_sizes(matrix_a: List[list], matrix_b: List[list]) -> Tuple[list]: - shape = _shape(matrix_a) - shape += _shape(matrix_b) - if shape[0] != shape[2] or shape[1] != shape[3]: - raise ValueError( - f"operands could not be broadcast together with shape " - f"({shape[0], shape[1]}), ({shape[2], shape[3]})" - ) - return [shape[0], shape[2]], [shape[1], shape[3]] + j += 1 + print(f"Key {key} not found") def main(): - matrix_a = [[12, 10], [3, 9]] - matrix_b = [[3, 4], [7, 4]] - matrix_c = [[11, 12, 13, 14], [21, 22, 23, 24], [31, 32, 33, 34], [41, 42, 43, 44]] - matrix_d = [[3, 0, 2], [2, 0, -2], [0, 1, 1]] - print(f"Add Operation, {matrix_a} + {matrix_b} = {add(matrix_a, matrix_b)} \n") - print( - f"Multiply Operation, {matrix_a} * {matrix_b}", - f"= {multiply(matrix_a, matrix_b)} \n", - ) - print(f"Identity: {identity(5)}\n") - print(f"Minor of {matrix_c} = {minor(matrix_c, 1, 2)} \n") - print(f"Determinant of {matrix_b} = {determinant(matrix_b)} \n") - print(f"Inverse of {matrix_d} = {inverse(matrix_d)}\n") + mat = [[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]] + x = int(input("Enter the element to be searched:")) + print(mat) + search_in_a_sorted_matrix(mat, len(mat), len(mat[0]), x) if __name__ == "__main__": import doctest - doctest.testmod() main() From 52b5bdd6a7e05185f6ee281231d53213c1ec617e Mon Sep 17 00:00:00 2001 From: wuyudi Date: Thu, 2 Jul 2020 13:05:31 +0000 Subject: [PATCH 16/19] Update matrix_operation.py --- matrix/matrix_operation.py | 214 +++++++++++++++++++++++++++++++------ 1 file changed, 183 insertions(+), 31 deletions(-) diff --git a/matrix/matrix_operation.py b/matrix/matrix_operation.py index 996805d4e231..47d61ae10fe9 100644 --- a/matrix/matrix_operation.py +++ b/matrix/matrix_operation.py @@ -1,42 +1,194 @@ -from typing import List - - -def search_in_a_sorted_matrix( - mat: List[list], m: int, n: int, key: int or float) -> None: - ''' - >>> search_in_a_sorted_matrix(\ - [[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 5) - Key 5 found at row- 1 column- 2 - >>> search_in_a_sorted_matrix(\ - [[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 21) - Key 21 not found - >>> search_in_a_sorted_matrix(\ - [[2.1, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 2.1) - Key 2.1 found at row- 1 column- 1 - >>> search_in_a_sorted_matrix(\ - [[2.1, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 2.2) - Key 2.2 not found - ''' - i, j = m - 1, 0 - while i >= 0 and j < n: - if key == mat[i][j]: - print(f"Key {key} found at row- {i + 1} column- {j + 1}") - return - if key < mat[i][j]: - i -= 1 +""" +Functions for 2D matrix operations +""" + +from typing import List, Tuple + + +def add(matrix_a: List[list], matrix_b: List[list]) -> List[list]: + """ + >>> add([[1,2],[3,4]],[[2,3],[4,5]]) + [[3, 5], [7, 9]] + >>> add([[1.2,2.4],[3,4]],[[2,3],[4,5]]) + [[3.2, 5.4], [7, 9]] + """ + if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): + _verify_matrix_sizes(matrix_a, matrix_b) + matrix_c = [[i + j for i, j in zip(m, n)] + for m, n in zip(matrix_a, matrix_b)] + return matrix_c + + +def subtract(matrix_a: List[list], matrix_b: List[list]) -> List[list]: + """ + >>> subtract([[1,2],[3,4]],[[2,3],[4,5]]) + [[-1, -1], [-1, -1]] + >>> subtract([[1,2.5],[3,4]],[[2,3],[4,5.5]]) + [[-1, -0.5], [-1, -1.5]] + """ + if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): + _verify_matrix_sizes(matrix_a, matrix_b) + matrix_c = [[i - j for i, j in zip(m, n)] + for m, n in zip(matrix_a, matrix_b)] + return matrix_c + + +def scalar_multiply(matrix: List[list], n: int) -> List[list]: + """ + >>> scalar_multiply([[1,2],[3,4]],5) + [[5, 10], [15, 20]] + >>> scalar_multiply([[1.4,2.3],[3,4]],5) + [[7.0, 11.5], [15, 20]] + """ + return [[x * n for x in row] for row in matrix] + + +def multiply(matrix_a: List[list], matrix_b: List[list]) -> List[list]: + """ + >>> multiply([[1,2],[3,4]],[[5,5],[7,5]]) + [[19, 15], [43, 35]] + >>> multiply([[1,2.5],[3,4.5]],[[5,5],[7,5]]) + [[22.5, 17.5], [46.5, 37.5]] + """ + if _check_not_integer(matrix_a) and _check_not_integer(matrix_b): + matrix_c = [] + rows, cols = _verify_matrix_sizes(matrix_a, matrix_b) + + if cols[0] != rows[1]: + raise ValueError( + f"Cannot multiply matrix of dimensions ({rows[0]},{cols[0]}) " + f"and ({rows[1]},{cols[1]})" + ) + for i in range(rows[0]): + list_1 = [] + for j in range(cols[1]): + val = 0 + for k in range(cols[1]): + val += matrix_a[i][k] * matrix_b[k][j] + list_1.append(val) + matrix_c.append(list_1) + return matrix_c + + +def identity(n: int) -> List[list]: + """ + :param n: dimension for nxn matrix + :type n: int + :return: Identity matrix of shape [n, n] + >>> identity(3) + [[1, 0, 0], [0, 1, 0], [0, 0, 1]] + """ + n = int(n) + return [[int(row == column) for column in range(n)] for row in range(n)] + + +def transpose(matrix: List[list], return_map: bool = True) -> List[list]: + """ + >>> transpose([[1,2],[3,4]]) # doctest: +ELLIPSIS + >> transpose([[1,2],[3,4]], return_map=False) + [[1, 3], [2, 4]] + """ + if _check_not_integer(matrix): + if return_map: + return map(list, zip(*matrix)) else: - j += 1 + return [[row[i] for row in matrix] for i in range(len(matrix[0]))] + + +def minor(matrix: List[list], row: int, column: int) -> List[list]: + """ + >>> minor([[1, 2], [3, 4]], 1, 1) + [[1]] + """ + minor = matrix[:row] + matrix[row + 1:] + minor = [row[:column] + row[column + 1:] for row in minor] + return minor + + +def determinant(matrix: List[list]) -> int: + """ + >>> determinant([[1, 2], [3, 4]]) + -2 + >>> determinant([[1.5, 2.5], [3, 4]]) + -1.5 + """ + if len(matrix) == 1: + return matrix[0][0] + + res = 0 + for x in range(len(matrix)): + res += matrix[0][x] * determinant(minor(matrix, 0, x)) * (-1) ** x + return res + + +def inverse(matrix: List[list]) -> List[list]: + """ + >>> inverse([[1, 2], [3, 4]]) + [[-2.0, 1.0], [1.5, -0.5]] + >>> inverse([[1, 1], [1, 1]]) + """ + # https://stackoverflow.com/questions/20047519/python-doctests-test-for-none + det = determinant(matrix) + if det == 0: + return None + + matrix_minor = [[] for _ in matrix] + for i in range(len(matrix)): + for j in range(len(matrix)): + matrix_minor[i].append(determinant(minor(matrix, i, j))) + + cofactors = [ + [x * (-1) ** (row + col) for col, x in enumerate(matrix_minor[row])] + for row in range(len(matrix)) + ] + adjugate = transpose(cofactors) + return scalar_multiply(adjugate, 1 / det) + + +def _check_not_integer(matrix: List[list]) -> bool: + if not isinstance(matrix, int) and not isinstance(matrix[0], int): + return True + raise TypeError("Expected a matrix, got int/list instead") + + +def _shape(matrix: List[list]) -> list: + return list((len(matrix), len(matrix[0]))) + + +def _verify_matrix_sizes(matrix_a: List[list], matrix_b: List[list]) -> Tuple[list]: + shape = _shape(matrix_a) + shape += _shape(matrix_b) + if shape[0] != shape[2] or shape[1] != shape[3]: + raise ValueError( + f"operands could not be broadcast together with shape " + f"({shape[0], shape[1]}), ({shape[2], shape[3]})" + ) + return [shape[0], shape[2]], [shape[1], shape[3]] + j += 1 print(f"Key {key} not found") def main(): - mat = [[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]] - x = int(input("Enter the element to be searched:")) - print(mat) - search_in_a_sorted_matrix(mat, len(mat), len(mat[0]), x) + matrix_a = [[12, 10], [3, 9]] + matrix_b = [[3, 4], [7, 4]] + matrix_c = [[11, 12, 13, 14], [21, 22, 23, 24], + [31, 32, 33, 34], [41, 42, 43, 44]] + matrix_d = [[3, 0, 2], [2, 0, -2], [0, 1, 1]] + print( + f"Add Operation, {matrix_a} + {matrix_b} = {add(matrix_a, matrix_b)} \n") + print( + f"Multiply Operation, {matrix_a} * {matrix_b}", + f"= {multiply(matrix_a, matrix_b)} \n", + ) + print(f"Identity: {identity(5)}\n") + print(f"Minor of {matrix_c} = {minor(matrix_c, 1, 2)} \n") + print(f"Determinant of {matrix_b} = {determinant(matrix_b)} \n") + print(f"Inverse of {matrix_d} = {inverse(matrix_d)}\n") if __name__ == "__main__": import doctest + doctest.testmod() main() From de77ae619edbe3cc2741c3de342169ffbef66f63 Mon Sep 17 00:00:00 2001 From: wuyudi Date: Thu, 2 Jul 2020 13:06:29 +0000 Subject: [PATCH 17/19] Update searching_in_sorted_matrix.py --- matrix/searching_in_sorted_matrix.py | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/matrix/searching_in_sorted_matrix.py b/matrix/searching_in_sorted_matrix.py index 3897ffb1d9c6..996805d4e231 100644 --- a/matrix/searching_in_sorted_matrix.py +++ b/matrix/searching_in_sorted_matrix.py @@ -1,14 +1,32 @@ -def search_in_a_sorted_matrix(mat, m, n, key): +from typing import List + + +def search_in_a_sorted_matrix( + mat: List[list], m: int, n: int, key: int or float) -> None: + ''' + >>> search_in_a_sorted_matrix(\ + [[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 5) + Key 5 found at row- 1 column- 2 + >>> search_in_a_sorted_matrix(\ + [[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 21) + Key 21 not found + >>> search_in_a_sorted_matrix(\ + [[2.1, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 2.1) + Key 2.1 found at row- 1 column- 1 + >>> search_in_a_sorted_matrix(\ + [[2.1, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]], 3, 3, 2.2) + Key 2.2 not found + ''' i, j = m - 1, 0 while i >= 0 and j < n: if key == mat[i][j]: - print("Key {} found at row- {} column- {}".format(key, i + 1, j + 1)) + print(f"Key {key} found at row- {i + 1} column- {j + 1}") return if key < mat[i][j]: i -= 1 else: j += 1 - print("Key %s not found" % (key)) + print(f"Key {key} not found") def main(): @@ -19,4 +37,6 @@ def main(): if __name__ == "__main__": + import doctest + doctest.testmod() main() From cd2952403bdf19085aa8e5eb123d2094eb8db232 Mon Sep 17 00:00:00 2001 From: wuyudi Date: Thu, 2 Jul 2020 13:53:52 +0000 Subject: [PATCH 18/19] Update matrix_operation.py --- matrix/matrix_operation.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/matrix/matrix_operation.py b/matrix/matrix_operation.py index 47d61ae10fe9..b0e43830f1dc 100644 --- a/matrix/matrix_operation.py +++ b/matrix/matrix_operation.py @@ -156,7 +156,8 @@ def _shape(matrix: List[list]) -> list: return list((len(matrix), len(matrix[0]))) -def _verify_matrix_sizes(matrix_a: List[list], matrix_b: List[list]) -> Tuple[list]: +def _verify_matrix_sizes( + matrix_a: List[list], matrix_b: List[list]) -> Tuple[list]: shape = _shape(matrix_a) shape += _shape(matrix_b) if shape[0] != shape[2] or shape[1] != shape[3]: @@ -165,8 +166,6 @@ def _verify_matrix_sizes(matrix_a: List[list], matrix_b: List[list]) -> Tuple[li f"({shape[0], shape[1]}), ({shape[2], shape[3]})" ) return [shape[0], shape[2]], [shape[1], shape[3]] - j += 1 - print(f"Key {key} not found") def main(): @@ -176,7 +175,8 @@ def main(): [31, 32, 33, 34], [41, 42, 43, 44]] matrix_d = [[3, 0, 2], [2, 0, -2], [0, 1, 1]] print( - f"Add Operation, {matrix_a} + {matrix_b} = {add(matrix_a, matrix_b)} \n") + f"Add Operation, {matrix_a} + {matrix_b}", + f" = {add(matrix_a, matrix_b)} \n") print( f"Multiply Operation, {matrix_a} * {matrix_b}", f"= {multiply(matrix_a, matrix_b)} \n", From 5c0f79c932e8ab99c71e910d549e0c11a8a47853 Mon Sep 17 00:00:00 2001 From: wuyudi Date: Thu, 2 Jul 2020 23:01:08 +0800 Subject: [PATCH 19/19] Update matrix/matrix_operation.py Co-authored-by: Christian Clauss --- matrix/matrix_operation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix/matrix_operation.py b/matrix/matrix_operation.py index b0e43830f1dc..2580ef85dcc6 100644 --- a/matrix/matrix_operation.py +++ b/matrix/matrix_operation.py @@ -175,7 +175,7 @@ def main(): [31, 32, 33, 34], [41, 42, 43, 44]] matrix_d = [[3, 0, 2], [2, 0, -2], [0, 1, 1]] print( - f"Add Operation, {matrix_a} + {matrix_b}", + f"Add Operation, {matrix_a} + {matrix_b}" f" = {add(matrix_a, matrix_b)} \n") print( f"Multiply Operation, {matrix_a} * {matrix_b}",