10
10
Overview:
11
11
12
12
- class Vector
13
- - function zeroVector (dimension)
14
- - function unitBasisVector (dimension,pos)
15
- - function axpy(scalar,vector1,vector2)
16
- - function randomVector (N,a, b)
13
+ - function zero_vector (dimension)
14
+ - function unit_basis_vector (dimension, pos)
15
+ - function axpy(scalar, vector1, vector2)
16
+ - function random_vector (N, a, b)
17
17
- class Matrix
18
- - function squareZeroMatrix (N)
19
- - function randomMatrix (W,H,a, b)
18
+ - function square_zero_matrix (N)
19
+ - function random_matrix (W, H, a, b)
20
20
"""
21
21
from __future__ import annotations
22
22
@@ -30,20 +30,23 @@ class Vector:
30
30
This class represents a vector of arbitrary size.
31
31
You need to give the vector components.
32
32
33
- Overview about the methods:
34
-
35
- constructor(components : list) : init the vector
36
- set(components : list) : changes the vector components.
37
- __str__() : toString method
38
- component(i : int): gets the i-th component (start by 0)
39
- __len__() : gets the size of the vector (number of components)
40
- euclidLength() : returns the euclidean length of the vector.
41
- operator + : vector addition
42
- operator - : vector subtraction
43
- operator * : scalar multiplication and dot product
44
- copy() : copies this vector and returns it.
45
- changeComponent(pos,value) : changes the specified component.
46
- TODO: compare-operator
33
+ Overview of the methods:
34
+
35
+ __init__(components: Collection[float] | None): init the vector
36
+ __len__(): gets the size of the vector (number of components)
37
+ __str__(): returns a string representation
38
+ __add__(other: Vector): vector addition
39
+ __sub__(other: Vector): vector subtraction
40
+ __mul__(other: float): scalar multiplication
41
+ __mul__(other: Vector): dot product
42
+ set(components: Collection[float]): changes the vector components
43
+ copy(): copies this vector and returns it
44
+ component(i): gets the i-th component (0-indexed)
45
+ change_component(pos: int, value: float): changes specified component
46
+ euclidean_length(): returns the euclidean length of the vector
47
+ magnitude(): returns the magnitude of the vector
48
+ angle(other: Vector, deg: bool): returns the angle between two vectors
49
+ TODO: compare-operator
47
50
"""
48
51
49
52
def __init__ (self , components : Collection [float ] | None = None ) -> None :
@@ -55,47 +58,17 @@ def __init__(self, components: Collection[float] | None = None) -> None:
55
58
components = []
56
59
self .__components = list (components )
57
60
58
- def set (self , components : Collection [float ]) -> None :
59
- """
60
- input: new components
61
- changes the components of the vector.
62
- replace the components with newer one.
63
- """
64
- if len (components ) > 0 :
65
- self .__components = list (components )
66
- else :
67
- raise Exception ("please give any vector" )
68
-
69
- def __str__ (self ) -> str :
70
- """
71
- returns a string representation of the vector
72
- """
73
- return "(" + "," .join (map (str , self .__components )) + ")"
74
-
75
- def component (self , i : int ) -> float :
76
- """
77
- input: index (start at 0)
78
- output: the i-th component of the vector.
79
- """
80
- if type (i ) is int and - len (self .__components ) <= i < len (self .__components ):
81
- return self .__components [i ]
82
- else :
83
- raise Exception ("index out of range" )
84
-
85
61
def __len__ (self ) -> int :
86
62
"""
87
63
returns the size of the vector
88
64
"""
89
65
return len (self .__components )
90
66
91
- def euclidLength (self ) -> float :
67
+ def __str__ (self ) -> str :
92
68
"""
93
- returns the euclidean length of the vector
69
+ returns a string representation of the vector
94
70
"""
95
- summe : float = 0
96
- for c in self .__components :
97
- summe += c ** 2
98
- return math .sqrt (summe )
71
+ return "(" + "," .join (map (str , self .__components )) + ")"
99
72
100
73
def __add__ (self , other : Vector ) -> Vector :
101
74
"""
@@ -139,15 +112,57 @@ def __mul__(self, other: float | Vector) -> float | Vector:
139
112
if isinstance (other , float ) or isinstance (other , int ):
140
113
ans = [c * other for c in self .__components ]
141
114
return Vector (ans )
142
- elif isinstance (other , Vector ) and ( len (self ) == len (other ) ):
115
+ elif isinstance (other , Vector ) and len (self ) == len (other ):
143
116
size = len (self )
144
- summe : float = 0
145
- for i in range (size ):
146
- summe += self .__components [i ] * other .component (i )
147
- return summe
117
+ prods = [self .__components [i ] * other .component (i ) for i in range (size )]
118
+ return sum (prods )
148
119
else : # error case
149
120
raise Exception ("invalid operand!" )
150
121
122
+ def set (self , components : Collection [float ]) -> None :
123
+ """
124
+ input: new components
125
+ changes the components of the vector.
126
+ replaces the components with newer one.
127
+ """
128
+ if len (components ) > 0 :
129
+ self .__components = list (components )
130
+ else :
131
+ raise Exception ("please give any vector" )
132
+
133
+ def copy (self ) -> Vector :
134
+ """
135
+ copies this vector and returns it.
136
+ """
137
+ return Vector (self .__components )
138
+
139
+ def component (self , i : int ) -> float :
140
+ """
141
+ input: index (0-indexed)
142
+ output: the i-th component of the vector.
143
+ """
144
+ if type (i ) is int and - len (self .__components ) <= i < len (self .__components ):
145
+ return self .__components [i ]
146
+ else :
147
+ raise Exception ("index out of range" )
148
+
149
+ def change_component (self , pos : int , value : float ) -> None :
150
+ """
151
+ input: an index (pos) and a value
152
+ changes the specified component (pos) with the
153
+ 'value'
154
+ """
155
+ # precondition
156
+ assert - len (self .__components ) <= pos < len (self .__components )
157
+ self .__components [pos ] = value
158
+
159
+ def euclidean_length (self ) -> float :
160
+ """
161
+ returns the euclidean length of the vector
162
+ """
163
+ squares = [c ** 2 for c in self .__components ]
164
+ return math .sqrt (sum (squares ))
165
+
151
166
def magnitude (self ) -> float :
152
167
"""
153
168
Magnitude of a Vector
@@ -156,7 +171,8 @@ def magnitude(self) -> float:
156
171
5.385164807134504
157
172
158
173
"""
159
- return sum ([i ** 2 for i in self .__components ]) ** (1 / 2 )
174
+ squares = [c ** 2 for c in self .__components ]
175
+ return math .sqrt (sum (squares ))
160
176
161
177
def angle (self , other : Vector , deg : bool = False ) -> float :
162
178
"""
@@ -178,24 +194,8 @@ def angle(self, other: Vector, deg: bool = False) -> float:
178
194
else :
179
195
return math .acos (num / den )
180
196
181
- def copy (self ) -> Vector :
182
- """
183
- copies this vector and returns it.
184
- """
185
- return Vector (self .__components )
186
-
187
- def changeComponent (self , pos : int , value : float ) -> None :
188
- """
189
- input: an index (pos) and a value
190
- changes the specified component (pos) with the
191
- 'value'
192
- """
193
- # precondition
194
- assert - len (self .__components ) <= pos < len (self .__components )
195
- self .__components [pos ] = value
196
197
197
-
198
- def zeroVector (dimension : int ) -> Vector :
198
+ def zero_vector (dimension : int ) -> Vector :
199
199
"""
200
200
returns a zero-vector of size 'dimension'
201
201
"""
@@ -204,7 +204,7 @@ def zeroVector(dimension: int) -> Vector:
204
204
return Vector ([0 ] * dimension )
205
205
206
206
207
- def unitBasisVector (dimension : int , pos : int ) -> Vector :
207
+ def unit_basis_vector (dimension : int , pos : int ) -> Vector :
208
208
"""
209
209
returns a unit basis vector with a One
210
210
at index 'pos' (indexing at 0)
@@ -225,40 +225,44 @@ def axpy(scalar: float, x: Vector, y: Vector) -> Vector:
225
225
# precondition
226
226
assert (
227
227
isinstance (x , Vector )
228
- and ( isinstance (y , Vector ) )
228
+ and isinstance (y , Vector )
229
229
and (isinstance (scalar , int ) or isinstance (scalar , float ))
230
230
)
231
231
return x * scalar + y
232
232
233
233
234
- def randomVector ( N : int , a : int , b : int ) -> Vector :
234
+ def random_vector ( n : int , a : int , b : int ) -> Vector :
235
235
"""
236
236
input: size (N) of the vector.
237
237
random range (a,b)
238
238
output: returns a random vector of size N, with
239
239
random integer components between 'a' and 'b'.
240
240
"""
241
241
random .seed (None )
242
- ans = [random .randint (a , b ) for _ in range (N )]
242
+ ans = [random .randint (a , b ) for _ in range (n )]
243
243
return Vector (ans )
244
244
245
245
246
246
class Matrix :
247
247
"""
248
248
class: Matrix
249
- This class represents a arbitrary matrix.
250
-
251
- Overview about the methods:
252
-
253
- __str__() : returns a string representation
254
- operator * : implements the matrix vector multiplication
255
- implements the matrix-scalar multiplication.
256
- changeComponent(x,y,value) : changes the specified component.
257
- component(x,y) : returns the specified component.
258
- width() : returns the width of the matrix
259
- height() : returns the height of the matrix
260
- operator + : implements the matrix-addition.
261
- operator - _ implements the matrix-subtraction
249
+ This class represents an arbitrary matrix.
250
+
251
+ Overview of the methods:
252
+
253
+ __init__():
254
+ __str__(): returns a string representation
255
+ __add__(other: Matrix): matrix addition
256
+ __sub__(other: Matrix): matrix subtraction
257
+ __mul__(other: float): scalar multiplication
258
+ __mul__(other: Vector): vector multiplication
259
+ height() : returns height
260
+ width() : returns width
261
+ component(x: int, y: int): returns specified component
262
+ change_component(x: int, y: int, value: float): changes specified component
263
+ minor(x: int, y: int): returns minor along (x, y)
264
+ cofactor(x: int, y: int): returns cofactor along (x, y)
265
+ determinant() : returns determinant
262
266
"""
263
267
264
268
def __init__ (self , matrix : list [list [float ]], w : int , h : int ) -> None :
@@ -285,62 +289,37 @@ def __str__(self) -> str:
285
289
ans += str (self .__matrix [i ][j ]) + "|\n "
286
290
return ans
287
291
288
- def changeComponent (self , x : int , y : int , value : float ) -> None :
289
- """
290
- changes the x-y component of this matrix
291
- """
292
- if 0 <= x < self .__height and 0 <= y < self .__width :
293
- self .__matrix [x ][y ] = value
294
- else :
295
- raise Exception ("changeComponent: indices out of bounds" )
296
-
297
- def component (self , x : int , y : int ) -> float :
292
+ def __add__ (self , other : Matrix ) -> Matrix :
298
293
"""
299
- returns the specified (x,y) component
294
+ implements the matrix-addition.
300
295
"""
301
- if 0 <= x < self .__height and 0 <= y < self .__width :
302
- return self .__matrix [x ][y ]
296
+ if self .__width == other .width () and self .__height == other .height ():
297
+ matrix = []
298
+ for i in range (self .__height ):
299
+ row = [
300
+ self .__matrix [i ][j ] + other .component (i , j )
301
+ for j in range (self .__width )
302
+ ]
303
+ matrix .append (row )
304
+ return Matrix (matrix , self .__width , self .__height )
303
305
else :
304
- raise Exception ("changeComponent: indices out of bounds" )
305
-
306
- def width (self ) -> int :
307
- """
308
- getter for the width
309
- """
310
- return self .__width
306
+ raise Exception ("matrix must have the same dimension!" )
311
307
312
- def height (self ) -> int :
308
+ def __sub__ (self , other : Matrix ) -> Matrix :
313
309
"""
314
- getter for the height
310
+ implements the matrix-subtraction.
315
311
"""
316
- return self .__height
317
-
318
- def determinate (self ) -> float :
319
- """
320
- returns the determinate of an nxn matrix using Laplace expansion
321
- """
322
- if self .__height == self .__width and self .__width >= 2 :
323
- total = 0
324
- if self .__width > 2 :
325
- for x in range (0 , self .__width ):
326
- for y in range (0 , self .__height ):
327
- total += (
328
- self .__matrix [x ][y ]
329
- * (- 1 ) ** (x + y )
330
- * Matrix (
331
- self .__matrix [0 :x ] + self .__matrix [x + 1 :],
332
- self .__width - 1 ,
333
- self .__height - 1 ,
334
- ).determinate ()
335
- )
336
- else :
337
- return (
338
- self .__matrix [0 ][0 ] * self .__matrix [1 ][1 ]
339
- - self .__matrix [0 ][1 ] * self .__matrix [1 ][0 ]
340
- )
341
- return total
312
+ if self .__width == other .width () and self .__height == other .height ():
313
+ matrix = []
314
+ for i in range (self .__height ):
315
+ row = [
316
+ self .__matrix [i ][j ] - other .component (i , j )
317
+ for j in range (self .__width )
318
+ ]
319
+ matrix .append (row )
320
+ return Matrix (matrix , self .__width , self .__height )
342
321
else :
343
- raise Exception ("matrix is not square " )
322
+ raise Exception ("matrices must have the same dimension! " )
344
323
345
324
@overload
346
325
def __mul__ (self , other : float ) -> Matrix :
@@ -355,20 +334,20 @@ def __mul__(self, other: float | Vector) -> Vector | Matrix:
355
334
implements the matrix-vector multiplication.
356
335
implements the matrix-scalar multiplication
357
336
"""
358
- if isinstance (other , Vector ): # vector- matrix
337
+ if isinstance (other , Vector ): # matrix-vector
359
338
if len (other ) == self .__width :
360
- ans = zeroVector (self .__height )
339
+ ans = zero_vector (self .__height )
361
340
for i in range (self .__height ):
362
- summe : float = 0
363
- for j in range ( self .__width ):
364
- summe += other . component ( j ) * self .__matrix [ i ][ j ]
365
- ans . changeComponent ( i , summe )
366
- summe = 0
341
+ prods = [
342
+ self .__matrix [ i ][ j ] * other . component ( j )
343
+ for j in range ( self .__width )
344
+ ]
345
+ ans . change_component ( i , sum ( prods ))
367
346
return ans
368
347
else :
369
348
raise Exception (
370
349
"vector must have the same size as the "
371
- + "number of columns of the matrix!"
350
+ "number of columns of the matrix!"
372
351
)
373
352
elif isinstance (other , int ) or isinstance (other , float ): # matrix-scalar
374
353
matrix = [
@@ -377,52 +356,95 @@ def __mul__(self, other: float | Vector) -> Vector | Matrix:
377
356
]
378
357
return Matrix (matrix , self .__width , self .__height )
379
358
380
- def __add__ (self , other : Matrix ) -> Matrix :
359
+ def height (self ) -> int :
381
360
"""
382
- implements the matrix-addition.
361
+ getter for the height
383
362
"""
384
- if self .__width == other .width () and self .__height == other .height ():
385
- matrix = []
386
- for i in range (self .__height ):
387
- row = []
388
- for j in range (self .__width ):
389
- row .append (self .__matrix [i ][j ] + other .component (i , j ))
390
- matrix .append (row )
391
- return Matrix (matrix , self .__width , self .__height )
363
+ return self .__height
364
+
365
+ def width (self ) -> int :
366
+ """
367
+ getter for the width
368
+ """
369
+ return self .__width
370
+
371
+ def component (self , x : int , y : int ) -> float :
372
+ """
373
+ returns the specified (x,y) component
374
+ """
375
+ if 0 <= x < self .__height and 0 <= y < self .__width :
376
+ return self .__matrix [x ][y ]
392
377
else :
393
- raise Exception ("matrix must have the same dimension! " )
378
+ raise Exception ("change_component: indices out of bounds " )
394
379
395
- def __sub__ (self , other : Matrix ) -> Matrix :
380
+ def change_component (self , x : int , y : int , value : float ) -> None :
396
381
"""
397
- implements the matrix-subtraction.
382
+ changes the x-y component of this matrix
398
383
"""
399
- if self .__width == other .width () and self .__height == other .height ():
400
- matrix = []
401
- for i in range (self .__height ):
402
- row = []
403
- for j in range (self .__width ):
404
- row .append (self .__matrix [i ][j ] - other .component (i , j ))
405
- matrix .append (row )
406
- return Matrix (matrix , self .__width , self .__height )
384
+ if 0 <= x < self .__height and 0 <= y < self .__width :
385
+ self .__matrix [x ][y ] = value
407
386
else :
408
- raise Exception ("matrix must have the same dimension!" )
387
+ raise Exception ("change_component: indices out of bounds" )
388
+
389
+ def minor (self , x : int , y : int ) -> float :
390
+ """
391
+ returns the minor along (x, y)
392
+ """
393
+ if self .__height != self .__width :
394
+ raise Exception ("Matrix is not square" )
395
+ minor = self .__matrix [:x ] + self .__matrix [x + 1 :]
396
+ for i in range (len (minor )):
397
+ minor [i ] = minor [i ][:y ] + minor [i ][y + 1 :]
398
+ return Matrix (minor , self .__width - 1 , self .__height - 1 ).determinant ()
399
+
400
+ def cofactor (self , x : int , y : int ) -> float :
401
+ """
402
+ returns the cofactor (signed minor) along (x, y)
403
+ """
404
+ if self .__height != self .__width :
405
+ raise Exception ("Matrix is not square" )
406
+ if 0 <= x < self .__height and 0 <= y < self .__width :
407
+ return (- 1 ) ** (x + y ) * self .minor (x , y )
408
+ else :
409
+ raise Exception ("Indices out of bounds" )
410
+
411
+ def determinant (self ) -> float :
412
+ """
413
+ returns the determinant of an nxn matrix using Laplace expansion
414
+ """
415
+ if self .__height != self .__width :
416
+ raise Exception ("Matrix is not square" )
417
+ if self .__height < 1 :
418
+ raise Exception ("Matrix has no element" )
419
+ elif self .__height == 1 :
420
+ return self .__matrix [0 ][0 ]
421
+ elif self .__height == 2 :
422
+ return (
423
+ self .__matrix [0 ][0 ] * self .__matrix [1 ][1 ]
424
+ - self .__matrix [0 ][1 ] * self .__matrix [1 ][0 ]
425
+ )
426
+ else :
427
+ cofactor_prods = [
428
+ self .__matrix [0 ][y ] * self .cofactor (0 , y ) for y in range (self .__width )
429
+ ]
430
+ return sum (cofactor_prods )
409
431
410
432
411
- def squareZeroMatrix ( N : int ) -> Matrix :
433
+ def square_zero_matrix ( n : int ) -> Matrix :
412
434
"""
413
435
returns a square zero-matrix of dimension NxN
414
436
"""
415
- ans : list [list [float ]] = [[0 ] * N for _ in range (N )]
416
- return Matrix (ans , N , N )
437
+ ans : list [list [float ]] = [[0 ] * n for _ in range (n )]
438
+ return Matrix (ans , n , n )
417
439
418
440
419
- def randomMatrix ( W : int , H : int , a : int , b : int ) -> Matrix :
441
+ def random_matrix ( width : int , height : int , a : int , b : int ) -> Matrix :
420
442
"""
421
443
returns a random matrix WxH with integer components
422
444
between 'a' and 'b'
423
445
"""
424
446
random .seed (None )
425
447
matrix : list [list [float ]] = [
426
- [random .randint (a , b ) for _ in range (W )] for _ in range (H )
448
+ [random .randint (a , b ) for _ in range (width )] for _ in range (height )
427
449
]
428
- return Matrix (matrix , W , H )
450
+ return Matrix (matrix , width , height )
0 commit comments