Skip to content

Physicists’ Hermite polynomial

beignet.add_physicists_hermite_polynomial

add_physicists_hermite_polynomial(input, other)

Returns the sum of two polynomials.

Parameters:

Name Type Description Default
input Tensor

Polynomial coefficients.

required
other Tensor

Polynomial coefficients.

required

Returns:

Name Type Description
output Tensor

Polynomial coefficients.

Source code in src/beignet/_add_physicists_hermite_polynomial.py
 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
def add_physicists_hermite_polynomial(input: Tensor, other: Tensor) -> Tensor:
    r"""
    Returns the sum of two polynomials.

    Parameters
    ----------
    input : Tensor
        Polynomial coefficients.

    other : Tensor
        Polynomial coefficients.

    Returns
    -------
    output : Tensor
        Polynomial coefficients.
    """
    input = torch.atleast_1d(input)
    other = torch.atleast_1d(other)

    dtype = torch.promote_types(input.dtype, other.dtype)

    input = input.to(dtype)
    other = other.to(dtype)

    if input.shape[0] > other.shape[0]:
        output = torch.concatenate(
            [
                other,
                torch.zeros(
                    input.shape[0] - other.shape[0],
                    dtype=other.dtype,
                ),
            ],
        )

        output = input + output
    else:
        output = torch.concatenate(
            [
                input,
                torch.zeros(
                    other.shape[0] - input.shape[0],
                    dtype=input.dtype,
                ),
            ]
        )

        output = other + output

    return output

beignet.differentiate_physicists_hermite_polynomial

differentiate_physicists_hermite_polynomial(input, order=1, scale=1, axis=0)

Returns the derivative of a polynomial.

Parameters:

Name Type Description Default
input Tensor

Polynomial coefficients.

required
order Tensor
1
scale Tensor
1
dim int
0

Returns:

Name Type Description
output Tensor

Polynomial coefficients of the derivative.

Source code in src/beignet/_differentiate_physicists_hermite_polynomial.py
 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
def differentiate_physicists_hermite_polynomial(
    input,
    order=1,
    scale=1,
    axis=0,
) -> Tensor:
    r"""
    Returns the derivative of a polynomial.

    Parameters
    ----------
    input : Tensor
        Polynomial coefficients.

    order : Tensor, optional

    scale : Tensor, optional

    dim : int, default=0

    Returns
    -------
    output : Tensor
        Polynomial coefficients of the derivative.
    """
    if order < 0:
        raise ValueError

    input = torch.atleast_1d(input)

    if order == 0:
        return input

    input = torch.moveaxis(input, axis, 0)

    n = input.shape[0]

    if order >= n:
        input = torch.zeros_like(input[:1])
    else:
        for _ in range(order):
            n = n - 1

            input *= scale

            der = torch.empty((n,) + input.shape[1:], dtype=input.dtype)

            j = torch.arange(n, 0, -1)

            der[j - 1] = (2 * j * (input[j]).T).T

            input = der

    input = torch.moveaxis(input, 0, axis)

    return input

beignet.divide_physicists_hermite_polynomial

divide_physicists_hermite_polynomial(input, other)

Returns the quotient and remainder of two polynomials.

Parameters:

Name Type Description Default
input Tensor

Polynomial coefficients.

required
other Tensor

Polynomial coefficients.

required

Returns:

Name Type Description
output Tuple[Tensor, Tensor]

Polynomial coefficients of the quotient and remainder.

Source code in src/beignet/_divide_physicists_hermite_polynomial.py
 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
def divide_physicists_hermite_polynomial(
    input: Tensor,
    other: Tensor,
) -> Tuple[Tensor, Tensor]:
    r"""
    Returns the quotient and remainder of two polynomials.

    Parameters
    ----------
    input : Tensor
        Polynomial coefficients.

    other : Tensor
        Polynomial coefficients.

    Returns
    -------
    output : Tuple[Tensor, Tensor]
        Polynomial coefficients of the quotient and remainder.
    """
    input = torch.atleast_1d(input)
    other = torch.atleast_1d(other)

    dtype = torch.promote_types(input.dtype, other.dtype)

    input = input.to(dtype)
    other = other.to(dtype)

    m = input.shape[0]
    n = other.shape[0]

    if m < n:
        return torch.zeros_like(input[:1]), input

    if n == 1:
        return input / other[-1], torch.zeros_like(input[:1])

    def f(x: Tensor) -> Tensor:
        indicies = torch.flip(x, [0])

        indicies = torch.nonzero(indicies, as_tuple=False)

        if indicies.shape[0] > 1:
            indicies = indicies[:1]

        if indicies.shape[0] < 1:
            indicies = torch.concatenate(
                [
                    indicies,
                    torch.full(
                        [
                            1 - indicies.shape[0],
                            indicies.shape[1],
                        ],
                        0,
                    ),
                ],
                0,
            )

        return x.shape[0] - 1 - indicies[0][0]

    quotient = torch.zeros(m - n + 1, dtype=input.dtype)

    ridx = input.shape[0] - 1

    size = m - f(other) - 1

    y = torch.zeros(m + n + 1, dtype=input.dtype)

    y[size] = 1.0

    x = quotient, input, y, ridx

    for index in range(0, size):
        quotient, remainder, y2, ridx1 = x

        j = size - index

        p = multiply_physicists_hermite_polynomial(y2, other)

        pidx = f(p)

        t = remainder[ridx1] / p[pidx]

        remainder_modified = remainder.clone()
        remainder_modified[ridx1] = 0.0

        a = remainder_modified

        p_modified = p.clone()
        p_modified[pidx] = 0.0

        b = t * p_modified

        a = torch.atleast_1d(a)
        b = torch.atleast_1d(b)

        dtype = torch.promote_types(a.dtype, b.dtype)

        a = a.to(dtype)
        b = b.to(dtype)

        if a.shape[0] > b.shape[0]:
            output = -b

            output = torch.concatenate(
                [
                    output,
                    torch.zeros(
                        a.shape[0] - b.shape[0],
                        dtype=b.dtype,
                    ),
                ],
            )
            output = a + output
        else:
            output = -b

            output = torch.concatenate(
                [
                    output[: a.shape[0]] + a,
                    output[a.shape[0] :],
                ],
            )

        remainder = output

        remainder = remainder[: remainder.shape[0]]

        quotient[j] = t

        ridx1 = ridx1 - 1

        y2 = torch.roll(y2, -1)

        x = quotient, remainder, y2, ridx1

    quotient, remainder, _, _ = x

    return quotient, remainder

beignet.evaluate_physicists_hermite_polynomial

evaluate_physicists_hermite_polynomial(input, coefficients, tensor=True)
Source code in src/beignet/_evaluate_physicists_hermite_polynomial.py
 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
def evaluate_physicists_hermite_polynomial(
    input: Tensor,
    coefficients: Tensor,
    tensor: bool = True,
):
    coefficients = torch.atleast_1d(coefficients)

    if tensor:
        coefficients = torch.reshape(
            coefficients,
            coefficients.shape + (1,) * input.ndim,
        )

    match coefficients.shape[0]:
        case 1:
            a = coefficients[0]
            b = 0.0
        case 2:
            a = coefficients[0]
            b = coefficients[1]
        case _:
            size = coefficients.shape[0]

            a = coefficients[-2] * torch.ones_like(input)
            b = coefficients[-1] * torch.ones_like(input)

            for i in range(3, coefficients.shape[0] + 1):
                previous = a

                size = size - 1

                a = coefficients[-i] - b * (2.0 * (size - 1.0))

                b = previous + b * input * 2.0

    return a + b * input * 2.0

beignet.evaluate_physicists_hermite_polynomial_2d

evaluate_physicists_hermite_polynomial_2d(x, y, coefficients)
Source code in src/beignet/_evaluate_physicists_hermite_polynomial_2d.py
 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
def evaluate_physicists_hermite_polynomial_2d(
    x: Tensor,
    y: Tensor,
    coefficients: Tensor,
) -> Tensor:
    points = [x, y]

    if not all(a.shape == points[0].shape for a in points[1:]):
        match len(points):
            case 2:
                raise ValueError
            case 3:
                raise ValueError
            case _:
                raise ValueError

    points = iter(points)

    output = evaluate_physicists_hermite_polynomial(
        next(points),
        coefficients,
    )

    for x in points:
        output = evaluate_physicists_hermite_polynomial(
            x,
            output,
            tensor=False,
        )

    return output

beignet.evaluate_physicists_hermite_polynomial_3d

evaluate_physicists_hermite_polynomial_3d(x, y, z, coefficients)
Source code in src/beignet/_evaluate_physicists_hermite_polynomial_3d.py
 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
def evaluate_physicists_hermite_polynomial_3d(
    x: Tensor,
    y: Tensor,
    z: Tensor,
    coefficients: Tensor,
) -> Tensor:
    points = [x, y, z]

    if not all(a.shape == points[0].shape for a in points[1:]):
        match len(points):
            case 2:
                raise ValueError
            case 3:
                raise ValueError
            case _:
                raise ValueError

    points = iter(points)

    output = evaluate_physicists_hermite_polynomial(
        next(points),
        coefficients,
    )

    for x in points:
        output = evaluate_physicists_hermite_polynomial(
            x,
            output,
            tensor=False,
        )

    return output

beignet.evaluate_physicists_hermite_polynomial_cartesian_2d

evaluate_physicists_hermite_polynomial_cartesian_2d(x, y, coefficients)
Source code in src/beignet/_evaluate_physicists_hermite_polynomial_cartesian_2d.py
 8
 9
10
11
12
13
14
15
16
17
18
19
def evaluate_physicists_hermite_polynomial_cartesian_2d(
    x: Tensor,
    y: Tensor,
    coefficients: Tensor,
) -> Tensor:
    for point in [x, y]:
        coefficients = evaluate_physicists_hermite_polynomial(
            point,
            coefficients,
        )

    return coefficients

beignet.evaluate_physicists_hermite_polynomial_cartesian_3d

evaluate_physicists_hermite_polynomial_cartesian_3d(x, y, z, c)
Source code in src/beignet/_evaluate_physicists_hermite_polynomial_cartesian_3d.py
 8
 9
10
11
12
13
14
15
16
def evaluate_physicists_hermite_polynomial_cartesian_3d(
    x: Tensor,
    y: Tensor,
    z: Tensor,
    c: Tensor,
) -> Tensor:
    for arg in [x, y, z]:
        c = evaluate_physicists_hermite_polynomial(arg, c)
    return c

beignet.fit_physicists_hermite_polynomial

fit_physicists_hermite_polynomial(input, other, degree, relative_condition=None, full=False, weight=None)
Source code in src/beignet/_fit_physicists_hermite_polynomial.py
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
def fit_physicists_hermite_polynomial(
    input: Tensor,
    other: Tensor,
    degree: Tensor | int,
    relative_condition: float | None = None,
    full: bool = False,
    weight: Tensor | None = None,
):
    input = torch.tensor(input)
    other = torch.tensor(other)
    degree = torch.tensor(degree)
    if degree.ndim > 1:
        raise TypeError
    # if deg.dtype.kind not in "iu":
    #     raise TypeError
    if math.prod(degree.shape) == 0:
        raise TypeError
    if degree.min() < 0:
        raise ValueError
    if input.ndim != 1:
        raise TypeError
    if input.size == 0:
        raise TypeError
    if other.ndim < 1 or other.ndim > 2:
        raise TypeError
    if len(input) != len(other):
        raise TypeError
    if degree.ndim == 0:
        lmax = int(degree)
        van = physicists_hermite_polynomial_vandermonde(input, lmax)
    else:
        degree, _ = torch.sort(degree)
        lmax = int(degree[-1])
        van = physicists_hermite_polynomial_vandermonde(input, lmax)[:, degree]
    # set up the least squares matrices in transposed form
    lhs = van.T
    rhs = other.T
    if weight is not None:
        if weight.ndim != 1:
            raise TypeError("expected 1D vector for w")

        if len(input) != len(weight):
            raise TypeError("expected x and w to have same length")

        # apply weights. Don't use inplace operations as they
        # can cause problems with NA.
        lhs = lhs * weight
        rhs = rhs * weight
    # set rcond
    if relative_condition is None:
        relative_condition = len(input) * torch.finfo(input.dtype).eps
    # Determine the norms of the design matrix columns.
    if torch.is_complex(lhs):
        scl = torch.sqrt((torch.square(lhs.real) + torch.square(lhs.imag)).sum(1))
    else:
        scl = torch.sqrt(torch.square(lhs).sum(1))
    scl = torch.where(scl == 0, 1, scl)
    # Solve the least squares problem.
    c, resids, rank, s = torch.linalg.lstsq(lhs.T / scl, rhs.T, relative_condition)
    c = (c.T / scl).T
    # Expand c to include non-fitted coefficients which are set to zero
    if degree.ndim > 0:
        if c.ndim == 2:
            cc = torch.zeros((lmax + 1, c.shape[1]), dtype=c.dtype)
        else:
            cc = torch.zeros(lmax + 1, dtype=c.dtype)

        cc[degree] = c

        c = cc
    if full:
        result = c, [resids, rank, s, relative_condition]
    else:
        result = c
    return result

beignet.integrate_physicists_hermite_polynomial

integrate_physicists_hermite_polynomial(input, order=1, k=None, lower_bound=0, scale=1, axis=0)
Source code in src/beignet/_integrate_physicists_hermite_polynomial.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
def integrate_physicists_hermite_polynomial(
    input,
    order=1,
    k=None,
    lower_bound=0,
    scale=1,
    axis=0,
):
    if k is None:
        k = []

    input = torch.atleast_1d(input)

    lower_bound, scale = map(torch.tensor, (lower_bound, scale))

    if not numpy.iterable(k):
        k = [k]

    if len(k) > order:
        raise ValueError

    if lower_bound.ndim != 0:
        raise ValueError

    if scale.ndim != 0:
        raise ValueError

    if order == 0:
        return input

    input = torch.moveaxis(input, axis, 0)

    k = torch.tensor(list(k) + [0] * (order - len(k)))
    k = torch.atleast_1d(k)

    for i in range(order):
        n = input.shape[0]
        input *= scale
        tmp = torch.empty((n + 1,) + input.shape[1:], dtype=input.dtype)

        tmp[0] = input[0] * 0
        tmp[1] = input[0] / 2

        j = torch.arange(1, n)

        tmp[j + 1] = (input[j].T / (2 * (j + 1))).T

        tmp_value = evaluate_physicists_hermite_polynomial(lower_bound, tmp)
        tmp[0] += k[i] - tmp_value

        input = tmp

    input = torch.moveaxis(input, 0, axis)

    return input

beignet.linear_physicists_hermite_polynomial

linear_physicists_hermite_polynomial(input, other)
Source code in src/beignet/_linear_physicists_hermite_polynomial.py
5
6
def linear_physicists_hermite_polynomial(input: float, other: float) -> Tensor:
    return torch.tensor([input, other / 2])

beignet.multiply_physicists_hermite_polynomial

multiply_physicists_hermite_polynomial(input, other, mode='full')

Returns the product of two polynomials.

Parameters:

Name Type Description Default
input Tensor

Polynomial coefficients.

required
other Tensor

Polynomial coefficients.

required

Returns:

Name Type Description
output Tensor

Polynomial coefficients of the product.

Source code in src/beignet/_multiply_physicists_hermite_polynomial.py
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
def multiply_physicists_hermite_polynomial(
    input: Tensor,
    other: Tensor,
    mode: Literal["full", "same", "valid"] = "full",
) -> Tensor:
    r"""
    Returns the product of two polynomials.

    Parameters
    ----------
    input : Tensor
        Polynomial coefficients.

    other : Tensor
        Polynomial coefficients.

    Returns
    -------
    output : Tensor
        Polynomial coefficients of the product.
    """
    input = torch.atleast_1d(input)
    other = torch.atleast_1d(other)

    dtype = torch.promote_types(input.dtype, other.dtype)

    input = input.to(dtype)
    other = other.to(dtype)

    m, n = input.shape[0], other.shape[0]

    if m > n:
        x, y = other, input
    else:
        x, y = input, other

    match x.shape[0]:
        case 1:
            a = add_physicists_hermite_polynomial(torch.zeros(m + n - 1), x[0] * y)
            b = torch.zeros(m + n - 1)
        case 2:
            a = add_physicists_hermite_polynomial(torch.zeros(m + n - 1), x[0] * y)
            b = add_physicists_hermite_polynomial(torch.zeros(m + n - 1), x[1] * y)
        case _:
            size = x.shape[0]

            a = add_physicists_hermite_polynomial(torch.zeros(m + n - 1), x[-2] * y)
            b = add_physicists_hermite_polynomial(torch.zeros(m + n - 1), x[-1] * y)

            for i in range(3, x.shape[0] + 1):
                previous = a

                size = size - 1

                a = subtract_physicists_hermite_polynomial(
                    x[-i] * y, b * (2 * (size - 1.0))
                )

                b = add_physicists_hermite_polynomial(
                    previous,
                    multiply_physicists_hermite_polynomial_by_x(b, "same") * 2.0,
                )

    output = add_physicists_hermite_polynomial(
        a, multiply_physicists_hermite_polynomial_by_x(b, "same") * 2
    )

    if mode == "same":
        output = output[: max(m, n)]

    return output

beignet.multiply_physicists_hermite_polynomial_by_x

multiply_physicists_hermite_polynomial_by_x(input, mode='full')
Source code in src/beignet/_multiply_physicists_hermite_polynomial_by_x.py
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def multiply_physicists_hermite_polynomial_by_x(
    input: Tensor,
    mode: Literal["full", "same", "valid"] = "full",
) -> Tensor:
    input = torch.atleast_1d(input)

    output = torch.zeros(input.shape[0] + 1, dtype=input.dtype)

    output[1] = input[0] / 2.0

    i = torch.arange(1, input.shape[0])

    output[i + 1] = input[i] / 2.0
    output[i - 1] = output[i - 1] + input[i] * i

    if mode == "same":
        output = output[: input.shape[0]]

    return output

beignet.physicists_hermite_polynomial_companion

physicists_hermite_polynomial_companion(input)
Source code in src/beignet/_physicists_hermite_polynomial_companion.py
 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
def physicists_hermite_polynomial_companion(input: Tensor) -> Tensor:
    input = torch.atleast_1d(input)

    if input.shape[0] < 2:
        raise ValueError

    if input.shape[0] == 2:
        return torch.tensor([[-0.5 * input[0] / input[1]]])

    n = input.shape[0] - 1

    output = torch.zeros((n, n), dtype=input.dtype)

    scale = torch.hstack(
        [
            torch.tensor([1.0]),
            1.0 / torch.sqrt(2.0 * torch.arange(n - 1, 0, -1)),
        ],
    )

    scale = torch.cumprod(scale, dim=0)

    scale = torch.flip(scale, dims=[0])

    shp = output.shape

    output = torch.reshape(output, [-1])

    output[1 :: n + 1] = torch.sqrt(0.5 * torch.arange(1, n))
    output[n :: n + 1] = torch.sqrt(0.5 * torch.arange(1, n))

    output = torch.reshape(output, shp)

    output[:, -1] += -scale * input[:-1] / (2.0 * input[-1])

    return output

beignet.physicists_hermite_polynomial_domain module-attribute

physicists_hermite_polynomial_domain = tensor([-1.0, 1.0])

beignet.physicists_hermite_polynomial_from_roots

physicists_hermite_polynomial_from_roots(input)
Source code in src/beignet/_physicists_hermite_polynomial_from_roots.py
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
def physicists_hermite_polynomial_from_roots(input):
    f = linear_physicists_hermite_polynomial
    g = multiply_physicists_hermite_polynomial
    if math.prod(input.shape) == 0:
        return torch.ones([1])

    input, _ = torch.sort(input)

    ys = []

    for x in input:
        a = torch.zeros(input.shape[0] + 1, dtype=x.dtype)
        b = f(-x, 1)

        a = torch.atleast_1d(a)
        b = torch.atleast_1d(b)

        dtype = torch.promote_types(a.dtype, b.dtype)

        a = a.to(dtype)
        b = b.to(dtype)

        if a.shape[0] > b.shape[0]:
            y = torch.concatenate(
                [
                    b,
                    torch.zeros(
                        a.shape[0] - b.shape[0],
                        dtype=b.dtype,
                    ),
                ],
            )

            y = a + y
        else:
            y = torch.concatenate(
                [
                    a,
                    torch.zeros(
                        b.shape[0] - a.shape[0],
                        dtype=a.dtype,
                    ),
                ]
            )

            y = b + y

        ys = [*ys, y]

    p = torch.stack(ys)

    m = p.shape[0]

    x = m, p

    while x[0] > 1:
        m, r = divmod(x[0], 2)

        z = x[1]

        previous = torch.zeros([len(p), input.shape[0] + 1])

        y = previous

        for i in range(0, m):
            y[i] = g(z[i], z[i + m])[: input.shape[0] + 1]

        previous = y

        if r:
            previous[0] = g(previous[0], z[2 * m])[: input.shape[0] + 1]

        x = m, previous

    _, output = x

    return output[0]

beignet.physicists_hermite_polynomial_one module-attribute

physicists_hermite_polynomial_one = tensor([1.0])

beignet.physicists_hermite_polynomial_power

physicists_hermite_polynomial_power(input, exponent, maximum_exponent=16.0)
Source code in src/beignet/_physicists_hermite_polynomial_power.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
def physicists_hermite_polynomial_power(
    input: Tensor,
    exponent: float | Tensor,
    maximum_exponent: float | Tensor = 16.0,
) -> Tensor:
    input = torch.atleast_1d(input)
    _exponent = int(exponent)
    if _exponent != exponent or _exponent < 0:
        raise ValueError
    if maximum_exponent is not None and _exponent > maximum_exponent:
        raise ValueError
    match _exponent:
        case 0:
            output = torch.tensor([1], dtype=input.dtype)
        case 1:
            output = input
        case _:
            output = torch.zeros(input.shape[0] * exponent, dtype=input.dtype)

            input = torch.atleast_1d(input)
            output = torch.atleast_1d(output)

            dtype = torch.promote_types(input.dtype, output.dtype)

            input = input.to(dtype)
            output = output.to(dtype)

            if output.shape[0] > input.shape[0]:
                input = torch.concatenate(
                    [
                        input,
                        torch.zeros(
                            output.shape[0] - input.shape[0],
                            dtype=input.dtype,
                        ),
                    ],
                )

                output = output + input
            else:
                output = torch.concatenate(
                    [
                        output,
                        torch.zeros(
                            input.shape[0] - output.shape[0],
                            dtype=output.dtype,
                        ),
                    ]
                )

                output = input + output

            for _ in range(2, _exponent + 1):
                output = multiply_physicists_hermite_polynomial(
                    output, input, mode="same"
                )
    return output

beignet.physicists_hermite_polynomial_roots

physicists_hermite_polynomial_roots(input)
Source code in src/beignet/_physicists_hermite_polynomial_roots.py
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def physicists_hermite_polynomial_roots(input: Tensor) -> Tensor:
    input = torch.atleast_1d(input)

    if input.shape[0] <= 1:
        return torch.tensor([], dtype=input.dtype)

    if input.shape[0] == 2:
        return torch.tensor([-0.5 * input[0] / input[1]])

    output = physicists_hermite_polynomial_companion(input)

    output = torch.flip(output, dims=[0])
    output = torch.flip(output, dims=[1])

    output = torch.linalg.eigvals(output)

    output, _ = torch.sort(output.real)

    return output

beignet.physicists_hermite_polynomial_to_polynomial

physicists_hermite_polynomial_to_polynomial(input)
Source code in src/beignet/_physicists_hermite_polynomial_to_polynomial.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
def physicists_hermite_polynomial_to_polynomial(input: Tensor) -> Tensor:
    input = torch.atleast_1d(input)

    n = input.shape[0]

    if n == 1:
        return input

    if n == 2:
        input[1] = input[1] * 2

        return input
    else:
        c0 = torch.zeros_like(input)
        c0[0] = input[-2]

        c1 = torch.zeros_like(input)
        c1[0] = input[-1]

        def body(k, c0c1):
            i = n - 1 - k
            c0, c1 = c0c1
            tmp = c0
            c0 = subtract_polynomial(input[i - 2], c1 * (2 * (i - 1)))
            c1 = add_polynomial(tmp, multiply_polynomial_by_x(c1, "same") * 2)
            return c0, c1

        x = (c0, c1)

        y = x

        for index in range(0, n - 2):
            y = body(index, y)

        c0, c1 = y

        return add_polynomial(c0, multiply_polynomial_by_x(c1, "same") * 2)

beignet.physicists_hermite_polynomial_vandermonde

physicists_hermite_polynomial_vandermonde(x, degree)
Source code in src/beignet/_physicists_hermite_polynomial_vandermonde.py
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def physicists_hermite_polynomial_vandermonde(
    x: Tensor,
    degree: Tensor,
) -> Tensor:
    if degree < 0:
        raise ValueError

    x = torch.atleast_1d(x)
    dims = (degree + 1,) + x.shape
    dtyp = torch.promote_types(x.dtype, torch.tensor(0.0).dtype)
    x = x.to(dtyp)
    v = torch.empty(dims, dtype=dtyp)
    v[0] = torch.ones_like(x)

    if degree > 0:
        v[1] = x * 2

        for index in range(2, degree + 1):
            v[index] = v[index - 1] * x * 2 - v[index - 2] * (2 * (index - 1))

    return torch.moveaxis(v, 0, -1)

beignet.physicists_hermite_polynomial_vandermonde_2d

physicists_hermite_polynomial_vandermonde_2d(x, y, degree)
Source code in src/beignet/_physicists_hermite_polynomial_vandermonde_2d.py
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
def physicists_hermite_polynomial_vandermonde_2d(
    x: Tensor,
    y: Tensor,
    degree: Tensor,
) -> Tensor:
    functions = (
        physicists_hermite_polynomial_vandermonde,
        physicists_hermite_polynomial_vandermonde,
    )

    n = len(functions)

    if n != len([x, y]):
        raise ValueError

    if n != len(degree):
        raise ValueError

    if n == 0:
        raise ValueError

    matrices = []

    for i in range(n):
        matrix = functions[i]((x, y)[i], degree[i])

        matrices = [
            *matrices,
            matrix[(..., *tuple(slice(None) if j == i else None for j in range(n)))],
        ]

    vandermonde = functools.reduce(
        operator.mul,
        matrices,
    )

    return torch.reshape(
        vandermonde,
        [*vandermonde.shape[: -len(degree)], -1],
    )

beignet.physicists_hermite_polynomial_vandermonde_3d

physicists_hermite_polynomial_vandermonde_3d(x, y, z, degree)
Source code in src/beignet/_physicists_hermite_polynomial_vandermonde_3d.py
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
def physicists_hermite_polynomial_vandermonde_3d(
    x: Tensor,
    y: Tensor,
    z: Tensor,
    degree: Tensor,
) -> Tensor:
    functions = (
        physicists_hermite_polynomial_vandermonde,
        physicists_hermite_polynomial_vandermonde,
        physicists_hermite_polynomial_vandermonde,
    )

    n = len(functions)

    if n != len([x, y, z]):
        raise ValueError

    if n != len(degree):
        raise ValueError

    if n == 0:
        raise ValueError

    matrices = []

    for i in range(n):
        matrix = functions[i]((x, y, z)[i], degree[i])

        matrices = [
            *matrices,
            matrix[(..., *tuple(slice(None) if j == i else None for j in range(n)))],
        ]

    vandermonde = functools.reduce(
        operator.mul,
        matrices,
    )

    return torch.reshape(
        vandermonde,
        [*vandermonde.shape[: -len(degree)], -1],
    )

beignet.physicists_hermite_polynomial_weight

physicists_hermite_polynomial_weight(x)
Source code in src/beignet/_physicists_hermite_polynomial_weight.py
5
6
def physicists_hermite_polynomial_weight(x: Tensor) -> Tensor:
    return torch.exp(-(x**2))

beignet.physicists_hermite_polynomial_x module-attribute

physicists_hermite_polynomial_x = tensor([0.0, 1.0 / 2.0])

beignet.physicists_hermite_polynomial_zero module-attribute

physicists_hermite_polynomial_zero = tensor([0.0])

beignet.subtract_physicists_hermite_polynomial

subtract_physicists_hermite_polynomial(input, other)

Returns the difference of two polynomials.

Parameters:

Name Type Description Default
input Tensor

Polynomial coefficients.

required
other Tensor

Polynomial coefficients.

required

Returns:

Name Type Description
output Tensor

Polynomial coefficients of the difference.

Source code in src/beignet/_subtract_physicists_hermite_polynomial.py
 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
def subtract_physicists_hermite_polynomial(
    input: Tensor,
    other: Tensor,
) -> Tensor:
    r"""
    Returns the difference of two polynomials.

    Parameters
    ----------
    input : Tensor
        Polynomial coefficients.

    other : Tensor
        Polynomial coefficients.

    Returns
    -------
    output : Tensor
        Polynomial coefficients of the difference.
    """
    input = torch.atleast_1d(input)
    other = torch.atleast_1d(other)

    dtype = torch.promote_types(input.dtype, other.dtype)

    input = input.to(dtype)
    other = other.to(dtype)

    if input.shape[0] > other.shape[0]:
        output = -other

        output = torch.concatenate(
            [
                output,
                torch.zeros(
                    input.shape[0] - other.shape[0],
                    dtype=other.dtype,
                ),
            ],
        )
        output = input + output
    else:
        output = -other

        output = torch.concatenate(
            [
                output[: input.shape[0]] + input,
                output[input.shape[0] :],
            ],
        )

    return output

beignet.trim_physicists_hermite_polynomial_coefficients

trim_physicists_hermite_polynomial_coefficients(input, tol=0.0)
Source code in src/beignet/_trim_physicists_hermite_polynomial_coefficients.py
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
def trim_physicists_hermite_polynomial_coefficients(
    input: Tensor,
    tol: float = 0.0,
) -> Tensor:
    if tol < 0:
        raise ValueError

    input = torch.atleast_1d(input)

    indices = torch.nonzero(torch.abs(input) > tol)

    if indices.shape[0] == 0:
        output = input[:1] * 0
    else:
        output = input[: indices[-1] + 1]

    return output