@@ -62,9 +62,21 @@ def print(self):
62
62
63
63
for row in self .entries : print (row )
64
64
65
+ def transpose (self ):
66
+
67
+ entries = [[self .entries [i ][j ] for i in range (self .rows )] for j in range (self .cols )]
68
+ return Matrix (entries )
69
+
70
+ def vectorize (self ):
71
+
72
+ if self .cols != 1 :
73
+ raise Exception ("Only Matrices with one column can be converted to column Vectors" )
74
+ else :
75
+ return Vector ([row [0 ] for row in self .entries ])
76
+
65
77
def __add__ (a , b ):
66
78
67
- if type ( a ) != Matrix or type ( b ) != Matrix :
79
+ if not ( isinstance ( a , Matrix ) and isinstance ( b , Matrix )) :
68
80
raise Exception ("Matrices can only be added to other matrices" )
69
81
elif a .rows != b .rows or a .cols != b .cols :
70
82
raise Exception ("Matrices with different dimensions cannot be added" )
@@ -74,19 +86,23 @@ def __add__(a, b):
74
86
ae = a .entries
75
87
be = b .entries
76
88
entries = [[ae [i ][j ] + be [i ][j ] for j in range (c )] for i in range (r )]
77
- return Matrix (entries )
89
+ result = Matrix (entries )
90
+ if result .cols == 1 : result = result .vectorize ()
91
+ return result
78
92
79
93
def __mul__ (a , b ):
80
94
81
- if type (a ) != Matrix or type (b ) != Matrix :
95
+ result = False
96
+
97
+ if not (isinstance (a , Matrix ) and isinstance (b , Matrix )):
82
98
83
99
if is_number (a ):
84
100
entries = [[entry * a for entry in row ] for row in b .entries ]
85
- return Matrix (entries )
101
+ result = Matrix (entries )
86
102
87
103
elif is_number (b ):
88
104
entries = [[entry * b for entry in row ] for row in a .entries ]
89
- return Matrix (entries )
105
+ result = Matrix (entries )
90
106
91
107
else :
92
108
raise Exception ("Only matrix-matrix and matrix-scalar multiplication are supported" )
@@ -103,12 +119,19 @@ def __mul__(a, b):
103
119
b_col = b .col_at (j )
104
120
entry = sum ([a_row [n ] * b_col [n ][0 ] for n in range (length )])
105
121
entries [i ][j ] = entry
106
- return Matrix (entries )
122
+ result = Matrix (entries )
123
+
124
+ if result .cols == 1 : result = result .vectorize ()
125
+ return result
107
126
108
127
def __rmul__ (a , b ):
109
128
110
129
return Matrix .__mul__ (b , a )
111
130
131
+ def __sub__ (a , b ):
132
+
133
+ return a + (- 1 )* b
134
+
112
135
def column (entries ):
113
136
114
137
return Matrix ([[e ] for e in entries ])
@@ -140,10 +163,6 @@ def dilation(factor, center):
140
163
t_inv = Matrix .translation (center )
141
164
return t_inv * d * t
142
165
143
- def rotation (theta , normal ):
144
-
145
- dim = len (normal )
146
-
147
166
class Vector (Matrix ):
148
167
149
168
def __init__ (self , coords ):
@@ -171,6 +190,42 @@ def normalize(self):
171
190
self .set (i , 0 , val / norm )
172
191
return self
173
192
193
+ def dot (a , b ):
194
+
195
+ if not (isinstance (a , Vector ) and isinstance (b , Vector )):
196
+ raise Exception ("Dot product is only supported for Vectors" )
197
+ elif a .cols != b .cols :
198
+ raise Exception ("Only Vectors of the same length can be dotted" )
199
+ else :
200
+ return (a .transpose () * b ).at (0 , 0 )
201
+
202
+ def projection (a , b ):
203
+
204
+ if not (isinstance (a , Vector ) and isinstance (b , Vector )):
205
+ raise Exception ("Vector projection is only supported for Vectors" )
206
+ elif a .cols != b .cols :
207
+ raise Exception ("A Vector can only be projected onto another Vector of the same length" )
208
+ else :
209
+ a_unit = a .normalize ()
210
+ a_norm = a .norm ()
211
+ length = Vector .dot (a , b ) / a_norm ** 2
212
+ return length * a_unit
213
+
214
+ ## this function assumes that the set of vectors it is passed is already linearly independent
215
+ def gram_schmidt (vectors ):
216
+
217
+ dim = vectors [0 ].cols
218
+ dim_subspace = len (vectors )
219
+
220
+ basis_vectors = []
221
+ for v in vectors :
222
+ new_bv = v
223
+ for w in basis_vectors :
224
+ new_bv = new_bv - Vector .projection (w , v )
225
+ basis_vectors .append (new_bv )
226
+
227
+ return [v .normalize () for v in basis_vectors ]
228
+
174
229
class Point (Matrix ):
175
230
176
231
def __init__ (self , coords ):
0 commit comments