pynamicalsys 1.5.3__tar.gz → 1.6.0__tar.gz

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 (115) hide show
  1. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/.gitignore +1 -0
  2. pynamicalsys-1.6.0/CHANGELOG.md +412 -0
  3. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/PKG-INFO +1 -1
  4. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/src/pynamicalsys/__init__.py +2 -1
  5. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/src/pynamicalsys/__version__.py +3 -3
  6. pynamicalsys-1.6.0/src/pynamicalsys/common/__init__.py +16 -0
  7. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/src/pynamicalsys/common/basin_analysis.py +107 -2
  8. pynamicalsys-1.6.0/src/pynamicalsys/common/clv.py +97 -0
  9. pynamicalsys-1.6.0/src/pynamicalsys/common/differentiation.py +93 -0
  10. pynamicalsys-1.6.0/src/pynamicalsys/common/fitting.py +50 -0
  11. pynamicalsys-1.5.3/src/pynamicalsys/common/time_series_metrics.py → pynamicalsys-1.6.0/src/pynamicalsys/common/hurst.py +19 -2
  12. pynamicalsys-1.6.0/src/pynamicalsys/common/linalg.py +154 -0
  13. pynamicalsys-1.6.0/src/pynamicalsys/common/poincare.py +42 -0
  14. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/src/pynamicalsys/common/recurrence_quantification_analysis.py +1 -1
  15. pynamicalsys-1.6.0/src/pynamicalsys/common/types.py +96 -0
  16. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/src/pynamicalsys/common/validators.py +30 -29
  17. pynamicalsys-1.6.0/src/pynamicalsys/continuous_time/__init__.py +16 -0
  18. pynamicalsys-1.6.0/src/pynamicalsys/continuous_time/adaptive_step.py +214 -0
  19. pynamicalsys-1.6.0/src/pynamicalsys/continuous_time/basins.py +150 -0
  20. pynamicalsys-1.6.0/src/pynamicalsys/continuous_time/clv.py +460 -0
  21. pynamicalsys-1.6.0/src/pynamicalsys/continuous_time/fixed_step.py +165 -0
  22. pynamicalsys-1.6.0/src/pynamicalsys/continuous_time/gali.py +215 -0
  23. pynamicalsys-1.6.0/src/pynamicalsys/continuous_time/hurst.py +164 -0
  24. pynamicalsys-1.6.0/src/pynamicalsys/continuous_time/ldi.py +178 -0
  25. pynamicalsys-1.6.0/src/pynamicalsys/continuous_time/lyapunov.py +310 -0
  26. pynamicalsys-1.6.0/src/pynamicalsys/continuous_time/maxima_map.py +229 -0
  27. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/src/pynamicalsys/continuous_time/models.py +1 -46
  28. pynamicalsys-1.6.0/src/pynamicalsys/continuous_time/poincare.py +224 -0
  29. pynamicalsys-1.6.0/src/pynamicalsys/continuous_time/rte.py +213 -0
  30. pynamicalsys-1.6.0/src/pynamicalsys/continuous_time/sali.py +170 -0
  31. pynamicalsys-1.6.0/src/pynamicalsys/continuous_time/step.py +172 -0
  32. pynamicalsys-1.6.0/src/pynamicalsys/continuous_time/step_methods.py +234 -0
  33. pynamicalsys-1.6.0/src/pynamicalsys/continuous_time/stroboscopic.py +193 -0
  34. pynamicalsys-1.6.0/src/pynamicalsys/continuous_time/trajectory.py +196 -0
  35. pynamicalsys-1.6.0/src/pynamicalsys/continuous_time/validators.py +79 -0
  36. pynamicalsys-1.6.0/src/pynamicalsys/continuous_time/variational.py +109 -0
  37. pynamicalsys-1.6.0/src/pynamicalsys/core/__init__.py +16 -0
  38. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/src/pynamicalsys/core/basin_metrics.py +206 -2
  39. pynamicalsys-1.6.0/src/pynamicalsys/core/continuous_dynamical_systems.py +2276 -0
  40. pynamicalsys-1.6.0/src/pynamicalsys/core/discrete_dynamical_systems.py +3932 -0
  41. pynamicalsys-1.6.0/src/pynamicalsys/core/hamiltonian_systems.py +2224 -0
  42. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/src/pynamicalsys/core/plot_styler.py +1 -1
  43. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/src/pynamicalsys/core/time_series_metrics.py +6 -5
  44. pynamicalsys-1.6.0/src/pynamicalsys/discrete_time/__init__.py +16 -0
  45. pynamicalsys-1.6.0/src/pynamicalsys/discrete_time/averages.py +81 -0
  46. pynamicalsys-1.6.0/src/pynamicalsys/discrete_time/bifurcation.py +134 -0
  47. pynamicalsys-1.6.0/src/pynamicalsys/discrete_time/birkhoff.py +120 -0
  48. pynamicalsys-1.6.0/src/pynamicalsys/discrete_time/clv.py +457 -0
  49. pynamicalsys-1.6.0/src/pynamicalsys/discrete_time/escape.py +235 -0
  50. pynamicalsys-1.6.0/src/pynamicalsys/discrete_time/gali.py +198 -0
  51. pynamicalsys-1.6.0/src/pynamicalsys/discrete_time/hurst.py +167 -0
  52. pynamicalsys-1.6.0/src/pynamicalsys/discrete_time/ldi.py +142 -0
  53. pynamicalsys-1.6.0/src/pynamicalsys/discrete_time/lyapunov.py +637 -0
  54. pynamicalsys-1.6.0/src/pynamicalsys/discrete_time/manifolds.py +173 -0
  55. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/src/pynamicalsys/discrete_time/models.py +1 -1
  56. pynamicalsys-1.6.0/src/pynamicalsys/discrete_time/periodic_orbits.py +568 -0
  57. pynamicalsys-1.6.0/src/pynamicalsys/discrete_time/rotation.py +76 -0
  58. pynamicalsys-1.6.0/src/pynamicalsys/discrete_time/rte.py +203 -0
  59. pynamicalsys-1.6.0/src/pynamicalsys/discrete_time/sali.py +141 -0
  60. pynamicalsys-1.6.0/src/pynamicalsys/discrete_time/stability.py +198 -0
  61. pynamicalsys-1.6.0/src/pynamicalsys/discrete_time/symmetry.py +73 -0
  62. pynamicalsys-1.6.0/src/pynamicalsys/discrete_time/trajectory.py +187 -0
  63. pynamicalsys-1.6.0/src/pynamicalsys/discrete_time/transport.py +366 -0
  64. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/src/pynamicalsys/discrete_time/validators.py +12 -13
  65. pynamicalsys-1.6.0/src/pynamicalsys/hamiltonian_systems/__init__.py +16 -0
  66. pynamicalsys-1.6.0/src/pynamicalsys/hamiltonian_systems/clv.py +950 -0
  67. pynamicalsys-1.6.0/src/pynamicalsys/hamiltonian_systems/coefficients.py +22 -0
  68. pynamicalsys-1.6.0/src/pynamicalsys/hamiltonian_systems/fixed_step.py +249 -0
  69. pynamicalsys-1.6.0/src/pynamicalsys/hamiltonian_systems/gali.py +313 -0
  70. pynamicalsys-1.6.0/src/pynamicalsys/hamiltonian_systems/hurst.py +119 -0
  71. pynamicalsys-1.6.0/src/pynamicalsys/hamiltonian_systems/ldi.py +259 -0
  72. pynamicalsys-1.6.0/src/pynamicalsys/hamiltonian_systems/lyapunov.py +506 -0
  73. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/src/pynamicalsys/hamiltonian_systems/models.py +41 -1
  74. pynamicalsys-1.6.0/src/pynamicalsys/hamiltonian_systems/poincare.py +368 -0
  75. pynamicalsys-1.6.0/src/pynamicalsys/hamiltonian_systems/rte.py +175 -0
  76. pynamicalsys-1.6.0/src/pynamicalsys/hamiltonian_systems/sali.py +255 -0
  77. pynamicalsys-1.6.0/src/pynamicalsys/hamiltonian_systems/tangent.py +438 -0
  78. pynamicalsys-1.6.0/src/pynamicalsys/hamiltonian_systems/trajectory.py +156 -0
  79. pynamicalsys-1.6.0/src/pynamicalsys/hamiltonian_systems/validators.py +142 -0
  80. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/src/pynamicalsys.egg-info/PKG-INFO +1 -1
  81. pynamicalsys-1.6.0/src/pynamicalsys.egg-info/SOURCES.txt +91 -0
  82. pynamicalsys-1.6.0/src/pynamicalsys.egg-info/scm_file_list.json +218 -0
  83. pynamicalsys-1.6.0/src/pynamicalsys.egg-info/scm_version.json +8 -0
  84. pynamicalsys-1.5.3/CHANGELOG.md +0 -210
  85. pynamicalsys-1.5.3/src/pynamicalsys/common/__init__.py +0 -16
  86. pynamicalsys-1.5.3/src/pynamicalsys/common/utils.py +0 -412
  87. pynamicalsys-1.5.3/src/pynamicalsys/continuous_time/__init__.py +0 -16
  88. pynamicalsys-1.5.3/src/pynamicalsys/continuous_time/chaotic_indicators.py +0 -1127
  89. pynamicalsys-1.5.3/src/pynamicalsys/continuous_time/numerical_integrators.py +0 -337
  90. pynamicalsys-1.5.3/src/pynamicalsys/continuous_time/trajectory_analysis.py +0 -646
  91. pynamicalsys-1.5.3/src/pynamicalsys/continuous_time/validators.py +0 -42
  92. pynamicalsys-1.5.3/src/pynamicalsys/core/__init__.py +0 -16
  93. pynamicalsys-1.5.3/src/pynamicalsys/core/continuous_dynamical_systems.py +0 -2277
  94. pynamicalsys-1.5.3/src/pynamicalsys/core/discrete_dynamical_systems.py +0 -4186
  95. pynamicalsys-1.5.3/src/pynamicalsys/core/hamiltonian_systems.py +0 -1674
  96. pynamicalsys-1.5.3/src/pynamicalsys/discrete_time/__init__.py +0 -16
  97. pynamicalsys-1.5.3/src/pynamicalsys/discrete_time/dynamical_indicators.py +0 -1692
  98. pynamicalsys-1.5.3/src/pynamicalsys/discrete_time/trajectory_analysis.py +0 -1460
  99. pynamicalsys-1.5.3/src/pynamicalsys/discrete_time/transport.py +0 -463
  100. pynamicalsys-1.5.3/src/pynamicalsys/hamiltonian_systems/__init__.py +0 -16
  101. pynamicalsys-1.5.3/src/pynamicalsys/hamiltonian_systems/chaotic_indicators.py +0 -868
  102. pynamicalsys-1.5.3/src/pynamicalsys/hamiltonian_systems/numerical_integrators.py +0 -308
  103. pynamicalsys-1.5.3/src/pynamicalsys/hamiltonian_systems/trajectory_analysis.py +0 -390
  104. pynamicalsys-1.5.3/src/pynamicalsys/hamiltonian_systems/validators.py +0 -114
  105. pynamicalsys-1.5.3/src/pynamicalsys.egg-info/SOURCES.txt +0 -46
  106. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/CITATION.cff +0 -0
  107. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/CONTRIBUTING.md +0 -0
  108. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/LICENSE +0 -0
  109. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/MANIFEST.in +0 -0
  110. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/README.md +0 -0
  111. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/pyproject.toml +0 -0
  112. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/setup.cfg +0 -0
  113. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/src/pynamicalsys.egg-info/dependency_links.txt +0 -0
  114. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/src/pynamicalsys.egg-info/requires.txt +0 -0
  115. {pynamicalsys-1.5.3 → pynamicalsys-1.6.0}/src/pynamicalsys.egg-info/top_level.txt +0 -0
@@ -1,5 +1,6 @@
1
1
  __pycache__
2
2
  .vscode/
3
+ .venv/
3
4
  .DS_Store
4
5
  *.egg-info/
5
6
  tests/*.png
@@ -0,0 +1,412 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [v1.6.0] - 2026-07-01
9
+
10
+ ### Added
11
+
12
+ - Support for **general (non-separable) Hamiltonian systems** `H(q, p)`
13
+ via a new `"imp"` (implicit midpoint) integrator. Specify the system
14
+ via `eom` and `hess_H` instead of `grad_T`/`grad_V`. All analysis
15
+ methods (`lyapunov`, `CLV`, `CLV_angles`, `SALI`, `LDI`, `GALI`,
16
+ `poincare_section`, `recurrence_time_entropy`, `hurst_exponent`)
17
+ dispatch to the implicit midpoint backend automatically when `"imp"`
18
+ is selected.
19
+ - Support for **periodic/angular section coordinates** in Poincaré
20
+ sections via `periodic_section_coordinate` and `period` parameters.
21
+ Useful for action-angle systems where the section coordinate grows
22
+ unbounded rather than oscillating. Available on `poincare_section`,
23
+ `recurrence_time_entropy`, and `hurst_exponent`.
24
+ - `poincare_section` now accepts a `max_workers` parameter controlling
25
+ the number of parallel workers used when computing an ensemble of
26
+ initial conditions (default: all available CPUs).
27
+ - The implicit midpoint integrator now raises `RuntimeError` on
28
+ non-convergence instead of silently returning corrupted results.
29
+ - `BasinMetrics`: added `uncertainty_fraction_mapping` for Monte Carlo
30
+ estimation of the uncertainty fraction and uncertainty exponent of
31
+ escape basins, with parallel evaluation and reproducible random
32
+ sampling via a user-provided seed.
33
+
34
+ [v1.6.0]: https://github.com/mrolims/pynamicalsys/compare/v1.5.4...v1.6.0
35
+
36
+ ## [v1.5.4] - 2026-05-28
37
+
38
+ ### Added
39
+
40
+ - `DiscreteDynamicalSystem` class:
41
+ - Added `return_last_state` to the `SALI`, `LDI`, and `GALI` methods.
42
+ - Added `method` option to `GALI` with the following implementations:
43
+ - `"DET"`: computes `GALI_k` from the Gram matrix determinant.
44
+ - `"QR"`: computes `GALI_k` from the diagonal of the triangular factor returned by the internal QR routine.
45
+ - `"QR_HH"`: computes `GALI_k` from the diagonal of the triangular factor returned by `numpy.linalg.qr`.
46
+
47
+ - `ContinuousDynamicalSystem` class:
48
+ - Added `method` option to `GALI` with the following implementations:
49
+ - `"DET"`: computes `GALI_k` from the Gram matrix determinant.
50
+ - `"QR"`: computes `GALI_k` from the diagonal of the triangular factor returned by the internal QR routine.
51
+ - `"QR_HH"`: computes `GALI_k` from the diagonal of the triangular factor returned by `numpy.linalg.qr`.
52
+
53
+ - `HamiltonianSystem` class:
54
+ - Added `method` option to `GALI` with the following implementations:
55
+ - `"DET"`: computes `GALI_k` from the Gram matrix determinant.
56
+ - `"QR"`: computes `GALI_k` from the diagonal of the triangular factor returned by the internal QR routine.
57
+ - `"QR_HH"`: computes `GALI_k` from the diagonal of the triangular factor returned by `numpy.linalg.qr`.
58
+
59
+ - `discrete_time` module:
60
+ - Added dedicated low-level modules:
61
+ - `trajectory.py`
62
+ - `bifurcation.py`
63
+ - `birkhoff.py`
64
+ - `hurst.py`
65
+ - `rte.py`
66
+ - `periodic_orbits.py`
67
+ - `stability.py`
68
+ - `manifolds.py`
69
+ - `rotation.py`
70
+ - `escape.py`
71
+ - `transport.py`
72
+ - `averages.py`
73
+ - `symmetry.py`
74
+ - `sali.py`
75
+ - `ldi.py`
76
+ - `gali.py`
77
+ - `clv.py`
78
+
79
+ - `continuous_time` module:
80
+ - Added dedicated low-level modules:
81
+ - `fixed_step.py`
82
+ - `adaptive_step.py`
83
+ - `step_methods.py`
84
+ - `variational.py`
85
+ - `step.py`
86
+ - `trajectory.py`
87
+ - `poincare.py`
88
+ - `stroboscopic.py`
89
+ - `maxima_map.py`
90
+ - `basins.py`
91
+ - `lyapunov.py`
92
+ - `sali.py`
93
+ - `ldi.py`
94
+ - `gali.py`
95
+ - `clv.py`
96
+ - `rte.py`
97
+ - `hurst.py`
98
+
99
+ - `hamiltonian_systems` module:
100
+ - Added dedicated low-level modules:
101
+ - `coefficients.py`
102
+ - `fixed_step.py`
103
+ - `tangent.py`
104
+ - `trajectory.py`
105
+ - `poincare.py`
106
+ - `lyapunov.py`
107
+ - `sali.py`
108
+ - `ldi.py`
109
+ - `gali.py`
110
+ - `clv.py`
111
+ - `rte.py`
112
+ - `hurst.py`
113
+
114
+ - `common.types`:
115
+ - Added `observable_t` type alias for weighted-Birkhoff observable functions.
116
+ - Added `flow_t` and `flow_jacobian_t` type aliases for continuous-time vector fields and their Jacobians.
117
+ - Added `grad_t` and `hess_t` type aliases for Hamiltonian gradients and Hessians.
118
+ - Added `symplectic_step_t` and `symplectic_tangent_step_t` type aliases for Hamiltonian fixed-step integrators and their tangent-map variants.
119
+
120
+ ### Changed
121
+
122
+ - Refactored low-level discrete-time analysis routines by splitting the old monolithic modules into dedicated files for improved project organization, readability, and maintainability.
123
+ - Refactored low-level continuous-time analysis routines by splitting the old monolithic modules into dedicated files for improved project organization, readability, and maintainability.
124
+ - Refactored low-level Hamiltonian-system analysis and integration routines by splitting the old monolithic modules into dedicated files for improved project organization, readability, and maintainability.
125
+
126
+ - `DiscreteDynamicalSystem` class:
127
+ - Updated wrappers across the discrete-time analysis API with improved type annotations, return annotations, argument validation, and docstrings.
128
+ - Standardized handling of `sample_times` in wrappers that support sampled outputs by explicitly validating user input and constructing internal sampling arrays only when needed.
129
+ - Updated `dig` observable validation so the observable must be callable and return a 1D NumPy array with one value per input state.
130
+ - Improved validation and normalization of wrapper inputs for periodic-orbit, manifold, transport, escape, Hurst, and recurrence diagnostics.
131
+ - The Lyapunov exponent API now exposes the analytical QR procedure (after Eckmann-Ruelle) explicitly through the `method` argument:
132
+ - `method="ER"` now selects the analytical QR-based approach (available only for 2D systems).
133
+ - `method="QR"` now consistently uses the modifed Gram-Schmidt QR decomposition, independent of system dimension.
134
+ - `method=QR_HH` uses Householder QR decomposition via `np.linalg.qr`.
135
+ - The previous implicit behavior where method="QR" automatically switched to the Eckmann–Ruelle algorithm for 2D systems has been removed. Existing code relying on this optimization should now explicitly set `ds.lyapunov(..., method="ER")`.
136
+
137
+ - `ContinuousDynamicalSystem` class:
138
+ - Reorganized imports and internal plumbing to use the new continuous-time module layout.
139
+ - Updated constructor, integrator configuration, and wrapper methods with improved type annotations, return annotations, argument validation, and docstrings.
140
+ - Standardized validation of continuous-time arguments by using dedicated time validation helpers and more explicit normalization of parameters and wrapper inputs.
141
+ - Updated trajectory-related wrappers to reflect adaptive-step behavior more faithfully when ensemble trajectories do not all share the same stored length.
142
+ - Updated Lyapunov-related return annotations and docstrings so the scalar `num_exponents=1` case is documented and handled consistently.
143
+
144
+ - `HamiltonianSystem` class:
145
+ - Reorganized imports and internal plumbing to use the new Hamiltonian-system module layout.
146
+ - Updated constructor, integrator configuration, and wrapper methods with improved type annotations, return annotations, argument validation, and docstrings.
147
+ - Standardized validation of Hamiltonian wrapper inputs for coordinates, momenta, parameters, section arguments, CLV configuration, and time-like arguments.
148
+ - Updated Lyapunov-, CLV-, SALI-, LDI-, GALI-, RTE-, Hurst-, trajectory-, and Poincaré-related wrappers to use the refactored low-level modules and more explicit scalar/array return semantics.
149
+
150
+ - `continuous_time.validators`:
151
+ - Refactored `validate_times()` to return validated `np.float64` values and to enforce stricter type and range checks for continuous-time arguments.
152
+
153
+ - `hamiltonian_systems.validators`:
154
+ - Refactored `validate_times()` and `validate_initial_conditions()` with stricter typing, shape checks, and `np.float64` normalization for Hamiltonian-system inputs.
155
+
156
+ - `common.validators`:
157
+ - Refactored `validate_clv_subspaces()` and `validate_clv_pairs()` to validate indices against `num_clvs` instead of the full system dimension.
158
+ - Improved normalization of single subspace and single pair inputs into canonical tuple-based representations.
159
+
160
+ - `common.utils`:
161
+ - Refactored the internal QR routine to a simpler reduced modified Gram-Schmidt implementation with manual inner products for better Numba compatibility and lower overhead.
162
+ - Simplified `householder_qr()` implementation.
163
+ - Temporarily kept shared CLV helper routines in `utils.py` because they are still used by the continuous and Hamiltonian classes during the refactor.
164
+ - Added typed `qr_truncate()` helper documentation and return annotations for CLV-related truncation logic.
165
+
166
+ ### Fixed
167
+
168
+ - `DiscreteDynamicalSystem` class:
169
+ - Fixed `SALI`, `LDI`, and `GALI` wrappers so that scalar outputs are returned consistently when `return_history=False`, while preserving the final state when `return_last_state=True`.
170
+ - Fixed `GALI` computation by using stable QR-based volume evaluation.
171
+ - Fixed `CLV_angles` validation so subspace and pair indices are checked against the number of computed CLVs rather than the ambient phase-space dimension.
172
+ - Removed a stray debug `print(iter_time)` from `manifold()`.
173
+ - Added validation to prevent the use of `method="ER"` for systems with dimension greater than 2, raising a clear error instead of silently falling back to another implementation.
174
+
175
+ - `ContinuousDynamicalSystem` class:
176
+ - Fixed wrapper regressions introduced during the continuous-time refactor in trajectory, reduced-map, Lyapunov, CLV, SALI, LDI, GALI, RTE, and Hurst-related methods.
177
+ - Fixed `trajectory()` return handling for ensembles evolved with adaptive integrators, where different initial conditions may produce trajectories with different numbers of stored time steps.
178
+ - Fixed `lyapunov()` so `method="QR_HH"` works correctly with the refactored low-level implementation.
179
+ - Fixed `lyapunov()` so `num_exponents=1` returns a scalar instead of a length-1 array when `return_history=False`.
180
+ - Fixed `GALI()` wrapper so the selected low-level computation method is validated and passed through correctly.
181
+
182
+ - `HamiltonianSystem` class:
183
+ - Fixed wrapper validation bugs in trajectory, Poincaré-section, Lyapunov, CLV, CLV-angle, SALI, LDI, GALI, RTE, and Hurst-related methods introduced during the Hamiltonian refactor.
184
+ - Fixed wrapper shape checks so coordinate and momentum arrays are validated by full shape compatibility rather than only by matching dimensionality.
185
+ - Fixed `lyapunov()` so `num_exponents=1` returns a scalar instead of a length-1 array when `return_history=False`.
186
+ - Fixed `GALI()` wrapper so the selected low-level computation method is validated and passed through correctly.
187
+ - Fixed section-index validation in Hamiltonian reduced-map wrappers so section coordinates are checked against the number of degrees of freedom rather than the full phase-space dimension where appropriate.
188
+
189
+ - `discrete_time` module:
190
+ - Fixed low-level `SALI`, `LDI`, and `GALI` implementations to return both the computed result and the final state consistently.
191
+ - Fixed history allocation and sampling logic in low-level `SALI`, `LDI`, and `GALI` implementations for `return_history=True`.
192
+ - Fixed the weighted-Birkhoff `dig` implementation to live in its own dedicated module while preserving wrapper behavior.
193
+ - Fixed dtype consistency in sampled transport routines to avoid Numba typing errors from mixing `int32` and `int64` sampling arrays.
194
+
195
+ - `continuous_time` module:
196
+ - Fixed QR-related low-level Lyapunov and GALI computations to handle Householder-based QR consistently under Numba.
197
+ - Fixed array contiguity issues in low-level QR-based continuous-time routines to avoid reshape/type failures after `numpy.linalg.qr`.
198
+
199
+ - `hamiltonian_systems` module:
200
+ - Fixed low-level Lyapunov and GALI computations to support both internal QR and Householder-based QR through method dispatch instead of passing unsupported callable QR objects into Numba-compiled routines.
201
+ - Fixed low-level trajectory and reduced-map helpers with clearer typing, stricter validation, and dedicated Poincaré-section extraction from stored trajectories.
202
+ - Fixed Hamiltonian recurrence-time-entropy returns by replacing dynamically assembled list-based returns with explicit tuple branches compatible with static typing.
203
+
204
+ - `common.validators`:
205
+ - Fixed `validate_positive()` so zero is rejected correctly.
206
+
207
+ [v1.5.4]: https://github.com/mrolims/pynamicalsys/compare/v1.5.3...v1.5.4
208
+
209
+ ## [v1.5.3] - 2026-04-08
210
+
211
+ ### Fixed
212
+
213
+ - Incorrect tangent drift update in symplectic (Verlet/Yoshida) integrators (used δq instead of δp in δq update)
214
+ - QR re-orthonormalization scheduling in Lyapunov spectrum (`(i + 1) % qr_interval`)
215
+ - History allocation using `round` instead of integer division
216
+ - Incorrect normalization of history array (time column was being scaled)
217
+
218
+ [v1.5.3]: https://github.com/mrolims/pynamicalsys/compare/v1.5.2...v1.5.3
219
+
220
+ ## [v1.5.2] - 2026-03-23
221
+
222
+ ### Fixed
223
+
224
+ - `DiscreteDynamicalSystem` class:
225
+ - Fixed parameter handling in `DiscreteDynamicalSystem.bifurcation_diagram()` when the system has no stored default parameters:
226
+ - user-provided parameters are now validated and the scanned parameter is inserted at `param_index`;
227
+ - if no parameters are provided, a default parameter array is initialized so the scanned parameter can be assigned correctly.
228
+
229
+ ### Changed
230
+
231
+ - Minor formatting cleanup in `logistic_map()`.
232
+
233
+ [v1.5.2]: https://github.com/mrolims/pynamicalsys/compare/v1.5.1...v1.5.2
234
+
235
+ ## [v1.5.1] - 2026-03-16
236
+
237
+ ### Added
238
+
239
+ - Support for fixed recurrence rate threshold selection via `fixed_rr=True`. When enabled, the recurrence threshold is automatically chosen such that the recurrence matrix achieves the desired recurrence rate (`threshold` interpreted as the target RR).
240
+
241
+ - Support for callable distance metrics for recurrence matrix computation and recurrence-rate threshold estimation. Custom metrics must have signature `metric(x, y) -> float` and must be Numba-compatible (decorated with `@numba.njit`).
242
+
243
+ - New `return_eps` option in `TimeSeriesMetrics.recurrence_matrix()` to return the threshold value used to construct the recurrence matrix.
244
+
245
+ ### Modifed
246
+
247
+ - Internal recurrence matrix computation has been refactored for improved performance and consistency between built-in metrics (supremum, euclidean, manhattan) and callable metrics.
248
+
249
+ - Threshold selection is now centralized in a new `calculate_threshold()` function, which handles
250
+ - direct thresholds.
251
+ - standard-deviation–scaled thresholds (`threshold_mode="std"`).
252
+ - fixed recurrence rate thresholds (`threshold_mode="rr"`).
253
+
254
+ [v1.5.1]: https://github.com/mrolims/pynamicalsys/compare/v1.5.0...v1.5.1
255
+
256
+ ## [v1.5.0] - 2026-01-07
257
+
258
+ ### Added
259
+
260
+ - Added two new methods, `set_parameters` and `get_parameters`, to each of the three main classes to improve parameter management. Parameters can now be set once via `set_parameters` and stored internally, allowing subsequent method calls to use the stored values without requiring parameters to be passed explicitly each time. Existing workflows remain fully backward compatible: methods that accept parameters directly continue to work as before.
261
+
262
+ - Added **Covariant Lyapunov Vector (CLV) angle diagnostics** to all three core system classes:
263
+ - The new methods `CLV` and `CLV_angles` allow computation of the **CLVs**, **angles between arbitrary CLV subspaces** and **pairwise CLV angles**, with full user control over:
264
+ - which subspaces are compared,
265
+ - which CLV pairs are measured.
266
+ - Support for **Poincaré-section–restricted CLV angles** in Hamiltonian systems, enabling angle analysis directly on the section.
267
+ - Angle diagnostics are based on **minimum principal angles between covariant subspaces**, providing a geometrically meaningful measure of hyperbolicity and near-tangencies in high-dimensional systems.
268
+
269
+ ### Modified
270
+
271
+ - The parameter validator now accepts empty lists for systems that take no parameters.
272
+
273
+ [v1.5.0]: https://github.com/mrolims/pynamicalsys/compare/v1.4.9...v1.5.0
274
+
275
+ ## [v1.4.9] - 2025-11-18
276
+
277
+ ### Fixed
278
+
279
+ - Fix missing dependency:
280
+ - Added `ipython (>=8.13,<9.0.0)` to `pyproject.toml` dependencies, since it is required by the `ContinuousDynamicalSystem` class.
281
+
282
+ [v1.4.9]: https://github.com/mrolims/pynamicalsys/compare/v1.4.1...v1.4.9
283
+
284
+ ## [v1.4.6] - 2025-10-09
285
+
286
+ ### Modified
287
+
288
+ - `HamiltonianSystem` class:
289
+ - Fixed the integration of the tangent vectors that was leading to numerical instability for long integration times.
290
+
291
+ - Refactored `recurrence_time_entropy` methods and `white_vertline_distr` function to handle the minimum line length parameter more consistently.
292
+
293
+ [v1.4.6]: https://github.com/mrolims/pynamicalsys/compare/v1.4.1...v1.4.6
294
+
295
+ ## [v1.4.5] - 2025-09-17
296
+
297
+ ### Modified
298
+
299
+ - `DiscreteDynamicalSystem` class:
300
+ - Fixed problems in the `finite_hurst_exponent`
301
+
302
+ - `ContinuousDynamicalSystem` and `HamiltonianSystem` classes:
303
+ - Fixed the output of the `recurrence_time_entropy` method when `return_final_state=True`.
304
+
305
+ [v1.4.5]: https://github.com/mrolims/pynamicalsys/compare/v1.4.1...v1.4.5
306
+
307
+ ## [v1.4.1] - 2025-09-15
308
+
309
+ ### Added
310
+
311
+ - `HamiltonianSystem` class for simulating and analyzing continuous-time Hamiltonian systems.
312
+ - Support for symplectic integration:
313
+ - 2nd-order velocity–Verlet
314
+ - 4th-order Yoshida
315
+ - Trajectory computation and ensemble trajectories.
316
+ - Poincaré section generation (single and ensemble).
317
+ - Chaos indicators:
318
+ - Lyapunov spectrum and maximum Lyapunov exponent.
319
+ - Smaller Alignment Index (SALI).
320
+ - Generalized Alignment Index (GALI).
321
+ - Linear Dependence Index (LDI).
322
+ - Recurrence time entropy (RTE).
323
+ - Hurst exponent.
324
+
325
+ - `ContinuousDynamicalSystem` class:
326
+ - `poincare_section` method: return the Poincaré section of a given initial condition or of an ensemble of initial conditions.
327
+ - `stroboscopic_map` method: return the stroboscopic map of a given initial condition or of an ensemble of initial conditions.
328
+ - `maxima_map` method: return the maxima map of a given initial condition or of an ensemble of inital conditions.
329
+ - `basin_of_attraction` method: given an ensemble of initial conditions, detect and label the attractors in the system.
330
+ - `recurrence_time_entropy` method: calculates the recurrence time entropy for a given initial condition using the Poincaré section, stroboscopic map, or maxima map to construct the recurrence matrix.
331
+ - `hurst_exponent` method: calculates the Hurst exponent for a given initial condition using the Poincaré section, stroboscopic map, or maxima map.
332
+
333
+ - `TimeSeriesMetrics`:
334
+ - `hurst_exponent` method.
335
+
336
+ ### Modified
337
+
338
+ - `DiscreteDynamicalSystem` class:
339
+ - Unified the Hurst exponent calculation into a single function.
340
+
341
+ - `ContinuousDynamicalSystem` class:
342
+ - `lyapunov` method now uses a specific function to compute only the maximum Lyapunov exponent when `num_exponents=1`.
343
+
344
+ [v1.4.1]: https://github.com/mrolims/pynamicalsys/compare/v1.3.1...v1.4.1
345
+
346
+ ## [v1.3.1] - 2025-08-24
347
+
348
+ ### Modified
349
+
350
+ - Removed `cache=True` from the low level methods that was leading to cache compilation errors.
351
+
352
+ [v1.3.1]: https://github.com/mrolims/pynamicalsys/compare/v1.3.0...v1.3.1
353
+
354
+ ## [v1.3.0] - 2025-08-23
355
+
356
+ ### Added
357
+
358
+ - `DiscreteDynamicalSystem` class:
359
+ - `step` method: returns the next state of the system.
360
+ - `GALI` method: computes the generalized alignment index (GALI).
361
+
362
+ - `ContinuousDynamicalSystem` class:
363
+ - `GALI` method that computes the generalized alignment index (GALI).
364
+
365
+ ### Modified
366
+
367
+ - `DiscreteDynamicalSystem` class:
368
+ - Improved performance when checking sampling points by avoiding repeated searches in sample_times.
369
+ - Refactored the `lyapunov` method to allow computing only a subset of the Lyapunov spectrum.
370
+
371
+ - `ContinuousDynamicalSystem` class:
372
+ - Unified integration step logic (previously duplicated across methods like trajectory and lyapunov_exponents) into a single step function.
373
+ - Refactored the `lyapunov` method to allow computing only a subset of the Lyapunov spectrum.
374
+
375
+ [v1.3.0]: https://github.com/mrolims/pynamicalsys/compare/v1.2.2...v1.3.0
376
+
377
+ ## [v1.2.2] - 2025-06-29
378
+
379
+ ### Added
380
+
381
+ - `ContinuousDynamicalSystem` class for simulating and analyzing continuous nonlinear dynamical systems:
382
+ - Integration using the 4th order Runge-Kutta method with fixed time step.
383
+ - Integration using the adaptive 4th/5th order Runge-Kutta method with adaptive time step.
384
+ - Trajectory computation.
385
+ - Lyapunov exponents calculation.
386
+ - The smaller aligment index (SALI) and linear dependence index (LDI) for chaos detection.
387
+
388
+ [v1.2.2]: https://github.com/mrolims/pynamicalsys/compare/v1.0.0...v1.2.2
389
+
390
+ ## v1.0.0 - 2025-06-16
391
+
392
+ ### Added
393
+
394
+ - `DiscreteDynamicalSystem` class for simulating and analyzing discrete nonlinear dynamical systems:
395
+ - Trajectory computation.
396
+ - Chaotic indicators.
397
+ - Fixed points, periodic orbits, and manifolds.
398
+ - Statistical analysis of ensemble of trajetories.
399
+ - Escape basin quantification.
400
+ - Initial release of the package
401
+ - First version of documentation
402
+ - Basic tests
403
+
404
+ - `BasinMetrics` class to compute basin metris such as basin entropy and boundary dimension.
405
+
406
+ - `TimeSeriesMetrics` class to compute metrics related to time series analysis.
407
+
408
+ - `PlotStyler` utility class to globally configure and apply consistent styling for Matplotlib plots.
409
+
410
+ <!-- Dummy heading to avoid ending on a transition -->
411
+
412
+ ##
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pynamicalsys
3
- Version: 1.5.3
3
+ Version: 1.6.0
4
4
  Summary: A Python toolkit for the analysis of dynamical systems
5
5
  Author-email: Matheus Rolim Sales <rolim.sales.m@gmail.com>
6
6
  License-Expression: GPL-3.0-only
@@ -1,6 +1,6 @@
1
1
  # __init__.py
2
2
 
3
- # Copyright (C) 2025 Matheus Rolim Sales
3
+ # Copyright (C) 2025-2026 Matheus Rolim Sales
4
4
  #
5
5
  # This program is free software: you can redistribute it and/or modify
6
6
  # it under the terms of the GNU General Public License as published by
@@ -16,6 +16,7 @@
16
16
  # along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
 
18
18
  from pynamicalsys.core.discrete_dynamical_systems import DiscreteDynamicalSystem
19
+
19
20
  from pynamicalsys.core.continuous_dynamical_systems import ContinuousDynamicalSystem
20
21
  from pynamicalsys.core.hamiltonian_systems import HamiltonianSystem
21
22
  from pynamicalsys.core.basin_metrics import BasinMetrics
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '1.5.3'
22
- __version_tuple__ = version_tuple = (1, 5, 3)
21
+ __version__ = version = '1.6.0'
22
+ __version_tuple__ = version_tuple = (1, 6, 0)
23
23
 
24
- __commit_id__ = commit_id = 'ge5f4a0776'
24
+ __commit_id__ = commit_id = 'g4ec6e167d'
@@ -0,0 +1,16 @@
1
+ # __init__.py
2
+ #
3
+ # Copyright (C) 2025-2026 Matheus Rolim Sales
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
@@ -1,6 +1,6 @@
1
1
  # basin_analysis.py
2
2
 
3
- # Copyright (C) 2025 Matheus Rolim Sales
3
+ # Copyright (C) 2025-2026 Matheus Rolim Sales
4
4
  #
5
5
  # This program is free software: you can redistribute it and/or modify
6
6
  # it under the terms of the GNU General Public License as published by
@@ -17,8 +17,9 @@
17
17
 
18
18
  import numpy as np
19
19
  from numba import njit, prange
20
- from typing import Optional, Tuple
20
+ from typing import Tuple
21
21
  from numpy.typing import NDArray
22
+ from joblib import delayed, Parallel
22
23
 
23
24
 
24
25
  def uncertainty_fraction(x, y, basin, epsilon_max, n_eps=100, epsilon_min=0):
@@ -168,3 +169,107 @@ def basin_entropy(
168
169
  Sbb = np.mean(S[boundary_mask]) if boundary_mask.any() else 0.0
169
170
 
170
171
  return float(Sb), float(Sbb)
172
+
173
+ def uncertainty_fraction_mapping(
174
+ X: NDArray[np.float64],
175
+ Y: NDArray[np.float64],
176
+ basin: NDArray[np.float64],
177
+ mapping: object,
178
+ parameters: object,
179
+ exits: object,
180
+ escape: str = "exiting",
181
+ n_samples: int = 120_000,
182
+ p_samples: int = 7,
183
+ threshold: float = 0.1,
184
+ n_eps: int = 100,
185
+ max_time: int = 1000,
186
+ seed: int = 13,
187
+ n_jobs: int = -1,
188
+ ) -> Tuple[NDArray[np.float64], NDArray[np.float64]]:
189
+ """
190
+ Wrapper to compute the uncertainty fraction f(epsilon) for a given basin of attraction with mapping.
191
+ """
192
+
193
+ rng = np.random.default_rng(seed)
194
+
195
+ flat_x = X.flatten()
196
+ flat_y = Y.flatten()
197
+ flat_basin = basin.flatten()
198
+
199
+ epsilons = np.logspace(np.log10(0.1), np.log10(1 / X.size), n_eps)
200
+
201
+ idx = rng.choice(len(flat_x), size=n_samples, replace=False)
202
+ xs = flat_x[idx]
203
+ ys = flat_y[idx]
204
+ labels = flat_basin[idx]
205
+
206
+ angles = np.linspace(0, 2 * np.pi, p_samples, endpoint=False)
207
+ dcos = np.cos(angles)
208
+ dsin = np.sin(angles)
209
+
210
+ needed = max(1, int(np.ceil(threshold * p_samples)))
211
+
212
+ ss = np.random.SeedSequence(seed)
213
+ child_seeds = ss.spawn(n_eps)
214
+
215
+ f_eps = Parallel(n_jobs=n_jobs)(
216
+ delayed(_process_single_epsilon)(
217
+ eps, xs, ys, labels, p_samples, dcos, dsin, needed,
218
+ mapping, max_time, parameters, exits, escape, n_samples,
219
+ child_seeds[i],
220
+ )
221
+ for i, eps in enumerate(epsilons)
222
+ )
223
+
224
+ return epsilons, f_eps
225
+
226
+
227
+ def _process_single_epsilon(
228
+ eps: float,
229
+ xs: NDArray[np.float64],
230
+ ys: NDArray[np.float64],
231
+ labels: NDArray[np.float64],
232
+ p_samples: int,
233
+ dcos: NDArray[np.float64],
234
+ dsin: NDArray[np.float64],
235
+ needed: int,
236
+ mapping: object,
237
+ max_time: int,
238
+ parameters: object,
239
+ exits: object,
240
+ escape: str,
241
+ n_samples: int,
242
+ child_seed: np.random.SeedSequence,
243
+ ) -> float:
244
+ """Worker function that computes the uncertainty fraction for a single
245
+ epsilon value.
246
+ """
247
+
248
+ rng = np.random.default_rng(child_seed)
249
+ uncertain = 0
250
+
251
+ for x, y, side_center in zip(xs, ys, labels):
252
+ u_rand = rng.random(p_samples)
253
+ r = eps * np.sqrt(u_rand)
254
+ x_eps = x + r * dcos
255
+ y_eps = y + r * dsin
256
+
257
+ different = 0
258
+ for xp, yp in zip(x_eps, y_eps):
259
+ side_p, _ = mapping.escape_analysis(
260
+ u=(xp, yp),
261
+ max_time=max_time,
262
+ parameters=parameters,
263
+ exits=exits,
264
+ escape=escape,
265
+ )
266
+ if side_p != side_center:
267
+ different += 1
268
+ if different >= needed:
269
+ break
270
+
271
+ if different >= needed:
272
+ uncertain += 1
273
+
274
+ return uncertain / n_samples
275
+