Coverage for yasfpy/functions/legendre_normalized_trigon.py: 7%
42 statements
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-15 20:36 +0100
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-15 20:36 +0100
1import numpy as np
3# https://github.com/disordered-photonics/celes/blob/master/src/mathematics/legendre_normalized_trigon.m
6def legendre_normalized_trigon(lmax, x: np.ndarray, y: np.ndarray = None):
7 # if not(isinstance(x, np.ndarray) or np.isscalar(x) or isinstance(x, list)):
8 # return legendre_normalized_trigon_legacy(x, y, lmax)
10 # if np.isscalar(x):
11 # x = np.array([x])
12 # elif isinstance(x, list):
13 # x = np.array(x)
14 size = x.shape
15 if y is None:
16 x = np.ravel(x)
17 ct = np.cos(x)
18 st = np.sin(x)
19 else:
20 ct = x.ravel()
21 st = y.ravel()
23 plm = np.zeros((lmax + 1, lmax + 1, ct.size)) * np.nan
25 plm[0, 0, :] = np.sqrt(1 / 2) * np.ones_like(ct)
26 plm[1, 0, :] = np.sqrt(3 / 2) * ct
28 for l in range(1, lmax):
29 plm[l + 1, 0, :] = (
30 1 / (l + 1) * np.sqrt((2 * l + 1) * (2 * l + 3)) * plm[l, 0, :] * ct
31 - l / (l + 1) * np.sqrt((2 * l + 3) / (2 * l - 1)) * plm[l - 1, 0, :]
32 )
34 for m in range(1, lmax + 1):
35 plm[m - 1, m, :] = np.zeros_like(ct)
36 plm[m, m, :] = (
37 np.sqrt((2 * m + 1) / 2 / np.math.factorial(2 * m))
38 * np.prod(np.arange(1, 2 * m, 2))
39 * np.power(st, m)
40 )
41 for l in range(m, lmax):
42 plm[l + 1, m, :] = (
43 np.sqrt((2 * l + 1) * (2 * l + 3) / (l + 1 - m) / (l + 1 + m))
44 * ct
45 * plm[l, m, :]
46 - np.sqrt(
47 (2 * l + 3)
48 * (l - m)
49 * (l + m)
50 / (2 * l - 1)
51 / (l + 1 - m)
52 / (l + 1 + m)
53 )
54 * plm[l - 1, m, :]
55 )
57 plm = np.reshape(plm, np.concatenate(([lmax + 1, lmax + 1], size)))
59 return plm
62def legendre_normalized_trigon_legacy(x, y=None, lmax=4):
63 import sympy as sym
65 plm = sym.zeros(lmax + 1, lmax + 1)
66 if y == None:
67 ct = sym.cos(x)
68 st = sym.sin(x)
69 elif isinstance(x, sym.core.symbol.Symbol) and isinstance(
70 y, sym.core.symbol.Symbol
71 ):
72 ct = x
73 st = y
74 else:
75 ct = sym.Symbol("ct")
76 st = sym.Symbol("st")
78 plm[0, 0] = np.sqrt(1 / 2)
79 plm[1, 0] = np.sqrt(3 / 2) * ct
81 for l in range(1, lmax):
82 plm[l + 1, 0] = (
83 1 / (l + 1) * np.sqrt((2 * l + 1) * (2 * l + 3)) * plm[l, 0] * ct
84 - l / (l + 1) * np.sqrt((2 * l + 3) / (2 * l - 1)) * plm[l - 1, 0]
85 )
87 for m in range(1, lmax + 1):
88 plm[m - 1, m] = np.zeros_like(ct)
89 plm[m, m] = (
90 np.sqrt((2 * m + 1) / 2 / np.math.factorial(2 * m))
91 * np.prod(np.arange(1, 2 * m, 2))
92 * st**m
93 )
94 for l in range(m, lmax):
95 plm[l + 1, m] = (
96 np.sqrt((2 * l + 1) * (2 * l + 3) / (l + 1 - m) / (l + 1 + m))
97 * ct
98 * plm[l, m]
99 - np.sqrt(
100 (2 * l + 3)
101 * (l - m)
102 * (l + m)
103 / (2 * l - 1)
104 / (l + 1 - m)
105 / (l + 1 + m)
106 )
107 * plm[l - 1, m]
108 )
110 return plm