1
+ import numpy as np
2
+ import math
3
+ from scipy .linalg import sqrtm
4
+
5
+ # TODO: Implement a function for computing the inverse of a matrix (if it exists) ---- Done!
6
+ # TODO: Implement a function for computing the adjoint of a matrix
7
+
8
+ def MatrixAddition (matrix_a , matrix_b ):
9
+ matrix_a , matrix_b = np .array (matrix_a ), np .array (matrix_b )
10
+ m ,n = matrix_a .shape
11
+ matrix_c = [[0 for _ in range (m )] for _ in range (n )]
12
+ for i in range (m ):
13
+ for j in range (n ):
14
+ matrix_c [i ][j ] += matrix_a [i ][j ] + matrix_b [i ][j ]
15
+ return np .array (matrix_c )
16
+
17
+ def MatrixSubtraction (matrix_a , matrix_b ):
18
+ matrix_a , matrix_b = np .array (matrix_a ), np .array (matrix_b )
19
+ m ,n = matrix_a .shape
20
+ matrix_c = [[0 for _ in range (m )] for _ in range (n )]
21
+ for i in range (m ):
22
+ for j in range (n ):
23
+ matrix_c [i ][j ] += matrix_a [i ][j ] - matrix_b [i ][j ]
24
+ return np .array (matrix_c )
25
+
26
+ def MatrixMultiplication (matrix_a , matrix_b ):
27
+ matrix_a , matrix_b = np .array (matrix_a ), np .array (matrix_b )
28
+ m ,n = matrix_a .shape
29
+ n ,p = matrix_b .shape
30
+ matrix_c = [[0 for j in range (p )] for i in range (m )]
31
+ for i in range (m ):
32
+ for j in range (p ):
33
+ for k in range (n ):
34
+ matrix_c [i ][j ] += matrix_a [i ][k ]* matrix_b [k ][j ]
35
+ return np .array (matrix_c )
36
+
37
+ def ifSymmetric (matrix ):
38
+ matrix = np .array (matrix )
39
+ matrix_transpose = matrix .transpose ()
40
+ if ((matrix_transpose == matrix ).sum () == matrix .shape [0 ]* matrix .shape [1 ]):
41
+ print (f"The matrix:\n { matrix } is symmetric!" )
42
+ else :
43
+ print (f"The matrix:\n { matrix } is not symmetric.." )
44
+
45
+ def compute_determinant (matrix ):
46
+ matrix = np .array (matrix )
47
+ if (matrix .shape [0 ] != matrix .shape [1 ]):
48
+ print ("Oops, the determinant of a non-square matrix cannot be computed.." )
49
+ det = np .linalg .det (matrix )
50
+ print (f"The determinant of \n { matrix } is: %.3f" % det )
51
+
52
+ def innerProduct (matrix_a , matrix_b ):
53
+ matrix_a = np .array (matrix_a )
54
+ matrix_b = np .array (matrix_b )
55
+ a_t = matrix_a .transpose ()
56
+ if ((matrix_a .ndim == 1 ) and (matrix_b .ndim == 1 )):
57
+ if (matrix_a .shape [0 ] != matrix_b .shape [0 ]):
58
+ print ("Cannot take inner product of vectors that are of different shapes..." )
59
+ exit (0 )
60
+ inner_product = np .dot (matrix_a , matrix_b )
61
+ else :
62
+ inner_product = MatrixMultiplication (a_t , matrix_b )
63
+ return inner_product
64
+
65
+ def outerProduct (matrix_a , matrix_b ):
66
+ matrix_a = np .array (matrix_a )
67
+ matrix_b = np .array (matrix_b )
68
+ b_t = matrix_b .transpose ()
69
+ if ((matrix_a .ndim == 1 ) and (matrix_b .ndim == 1 )):
70
+ matrix_a = matrix_a .reshape (- 1 ,1 )
71
+ matrix_b = matrix_b .reshape (- 1 ,1 )
72
+ matrix_b_transpose = matrix_b .transpose ()
73
+ outer_product = np .dot (matrix_a , matrix_b_transpose )
74
+ else :
75
+ outer_product = MatrixMultiplication (matrix_a , b_t )
76
+ return outer_product
77
+
78
+ def compute_inverse (matrix ):
79
+ matrix = np .array (matrix )
80
+ if matrix .shape [0 ] != matrix .shape [1 ]:
81
+ print ("No unique inverse exists!" , end = ' ' )
82
+ pseudo_inverse = np .linalg .pinv (matrix )
83
+ print ("So calcluated the pseudo-inverse, which is:" )
84
+ return pseudo_inverse
85
+ else :
86
+ return np .linalg .inv (matrix )
87
+
88
+ def Frobenius_norm (matrix ):
89
+ matrix = np .array (matrix )
90
+ sum_squares = 0.
91
+ for i in range (matrix .shape [0 ]):
92
+ for j in range (matrix .shape [1 ]):
93
+ sum_squares += matrix [i ][j ]** 2
94
+ return math .sqrt (sum_squares )
95
+
96
+ def compute_trace (A ):
97
+ if len (A ) != len (A [0 ]):
98
+ return "The matrix is not square!"
99
+ else :
100
+ trace = 0.
101
+ for i in range (len (A )):
102
+ trace += A [i ][i ]
103
+ return trace
104
+
105
+ def vector_norm (v , metric : int ) -> float :
106
+ norm = 0.
107
+ for i in range (len (v )):
108
+ norm += v [i ]** metric
109
+ return norm ** (1 / metric )
110
+
111
+ def matrix_norm (A , _norm ):
112
+ # Rather than this, you can also use my already defined function Frobenius_norm() above
113
+ if (_norm == "Frobenius" or _norm == 'frobenius' or _norm == 'frob' ):
114
+ # return np.linalg.norm(A, ord='fro') # Simply using the library function in NumPy
115
+ norm = 0.
116
+ for i in range (len (A )):
117
+ for j in range (len (A [0 ])):
118
+ norm += A [i ][j ]** 2
119
+ return np .sqrt (norm )
120
+ elif (_norm == "Max" or _norm == 'max' ):
121
+ return np .max (np .abs (A ))
122
+ elif (_norm == "nuclear" or _norm == 'nuc' or _norm == 'Nuclear' ):
123
+ # return np.linalg.norm(A, ord='nuc') # Simply using the library function in NumPy
124
+ m = MatrixMultiplication (np .transpose (A ), A )
125
+ sqrt_m = sqrtm (m )
126
+ return compute_trace (sqrt_m )
0 commit comments