Skip to main content

TSDynamics

Python CI Release Docs PyPI codecov

Dynamical systems in Python: 177 built-in systems, a native Rust integration engine, and a chaos-analysis toolkit.

You write the math (one symbolic method); TSDynamics lowers it to a native Rust engine and handles integration, Lyapunov spectra, bifurcation diagrams, Poincaré sections, attractors & basins — and even the documentation page for your system.

A spinning Lorenz attractor
A built-in Lorenz attractor — integrated, spun, and saved to a GIF (code below).

import tsdynamics as ts

lor = ts.systems.Lorenz(ic=[1.0, 1.0, 1.0])
traj = lor.run(final_time=100.0, dt=0.01)   # `run` is the one verb, every family
traj["x"]                                   # named component access

print(ts.analysis.lyapunov_spectrum(lor))   # an analysis is a free function
# LyapunovSpectrum  λ = [0.916, 0.0001893, -14.58]   chaotic · D_KY = 2.063   (Lorenz)

📖 Documentation: https://el3ssar.github.io/TSDynamics/


Define your own system

import tsdynamics as ts

class Rossler(ts.ContinuousSystem):
    variables = ("x", "y", "z")            # dim inferred = 3
    params = {"a": 0.2, "b": 0.2, "c": 5.7}
    _reference = "Rössler (1976), Phys. Lett. A 57, 397-398"

    def _equations(y, t, a, b, c):
        x, yv, z = y(0), y(1), y(2)
        return (-yv - z, x + a * yv, b + z * (x - c))

That's the whole ODE contract. The class auto-registers and works with analyses that accept flows. For systems added to the built-in catalogue, the test suite sweeps them and the docs build renders their equations and attractors. Delay systems use y(0, t - tau); maps implement _step (the Jacobian is derived from it); SDEs add a _diffusion term. Rossler().info prints everything the library read back to you.

From equations to figures

There is one plotting verb, and it has one rule: ts.plot draws everything you hand it on one figure and gives you back a Plot — a positional string says how to draw, everything else says what to draw, and a Plot handed back in is just another thing to draw. That last clause is why grids, movies and escape-to-matplotlib need no extra API. The Plot is backend-neutral: tweak it fluently, then save to matplotlib, plotly (interactive), three.js or JSON.

Bifurcation diagram of the logistic map, with the period-doubling onsets marked — orbit_diagram is one call, and .bifurcation_points() finds the cascade ($r_1 = 3$, $r_2 = 1 + \sqrt6 \approx 3.449$, …):

import numpy as np, tsdynamics as ts

orbit = ts.analysis.orbit_diagram(ts.systems.Logistic(), "r", np.linspace(2.8, 4.0, 2000))
pts = orbit.bifurcation_points()

p = ts.plot(orbit, color="k", markersize=0.2, alpha=0.5,   # tiny translucent dots
            xlabel="r", ylabel="x*", title="Logistic bifurcation")
for i, lbl in [(0, " r₁"), (1, " r₂"), (3, " r₄")]:        # mark the onsets
    p.vline(pts[i], label=lbl, color="red", linestyle="dashed")
p.save("bifurcation.png", size=(1600, 700))

Logistic bifurcation diagram

A PDE, too — the Kuramoto–Sivashinsky equation is a built-in spatially extended system; its space–time field is auto-detected and drawn as a heatmap:

import tsdynamics as ts

ks = ts.systems.KuramotoSivashinsky(N=128, L=22.0)
traj = ks.run(final_time=200.0, dt=0.25)
ts.plot(traj).save("ks.png")              # 128-mode space–time field

Kuramoto–Sivashinsky space–time field

Named plots, grids, primitives. Beyond the auto-detected default, a positional string names a plot transform — 38 of them, from nullclines and streamlines to ftle, cobweb, invariant_density and trace_determinant. Each declares which primitives can draw it, so you pick the drawing without touching a backend; and because a Plot is itself a legal subject, a grid of different plots is the same call:

import numpy as np, tsdynamics as ts

vdp = ts.systems.VanDerPol(params={"mu": 1.0})
traj = vdp.run(final_time=30.0, dt=0.01, ic=[0.5, 0.0])

ts.plot(vdp, traj, "flow_speed", "nullclines")                   # overlay, order-free
ts.plot(ts.plot(traj), ts.plot(traj, "psd"), layout="row")       # a grid
ts.viz.draw({"x": np.arange(5.0), "y": np.arange(5.0) ** 2}, "line")   # bare arrays

@ts.viz.transforms.register(source="data", frame="time", kind="diagnostic_curve",
                            primitives=("line", "points"))
def speed(traj):
    """Instantaneous speed |dx/dt| along the orbit."""
    return {"x": traj.t[1:],
            "y": np.linalg.norm(np.diff(traj.y, axis=0), axis=1) / np.diff(traj.t)}

ts.plot(traj, "speed")   # ...now in the gallery, the matrix, and every plot door

A transform owns no new math — it adapts an estimator from tsdynamics.analysis. The gallery is generated from the registry, so every picture there is produced by the snippet printed beside it.

The spinning attractor at the top is the same call, animated:

import tsdynamics as ts

traj = ts.systems.Lorenz().run(final_time=100.0, dt=0.01)
p = ts.plot(traj, animate=True)
p.style(axes=False).trail(None).camera(spin=0.4)      # full curve, no axes, rotate
p.animate(fps=30, duration=10, loop=True)
p.save("lorenz.gif")

A taste of the analysis layer

import numpy as np, tsdynamics as ts

# Poincaré section of the Rössler attractor (root-refined crossings)
section = ts.analysis.poincare_section(ts.systems.Rossler(), plane=("y", 0.0, "up"), crossings=500)

# Fixed points of the Hénon map, with stability — the repr IS the report
print(ts.analysis.fixed_points(ts.systems.Henon()))
# FixedPointSet  2 points · 0 stable, 2 unstable   (Henon)
#     [0] x* = [-1.1314 -0.3394]  unstable  |λ|max = 3.26
#     [1] x* = [0.6314 0.1894]  unstable  |λ|max = 1.924

# Maximal Lyapunov exponent — no Jacobian needed
ts.analysis.lyapunov_spectrum(ts.systems.Lorenz(), k=1, ic=[1, 1, 1])     # ≈ 0.90

Plus: attractors & basins of any flow or map, correlation/Rényi fractal dimensions, RQA (recurrence quantification), delay embedding (Takens, optimal τ, Cao/FNN), periodic orbits (shooting, Davidchack–Lai), numerical interval search for fixed points, GALI, the 0–1 chaos test & Hunt–Ott expansion entropy, and Lyapunov exponents from a bare time series (Kantz/Rosenstein).

Highlights

  • Four families, one interface — ODEs, DDEs, SDEs and discrete maps all answer the same run verb and the same stepping protocol (reinit / step / state / time). Each analysis documents the families and inputs it supports; ts.analysis.find(system) lists compatible routines.

  • A small surface — tsdynamics.<TAB> is 11 names, lorenz.<TAB> is 20, and every analysis is a free function whose first argument is its subject (ts.analysis.lyapunov_spectrum(lorenz)). A name that moved raises an error printing its new address; that error is the migration guide.

  • 177 built-in systems with literature parameters (142 ODEs, 26 maps, 6 DDEs, 3 SDEs).

  • Native engine: equations lower to a Rust engine in-process and run on a built-in Cranelift JIT (or a bit-for-bit identical SSA-tape interpreter); ordinary parameters are runtime values, so changing them reuses the tape. Structural parameters and delay values require fresh lowering. The engine writes no compilation cache to disk.

  • For adaptive ODE solvers, dt samples, rtol decides — the output grid and the accuracy knob are separate. The adaptive steppers use genuine dense output, so a coarse dt is cheap without being less accurate, and max_step= is there when you need to bound the step explicitly. Defaults are rtol=1e-9 / atol=1e-12.

  • Composition — a Poincaré section of a flow is a discrete map, so ts.analysis.orbit_diagram(ros.poincare("y", 0.0), "c", values) draws the bifurcation diagram of a flow in one line.

  • Backend-neutral plotting — one Plot renders to matplotlib, plotly (interactive + animated HTML), three.js, or JSON, with a fluent styling/theming vocabulary and registries for transforms, primitives, themes and renderers.

Install

pip install tsdynamics            # or: uv add tsdynamics

A prebuilt abi3 wheel (manylinux / musllinux / macOS / Windows) bundles the native Rust engine. No Rust toolchain and no C compiler needed to install or run. Optional plotting extra: tsdynamics[plot,interactive] (matplotlib, plotly).

Development

git clone https://github.com/El3ssar/TSDynamics && cd TSDynamics
uv sync --group dev --group docs
make test                                # change-scoped fast tier (the loop)
make test-slow                           # change-scoped slow tier
make test-all                            # whole fast tier — pre-push sanity
TSD_DOCS_FIGURES=0 uv run mkdocs serve   # docs preview

The suite is registry-driven — every test is parametrized over all 177 systems — so a plain pytest is thousands of items. make test runs only what your diff touches, which is what CI does too.

Releases are automated: conventional-commit PR titles drive semantic-release on merge. See CONTRIBUTING.

License

MIT © Daniel Estevez

Metadata

Release files for tsdynamics 6.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tsdynamics 6.0.3
File Size Uploaded Provenance
tsdynamics-6.0.3.tar.gz 1.7 MB With provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for tsdynamics 6.0.3
File
tsdynamics-6.0.3-cp312-abi3-win_amd64.whl CPython 3.12 abi3 Windows x86-64 Details
tsdynamics-6.0.3-cp312-abi3-musllinux_1_2_x86_64.whl CPython 3.12 abi3 Linux musl 1.2+ x86-64 Details
tsdynamics-6.0.3-cp312-abi3-musllinux_1_2_aarch64.whl CPython 3.12 abi3 Linux musl 1.2+ ARM64 Details
tsdynamics-6.0.3-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.12 abi3 Linux glibc 2.17+ x86-64 Details
tsdynamics-6.0.3-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.12 abi3 Linux glibc 2.17+ ARM64 Details
tsdynamics-6.0.3-cp312-abi3-macosx_11_0_arm64.whl CPython 3.12 abi3 macOS 11.0+ ARM64 Details
tsdynamics-6.0.3-cp312-abi3-macosx_10_12_x86_64.whl CPython 3.12 abi3 macOS 10.12+ x86-64 Details

Total release size: 25.5 MB

Release files / tsdynamics-6.0.3.tar.gz

Download URL tsdynamics-6.0.3.tar.gz
Size 1.7 MB
Tags Source
SHA-256 checksum
How to use checksums
871e5357b9eecbef8eaf8304837c2cb34daa2aa341045fa7959095ded41ee5d6
BLAKE2b-256 checksum
How to use checksums
ceeef28743162e18f98aa413713315f22824e37a9dcd1fcf38a0c58a7d680c7f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Release files / tsdynamics-6.0.3-cp312-abi3-win_amd64.whl

Download URL tsdynamics-6.0.3-cp312-abi3-win_amd64.whl
Size 3.6 MB
Tags CPython 3.12 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
e4bde76a77cb7884ae151cb5cdf2244a5cd21e88ae96dad46bfb336aa3e0ff99
BLAKE2b-256 checksum
How to use checksums
78e6899af0738fb86f5939351af74012f224bb0a1e9c6ab21701ea27df622a7c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Release files / tsdynamics-6.0.3-cp312-abi3-musllinux_1_2_x86_64.whl

Download URL tsdynamics-6.0.3-cp312-abi3-musllinux_1_2_x86_64.whl
Size 3.9 MB
Tags CPython 3.12 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
7caade59e068b9ca9d24aa4b7116d901749260fec759e38cd1681e0c9cfc3693
BLAKE2b-256 checksum
How to use checksums
4b6a14f712cc3e9059b0feb4d308283e475e03bf5436120a623ab7a77f56e222
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Release files / tsdynamics-6.0.3-cp312-abi3-musllinux_1_2_aarch64.whl

Download URL tsdynamics-6.0.3-cp312-abi3-musllinux_1_2_aarch64.whl
Size 3.2 MB
Tags CPython 3.12 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
a5ec1cb504ab2a319e26e6b270a2271e79d1fdbfc5087c6ae391b5155d35a82e
BLAKE2b-256 checksum
How to use checksums
06320404b6076a43e7f7119e544d0556e3f2fbd6c27c84392cbb8c6c217167e2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Release files / tsdynamics-6.0.3-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL tsdynamics-6.0.3-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 3.6 MB
Tags CPython 3.12 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
b4b74f81da2a5648072994d42d3deb83416717d160470854d7c9f8c05fbb51c8
BLAKE2b-256 checksum
How to use checksums
5bee5d5cec3e82b9a99caa60ee3cab8885506b853748c6cac8c6220cc675fe39
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Release files / tsdynamics-6.0.3-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL tsdynamics-6.0.3-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 3.0 MB
Tags CPython 3.12 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
fd9cc0f05cec0390cb7d85d8ebe41828b436e5f093aed10391e97c4dd527a8f7
BLAKE2b-256 checksum
How to use checksums
da5dacda6b0f7c238bd5cc07cac6be4a5fc8cb18bfdc51572f399e7d4363a84b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Release files / tsdynamics-6.0.3-cp312-abi3-macosx_11_0_arm64.whl

Download URL tsdynamics-6.0.3-cp312-abi3-macosx_11_0_arm64.whl
Size 2.9 MB
Tags CPython 3.12 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
f6bc96dc7c6bc85a0915eccd6c51d4bf702d368147ee9ee24c7f9edaab75a8a3
BLAKE2b-256 checksum
How to use checksums
1eaf2c86b7334f0cb01bf6457669f0a9174caa3e32dc6ef1b964fecdeff6439a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Release files / tsdynamics-6.0.3-cp312-abi3-macosx_10_12_x86_64.whl

Download URL tsdynamics-6.0.3-cp312-abi3-macosx_10_12_x86_64.whl
Size 3.5 MB
Tags CPython 3.12 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
12b2fb270e499f3e74f1bb825106bdd0a3aa64ee2c1a1bd6cadb9b9a356bd735
BLAKE2b-256 checksum
How to use checksums
ab8af4d241bb678e0909a7d0f3efd13aac26fd909aad63e4a57e5596e4a1898c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Security for tsdynamics 6.0.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 8 files in this release have been uploaded with provenance metadata.

Select from 8 files

Attestation for tsdynamics-6.0.3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

6.0.3 This release

8 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page