tsdynamics 3.0.2__tar.gz → 3.0.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.
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/PKG-INFO +1 -1
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/pyproject.toml +2 -1
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/__init__.py +1 -1
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/orbits/orbit_diagram.py +72 -8
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/engine/run.py +92 -6
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/families/continuous.py +57 -22
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/LICENSE +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/README.md +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/Cargo.toml +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-core/Cargo.lock +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-core/Cargo.toml +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-core/src/bridge.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-core/src/lib.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-engine/Cargo.toml +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-engine/src/dde.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-engine/src/ensemble.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-engine/src/event.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-engine/src/integrate.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-engine/src/lib.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-engine/src/map.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-engine/src/problem.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-engine/src/rng.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-engine/src/sde.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-engine/src/testkit.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-ir/Cargo.toml +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-ir/src/builder.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-ir/src/eval.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-ir/src/lib.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-ir/src/op.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-ir/src/reference.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-ir/src/tape.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-ir/tests/coverage_tape.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-ir/tests/fixtures/CircadianRhythm.txt +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-ir/tests/fixtures/Lorenz.txt +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-ir/tests/fixtures/SanUmSrisuchinwong.txt +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-ir/tests/fixtures/SprottMore.txt +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-ir/tests/fixtures/Torus.txt +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-ir/tests/fixtures/YuWang2.txt +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-ir/tests/gen_fixtures.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-ir/tests/golden_fixtures.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-ir/tests/roundtrip.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-jit/Cargo.toml +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-jit/src/codegen.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-jit/src/error.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-jit/src/evaluator.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-jit/src/lib.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-jit/src/shims.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-jit/tests/compile_latency.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-jit/tests/golden_fixtures.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-jit/tests/interpreter_equivalence.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/Cargo.toml +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/caps.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/explicit/control.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/explicit/dop853.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/explicit/mod.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/explicit/rk4.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/explicit/rk45.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/explicit/testkit.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/explicit/tsit5.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/implicit/bdf.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/implicit/control.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/implicit/linalg.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/implicit/mod.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/implicit/rosenbrock.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/implicit/trbdf2.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/lib.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/registry.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/sde/euler_maruyama.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/sde/milstein.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/sde/mod.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/sde/testkit.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/src/solver.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/tests/explicit_accuracy.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/tests/implicit_stiff.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-solvers/tests/registry.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-vm/Cargo.toml +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-vm/src/interp.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-vm/src/lib.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-vm/tests/golden_fixtures.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/crates/tsdyn-vm/tests/oracle_equivalence.rs +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/_result.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/basins/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/basins/_common.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/basins/attractors.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/basins/basins.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/basins/continuation.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/basins/metrics.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/chaos/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/chaos/_common.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/chaos/expansion.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/chaos/gali.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/chaos/zero_one.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/dimensions/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/dimensions/_common.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/dimensions/_scaling.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/dimensions/correlation.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/dimensions/fixedmass.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/dimensions/generalized.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/embedding/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/embedding/_common.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/embedding/delay.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/embedding/dimension.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/embedding/embed.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/entropy/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/entropy/core.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/entropy/dispersion.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/entropy/lz.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/entropy/multiscale.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/entropy/permutation.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/entropy/sample.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/fixedpoints/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/fixedpoints/_common.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/fixedpoints/fixed.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/fixedpoints/periodic.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/lyapunov/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/lyapunov/from_data.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/orbits/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/orbits/poincare.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/orbits/return_map.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/recurrence/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/recurrence/_common.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/recurrence/matrix.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/recurrence/rqa.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/recurrence/windowed.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/surrogate/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/surrogate/_common.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/surrogate/generators.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/surrogate/hypothesis.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/analysis/surrogate/statistics.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/data/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/data/sampling.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/data/trajectory.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/derived/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/derived/_base.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/derived/_crossings.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/derived/_variational.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/derived/ensemble.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/derived/poincare.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/derived/projected.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/derived/stroboscopic.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/derived/tangent.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/derived/wrapped.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/engine/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/engine/compile.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/engine/problem.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/engine/symbols.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/errors.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/families/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/families/_accessors.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/families/_dde_lyapunov.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/families/base.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/families/delay.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/families/discrete.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/families/protocol.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/families/stochastic.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/plugins.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/py.typed +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/registry.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/solvers/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/solvers/explicit.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/solvers/implicit.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/solvers/select.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/solvers/stochastic.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/continuous/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/continuous/chaotic_attractors.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/continuous/chem_bio_systems.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/continuous/climate_geophysics.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/continuous/coupled_systems.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/continuous/delayed_systems.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/continuous/exotic_systems.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/continuous/oscillatory_systems.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/continuous/physical_systems.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/continuous/population_dynamics.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/discrete/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/discrete/chaotic_maps.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/discrete/exotic_maps.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/discrete/geometric_maps.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/discrete/polynomial_maps.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/discrete/population_maps.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/transforms/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/transforms/_common.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/transforms/features.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/transforms/preprocessing.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/transforms/spectral.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/utils/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/utils/general.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/utils/grids.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/utils/sagitta_dt.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/viz/__init__.py +0 -0
- {tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/viz/spec.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tsdynamics"
|
|
7
|
-
version = "3.0.
|
|
7
|
+
version = "3.0.4"
|
|
8
8
|
description = "Zero-warmup Rust-engine ODE/DDE/SDE integration, discrete maps, and chaos analysis for dynamical systems."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.12,<4.0"
|
|
@@ -62,6 +62,7 @@ lz = ["lzcomplexity>=0.9"]
|
|
|
62
62
|
dev = [
|
|
63
63
|
"pytest>=8.0",
|
|
64
64
|
"pytest-cov>=5.0",
|
|
65
|
+
"pytest-xdist>=3.6",
|
|
65
66
|
"ruff>=0.6",
|
|
66
67
|
"mypy>=1.10",
|
|
67
68
|
"pre-commit>=3.8",
|
|
@@ -124,7 +124,7 @@ from .families import (
|
|
|
124
124
|
)
|
|
125
125
|
|
|
126
126
|
# Single source of truth for the package version; rewritten by python-semantic-release.
|
|
127
|
-
__version__ = "3.0.
|
|
127
|
+
__version__ = "3.0.4"
|
|
128
128
|
|
|
129
129
|
# Built-in system classes are NOT bound into this namespace — that would bury the
|
|
130
130
|
# submodules (``analysis``, ``data``, ``systems``, …) under ~149 model names in
|
|
@@ -164,6 +164,47 @@ def _count_branches(col: np.ndarray, rtol: float) -> int:
|
|
|
164
164
|
return 1 + int(np.count_nonzero(np.diff(s) > rtol * span))
|
|
165
165
|
|
|
166
166
|
|
|
167
|
+
def _record_via_iterate(
|
|
168
|
+
current: Any, start: Any, transient: int, n: int, idx: list[int]
|
|
169
|
+
) -> tuple[np.ndarray, np.ndarray]:
|
|
170
|
+
"""Record one parameter value on the Rust engine, in a single ``iterate`` call.
|
|
171
|
+
|
|
172
|
+
Resolve the initial condition explicitly and iterate ``transient + n`` steps
|
|
173
|
+
in one FFI round-trip, then slice off the transient. ``max_retries=1`` with an
|
|
174
|
+
explicit ``ic`` makes a divergent value raise ``RuntimeError`` (no random-IC
|
|
175
|
+
retry) — the caller turns that into an empty record set, exactly as the
|
|
176
|
+
per-step path does. Returns the recorded points and the final state (the
|
|
177
|
+
carry-over initial condition for the next value).
|
|
178
|
+
"""
|
|
179
|
+
ic_resolved = current.resolve_ic(start)
|
|
180
|
+
traj = current.iterate(steps=transient + n, ic=ic_resolved, max_retries=1)
|
|
181
|
+
y = traj.y
|
|
182
|
+
rec = np.asarray(y[transient : transient + n][:, idx], dtype=float)
|
|
183
|
+
# A zero-length run (``transient + n == 0``) yields no rows; the carry-over
|
|
184
|
+
# final state is then just the resolved initial condition — matching the old
|
|
185
|
+
# step-loop's ``current.state()`` after taking no steps.
|
|
186
|
+
last = y[-1].copy() if y.shape[0] else np.asarray(ic_resolved, dtype=float).reshape(current.dim)
|
|
187
|
+
return rec, last
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def _record_via_step(
|
|
191
|
+
current: Any, start: Any, transient: int, n: int, idx: list[int]
|
|
192
|
+
) -> tuple[np.ndarray, np.ndarray]:
|
|
193
|
+
"""Record one parameter value via the per-step protocol path (a ``step()`` loop).
|
|
194
|
+
|
|
195
|
+
The fallback for flow wrappers (``PoincareMap`` / ``StroboscopicMap``), maps
|
|
196
|
+
whose ``_step`` will not lower to the engine IR, and wheel-free environments.
|
|
197
|
+
Returns the recorded points and the final state.
|
|
198
|
+
"""
|
|
199
|
+
current.reinit(start)
|
|
200
|
+
for _ in range(transient):
|
|
201
|
+
current.step()
|
|
202
|
+
rec = np.empty((n, len(idx)))
|
|
203
|
+
for i in range(n):
|
|
204
|
+
rec[i] = current.step()[idx]
|
|
205
|
+
return rec, current.state()
|
|
206
|
+
|
|
207
|
+
|
|
167
208
|
def orbit_diagram(
|
|
168
209
|
sys: Any,
|
|
169
210
|
param: str,
|
|
@@ -241,21 +282,44 @@ def orbit_diagram(
|
|
|
241
282
|
|
|
242
283
|
import warnings
|
|
243
284
|
|
|
285
|
+
from tsdynamics.engine.compile import TapeCompileError
|
|
286
|
+
from tsdynamics.engine.run import EngineNotAvailableError
|
|
287
|
+
from tsdynamics.families import DiscreteMap
|
|
288
|
+
|
|
244
289
|
values_arr = np.asarray(list(values), dtype=float)
|
|
245
290
|
points: list[np.ndarray] = []
|
|
246
291
|
state: np.ndarray | None = None
|
|
247
292
|
|
|
293
|
+
# A genuine DiscreteMap iterates on the Rust engine: the whole transient +
|
|
294
|
+
# record run for one parameter value becomes a single engine call (one FFI
|
|
295
|
+
# round-trip) rather than ``transient + n`` Python ``step()`` calls — the
|
|
296
|
+
# per-value bottleneck this stream removes (Logistic 600×120: ~9× faster).
|
|
297
|
+
# Flow wrappers (PoincareMap / StroboscopicMap) have no ``iterate`` and keep
|
|
298
|
+
# the per-step protocol path; a map whose ``_step`` will not lower to the IR,
|
|
299
|
+
# or a wheel-free environment with no compiled engine, falls back to it too
|
|
300
|
+
# (the decision is taken once and latched for the rest of the sweep). Both
|
|
301
|
+
# paths iterate the *same* lowered ``_step``, so a periodic window converges to
|
|
302
|
+
# the identical cycle and — where the engine and NumPy agree bit-for-bit (e.g.
|
|
303
|
+
# the logistic map) — the whole diagram is byte-identical; a chaotic window
|
|
304
|
+
# records the same attractor (the engine ``iterate`` being the canonical map
|
|
305
|
+
# runner).
|
|
306
|
+
use_engine = isinstance(sys, DiscreteMap)
|
|
307
|
+
|
|
248
308
|
for v in values_arr:
|
|
249
309
|
current = sys.with_params(**{param: v})
|
|
250
310
|
start = state if (carry_state and state is not None) else ic
|
|
251
311
|
try:
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
312
|
+
if use_engine:
|
|
313
|
+
try:
|
|
314
|
+
rec, last = _record_via_iterate(current, start, transient, n, idx)
|
|
315
|
+
except (TapeCompileError, EngineNotAvailableError):
|
|
316
|
+
# This map cannot run on the engine (a non-lowerable step, or
|
|
317
|
+
# no compiled wheel): fall back to the protocol path for this
|
|
318
|
+
# value and the rest of the sweep.
|
|
319
|
+
use_engine = False
|
|
320
|
+
rec, last = _record_via_step(current, start, transient, n, idx)
|
|
321
|
+
else:
|
|
322
|
+
rec, last = _record_via_step(current, start, transient, n, idx)
|
|
259
323
|
except RuntimeError as exc:
|
|
260
324
|
# One divergent value must not discard the whole sweep: record an
|
|
261
325
|
# empty point set and restart the next value from `ic`.
|
|
@@ -270,7 +334,7 @@ def orbit_diagram(
|
|
|
270
334
|
continue
|
|
271
335
|
points.append(rec)
|
|
272
336
|
if carry_state:
|
|
273
|
-
state =
|
|
337
|
+
state = last
|
|
274
338
|
|
|
275
339
|
meta = {
|
|
276
340
|
"system": type(sys).__name__,
|
|
@@ -526,7 +526,15 @@ def _run_continuous(
|
|
|
526
526
|
|
|
527
527
|
eng = _engine()
|
|
528
528
|
y = _engine_integrate_dense(
|
|
529
|
-
eng,
|
|
529
|
+
eng,
|
|
530
|
+
_primary_tape(problem).to_arrays(),
|
|
531
|
+
problem.ic,
|
|
532
|
+
problem.params_vec(),
|
|
533
|
+
t_eval,
|
|
534
|
+
method=method,
|
|
535
|
+
rtol=rtol,
|
|
536
|
+
atol=atol,
|
|
537
|
+
jit=(backend == "jit"),
|
|
530
538
|
)
|
|
531
539
|
y = np.asarray(y, dtype=np.float64)
|
|
532
540
|
if not np.all(np.isfinite(y)):
|
|
@@ -537,6 +545,74 @@ def _run_continuous(
|
|
|
537
545
|
return y
|
|
538
546
|
|
|
539
547
|
|
|
548
|
+
def _step_continuous(
|
|
549
|
+
tape_arrays: tuple,
|
|
550
|
+
ic: np.ndarray,
|
|
551
|
+
params_vec: np.ndarray,
|
|
552
|
+
t_eval: np.ndarray,
|
|
553
|
+
*,
|
|
554
|
+
method: str,
|
|
555
|
+
rtol: float,
|
|
556
|
+
atol: float,
|
|
557
|
+
jit: bool,
|
|
558
|
+
name: str,
|
|
559
|
+
) -> np.ndarray:
|
|
560
|
+
"""Integrate one dense ODE span from pre-marshalled tape arrays — the per-step seam.
|
|
561
|
+
|
|
562
|
+
The lean inner core of
|
|
563
|
+
:meth:`~tsdynamics.families.continuous.ContinuousSystem.step`: it performs
|
|
564
|
+
exactly the engine call and finiteness guard :func:`_run_continuous` does for an
|
|
565
|
+
ODE on the compiled engine, but takes the already-marshalled tape wire arrays
|
|
566
|
+
(cached once at ``reinit`` — they are loop-invariant) plus the live parameter
|
|
567
|
+
vector, skipping the per-call tape re-marshalling, ``Problem`` construction and
|
|
568
|
+
output-grid build that the full :func:`integrate` entry point pays. It is
|
|
569
|
+
therefore **answer-identical** to :func:`_run_continuous` over the same inputs
|
|
570
|
+
(stream WS-INVHOIST); it serves only the constant-/small-``dt`` stepping loops
|
|
571
|
+
(Poincaré refinement, basins over flows, the streaming protocol), never a
|
|
572
|
+
user-facing :class:`~tsdynamics.families.Trajectory` (which keeps its
|
|
573
|
+
provenance via :func:`integrate`).
|
|
574
|
+
|
|
575
|
+
Parameters
|
|
576
|
+
----------
|
|
577
|
+
tape_arrays : tuple
|
|
578
|
+
The RHS tape's engine wire arrays (:meth:`Tape.to_arrays`), marshalled once
|
|
579
|
+
by the caller and reused across the loop.
|
|
580
|
+
ic : ndarray, shape (dim,)
|
|
581
|
+
The state to start this span from.
|
|
582
|
+
params_vec : ndarray
|
|
583
|
+
Live control-parameter values, read per step so a mid-loop parameter change
|
|
584
|
+
still takes effect — identical to the pre-hoist path.
|
|
585
|
+
t_eval : ndarray
|
|
586
|
+
The (two-node) output grid for this span.
|
|
587
|
+
method, rtol, atol, jit : str, float, float, bool
|
|
588
|
+
Solver configuration, resolved once by ``reinit``.
|
|
589
|
+
name : str
|
|
590
|
+
System name, for the divergence error message.
|
|
591
|
+
|
|
592
|
+
Returns
|
|
593
|
+
-------
|
|
594
|
+
ndarray, shape (len(t_eval), dim)
|
|
595
|
+
|
|
596
|
+
Raises
|
|
597
|
+
------
|
|
598
|
+
RuntimeError
|
|
599
|
+
If the integration diverged or the step collapsed (non-finite output) —
|
|
600
|
+
the same loud-divergence contract as :func:`_run_continuous`.
|
|
601
|
+
"""
|
|
602
|
+
eng = _engine()
|
|
603
|
+
y = np.asarray(
|
|
604
|
+
_engine_integrate_dense(
|
|
605
|
+
eng, tape_arrays, ic, params_vec, t_eval, method=method, rtol=rtol, atol=atol, jit=jit
|
|
606
|
+
),
|
|
607
|
+
dtype=np.float64,
|
|
608
|
+
)
|
|
609
|
+
if not np.isfinite(y).all():
|
|
610
|
+
raise RuntimeError(
|
|
611
|
+
f"{name}: integration diverged or the step collapsed before reaching the final time."
|
|
612
|
+
)
|
|
613
|
+
return y
|
|
614
|
+
|
|
615
|
+
|
|
540
616
|
def _run_dde(
|
|
541
617
|
problem: DDEProblem,
|
|
542
618
|
t_eval: np.ndarray,
|
|
@@ -917,7 +993,9 @@ def sde_ensemble_final(
|
|
|
917
993
|
|
|
918
994
|
def _engine_integrate_dense(
|
|
919
995
|
eng: Any,
|
|
920
|
-
|
|
996
|
+
tape_arrays: tuple,
|
|
997
|
+
ic: np.ndarray,
|
|
998
|
+
params_vec: np.ndarray,
|
|
921
999
|
t_eval: np.ndarray,
|
|
922
1000
|
*,
|
|
923
1001
|
method: str,
|
|
@@ -925,11 +1003,19 @@ def _engine_integrate_dense(
|
|
|
925
1003
|
atol: float,
|
|
926
1004
|
jit: bool,
|
|
927
1005
|
) -> np.ndarray:
|
|
928
|
-
"""Dispatch a dense single-trajectory integration to the engine.
|
|
1006
|
+
"""Dispatch a dense single-trajectory integration to the engine.
|
|
1007
|
+
|
|
1008
|
+
``tape_arrays`` is the RHS tape's wire tuple (:meth:`Tape.to_arrays` — the
|
|
1009
|
+
drift tape for an SDE). Taking the marshalled arrays as an argument rather than
|
|
1010
|
+
deriving them here lets a hot stepping loop pass arrays it marshalled once
|
|
1011
|
+
(:func:`_step_continuous`) instead of rebuilding the tuple per step (stream
|
|
1012
|
+
WS-INVHOIST), while the single-shot :func:`integrate` path marshals them inline
|
|
1013
|
+
at the call site.
|
|
1014
|
+
"""
|
|
929
1015
|
return eng.integrate_dense(
|
|
930
|
-
*
|
|
931
|
-
np.ascontiguousarray(
|
|
932
|
-
|
|
1016
|
+
*tape_arrays,
|
|
1017
|
+
np.ascontiguousarray(ic, dtype=np.float64),
|
|
1018
|
+
params_vec,
|
|
933
1019
|
np.ascontiguousarray(t_eval, dtype=np.float64),
|
|
934
1020
|
method,
|
|
935
1021
|
float(rtol),
|
|
@@ -165,8 +165,11 @@ class ContinuousSystem(SystemBase, ABC):
|
|
|
165
165
|
# Per-step integration context cached by ``reinit`` so a repeated constant-``dt``
|
|
166
166
|
# stepping loop pays the fixed per-call overhead (solver-registry resolve,
|
|
167
167
|
# Jacobian decision, output-grid build, provenance, Trajectory wrap) once at
|
|
168
|
-
# reinit instead of on every ``step`` (stream WS-STEPBUF).
|
|
168
|
+
# reinit instead of on every ``step`` (stream WS-STEPBUF). ``_step_tape_arrays``
|
|
169
|
+
# caches the engine wire arrays of the (loop-invariant) tape so the per-``dt``
|
|
170
|
+
# loop reuses them rather than re-marshalling the tuple each call (WS-INVHOIST).
|
|
169
171
|
_step_method_canonical: str | None = None
|
|
172
|
+
_step_tape_arrays: Any = None
|
|
170
173
|
|
|
171
174
|
# ------------------------------------------------------------------ #
|
|
172
175
|
# Subclass interface
|
|
@@ -304,7 +307,16 @@ class ContinuousSystem(SystemBase, ABC):
|
|
|
304
307
|
# Cache the canonical kernel name (``"RK45"`` → ``"rk45"``) so the per-step
|
|
305
308
|
# loop hits the engine core directly without re-resolving every call.
|
|
306
309
|
self._step_method_canonical = resolution.name
|
|
307
|
-
|
|
310
|
+
prob = ode_problem(self, ic=ic_arr, t0=t0, **resolution.build_kwargs)
|
|
311
|
+
# Marshal the (loop-invariant) tape to its engine wire arrays once here so the
|
|
312
|
+
# per-``dt`` ``step`` loop reuses them instead of rebuilding the tuple on every
|
|
313
|
+
# call (stream WS-INVHOIST). Re-derived on each ``reinit`` (a sweep reinits
|
|
314
|
+
# per parameter value), so a re-lowered tape is always picked up. Marshal before
|
|
315
|
+
# publishing the problem so a (theoretical) marshalling failure can't leave a new
|
|
316
|
+
# ``_engine_problem`` paired with a stale ``_step_tape_arrays``.
|
|
317
|
+
step_arrays = prob.tape.to_arrays()
|
|
318
|
+
self._engine_problem = prob
|
|
319
|
+
self._step_tape_arrays = step_arrays
|
|
308
320
|
self._step_rtol = float(rtol)
|
|
309
321
|
self._step_atol = float(atol)
|
|
310
322
|
self._state_now = ic_arr.copy()
|
|
@@ -323,14 +335,18 @@ class ContinuousSystem(SystemBase, ABC):
|
|
|
323
335
|
Each call integrates **exactly one** ``dt`` from the live ``(state, t)``,
|
|
324
336
|
returning byte-for-byte the trajectory the released per-``dt`` path
|
|
325
337
|
produced — there is no batching, so the numbers are unchanged for every
|
|
326
|
-
method, adaptive or fixed-step (
|
|
327
|
-
only from
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
338
|
+
method, adaptive or fixed-step (streams WS-STEPBUF, WS-INVHOIST). The
|
|
339
|
+
speedup comes only from hoisting fixed per-call overhead out of the loop:
|
|
340
|
+
``step`` reuses the tape, its canonical kernel name and its marshalled
|
|
341
|
+
engine wire arrays — all cached by :meth:`reinit` — and calls the engine's
|
|
342
|
+
lean dense-output core (:func:`~tsdynamics.engine.run._step_continuous`)
|
|
343
|
+
directly. So a constant-``dt`` stepping loop (Poincaré refinement, basins
|
|
331
344
|
over flows) skips the solver-registry resolve, the implicit-Jacobian
|
|
332
|
-
decision,
|
|
333
|
-
|
|
345
|
+
decision, the tape re-marshalling, the output-grid ``arange``/append,
|
|
346
|
+
provenance assembly and the :class:`Trajectory` wrap that the full
|
|
347
|
+
:meth:`integrate` entry point pays on every call. The control-parameter
|
|
348
|
+
vector is still read live each step, so the live-stepper semantics are
|
|
349
|
+
unchanged.
|
|
334
350
|
|
|
335
351
|
A batch-ahead variant that integrated a whole chunk in one engine call was
|
|
336
352
|
rejected: a chunked adaptive integration is *not* equal to N single-``dt``
|
|
@@ -339,31 +355,50 @@ class ContinuousSystem(SystemBase, ABC):
|
|
|
339
355
|
``max_lyapunov``. The durable amortisation is the resumable engine stepper
|
|
340
356
|
(WS-STEPPER), which advances without re-seeding and stays answer-exact.
|
|
341
357
|
"""
|
|
342
|
-
from tsdynamics.engine.
|
|
343
|
-
from tsdynamics.engine.run import _run_continuous
|
|
344
|
-
from tsdynamics.utils.grids import make_output_grid
|
|
358
|
+
from tsdynamics.engine.run import _step_continuous
|
|
345
359
|
|
|
346
360
|
if self._engine_problem is None:
|
|
347
361
|
self.reinit()
|
|
348
362
|
dt = float(n_or_dt) if n_or_dt is not None else self._default_step_dt
|
|
349
363
|
|
|
350
364
|
t0 = self._t_now
|
|
351
|
-
|
|
352
|
-
#
|
|
353
|
-
#
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
365
|
+
tf = t0 + dt
|
|
366
|
+
# The two-node grid ``make_output_grid(t0, tf, dt)`` builds for a single ``dt``
|
|
367
|
+
# span, assembled directly to skip its ``arange``/append (WS-INVHOIST). When the
|
|
368
|
+
# span clears ``1e-9`` the helper is byte-for-byte exactly ``[t0, tf]``: that sits
|
|
369
|
+
# a thousandfold above its ``1e-12`` append tolerance (``t_arr[-1] < tf - 1e-12``)
|
|
370
|
+
# and above the float-subtraction rounding even at large ``t0``, and a single
|
|
371
|
+
# ``dt`` span never yields more than two nodes — so the shortcut is identical
|
|
372
|
+
# there (the regime of every real step; verified bit-for-bit over a wide
|
|
373
|
+
# ``t0``/``dt`` fuzz). The rare remainder — a sub-``1e-9`` step (whose helper grid
|
|
374
|
+
# may degenerate to a single un-advanced node) or a non-forward / non-positive
|
|
375
|
+
# ``dt`` (which must raise the canonical
|
|
376
|
+
# :class:`~tsdynamics.errors.InvalidParameterError`) — defers to the helper so
|
|
377
|
+
# ``step`` stays byte-identical to the pre-hoist path for *every* input.
|
|
378
|
+
if tf - t0 > 1e-9:
|
|
379
|
+
t_eval = np.array([t0, tf], dtype=np.float64)
|
|
380
|
+
else:
|
|
381
|
+
from tsdynamics.utils.grids import make_output_grid
|
|
382
|
+
|
|
383
|
+
t_eval = make_output_grid(t0, tf, dt)
|
|
384
|
+
y = _step_continuous(
|
|
385
|
+
self._step_tape_arrays,
|
|
386
|
+
self._state_now,
|
|
387
|
+
self._engine_problem.params_vec(),
|
|
358
388
|
t_eval,
|
|
359
389
|
method=self._step_method_canonical,
|
|
360
390
|
rtol=self._step_rtol,
|
|
361
391
|
atol=self._step_atol,
|
|
362
|
-
|
|
392
|
+
jit=self._step_backend == "jit",
|
|
393
|
+
name=type(self).__name__,
|
|
363
394
|
)
|
|
364
395
|
state = np.asarray(y[-1], dtype=float)
|
|
365
|
-
|
|
366
|
-
|
|
396
|
+
# The state/time advance writes private framework attributes that always pass
|
|
397
|
+
# straight through ``SystemBase.__setattr__`` (underscore-prefixed) — go direct
|
|
398
|
+
# to ``object.__setattr__`` so the hot loop skips the param-typo guard's
|
|
399
|
+
# ``params`` membership check on every step (WS-INVHOIST).
|
|
400
|
+
object.__setattr__(self, "_t_now", tf)
|
|
401
|
+
object.__setattr__(self, "_state_now", state.copy())
|
|
367
402
|
return state.copy()
|
|
368
403
|
|
|
369
404
|
def state(self) -> np.ndarray:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/continuous/chaotic_attractors.py
RENAMED
|
File without changes
|
|
File without changes
|
{tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/continuous/climate_geophysics.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/continuous/oscillatory_systems.py
RENAMED
|
File without changes
|
|
File without changes
|
{tsdynamics-3.0.2 → tsdynamics-3.0.4}/src/tsdynamics/systems/continuous/population_dynamics.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|