-
Notifications
You must be signed in to change notification settings - Fork 110
Expand file tree
/
Copy pathvector.py
More file actions
150 lines (116 loc) · 3.66 KB
/
vector.py
File metadata and controls
150 lines (116 loc) · 3.66 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
147
148
149
150
"""
Implements mainly the Vector class. See its documentation.
"""
class VectorError(Exception):
"""
An exception to use with Vector
"""
def __init__(self, msg):
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) or isinstance(other, float)):
raise VectorError("right hand side is illegal")
return Vector(map(lambda x: x * other, self))
def __rmul__(self, other):
return self * other
def __div__(self, other):
if not (isinstance(other, int) or isinstance(other, float)):
raise VectorError("right hand side is illegal")
return Vector(map(lambda x: x / other, self))
def __rdiv__(self, other):
raise VectorError("you sick pervert! "
"you tried to 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 fucked up operator precedence.
"""
if not isinstance(other, Vector):
raise VectorError("trying to do dot product of Vector "
"with non-Vector")
"""
if self.dim()!=other.dim():
raise("trying to do dot product of Vectors of unequal "
"dimension!")
"""
d = self.dim()
s = 0.
for i in range(d):
s += self[i] * other[i]
return s
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(n):
"""
Returns a zero Vector of length n.
"""
return Vector(map(lambda x: 0., range(n)))
def ones(n):
"""
Returns a Vector of length n with all ones.
"""
return Vector(map(lambda x: 1., range(n)))