-
Notifications
You must be signed in to change notification settings - Fork 110
Expand file tree
/
Copy pathvector.py
More file actions
146 lines (112 loc) · 3.48 KB
/
vector.py
File metadata and controls
146 lines (112 loc) · 3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
"""
Implements mainly the Vector class. See its documentation.
"""
class VectorError(Exception):
"""
An exception to use with Vector
"""
def __init__(self, msg):
super().__init__()
self.msg = msg
def __str__(self):
return repr(self.value)
class Vector(tuple):
"""
A vector.
"""
def __init__(self, seq):
tuple.__init__(seq)
def __add__(self, other):
if not isinstance(other, Vector):
raise VectorError("right hand side is not a Vector")
return Vector(map(lambda x, y: x + y, self, other))
def __neg__(self):
return Vector(map(lambda x: -x, self))
def __pos__(self):
return self
def __sub__(self, other):
return Vector(map(lambda x, y: x - y, self, other))
def __mul__(self, other):
if not isinstance(other, (int, float)):
raise VectorError("right hand side is illegal")
return Vector(map(lambda x: x * other, self))
def __rmul__(self, other):
return self * other
def __truediv__(self, other):
if not isinstance(other, (int, float)):
raise VectorError("right hand side is illegal")
return Vector(map(lambda x: x / other, self))
@staticmethod
def __rdiv__():
raise VectorError("you can't divide something by a vector")
def __and__(self, other):
"""
this is a dot product, done like this: a&b
must use () around it because of broken operator precedence.
"""
if not isinstance(other, Vector):
raise VectorError("you can't do dot product of Vector with a "
"non-Vector")
dimension = self.dim()
size = 0.
for i in range(dimension):
size += self[i] * other[i]
return size
def __rand__(self, other):
return self & other
def __or__(self, other):
"""
cross product, defined only for 3D Vectors. goes like this: a|b
don't try this on non-3d Vectors. must use () around it because of
fucked up operator precedence.
"""
a = self
b = other
return Vector([a[1] * b[2] - a[2] * b[1],
a[2] * b[0] - a[0] * b[2],
a[0] * b[1] - a[1] * b[0]])
def __ror__(self, other):
return -(self | other)
def __abs__(self):
s = 0.
for x in self:
s += x ** 2
return s ** (1.0 / 2)
def __iadd__(self, other):
self = self + other
return self
def __isub__(self, other):
self = self - other
return self
def __imul__(self, other):
self = self * other
return self
def __idiv__(self, other):
self = self / other
return self
def __iand__(self, other):
raise VectorError("please don't do &= with my Vectors, it confuses me")
def __ior__(self, other):
self = self | other
return self
def __repr__(self):
return "Vector(" + tuple.__repr__(self) + ")"
def norm(self):
"""
gives the Vector, normalized
"""
return self / abs(self)
def dim(self):
return len(self)
def copy(self):
return Vector(self)
def zeros(length):
"""
Returns a zero Vector of length n.
"""
return Vector(map(lambda x: 0., range(length)))
def ones(length):
"""
Returns a Vector of length n with all ones.
"""
return Vector(map(lambda x: 1., range(length)))