Skip to content

Legendre Normalized Trigon

legendre_normalized_trigon

Compute the normalized Legendre polynomials of the first kind for trigonometric arguments.

Parameters:

Name Type Description Default
lmax int

The maximum degree of the Legendre polynomials.

required
x ndarray

The input array of x-coordinates.

required
y ndarray

The input array of y-coordinates. Defaults to None.

None

Returns:

Name Type Description
plm ndarray

The array of computed Legendre polynomials.

Note

Base on the celes implementation of legendre_normalized_trigon.m

Examples:

>>> lmax = 2
>>> x = np.array([0, np.pi/4, np.pi/2])
>>> y = np.array([0, 1, 0])
>>> result = legendre_normalized_trigon(lmax, x, y)
>>> print(result)
array([[[ 0.70710678,  0.        ,  0.        ],
        [ 0.        ,  0.        ,  0.        ],
        [ 0.        ,  0.        ,  0.        ]],
       [[ 0.        ,  0.        ,  0.        ],
        [ 0.        ,  0.70710678,  0.        ],
        [ 0.        ,  0.        ,  0.        ]],
       [[ 0.        ,  0.        ,  0.        ],
        [ 0.        ,  0.        ,  0.        ],
        [ 0.        ,  0.        ,  0.70710678]]])
Source code in yasfpy/functions/legendre_normalized_trigon.py
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
def legendre_normalized_trigon(lmax, x: np.ndarray, y: np.ndarray = None):
    """
    Compute the normalized Legendre polynomials of the first kind for trigonometric arguments.

    Args:
        lmax (int): The maximum degree of the Legendre polynomials.
        x (np.ndarray): The input array of x-coordinates.
        y (np.ndarray, optional): The input array of y-coordinates. Defaults to None.

    Returns:
        plm (np.ndarray): The array of computed Legendre polynomials.

    Note:
        Base on the celes implementation of [legendre_normalized_trigon.m](https://github.com/disordered-photonics/celes/blob/master/src/mathematics/legendre_normalized_trigon.m){:target="_blank"}

    Examples:
        >>> lmax = 2
        >>> x = np.array([0, np.pi/4, np.pi/2])
        >>> y = np.array([0, 1, 0])
        >>> result = legendre_normalized_trigon(lmax, x, y)
        >>> print(result)
        array([[[ 0.70710678,  0.        ,  0.        ],
                [ 0.        ,  0.        ,  0.        ],
                [ 0.        ,  0.        ,  0.        ]],
               [[ 0.        ,  0.        ,  0.        ],
                [ 0.        ,  0.70710678,  0.        ],
                [ 0.        ,  0.        ,  0.        ]],
               [[ 0.        ,  0.        ,  0.        ],
                [ 0.        ,  0.        ,  0.        ],
                [ 0.        ,  0.        ,  0.70710678]]])
    """
    #   if not(isinstance(x, np.ndarray) or np.isscalar(x) or isinstance(x, list)):
    #     return legendre_normalized_trigon_legacy(x, y, lmax)

    #   if np.isscalar(x):
    #     x = np.array([x])
    #   elif isinstance(x, list):
    #     x = np.array(x)
    size = x.shape
    if y is None:
        x = np.ravel(x)
        ct = np.cos(x)
        st = np.sin(x)
    else:
        ct = x.ravel()
        st = y.ravel()

    plm = np.zeros((lmax + 1, lmax + 1, ct.size)) * np.nan

    plm[0, 0, :] = np.sqrt(1 / 2) * np.ones_like(ct)
    plm[1, 0, :] = np.sqrt(3 / 2) * ct

    for l in range(1, lmax):
        plm[l + 1, 0, :] = (
            1 / (l + 1) * np.sqrt((2 * l + 1) * (2 * l + 3)) * plm[l, 0, :] * ct
            - l / (l + 1) * np.sqrt((2 * l + 3) / (2 * l - 1)) * plm[l - 1, 0, :]
        )

    for m in range(1, lmax + 1):
        plm[m - 1, m, :] = np.zeros_like(ct)
        plm[m, m, :] = (
            np.sqrt((2 * m + 1) / 2 / np.math.factorial(2 * m))
            * np.prod(np.arange(1, 2 * m, 2))
            * np.power(st, m)
        )
        for l in range(m, lmax):
            plm[l + 1, m, :] = (
                np.sqrt((2 * l + 1) * (2 * l + 3) / (l + 1 - m) / (l + 1 + m))
                * ct
                * plm[l, m, :]
                - np.sqrt(
                    (2 * l + 3)
                    * (l - m)
                    * (l + m)
                    / (2 * l - 1)
                    / (l + 1 - m)
                    / (l + 1 + m)
                )
                * plm[l - 1, m, :]
            )

    plm = np.reshape(plm, np.concatenate(([lmax + 1, lmax + 1], size)))

    return plm

legendre_normalized_trigon_legacy

Calculate the normalized Legendre polynomials for trigonometric functions.

Parameters:

Name Type Description Default
x float or Symbol

The input variable x.

required
y float or Symbol

The input variable y. Defaults to None.

None
lmax int

The maximum degree of the Legendre polynomials. Defaults to 4.

4

Returns:

Name Type Description
plm ndarray

The matrix of Legendre polynomials.

Source code in yasfpy/functions/legendre_normalized_trigon.py
 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
def legendre_normalized_trigon_legacy(x, y=None, lmax=4):
    """
    Calculate the normalized Legendre polynomials for trigonometric functions.

    Args:
        x (float or sympy.core.symbol.Symbol): The input variable x.
        y (float or sympy.core.symbol.Symbol, optional): The input variable y. Defaults to None.
        lmax (int, optional): The maximum degree of the Legendre polynomials. Defaults to 4.

    Returns:
        plm (numpy.ndarray): The matrix of Legendre polynomials.

    """
    import sympy as sym
    import numpy as np

    plm = sym.zeros(lmax + 1, lmax + 1)
    if y == None:
        ct = sym.cos(x)
        st = sym.sin(x)
    elif isinstance(x, sym.core.symbol.Symbol) and isinstance(
        y, sym.core.symbol.Symbol
    ):
        ct = x
        st = y
    else:
        ct = sym.Symbol("ct")
        st = sym.Symbol("st")

    plm[0, 0] = np.sqrt(1 / 2)
    plm[1, 0] = np.sqrt(3 / 2) * ct

    for l in range(1, lmax):
        plm[l + 1, 0] = (
            1 / (l + 1) * np.sqrt((2 * l + 1) * (2 * l + 3)) * plm[l, 0] * ct
            - l / (l + 1) * np.sqrt((2 * l + 3) / (2 * l - 1)) * plm[l - 1, 0]
        )

    for m in range(1, lmax + 1):
        plm[m - 1, m] = np.zeros_like(ct)
        plm[m, m] = (
            np.sqrt((2 * m + 1) / 2 / np.math.factorial(2 * m))
            * np.prod(np.arange(1, 2 * m, 2))
            * st**m
        )
        for l in range(m, lmax):
            plm[l + 1, m] = (
                np.sqrt((2 * l + 1) * (2 * l + 3) / (l + 1 - m) / (l + 1 + m))
                * ct
                * plm[l, m]
                - np.sqrt(
                    (2 * l + 3)
                    * (l - m)
                    * (l + m)
                    / (2 * l - 1)
                    / (l + 1 - m)
                    / (l + 1 + m)
                )
                * plm[l - 1, m]
            )

    return plm

Comments