Functions
>>> from vector import vecadd
>>> a = (5, 6, 7)
>>> b = [2]
>>> c = range(4)
>>> vecadd(a, b, c)
(7, 7, 9, 3)
Prefixed by vec...
(vector).
All functions accept vectors as single exhaustible iterables.
They return vectors as tuples.
Padding is done with int(0)
.
The functions are type-independent. However, the data types used must
support necessary scalar operations. For instance, for vector addition,
coefficients must be addable — this may include operations with padded integer
zeros. Empty operations return the zero vector (e.g. vecadd()==veczero
) or
integer zeros (e.g. vecdot(veczero, veczero)==int(0)
).
Creation
veczero = ()
Zero vector.
\[
\vec{0} \qquad \mathbb{K}^0
\]
vecbasis(i, c=1)
Return the i
-th basis vector times c
.
\[
c\vec{e}_i \qquad \mathbb{K}^{i+1}
\]
Returns a tuple with i
zeros followed by c
.
Source code in vector\functional.py
33
34
35
36
37
38
39
40
41
42 | def vecbasis(i, c=1):
r"""Return the `i`-th basis vector times `c`.
$$
c\vec{e}_i \qquad \mathbb{K}^{i+1}
$$
Returns a tuple with `i` zeros followed by `c`.
"""
return (0,)*i + (c,)
|
vecbasisgen()
Yield all basis vectors.
\[
\left(\vec{e}_n\right)_\mathbb{n\in\mathbb{N_0}} = \left(\vec{e}_0, \vec{e}_1, \vec{e}_2, \dots \right)
\]
See also
Source code in vector\functional.py
44
45
46
47
48
49
50
51
52
53
54
55
56 | def vecbasisgen():
r"""Yield all basis vectors.
$$
\left(\vec{e}_n\right)_\mathbb{n\in\mathbb{N_0}} = \left(\vec{e}_0, \vec{e}_1, \vec{e}_2, \dots \right)
$$
See also
--------
- for single basis vector: [`vecbasis`][vector.functional.vecbasis]
"""
for i in count():
yield vecbasis(i)
|
vecrand(n)
Return a random vector of n
uniform float
coefficients in [0, 1[
.
\[
\vec{v}\sim\mathcal{U}^n([0, 1[) \qquad \mathbb{K}^n
\]
Notes
Naming like in numpy.random
, because seems more concise
(not random
& gauss
as in the stdlib).
Source code in vector\functional.py
58
59
60
61
62
63
64
65
66
67
68
69
70 | def vecrand(n):
r"""Return a random vector of `n` uniform `float` coefficients in `[0, 1[`.
$$
\vec{v}\sim\mathcal{U}^n([0, 1[) \qquad \mathbb{K}^n
$$
Notes
-----
Naming like in `numpy.random`, because seems more concise
(not `random` & `gauss` as in the stdlib).
"""
return tuple(random() for _ in range(n))
|
vecrandn(n, normed=True, mu=0, sigma=1)
Return a random vector of n
normal distributed float
coefficients.
\[
\vec{v}\sim\mathcal{N}^n(\mu, \sigma) \qquad \mathbb{K}^n
\]
Notes
Naming like in numpy.random
, because seems more concise
(not random
& gauss
as in the stdlib).
Source code in vector\functional.py
72
73
74
75
76
77
78
79
80
81
82
83
84
85 | def vecrandn(n, normed=True, mu=0, sigma=1):
r"""Return a random vector of `n` normal distributed `float` coefficients.
$$
\vec{v}\sim\mathcal{N}^n(\mu, \sigma) \qquad \mathbb{K}^n
$$
Notes
-----
Naming like in `numpy.random`, because seems more concise
(not `random` & `gauss` as in the stdlib).
"""
v = tuple(gauss(mu, sigma) for _ in range(n))
return vectruediv(v, vecabs(v)) if normed else v
|
Utility
veceq(v, w)
Return if two vectors are equal.
\[
\vec{v}=\vec{w} \qquad \mathbb{K}^m\times\mathbb{K}^n\to\mathbb{B}
\]
Source code in vector\functional.py
| def veceq(v, w):
r"""Return if two vectors are equal.
$$
\vec{v}=\vec{w} \qquad \mathbb{K}^m\times\mathbb{K}^n\to\mathbb{B}
$$
"""
return all(starmap(eq, zip_longest(v, w, fillvalue=0)))
|
vectrim(v, tol=1e-09)
Remove all trailing near zero (abs(v_i)<=tol
) coefficients.
\[
\begin{pmatrix}
v_0 \\
\vdots \\
v_m
\end{pmatrix} \ \text{where} \ m=\max\{\, j\mid |v_{j-1}|>\text{tol}\,\}\cup\{-1\} \qquad \mathbb{K}^n\to\mathbb{K}^{\leq n}
\]
Notes
- Cutting of elements that are
abs(vi)<=tol
instead of abs(vi)<tol
to
allow cutting of elements that are exactly zero by trim(v, 0)
instead
of trim(v, sys.float_info.min)
.
tol=1e-9
like in PEP 485.
Source code in vector\functional.py
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 | def vectrim(v, tol=1e-9):
r"""Remove all trailing near zero (`abs(v_i)<=tol`) coefficients.
$$
\begin{pmatrix}
v_0 \\
\vdots \\
v_m
\end{pmatrix} \ \text{where} \ m=\max\{\, j\mid |v_{j-1}|>\text{tol}\,\}\cup\{-1\} \qquad \mathbb{K}^n\to\mathbb{K}^{\leq n}
$$
Notes
-----
- Cutting of elements that are `abs(vi)<=tol` instead of `abs(vi)<tol` to
allow cutting of elements that are exactly zero by `trim(v, 0)` instead
of `trim(v, sys.float_info.min)`.
- `tol=1e-9` like in [PEP 485](https://peps.python.org/pep-0485/#defaults).
"""
#doesn't work for iterators
#while v and abs(v[-1])<=tol:
# v = v[:-1]
#return v
r, t = [], []
for x in v:
t.append(x)
if abs(x)>tol:
r.extend(t)
t.clear()
return tuple(r)
|
vecround(v, ndigits=None)
Round all coefficients to the given precision.
\[
(\text{round}_\text{ndigits}(v_i))_i \qquad \mathbb{K}^n\to\mathbb{K}^n
\]
Source code in vector\functional.py
128
129
130
131
132
133
134
135 | def vecround(v, ndigits=None):
r"""Round all coefficients to the given precision.
$$
(\text{round}_\text{ndigits}(v_i))_i \qquad \mathbb{K}^n\to\mathbb{K}^n
$$
"""
return tuple(round(c, ndigits) for c in v)
|
vecrshift(v, n, fill=0)
Pad n
many fill
s to the beginning of the vector.
\[
(v_{i-n})_i \qquad \begin{pmatrix}
0 \\
\vdots \\
0 \\
v_0 \\
v_1 \\
\vdots
\end{pmatrix} \qquad \mathbb{K}^m\to\mathbb{K}^{m+n}
\]
Source code in vector\functional.py
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151 | def vecrshift(v, n, fill=0):
r"""Pad `n` many `fill`s to the beginning of the vector.
$$
(v_{i-n})_i \qquad \begin{pmatrix}
0 \\
\vdots \\
0 \\
v_0 \\
v_1 \\
\vdots
\end{pmatrix} \qquad \mathbb{K}^m\to\mathbb{K}^{m+n}
$$
"""
return tuple(chain((fill,)*n, v))
|
veclshift(v, n)
Remove n
many coefficients at the beginning of the vector.
\[
(v_{i+n})_i \qquad \begin{pmatrix}
v_n \\
v_{n+1} \\
\vdots
\end{pmatrix} \qquad \mathbb{K}^m\to\mathbb{K}^{\max\{m-n, 0\}}
\]
Source code in vector\functional.py
153
154
155
156
157
158
159
160
161
162
163
164 | def veclshift(v, n):
r"""Remove `n` many coefficients at the beginning of the vector.
$$
(v_{i+n})_i \qquad \begin{pmatrix}
v_n \\
v_{n+1} \\
\vdots
\end{pmatrix} \qquad \mathbb{K}^m\to\mathbb{K}^{\max\{m-n, 0\}}
$$
"""
return tuple(islice(v, n, None))
|
Hilbert space
vecabsq(v)
Return the sum of absolute squares of the coefficients.
\[
||\vec{v}||_{\ell_{\mathbb{N}_0}^2}^2=\sum_i|v_i|^2 \qquad \mathbb{K}^n\to\mathbb{K}_0^+
\]
Notes
Reasons why it exists:
- Occurs in math.
- Most importantly: type independent because it doesn't use
sqrt
.
References
Source code in vector\functional.py
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187 | def vecabsq(v):
r"""Return the sum of absolute squares of the coefficients.
$$
||\vec{v}||_{\ell_{\mathbb{N}_0}^2}^2=\sum_i|v_i|^2 \qquad \mathbb{K}^n\to\mathbb{K}_0^+
$$
Notes
-----
Reasons why it exists:
- Occurs in math.
- Most importantly: type independent because it doesn't use `sqrt`.
References
----------
- <https://docs.python.org/3/library/itertools.html#itertools-recipes>: `sum_of_squares`
"""
#return sumprod(v, v) #no abs
return sumprod(*tee(map(abs, v), 2))
|
vecabs(v)
Return the Euclidean/L2-norm.
\[
||\vec{v}||_{\ell_{\mathbb{N}_0}^2}=\sqrt{\sum_i|v_i|^2} \qquad \mathbb{K}^n\to\mathbb{K}_0^+
\]
Returns the square root of vecabsq
.
Source code in vector\functional.py
189
190
191
192
193
194
195
196
197
198
199
200
201 | def vecabs(v):
r"""Return the Euclidean/L2-norm.
$$
||\vec{v}||_{\ell_{\mathbb{N}_0}^2}=\sqrt{\sum_i|v_i|^2} \qquad \mathbb{K}^n\to\mathbb{K}_0^+
$$
Returns the square root of [`vecabsq`][vector.functional.vecabsq].
"""
#hypot(*v) doesn't work for complex
#math.sqrt doesn't work for complex and cmath.sqrt always returns complex
#therefore use **0.5 instead of sqrt because it is type conserving
return vecabsq(v)**0.5
|
vecdot(v, w)
Return the inner product of two vectors without conjugation.
\[
\left<\vec{v}\mid\vec{w}\right>_{\ell_{\mathbb{N}_0}^2}=\sum_iv_iw_i \qquad \mathbb{K}^m\times\mathbb{K}^n\to\mathbb{K}
\]
Source code in vector\functional.py
203
204
205
206
207
208
209
210
211
212
213 | def vecdot(v, w):
r"""Return the inner product of two vectors without conjugation.
$$
\left<\vec{v}\mid\vec{w}\right>_{\ell_{\mathbb{N}_0}^2}=\sum_iv_iw_i \qquad \mathbb{K}^m\times\mathbb{K}^n\to\mathbb{K}
$$
"""
#unreadable and doesn't work for generators
#return sumprod(v[:min(len(v), len(w))], w[:min(len(v), len(w))])
#return sumprod(*zip(*zip(v, w))) #would be more precise, but is bloat
return sum(map(mul, v, w))
|
vecparallel(v, w)
Return if two vectors are parallel.
\[
\vec{v}\parallel\vec{w} \qquad ||\vec{v}||\,||\vec{w}|| \overset{?}{=} |\vec{v}\vec{w}|^2 \qquad \mathbb{K}^m\times\mathbb{K}^n\to\mathbb{B}
\]
Source code in vector\functional.py
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231 | def vecparallel(v, w):
r"""Return if two vectors are parallel.
$$
\vec{v}\parallel\vec{w} \qquad ||\vec{v}||\,||\vec{w}|| \overset{?}{=} |\vec{v}\vec{w}|^2 \qquad \mathbb{K}^m\times\mathbb{K}^n\to\mathbb{B}
$$
"""
#doesn't work for exhaustible iterables
#return vecabsq(v)*vecabsq(w) == abs(vecdot(v, w))**2
v2, w2, vw = 0, 0, 0
for vi, wi in zip_longest(v, w, fillvalue=0):
via, wia = abs(vi), abs(wi)
v2 += via * via
w2 += wia * wia
vw += vi * wi
vw = abs(vw)
return v2 * w2 == vw * vw
|
Vector space
vecpos(v)
Return the vector with the unary positive operator applied.
\[
+\vec{v} \qquad \mathbb{K}^n\to\mathbb{K}^n
\]
Source code in vector\functional.py
235
236
237
238
239
240
241
242 | def vecpos(v):
r"""Return the vector with the unary positive operator applied.
$$
+\vec{v} \qquad \mathbb{K}^n\to\mathbb{K}^n
$$
"""
return tuple(map(pos, v))
|
vecneg(v)
Return the vector with the unary negative operator applied.
\[
-\vec{v} \qquad \mathbb{K}^n\to\mathbb{K}^n
\]
Source code in vector\functional.py
244
245
246
247
248
249
250
251 | def vecneg(v):
r"""Return the vector with the unary negative operator applied.
$$
-\vec{v} \qquad \mathbb{K}^n\to\mathbb{K}^n
$$
"""
return tuple(map(neg, v))
|
vecadd(*vs)
Return the sum of vectors.
\[
\vec{v}_0+\vec{v}_1+\cdots \qquad \mathbb{K}^{n_0}\times\mathbb{K}^{n_1}\times\cdots\to\mathbb{K}^{\max_i n_i}
\]
Source code in vector\functional.py
253
254
255
256
257
258
259
260 | def vecadd(*vs):
r"""Return the sum of vectors.
$$
\vec{v}_0+\vec{v}_1+\cdots \qquad \mathbb{K}^{n_0}\times\mathbb{K}^{n_1}\times\cdots\to\mathbb{K}^{\max_i n_i}
$$
"""
return tuple(map(sum, zip_longest(*vs, fillvalue=0)))
|
vecaddc(v, c, i=0)
Return v
with c
added to the i
-th coefficient.
\[
\vec{v}+c\vec{e}_i \qquad \mathbb{K}^n\to\mathbb{K}^{\max\{n, i\}}
\]
More efficient than vecadd(v, vecbasis(i, c))
.
Source code in vector\functional.py
262
263
264
265
266
267
268
269
270
271
272
273
274 | def vecaddc(v, c, i=0):
r"""Return `v` with `c` added to the `i`-th coefficient.
$$
\vec{v}+c\vec{e}_i \qquad \mathbb{K}^n\to\mathbb{K}^{\max\{n, i\}}
$$
More efficient than `vecadd(v, vecbasis(i, c))`.
"""
v = list(v)
v.extend([0] * (i-len(v)+1))
v[i] += c
return tuple(v)
|
vecsub(v, w)
Return the difference of two vectors.
\[
\vec{v}-\vec{w} \qquad \mathbb{K}^m\times\mathbb{K}^n\to\mathbb{K}^{\max\{m, n\}}
\]
Source code in vector\functional.py
276
277
278
279
280
281
282
283 | def vecsub(v, w):
r"""Return the difference of two vectors.
$$
\vec{v}-\vec{w} \qquad \mathbb{K}^m\times\mathbb{K}^n\to\mathbb{K}^{\max\{m, n\}}
$$
"""
return tuple(starmap(sub, zip_longest(v, w, fillvalue=0)))
|
vecmul(a, v)
Return the product of a scalar and a vector.
\[
a\vec{v} \qquad \mathbb{K}\times\mathbb{K}^n\to\mathbb{K}^n
\]
Source code in vector\functional.py
285
286
287
288
289
290
291
292 | def vecmul(a, v):
r"""Return the product of a scalar and a vector.
$$
a\vec{v} \qquad \mathbb{K}\times\mathbb{K}^n\to\mathbb{K}^n
$$
"""
return tuple(map(mul, repeat(a), v))
|
vectruediv(v, a)
Return the true division of a vector and a scalar.
\[
\frac{\vec{v}}{a} \qquad \mathbb{K}^n\times\mathbb{K}\to\mathbb{K}^n
\]
Notes
Why called truediv
instead of div
?
div
would be more appropriate for an absolute clean mathematical
implementation, that doesn't care about the language used. But the package
might be used for pure integers/integer arithmetic, so both, truediv
and floordiv
operations have to be provided, and none should be
privileged over the other by getting the universal div
name.
truediv
/floordiv
is unambiguous, like Python operator
s.
Source code in vector\functional.py
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312 | def vectruediv(v, a):
r"""Return the true division of a vector and a scalar.
$$
\frac{\vec{v}}{a} \qquad \mathbb{K}^n\times\mathbb{K}\to\mathbb{K}^n
$$
Notes
-----
Why called `truediv` instead of `div`?
- `div` would be more appropriate for an absolute clean mathematical
implementation, that doesn't care about the language used. But the package
might be used for pure integers/integer arithmetic, so both, `truediv`
and `floordiv` operations have to be provided, and none should be
privileged over the other by getting the universal `div` name.
- `truediv`/`floordiv` is unambiguous, like Python `operator`s.
"""
return tuple(map(truediv, v, repeat(a)))
|
vecfloordiv(v, a)
Return the floor division of a vector and a scalar.
\[
\left(\left\lfloor\frac{v_i}{a}\right\rfloor\right)_i \qquad \mathbb{K}^n\times\mathbb{K}\to\mathbb{K}^n
\]
Source code in vector\functional.py
314
315
316
317
318
319
320
321 | def vecfloordiv(v, a):
r"""Return the floor division of a vector and a scalar.
$$
\left(\left\lfloor\frac{v_i}{a}\right\rfloor\right)_i \qquad \mathbb{K}^n\times\mathbb{K}\to\mathbb{K}^n
$$
"""
return tuple(map(floordiv, v, repeat(a)))
|
vecmod(v, a)
Return the elementwise mod of a vector and a scalar.
\[
\left(v_i \mod a\right)_i \qquad \mathbb{K}^n\times\mathbb{K}\to\mathbb{K}^n
\]
Source code in vector\functional.py
323
324
325
326
327
328
329
330 | def vecmod(v, a):
r"""Return the elementwise mod of a vector and a scalar.
$$
\left(v_i \mod a\right)_i \qquad \mathbb{K}^n\times\mathbb{K}\to\mathbb{K}^n
$$
"""
return tuple(map(mod, v, repeat(a)))
|
vecdivmod(v, a)
Return the elementwise divmod of a vector and a scalar.
\[
\left(\left\lfloor\frac{v_i}{a}\right\rfloor\right)_i, \ \left(v_i \mod a\right)_i \qquad \mathbb{K}^n\times\mathbb{K}\to\mathbb{K}^n\times\mathbb{K}^n
\]
Source code in vector\functional.py
332
333
334
335
336
337
338
339
340
341
342
343
344 | def vecdivmod(v, a):
r"""Return the elementwise divmod of a vector and a scalar.
$$
\left(\left\lfloor\frac{v_i}{a}\right\rfloor\right)_i, \ \left(v_i \mod a\right)_i \qquad \mathbb{K}^n\times\mathbb{K}\to\mathbb{K}^n\times\mathbb{K}^n
$$
"""
q, r = [], []
for vi in v:
qi, ri = divmod(vi, a)
q.append(qi)
r.append(ri)
return tuple(q), tuple(r)
|
Elementwise
vechadamard(*vs)
Return the elementwise product of vectors.
\[
\left((\vec{v}_0)_i\cdot(\vec{v}_1)_i\cdot\cdots\right)_i \qquad \mathbb{K}^{n_0}\times\mathbb{K}^{n_1}\times\cdots\to\mathbb{K}^{\min_i n_i}
\]
Source code in vector\functional.py
348
349
350
351
352
353
354
355 | def vechadamard(*vs):
r"""Return the elementwise product of vectors.
$$
\left((\vec{v}_0)_i\cdot(\vec{v}_1)_i\cdot\cdots\right)_i \qquad \mathbb{K}^{n_0}\times\mathbb{K}^{n_1}\times\cdots\to\mathbb{K}^{\min_i n_i}
$$
"""
return tuple(map(prod, zip(*vs)))
|
vechadamardtruediv(v, w)
Return the elementwise true division of two vectors.
\[
\left(\frac{v_i}{w_i}\right)_i \qquad \mathbb{K}^m\times\mathbb{K}^n\to\mathbb{K}^m
\]
Source code in vector\functional.py
357
358
359
360
361
362
363
364 | def vechadamardtruediv(v, w):
r"""Return the elementwise true division of two vectors.
$$
\left(\frac{v_i}{w_i}\right)_i \qquad \mathbb{K}^m\times\mathbb{K}^n\to\mathbb{K}^m
$$
"""
return tuple(map(truediv, v, chain(w, repeat(0))))
|
vechadamardfloordiv(v, w)
Return the elementwise floor division of two vectors.
\[
\left(\left\lfloor\frac{v_i}{w_i}\right\rfloor\right)_i \qquad \mathbb{K}^m\times\mathbb{K}^n\to\mathbb{K}^m
\]
Source code in vector\functional.py
366
367
368
369
370
371
372
373 | def vechadamardfloordiv(v, w):
r"""Return the elementwise floor division of two vectors.
$$
\left(\left\lfloor\frac{v_i}{w_i}\right\rfloor\right)_i \qquad \mathbb{K}^m\times\mathbb{K}^n\to\mathbb{K}^m
$$
"""
return tuple(map(floordiv, v, chain(w, repeat(0))))
|
vechadamardmod(v, w)
Return the elementwise mod of two vectors.
\[
\left(v_i \mod w_i\right)_i \qquad \mathbb{K}^m\times\mathbb{K}^n\to\mathbb{K}^m
\]
Source code in vector\functional.py
375
376
377
378
379
380
381
382 | def vechadamardmod(v, w):
r"""Return the elementwise mod of two vectors.
$$
\left(v_i \mod w_i\right)_i \qquad \mathbb{K}^m\times\mathbb{K}^n\to\mathbb{K}^m
$$
"""
return tuple(map(mod, v, chain(w, repeat(0))))
|
vechadamardmin(*vs)
Return the elementwise minimum of vectors.
\[
\left(\min((\vec{v}_0)_i,(\vec{v}_1)_i,\cdots)\right)_i \qquad \mathbb{K}^{n_0}\times\mathbb{K}^{n_1}\times\cdots\to\mathbb{K}^{\max_i n_i}
\]
Source code in vector\functional.py
384
385
386
387
388
389
390
391 | def vechadamardmin(*vs):
r"""Return the elementwise minimum of vectors.
$$
\left(\min((\vec{v}_0)_i,(\vec{v}_1)_i,\cdots)\right)_i \qquad \mathbb{K}^{n_0}\times\mathbb{K}^{n_1}\times\cdots\to\mathbb{K}^{\max_i n_i}
$$
"""
return tuple(map(min, zip_longest(*vs, fillvalue=inf)))
|
vechadamardmax(*vs)
Return the elementwise maximum of vectors.
\[
\left(\max((\vec{v}_0)_i,(\vec{v}_1)_i,\cdots)\right)_i \qquad \mathbb{K}^{n_0}\times\mathbb{K}^{n_1}\times\cdots\to\mathbb{K}^{\max_i n_i}
\]
Source code in vector\functional.py
393
394
395
396
397
398
399
400 | def vechadamardmax(*vs):
r"""Return the elementwise maximum of vectors.
$$
\left(\max((\vec{v}_0)_i,(\vec{v}_1)_i,\cdots)\right)_i \qquad \mathbb{K}^{n_0}\times\mathbb{K}^{n_1}\times\cdots\to\mathbb{K}^{\max_i n_i}
$$
"""
return tuple(map(max, zip_longest(*vs, fillvalue=-inf)))
|