Skip to content

Object-oriented

>>> from vector import Vector
>>> Vector((1, 2, 3))
Vector(1, 2, 3, ...)
>>> Vector.randn(3)
Vector(-0.5613820142699765, -0.028308921297709365, 0.8270724508948077, ...)
>>> Vector(3)
Vector(0, 0, 0, 1, ...)

The immutable Vector class wraps all the mentioned functions into a tidy package, making them easier to use by enabling interaction through operators.

Its coefficients are internally stored as a tuple in the coef attribute and therefore zero-indexed.

Vector operations return the same type (type(v+w)==type(v)) so the class can easily be extended (to e.g. a polynomial class).


veczero = () module-attribute

Zero vector.

\[ \vec{0} \qquad \mathbb{K}^0 \]

Vector

An infinite-dimensional vector class.

Its coefficients are internally stored as a tuple in the coef attribute.

Source code in vector\objectoriented.py
  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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
class Vector:
    """An infinite-dimensional vector class.

    Its coefficients are internally stored as a tuple in the `coef` attribute.
    """

    ZERO: 'Vector'
    """Zero vector.

    See also
    --------
    [`veczero`][vector.functional.veczero]
    """

    #creation
    def __init__(self, coef):
        """Create a new vector with the given coefficients
        or the `i`-th basis vector if an integer `i` is given.

        Notes
        -----
        - varargs (single argument=basis or multiple args=coefficients)?
        No, because then a single coefficient vector can't be distinguished
        from an index for a basis vector.
        - Automatically trim on creation?
        Nah, other functions also don't do that.
        """
        if isinstance(coef, int):
            self.coef = vecbasis(coef)
        else:
            self.coef = tuple(coef)

    @staticmethod
    def rand(n):
        """Create a random vector of `n` uniform coefficients in `[0, 1[`.

        See also
        --------
        [`vecrand`][vector.functional.vecrand]
        """
        return Vector(vecrand(n))

    @staticmethod
    def randn(n, normed=True, mu=0, sigma=1):
        """Create a random vector of `n` normal distributed coefficients.

        See also
        --------
        [`vecrandn`][vector.functional.vecrandn]
        """
        return Vector(vecrandn(n, normed, mu, sigma))


    #sequence
    def __len__(self):
        """Return the number of set coefficients."""
        return len(self.coef)

    def __getitem__(self, key):
        """Return the indexed coefficient or coefficients.

        Not set coefficients default to 0.
        """
        #getter has if and try-else
        #might access coef directly in the following methods
        #for better performance
        #on the other hand most functions access the iterator
        #that directly goes for the tuple
        if isinstance(key, slice):
            #enable stop>=len with zero padding
            if key.stop is not None and key.stop >= 0:
                l = key.stop
            else:
                l = len(self)
            return Vector(self[i] for i in range(*key.indices(l)))
        try:
            return self.coef[key]
        except IndexError:
            return 0

    def __iter__(self):
        """Return an iterator over the set coefficients."""
        return iter(self.coef)

    def __eq__(self, other):
        """Return if of same type with same coefficients.

        See also
        --------
        [`veceq`][vector.functional.veceq]
        """
        return isinstance(other, type(self)) and veceq(self, other)


    def __lshift__(self, other):
        """Return a vector with coefficients shifted to lower indices.

        See also
        --------
        [`veclshift`][vector.functional.veclshift]
        """
        return type(self)(self[other:])

    def __rshift__(self, other):
        """Return a vector with coefficients shifted to higher indices.

        See also
        --------
        [`vecrshift`][vector.functional.vecrshift]
        """
        return type(self)((0,)*other + self.coef)


    #utility
    def trim(self, tol=1e-9):
        """Remove all trailing near zero (abs<=tol) coefficients.

        See also
        --------
        [`vectrim`][vector.functional.vectrim]
        """
        return type(self)(vectrim(self, tol))

    def round(self, ndigits=None):
        """Round all coefficients to the given precision.

        See also
        --------
        [`vecround`][vector.functional.vecround]
        """
        return type(self)(vecround(self, ndigits))

    def is_parallel(self, other):
        """Return if the other vector is parallel.

        See also
        --------
        [`vecparallel`][vector.functional.vecparallel]
        """
        return vecparallel(self, other)


    #Hilbert space
    def absq(self):
        """Return the sum of absolute squares of the coefficients.

        See also
        --------
        [`vecabsq`][vector.functional.vecabsq]
        """
        return vecabsq(self)

    def __abs__(self):
        """Return the Euclidean/L2-norm.

        Return the square root of `vecabsq`.

        See also
        --------
        [`vecabs`][vector.functional.vecabs]
        """
        return self.absq()**0.5

    def __matmul__(self, other):
        """Return the real dot product of two vectors.

        No argument is complex conjugated. All coefficients are used as is.

        See also
        --------
        [`vecdot`][vector.functional.vecdot]
        """
        return vecdot(self, other)


    #vector space operations like they would be correct on paper:
    #+v, -v, v+w, v-w, av, va, v/a, v//a
    def __pos__(self):
        """Return the unary positive.

        See also
        --------
        [`vecpos`][vector.functional.vecpos]
        """
        return type(self)(vecpos(self))

    def __neg__(self):
        """Return the negative.

        See also
        --------
        [`vecneg`][vector.functional.vecneg]
        """
        return type(self)(vecneg(self))

    def __add__(self, other):
        """Return the vector sum.

        See also
        --------
        [`vecadd`][vector.functional.vecadd]
        """
        return type(self)(vecadd(self, other))
    __radd__ = __add__

    def addc(self, c, i=0):
        """Return the sum with the `i`-th basis vector times `c`.

        See also
        --------
        [`vecaddc`][vector.functional.vecaddc]
        """
        return type(self)(vecaddc(self, c, i))

    def __sub__(self, other):
        """Return the vector difference.

        See also
        --------
        [`vecsub`][vector.functional.vecsub]
        """
        return type(self)(vecsub(self, other))
    def __rsub__(self, other):
        return type(self)(vecsub(other, self))

    def __mul__(self, other):
        """Return the scalar product.

        See also
        --------
        [`vecmul`][vector.functional.vecmul]
        """
        return type(self)(vecmul(other, self))
    __rmul__ = __mul__

    def __truediv__(self, other):
        """Return the scalar true division.

        See also
        --------
        [`vectruediv`][vector.functional.vectruediv]
        """
        return type(self)(vectruediv(self, other))

    def __floordiv__(self, other):
        """Return the scalar floor division.

        See also
        --------
        [`vecfloordiv`][vector.functional.vecfloordiv]
        """
        return type(self)(vecfloordiv(self, other))

    def __mod__(self, other):
        """Return the elementwise mod with a scalar.

        See also
        --------
        [`vecmod`][vector.functional.vecmod]
        """
        return type(self)(vecmod(self, other))

    def __divmod__(self, other):
        """Return the elementwise divmod with a scalar.

        See also
        --------
        [`vecdivmod`][vector.functional.vecdivmod]
        """
        q, r = vecdivmod(self, other)
        return type(self)(q), type(self)(r)


    #elementwise
    def hadamard(self, other):
        """Return the elementwise product with another vector.

        See also
        --------
        [`vechadamard`][vector.functional.vechadamard]
        """
        return type(self)(vechadamard(self, other))

    def hadamardtruediv(self, other):
        """Return the elementwise true division with another vector.

        See also
        --------
        [`vechadamardtruediv`][vector.functional.vechadamardtruediv]
        """
        return type(self)(vechadamardtruediv(self, other))

    def hadamardfloordiv(self, other):
        """Return the elementwise floor division with another vector.

        See also
        --------
        [`vechadamardfloordiv`][vector.functional.vechadamardfloordiv]
        """
        return type(self)(vechadamardfloordiv(self, other))

    def hadamardmod(self, other):
        """Return the elementwise mod with another vector.

        See also
        --------
        [`vechadamardmod`][vector.functional.vechadamardmod]
        """
        return type(self)(vechadamardmod(self, other))

    def hadamardmin(self, other):
        """Return the elementwise minimum with another vector.

        See also
        --------
        [`vechadamardmin`][vector.functional.vechadamardmin]
        """
        return type(self)(vechadamardmin(self, other))

    def hadamardmax(self, other):
        """Return the elementwise maximum with another vector.

        See also
        --------
        [`vechadamardmax`][vector.functional.vechadamardmax]
        """
        return type(self)(vechadamardmax(self, other))


    #python stuff
    def __format__(self, format_spec):
        return 'Vector(' + ', '.join(format(c, format_spec) for c in self.coef) + ')'

    def __str__(self):
        return 'Vector(' + ', '.join(map(str, self.coef)) + ')'

ZERO instance-attribute

Zero vector.

See also

veczero

__init__(coef)

Create a new vector with the given coefficients or the i-th basis vector if an integer i is given.

Notes
  • varargs (single argument=basis or multiple args=coefficients)? No, because then a single coefficient vector can't be distinguished from an index for a basis vector.
  • Automatically trim on creation? Nah, other functions also don't do that.
Source code in vector\objectoriented.py
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
def __init__(self, coef):
    """Create a new vector with the given coefficients
    or the `i`-th basis vector if an integer `i` is given.

    Notes
    -----
    - varargs (single argument=basis or multiple args=coefficients)?
    No, because then a single coefficient vector can't be distinguished
    from an index for a basis vector.
    - Automatically trim on creation?
    Nah, other functions also don't do that.
    """
    if isinstance(coef, int):
        self.coef = vecbasis(coef)
    else:
        self.coef = tuple(coef)

rand(n) staticmethod

Create a random vector of n uniform coefficients in [0, 1[.

See also

vecrand

Source code in vector\objectoriented.py
41
42
43
44
45
46
47
48
49
@staticmethod
def rand(n):
    """Create a random vector of `n` uniform coefficients in `[0, 1[`.

    See also
    --------
    [`vecrand`][vector.functional.vecrand]
    """
    return Vector(vecrand(n))

randn(n, normed=True, mu=0, sigma=1) staticmethod

Create a random vector of n normal distributed coefficients.

See also

vecrandn

Source code in vector\objectoriented.py
51
52
53
54
55
56
57
58
59
@staticmethod
def randn(n, normed=True, mu=0, sigma=1):
    """Create a random vector of `n` normal distributed coefficients.

    See also
    --------
    [`vecrandn`][vector.functional.vecrandn]
    """
    return Vector(vecrandn(n, normed, mu, sigma))

__len__()

Return the number of set coefficients.

Source code in vector\objectoriented.py
63
64
65
def __len__(self):
    """Return the number of set coefficients."""
    return len(self.coef)

__getitem__(key)

Return the indexed coefficient or coefficients.

Not set coefficients default to 0.

Source code in vector\objectoriented.py
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
def __getitem__(self, key):
    """Return the indexed coefficient or coefficients.

    Not set coefficients default to 0.
    """
    #getter has if and try-else
    #might access coef directly in the following methods
    #for better performance
    #on the other hand most functions access the iterator
    #that directly goes for the tuple
    if isinstance(key, slice):
        #enable stop>=len with zero padding
        if key.stop is not None and key.stop >= 0:
            l = key.stop
        else:
            l = len(self)
        return Vector(self[i] for i in range(*key.indices(l)))
    try:
        return self.coef[key]
    except IndexError:
        return 0

__iter__()

Return an iterator over the set coefficients.

Source code in vector\objectoriented.py
89
90
91
def __iter__(self):
    """Return an iterator over the set coefficients."""
    return iter(self.coef)

__eq__(other)

Return if of same type with same coefficients.

See also

veceq

Source code in vector\objectoriented.py
 93
 94
 95
 96
 97
 98
 99
100
def __eq__(self, other):
    """Return if of same type with same coefficients.

    See also
    --------
    [`veceq`][vector.functional.veceq]
    """
    return isinstance(other, type(self)) and veceq(self, other)

__lshift__(other)

Return a vector with coefficients shifted to lower indices.

See also

veclshift

Source code in vector\objectoriented.py
103
104
105
106
107
108
109
110
def __lshift__(self, other):
    """Return a vector with coefficients shifted to lower indices.

    See also
    --------
    [`veclshift`][vector.functional.veclshift]
    """
    return type(self)(self[other:])

__rshift__(other)

Return a vector with coefficients shifted to higher indices.

See also

vecrshift

Source code in vector\objectoriented.py
112
113
114
115
116
117
118
119
def __rshift__(self, other):
    """Return a vector with coefficients shifted to higher indices.

    See also
    --------
    [`vecrshift`][vector.functional.vecrshift]
    """
    return type(self)((0,)*other + self.coef)

trim(tol=1e-09)

Remove all trailing near zero (abs<=tol) coefficients.

See also

vectrim

Source code in vector\objectoriented.py
123
124
125
126
127
128
129
130
def trim(self, tol=1e-9):
    """Remove all trailing near zero (abs<=tol) coefficients.

    See also
    --------
    [`vectrim`][vector.functional.vectrim]
    """
    return type(self)(vectrim(self, tol))

round(ndigits=None)

Round all coefficients to the given precision.

See also

vecround

Source code in vector\objectoriented.py
132
133
134
135
136
137
138
139
def round(self, ndigits=None):
    """Round all coefficients to the given precision.

    See also
    --------
    [`vecround`][vector.functional.vecround]
    """
    return type(self)(vecround(self, ndigits))

is_parallel(other)

Return if the other vector is parallel.

See also

vecparallel

Source code in vector\objectoriented.py
141
142
143
144
145
146
147
148
def is_parallel(self, other):
    """Return if the other vector is parallel.

    See also
    --------
    [`vecparallel`][vector.functional.vecparallel]
    """
    return vecparallel(self, other)

absq()

Return the sum of absolute squares of the coefficients.

See also

vecabsq

Source code in vector\objectoriented.py
152
153
154
155
156
157
158
159
def absq(self):
    """Return the sum of absolute squares of the coefficients.

    See also
    --------
    [`vecabsq`][vector.functional.vecabsq]
    """
    return vecabsq(self)

__abs__()

Return the Euclidean/L2-norm.

Return the square root of vecabsq.

See also

vecabs

Source code in vector\objectoriented.py
161
162
163
164
165
166
167
168
169
170
def __abs__(self):
    """Return the Euclidean/L2-norm.

    Return the square root of `vecabsq`.

    See also
    --------
    [`vecabs`][vector.functional.vecabs]
    """
    return self.absq()**0.5

__matmul__(other)

Return the real dot product of two vectors.

No argument is complex conjugated. All coefficients are used as is.

See also

vecdot

Source code in vector\objectoriented.py
172
173
174
175
176
177
178
179
180
181
def __matmul__(self, other):
    """Return the real dot product of two vectors.

    No argument is complex conjugated. All coefficients are used as is.

    See also
    --------
    [`vecdot`][vector.functional.vecdot]
    """
    return vecdot(self, other)

__pos__()

Return the unary positive.

See also

vecpos

Source code in vector\objectoriented.py
186
187
188
189
190
191
192
193
def __pos__(self):
    """Return the unary positive.

    See also
    --------
    [`vecpos`][vector.functional.vecpos]
    """
    return type(self)(vecpos(self))

__neg__()

Return the negative.

See also

vecneg

Source code in vector\objectoriented.py
195
196
197
198
199
200
201
202
def __neg__(self):
    """Return the negative.

    See also
    --------
    [`vecneg`][vector.functional.vecneg]
    """
    return type(self)(vecneg(self))

__add__(other)

Return the vector sum.

See also

vecadd

Source code in vector\objectoriented.py
204
205
206
207
208
209
210
211
def __add__(self, other):
    """Return the vector sum.

    See also
    --------
    [`vecadd`][vector.functional.vecadd]
    """
    return type(self)(vecadd(self, other))

addc(c, i=0)

Return the sum with the i-th basis vector times c.

See also

vecaddc

Source code in vector\objectoriented.py
214
215
216
217
218
219
220
221
def addc(self, c, i=0):
    """Return the sum with the `i`-th basis vector times `c`.

    See also
    --------
    [`vecaddc`][vector.functional.vecaddc]
    """
    return type(self)(vecaddc(self, c, i))

__sub__(other)

Return the vector difference.

See also

vecsub

Source code in vector\objectoriented.py
223
224
225
226
227
228
229
230
def __sub__(self, other):
    """Return the vector difference.

    See also
    --------
    [`vecsub`][vector.functional.vecsub]
    """
    return type(self)(vecsub(self, other))

__mul__(other)

Return the scalar product.

See also

vecmul

Source code in vector\objectoriented.py
234
235
236
237
238
239
240
241
def __mul__(self, other):
    """Return the scalar product.

    See also
    --------
    [`vecmul`][vector.functional.vecmul]
    """
    return type(self)(vecmul(other, self))

__truediv__(other)

Return the scalar true division.

See also

vectruediv

Source code in vector\objectoriented.py
244
245
246
247
248
249
250
251
def __truediv__(self, other):
    """Return the scalar true division.

    See also
    --------
    [`vectruediv`][vector.functional.vectruediv]
    """
    return type(self)(vectruediv(self, other))

__floordiv__(other)

Return the scalar floor division.

See also

vecfloordiv

Source code in vector\objectoriented.py
253
254
255
256
257
258
259
260
def __floordiv__(self, other):
    """Return the scalar floor division.

    See also
    --------
    [`vecfloordiv`][vector.functional.vecfloordiv]
    """
    return type(self)(vecfloordiv(self, other))

__mod__(other)

Return the elementwise mod with a scalar.

See also

vecmod

Source code in vector\objectoriented.py
262
263
264
265
266
267
268
269
def __mod__(self, other):
    """Return the elementwise mod with a scalar.

    See also
    --------
    [`vecmod`][vector.functional.vecmod]
    """
    return type(self)(vecmod(self, other))

__divmod__(other)

Return the elementwise divmod with a scalar.

See also

vecdivmod

Source code in vector\objectoriented.py
271
272
273
274
275
276
277
278
279
def __divmod__(self, other):
    """Return the elementwise divmod with a scalar.

    See also
    --------
    [`vecdivmod`][vector.functional.vecdivmod]
    """
    q, r = vecdivmod(self, other)
    return type(self)(q), type(self)(r)

hadamard(other)

Return the elementwise product with another vector.

See also

vechadamard

Source code in vector\objectoriented.py
283
284
285
286
287
288
289
290
def hadamard(self, other):
    """Return the elementwise product with another vector.

    See also
    --------
    [`vechadamard`][vector.functional.vechadamard]
    """
    return type(self)(vechadamard(self, other))

hadamardtruediv(other)

Return the elementwise true division with another vector.

See also

vechadamardtruediv

Source code in vector\objectoriented.py
292
293
294
295
296
297
298
299
def hadamardtruediv(self, other):
    """Return the elementwise true division with another vector.

    See also
    --------
    [`vechadamardtruediv`][vector.functional.vechadamardtruediv]
    """
    return type(self)(vechadamardtruediv(self, other))

hadamardfloordiv(other)

Return the elementwise floor division with another vector.

See also

vechadamardfloordiv

Source code in vector\objectoriented.py
301
302
303
304
305
306
307
308
def hadamardfloordiv(self, other):
    """Return the elementwise floor division with another vector.

    See also
    --------
    [`vechadamardfloordiv`][vector.functional.vechadamardfloordiv]
    """
    return type(self)(vechadamardfloordiv(self, other))

hadamardmod(other)

Return the elementwise mod with another vector.

See also

vechadamardmod

Source code in vector\objectoriented.py
310
311
312
313
314
315
316
317
def hadamardmod(self, other):
    """Return the elementwise mod with another vector.

    See also
    --------
    [`vechadamardmod`][vector.functional.vechadamardmod]
    """
    return type(self)(vechadamardmod(self, other))

hadamardmin(other)

Return the elementwise minimum with another vector.

See also

vechadamardmin

Source code in vector\objectoriented.py
319
320
321
322
323
324
325
326
def hadamardmin(self, other):
    """Return the elementwise minimum with another vector.

    See also
    --------
    [`vechadamardmin`][vector.functional.vechadamardmin]
    """
    return type(self)(vechadamardmin(self, other))

hadamardmax(other)

Return the elementwise maximum with another vector.

See also

vechadamardmax

Source code in vector\objectoriented.py
328
329
330
331
332
333
334
335
def hadamardmax(self, other):
    """Return the elementwise maximum with another vector.

    See also
    --------
    [`vechadamardmax`][vector.functional.vechadamardmax]
    """
    return type(self)(vechadamardmax(self, other))

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

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
89
90
91
92
93
94
95
96
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 fills 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))

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

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 operators.
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)

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)))