dynlib 0.37.4__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 (119) hide show
  1. dynlib-0.37.4/LICENSE +29 -0
  2. dynlib-0.37.4/PKG-INFO +119 -0
  3. dynlib-0.37.4/README.md +93 -0
  4. dynlib-0.37.4/pyproject.toml +37 -0
  5. dynlib-0.37.4/setup.cfg +4 -0
  6. dynlib-0.37.4/src/dynlib/__init__.py +96 -0
  7. dynlib-0.37.4/src/dynlib/analysis/__init__.py +202 -0
  8. dynlib-0.37.4/src/dynlib/analysis/basin.py +498 -0
  9. dynlib-0.37.4/src/dynlib/analysis/basin_auto.py +2282 -0
  10. dynlib-0.37.4/src/dynlib/analysis/basin_codes.py +9 -0
  11. dynlib-0.37.4/src/dynlib/analysis/basin_known.py +2207 -0
  12. dynlib-0.37.4/src/dynlib/analysis/basin_stats.py +247 -0
  13. dynlib-0.37.4/src/dynlib/analysis/fixed_points.py +297 -0
  14. dynlib-0.37.4/src/dynlib/analysis/manifold.py +6858 -0
  15. dynlib-0.37.4/src/dynlib/analysis/post/__init__.py +11 -0
  16. dynlib-0.37.4/src/dynlib/analysis/post/bifurcation.py +427 -0
  17. dynlib-0.37.4/src/dynlib/analysis/post/trajectory.py +465 -0
  18. dynlib-0.37.4/src/dynlib/analysis/sweep.py +1795 -0
  19. dynlib-0.37.4/src/dynlib/cli.py +347 -0
  20. dynlib-0.37.4/src/dynlib/compiler/__init__.py +12 -0
  21. dynlib-0.37.4/src/dynlib/compiler/build.py +1443 -0
  22. dynlib-0.37.4/src/dynlib/compiler/codegen/__init__.py +4 -0
  23. dynlib-0.37.4/src/dynlib/compiler/codegen/_runner_cache.py +338 -0
  24. dynlib-0.37.4/src/dynlib/compiler/codegen/cache_importer.py +142 -0
  25. dynlib-0.37.4/src/dynlib/compiler/codegen/emitter.py +723 -0
  26. dynlib-0.37.4/src/dynlib/compiler/codegen/rewrite.py +735 -0
  27. dynlib-0.37.4/src/dynlib/compiler/codegen/runner_cache.py +681 -0
  28. dynlib-0.37.4/src/dynlib/compiler/codegen/runner_variants.py +2515 -0
  29. dynlib-0.37.4/src/dynlib/compiler/codegen/validate.py +227 -0
  30. dynlib-0.37.4/src/dynlib/compiler/guards.py +304 -0
  31. dynlib-0.37.4/src/dynlib/compiler/jit/__init__.py +0 -0
  32. dynlib-0.37.4/src/dynlib/compiler/jit/cache.py +27 -0
  33. dynlib-0.37.4/src/dynlib/compiler/jit/compile.py +132 -0
  34. dynlib-0.37.4/src/dynlib/compiler/mods.py +336 -0
  35. dynlib-0.37.4/src/dynlib/compiler/paths.py +488 -0
  36. dynlib-0.37.4/src/dynlib/dsl/__init__.py +0 -0
  37. dynlib-0.37.4/src/dynlib/dsl/astcheck.py +757 -0
  38. dynlib-0.37.4/src/dynlib/dsl/constants.py +48 -0
  39. dynlib-0.37.4/src/dynlib/dsl/parser.py +382 -0
  40. dynlib-0.37.4/src/dynlib/dsl/schema.py +279 -0
  41. dynlib-0.37.4/src/dynlib/dsl/spec.py +396 -0
  42. dynlib-0.37.4/src/dynlib/errors.py +98 -0
  43. dynlib-0.37.4/src/dynlib/mkdocs_helpers.py +114 -0
  44. dynlib-0.37.4/src/dynlib/models/__init__.py +7 -0
  45. dynlib-0.37.4/src/dynlib/models/map/henon.toml +23 -0
  46. dynlib-0.37.4/src/dynlib/models/map/henon2.toml +28 -0
  47. dynlib-0.37.4/src/dynlib/models/map/ikeda.toml +22 -0
  48. dynlib-0.37.4/src/dynlib/models/map/logistic.toml +17 -0
  49. dynlib-0.37.4/src/dynlib/models/map/lozi.toml +17 -0
  50. dynlib-0.37.4/src/dynlib/models/map/sine.toml +20 -0
  51. dynlib-0.37.4/src/dynlib/models/map/standard.toml +22 -0
  52. dynlib-0.37.4/src/dynlib/models/ode/duffing.toml +25 -0
  53. dynlib-0.37.4/src/dynlib/models/ode/eto-circular.toml +27 -0
  54. dynlib-0.37.4/src/dynlib/models/ode/exp-if.toml +22 -0
  55. dynlib-0.37.4/src/dynlib/models/ode/expdecay.toml +20 -0
  56. dynlib-0.37.4/src/dynlib/models/ode/fitzhugh-nagumo.toml +28 -0
  57. dynlib-0.37.4/src/dynlib/models/ode/hodgkin-huxley.toml +72 -0
  58. dynlib-0.37.4/src/dynlib/models/ode/izhikevich.toml +65 -0
  59. dynlib-0.37.4/src/dynlib/models/ode/leaky-if.toml +20 -0
  60. dynlib-0.37.4/src/dynlib/models/ode/lorenz.toml +26 -0
  61. dynlib-0.37.4/src/dynlib/models/ode/quadratic-if.toml +22 -0
  62. dynlib-0.37.4/src/dynlib/models/ode/resonate-if.toml +38 -0
  63. dynlib-0.37.4/src/dynlib/models/ode/vanderpol.toml +21 -0
  64. dynlib-0.37.4/src/dynlib/plot/__init__.py +67 -0
  65. dynlib-0.37.4/src/dynlib/plot/_export.py +107 -0
  66. dynlib-0.37.4/src/dynlib/plot/_facet.py +17 -0
  67. dynlib-0.37.4/src/dynlib/plot/_fig.py +113 -0
  68. dynlib-0.37.4/src/dynlib/plot/_primitives.py +2140 -0
  69. dynlib-0.37.4/src/dynlib/plot/_theme.py +451 -0
  70. dynlib-0.37.4/src/dynlib/plot/basin.py +334 -0
  71. dynlib-0.37.4/src/dynlib/plot/bifurcation.py +137 -0
  72. dynlib-0.37.4/src/dynlib/plot/dynamics.py +160 -0
  73. dynlib-0.37.4/src/dynlib/plot/vectorfield.py +1502 -0
  74. dynlib-0.37.4/src/dynlib/runtime/__init__.py +0 -0
  75. dynlib-0.37.4/src/dynlib/runtime/analysis_meta.py +64 -0
  76. dynlib-0.37.4/src/dynlib/runtime/buffers.py +155 -0
  77. dynlib-0.37.4/src/dynlib/runtime/fastpath/__init__.py +49 -0
  78. dynlib-0.37.4/src/dynlib/runtime/fastpath/capability.py +112 -0
  79. dynlib-0.37.4/src/dynlib/runtime/fastpath/executor.py +1273 -0
  80. dynlib-0.37.4/src/dynlib/runtime/fastpath/plans.py +149 -0
  81. dynlib-0.37.4/src/dynlib/runtime/initial_step.py +145 -0
  82. dynlib-0.37.4/src/dynlib/runtime/observers/__init__.py +51 -0
  83. dynlib-0.37.4/src/dynlib/runtime/observers/core.py +713 -0
  84. dynlib-0.37.4/src/dynlib/runtime/observers/lyapunov.py +1510 -0
  85. dynlib-0.37.4/src/dynlib/runtime/results.py +259 -0
  86. dynlib-0.37.4/src/dynlib/runtime/results_api.py +1007 -0
  87. dynlib-0.37.4/src/dynlib/runtime/runner_api.py +180 -0
  88. dynlib-0.37.4/src/dynlib/runtime/sim.py +3144 -0
  89. dynlib-0.37.4/src/dynlib/runtime/softdeps.py +96 -0
  90. dynlib-0.37.4/src/dynlib/runtime/stepper_checks.py +86 -0
  91. dynlib-0.37.4/src/dynlib/runtime/types.py +9 -0
  92. dynlib-0.37.4/src/dynlib/runtime/workspace.py +160 -0
  93. dynlib-0.37.4/src/dynlib/runtime/wrapper.py +497 -0
  94. dynlib-0.37.4/src/dynlib/steppers/__init__.py +15 -0
  95. dynlib-0.37.4/src/dynlib/steppers/base.py +170 -0
  96. dynlib-0.37.4/src/dynlib/steppers/config_base.py +148 -0
  97. dynlib-0.37.4/src/dynlib/steppers/config_utils.py +229 -0
  98. dynlib-0.37.4/src/dynlib/steppers/discrete/__init__.py +0 -0
  99. dynlib-0.37.4/src/dynlib/steppers/discrete/map.py +108 -0
  100. dynlib-0.37.4/src/dynlib/steppers/ode/__init__.py +0 -0
  101. dynlib-0.37.4/src/dynlib/steppers/ode/ab2.py +240 -0
  102. dynlib-0.37.4/src/dynlib/steppers/ode/ab3.py +320 -0
  103. dynlib-0.37.4/src/dynlib/steppers/ode/bdf2.py +380 -0
  104. dynlib-0.37.4/src/dynlib/steppers/ode/bdf2a.py +623 -0
  105. dynlib-0.37.4/src/dynlib/steppers/ode/euler.py +199 -0
  106. dynlib-0.37.4/src/dynlib/steppers/ode/rk2_midpoint.py +257 -0
  107. dynlib-0.37.4/src/dynlib/steppers/ode/rk4.py +365 -0
  108. dynlib-0.37.4/src/dynlib/steppers/ode/rk45.py +402 -0
  109. dynlib-0.37.4/src/dynlib/steppers/ode/sdirk2.py +587 -0
  110. dynlib-0.37.4/src/dynlib/steppers/ode/tr_bdf2a.py +616 -0
  111. dynlib-0.37.4/src/dynlib/steppers/registry.py +167 -0
  112. dynlib-0.37.4/src/dynlib/utils/__init__.py +3 -0
  113. dynlib-0.37.4/src/dynlib/utils/timer.py +17 -0
  114. dynlib-0.37.4/src/dynlib.egg-info/PKG-INFO +119 -0
  115. dynlib-0.37.4/src/dynlib.egg-info/SOURCES.txt +117 -0
  116. dynlib-0.37.4/src/dynlib.egg-info/dependency_links.txt +1 -0
  117. dynlib-0.37.4/src/dynlib.egg-info/entry_points.txt +2 -0
  118. dynlib-0.37.4/src/dynlib.egg-info/requires.txt +13 -0
  119. dynlib-0.37.4/src/dynlib.egg-info/top_level.txt +1 -0
dynlib-0.37.4/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, İsmail Öztürk
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dynlib-0.37.4/PKG-INFO ADDED
@@ -0,0 +1,119 @@
1
+ Metadata-Version: 2.4
2
+ Name: dynlib
3
+ Version: 0.37.4
4
+ Summary: A dynamical systems simulation library.
5
+ Author-email: İsmail Öztürk <ismail.ozturk@amasya.edu.tr>
6
+ License-Expression: BSD-3-Clause
7
+ Keywords: ODE,dynamical-systems,simulation
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Science/Research
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
12
+ Requires-Python: >=3.10
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: numpy>=1.24
16
+ Provides-Extra: jit
17
+ Requires-Dist: numba>=0.57.1; extra == "jit"
18
+ Provides-Extra: plot
19
+ Requires-Dist: matplotlib>=3.7; extra == "plot"
20
+ Provides-Extra: dev
21
+ Requires-Dist: pytest>=7; extra == "dev"
22
+ Requires-Dist: scipy>=1.9; extra == "dev"
23
+ Requires-Dist: matplotlib>=3.7; extra == "dev"
24
+ Requires-Dist: numba>=0.57.1; extra == "dev"
25
+ Dynamic: license-file
26
+
27
+ # dynlib
28
+
29
+ Dynlib is a Python library for **modeling, simulating, and analyzing dynamical systems**.
30
+ Models are described in a TOML-based DSL (Domain-Specific Language) and then executed through a unified runtime—so you can iterate on solvers, parameters, and analyses without rewriting the same Numpy/Matplotlib plumbing for every experiment.
31
+
32
+ With dynlib, you can define or tweak a model, try different solvers/settings, and visualize behavior quickly. It can be used with notebooks for teaching and demonstration purposes. Created models can be kept in an organized manner and can be shared easily.
33
+
34
+ ## Project status
35
+
36
+ Dynlib is **alpha-stage** software. APIs may change, and numerical edge cases or bugs can surface. Treat results as exploratory unless you validate them (e.g., alternative steppers, tighter tolerances, smaller step sizes, or analytical checks). If you find suspicious behavior, please open an issue with a minimal reproducer.
37
+
38
+ ## Highlights
39
+
40
+ ### Modeling (TOML DSL)
41
+ - Define **ODEs** and **discrete-time maps** using a declarative TOML spec.
42
+ - Express equations, parameters, state initialization, and metadata in a consistent format.
43
+ - Support for **events**, **auxiliary variables**, **functions/macros**, and **lagging** where applicable.
44
+ - Built-in **model registry** and URI loading (including `builtin://...` models).
45
+
46
+ ### Simulation runtime
47
+ - Multiple stepper families:
48
+ - ODE: Euler, RK4, RK45, Adams–Bashforth (AB2/AB3), and implicit methods (e.g., SDIRK/TR-BDF2).
49
+ - Maps: dedicated discrete runner(s) including integer-safe modes.
50
+ - Runner variants and session introspection utilities for iterative workflows.
51
+ - **JIT acceleration** via Numba (optional but highly recommended), plus **disk caching** for compiled runners.
52
+ - **Snapshots and resume** support for long or staged simulations.
53
+ - Selective recording and result APIs designed for downstream analysis.
54
+
55
+ ### Analysis
56
+ Built-in analysis utilities for common dynamical-systems tasks:
57
+ - **Bifurcation** and post-processing utilities
58
+ - **Basins of attraction** (auto/known variants)
59
+ - **Lyapunov exponent** analysis (including runtime observer support)
60
+ - **Fixed point / Equilibria** detection
61
+ - **Manifold** tracing tools (currently limited to 1D manifolds)
62
+ - **Homoclinic/Heteroclinic** orbit tracing and detection
63
+ - **Parameter sweep** helpers and trajectory/post-analysis utilities
64
+
65
+ ### Vector fields & plotting (on top of Matplotlib)
66
+ Dynlib includes plotting helpers tailored for dynamical systems rather than raw Matplotlib boilerplate:
67
+ - Vector field evaluation utilities and **phase-portrait** helpers
68
+ - Plot modules for **basins**, **bifurcation diagrams**, **manifolds**, and general dynamics
69
+ - Higher-level plotting conveniences: **themes**, **facets**, decorations, and export helpers
70
+ - Vector field **animation** support
71
+
72
+ ### CLI
73
+ Dynlib ships a small CLI (Command Line Interface) for convenience tasks such as model validation, listing steppers, and inspecting caches.
74
+ The CLI is not required for the Python API.
75
+
76
+ ## Prerequisites
77
+ - Python 3.10+
78
+ - Matplotlib for plots.
79
+ - Numpy for numerical calculations.
80
+ - **Numba** is highly recommended for JIT execution:
81
+ - `python -m pip install numba`
82
+
83
+ ## Installation
84
+ - `pip install dynlib` (when published), or
85
+ - `pip install -e .` for editable installs from source
86
+
87
+ ## Quickstart
88
+
89
+ Sanity-check the CLI and validate a bundled model:
90
+
91
+ ```bash
92
+ dynlib --version
93
+ dynlib model validate builtin://ode/lorenz.toml
94
+ ```
95
+
96
+ Run a built-in model from Python (Lorenz system):
97
+
98
+ ```python
99
+ from dynlib import setup
100
+ from dynlib.plot import fig, series, export
101
+
102
+ sim = setup("builtin://ode/lorenz.toml", stepper="rk4")
103
+
104
+ sim.run(T=15.0, dt=0.01)
105
+ res = sim.results()
106
+
107
+ print("States:", res.state_names)
108
+ print("Final z:", res["z"][-1])
109
+
110
+ ax = fig.single()
111
+ series.plot(x=res.t, y=res["x"], ax=ax, label="x")
112
+ series.plot(x=res.t, y=res["z"], ax=ax, label="z", xlabel="time")
113
+ export.show()
114
+ ```
115
+
116
+ Next: see the docs for defining your own TOML models, URI tags (`proj://...`), recording options, and analysis workflows (basins, bifurcation, Lyapunov, fixed points).
117
+
118
+ ## Documentation
119
+ The documentation can be accessed via (#TODO: Add a link ...)
@@ -0,0 +1,93 @@
1
+ # dynlib
2
+
3
+ Dynlib is a Python library for **modeling, simulating, and analyzing dynamical systems**.
4
+ Models are described in a TOML-based DSL (Domain-Specific Language) and then executed through a unified runtime—so you can iterate on solvers, parameters, and analyses without rewriting the same Numpy/Matplotlib plumbing for every experiment.
5
+
6
+ With dynlib, you can define or tweak a model, try different solvers/settings, and visualize behavior quickly. It can be used with notebooks for teaching and demonstration purposes. Created models can be kept in an organized manner and can be shared easily.
7
+
8
+ ## Project status
9
+
10
+ Dynlib is **alpha-stage** software. APIs may change, and numerical edge cases or bugs can surface. Treat results as exploratory unless you validate them (e.g., alternative steppers, tighter tolerances, smaller step sizes, or analytical checks). If you find suspicious behavior, please open an issue with a minimal reproducer.
11
+
12
+ ## Highlights
13
+
14
+ ### Modeling (TOML DSL)
15
+ - Define **ODEs** and **discrete-time maps** using a declarative TOML spec.
16
+ - Express equations, parameters, state initialization, and metadata in a consistent format.
17
+ - Support for **events**, **auxiliary variables**, **functions/macros**, and **lagging** where applicable.
18
+ - Built-in **model registry** and URI loading (including `builtin://...` models).
19
+
20
+ ### Simulation runtime
21
+ - Multiple stepper families:
22
+ - ODE: Euler, RK4, RK45, Adams–Bashforth (AB2/AB3), and implicit methods (e.g., SDIRK/TR-BDF2).
23
+ - Maps: dedicated discrete runner(s) including integer-safe modes.
24
+ - Runner variants and session introspection utilities for iterative workflows.
25
+ - **JIT acceleration** via Numba (optional but highly recommended), plus **disk caching** for compiled runners.
26
+ - **Snapshots and resume** support for long or staged simulations.
27
+ - Selective recording and result APIs designed for downstream analysis.
28
+
29
+ ### Analysis
30
+ Built-in analysis utilities for common dynamical-systems tasks:
31
+ - **Bifurcation** and post-processing utilities
32
+ - **Basins of attraction** (auto/known variants)
33
+ - **Lyapunov exponent** analysis (including runtime observer support)
34
+ - **Fixed point / Equilibria** detection
35
+ - **Manifold** tracing tools (currently limited to 1D manifolds)
36
+ - **Homoclinic/Heteroclinic** orbit tracing and detection
37
+ - **Parameter sweep** helpers and trajectory/post-analysis utilities
38
+
39
+ ### Vector fields & plotting (on top of Matplotlib)
40
+ Dynlib includes plotting helpers tailored for dynamical systems rather than raw Matplotlib boilerplate:
41
+ - Vector field evaluation utilities and **phase-portrait** helpers
42
+ - Plot modules for **basins**, **bifurcation diagrams**, **manifolds**, and general dynamics
43
+ - Higher-level plotting conveniences: **themes**, **facets**, decorations, and export helpers
44
+ - Vector field **animation** support
45
+
46
+ ### CLI
47
+ Dynlib ships a small CLI (Command Line Interface) for convenience tasks such as model validation, listing steppers, and inspecting caches.
48
+ The CLI is not required for the Python API.
49
+
50
+ ## Prerequisites
51
+ - Python 3.10+
52
+ - Matplotlib for plots.
53
+ - Numpy for numerical calculations.
54
+ - **Numba** is highly recommended for JIT execution:
55
+ - `python -m pip install numba`
56
+
57
+ ## Installation
58
+ - `pip install dynlib` (when published), or
59
+ - `pip install -e .` for editable installs from source
60
+
61
+ ## Quickstart
62
+
63
+ Sanity-check the CLI and validate a bundled model:
64
+
65
+ ```bash
66
+ dynlib --version
67
+ dynlib model validate builtin://ode/lorenz.toml
68
+ ```
69
+
70
+ Run a built-in model from Python (Lorenz system):
71
+
72
+ ```python
73
+ from dynlib import setup
74
+ from dynlib.plot import fig, series, export
75
+
76
+ sim = setup("builtin://ode/lorenz.toml", stepper="rk4")
77
+
78
+ sim.run(T=15.0, dt=0.01)
79
+ res = sim.results()
80
+
81
+ print("States:", res.state_names)
82
+ print("Final z:", res["z"][-1])
83
+
84
+ ax = fig.single()
85
+ series.plot(x=res.t, y=res["x"], ax=ax, label="x")
86
+ series.plot(x=res.t, y=res["z"], ax=ax, label="z", xlabel="time")
87
+ export.show()
88
+ ```
89
+
90
+ Next: see the docs for defining your own TOML models, URI tags (`proj://...`), recording options, and analysis workflows (basins, bifurcation, Lyapunov, fixed points).
91
+
92
+ ## Documentation
93
+ The documentation can be accessed via (#TODO: Add a link ...)
@@ -0,0 +1,37 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77.0.3", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "dynlib"
7
+ version = "0.37.4"
8
+ description = "A dynamical systems simulation library."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ authors = [{ name = "İsmail Öztürk", email = "ismail.ozturk@amasya.edu.tr" }]
12
+ license = "BSD-3-Clause"
13
+ license-files = ["LICENSE"]
14
+ keywords = ["ODE", "dynamical-systems", "simulation"]
15
+ dependencies = [
16
+ "numpy>=1.24",
17
+ ]
18
+ classifiers = [
19
+ "Development Status :: 3 - Alpha",
20
+ "Intended Audience :: Science/Research",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Topic :: Scientific/Engineering :: Mathematics",
23
+ ]
24
+
25
+ [project.optional-dependencies]
26
+ jit = ["numba>=0.57.1"]
27
+ plot = ["matplotlib>=3.7"]
28
+ dev = ["pytest>=7", "scipy>=1.9", "matplotlib>=3.7", "numba>=0.57.1"]
29
+
30
+ [project.scripts]
31
+ dynlib = "dynlib.cli:main"
32
+
33
+ [tool.setuptools.packages.find]
34
+ where = ["src"]
35
+
36
+ [tool.setuptools.package-data]
37
+ "dynlib.models" = ["**/*.toml"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -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}'")