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.
- dynlib-0.37.4/LICENSE +29 -0
- dynlib-0.37.4/PKG-INFO +119 -0
- dynlib-0.37.4/README.md +93 -0
- dynlib-0.37.4/pyproject.toml +37 -0
- dynlib-0.37.4/setup.cfg +4 -0
- dynlib-0.37.4/src/dynlib/__init__.py +96 -0
- dynlib-0.37.4/src/dynlib/analysis/__init__.py +202 -0
- dynlib-0.37.4/src/dynlib/analysis/basin.py +498 -0
- dynlib-0.37.4/src/dynlib/analysis/basin_auto.py +2282 -0
- dynlib-0.37.4/src/dynlib/analysis/basin_codes.py +9 -0
- dynlib-0.37.4/src/dynlib/analysis/basin_known.py +2207 -0
- dynlib-0.37.4/src/dynlib/analysis/basin_stats.py +247 -0
- dynlib-0.37.4/src/dynlib/analysis/fixed_points.py +297 -0
- dynlib-0.37.4/src/dynlib/analysis/manifold.py +6858 -0
- dynlib-0.37.4/src/dynlib/analysis/post/__init__.py +11 -0
- dynlib-0.37.4/src/dynlib/analysis/post/bifurcation.py +427 -0
- dynlib-0.37.4/src/dynlib/analysis/post/trajectory.py +465 -0
- dynlib-0.37.4/src/dynlib/analysis/sweep.py +1795 -0
- dynlib-0.37.4/src/dynlib/cli.py +347 -0
- dynlib-0.37.4/src/dynlib/compiler/__init__.py +12 -0
- dynlib-0.37.4/src/dynlib/compiler/build.py +1443 -0
- dynlib-0.37.4/src/dynlib/compiler/codegen/__init__.py +4 -0
- dynlib-0.37.4/src/dynlib/compiler/codegen/_runner_cache.py +338 -0
- dynlib-0.37.4/src/dynlib/compiler/codegen/cache_importer.py +142 -0
- dynlib-0.37.4/src/dynlib/compiler/codegen/emitter.py +723 -0
- dynlib-0.37.4/src/dynlib/compiler/codegen/rewrite.py +735 -0
- dynlib-0.37.4/src/dynlib/compiler/codegen/runner_cache.py +681 -0
- dynlib-0.37.4/src/dynlib/compiler/codegen/runner_variants.py +2515 -0
- dynlib-0.37.4/src/dynlib/compiler/codegen/validate.py +227 -0
- dynlib-0.37.4/src/dynlib/compiler/guards.py +304 -0
- dynlib-0.37.4/src/dynlib/compiler/jit/__init__.py +0 -0
- dynlib-0.37.4/src/dynlib/compiler/jit/cache.py +27 -0
- dynlib-0.37.4/src/dynlib/compiler/jit/compile.py +132 -0
- dynlib-0.37.4/src/dynlib/compiler/mods.py +336 -0
- dynlib-0.37.4/src/dynlib/compiler/paths.py +488 -0
- dynlib-0.37.4/src/dynlib/dsl/__init__.py +0 -0
- dynlib-0.37.4/src/dynlib/dsl/astcheck.py +757 -0
- dynlib-0.37.4/src/dynlib/dsl/constants.py +48 -0
- dynlib-0.37.4/src/dynlib/dsl/parser.py +382 -0
- dynlib-0.37.4/src/dynlib/dsl/schema.py +279 -0
- dynlib-0.37.4/src/dynlib/dsl/spec.py +396 -0
- dynlib-0.37.4/src/dynlib/errors.py +98 -0
- dynlib-0.37.4/src/dynlib/mkdocs_helpers.py +114 -0
- dynlib-0.37.4/src/dynlib/models/__init__.py +7 -0
- dynlib-0.37.4/src/dynlib/models/map/henon.toml +23 -0
- dynlib-0.37.4/src/dynlib/models/map/henon2.toml +28 -0
- dynlib-0.37.4/src/dynlib/models/map/ikeda.toml +22 -0
- dynlib-0.37.4/src/dynlib/models/map/logistic.toml +17 -0
- dynlib-0.37.4/src/dynlib/models/map/lozi.toml +17 -0
- dynlib-0.37.4/src/dynlib/models/map/sine.toml +20 -0
- dynlib-0.37.4/src/dynlib/models/map/standard.toml +22 -0
- dynlib-0.37.4/src/dynlib/models/ode/duffing.toml +25 -0
- dynlib-0.37.4/src/dynlib/models/ode/eto-circular.toml +27 -0
- dynlib-0.37.4/src/dynlib/models/ode/exp-if.toml +22 -0
- dynlib-0.37.4/src/dynlib/models/ode/expdecay.toml +20 -0
- dynlib-0.37.4/src/dynlib/models/ode/fitzhugh-nagumo.toml +28 -0
- dynlib-0.37.4/src/dynlib/models/ode/hodgkin-huxley.toml +72 -0
- dynlib-0.37.4/src/dynlib/models/ode/izhikevich.toml +65 -0
- dynlib-0.37.4/src/dynlib/models/ode/leaky-if.toml +20 -0
- dynlib-0.37.4/src/dynlib/models/ode/lorenz.toml +26 -0
- dynlib-0.37.4/src/dynlib/models/ode/quadratic-if.toml +22 -0
- dynlib-0.37.4/src/dynlib/models/ode/resonate-if.toml +38 -0
- dynlib-0.37.4/src/dynlib/models/ode/vanderpol.toml +21 -0
- dynlib-0.37.4/src/dynlib/plot/__init__.py +67 -0
- dynlib-0.37.4/src/dynlib/plot/_export.py +107 -0
- dynlib-0.37.4/src/dynlib/plot/_facet.py +17 -0
- dynlib-0.37.4/src/dynlib/plot/_fig.py +113 -0
- dynlib-0.37.4/src/dynlib/plot/_primitives.py +2140 -0
- dynlib-0.37.4/src/dynlib/plot/_theme.py +451 -0
- dynlib-0.37.4/src/dynlib/plot/basin.py +334 -0
- dynlib-0.37.4/src/dynlib/plot/bifurcation.py +137 -0
- dynlib-0.37.4/src/dynlib/plot/dynamics.py +160 -0
- dynlib-0.37.4/src/dynlib/plot/vectorfield.py +1502 -0
- dynlib-0.37.4/src/dynlib/runtime/__init__.py +0 -0
- dynlib-0.37.4/src/dynlib/runtime/analysis_meta.py +64 -0
- dynlib-0.37.4/src/dynlib/runtime/buffers.py +155 -0
- dynlib-0.37.4/src/dynlib/runtime/fastpath/__init__.py +49 -0
- dynlib-0.37.4/src/dynlib/runtime/fastpath/capability.py +112 -0
- dynlib-0.37.4/src/dynlib/runtime/fastpath/executor.py +1273 -0
- dynlib-0.37.4/src/dynlib/runtime/fastpath/plans.py +149 -0
- dynlib-0.37.4/src/dynlib/runtime/initial_step.py +145 -0
- dynlib-0.37.4/src/dynlib/runtime/observers/__init__.py +51 -0
- dynlib-0.37.4/src/dynlib/runtime/observers/core.py +713 -0
- dynlib-0.37.4/src/dynlib/runtime/observers/lyapunov.py +1510 -0
- dynlib-0.37.4/src/dynlib/runtime/results.py +259 -0
- dynlib-0.37.4/src/dynlib/runtime/results_api.py +1007 -0
- dynlib-0.37.4/src/dynlib/runtime/runner_api.py +180 -0
- dynlib-0.37.4/src/dynlib/runtime/sim.py +3144 -0
- dynlib-0.37.4/src/dynlib/runtime/softdeps.py +96 -0
- dynlib-0.37.4/src/dynlib/runtime/stepper_checks.py +86 -0
- dynlib-0.37.4/src/dynlib/runtime/types.py +9 -0
- dynlib-0.37.4/src/dynlib/runtime/workspace.py +160 -0
- dynlib-0.37.4/src/dynlib/runtime/wrapper.py +497 -0
- dynlib-0.37.4/src/dynlib/steppers/__init__.py +15 -0
- dynlib-0.37.4/src/dynlib/steppers/base.py +170 -0
- dynlib-0.37.4/src/dynlib/steppers/config_base.py +148 -0
- dynlib-0.37.4/src/dynlib/steppers/config_utils.py +229 -0
- dynlib-0.37.4/src/dynlib/steppers/discrete/__init__.py +0 -0
- dynlib-0.37.4/src/dynlib/steppers/discrete/map.py +108 -0
- dynlib-0.37.4/src/dynlib/steppers/ode/__init__.py +0 -0
- dynlib-0.37.4/src/dynlib/steppers/ode/ab2.py +240 -0
- dynlib-0.37.4/src/dynlib/steppers/ode/ab3.py +320 -0
- dynlib-0.37.4/src/dynlib/steppers/ode/bdf2.py +380 -0
- dynlib-0.37.4/src/dynlib/steppers/ode/bdf2a.py +623 -0
- dynlib-0.37.4/src/dynlib/steppers/ode/euler.py +199 -0
- dynlib-0.37.4/src/dynlib/steppers/ode/rk2_midpoint.py +257 -0
- dynlib-0.37.4/src/dynlib/steppers/ode/rk4.py +365 -0
- dynlib-0.37.4/src/dynlib/steppers/ode/rk45.py +402 -0
- dynlib-0.37.4/src/dynlib/steppers/ode/sdirk2.py +587 -0
- dynlib-0.37.4/src/dynlib/steppers/ode/tr_bdf2a.py +616 -0
- dynlib-0.37.4/src/dynlib/steppers/registry.py +167 -0
- dynlib-0.37.4/src/dynlib/utils/__init__.py +3 -0
- dynlib-0.37.4/src/dynlib/utils/timer.py +17 -0
- dynlib-0.37.4/src/dynlib.egg-info/PKG-INFO +119 -0
- dynlib-0.37.4/src/dynlib.egg-info/SOURCES.txt +117 -0
- dynlib-0.37.4/src/dynlib.egg-info/dependency_links.txt +1 -0
- dynlib-0.37.4/src/dynlib.egg-info/entry_points.txt +2 -0
- dynlib-0.37.4/src/dynlib.egg-info/requires.txt +13 -0
- 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 ...)
|
dynlib-0.37.4/README.md
ADDED
|
@@ -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"]
|
dynlib-0.37.4/setup.cfg
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}'")
|