nrl-tracker 0.20.1__py3-none-any.whl → 0.21.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {nrl_tracker-0.20.1.dist-info → nrl_tracker-0.21.0.dist-info}/METADATA +1 -1
- {nrl_tracker-0.20.1.dist-info → nrl_tracker-0.21.0.dist-info}/RECORD +12 -8
- pytcl/mathematical_functions/numerical_integration/quadrature.py +36 -7
- pytcl/mathematical_functions/special_functions/__init__.py +82 -0
- pytcl/mathematical_functions/special_functions/bessel.py +260 -0
- pytcl/mathematical_functions/special_functions/debye.py +288 -0
- pytcl/mathematical_functions/special_functions/hypergeometric.py +420 -0
- pytcl/mathematical_functions/special_functions/lambert_w.py +294 -0
- pytcl/mathematical_functions/special_functions/marcum_q.py +370 -0
- {nrl_tracker-0.20.1.dist-info → nrl_tracker-0.21.0.dist-info}/LICENSE +0 -0
- {nrl_tracker-0.20.1.dist-info → nrl_tracker-0.21.0.dist-info}/WHEEL +0 -0
- {nrl_tracker-0.20.1.dist-info → nrl_tracker-0.21.0.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: nrl-tracker
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.21.0
|
|
4
4
|
Summary: Python port of the U.S. Naval Research Laboratory's Tracker Component Library for target tracking algorithms
|
|
5
5
|
Author: Original: David F. Crouse, Naval Research Laboratory
|
|
6
6
|
Maintainer: Python Port Contributors
|
|
@@ -88,17 +88,21 @@ pytcl/mathematical_functions/geometry/geometry.py,sha256=l63wQnhCtJwVHZOJeONX1qy
|
|
|
88
88
|
pytcl/mathematical_functions/interpolation/__init__.py,sha256=HDhP7ZsgUrXFBNJ_eCZEdp5gizWJ-BxvkQSCMnvBg3A,677
|
|
89
89
|
pytcl/mathematical_functions/interpolation/interpolation.py,sha256=2cXMDgWBjWDGHnK1K_lawFlJL8oPl5AQGf9MNgsESfo,12610
|
|
90
90
|
pytcl/mathematical_functions/numerical_integration/__init__.py,sha256=iXiHzyV_KIhCv7tXErXlN1_fUEACN6yN3CYDHRA7esw,974
|
|
91
|
-
pytcl/mathematical_functions/numerical_integration/quadrature.py,sha256=
|
|
91
|
+
pytcl/mathematical_functions/numerical_integration/quadrature.py,sha256=ZRMKs0vbcgFDe1Sr8sjyEOkALLmJU4zKRJjoPEcXrUc,15670
|
|
92
92
|
pytcl/mathematical_functions/polynomials/__init__.py,sha256=WJWZcoQhnvy5f59-kncMTgD9mCtgwfDgULvDYYHS5ys,43
|
|
93
93
|
pytcl/mathematical_functions/signal_processing/__init__.py,sha256=_SzzBVtxmSvP8FKeogRdNmFo8FOVDDoexVOqd-lE7do,2325
|
|
94
94
|
pytcl/mathematical_functions/signal_processing/detection.py,sha256=9F0xdy3hMat1czSWAQYMExn0kY5DBRpyBneAfjjHUVI,30377
|
|
95
95
|
pytcl/mathematical_functions/signal_processing/filters.py,sha256=8Ojf4h4rfiucBXqUmB1odvHH41Gf3rPwmWCMKb-qzWk,23435
|
|
96
96
|
pytcl/mathematical_functions/signal_processing/matched_filter.py,sha256=AahJZRZk2IIXzRL7www0n8bc0XoKabaLOe8yYNSjuDY,22893
|
|
97
|
-
pytcl/mathematical_functions/special_functions/__init__.py,sha256=
|
|
98
|
-
pytcl/mathematical_functions/special_functions/bessel.py,sha256=
|
|
97
|
+
pytcl/mathematical_functions/special_functions/__init__.py,sha256=qDPGfee1i1NkVi9LXJKnsWXL3CWHkPQINrkwqLqB8YU,3796
|
|
98
|
+
pytcl/mathematical_functions/special_functions/bessel.py,sha256=M0mwLQBaUXEHA8wyKReJ2D66I1v1XR7y-txAipd-WDs,14377
|
|
99
|
+
pytcl/mathematical_functions/special_functions/debye.py,sha256=Nchjwkl1vzSL1L7nQpslb-lvT49LgTfdTIQMeSNn4vQ,6689
|
|
99
100
|
pytcl/mathematical_functions/special_functions/elliptic.py,sha256=WyzBkrfZufIR5dUmCKGcxp6KNpVDrU89NGLDyRrZOqQ,7418
|
|
100
101
|
pytcl/mathematical_functions/special_functions/error_functions.py,sha256=a3SS8FYAMRv1KdCmebOZL95yjvVt9gZRF2XOjHvQ9M8,6253
|
|
101
102
|
pytcl/mathematical_functions/special_functions/gamma_functions.py,sha256=xXN_9SCokH10HjE8PpaPKHYVK_RZRHRAbZgR2mZYIAA,10191
|
|
103
|
+
pytcl/mathematical_functions/special_functions/hypergeometric.py,sha256=gKn_tXboEst7pVDiW15IbKFAANM4XVqKtDc1dmWL-2A,9768
|
|
104
|
+
pytcl/mathematical_functions/special_functions/lambert_w.py,sha256=ivRc4KH5Lwoxb_yijrJEwG0ITa0hhcYF7_gCfVBBNW4,6855
|
|
105
|
+
pytcl/mathematical_functions/special_functions/marcum_q.py,sha256=OZ5QjIB1e_XvRG8A-3dbZ13YXHtdk2EYVEPaqtgVr14,9580
|
|
102
106
|
pytcl/mathematical_functions/statistics/__init__.py,sha256=dfypStgmnFmOrnWcm-3CEvLinONHraFgx9O66_37bqw,1278
|
|
103
107
|
pytcl/mathematical_functions/statistics/distributions.py,sha256=icfFIIKCEFzkpFHuYGWL197nm8wvS7UPJlr9kd_uEgw,19373
|
|
104
108
|
pytcl/mathematical_functions/statistics/estimators.py,sha256=TLnYXSwk5MzBakZrzDBupbOB3ONmJI7q1-oB2xuSVQM,10831
|
|
@@ -137,8 +141,8 @@ pytcl/trackers/mht.py,sha256=7mwhMmja3ri2wnx7W1wueDGn2r3ArwAxJDPUJ7IZAkQ,20617
|
|
|
137
141
|
pytcl/trackers/multi_target.py,sha256=7ZL8V25TO_rEMtQm2eYkScesDQHC9qXZVHLHyVbxy3M,10529
|
|
138
142
|
pytcl/trackers/single_target.py,sha256=Yy3FwaNTArMWcaod-0HVeiioNV4xLWxNDn_7ZPVqQYs,6562
|
|
139
143
|
pytcl/transponders/__init__.py,sha256=5fL4u3lKCYgPLo5uFeuZbtRZkJPABntuKYGUvVgMMEI,41
|
|
140
|
-
nrl_tracker-0.
|
|
141
|
-
nrl_tracker-0.
|
|
142
|
-
nrl_tracker-0.
|
|
143
|
-
nrl_tracker-0.
|
|
144
|
-
nrl_tracker-0.
|
|
144
|
+
nrl_tracker-0.21.0.dist-info/LICENSE,sha256=rB5G4WppIIUzMOYr2N6uyYlNJ00hRJqE5tie6BMvYuE,1612
|
|
145
|
+
nrl_tracker-0.21.0.dist-info/METADATA,sha256=eDRPYJpt_3_IysLZ1cPPhRikpdZmtCd_1EF8Fmfyq6M,9699
|
|
146
|
+
nrl_tracker-0.21.0.dist-info/WHEEL,sha256=pL8R0wFFS65tNSRnaOVrsw9EOkOqxLrlUPenUYnJKNo,91
|
|
147
|
+
nrl_tracker-0.21.0.dist-info/top_level.txt,sha256=17megxcrTPBWwPZTh6jTkwTKxX7No-ZqRpyvElnnO-s,6
|
|
148
|
+
nrl_tracker-0.21.0.dist-info/RECORD,,
|
|
@@ -336,7 +336,8 @@ def romberg(
|
|
|
336
336
|
f: Callable[[float], float],
|
|
337
337
|
a: float,
|
|
338
338
|
b: float,
|
|
339
|
-
|
|
339
|
+
tol: float = 1e-8,
|
|
340
|
+
max_steps: int = 20,
|
|
340
341
|
) -> float:
|
|
341
342
|
"""
|
|
342
343
|
Romberg integration.
|
|
@@ -351,19 +352,47 @@ def romberg(
|
|
|
351
352
|
Lower limit.
|
|
352
353
|
b : float
|
|
353
354
|
Upper limit.
|
|
354
|
-
|
|
355
|
-
|
|
355
|
+
tol : float, optional
|
|
356
|
+
Desired tolerance. Default is 1e-8.
|
|
357
|
+
max_steps : int, optional
|
|
358
|
+
Maximum number of extrapolation steps. Default is 20.
|
|
356
359
|
|
|
357
360
|
Returns
|
|
358
361
|
-------
|
|
359
362
|
result : float
|
|
360
363
|
Estimated integral value.
|
|
361
364
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
scipy.integrate.romberg
|
|
365
|
+
Notes
|
|
366
|
+
-----
|
|
367
|
+
This is a native implementation that does not depend on scipy.integrate.romberg,
|
|
368
|
+
which was deprecated in scipy 1.12 and removed in scipy 1.15.
|
|
365
369
|
"""
|
|
366
|
-
|
|
370
|
+
# Romberg table
|
|
371
|
+
R = np.zeros((max_steps, max_steps), dtype=np.float64)
|
|
372
|
+
|
|
373
|
+
h = b - a
|
|
374
|
+
R[0, 0] = 0.5 * h * (f(a) + f(b))
|
|
375
|
+
|
|
376
|
+
for i in range(1, max_steps):
|
|
377
|
+
h = h / 2.0
|
|
378
|
+
|
|
379
|
+
# Composite trapezoidal rule with 2^i intervals
|
|
380
|
+
n_new = 2 ** (i - 1)
|
|
381
|
+
total = 0.0
|
|
382
|
+
for k in range(1, n_new + 1):
|
|
383
|
+
total += f(a + (2 * k - 1) * h)
|
|
384
|
+
R[i, 0] = 0.5 * R[i - 1, 0] + h * total
|
|
385
|
+
|
|
386
|
+
# Richardson extrapolation
|
|
387
|
+
for j in range(1, i + 1):
|
|
388
|
+
factor = 4**j
|
|
389
|
+
R[i, j] = (factor * R[i, j - 1] - R[i - 1, j - 1]) / (factor - 1)
|
|
390
|
+
|
|
391
|
+
# Check convergence
|
|
392
|
+
if i > 0 and abs(R[i, i] - R[i - 1, i - 1]) < tol:
|
|
393
|
+
return float(R[i, i])
|
|
394
|
+
|
|
395
|
+
return float(R[max_steps - 1, max_steps - 1])
|
|
367
396
|
|
|
368
397
|
|
|
369
398
|
def simpson(
|
|
@@ -7,19 +7,38 @@ physics, signal processing, and statistical applications:
|
|
|
7
7
|
- Gamma and beta functions
|
|
8
8
|
- Error functions
|
|
9
9
|
- Elliptic integrals
|
|
10
|
+
- Marcum Q function (radar detection)
|
|
11
|
+
- Hypergeometric functions
|
|
12
|
+
- Lambert W function
|
|
13
|
+
- Debye functions (thermodynamics)
|
|
10
14
|
"""
|
|
11
15
|
|
|
12
16
|
from pytcl.mathematical_functions.special_functions.bessel import (
|
|
13
17
|
airy,
|
|
18
|
+
bessel_deriv,
|
|
19
|
+
bessel_ratio,
|
|
20
|
+
bessel_zeros,
|
|
14
21
|
besselh,
|
|
15
22
|
besseli,
|
|
16
23
|
besselj,
|
|
17
24
|
besselk,
|
|
18
25
|
bessely,
|
|
26
|
+
kelvin,
|
|
19
27
|
spherical_in,
|
|
20
28
|
spherical_jn,
|
|
21
29
|
spherical_kn,
|
|
22
30
|
spherical_yn,
|
|
31
|
+
struve_h,
|
|
32
|
+
struve_l,
|
|
33
|
+
)
|
|
34
|
+
from pytcl.mathematical_functions.special_functions.debye import (
|
|
35
|
+
debye,
|
|
36
|
+
debye_1,
|
|
37
|
+
debye_2,
|
|
38
|
+
debye_3,
|
|
39
|
+
debye_4,
|
|
40
|
+
debye_entropy,
|
|
41
|
+
debye_heat_capacity,
|
|
23
42
|
)
|
|
24
43
|
from pytcl.mathematical_functions.special_functions.elliptic import ( # noqa: E501
|
|
25
44
|
ellipe,
|
|
@@ -62,6 +81,32 @@ from pytcl.mathematical_functions.special_functions.gamma_functions import ( #
|
|
|
62
81
|
perm,
|
|
63
82
|
polygamma,
|
|
64
83
|
)
|
|
84
|
+
from pytcl.mathematical_functions.special_functions.hypergeometric import (
|
|
85
|
+
falling_factorial,
|
|
86
|
+
generalized_hypergeometric,
|
|
87
|
+
hyp0f1,
|
|
88
|
+
hyp1f1,
|
|
89
|
+
hyp1f1_regularized,
|
|
90
|
+
hyp2f1,
|
|
91
|
+
hyperu,
|
|
92
|
+
pochhammer,
|
|
93
|
+
)
|
|
94
|
+
from pytcl.mathematical_functions.special_functions.lambert_w import (
|
|
95
|
+
lambert_w,
|
|
96
|
+
lambert_w_real,
|
|
97
|
+
omega_constant,
|
|
98
|
+
solve_exponential_equation,
|
|
99
|
+
time_delay_equation,
|
|
100
|
+
wright_omega,
|
|
101
|
+
)
|
|
102
|
+
from pytcl.mathematical_functions.special_functions.marcum_q import (
|
|
103
|
+
log_marcum_q,
|
|
104
|
+
marcum_q,
|
|
105
|
+
marcum_q1,
|
|
106
|
+
marcum_q_inv,
|
|
107
|
+
nuttall_q,
|
|
108
|
+
swerling_detection_probability,
|
|
109
|
+
)
|
|
65
110
|
|
|
66
111
|
__all__ = [
|
|
67
112
|
# Bessel functions
|
|
@@ -75,6 +120,12 @@ __all__ = [
|
|
|
75
120
|
"spherical_in",
|
|
76
121
|
"spherical_kn",
|
|
77
122
|
"airy",
|
|
123
|
+
"bessel_ratio",
|
|
124
|
+
"bessel_deriv",
|
|
125
|
+
"bessel_zeros",
|
|
126
|
+
"struve_h",
|
|
127
|
+
"struve_l",
|
|
128
|
+
"kelvin",
|
|
78
129
|
# Gamma functions
|
|
79
130
|
"gamma",
|
|
80
131
|
"gammaln",
|
|
@@ -113,4 +164,35 @@ __all__ = [
|
|
|
113
164
|
"elliprg",
|
|
114
165
|
"elliprj",
|
|
115
166
|
"elliprc",
|
|
167
|
+
# Marcum Q function (radar detection)
|
|
168
|
+
"marcum_q",
|
|
169
|
+
"marcum_q1",
|
|
170
|
+
"log_marcum_q",
|
|
171
|
+
"marcum_q_inv",
|
|
172
|
+
"nuttall_q",
|
|
173
|
+
"swerling_detection_probability",
|
|
174
|
+
# Lambert W function
|
|
175
|
+
"lambert_w",
|
|
176
|
+
"lambert_w_real",
|
|
177
|
+
"omega_constant",
|
|
178
|
+
"wright_omega",
|
|
179
|
+
"solve_exponential_equation",
|
|
180
|
+
"time_delay_equation",
|
|
181
|
+
# Debye functions
|
|
182
|
+
"debye",
|
|
183
|
+
"debye_1",
|
|
184
|
+
"debye_2",
|
|
185
|
+
"debye_3",
|
|
186
|
+
"debye_4",
|
|
187
|
+
"debye_heat_capacity",
|
|
188
|
+
"debye_entropy",
|
|
189
|
+
# Hypergeometric functions
|
|
190
|
+
"hyp0f1",
|
|
191
|
+
"hyp1f1",
|
|
192
|
+
"hyp2f1",
|
|
193
|
+
"hyperu",
|
|
194
|
+
"hyp1f1_regularized",
|
|
195
|
+
"pochhammer",
|
|
196
|
+
"falling_factorial",
|
|
197
|
+
"generalized_hypergeometric",
|
|
116
198
|
]
|
|
@@ -345,6 +345,260 @@ def airy(x: ArrayLike) -> tuple:
|
|
|
345
345
|
return tuple(np.asarray(r, dtype=np.float64) for r in result)
|
|
346
346
|
|
|
347
347
|
|
|
348
|
+
def bessel_ratio(
|
|
349
|
+
n: Union[int, float],
|
|
350
|
+
x: ArrayLike,
|
|
351
|
+
kind: str = "j",
|
|
352
|
+
) -> NDArray[np.floating]:
|
|
353
|
+
"""
|
|
354
|
+
Ratio of Bessel functions J_{n+1}(x) / J_n(x) or I_{n+1}(x) / I_n(x).
|
|
355
|
+
|
|
356
|
+
Parameters
|
|
357
|
+
----------
|
|
358
|
+
n : int or float
|
|
359
|
+
Order of the Bessel function in the denominator.
|
|
360
|
+
x : array_like
|
|
361
|
+
Argument of the Bessel function.
|
|
362
|
+
kind : str, optional
|
|
363
|
+
Type of Bessel function: 'j' for J_n, 'i' for I_n. Default is 'j'.
|
|
364
|
+
|
|
365
|
+
Returns
|
|
366
|
+
-------
|
|
367
|
+
ratio : ndarray
|
|
368
|
+
Values of J_{n+1}(x) / J_n(x) or I_{n+1}(x) / I_n(x).
|
|
369
|
+
|
|
370
|
+
Notes
|
|
371
|
+
-----
|
|
372
|
+
Uses the recurrence relation for numerical stability:
|
|
373
|
+
J_{n+1}(x) / J_n(x) = 2n/x - 1/(J_n(x)/J_{n-1}(x))
|
|
374
|
+
|
|
375
|
+
Examples
|
|
376
|
+
--------
|
|
377
|
+
>>> bessel_ratio(0, 1) # J_1(1) / J_0(1)
|
|
378
|
+
0.5767...
|
|
379
|
+
"""
|
|
380
|
+
x = np.asarray(x, dtype=np.float64)
|
|
381
|
+
|
|
382
|
+
if kind.lower() == "j":
|
|
383
|
+
num = sp.jv(n + 1, x)
|
|
384
|
+
den = sp.jv(n, x)
|
|
385
|
+
elif kind.lower() == "i":
|
|
386
|
+
num = sp.iv(n + 1, x)
|
|
387
|
+
den = sp.iv(n, x)
|
|
388
|
+
else:
|
|
389
|
+
raise ValueError(f"kind must be 'j' or 'i', got '{kind}'")
|
|
390
|
+
|
|
391
|
+
# Handle zeros in denominator
|
|
392
|
+
with np.errstate(divide="ignore", invalid="ignore"):
|
|
393
|
+
ratio = np.where(den != 0, num / den, np.inf * np.sign(num))
|
|
394
|
+
|
|
395
|
+
return np.asarray(ratio, dtype=np.float64)
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
def bessel_deriv(
|
|
399
|
+
n: Union[int, float],
|
|
400
|
+
x: ArrayLike,
|
|
401
|
+
kind: str = "j",
|
|
402
|
+
) -> NDArray[np.floating]:
|
|
403
|
+
"""
|
|
404
|
+
Derivative of Bessel function d/dx[B_n(x)].
|
|
405
|
+
|
|
406
|
+
Parameters
|
|
407
|
+
----------
|
|
408
|
+
n : int or float
|
|
409
|
+
Order of the Bessel function.
|
|
410
|
+
x : array_like
|
|
411
|
+
Argument of the Bessel function.
|
|
412
|
+
kind : str, optional
|
|
413
|
+
Type of Bessel function: 'j', 'y', 'i', or 'k'. Default is 'j'.
|
|
414
|
+
|
|
415
|
+
Returns
|
|
416
|
+
-------
|
|
417
|
+
deriv : ndarray
|
|
418
|
+
Values of dB_n(x)/dx.
|
|
419
|
+
|
|
420
|
+
Notes
|
|
421
|
+
-----
|
|
422
|
+
Uses the identity:
|
|
423
|
+
dJ_n/dx = (J_{n-1}(x) - J_{n+1}(x)) / 2
|
|
424
|
+
dY_n/dx = (Y_{n-1}(x) - Y_{n+1}(x)) / 2
|
|
425
|
+
dI_n/dx = (I_{n-1}(x) + I_{n+1}(x)) / 2
|
|
426
|
+
dK_n/dx = -(K_{n-1}(x) + K_{n+1}(x)) / 2
|
|
427
|
+
|
|
428
|
+
Examples
|
|
429
|
+
--------
|
|
430
|
+
>>> bessel_deriv(0, 1, kind='j') # -J_1(1)
|
|
431
|
+
-0.4400...
|
|
432
|
+
"""
|
|
433
|
+
x = np.asarray(x, dtype=np.float64)
|
|
434
|
+
|
|
435
|
+
kind = kind.lower()
|
|
436
|
+
if kind == "j":
|
|
437
|
+
deriv = (sp.jv(n - 1, x) - sp.jv(n + 1, x)) / 2
|
|
438
|
+
elif kind == "y":
|
|
439
|
+
deriv = (sp.yv(n - 1, x) - sp.yv(n + 1, x)) / 2
|
|
440
|
+
elif kind == "i":
|
|
441
|
+
deriv = (sp.iv(n - 1, x) + sp.iv(n + 1, x)) / 2
|
|
442
|
+
elif kind == "k":
|
|
443
|
+
deriv = -(sp.kv(n - 1, x) + sp.kv(n + 1, x)) / 2
|
|
444
|
+
else:
|
|
445
|
+
raise ValueError(f"kind must be 'j', 'y', 'i', or 'k', got '{kind}'")
|
|
446
|
+
|
|
447
|
+
return np.asarray(deriv, dtype=np.float64)
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
def struve_h(
|
|
451
|
+
n: Union[int, float],
|
|
452
|
+
x: ArrayLike,
|
|
453
|
+
) -> NDArray[np.floating]:
|
|
454
|
+
"""
|
|
455
|
+
Struve function H_n(x).
|
|
456
|
+
|
|
457
|
+
The Struve function is defined by the integral:
|
|
458
|
+
H_n(x) = (2/sqrt(pi)) * (x/2)^n * integral from 0 to pi/2 of
|
|
459
|
+
sin(x*cos(t)) * sin^(2n)(t) dt
|
|
460
|
+
|
|
461
|
+
Parameters
|
|
462
|
+
----------
|
|
463
|
+
n : int or float
|
|
464
|
+
Order of the Struve function.
|
|
465
|
+
x : array_like
|
|
466
|
+
Argument of the function.
|
|
467
|
+
|
|
468
|
+
Returns
|
|
469
|
+
-------
|
|
470
|
+
H : ndarray
|
|
471
|
+
Values of H_n(x).
|
|
472
|
+
|
|
473
|
+
Notes
|
|
474
|
+
-----
|
|
475
|
+
Related to Bessel functions through:
|
|
476
|
+
H_0(x) is the particular solution of y'' + y'/x + y = 2/(pi*x)
|
|
477
|
+
|
|
478
|
+
Examples
|
|
479
|
+
--------
|
|
480
|
+
>>> struve_h(0, 1)
|
|
481
|
+
0.5688...
|
|
482
|
+
"""
|
|
483
|
+
return np.asarray(sp.struve(n, x), dtype=np.float64)
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
def struve_l(
|
|
487
|
+
n: Union[int, float],
|
|
488
|
+
x: ArrayLike,
|
|
489
|
+
) -> NDArray[np.floating]:
|
|
490
|
+
"""
|
|
491
|
+
Modified Struve function L_n(x).
|
|
492
|
+
|
|
493
|
+
The modified Struve function is related to the Struve function by:
|
|
494
|
+
L_n(x) = -i * exp(-i*n*pi/2) * H_n(i*x)
|
|
495
|
+
|
|
496
|
+
Parameters
|
|
497
|
+
----------
|
|
498
|
+
n : int or float
|
|
499
|
+
Order of the modified Struve function.
|
|
500
|
+
x : array_like
|
|
501
|
+
Argument of the function.
|
|
502
|
+
|
|
503
|
+
Returns
|
|
504
|
+
-------
|
|
505
|
+
L : ndarray
|
|
506
|
+
Values of L_n(x).
|
|
507
|
+
"""
|
|
508
|
+
return np.asarray(sp.modstruve(n, x), dtype=np.float64)
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
def bessel_zeros(
|
|
512
|
+
n: int,
|
|
513
|
+
nt: int,
|
|
514
|
+
kind: str = "j",
|
|
515
|
+
) -> NDArray[np.floating]:
|
|
516
|
+
"""
|
|
517
|
+
Zeros of Bessel functions.
|
|
518
|
+
|
|
519
|
+
Computes the first nt zeros of J_n(x), Y_n(x), or their derivatives.
|
|
520
|
+
|
|
521
|
+
Parameters
|
|
522
|
+
----------
|
|
523
|
+
n : int
|
|
524
|
+
Order of the Bessel function.
|
|
525
|
+
nt : int
|
|
526
|
+
Number of zeros to compute.
|
|
527
|
+
kind : str, optional
|
|
528
|
+
Type: 'j' for J_n zeros, 'y' for Y_n zeros,
|
|
529
|
+
'jp' for J_n' zeros, 'yp' for Y_n' zeros. Default is 'j'.
|
|
530
|
+
|
|
531
|
+
Returns
|
|
532
|
+
-------
|
|
533
|
+
zeros : ndarray
|
|
534
|
+
Array of zeros.
|
|
535
|
+
|
|
536
|
+
Examples
|
|
537
|
+
--------
|
|
538
|
+
>>> bessel_zeros(0, 3, kind='j') # First 3 zeros of J_0
|
|
539
|
+
array([2.404..., 5.520..., 8.653...])
|
|
540
|
+
"""
|
|
541
|
+
kind = kind.lower()
|
|
542
|
+
|
|
543
|
+
if kind == "j":
|
|
544
|
+
return np.asarray(sp.jn_zeros(n, nt), dtype=np.float64)
|
|
545
|
+
elif kind == "y":
|
|
546
|
+
return np.asarray(sp.yn_zeros(n, nt), dtype=np.float64)
|
|
547
|
+
elif kind == "jp":
|
|
548
|
+
return np.asarray(sp.jnp_zeros(n, nt), dtype=np.float64)
|
|
549
|
+
elif kind == "yp":
|
|
550
|
+
return np.asarray(sp.ynp_zeros(n, nt), dtype=np.float64)
|
|
551
|
+
else:
|
|
552
|
+
raise ValueError(f"kind must be 'j', 'y', 'jp', or 'yp', got '{kind}'")
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
def kelvin(
|
|
556
|
+
x: ArrayLike,
|
|
557
|
+
) -> tuple:
|
|
558
|
+
"""
|
|
559
|
+
Kelvin functions ber, bei, ker, kei.
|
|
560
|
+
|
|
561
|
+
Kelvin functions are the real and imaginary parts of the
|
|
562
|
+
Bessel functions with argument x*exp(3*pi*i/4).
|
|
563
|
+
|
|
564
|
+
Parameters
|
|
565
|
+
----------
|
|
566
|
+
x : array_like
|
|
567
|
+
Argument of the Kelvin functions.
|
|
568
|
+
|
|
569
|
+
Returns
|
|
570
|
+
-------
|
|
571
|
+
ber : ndarray
|
|
572
|
+
Kelvin function ber(x).
|
|
573
|
+
bei : ndarray
|
|
574
|
+
Kelvin function bei(x).
|
|
575
|
+
ker : ndarray
|
|
576
|
+
Kelvin function ker(x).
|
|
577
|
+
kei : ndarray
|
|
578
|
+
Kelvin function kei(x).
|
|
579
|
+
|
|
580
|
+
Notes
|
|
581
|
+
-----
|
|
582
|
+
ber(x) + i*bei(x) = J_0(x * exp(3*pi*i/4))
|
|
583
|
+
ker(x) + i*kei(x) = K_0(x * exp(pi*i/4))
|
|
584
|
+
|
|
585
|
+
Examples
|
|
586
|
+
--------
|
|
587
|
+
>>> ber, bei, ker, kei = kelvin(1)
|
|
588
|
+
>>> ber
|
|
589
|
+
0.984...
|
|
590
|
+
"""
|
|
591
|
+
x = np.asarray(x, dtype=np.float64)
|
|
592
|
+
|
|
593
|
+
# Use the individual scipy Kelvin functions for real-valued results
|
|
594
|
+
ber = np.asarray(sp.ber(x), dtype=np.float64)
|
|
595
|
+
bei = np.asarray(sp.bei(x), dtype=np.float64)
|
|
596
|
+
ker = np.asarray(sp.ker(x), dtype=np.float64)
|
|
597
|
+
kei = np.asarray(sp.kei(x), dtype=np.float64)
|
|
598
|
+
|
|
599
|
+
return ber, bei, ker, kei
|
|
600
|
+
|
|
601
|
+
|
|
348
602
|
__all__ = [
|
|
349
603
|
"besselj",
|
|
350
604
|
"bessely",
|
|
@@ -356,4 +610,10 @@ __all__ = [
|
|
|
356
610
|
"spherical_in",
|
|
357
611
|
"spherical_kn",
|
|
358
612
|
"airy",
|
|
613
|
+
"bessel_ratio",
|
|
614
|
+
"bessel_deriv",
|
|
615
|
+
"struve_h",
|
|
616
|
+
"struve_l",
|
|
617
|
+
"bessel_zeros",
|
|
618
|
+
"kelvin",
|
|
359
619
|
]
|