nrl-tracker 1.6.0__py3-none-any.whl → 1.7.1__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-1.6.0.dist-info → nrl_tracker-1.7.1.dist-info}/METADATA +14 -10
- {nrl_tracker-1.6.0.dist-info → nrl_tracker-1.7.1.dist-info}/RECORD +75 -68
- pytcl/__init__.py +2 -2
- pytcl/assignment_algorithms/__init__.py +28 -0
- pytcl/assignment_algorithms/gating.py +10 -10
- pytcl/assignment_algorithms/jpda.py +40 -40
- pytcl/assignment_algorithms/nd_assignment.py +379 -0
- pytcl/assignment_algorithms/network_flow.py +371 -0
- pytcl/assignment_algorithms/three_dimensional/assignment.py +3 -3
- pytcl/astronomical/__init__.py +35 -0
- pytcl/astronomical/ephemerides.py +14 -11
- pytcl/astronomical/reference_frames.py +110 -4
- pytcl/astronomical/relativity.py +6 -5
- pytcl/astronomical/special_orbits.py +532 -0
- pytcl/atmosphere/__init__.py +11 -0
- pytcl/atmosphere/nrlmsise00.py +809 -0
- pytcl/clustering/dbscan.py +2 -2
- pytcl/clustering/gaussian_mixture.py +3 -3
- pytcl/clustering/hierarchical.py +15 -15
- pytcl/clustering/kmeans.py +4 -4
- pytcl/containers/base.py +3 -3
- pytcl/containers/cluster_set.py +12 -2
- pytcl/containers/covertree.py +5 -3
- pytcl/containers/rtree.py +1 -1
- pytcl/containers/vptree.py +4 -2
- pytcl/coordinate_systems/conversions/geodetic.py +272 -5
- pytcl/coordinate_systems/jacobians/jacobians.py +2 -2
- pytcl/coordinate_systems/projections/projections.py +2 -2
- pytcl/coordinate_systems/rotations/rotations.py +10 -6
- pytcl/core/validation.py +3 -3
- pytcl/dynamic_estimation/__init__.py +26 -0
- pytcl/dynamic_estimation/gaussian_sum_filter.py +434 -0
- pytcl/dynamic_estimation/imm.py +14 -14
- pytcl/dynamic_estimation/kalman/__init__.py +12 -0
- pytcl/dynamic_estimation/kalman/constrained.py +382 -0
- pytcl/dynamic_estimation/kalman/extended.py +8 -8
- pytcl/dynamic_estimation/kalman/h_infinity.py +2 -2
- pytcl/dynamic_estimation/kalman/square_root.py +8 -2
- pytcl/dynamic_estimation/kalman/sr_ukf.py +3 -3
- pytcl/dynamic_estimation/kalman/ud_filter.py +11 -5
- pytcl/dynamic_estimation/kalman/unscented.py +8 -6
- pytcl/dynamic_estimation/particle_filters/bootstrap.py +15 -15
- pytcl/dynamic_estimation/rbpf.py +589 -0
- pytcl/gravity/spherical_harmonics.py +3 -3
- pytcl/gravity/tides.py +6 -6
- pytcl/logging_config.py +3 -3
- pytcl/magnetism/emm.py +10 -3
- pytcl/magnetism/wmm.py +4 -4
- pytcl/mathematical_functions/combinatorics/combinatorics.py +5 -5
- pytcl/mathematical_functions/geometry/geometry.py +5 -5
- pytcl/mathematical_functions/numerical_integration/quadrature.py +6 -6
- pytcl/mathematical_functions/signal_processing/detection.py +24 -24
- pytcl/mathematical_functions/signal_processing/filters.py +14 -14
- pytcl/mathematical_functions/signal_processing/matched_filter.py +12 -12
- pytcl/mathematical_functions/special_functions/bessel.py +15 -3
- pytcl/mathematical_functions/special_functions/debye.py +5 -1
- pytcl/mathematical_functions/special_functions/error_functions.py +3 -1
- pytcl/mathematical_functions/special_functions/gamma_functions.py +4 -4
- pytcl/mathematical_functions/special_functions/hypergeometric.py +6 -4
- pytcl/mathematical_functions/transforms/fourier.py +8 -8
- pytcl/mathematical_functions/transforms/stft.py +12 -12
- pytcl/mathematical_functions/transforms/wavelets.py +9 -9
- pytcl/navigation/geodesy.py +3 -3
- pytcl/navigation/great_circle.py +5 -5
- pytcl/plotting/coordinates.py +7 -7
- pytcl/plotting/tracks.py +2 -2
- pytcl/static_estimation/maximum_likelihood.py +16 -14
- pytcl/static_estimation/robust.py +5 -5
- pytcl/terrain/loaders.py +5 -5
- pytcl/trackers/hypothesis.py +1 -1
- pytcl/trackers/mht.py +9 -9
- pytcl/trackers/multi_target.py +1 -1
- {nrl_tracker-1.6.0.dist-info → nrl_tracker-1.7.1.dist-info}/LICENSE +0 -0
- {nrl_tracker-1.6.0.dist-info → nrl_tracker-1.7.1.dist-info}/WHEEL +0 -0
- {nrl_tracker-1.6.0.dist-info → nrl_tracker-1.7.1.dist-info}/top_level.txt +0 -0
pytcl/magnetism/wmm.py
CHANGED
|
@@ -13,7 +13,7 @@ References
|
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
15
|
from functools import lru_cache
|
|
16
|
-
from typing import NamedTuple, Optional, Tuple
|
|
16
|
+
from typing import Any, NamedTuple, Optional, Tuple
|
|
17
17
|
|
|
18
18
|
import numpy as np
|
|
19
19
|
from numpy.typing import NDArray
|
|
@@ -482,7 +482,7 @@ def _magnetic_field_spherical_cached(
|
|
|
482
482
|
|
|
483
483
|
|
|
484
484
|
# Registry to hold coefficient sets by id
|
|
485
|
-
_coefficient_registry: dict = {}
|
|
485
|
+
_coefficient_registry: dict[str, Any] = {}
|
|
486
486
|
|
|
487
487
|
|
|
488
488
|
def _register_coefficients(coeffs: "MagneticCoefficients") -> int:
|
|
@@ -579,7 +579,7 @@ def _compute_magnetic_field_spherical_impl(
|
|
|
579
579
|
# =============================================================================
|
|
580
580
|
|
|
581
581
|
|
|
582
|
-
def get_magnetic_cache_info() -> dict:
|
|
582
|
+
def get_magnetic_cache_info() -> dict[str, Any]:
|
|
583
583
|
"""
|
|
584
584
|
Get information about the magnetic field computation cache.
|
|
585
585
|
|
|
@@ -630,7 +630,7 @@ def clear_magnetic_cache() -> None:
|
|
|
630
630
|
|
|
631
631
|
def configure_magnetic_cache(
|
|
632
632
|
maxsize: Optional[int] = None,
|
|
633
|
-
precision: Optional[dict] = None,
|
|
633
|
+
precision: Optional[dict[str, Any]] = None,
|
|
634
634
|
) -> None:
|
|
635
635
|
"""
|
|
636
636
|
Configure the magnetic field computation cache.
|
|
@@ -7,7 +7,7 @@ related operations commonly used in assignment problems and data association.
|
|
|
7
7
|
|
|
8
8
|
import itertools
|
|
9
9
|
from functools import lru_cache
|
|
10
|
-
from typing import Iterator, List, Optional, Tuple
|
|
10
|
+
from typing import Any, Iterator, List, Optional, Tuple
|
|
11
11
|
|
|
12
12
|
from numpy.typing import ArrayLike
|
|
13
13
|
|
|
@@ -108,7 +108,7 @@ def n_permute_k(n: int, k: int) -> int:
|
|
|
108
108
|
def permutations(
|
|
109
109
|
items: ArrayLike,
|
|
110
110
|
k: Optional[int] = None,
|
|
111
|
-
) -> Iterator[
|
|
111
|
+
) -> Iterator[tuple[Any, ...]]:
|
|
112
112
|
"""
|
|
113
113
|
Generate all k-permutations of items.
|
|
114
114
|
|
|
@@ -136,7 +136,7 @@ def permutations(
|
|
|
136
136
|
def combinations(
|
|
137
137
|
items: ArrayLike,
|
|
138
138
|
k: int,
|
|
139
|
-
) -> Iterator[
|
|
139
|
+
) -> Iterator[tuple[Any, ...]]:
|
|
140
140
|
"""
|
|
141
141
|
Generate all k-combinations of items.
|
|
142
142
|
|
|
@@ -164,7 +164,7 @@ def combinations(
|
|
|
164
164
|
def combinations_with_replacement(
|
|
165
165
|
items: ArrayLike,
|
|
166
166
|
k: int,
|
|
167
|
-
) -> Iterator[
|
|
167
|
+
) -> Iterator[tuple[Any, ...]]:
|
|
168
168
|
"""
|
|
169
169
|
Generate all k-combinations with replacement.
|
|
170
170
|
|
|
@@ -263,7 +263,7 @@ def permutation_unrank(rank: int, n: int) -> List[int]:
|
|
|
263
263
|
return perm
|
|
264
264
|
|
|
265
265
|
|
|
266
|
-
def next_permutation(perm: ArrayLike) -> Optional[List]:
|
|
266
|
+
def next_permutation(perm: ArrayLike) -> Optional[List[Any]]:
|
|
267
267
|
"""
|
|
268
268
|
Generate the next permutation in lexicographic order.
|
|
269
269
|
|
|
@@ -5,7 +5,7 @@ This module provides geometric functions for points, lines, planes,
|
|
|
5
5
|
polygons, and related operations used in tracking applications.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
from typing import Optional, Tuple
|
|
8
|
+
from typing import Any, Optional, Tuple
|
|
9
9
|
|
|
10
10
|
import numpy as np
|
|
11
11
|
from numpy.typing import ArrayLike, NDArray
|
|
@@ -527,12 +527,12 @@ def minimum_bounding_circle(
|
|
|
527
527
|
"""
|
|
528
528
|
points = np.asarray(points, dtype=np.float64)
|
|
529
529
|
|
|
530
|
-
def circle_from_two_points(p1, p2):
|
|
530
|
+
def circle_from_two_points(p1: Any, p2: Any) -> tuple[Any, Any]:
|
|
531
531
|
center = (p1 + p2) / 2
|
|
532
532
|
radius = np.linalg.norm(p1 - center)
|
|
533
533
|
return center, radius
|
|
534
534
|
|
|
535
|
-
def circle_from_three_points(p1, p2, p3):
|
|
535
|
+
def circle_from_three_points(p1: Any, p2: Any, p3: Any) -> tuple[Any, Any]:
|
|
536
536
|
ax, ay = p1
|
|
537
537
|
bx, by = p2
|
|
538
538
|
cx, cy = p3
|
|
@@ -565,10 +565,10 @@ def minimum_bounding_circle(
|
|
|
565
565
|
radius = np.linalg.norm(p1 - center)
|
|
566
566
|
return center, radius
|
|
567
567
|
|
|
568
|
-
def is_inside(c, r, p):
|
|
568
|
+
def is_inside(c: Any, r: Any, p: Any) -> Any:
|
|
569
569
|
return np.linalg.norm(p - c) <= r + 1e-10
|
|
570
570
|
|
|
571
|
-
def welzl(P, R):
|
|
571
|
+
def welzl(P: Any, R: Any) -> tuple[Any, Any]:
|
|
572
572
|
if len(P) == 0 or len(R) == 3:
|
|
573
573
|
if len(R) == 0:
|
|
574
574
|
return np.array([0.0, 0.0]), 0.0
|
|
@@ -5,7 +5,7 @@ This module provides Gaussian quadrature rules and numerical integration
|
|
|
5
5
|
functions commonly used in state estimation and filtering.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
from typing import Callable, Literal, Optional, Tuple
|
|
8
|
+
from typing import Any, Callable, Literal, Optional, Tuple
|
|
9
9
|
|
|
10
10
|
import numpy as np
|
|
11
11
|
import scipy.integrate as integrate
|
|
@@ -158,7 +158,7 @@ def quad(
|
|
|
158
158
|
f: Callable[[float], float],
|
|
159
159
|
a: float,
|
|
160
160
|
b: float,
|
|
161
|
-
**kwargs,
|
|
161
|
+
**kwargs: Any,
|
|
162
162
|
) -> Tuple[float, float]:
|
|
163
163
|
"""
|
|
164
164
|
Adaptive quadrature integration.
|
|
@@ -203,7 +203,7 @@ def dblquad(
|
|
|
203
203
|
b: float,
|
|
204
204
|
gfun: Callable[[float], float],
|
|
205
205
|
hfun: Callable[[float], float],
|
|
206
|
-
**kwargs,
|
|
206
|
+
**kwargs: Any,
|
|
207
207
|
) -> Tuple[float, float]:
|
|
208
208
|
"""
|
|
209
209
|
Double integration.
|
|
@@ -248,7 +248,7 @@ def tplquad(
|
|
|
248
248
|
hfun: Callable[[float], float],
|
|
249
249
|
qfun: Callable[[float, float], float],
|
|
250
250
|
rfun: Callable[[float, float], float],
|
|
251
|
-
**kwargs,
|
|
251
|
+
**kwargs: Any,
|
|
252
252
|
) -> Tuple[float, float]:
|
|
253
253
|
"""
|
|
254
254
|
Triple integration.
|
|
@@ -290,11 +290,11 @@ def tplquad(
|
|
|
290
290
|
|
|
291
291
|
|
|
292
292
|
def fixed_quad(
|
|
293
|
-
f: Callable[[
|
|
293
|
+
f: Callable[[np.ndarray[Any, Any]], np.ndarray[Any, Any]],
|
|
294
294
|
a: float,
|
|
295
295
|
b: float,
|
|
296
296
|
n: int = 5,
|
|
297
|
-
) ->
|
|
297
|
+
) -> tuple[float, None]:
|
|
298
298
|
"""
|
|
299
299
|
Fixed-order Gaussian quadrature.
|
|
300
300
|
|
|
@@ -24,7 +24,7 @@ References
|
|
|
24
24
|
Systems, 19(4), 608-621.
|
|
25
25
|
"""
|
|
26
26
|
|
|
27
|
-
from typing import NamedTuple, Optional
|
|
27
|
+
from typing import Any, NamedTuple, Optional
|
|
28
28
|
|
|
29
29
|
import numpy as np
|
|
30
30
|
from numba import njit, prange
|
|
@@ -214,12 +214,12 @@ def detection_probability(
|
|
|
214
214
|
|
|
215
215
|
@njit(cache=True, fastmath=True)
|
|
216
216
|
def _cfar_ca_kernel(
|
|
217
|
-
signal: np.ndarray,
|
|
217
|
+
signal: np.ndarray[Any, Any],
|
|
218
218
|
guard_cells: int,
|
|
219
219
|
ref_cells: int,
|
|
220
220
|
alpha: float,
|
|
221
|
-
noise_estimate: np.ndarray,
|
|
222
|
-
threshold: np.ndarray,
|
|
221
|
+
noise_estimate: np.ndarray[Any, Any],
|
|
222
|
+
threshold: np.ndarray[Any, Any],
|
|
223
223
|
) -> None:
|
|
224
224
|
"""JIT-compiled CA-CFAR kernel."""
|
|
225
225
|
n = len(signal)
|
|
@@ -252,12 +252,12 @@ def _cfar_ca_kernel(
|
|
|
252
252
|
|
|
253
253
|
@njit(cache=True, fastmath=True)
|
|
254
254
|
def _cfar_go_kernel(
|
|
255
|
-
signal: np.ndarray,
|
|
255
|
+
signal: np.ndarray[Any, Any],
|
|
256
256
|
guard_cells: int,
|
|
257
257
|
ref_cells: int,
|
|
258
258
|
alpha: float,
|
|
259
|
-
noise_estimate: np.ndarray,
|
|
260
|
-
threshold: np.ndarray,
|
|
259
|
+
noise_estimate: np.ndarray[Any, Any],
|
|
260
|
+
threshold: np.ndarray[Any, Any],
|
|
261
261
|
) -> None:
|
|
262
262
|
"""JIT-compiled GO-CFAR kernel."""
|
|
263
263
|
n = len(signal)
|
|
@@ -290,12 +290,12 @@ def _cfar_go_kernel(
|
|
|
290
290
|
|
|
291
291
|
@njit(cache=True, fastmath=True)
|
|
292
292
|
def _cfar_so_kernel(
|
|
293
|
-
signal: np.ndarray,
|
|
293
|
+
signal: np.ndarray[Any, Any],
|
|
294
294
|
guard_cells: int,
|
|
295
295
|
ref_cells: int,
|
|
296
296
|
alpha: float,
|
|
297
|
-
noise_estimate: np.ndarray,
|
|
298
|
-
threshold: np.ndarray,
|
|
297
|
+
noise_estimate: np.ndarray[Any, Any],
|
|
298
|
+
threshold: np.ndarray[Any, Any],
|
|
299
299
|
) -> None:
|
|
300
300
|
"""JIT-compiled SO-CFAR kernel."""
|
|
301
301
|
n = len(signal)
|
|
@@ -331,13 +331,13 @@ def _cfar_so_kernel(
|
|
|
331
331
|
|
|
332
332
|
@njit(cache=True, fastmath=True)
|
|
333
333
|
def _cfar_os_kernel(
|
|
334
|
-
signal: np.ndarray,
|
|
334
|
+
signal: np.ndarray[Any, Any],
|
|
335
335
|
guard_cells: int,
|
|
336
336
|
ref_cells: int,
|
|
337
337
|
k: int,
|
|
338
338
|
alpha: float,
|
|
339
|
-
noise_estimate: np.ndarray,
|
|
340
|
-
threshold: np.ndarray,
|
|
339
|
+
noise_estimate: np.ndarray[Any, Any],
|
|
340
|
+
threshold: np.ndarray[Any, Any],
|
|
341
341
|
) -> None:
|
|
342
342
|
"""JIT-compiled OS-CFAR kernel."""
|
|
343
343
|
n = len(signal)
|
|
@@ -378,14 +378,14 @@ def _cfar_os_kernel(
|
|
|
378
378
|
|
|
379
379
|
@njit(cache=True, fastmath=True, parallel=True)
|
|
380
380
|
def _cfar_2d_ca_kernel(
|
|
381
|
-
image: np.ndarray,
|
|
381
|
+
image: np.ndarray[Any, Any],
|
|
382
382
|
guard_rows: int,
|
|
383
383
|
guard_cols: int,
|
|
384
384
|
ref_rows: int,
|
|
385
385
|
ref_cols: int,
|
|
386
386
|
alpha: float,
|
|
387
|
-
noise_estimate: np.ndarray,
|
|
388
|
-
threshold: np.ndarray,
|
|
387
|
+
noise_estimate: np.ndarray[Any, Any],
|
|
388
|
+
threshold: np.ndarray[Any, Any],
|
|
389
389
|
) -> None:
|
|
390
390
|
"""JIT-compiled 2D CA-CFAR kernel with parallel execution."""
|
|
391
391
|
n_rows, n_cols = image.shape
|
|
@@ -426,14 +426,14 @@ def _cfar_2d_ca_kernel(
|
|
|
426
426
|
|
|
427
427
|
@njit(cache=True, fastmath=True, parallel=True)
|
|
428
428
|
def _cfar_2d_go_kernel(
|
|
429
|
-
image: np.ndarray,
|
|
429
|
+
image: np.ndarray[Any, Any],
|
|
430
430
|
guard_rows: int,
|
|
431
431
|
guard_cols: int,
|
|
432
432
|
ref_rows: int,
|
|
433
433
|
ref_cols: int,
|
|
434
434
|
alpha: float,
|
|
435
|
-
noise_estimate: np.ndarray,
|
|
436
|
-
threshold: np.ndarray,
|
|
435
|
+
noise_estimate: np.ndarray[Any, Any],
|
|
436
|
+
threshold: np.ndarray[Any, Any],
|
|
437
437
|
) -> None:
|
|
438
438
|
"""JIT-compiled 2D GO-CFAR kernel with parallel execution."""
|
|
439
439
|
n_rows, n_cols = image.shape
|
|
@@ -478,14 +478,14 @@ def _cfar_2d_go_kernel(
|
|
|
478
478
|
|
|
479
479
|
@njit(cache=True, fastmath=True, parallel=True)
|
|
480
480
|
def _cfar_2d_so_kernel(
|
|
481
|
-
image: np.ndarray,
|
|
481
|
+
image: np.ndarray[Any, Any],
|
|
482
482
|
guard_rows: int,
|
|
483
483
|
guard_cols: int,
|
|
484
484
|
ref_rows: int,
|
|
485
485
|
ref_cols: int,
|
|
486
486
|
alpha: float,
|
|
487
|
-
noise_estimate: np.ndarray,
|
|
488
|
-
threshold: np.ndarray,
|
|
487
|
+
noise_estimate: np.ndarray[Any, Any],
|
|
488
|
+
threshold: np.ndarray[Any, Any],
|
|
489
489
|
) -> None:
|
|
490
490
|
"""JIT-compiled 2D SO-CFAR kernel with parallel execution."""
|
|
491
491
|
n_rows, n_cols = image.shape
|
|
@@ -830,8 +830,8 @@ def cfar_os(
|
|
|
830
830
|
|
|
831
831
|
def cfar_2d(
|
|
832
832
|
image: ArrayLike,
|
|
833
|
-
guard_cells: tuple,
|
|
834
|
-
ref_cells: tuple,
|
|
833
|
+
guard_cells: tuple[int, int],
|
|
834
|
+
ref_cells: tuple[int, int],
|
|
835
835
|
pfa: float = 1e-6,
|
|
836
836
|
method: str = "ca",
|
|
837
837
|
alpha: Optional[float] = None,
|
|
@@ -24,7 +24,7 @@ References
|
|
|
24
24
|
Wiley-Interscience.
|
|
25
25
|
"""
|
|
26
26
|
|
|
27
|
-
from typing import NamedTuple, Optional, Union
|
|
27
|
+
from typing import Any, NamedTuple, Optional, Union
|
|
28
28
|
|
|
29
29
|
import numpy as np
|
|
30
30
|
from numpy.typing import ArrayLike, NDArray
|
|
@@ -80,7 +80,7 @@ class FrequencyResponse(NamedTuple):
|
|
|
80
80
|
|
|
81
81
|
def butter_design(
|
|
82
82
|
order: int,
|
|
83
|
-
cutoff: Union[float, tuple],
|
|
83
|
+
cutoff: Union[float, tuple[float, ...]],
|
|
84
84
|
fs: float,
|
|
85
85
|
btype: str = "low",
|
|
86
86
|
output: str = "sos",
|
|
@@ -141,7 +141,7 @@ def butter_design(
|
|
|
141
141
|
def cheby1_design(
|
|
142
142
|
order: int,
|
|
143
143
|
ripple: float,
|
|
144
|
-
cutoff: Union[float, tuple],
|
|
144
|
+
cutoff: Union[float, tuple[float, ...]],
|
|
145
145
|
fs: float,
|
|
146
146
|
btype: str = "low",
|
|
147
147
|
output: str = "sos",
|
|
@@ -198,7 +198,7 @@ def cheby1_design(
|
|
|
198
198
|
def cheby2_design(
|
|
199
199
|
order: int,
|
|
200
200
|
attenuation: float,
|
|
201
|
-
cutoff: Union[float, tuple],
|
|
201
|
+
cutoff: Union[float, tuple[float, ...]],
|
|
202
202
|
fs: float,
|
|
203
203
|
btype: str = "low",
|
|
204
204
|
output: str = "sos",
|
|
@@ -255,7 +255,7 @@ def ellip_design(
|
|
|
255
255
|
order: int,
|
|
256
256
|
passband_ripple: float,
|
|
257
257
|
stopband_attenuation: float,
|
|
258
|
-
cutoff: Union[float, tuple],
|
|
258
|
+
cutoff: Union[float, tuple[float, ...]],
|
|
259
259
|
fs: float,
|
|
260
260
|
btype: str = "low",
|
|
261
261
|
output: str = "sos",
|
|
@@ -317,7 +317,7 @@ def ellip_design(
|
|
|
317
317
|
|
|
318
318
|
def bessel_design(
|
|
319
319
|
order: int,
|
|
320
|
-
cutoff: Union[float, tuple],
|
|
320
|
+
cutoff: Union[float, tuple[float, ...]],
|
|
321
321
|
fs: float,
|
|
322
322
|
btype: str = "low",
|
|
323
323
|
norm: str = "phase",
|
|
@@ -383,7 +383,7 @@ def bessel_design(
|
|
|
383
383
|
|
|
384
384
|
def fir_design(
|
|
385
385
|
numtaps: int,
|
|
386
|
-
cutoff: Union[float, tuple],
|
|
386
|
+
cutoff: Union[float, tuple[float, ...]],
|
|
387
387
|
fs: float,
|
|
388
388
|
window: str = "hamming",
|
|
389
389
|
pass_zero: Union[bool, str] = True,
|
|
@@ -499,10 +499,10 @@ def fir_design_remez(
|
|
|
499
499
|
|
|
500
500
|
|
|
501
501
|
def apply_filter(
|
|
502
|
-
coeffs: Union[FilterCoefficients, tuple, NDArray],
|
|
502
|
+
coeffs: Union[FilterCoefficients, tuple[Any, ...], NDArray[Any]],
|
|
503
503
|
x: ArrayLike,
|
|
504
504
|
zi: Optional[ArrayLike] = None,
|
|
505
|
-
) -> Union[NDArray[np.floating], tuple]:
|
|
505
|
+
) -> Union[NDArray[np.floating], tuple[NDArray[np.floating], Any]]:
|
|
506
506
|
"""
|
|
507
507
|
Apply a digital filter to a signal.
|
|
508
508
|
|
|
@@ -559,7 +559,7 @@ def apply_filter(
|
|
|
559
559
|
|
|
560
560
|
|
|
561
561
|
def filtfilt(
|
|
562
|
-
coeffs: Union[FilterCoefficients, tuple, NDArray],
|
|
562
|
+
coeffs: Union[FilterCoefficients, tuple[Any, ...], NDArray[Any]],
|
|
563
563
|
x: ArrayLike,
|
|
564
564
|
padtype: str = "odd",
|
|
565
565
|
padlen: Optional[int] = None,
|
|
@@ -627,7 +627,7 @@ def filtfilt(
|
|
|
627
627
|
|
|
628
628
|
|
|
629
629
|
def frequency_response(
|
|
630
|
-
coeffs: Union[FilterCoefficients, tuple, NDArray],
|
|
630
|
+
coeffs: Union[FilterCoefficients, tuple[Any, ...], NDArray[Any]],
|
|
631
631
|
fs: float,
|
|
632
632
|
n_points: int = 512,
|
|
633
633
|
whole: bool = False,
|
|
@@ -684,10 +684,10 @@ def frequency_response(
|
|
|
684
684
|
|
|
685
685
|
|
|
686
686
|
def group_delay(
|
|
687
|
-
coeffs: Union[FilterCoefficients, tuple, NDArray],
|
|
687
|
+
coeffs: Union[FilterCoefficients, tuple[Any, ...], NDArray[Any]],
|
|
688
688
|
fs: float,
|
|
689
689
|
n_points: int = 512,
|
|
690
|
-
) -> tuple:
|
|
690
|
+
) -> tuple[NDArray[np.floating], NDArray[np.floating]]:
|
|
691
691
|
"""
|
|
692
692
|
Compute the group delay of a digital filter.
|
|
693
693
|
|
|
@@ -793,7 +793,7 @@ def filter_order(
|
|
|
793
793
|
return int(order)
|
|
794
794
|
|
|
795
795
|
|
|
796
|
-
def sos_to_zpk(sos: ArrayLike) -> tuple:
|
|
796
|
+
def sos_to_zpk(sos: ArrayLike) -> tuple[NDArray[Any], NDArray[Any], Any]:
|
|
797
797
|
"""
|
|
798
798
|
Convert second-order sections to zeros, poles, gain.
|
|
799
799
|
|
|
@@ -21,7 +21,7 @@ References
|
|
|
21
21
|
IRE Transactions on Information Theory, 6(3), 311-329.
|
|
22
22
|
"""
|
|
23
23
|
|
|
24
|
-
from typing import NamedTuple, Optional
|
|
24
|
+
from typing import Any, NamedTuple, Optional
|
|
25
25
|
|
|
26
26
|
import numpy as np
|
|
27
27
|
from numba import njit, prange
|
|
@@ -553,11 +553,11 @@ def generate_nlfm_chirp(
|
|
|
553
553
|
|
|
554
554
|
@njit(cache=True, fastmath=True, parallel=True)
|
|
555
555
|
def _ambiguity_function_kernel(
|
|
556
|
-
signal: np.ndarray,
|
|
557
|
-
delays: np.ndarray,
|
|
558
|
-
dopplers: np.ndarray,
|
|
556
|
+
signal: np.ndarray[Any, Any],
|
|
557
|
+
delays: np.ndarray[Any, Any],
|
|
558
|
+
dopplers: np.ndarray[Any, Any],
|
|
559
559
|
fs: float,
|
|
560
|
-
af: np.ndarray,
|
|
560
|
+
af: np.ndarray[Any, Any],
|
|
561
561
|
) -> None:
|
|
562
562
|
"""JIT-compiled kernel for ambiguity function computation."""
|
|
563
563
|
n_signal = len(signal)
|
|
@@ -600,12 +600,12 @@ def _ambiguity_function_kernel(
|
|
|
600
600
|
|
|
601
601
|
@njit(cache=True, fastmath=True, parallel=True)
|
|
602
602
|
def _cross_ambiguity_kernel(
|
|
603
|
-
signal1: np.ndarray,
|
|
604
|
-
signal2: np.ndarray,
|
|
605
|
-
delays: np.ndarray,
|
|
606
|
-
dopplers: np.ndarray,
|
|
603
|
+
signal1: np.ndarray[Any, Any],
|
|
604
|
+
signal2: np.ndarray[Any, Any],
|
|
605
|
+
delays: np.ndarray[Any, Any],
|
|
606
|
+
dopplers: np.ndarray[Any, Any],
|
|
607
607
|
fs: float,
|
|
608
|
-
caf: np.ndarray,
|
|
608
|
+
caf: np.ndarray[Any, Any],
|
|
609
609
|
) -> None:
|
|
610
610
|
"""JIT-compiled kernel for cross-ambiguity function computation."""
|
|
611
611
|
n_signal = len(signal1)
|
|
@@ -653,7 +653,7 @@ def ambiguity_function(
|
|
|
653
653
|
max_doppler: Optional[float] = None,
|
|
654
654
|
n_delay: int = 256,
|
|
655
655
|
n_doppler: int = 256,
|
|
656
|
-
) -> tuple:
|
|
656
|
+
) -> tuple[NDArray[np.floating], NDArray[np.floating], NDArray[np.complexfloating]]:
|
|
657
657
|
"""
|
|
658
658
|
Compute the ambiguity function of a signal.
|
|
659
659
|
|
|
@@ -722,7 +722,7 @@ def cross_ambiguity(
|
|
|
722
722
|
max_doppler: Optional[float] = None,
|
|
723
723
|
n_delay: int = 256,
|
|
724
724
|
n_doppler: int = 256,
|
|
725
|
-
) -> tuple:
|
|
725
|
+
) -> tuple[NDArray[np.floating], NDArray[np.floating], NDArray[np.complexfloating]]:
|
|
726
726
|
"""
|
|
727
727
|
Compute the cross-ambiguity function between two signals.
|
|
728
728
|
|
|
@@ -5,7 +5,7 @@ This module provides Bessel functions commonly used in signal processing,
|
|
|
5
5
|
antenna theory, and scattering problems in tracking applications.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
from typing import Union
|
|
8
|
+
from typing import Any, Union
|
|
9
9
|
|
|
10
10
|
import numpy as np
|
|
11
11
|
import scipy.special as sp
|
|
@@ -315,7 +315,14 @@ def spherical_kn(
|
|
|
315
315
|
return np.asarray(sp.spherical_kn(n, x, derivative=derivative), dtype=np.float64)
|
|
316
316
|
|
|
317
317
|
|
|
318
|
-
def airy(
|
|
318
|
+
def airy(
|
|
319
|
+
x: ArrayLike,
|
|
320
|
+
) -> tuple[
|
|
321
|
+
np.ndarray[Any, Any],
|
|
322
|
+
np.ndarray[Any, Any],
|
|
323
|
+
np.ndarray[Any, Any],
|
|
324
|
+
np.ndarray[Any, Any],
|
|
325
|
+
]:
|
|
319
326
|
"""
|
|
320
327
|
Airy functions and their derivatives.
|
|
321
328
|
|
|
@@ -554,7 +561,12 @@ def bessel_zeros(
|
|
|
554
561
|
|
|
555
562
|
def kelvin(
|
|
556
563
|
x: ArrayLike,
|
|
557
|
-
) -> tuple
|
|
564
|
+
) -> tuple[
|
|
565
|
+
np.ndarray[Any, Any],
|
|
566
|
+
np.ndarray[Any, Any],
|
|
567
|
+
np.ndarray[Any, Any],
|
|
568
|
+
np.ndarray[Any, Any],
|
|
569
|
+
]:
|
|
558
570
|
"""
|
|
559
571
|
Kelvin functions ber, bei, ker, kei.
|
|
560
572
|
|
|
@@ -11,6 +11,8 @@ core, providing ~10-50x speedup for batch computations compared to
|
|
|
11
11
|
scipy.integrate.quad.
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
14
16
|
import numpy as np
|
|
15
17
|
from numba import njit, prange
|
|
16
18
|
from numpy.typing import ArrayLike, NDArray
|
|
@@ -90,7 +92,9 @@ def _debye_small_x(x: float, n: int) -> float:
|
|
|
90
92
|
|
|
91
93
|
|
|
92
94
|
@njit(cache=True, fastmath=True, parallel=True)
|
|
93
|
-
def _debye_batch(
|
|
95
|
+
def _debye_batch(
|
|
96
|
+
n: int, x_arr: np.ndarray[Any, Any], zeta_n_plus_1: float
|
|
97
|
+
) -> np.ndarray[Any, Any]:
|
|
94
98
|
"""
|
|
95
99
|
Batch computation of Debye function for array input.
|
|
96
100
|
|
|
@@ -5,6 +5,8 @@ This module provides error functions and their variants, commonly used
|
|
|
5
5
|
in probability theory and statistical analysis.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
8
10
|
import numpy as np
|
|
9
11
|
import scipy.special as sp
|
|
10
12
|
from numpy.typing import ArrayLike, NDArray
|
|
@@ -216,7 +218,7 @@ def dawsn(x: ArrayLike) -> NDArray[np.floating]:
|
|
|
216
218
|
return np.asarray(sp.dawsn(x), dtype=np.float64)
|
|
217
219
|
|
|
218
220
|
|
|
219
|
-
def fresnel(x: ArrayLike) -> tuple:
|
|
221
|
+
def fresnel(x: ArrayLike) -> tuple[np.ndarray[Any, Any], np.ndarray[Any, Any]]:
|
|
220
222
|
"""
|
|
221
223
|
Fresnel integrals.
|
|
222
224
|
|
|
@@ -318,7 +318,7 @@ def betaincinv(a: ArrayLike, b: ArrayLike, y: ArrayLike) -> NDArray[np.floating]
|
|
|
318
318
|
return np.asarray(sp.betaincinv(a, b, y), dtype=np.float64)
|
|
319
319
|
|
|
320
320
|
|
|
321
|
-
def factorial(n: ArrayLike, exact: bool = False) -> NDArray:
|
|
321
|
+
def factorial(n: ArrayLike, exact: bool = False) -> NDArray[np.floating]:
|
|
322
322
|
"""
|
|
323
323
|
Factorial function.
|
|
324
324
|
|
|
@@ -351,7 +351,7 @@ def factorial(n: ArrayLike, exact: bool = False) -> NDArray:
|
|
|
351
351
|
return np.asarray(sp.factorial(n, exact=exact), dtype=np.float64)
|
|
352
352
|
|
|
353
353
|
|
|
354
|
-
def factorial2(n: ArrayLike, exact: bool = False) -> NDArray:
|
|
354
|
+
def factorial2(n: ArrayLike, exact: bool = False) -> NDArray[np.floating]:
|
|
355
355
|
"""
|
|
356
356
|
Double factorial.
|
|
357
357
|
|
|
@@ -388,7 +388,7 @@ def comb(
|
|
|
388
388
|
k: ArrayLike,
|
|
389
389
|
exact: bool = False,
|
|
390
390
|
repetition: bool = False,
|
|
391
|
-
) -> NDArray:
|
|
391
|
+
) -> NDArray[np.floating]:
|
|
392
392
|
"""
|
|
393
393
|
Binomial coefficient (combinations).
|
|
394
394
|
|
|
@@ -426,7 +426,7 @@ def comb(
|
|
|
426
426
|
)
|
|
427
427
|
|
|
428
428
|
|
|
429
|
-
def perm(n: ArrayLike, k: ArrayLike, exact: bool = False) -> NDArray:
|
|
429
|
+
def perm(n: ArrayLike, k: ArrayLike, exact: bool = False) -> NDArray[np.floating]:
|
|
430
430
|
"""
|
|
431
431
|
Permutation coefficient.
|
|
432
432
|
|
|
@@ -11,6 +11,8 @@ the series summation loop, providing significant speedup for the general
|
|
|
11
11
|
case (p > 2 or q > 1).
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
14
16
|
import numpy as np
|
|
15
17
|
import scipy.special as sp
|
|
16
18
|
from numba import njit
|
|
@@ -19,12 +21,12 @@ from numpy.typing import ArrayLike, NDArray
|
|
|
19
21
|
|
|
20
22
|
@njit(cache=True, fastmath=True)
|
|
21
23
|
def _hypergeometric_series(
|
|
22
|
-
a: np.ndarray,
|
|
23
|
-
b: np.ndarray,
|
|
24
|
-
z: np.ndarray,
|
|
24
|
+
a: np.ndarray[Any, Any],
|
|
25
|
+
b: np.ndarray[Any, Any],
|
|
26
|
+
z: np.ndarray[Any, Any],
|
|
25
27
|
max_terms: int,
|
|
26
28
|
tol: float,
|
|
27
|
-
) -> np.ndarray:
|
|
29
|
+
) -> np.ndarray[Any, Any]:
|
|
28
30
|
"""
|
|
29
31
|
Numba-optimized series summation for generalized hypergeometric function.
|
|
30
32
|
|
|
@@ -247,8 +247,8 @@ def irfft(
|
|
|
247
247
|
|
|
248
248
|
def fft2(
|
|
249
249
|
x: ArrayLike,
|
|
250
|
-
s: Optional[tuple] = None,
|
|
251
|
-
axes: tuple = (-2, -1),
|
|
250
|
+
s: Optional[tuple[int, ...]] = None,
|
|
251
|
+
axes: tuple[int, ...] = (-2, -1),
|
|
252
252
|
norm: Optional[str] = None,
|
|
253
253
|
) -> NDArray[np.complexfloating]:
|
|
254
254
|
"""
|
|
@@ -284,8 +284,8 @@ def fft2(
|
|
|
284
284
|
|
|
285
285
|
def ifft2(
|
|
286
286
|
X: ArrayLike,
|
|
287
|
-
s: Optional[tuple] = None,
|
|
288
|
-
axes: tuple = (-2, -1),
|
|
287
|
+
s: Optional[tuple[int, ...]] = None,
|
|
288
|
+
axes: tuple[int, ...] = (-2, -1),
|
|
289
289
|
norm: Optional[str] = None,
|
|
290
290
|
) -> NDArray[np.complexfloating]:
|
|
291
291
|
"""
|
|
@@ -313,8 +313,8 @@ def ifft2(
|
|
|
313
313
|
|
|
314
314
|
def fftshift(
|
|
315
315
|
x: ArrayLike,
|
|
316
|
-
axes: Optional[Union[int, tuple]] = None,
|
|
317
|
-
) -> NDArray:
|
|
316
|
+
axes: Optional[Union[int, tuple[int, ...]]] = None,
|
|
317
|
+
) -> NDArray[np.floating]:
|
|
318
318
|
"""
|
|
319
319
|
Shift the zero-frequency component to the center of the spectrum.
|
|
320
320
|
|
|
@@ -345,8 +345,8 @@ def fftshift(
|
|
|
345
345
|
|
|
346
346
|
def ifftshift(
|
|
347
347
|
x: ArrayLike,
|
|
348
|
-
axes: Optional[Union[int, tuple]] = None,
|
|
349
|
-
) -> NDArray:
|
|
348
|
+
axes: Optional[Union[int, tuple[int, ...]]] = None,
|
|
349
|
+
) -> NDArray[np.floating]:
|
|
350
350
|
"""
|
|
351
351
|
Inverse of fftshift. Shift zero-frequency back to beginning.
|
|
352
352
|
|