dynlib 0.37.4__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 (114) hide show
  1. dynlib/__init__.py +96 -0
  2. dynlib/analysis/__init__.py +202 -0
  3. dynlib/analysis/basin.py +498 -0
  4. dynlib/analysis/basin_auto.py +2282 -0
  5. dynlib/analysis/basin_codes.py +9 -0
  6. dynlib/analysis/basin_known.py +2207 -0
  7. dynlib/analysis/basin_stats.py +247 -0
  8. dynlib/analysis/fixed_points.py +297 -0
  9. dynlib/analysis/manifold.py +6858 -0
  10. dynlib/analysis/post/__init__.py +11 -0
  11. dynlib/analysis/post/bifurcation.py +427 -0
  12. dynlib/analysis/post/trajectory.py +465 -0
  13. dynlib/analysis/sweep.py +1795 -0
  14. dynlib/cli.py +347 -0
  15. dynlib/compiler/__init__.py +12 -0
  16. dynlib/compiler/build.py +1443 -0
  17. dynlib/compiler/codegen/__init__.py +4 -0
  18. dynlib/compiler/codegen/_runner_cache.py +338 -0
  19. dynlib/compiler/codegen/cache_importer.py +142 -0
  20. dynlib/compiler/codegen/emitter.py +723 -0
  21. dynlib/compiler/codegen/rewrite.py +735 -0
  22. dynlib/compiler/codegen/runner_cache.py +681 -0
  23. dynlib/compiler/codegen/runner_variants.py +2515 -0
  24. dynlib/compiler/codegen/validate.py +227 -0
  25. dynlib/compiler/guards.py +304 -0
  26. dynlib/compiler/jit/__init__.py +0 -0
  27. dynlib/compiler/jit/cache.py +27 -0
  28. dynlib/compiler/jit/compile.py +132 -0
  29. dynlib/compiler/mods.py +336 -0
  30. dynlib/compiler/paths.py +488 -0
  31. dynlib/dsl/__init__.py +0 -0
  32. dynlib/dsl/astcheck.py +757 -0
  33. dynlib/dsl/constants.py +48 -0
  34. dynlib/dsl/parser.py +382 -0
  35. dynlib/dsl/schema.py +279 -0
  36. dynlib/dsl/spec.py +396 -0
  37. dynlib/errors.py +98 -0
  38. dynlib/mkdocs_helpers.py +114 -0
  39. dynlib/models/__init__.py +7 -0
  40. dynlib/models/map/henon.toml +23 -0
  41. dynlib/models/map/henon2.toml +28 -0
  42. dynlib/models/map/ikeda.toml +22 -0
  43. dynlib/models/map/logistic.toml +17 -0
  44. dynlib/models/map/lozi.toml +17 -0
  45. dynlib/models/map/sine.toml +20 -0
  46. dynlib/models/map/standard.toml +22 -0
  47. dynlib/models/ode/duffing.toml +25 -0
  48. dynlib/models/ode/eto-circular.toml +27 -0
  49. dynlib/models/ode/exp-if.toml +22 -0
  50. dynlib/models/ode/expdecay.toml +20 -0
  51. dynlib/models/ode/fitzhugh-nagumo.toml +28 -0
  52. dynlib/models/ode/hodgkin-huxley.toml +72 -0
  53. dynlib/models/ode/izhikevich.toml +65 -0
  54. dynlib/models/ode/leaky-if.toml +20 -0
  55. dynlib/models/ode/lorenz.toml +26 -0
  56. dynlib/models/ode/quadratic-if.toml +22 -0
  57. dynlib/models/ode/resonate-if.toml +38 -0
  58. dynlib/models/ode/vanderpol.toml +21 -0
  59. dynlib/plot/__init__.py +67 -0
  60. dynlib/plot/_export.py +107 -0
  61. dynlib/plot/_facet.py +17 -0
  62. dynlib/plot/_fig.py +113 -0
  63. dynlib/plot/_primitives.py +2140 -0
  64. dynlib/plot/_theme.py +451 -0
  65. dynlib/plot/basin.py +334 -0
  66. dynlib/plot/bifurcation.py +137 -0
  67. dynlib/plot/dynamics.py +160 -0
  68. dynlib/plot/vectorfield.py +1502 -0
  69. dynlib/runtime/__init__.py +0 -0
  70. dynlib/runtime/analysis_meta.py +64 -0
  71. dynlib/runtime/buffers.py +155 -0
  72. dynlib/runtime/fastpath/__init__.py +49 -0
  73. dynlib/runtime/fastpath/capability.py +112 -0
  74. dynlib/runtime/fastpath/executor.py +1273 -0
  75. dynlib/runtime/fastpath/plans.py +149 -0
  76. dynlib/runtime/initial_step.py +145 -0
  77. dynlib/runtime/observers/__init__.py +51 -0
  78. dynlib/runtime/observers/core.py +713 -0
  79. dynlib/runtime/observers/lyapunov.py +1510 -0
  80. dynlib/runtime/results.py +259 -0
  81. dynlib/runtime/results_api.py +1007 -0
  82. dynlib/runtime/runner_api.py +180 -0
  83. dynlib/runtime/sim.py +3144 -0
  84. dynlib/runtime/softdeps.py +96 -0
  85. dynlib/runtime/stepper_checks.py +86 -0
  86. dynlib/runtime/types.py +9 -0
  87. dynlib/runtime/workspace.py +160 -0
  88. dynlib/runtime/wrapper.py +497 -0
  89. dynlib/steppers/__init__.py +15 -0
  90. dynlib/steppers/base.py +170 -0
  91. dynlib/steppers/config_base.py +148 -0
  92. dynlib/steppers/config_utils.py +229 -0
  93. dynlib/steppers/discrete/__init__.py +0 -0
  94. dynlib/steppers/discrete/map.py +108 -0
  95. dynlib/steppers/ode/__init__.py +0 -0
  96. dynlib/steppers/ode/ab2.py +240 -0
  97. dynlib/steppers/ode/ab3.py +320 -0
  98. dynlib/steppers/ode/bdf2.py +380 -0
  99. dynlib/steppers/ode/bdf2a.py +623 -0
  100. dynlib/steppers/ode/euler.py +199 -0
  101. dynlib/steppers/ode/rk2_midpoint.py +257 -0
  102. dynlib/steppers/ode/rk4.py +365 -0
  103. dynlib/steppers/ode/rk45.py +402 -0
  104. dynlib/steppers/ode/sdirk2.py +587 -0
  105. dynlib/steppers/ode/tr_bdf2a.py +616 -0
  106. dynlib/steppers/registry.py +167 -0
  107. dynlib/utils/__init__.py +3 -0
  108. dynlib/utils/timer.py +17 -0
  109. dynlib-0.37.4.dist-info/METADATA +119 -0
  110. dynlib-0.37.4.dist-info/RECORD +114 -0
  111. dynlib-0.37.4.dist-info/WHEEL +5 -0
  112. dynlib-0.37.4.dist-info/entry_points.txt +2 -0
  113. dynlib-0.37.4.dist-info/licenses/LICENSE +29 -0
  114. dynlib-0.37.4.dist-info/top_level.txt +1 -0
dynlib/__init__.py ADDED
@@ -0,0 +1,96 @@
1
+ # src/dynlib/__init__.py
2
+ from __future__ import annotations
3
+
4
+ # Re-export frozen constants/types for stable imports
5
+ from dynlib.runtime.runner_api import (
6
+ Status, OK, STEPFAIL, NAN_DETECTED, DONE, GROW_REC, GROW_EVT, USER_BREAK,
7
+ )
8
+
9
+ from .steppers.registry import register, get_stepper, registry, select_steppers, list_steppers
10
+ from .compiler.build import build
11
+ from .runtime.sim import Sim
12
+
13
+
14
+ __all__ = [
15
+ # Core entry points
16
+ "build", "setup", "Sim", "plot",
17
+ # Status codes (for advanced use)
18
+ "Status", "OK", "STEPFAIL", "NAN_DETECTED", "DONE", "GROW_REC", "GROW_EVT", "USER_BREAK",
19
+ # Results
20
+ "Results",
21
+ # Stepper registry
22
+ "list_steppers", "select_steppers", "get_stepper", "register", "registry",
23
+ ]
24
+
25
+
26
+ def setup(
27
+ model, *,
28
+ stepper=None,
29
+ mods=None,
30
+ jit=False,
31
+ dtype=None,
32
+ disk_cache=False,
33
+ config=None,
34
+ validate_stepper=True,
35
+ ) -> Sim:
36
+ """Compile and setup a simulation in one call.
37
+
38
+ This is a convenience function that combines the `build()` and `Sim()`
39
+ calls into a single step. It compiles the provided model and initializes
40
+ a simulation instance with the specified stepper and configuration.
41
+
42
+ For most users, this is the recommended entry point. Advanced users who
43
+ need to inspect or modify the compiled model before simulation should use
44
+ `build()` and `Sim()` separately.
45
+
46
+ The compiled model remains accessible via the returned `Sim` instance's
47
+ `model` attribute for advanced use cases.
48
+
49
+ Parameters:
50
+ model: The model to be compiled (ModelSpec or URI string).
51
+ stepper: The stepper to use for the simulation (e.g., "euler", "rk4", "rk45").
52
+ If None, uses the model's sim.stepper default.
53
+ mods: Optional list of mod URIs to apply during compilation.
54
+ jit: Whether to use JIT compilation (default False).
55
+ dtype: The data type for computations. If None (default), uses the dtype from the model spec.
56
+ disk_cache: Whether to use disk caching for compiled models (default False).
57
+ config: Optional PathConfig for URI resolution.
58
+ validate_stepper: Whether to validate the stepper against the model (default True).
59
+
60
+ Returns:
61
+ An instance of `Sim` initialized with the compiled model.
62
+
63
+ Example:
64
+ Simple usage with inline model::
65
+
66
+ from dynlib import setup
67
+
68
+ sim = setup(model_uri, stepper="euler", jit=True)
69
+ sim.run(T=10.0)
70
+ results = sim.results()
71
+
72
+ Equivalent manual approach for advanced use::
73
+
74
+ from dynlib import build, Sim
75
+
76
+ model = build(model_uri, stepper="euler", jit=True)
77
+ # Inspect or modify model here if needed
78
+ sim = Sim(model)
79
+ sim.run(T=10.0)
80
+
81
+ See Also:
82
+ build : Compile a model without creating a Sim instance.
83
+ Sim : Simulation facade for compiled models.
84
+ """
85
+ compiled_model = build(
86
+ model,
87
+ stepper=stepper,
88
+ mods=mods,
89
+ jit=jit,
90
+ dtype=dtype,
91
+ disk_cache=disk_cache,
92
+ config=config,
93
+ validate_stepper=validate_stepper,
94
+ )
95
+ sim = Sim(compiled_model)
96
+ return sim
@@ -0,0 +1,202 @@
1
+ """Offline analysis namespace for dynlib."""
2
+
3
+ import importlib
4
+ from typing import TYPE_CHECKING
5
+
6
+ if TYPE_CHECKING:
7
+ from dynlib.analysis.basin import (
8
+ BLOWUP,
9
+ OUTSIDE,
10
+ UNRESOLVED,
11
+ Attractor,
12
+ BasinResult,
13
+ FixedPoint,
14
+ ReferenceRun,
15
+ KnownAttractorLibrary,
16
+ build_known_attractors_psc,
17
+ )
18
+ from dynlib.analysis.basin_auto import basin_auto
19
+ from dynlib.analysis.basin_known import basin_known
20
+ from dynlib.analysis.basin_stats import (
21
+ BasinStats,
22
+ AttractorStats,
23
+ basin_stats,
24
+ basin_summary,
25
+ print_basin_summary,
26
+ )
27
+ from dynlib.analysis.sweep import (
28
+ SweepResult,
29
+ TrajectoryPayload,
30
+ scalar_sweep,
31
+ traj_sweep,
32
+ lyapunov_mle_sweep,
33
+ lyapunov_spectrum_sweep,
34
+ )
35
+ from dynlib.analysis.post import (
36
+ BifurcationResult,
37
+ BifurcationExtractor,
38
+ TrajectoryAnalyzer,
39
+ MultiVarAnalyzer,
40
+ )
41
+ from dynlib.analysis.fixed_points import (
42
+ FixedPointConfig,
43
+ FixedPointResult,
44
+ find_fixed_points,
45
+ )
46
+ from dynlib.analysis.manifold import (
47
+ ManifoldTraceResult,
48
+ trace_manifold_1d_map,
49
+ trace_manifold_1d_ode,
50
+ HeteroclinicRK45Config,
51
+ HeteroclinicBranchConfig,
52
+ HeteroclinicFinderConfig2D,
53
+ HeteroclinicFinderConfigND,
54
+ HeteroclinicTraceEvent,
55
+ HeteroclinicMissResult2D,
56
+ HeteroclinicMissResultND,
57
+ HeteroclinicFinderResult,
58
+ HeteroclinicTraceMeta,
59
+ HeteroclinicTraceResult,
60
+ HeteroclinicPreset,
61
+ heteroclinic_finder,
62
+ heteroclinic_tracer,
63
+ HomoclinicRK45Config,
64
+ HomoclinicBranchConfig,
65
+ HomoclinicFinderConfig,
66
+ HomoclinicMissResult,
67
+ HomoclinicFinderResult,
68
+ HomoclinicTraceEvent,
69
+ HomoclinicTraceMeta,
70
+ HomoclinicTraceResult,
71
+ HomoclinicPreset,
72
+ homoclinic_finder,
73
+ homoclinic_tracer,
74
+ )
75
+
76
+ _SWEEP_EXPORTS = {
77
+ "SweepResult",
78
+ "TrajectoryPayload",
79
+ "scalar_sweep",
80
+ "traj_sweep",
81
+ "lyapunov_mle_sweep",
82
+ "lyapunov_spectrum_sweep",
83
+ }
84
+
85
+ _POST_EXPORTS = {
86
+ "BifurcationResult",
87
+ "BifurcationExtractor",
88
+ "TrajectoryAnalyzer",
89
+ "MultiVarAnalyzer",
90
+ }
91
+
92
+ _BASIN_EXPORTS = {
93
+ "BLOWUP",
94
+ "OUTSIDE",
95
+ "UNRESOLVED",
96
+ "Attractor",
97
+ "BasinResult",
98
+ "FixedPoint",
99
+ "ReferenceRun",
100
+ "KnownAttractorLibrary",
101
+ "basin_auto",
102
+ "build_known_attractors_psc",
103
+ "basin_known",
104
+ }
105
+
106
+ _BASIN_STATS_EXPORTS = {
107
+ "BasinStats",
108
+ "AttractorStats",
109
+ "basin_stats",
110
+ "basin_summary",
111
+ "print_basin_summary",
112
+ }
113
+
114
+ _FIXED_POINT_EXPORTS = {
115
+ "FixedPointConfig",
116
+ "FixedPointResult",
117
+ "find_fixed_points",
118
+ }
119
+
120
+ _MANIFOLD_EXPORTS = {
121
+ "ManifoldTraceResult",
122
+ "trace_manifold_1d_map",
123
+ "trace_manifold_1d_ode",
124
+ "HeteroclinicRK45Config",
125
+ "HeteroclinicBranchConfig",
126
+ "HeteroclinicFinderConfig2D",
127
+ "HeteroclinicFinderConfigND",
128
+ "HeteroclinicTraceEvent",
129
+ "HeteroclinicMissResult2D",
130
+ "HeteroclinicMissResultND",
131
+ "HeteroclinicFinderResult",
132
+ "HeteroclinicTraceMeta",
133
+ "HeteroclinicTraceResult",
134
+ "HeteroclinicPreset",
135
+ "heteroclinic_finder",
136
+ "heteroclinic_tracer",
137
+ "HomoclinicRK45Config",
138
+ "HomoclinicBranchConfig",
139
+ "HomoclinicFinderConfig",
140
+ "HomoclinicMissResult",
141
+ "HomoclinicFinderResult",
142
+ "HomoclinicTraceEvent",
143
+ "HomoclinicTraceMeta",
144
+ "HomoclinicTraceResult",
145
+ "HomoclinicPreset",
146
+ "homoclinic_finder",
147
+ "homoclinic_tracer",
148
+ }
149
+
150
+ __all__ = [
151
+ # Sweep orchestration
152
+ *_SWEEP_EXPORTS,
153
+ # Post-run analysis
154
+ *_POST_EXPORTS,
155
+ # Basin analysis
156
+ *_BASIN_EXPORTS,
157
+ # Basin statistics
158
+ *_BASIN_STATS_EXPORTS,
159
+ # Fixed points
160
+ *_FIXED_POINT_EXPORTS,
161
+ # Manifold tracing
162
+ *_MANIFOLD_EXPORTS,
163
+ ]
164
+
165
+
166
+ def __getattr__(name):
167
+ if name in _SWEEP_EXPORTS:
168
+ module = importlib.import_module("dynlib.analysis.sweep")
169
+ value = getattr(module, name)
170
+ globals()[name] = value
171
+ return value
172
+ if name in _POST_EXPORTS:
173
+ module = importlib.import_module("dynlib.analysis.post")
174
+ value = getattr(module, name)
175
+ globals()[name] = value
176
+ return value
177
+ if name in _BASIN_EXPORTS:
178
+ if name == "basin_auto":
179
+ module = importlib.import_module("dynlib.analysis.basin_auto")
180
+ elif name == "basin_known":
181
+ module = importlib.import_module("dynlib.analysis.basin_known")
182
+ else:
183
+ module = importlib.import_module("dynlib.analysis.basin")
184
+ value = getattr(module, name)
185
+ globals()[name] = value
186
+ return value
187
+ if name in _BASIN_STATS_EXPORTS:
188
+ module = importlib.import_module("dynlib.analysis.basin_stats")
189
+ value = getattr(module, name)
190
+ globals()[name] = value
191
+ return value
192
+ if name in _FIXED_POINT_EXPORTS:
193
+ module = importlib.import_module("dynlib.analysis.fixed_points")
194
+ value = getattr(module, name)
195
+ globals()[name] = value
196
+ return value
197
+ if name in _MANIFOLD_EXPORTS:
198
+ module = importlib.import_module("dynlib.analysis.manifold")
199
+ value = getattr(module, name)
200
+ globals()[name] = value
201
+ return value
202
+ raise AttributeError(f"module 'dynlib.analysis' has no attribute '{name}'")