nrl-tracker 0.21.1__py3-none-any.whl → 0.22.5__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.
Files changed (35) hide show
  1. {nrl_tracker-0.21.1.dist-info → nrl_tracker-0.22.5.dist-info}/METADATA +4 -4
  2. {nrl_tracker-0.21.1.dist-info → nrl_tracker-0.22.5.dist-info}/RECORD +35 -33
  3. pytcl/__init__.py +1 -1
  4. pytcl/assignment_algorithms/data_association.py +2 -7
  5. pytcl/assignment_algorithms/jpda.py +43 -29
  6. pytcl/assignment_algorithms/two_dimensional/assignment.py +14 -7
  7. pytcl/astronomical/__init__.py +60 -7
  8. pytcl/astronomical/ephemerides.py +530 -0
  9. pytcl/astronomical/relativity.py +472 -0
  10. pytcl/atmosphere/__init__.py +2 -2
  11. pytcl/clustering/dbscan.py +23 -5
  12. pytcl/clustering/hierarchical.py +23 -10
  13. pytcl/clustering/kmeans.py +5 -10
  14. pytcl/containers/__init__.py +4 -21
  15. pytcl/containers/cluster_set.py +1 -10
  16. pytcl/containers/measurement_set.py +1 -9
  17. pytcl/coordinate_systems/projections/__init__.py +4 -2
  18. pytcl/dynamic_estimation/imm.py +42 -36
  19. pytcl/dynamic_estimation/kalman/extended.py +1 -4
  20. pytcl/dynamic_estimation/kalman/linear.py +17 -13
  21. pytcl/dynamic_estimation/kalman/unscented.py +27 -27
  22. pytcl/dynamic_estimation/particle_filters/bootstrap.py +57 -19
  23. pytcl/dynamic_estimation/smoothers.py +1 -5
  24. pytcl/dynamic_models/discrete_time/__init__.py +1 -5
  25. pytcl/dynamic_models/process_noise/__init__.py +1 -5
  26. pytcl/magnetism/__init__.py +3 -14
  27. pytcl/mathematical_functions/interpolation/__init__.py +2 -2
  28. pytcl/mathematical_functions/special_functions/__init__.py +2 -2
  29. pytcl/navigation/__init__.py +14 -10
  30. pytcl/navigation/ins.py +1 -5
  31. pytcl/trackers/__init__.py +3 -14
  32. pytcl/trackers/multi_target.py +1 -4
  33. {nrl_tracker-0.21.1.dist-info → nrl_tracker-0.22.5.dist-info}/LICENSE +0 -0
  34. {nrl_tracker-0.21.1.dist-info → nrl_tracker-0.22.5.dist-info}/WHEEL +0 -0
  35. {nrl_tracker-0.21.1.dist-info → nrl_tracker-0.22.5.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.21.1
3
+ Version: 0.22.5
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
@@ -60,15 +60,15 @@ Requires-Dist: plotly>=5.15.0; extra == "visualization"
60
60
 
61
61
  # Tracker Component Library (Python)
62
62
 
63
- [![PyPI version](https://img.shields.io/badge/pypi-v0.21.1-blue.svg)](https://pypi.org/project/nrl-tracker/)
63
+ [![PyPI version](https://img.shields.io/badge/pypi-v0.22.5-blue.svg)](https://pypi.org/project/nrl-tracker/)
64
64
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
65
65
  [![License: Public Domain](https://img.shields.io/badge/License-Public%20Domain-brightgreen.svg)](https://en.wikipedia.org/wiki/Public_domain)
66
66
  [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
67
- [![Tests](https://img.shields.io/badge/tests-1530%20passing-success.svg)](https://github.com/nedonatelli/TCL)
67
+ [![Tests](https://img.shields.io/badge/tests-1598%20passing-success.svg)](https://github.com/nedonatelli/TCL)
68
68
 
69
69
  A Python port of the [U.S. Naval Research Laboratory's Tracker Component Library](https://github.com/USNavalResearchLaboratory/TrackerComponentLibrary), a comprehensive collection of algorithms for target tracking, estimation, coordinate systems, and related mathematical functions.
70
70
 
71
- **800+ functions** | **144 modules** | **1,530 tests** | **15+ algorithm categories**
71
+ **800+ functions** | **144 modules** | **1,598 tests** | **15+ algorithm categories**
72
72
 
73
73
  ## Overview
74
74
 
@@ -1,30 +1,32 @@
1
- pytcl/__init__.py,sha256=1grcwT7hqkF4MBmoUc9ugi2bhsecHLZuLZr8ALWSgC8,1894
1
+ pytcl/__init__.py,sha256=uQnRoRwqaWqcvE-GHRP1WQoDJ2Eg96DjEkzM7-oteL4,1894
2
2
  pytcl/assignment_algorithms/__init__.py,sha256=f9V-TkEVmiKYYyth4PTpDfJvA7yYV_ys6Zix-QwWIYY,2136
3
- pytcl/assignment_algorithms/data_association.py,sha256=X6Kww9-J2WLxU1790w7dRvAFdM90RSXHvs7IF26zweQ,11427
3
+ pytcl/assignment_algorithms/data_association.py,sha256=tsRxWJZk9aAPmE99BKXGouEpFfZrjPjb4HXvgxFUHhU,11405
4
4
  pytcl/assignment_algorithms/gating.py,sha256=fN_oAOkv7nYYOWE1oPOLrcCn3xEpKdMVlFSbRMAURxY,10815
5
- pytcl/assignment_algorithms/jpda.py,sha256=hvZGkSrStuw9iQg7gPuIV7_bOinX3Xix5vLrVLMnEMM,19288
5
+ pytcl/assignment_algorithms/jpda.py,sha256=Hv55j3J9qVwzlUfWdXdSasodTyB1ZKdgEpo5dBh95O8,19582
6
6
  pytcl/assignment_algorithms/three_dimensional/__init__.py,sha256=1Q40OUlUQoo7YKEucwdrSNo3D4A0Zibvkr8z4TpueBg,526
7
7
  pytcl/assignment_algorithms/three_dimensional/assignment.py,sha256=9BJhwlYu3JJ0kZ9sRyKKfpdvQdL4WYYHCtLbvaWycBw,19212
8
8
  pytcl/assignment_algorithms/two_dimensional/__init__.py,sha256=4Evsn__9hTfI2i8m8Ngl-Zy0Fa2OydKmDKlZlH6jaao,778
9
- pytcl/assignment_algorithms/two_dimensional/assignment.py,sha256=IRwbv-82dEbbm3KwjyUjuUWM3wP9s6oUtzX2mZffMjA,11419
9
+ pytcl/assignment_algorithms/two_dimensional/assignment.py,sha256=eh87MBb-uiUSI1MXj4HrreRKB6Z8rxAyDkNQ8-u4SbM,11848
10
10
  pytcl/assignment_algorithms/two_dimensional/kbest.py,sha256=yiTToLuP7xWxQlQ8E-fpgXg-5iu0nnXcJXStjUB0nOE,17284
11
- pytcl/astronomical/__init__.py,sha256=SKELDaDhxpvCo1dMswBQYOQr_Th3ShuzZTzxZMdhE-U,5650
11
+ pytcl/astronomical/__init__.py,sha256=Dtf6hqXyKyFL5VP-sqI7m2QGK6l-rqRGxVIhgDuYHOg,7182
12
+ pytcl/astronomical/ephemerides.py,sha256=x2500S0rF1D2h0dMR_2BnZaChbBZTooHLdrevttxlAc,16471
12
13
  pytcl/astronomical/lambert.py,sha256=Lc8FT1JmpI9WSXsG2s5vIRkSoBSV7r5hd3o2bGh2Ojo,15607
13
14
  pytcl/astronomical/orbital_mechanics.py,sha256=8GssRanwTowCl6PJYqmB_SDnNznLUq5gkPa3j6iEo3U,19965
14
15
  pytcl/astronomical/reference_frames.py,sha256=GDak7af6BqOwGnCUxkvFoeqd_H2TMubdjG9lGPCoUB4,15799
16
+ pytcl/astronomical/relativity.py,sha256=YPsXLD-VRh-nqs1laC-wKpRO00fflm4GkyLhojPydbo,15441
15
17
  pytcl/astronomical/time_systems.py,sha256=Jg0Zaq60hc4Ts1aQtb5bK4KSZhz-uQse8gYC89Y0-TA,15243
16
- pytcl/atmosphere/__init__.py,sha256=QAYgJYzgs0kreRV8fByii4p477LCxBDfrXB_cL7SYkM,706
18
+ pytcl/atmosphere/__init__.py,sha256=TTVz4hAM48Xd3jr6GKrR2GAABpx2z0aWvtzb9uIQiHk,737
17
19
  pytcl/atmosphere/models.py,sha256=pMLv8D7qoFqLZrlbTHLJJULOdDdhPskJ1m7KVKLV63E,9584
18
20
  pytcl/clustering/__init__.py,sha256=bYdhC_XJEt6KUUni9bIPxaddXNEGmIJQvGkA14rK4J8,1697
19
- pytcl/clustering/dbscan.py,sha256=cjBi5b0gcBgFqUtkLm1G0JMJLQYALahyYuoSI4G0zAY,6903
21
+ pytcl/clustering/dbscan.py,sha256=PS6QlOwHFerbZNEb3zcNhN4oNQpgOOw5y0WskQzyKIo,7364
20
22
  pytcl/clustering/gaussian_mixture.py,sha256=U5U0Z46tZWdTLNdNNNJenoeviwZRAOvexVFYVLt4QMc,22865
21
- pytcl/clustering/hierarchical.py,sha256=PEkIGqAQ33InUGIcCRevv0rko4R1HqIwfejNhHsbnKQ,13794
22
- pytcl/clustering/kmeans.py,sha256=fmUIQdQLKCocwmMabdReQ0cKqMNKNFI_DyTCivPmAtw,10842
23
- pytcl/containers/__init__.py,sha256=t8oRtusBrh6G2dEk2PcofmxrpLPQ9nOJwH19GyKnNcc,1699
24
- pytcl/containers/cluster_set.py,sha256=_lZ39PNHTL7fUEZAwBF2ICK6v0GjZKpeUOg0knEdPzo,22760
23
+ pytcl/clustering/hierarchical.py,sha256=Hw9BFCn5df_ATpJX63R3B31MHz27ztCw9ihMDIlI688,14202
24
+ pytcl/clustering/kmeans.py,sha256=250FQyDol5S_Y4TznNn9cEuE96UDp7wvEkPZJ1DLul8,10697
25
+ pytcl/containers/__init__.py,sha256=-hnqSMKlMugj2RRssx3p_48HWnfqLSrF6BCChsinCOg,1627
26
+ pytcl/containers/cluster_set.py,sha256=y36D5TNzvCN6xjg6taP2SD_MC-O5iLq9ncBlHsQ5IBs,22723
25
27
  pytcl/containers/covertree.py,sha256=1JWqXxoUFLxuMnjwj2qf0iz2uPzdujQYdwJW3l5qsOs,13282
26
28
  pytcl/containers/kd_tree.py,sha256=pxRC62RYkqz9zXPz6c1fubmtPPBDLYA5I9AXMAoGanw,16348
27
- pytcl/containers/measurement_set.py,sha256=Kr29mlJOCyGMYhMnE89f-W72aunlv4p04QAdfCZcm-0,12687
29
+ pytcl/containers/measurement_set.py,sha256=87AbdoZIUspn1yJsiMpyQ5LoEVcerUnXefXGGPtFTJg,12654
28
30
  pytcl/containers/rtree.py,sha256=gv2EztvPnaAXEa6OoFnOYBY1MfTwjNMYh_BCiIomHJk,15450
29
31
  pytcl/containers/track_list.py,sha256=6q9Qgcwm-8H_JqtOCsMssF27av4XaSkhfDl-MWb1ABc,12520
30
32
  pytcl/containers/vptree.py,sha256=6fBNHrezkmj7L2nH0-2bONRN92f5cZAhS-5vaI1JZnA,8814
@@ -34,7 +36,7 @@ pytcl/coordinate_systems/conversions/geodetic.py,sha256=qQSnJRt3jg5KiostvzyslPIb
34
36
  pytcl/coordinate_systems/conversions/spherical.py,sha256=q7k9l5mJbVzVdNj9Gcq4ibFxax8z_mVpJfITRBzx630,10812
35
37
  pytcl/coordinate_systems/jacobians/__init__.py,sha256=CRGB8GzvGT_sr4Ynm51S7gSX8grqt1pO1Pq1MWmHPTs,890
36
38
  pytcl/coordinate_systems/jacobians/jacobians.py,sha256=1KufIoktm9mXLO34X9KjysdMpu7itGwfssRyAdkTTN8,11703
37
- pytcl/coordinate_systems/projections/__init__.py,sha256=-IaYuCO9EU3ytik2KqIbFLP2YZScdaLsNJOXZJev6s0,2438
39
+ pytcl/coordinate_systems/projections/__init__.py,sha256=eWNtezPO62IUWxv7jymenIXsWS1MC66Q12u5KRUnqNE,2503
38
40
  pytcl/coordinate_systems/projections/projections.py,sha256=yODS7n1gA4jsCJcU8EaeclHrbUBsZI9O2M_XJs2HOXs,33169
39
41
  pytcl/coordinate_systems/rotations/__init__.py,sha256=nqAz4iJd2hEOX_r7Tz4cE524sShyxdbtcQ5m56RrDLg,1047
40
42
  pytcl/coordinate_systems/rotations/rotations.py,sha256=FAYHkShQcpOlWJjtvLfNvtCx-a56pr-cbpo0QjC5W9U,18227
@@ -43,26 +45,26 @@ pytcl/core/array_utils.py,sha256=SsgEiAoRCWxAVKq1aa5-nPdOi-2AB6XNObu0IaGClUk,139
43
45
  pytcl/core/constants.py,sha256=lZVDK5zsSR02_4b2Nqx9KDtZT9QaYhkZ9wuoODbifd4,8693
44
46
  pytcl/core/validation.py,sha256=WRlzMlUihtqc3XZoWOTFK0sBAZVDIwTMGCiWcX5OZVY,13093
45
47
  pytcl/dynamic_estimation/__init__.py,sha256=jA5FF6kHYklY5LMOfZaKcCeiPTpVe8vHIMp3ECDOmsc,4582
46
- pytcl/dynamic_estimation/imm.py,sha256=CoOwJJv0DMrNKRkP-OqWbSxZO_-GAgNLaQ4KiBhjvEg,21313
48
+ pytcl/dynamic_estimation/imm.py,sha256=IbKmouUiyzaYJbhWty63r3n_xV8thD-wd0qgZP1SxOI,22067
47
49
  pytcl/dynamic_estimation/information_filter.py,sha256=x7iQwO_iJT1dCSvDws5LqD3yAtjw9QVGUfMPcXn1IA4,17349
48
- pytcl/dynamic_estimation/smoothers.py,sha256=qC_g0YG0U4L_7rGBpcZzYcb11A--Hc8tb0fxWXIJdxM,18931
50
+ pytcl/dynamic_estimation/smoothers.py,sha256=x2j-nR--EI5JNZvMywPeDHcrfW8b5PYK0DCU4Rmig_g,18914
49
51
  pytcl/dynamic_estimation/batch_estimation/__init__.py,sha256=JQ0s76Enov5a7plA4EnUua4t-7etikQrwr5z4WIjUeo,46
50
52
  pytcl/dynamic_estimation/kalman/__init__.py,sha256=yoFLj0n-NRkdZnRVL-BkHBlATk8pfZEVlsY3BhSYgKc,2387
51
- pytcl/dynamic_estimation/kalman/extended.py,sha256=_deQTnUGOp_BlhP-FDEY0LOjgUMN32FQn0V12unCM4A,10397
52
- pytcl/dynamic_estimation/kalman/linear.py,sha256=sTfWt_yDxyQCA0SMjOx4xfhVnq3nReOVUObXuUuZRv8,11844
53
+ pytcl/dynamic_estimation/kalman/extended.py,sha256=51uhCqkZmErCx6MBfMq8eIQW8bD7n34zCe4v4dxNiMQ,10384
54
+ pytcl/dynamic_estimation/kalman/linear.py,sha256=1Zgg9gZya0Vxs9im7sPUqLj0Luo463vS-RSa6GCReFI,12248
53
55
  pytcl/dynamic_estimation/kalman/square_root.py,sha256=Hw1F4_Zc7IA6Mt1WCkjx1UuLAUmNhM5vPLvueb7oRSA,26931
54
- pytcl/dynamic_estimation/kalman/unscented.py,sha256=NXPBTAf6814Yw5HTFpX21w_Y0eSC6q1gZSRUHHYEQjI,14943
56
+ pytcl/dynamic_estimation/kalman/unscented.py,sha256=RDK6USkko9lj1K4-WYydh3_8GMZNng_PJVjfc-c_OwM,15427
55
57
  pytcl/dynamic_estimation/measurement_update/__init__.py,sha256=8rlyJwVpxf0fZj-AFo1hlewvryZRhUzcy3F8uMe6I8c,48
56
58
  pytcl/dynamic_estimation/particle_filters/__init__.py,sha256=-DRF5rVF2749suLlArmkTvVkqeMcV_mIx0eLeTj6wNU,906
57
- pytcl/dynamic_estimation/particle_filters/bootstrap.py,sha256=EfF9w0xqyBIYOHIwoYRt7D8aCgdPoGpvaFINu8gCZ80,12396
59
+ pytcl/dynamic_estimation/particle_filters/bootstrap.py,sha256=FcF4W_NM5ZqJnw5fq4rq6fLY9X1r4uFJOiAX9a-NGG8,13371
58
60
  pytcl/dynamic_models/__init__.py,sha256=Cd8MyyYuB8gMnepkPA-HSwTaKFPThnqoKOhdjVOsXWg,2783
59
61
  pytcl/dynamic_models/continuous_time/__init__.py,sha256=dAkfEddLkfMvDalK9v2GRBvaZV1KgqYpFBLOnoiFClw,1023
60
62
  pytcl/dynamic_models/continuous_time/dynamics.py,sha256=CDwqn-66eUwXA5xfIjaG6A4EDBqtOyQ3aWarJr9QH4g,12858
61
- pytcl/dynamic_models/discrete_time/__init__.py,sha256=pJ-VWMPkIdOcARM3CXlpYZcdUS5jWmqC6z2DXTd-b7c,966
63
+ pytcl/dynamic_models/discrete_time/__init__.py,sha256=1cdYeVIe-kgogiHzeCv1eYMctSimh8t1nIE6Z1N4im4,949
62
64
  pytcl/dynamic_models/discrete_time/coordinated_turn.py,sha256=jrSGCKiAdXaFIJBLzRyAv0xxxpOHOBnAtDHyu7VYsm8,7206
63
65
  pytcl/dynamic_models/discrete_time/polynomial.py,sha256=zv5V-AbuaXlIj36n-YkOEyC74jV2vczxpCW09P0kmi0,5529
64
66
  pytcl/dynamic_models/discrete_time/singer.py,sha256=wZS3Nad-YyPZp8Mle8Sf5GgW0-t4TxMRcnbc42HtQnA,3861
65
- pytcl/dynamic_models/process_noise/__init__.py,sha256=3KVpLzGaNaR36DloPG5R1yaZWcR5QpdUJp2hwh5KFnk,950
67
+ pytcl/dynamic_models/process_noise/__init__.py,sha256=ZRYgV40qmBkPwU3yTbIMvxorr4nVz0_FEP2oCeVjXoM,933
66
68
  pytcl/dynamic_models/process_noise/coordinated_turn.py,sha256=w7bHUImLPL5m3KYenfNgAnHPCRtAyYESbsFc6lQKXRg,4768
67
69
  pytcl/dynamic_models/process_noise/polynomial.py,sha256=natfpsdN3qM9VzPeXF_nBpsbRI74S1WkkRCaaem6EQo,7620
68
70
  pytcl/dynamic_models/process_noise/singer.py,sha256=lsJDT6xOvcS_qQKFtgHX0L7Ukpy4D7HgvPT8Q3I0ibU,3901
@@ -72,7 +74,7 @@ pytcl/gravity/egm.py,sha256=QTRuvCiMjuNQdZF163OGwjxuivpGu2dB6E0zQLbKPP8,18083
72
74
  pytcl/gravity/models.py,sha256=rdY3Do4M1eRFO74gu3xy-bBn7tox3zM49wYbfnsIQWw,11159
73
75
  pytcl/gravity/spherical_harmonics.py,sha256=uZasz-w2K16sWT6xrNIPyTEP6MSlMQSe_BCWpXhRkWY,14722
74
76
  pytcl/gravity/tides.py,sha256=hef_BGewFGD7dJwg0t09Z6tfWLco_avATLuu66rnTpI,27733
75
- pytcl/magnetism/__init__.py,sha256=FNggjh99tEybKM2RxuX_EJlgu3U3CrREBadXOvRguGA,2549
77
+ pytcl/magnetism/__init__.py,sha256=hE2BvberFSmimYuuwCYJ0g7ByxJAdj844vZJNkEotws,2502
76
78
  pytcl/magnetism/emm.py,sha256=5Jwl99wvdKYtx1-3LBB7x-w5KT-fqLiRg7uBW0Ai_Gw,22292
77
79
  pytcl/magnetism/igrf.py,sha256=3g0PsH8IdbwQQS28OR5XWD-g-QxvfUva7jOkKToxndQ,13384
78
80
  pytcl/magnetism/wmm.py,sha256=p0H7Eo02iB6nEMvGyvjsrAWOSKrIye6PGwQtNKfHaNw,15999
@@ -85,7 +87,7 @@ pytcl/mathematical_functions/combinatorics/combinatorics.py,sha256=3EgkWdBqQ9e6J
85
87
  pytcl/mathematical_functions/continuous_optimization/__init__.py,sha256=lck60eeCUOsRpEzPHBY3kiLKwNz_fhmYoUGP3lTmTwk,55
86
88
  pytcl/mathematical_functions/geometry/__init__.py,sha256=DhCmux9-6zxYRzlhQ9du18kvUL-leiiZwdd3Cmb5WX0,1092
87
89
  pytcl/mathematical_functions/geometry/geometry.py,sha256=l63wQnhCtJwVHZOJeONX1qyJ5Sedji8etgxwJCFtH8Y,16403
88
- pytcl/mathematical_functions/interpolation/__init__.py,sha256=HDhP7ZsgUrXFBNJ_eCZEdp5gizWJ-BxvkQSCMnvBg3A,677
90
+ pytcl/mathematical_functions/interpolation/__init__.py,sha256=lK4Rs0Ds_fzf9q0n6id5epdN0U8V7yD87dS-w1hvN8I,741
89
91
  pytcl/mathematical_functions/interpolation/interpolation.py,sha256=2cXMDgWBjWDGHnK1K_lawFlJL8oPl5AQGf9MNgsESfo,12610
90
92
  pytcl/mathematical_functions/numerical_integration/__init__.py,sha256=iXiHzyV_KIhCv7tXErXlN1_fUEACN6yN3CYDHRA7esw,974
91
93
  pytcl/mathematical_functions/numerical_integration/quadrature.py,sha256=ZRMKs0vbcgFDe1Sr8sjyEOkALLmJU4zKRJjoPEcXrUc,15670
@@ -94,7 +96,7 @@ pytcl/mathematical_functions/signal_processing/__init__.py,sha256=_SzzBVtxmSvP8F
94
96
  pytcl/mathematical_functions/signal_processing/detection.py,sha256=9F0xdy3hMat1czSWAQYMExn0kY5DBRpyBneAfjjHUVI,30377
95
97
  pytcl/mathematical_functions/signal_processing/filters.py,sha256=8Ojf4h4rfiucBXqUmB1odvHH41Gf3rPwmWCMKb-qzWk,23435
96
98
  pytcl/mathematical_functions/signal_processing/matched_filter.py,sha256=AahJZRZk2IIXzRL7www0n8bc0XoKabaLOe8yYNSjuDY,22893
97
- pytcl/mathematical_functions/special_functions/__init__.py,sha256=qDPGfee1i1NkVi9LXJKnsWXL3CWHkPQINrkwqLqB8YU,3796
99
+ pytcl/mathematical_functions/special_functions/__init__.py,sha256=AJBCKj32daQxdahUQckW0bWowzOoapxni2eZnVXERdg,3859
98
100
  pytcl/mathematical_functions/special_functions/bessel.py,sha256=M0mwLQBaUXEHA8wyKReJ2D66I1v1XR7y-txAipd-WDs,14377
99
101
  pytcl/mathematical_functions/special_functions/debye.py,sha256=Nchjwkl1vzSL1L7nQpslb-lvT49LgTfdTIQMeSNn4vQ,6689
100
102
  pytcl/mathematical_functions/special_functions/elliptic.py,sha256=WyzBkrfZufIR5dUmCKGcxp6KNpVDrU89NGLDyRrZOqQ,7418
@@ -111,10 +113,10 @@ pytcl/mathematical_functions/transforms/fourier.py,sha256=QH6OaTzw4kN6M-DuSmwB_5
111
113
  pytcl/mathematical_functions/transforms/stft.py,sha256=zQapXl-v69_RDPwMqci83jah17GyAfnr3gx0budv2Cg,18619
112
114
  pytcl/mathematical_functions/transforms/wavelets.py,sha256=dm273Z_t13BlEVSlHTaGE7jR1ocugL7lEkcO499U7bY,21656
113
115
  pytcl/misc/__init__.py,sha256=SCHf_lQVfdl2gwUluHBiIloTF8HRH8EkgYfbNr7zOug,33
114
- pytcl/navigation/__init__.py,sha256=9tUhEgPVugA8nmZ9rvOaAntCd7rDPgW2RBLHqaDAXSc,5864
116
+ pytcl/navigation/__init__.py,sha256=k1_x_FnnPrIzGeNu7zejPtPubIhweBgCfwqlZJEMw0I,6042
115
117
  pytcl/navigation/geodesy.py,sha256=M9XXfBTMCRdaWMV2-ViDSTEt94WZnMtxMeJQ1FAgQHY,17227
116
118
  pytcl/navigation/great_circle.py,sha256=TtlkWZbzr-HzSt4ultG_h137ZnX0pJZx_87kr3uvpjI,20923
117
- pytcl/navigation/ins.py,sha256=V3ZA4z8y5E6PBCd1FhifR5VaCU7DRAn2fb7W0LilByo,31168
119
+ pytcl/navigation/ins.py,sha256=OIi8_RjrgEYl0MFpJEFMjIlpgX8DYGTEhdLEvqG-ABU,31151
118
120
  pytcl/navigation/ins_gnss.py,sha256=euKF5JGgwmVBsw3jBf7_wa2z1BpZeVbSNmBuwzhGS6c,30157
119
121
  pytcl/navigation/rhumb.py,sha256=lr1c3iEXfoOSfIyyXSRWv6He5TlaxEHbJy-dhqM1gRw,18224
120
122
  pytcl/performance_evaluation/__init__.py,sha256=tM2pnBfDb2XbnLt4Y5MQ6w6XBwFy_5bf_y0toZmxx88,1859
@@ -135,14 +137,14 @@ pytcl/terrain/__init__.py,sha256=e7plNQI5Y_jpZ24r82AgqdX0ChmmyYoeT7HReclnGXc,322
135
137
  pytcl/terrain/dem.py,sha256=rg2o0h0ZDrfxvtYhnE2A5tdzRnCmqcihu4w1uNJdH3Y,20814
136
138
  pytcl/terrain/loaders.py,sha256=KBs1vdYUYW-0ETIujRv4-WxO-bExZk-FvPLY5l6gyTc,27028
137
139
  pytcl/terrain/visibility.py,sha256=nIJr9AVk7C8GCpJV4UDvUjhmAieycWD8BLepAMUBMIQ,22739
138
- pytcl/trackers/__init__.py,sha256=8-KpFtxS0n83B-dq4x0X4V1TQGHZnNSzdujAJUGcjxc,1198
140
+ pytcl/trackers/__init__.py,sha256=Gw79xlSIUzdPV8bN1slNWUlGxE3d-NsVmbMygkYVV20,1151
139
141
  pytcl/trackers/hypothesis.py,sha256=RApWfji-f0-a68KnAJela0BvPdIlOY_FV_cYJFmVUoE,17353
140
142
  pytcl/trackers/mht.py,sha256=7mwhMmja3ri2wnx7W1wueDGn2r3ArwAxJDPUJ7IZAkQ,20617
141
- pytcl/trackers/multi_target.py,sha256=7ZL8V25TO_rEMtQm2eYkScesDQHC9qXZVHLHyVbxy3M,10529
143
+ pytcl/trackers/multi_target.py,sha256=hvt89ERhMwpcHcIJeKHnkQSKdE3_LoRiX-gbaGoo300,10516
142
144
  pytcl/trackers/single_target.py,sha256=Yy3FwaNTArMWcaod-0HVeiioNV4xLWxNDn_7ZPVqQYs,6562
143
145
  pytcl/transponders/__init__.py,sha256=5fL4u3lKCYgPLo5uFeuZbtRZkJPABntuKYGUvVgMMEI,41
144
- nrl_tracker-0.21.1.dist-info/LICENSE,sha256=rB5G4WppIIUzMOYr2N6uyYlNJ00hRJqE5tie6BMvYuE,1612
145
- nrl_tracker-0.21.1.dist-info/METADATA,sha256=Do-PM_-vvQ08w8QWNyvIuRmsAEqzFXe8NSO5BXLTlHg,10005
146
- nrl_tracker-0.21.1.dist-info/WHEEL,sha256=pL8R0wFFS65tNSRnaOVrsw9EOkOqxLrlUPenUYnJKNo,91
147
- nrl_tracker-0.21.1.dist-info/top_level.txt,sha256=17megxcrTPBWwPZTh6jTkwTKxX7No-ZqRpyvElnnO-s,6
148
- nrl_tracker-0.21.1.dist-info/RECORD,,
146
+ nrl_tracker-0.22.5.dist-info/LICENSE,sha256=rB5G4WppIIUzMOYr2N6uyYlNJ00hRJqE5tie6BMvYuE,1612
147
+ nrl_tracker-0.22.5.dist-info/METADATA,sha256=-UF7pUd0_uGM8wPE1ge5WFz1Ojnv4C5MJJ6PEOoDJD0,10005
148
+ nrl_tracker-0.22.5.dist-info/WHEEL,sha256=pL8R0wFFS65tNSRnaOVrsw9EOkOqxLrlUPenUYnJKNo,91
149
+ nrl_tracker-0.22.5.dist-info/top_level.txt,sha256=17megxcrTPBWwPZTh6jTkwTKxX7No-ZqRpyvElnnO-s,6
150
+ nrl_tracker-0.22.5.dist-info/RECORD,,
pytcl/__init__.py CHANGED
@@ -20,7 +20,7 @@ References
20
20
  no. 5, pp. 18-27, May 2017.
21
21
  """
22
22
 
23
- __version__ = "0.18.0"
23
+ __version__ = "0.22.5"
24
24
  __author__ = "Python Port Contributors"
25
25
  __original_author__ = "David F. Crouse, Naval Research Laboratory"
26
26
 
@@ -10,13 +10,8 @@ from typing import List, NamedTuple, Optional
10
10
  import numpy as np
11
11
  from numpy.typing import ArrayLike, NDArray
12
12
 
13
- from pytcl.assignment_algorithms.gating import (
14
- mahalanobis_batch,
15
- mahalanobis_distance,
16
- )
17
- from pytcl.assignment_algorithms.two_dimensional import (
18
- assign2d,
19
- )
13
+ from pytcl.assignment_algorithms.gating import mahalanobis_batch, mahalanobis_distance
14
+ from pytcl.assignment_algorithms.two_dimensional import assign2d
20
15
 
21
16
 
22
17
  class AssociationResult(NamedTuple):
@@ -12,6 +12,7 @@ as JPDA can handle measurement origin uncertainty in cluttered environments.
12
12
  from typing import List, NamedTuple, Optional, Tuple
13
13
 
14
14
  import numpy as np
15
+ from numba import njit
15
16
  from numpy.typing import ArrayLike, NDArray
16
17
  from scipy.stats import chi2
17
18
 
@@ -314,45 +315,34 @@ def _jpda_exact(
314
315
  return beta
315
316
 
316
317
 
317
- def _jpda_approximate(
318
- likelihood_matrix: NDArray,
319
- gated: NDArray,
318
+ @njit(cache=True)
319
+ def _jpda_approximate_core(
320
+ likelihood_matrix: np.ndarray,
321
+ gated: np.ndarray,
320
322
  detection_prob: float,
321
323
  clutter_density: float,
322
- ) -> NDArray:
323
- """
324
- Approximate JPDA using parametric approach.
325
-
326
- Uses the approach from [1] which is O(n_tracks * n_meas^2).
327
-
328
- References
329
- ----------
330
- .. [1] Fitzgerald, R.J., "Development of Practical PDA Logic for
331
- Multitarget Tracking by Microprocessor", American Control
332
- Conference, 1986.
333
- """
334
- n_tracks, n_meas = likelihood_matrix.shape
335
- beta = np.zeros((n_tracks, n_meas + 1))
336
-
337
- # For each track, compute association probabilities independently
338
- # then apply correction for shared measurements
324
+ ) -> np.ndarray:
325
+ """JIT-compiled core of approximate JPDA computation."""
326
+ n_tracks = likelihood_matrix.shape[0]
327
+ n_meas = likelihood_matrix.shape[1]
328
+ beta = np.zeros((n_tracks, n_meas + 1), dtype=np.float64)
339
329
 
340
330
  # Likelihood ratio for each measurement given each track
341
- # L[i,j] = likelihood(z_j | track i) / clutter_density
342
- L = np.zeros((n_tracks, n_meas))
331
+ L = np.zeros((n_tracks, n_meas), dtype=np.float64)
343
332
  for i in range(n_tracks):
344
333
  for j in range(n_meas):
345
334
  if gated[i, j] and clutter_density > 0:
346
335
  L[i, j] = likelihood_matrix[i, j] / clutter_density
347
336
  elif gated[i, j]:
348
- L[i, j] = likelihood_matrix[i, j] * 1e10 # Large value
337
+ L[i, j] = likelihood_matrix[i, j] * 1e10
349
338
 
350
339
  # Compute delta factors (accounts for other tracks)
351
- delta = np.ones((n_tracks, n_meas))
340
+ delta = np.ones((n_tracks, n_meas), dtype=np.float64)
352
341
 
353
342
  for j in range(n_meas):
354
- # Sum of likelihood ratios for measurement j
355
- sum_L = np.sum(L[:, j])
343
+ sum_L = 0.0
344
+ for i in range(n_tracks):
345
+ sum_L += L[i, j]
356
346
  for i in range(n_tracks):
357
347
  if sum_L > 0:
358
348
  delta[i, j] = 1.0 / (1.0 + sum_L - L[i, j])
@@ -361,7 +351,6 @@ def _jpda_approximate(
361
351
 
362
352
  # Compute association probabilities
363
353
  for i in range(n_tracks):
364
- # Denominator for normalization
365
354
  denom = 1.0 - detection_prob
366
355
 
367
356
  for j in range(n_meas):
@@ -369,9 +358,9 @@ def _jpda_approximate(
369
358
  beta[i, j] = detection_prob * L[i, j] * delta[i, j]
370
359
  denom += beta[i, j]
371
360
 
372
- # Normalize
373
361
  if denom > 0:
374
- beta[i, :n_meas] /= denom
362
+ for j in range(n_meas):
363
+ beta[i, j] /= denom
375
364
  beta[i, n_meas] = (1.0 - detection_prob) / denom
376
365
  else:
377
366
  beta[i, n_meas] = 1.0
@@ -379,6 +368,31 @@ def _jpda_approximate(
379
368
  return beta
380
369
 
381
370
 
371
+ def _jpda_approximate(
372
+ likelihood_matrix: NDArray,
373
+ gated: NDArray,
374
+ detection_prob: float,
375
+ clutter_density: float,
376
+ ) -> NDArray:
377
+ """
378
+ Approximate JPDA using parametric approach.
379
+
380
+ Uses the approach from [1] which is O(n_tracks * n_meas^2).
381
+
382
+ References
383
+ ----------
384
+ .. [1] Fitzgerald, R.J., "Development of Practical PDA Logic for
385
+ Multitarget Tracking by Microprocessor", American Control
386
+ Conference, 1986.
387
+ """
388
+ return _jpda_approximate_core(
389
+ likelihood_matrix.astype(np.float64),
390
+ gated.astype(np.bool_),
391
+ detection_prob,
392
+ clutter_density,
393
+ )
394
+
395
+
382
396
  def jpda_update(
383
397
  track_states: List[ArrayLike],
384
398
  track_covariances: List[ArrayLike],
@@ -211,14 +211,21 @@ def auction(
211
211
  # Compute values: value[j] = -cost[i,j] - prices[j]
212
212
  values = -cost[i, :] - prices
213
213
 
214
- # Find best and second best
215
- sorted_idx = np.argsort(values)[::-1]
216
- best_j = sorted_idx[0]
217
- best_value = values[best_j]
218
-
219
- if len(sorted_idx) > 1:
220
- second_value = values[sorted_idx[1]]
214
+ # Find best and second best using argpartition (O(n) vs O(n log n))
215
+ if len(values) >= 2:
216
+ # Get indices of top 2 values
217
+ top2_idx = np.argpartition(values, -2)[-2:]
218
+ # Determine which is best and second best
219
+ if values[top2_idx[0]] > values[top2_idx[1]]:
220
+ best_j = top2_idx[0]
221
+ second_value = values[top2_idx[1]]
222
+ else:
223
+ best_j = top2_idx[1]
224
+ second_value = values[top2_idx[0]]
225
+ best_value = values[best_j]
221
226
  else:
227
+ best_j = np.argmax(values)
228
+ best_value = values[best_j]
222
229
  second_value = -np.inf
223
230
 
224
231
  # Bid increment
@@ -2,7 +2,8 @@
2
2
  Astronomical calculations for target tracking.
3
3
 
4
4
  This module provides time system conversions, orbital mechanics,
5
- Lambert problem solvers, and reference frame transformations.
5
+ Lambert problem solvers, reference frame transformations, and high-precision
6
+ ephemerides for celestial bodies.
6
7
 
7
8
  Examples
8
9
  --------
@@ -18,8 +19,19 @@ Examples
18
19
  >>> r1 = np.array([5000, 10000, 2100])
19
20
  >>> r2 = np.array([-14600, 2500, 7000])
20
21
  >>> sol = lambert_universal(r1, r2, 3600)
22
+
23
+ >>> # Query Sun position with high precision
24
+ >>> from pytcl.astronomical import sun_position
25
+ >>> r_sun, v_sun = sun_position(2451545.0) # J2000.0
21
26
  """
22
27
 
28
+ from pytcl.astronomical.ephemerides import (
29
+ DEEphemeris,
30
+ barycenter_position,
31
+ moon_position,
32
+ planet_position,
33
+ sun_position,
34
+ )
23
35
  from pytcl.astronomical.lambert import (
24
36
  LambertSolution,
25
37
  bi_elliptic_transfer,
@@ -28,8 +40,10 @@ from pytcl.astronomical.lambert import (
28
40
  lambert_universal,
29
41
  minimum_energy_transfer,
30
42
  )
31
- from pytcl.astronomical.orbital_mechanics import ( # Constants; Types; Anomaly conversions; Element conversions; Propagation; Orbital quantities
32
- GM_EARTH,
43
+ from pytcl.astronomical.orbital_mechanics import (
44
+ GM_EARTH, # Constants; Types; Anomaly conversions; Element conversions; Propagation; Orbital quantities
45
+ )
46
+ from pytcl.astronomical.orbital_mechanics import (
33
47
  GM_JUPITER,
34
48
  GM_MARS,
35
49
  GM_MOON,
@@ -62,8 +76,10 @@ from pytcl.astronomical.orbital_mechanics import ( # Constants; Types; Anomaly
62
76
  true_to_mean_anomaly,
63
77
  vis_viva,
64
78
  )
65
- from pytcl.astronomical.reference_frames import ( # Time utilities; Precession; Nutation; Earth rotation; Polar motion; Full transformations; Ecliptic/equatorial
66
- earth_rotation_angle,
79
+ from pytcl.astronomical.reference_frames import (
80
+ earth_rotation_angle, # Time utilities; Precession; Nutation; Earth rotation; Polar motion; Full transformations; Ecliptic/equatorial
81
+ )
82
+ from pytcl.astronomical.reference_frames import (
67
83
  ecef_to_eci,
68
84
  eci_to_ecef,
69
85
  ecliptic_to_equatorial,
@@ -83,8 +99,25 @@ from pytcl.astronomical.reference_frames import ( # Time utilities; Precession;
83
99
  sidereal_rotation_matrix,
84
100
  true_obliquity,
85
101
  )
86
- from pytcl.astronomical.time_systems import ( # Julian dates; Time scales; Unix time; GPS week; Sidereal time; Leap seconds; Constants
87
- JD_GPS_EPOCH,
102
+ from pytcl.astronomical.relativity import (
103
+ C_LIGHT, # Physical constants; Schwarzschild metric; Time dilation; Shapiro delay; Precession; PN effects; Range corrections
104
+ )
105
+ from pytcl.astronomical.relativity import (
106
+ G_GRAV,
107
+ geodetic_precession,
108
+ gravitational_time_dilation,
109
+ lense_thirring_precession,
110
+ post_newtonian_acceleration,
111
+ proper_time_rate,
112
+ relativistic_range_correction,
113
+ schwarzschild_precession_per_orbit,
114
+ schwarzschild_radius,
115
+ shapiro_delay,
116
+ )
117
+ from pytcl.astronomical.time_systems import (
118
+ JD_GPS_EPOCH, # Julian dates; Time scales; Unix time; GPS week; Sidereal time; Leap seconds; Constants
119
+ )
120
+ from pytcl.astronomical.time_systems import (
88
121
  JD_J2000,
89
122
  JD_UNIX_EPOCH,
90
123
  MJD_OFFSET,
@@ -218,4 +251,24 @@ __all__ = [
218
251
  # Reference frames - Ecliptic/equatorial
219
252
  "ecliptic_to_equatorial",
220
253
  "equatorial_to_ecliptic",
254
+ # Ephemerides - Classes
255
+ "DEEphemeris",
256
+ # Ephemerides - Functions
257
+ "sun_position",
258
+ "moon_position",
259
+ "planet_position",
260
+ "barycenter_position",
261
+ # Relativity - Constants
262
+ "C_LIGHT",
263
+ "G_GRAV",
264
+ # Relativity - Functions
265
+ "schwarzschild_radius",
266
+ "gravitational_time_dilation",
267
+ "proper_time_rate",
268
+ "shapiro_delay",
269
+ "schwarzschild_precession_per_orbit",
270
+ "post_newtonian_acceleration",
271
+ "geodetic_precession",
272
+ "lense_thirring_precession",
273
+ "relativistic_range_correction",
221
274
  ]