Skip to content

Lazy

Vector operations as lazy generators.

>>> from vector import veclbasis
>>> veclbasis(3)
<generator object veclbasis at 0x0123456789ABCDEF>
>>> tuple(veclbasis(3))
(0, 0, 0, 1)

Prefixed by vecl... (vector - lazy).

Lazy generator versions of functional.

Different behaviour:

Not implemented lazily:

creation

veclzero()

Zero vector.

\[ \vec{0} \qquad \mathbb{K}^0 \]
Source code in vector\lazy\creation.py
10
11
12
13
14
15
16
17
def veclzero():
    r"""Zero vector.

    $$
        \vec{0} \qquad \mathbb{K}^0
    $$
    """
    yield from ()

veclbasis(i, c=1, zero=0)

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\lazy\creation.py
19
20
21
22
23
24
25
26
27
28
def veclbasis(i, c=1, zero=0):
    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`.
    """
    yield from chain(repeat(zero, i), (c,))

veclbases(start=0, c=1, zero=0)

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\lazy\creation.py
30
31
32
33
34
35
36
37
38
39
40
41
42
def veclbases(start=0, c=1, zero=0):
    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(start=start):
        yield veclbasis(i, c=c, zero=zero)

veclrand(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\lazy\creation.py
44
45
46
47
48
49
50
51
52
53
54
55
56
def veclrand(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).
    """
    yield from (random() for _ in range(n))

veclrandn(n, 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 \]

Difference to vecrandn: The vector can't be normalised as it isn't materialised.

Notes

Naming like in numpy.random, because seems more concise (not random & gauss as in the stdlib).

Source code in vector\lazy\creation.py
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
def veclrandn(n, 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
    $$

    Difference to [`vecrandn`][vector.functional.vecrandn]: The vector can't be normalised as it isn't materialised.

    Notes
    -----
    Naming like in `numpy.random`, because seems more concise
    (not `random` & `gauss` as in the stdlib).
    """
    yield from (gauss(mu, sigma) for _ in range(n))

utility

vecleq(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\lazy\utility.py
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def vecleq(v, w):
    r"""Return if two vectors are equal.

    $$
        \vec{v}=\vec{w} \qquad \mathbb{K}^m\times\mathbb{K}^n\to\mathbb{B}
    $$
    """
    sentinel = object()
    for vi, wi in zip_longest(v, w, fillvalue=sentinel):
        if wi is sentinel:
            yield not bool(vi)
        elif vi is sentinel:
            yield not bool(wi)
        else:
            yield vi == wi

vecltrim(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\lazy\utility.py
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
def vecltrim(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).
    """
    t = []
    for x in v:
        t.append(x)
        if abs(x)>tol:
            yield from t
            t.clear()

veclround(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\lazy\utility.py
50
51
52
53
54
55
56
57
def veclround(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
    $$
    """
    yield from (round(c, ndigits) for c in v)

veclrshift(v, n, zero=0)

Pad n many zeros 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\lazy\utility.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
def veclrshift(v, n, zero=0):
    r"""Pad `n` many `zero`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}
    $$
    """
    yield from chain(repeat(zero, n), v)

vecllshift(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\lazy\utility.py
75
76
77
78
79
80
81
82
83
84
85
86
def vecllshift(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\}}
    $$
    """
    yield from islice(v, n, None)

hilbert_space

try_conjugate(x)

Return the complex conjugate of a scalar.

\[ x^* \qquad \mathbb{K}\to\mathbb{K} \]

Trys to call a method conjugate. If not found, simply returns the element as is.

Source code in vector\lazy\hilbert_space.py
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
def try_conjugate(x):
    r"""Return the complex conjugate of a scalar.

    $$
        x^* \qquad \mathbb{K}\to\mathbb{K}
    $$

    Trys to call a method `conjugate`.
    If not found, simply returns the element as is.
    """
    #try:
    #    return x.conjugate()
    #except AttributeError:
    #    return x
    #could throw an AttibuteError from somewhere deeper
    conj = getattr(x, 'conjugate', None)
    return conj() if callable(conj) else x

veclconj(v)

Return the elementwise complex conjugate of a vector.

\[ \vec{v}^* \qquad \mathbb{K}^n\to\mathbb{K}^n \]

Trys to call a method conjugate on each element. If not found, simply keeps the element as is.

Source code in vector\lazy\hilbert_space.py
23
24
25
26
27
28
29
30
31
32
33
def veclconj(v):
    r"""Return the elementwise complex conjugate of a vector.

    $$
        \vec{v}^* \qquad \mathbb{K}^n\to\mathbb{K}^n
    $$

    Trys to call a method `conjugate` on each element.
    If not found, simply keeps the element as is.
    """
    yield from map(try_conjugate, v)

vector_space

veclpos(v)

Return the vector with the unary positive operator applied.

\[ +\vec{v} \qquad \mathbb{K}^n\to\mathbb{K}^n \]
Source code in vector\lazy\vector_space.py
13
14
15
16
17
18
19
20
def veclpos(v):
    r"""Return the vector with the unary positive operator applied.

    $$
        +\vec{v} \qquad \mathbb{K}^n\to\mathbb{K}^n
    $$
    """
    yield from map(pos, v)

veclneg(v)

Return the vector with the unary negative operator applied.

\[ -\vec{v} \qquad \mathbb{K}^n\to\mathbb{K}^n \]
Source code in vector\lazy\vector_space.py
22
23
24
25
26
27
28
29
def veclneg(v):
    r"""Return the vector with the unary negative operator applied.

    $$
        -\vec{v} \qquad \mathbb{K}^n\to\mathbb{K}^n
    $$
    """
    yield from map(neg, v)

vecladd(*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\lazy\vector_space.py
31
32
33
34
35
36
37
38
def vecladd(*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}
    $$
    """
    yield from map(partial(sum_default, default=MISSING), group_ordinal(*vs))

vecladdc(v, c, i=0, zero=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 vecladd(v, veclbasis(i, c)).

Source code in vector\lazy\vector_space.py
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
def vecladdc(v, c, i=0, zero=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 `vecladd(v, veclbasis(i, c))`.
    """
    v = iter(v)
    yield from islice(chain(v, repeat(zero)), i)
    try:
        yield next(v) + c
    except StopIteration:
        yield +c
    yield from v

veclsub(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\lazy\vector_space.py
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
def veclsub(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\}}
    $$
    """
    sentinel = object()
    for vi, wi in zip_longest(v, w, fillvalue=sentinel):
        if wi is sentinel:
            yield vi
        elif vi is sentinel:
            yield -wi
        else:
            yield vi - wi

veclsubc(v, c, i=0, zero=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 veclsub(v, veclbasis(i, c)).

Source code in vector\lazy\vector_space.py
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
def veclsubc(v, c, i=0, zero=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 `veclsub(v, veclbasis(i, c))`.
    """
    v = iter(v)
    yield from islice(chain(v, repeat(zero)), i)
    try:
        yield next(v) - c
    except StopIteration:
        yield -c
    yield from v

veclmul(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\lazy\vector_space.py
90
91
92
93
94
95
96
97
def veclmul(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
    $$
    """
    yield from map(mul, repeat(a), v)

vecltruediv(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\lazy\vector_space.py
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
def vecltruediv(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.
    """
    yield from map(truediv, v, repeat(a))

veclfloordiv(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\lazy\vector_space.py
119
120
121
122
123
124
125
126
def veclfloordiv(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
    $$
    """
    yield from map(floordiv, v, repeat(a))

veclmod(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\lazy\vector_space.py
128
129
130
131
132
133
134
135
def veclmod(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
    $$
    """
    yield from map(mod, v, repeat(a))

vecldivmod(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\lazy\vector_space.py
137
138
139
140
141
142
143
144
145
def vecldivmod(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
    $$
    """
    for vi in v:
        yield divmod(vi, a)

elementwise

veclhadamard(*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\lazy\elementwise.py
14
15
16
17
18
19
20
21
def veclhadamard(*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}
    $$
    """
    yield from map(partial(prod_default, default=MISSING), zip(*vs))

veclhadamardtruediv(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\lazy\elementwise.py
23
24
25
26
27
28
29
30
def veclhadamardtruediv(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
    $$
    """
    yield from map(truediv, v, chain(w, exception_generator(ZeroDivisionError)))

veclhadamardfloordiv(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\lazy\elementwise.py
32
33
34
35
36
37
38
39
def veclhadamardfloordiv(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
    $$
    """
    yield from map(floordiv, v, chain(w, exception_generator(ZeroDivisionError)))

veclhadamardmod(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\lazy\elementwise.py
41
42
43
44
45
46
47
48
def veclhadamardmod(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
    $$
    """
    yield from map(mod, v, chain(w, exception_generator(ZeroDivisionError)))

veclhadamarddivmod(v, w)

Return the elementwise divmod of two vectors.

\[ \left(\left\lfloor\frac{v_i}{w_i}\right\rfloor\right)_i, \ \left(v_i \mod w_i\right)_i \qquad \mathbb{K}^n\times\mathbb{K}^m\to\mathbb{K}^n\times\mathbb{K}^n \]
Source code in vector\lazy\elementwise.py
50
51
52
53
54
55
56
57
def veclhadamarddivmod(v, w):
    r"""Return the elementwise divmod of two vectors.

    $$
        \left(\left\lfloor\frac{v_i}{w_i}\right\rfloor\right)_i, \ \left(v_i \mod w_i\right)_i \qquad \mathbb{K}^n\times\mathbb{K}^m\to\mathbb{K}^n\times\mathbb{K}^n
    $$
    """
    yield from map(divmod, v, chain(w, exception_generator(ZeroDivisionError)))

veclhadamardmin(*vs, key=None)

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\lazy\elementwise.py
59
60
61
62
63
64
65
66
def veclhadamardmin(*vs, key=None):
    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}
    $$
    """
    yield from map(partial(min, key=key), group_ordinal(*vs))

veclhadamardmax(*vs, key=None)

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\lazy\elementwise.py
68
69
70
71
72
73
74
75
def veclhadamardmax(*vs, key=None):
    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}
    $$
    """
    yield from map(partial(max, key=key), group_ordinal(*vs))