1- from __future__ import print_function
1+ """
2+ function based version of matrix operations, which are just 2D arrays
3+ """
4+
25
36def add (matrix_a , matrix_b ):
4- rows = len (matrix_a )
5- columns = len (matrix_a [0 ])
6- matrix_c = []
7- for i in range (rows ):
8- list_1 = []
9- for j in range (columns ):
10- val = matrix_a [i ][j ] + matrix_b [i ][j ]
11- list_1 .append (val )
12- matrix_c .append (list_1 )
13- return matrix_c
14-
15- def scalarMultiply (matrix , n ):
7+ if _check_not_integer (matrix_a ) and _check_not_integer (matrix_b ):
8+ rows , cols = _verify_matrix_sizes (matrix_a , matrix_b )
9+ matrix_c = []
10+ for i in range (rows [0 ]):
11+ list_1 = []
12+ for j in range (cols [0 ]):
13+ val = matrix_a [i ][j ] + matrix_b [i ][j ]
14+ list_1 .append (val )
15+ matrix_c .append (list_1 )
16+ return matrix_c
17+
18+
19+ def subtract (matrix_a , matrix_b ):
20+ if _check_not_integer (matrix_a ) and _check_not_integer (matrix_b ):
21+ rows , cols = _verify_matrix_sizes (matrix_a , matrix_b )
22+ matrix_c = []
23+ for i in range (rows [0 ]):
24+ list_1 = []
25+ for j in range (cols [0 ]):
26+ val = matrix_a [i ][j ] - matrix_b [i ][j ]
27+ list_1 .append (val )
28+ matrix_c .append (list_1 )
29+ return matrix_c
30+
31+
32+ def scalar_multiply (matrix , n ):
1633 return [[x * n for x in row ] for row in matrix ]
1734
35+
1836def multiply (matrix_a , matrix_b ):
19- matrix_c = []
20- n = len (matrix_a )
21- for i in range (n ):
22- list_1 = []
23- for j in range (n ):
24- val = 0
25- for k in range (n ):
26- val = val + matrix_a [i ][k ] * matrix_b [k ][j ]
27- list_1 .append (val )
28- matrix_c .append (list_1 )
29- return matrix_c
37+ if _check_not_integer (matrix_a ) and _check_not_integer (matrix_b ):
38+ matrix_c = []
39+ rows , cols = _verify_matrix_sizes (matrix_a , matrix_b )
40+
41+ if cols [0 ] != rows [1 ]:
42+ raise ValueError (f'Cannot multiply matrix of dimensions ({ rows [0 ]} ,{ cols [0 ]} ) '
43+ f'and ({ rows [1 ]} ,{ cols [1 ]} )' )
44+ for i in range (rows [0 ]):
45+ list_1 = []
46+ for j in range (cols [1 ]):
47+ val = 0
48+ for k in range (cols [1 ]):
49+ val = val + matrix_a [i ][k ] * matrix_b [k ][j ]
50+ list_1 .append (val )
51+ matrix_c .append (list_1 )
52+ return matrix_c
53+
3054
3155def identity (n ):
56+ """
57+ :param n: dimension for nxn matrix
58+ :type n: int
59+ :return: Identity matrix of shape [n, n]
60+ """
61+ n = int (n )
3262 return [[int (row == column ) for column in range (n )] for row in range (n )]
3363
34- def transpose (matrix ):
35- return map (list , zip (* matrix ))
64+
65+ def transpose (matrix , return_map = True ):
66+ if _check_not_integer (matrix ):
67+ if return_map :
68+ return map (list , zip (* matrix ))
69+ else :
70+ # mt = []
71+ # for i in range(len(matrix[0])):
72+ # mt.append([row[i] for row in matrix])
73+ # return mt
74+ return [[row [i ] for row in matrix ] for i in range (len (matrix [0 ]))]
75+
3676
3777def minor (matrix , row , column ):
3878 minor = matrix [:row ] + matrix [row + 1 :]
3979 minor = [row [:column ] + row [column + 1 :] for row in minor ]
4080 return minor
4181
82+
4283def determinant (matrix ):
43- if len (matrix ) == 1 : return matrix [0 ][0 ]
84+ if len (matrix ) == 1 :
85+ return matrix [0 ][0 ]
4486
4587 res = 0
4688 for x in range (len (matrix )):
47- res += matrix [0 ][x ] * determinant (minor (matrix , 0 , x )) * (- 1 ) ** x
89+ res += matrix [0 ][x ] * determinant (minor (matrix , 0 , x )) * (- 1 ) ** x
4890 return res
4991
92+
5093def inverse (matrix ):
5194 det = determinant (matrix )
52- if det == 0 : return None
95+ if det == 0 :
96+ return None
5397
54- matrixMinor = [[] for _ in range (len (matrix ))]
98+ matrix_minor = [[] for _ in range (len (matrix ))]
5599 for i in range (len (matrix )):
56100 for j in range (len (matrix )):
57- matrixMinor [i ].append (determinant (minor (matrix , i , j )))
101+ matrix_minor [i ].append (determinant (minor (matrix , i , j )))
58102
59- cofactors = [[x * (- 1 ) ** (row + col ) for col , x in enumerate (matrixMinor [row ])] for row in range (len (matrix ))]
103+ cofactors = [[x * (- 1 ) ** (row + col ) for col , x in enumerate (matrix_minor [row ])] for row in range (len (matrix ))]
60104 adjugate = transpose (cofactors )
61- return scalarMultiply (adjugate , 1 / det )
105+ return scalar_multiply (adjugate , 1 / det )
106+
107+
108+ def _check_not_integer (matrix ):
109+ try :
110+ rows = len (matrix )
111+ cols = len (matrix [0 ])
112+ return True
113+ except TypeError :
114+ raise TypeError ("Cannot input an integer value, it must be a matrix" )
115+
116+
117+ def _shape (matrix ):
118+ return list ((len (matrix ), len (matrix [0 ])))
119+
120+
121+ def _verify_matrix_sizes (matrix_a , matrix_b ):
122+ shape = _shape (matrix_a )
123+ shape += _shape (matrix_b )
124+ if shape [0 ] != shape [2 ] or shape [1 ] != shape [3 ]:
125+ raise ValueError (f"operands could not be broadcast together with shape "
126+ f"({ shape [0 ], shape [1 ]} ), ({ shape [2 ], shape [3 ]} )" )
127+ return [shape [0 ], shape [2 ]], [shape [1 ], shape [3 ]]
128+
62129
63130def main ():
64131 matrix_a = [[12 , 10 ], [3 , 9 ]]
@@ -68,9 +135,10 @@ def main():
68135 print ('Add Operation, %s + %s = %s \n ' % (matrix_a , matrix_b , (add (matrix_a , matrix_b ))))
69136 print ('Multiply Operation, %s * %s = %s \n ' % (matrix_a , matrix_b , multiply (matrix_a , matrix_b )))
70137 print ('Identity: %s \n ' % identity (5 ))
71- print ('Minor of %s = %s \n ' % (matrix_c , minor (matrix_c , 1 , 2 )))
138+ print ('Minor of %s = %s \n ' % (matrix_c , minor (matrix_c , 1 , 2 )))
72139 print ('Determinant of %s = %s \n ' % (matrix_b , determinant (matrix_b )))
73140 print ('Inverse of %s = %s\n ' % (matrix_d , inverse (matrix_d )))
74141
142+
75143if __name__ == '__main__' :
76144 main ()
0 commit comments