# dysts gives you 135 chaotic systems with the same three method calls

> dysts is a Python library that simulates hundreds of strange attractors behind one interface, with numba compiled right hand sides, JSON metadata for parameters and periods, and a resampling option that makes trajectories comparable across systems. It is a research code release with a published citation trail.

**GilpinLab/dysts** — Hundreds of strange attractors

- Repository: https://github.com/GilpinLab/dysts
- Stars: 560 · Forks: 75
- Language: Python
- License: Apache-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/gilpinlab-dysts

## One interface over a very large pile of differential equations

dysts is described as a library for analyzing hundreds of chaotic systems, and the package description puts it more simply: more than 100 strange attractors.

The scale is the point. The implementation notes say there are currently 135 continuous time models, including several delay differential equations, plus a separate module with 10 discrete maps which is currently being expanded. The acknowledgements say that two existing collections of named systems, from Jurgen Meier and J. C. Sprott, are both included in full.

So the library is an aggregation of published dynamical systems, not a general purpose ODE library. The value for a user is not that a particular equation is available, since a particular equation is a small amount of code, but that every system comes with the same metadata and the same conventions, and that a hundred and thirty five of them are guaranteed to behave the same way.

The audience is stated in the citation guidance. The README asks that you cite the papers if you use the code for published work, and lists two of them: Chaos as an interpretable benchmark for forecasting and data-driven modelling from NeurIPS 2021, and Model scale versus domain knowledge in statistical forecasting of chaotic systems from Physical Review Research in 2023.

Both papers are about using chaos as a benchmark. That tells you the intended use, and it is narrower than the phrase suggests at first glance.

## The three calls you actually need

The basic usage section is short because the API is.

You import a model and run a simulation with default initial conditions and parameter values.

```python
from dysts.flows import Lorenz

model = Lorenz()
sol = model.make_trajectory(1000)  # (1000, 3)
```

The comment on that line is the documentation of the return shape. A trajectory is a NumPy array with one row per time point and one column per state dimension, and for Lorenz that is three.

Second, you change a model's parameters and re-integrate.

```python
model = Lorenz(parameters={"beta": 0.7, "rho": 3, "signma": 0.1}, ic=[0.1, 0.0, 5])
sol = model.make_trajectory(1000)  # (1000, 3)
```

Note the initial conditions, passed as ic, and the parameters as a dictionary. The README's example spells one of the keys signma rather than sigma, which is a quirk of that snippet rather than something to copy. It is the kind of detail you only find by reading the code, and it is worth a moment of care if you are writing parameters from a paper.

Third, and the one that makes the library a benchmark rather than a toy, you can integrate new trajectories from all 135 chaotic systems with a custom granularity.

```python
from dysts.systems import make_trajectory_ensemble

all_out = make_trajectory_ensemble(100, resample=True, pts_per_period=75)
```

One call, all systems, the same output structure. That is what you want when the question is how a forecasting method behaves across a catalogue of dynamics rather than on one equation.

## Resampling is what makes trajectories from different systems comparable

The implementation notes are where the library earns its keep, and they are worth reading in full.

The right hand side of each dynamical equation is compiled using numba wherever possible, and ensembles of trajectories are vectorized where needed. That is the performance story.

The correctness story is the resampling behaviour. The default integration step is stored in each continuous time model's dt field, and this integration timestep was chosen based on the highest significant frequency observed in the power spectrum, with significance determined relative to random phase surrogates. The period field contains the timescale associated with the dominant frequency in each system's power spectrum.

Then the resampling option. When make_trajectory is used with the optional setting resample=True, integration is performed at the default dt, and the integrated trajectory is then resampled based on the period. The result is that trajectories have consistent dominant timescales across models, despite the models having different integration timesteps.

That is the single most important sentence in the README for anyone doing forecasting benchmarks. Without resampling you are comparing a method on trajectories sampled at different physical timescales, and any accuracy difference you measure may be an artefact of the sampling rather than of the model.

The metadata behind this is plain JSON. Attractor names, default parameter values, references and other metadata are stored in parseable JSON database files, chaotic_attractors.json for the flows and discrete_maps.json for the maps, and the parameter values are based on standard or published values. The default initial conditions were generated by running each model until the moments of the autocorrelation function all become stationary, which is a concrete, checkable rule rather than a hand picked triple of numbers.

## Installing it, and the optional pieces that matter

The installation is a single command from PyPI.

```bash
    pip install dysts
```

The core dependency list is short: numpy, scipy and tqdm. Python 3.10 or newer is required, and the package is built with uv-build. There are three optional dependency groups, and each maps to a distinct kind of work.

The benchmarks group pulls in darts, torch and pandas, which is what you need for the forecasting and training experiments. The numba group installs numba, which is what makes the compiled right hand sides work. And the extra group brings sdeint, hnswlib, statsmodels and scikit-learn, which are the analysis routines.

If you want the latest version with new features and bug fixes, the additional installation guide says to download and install directly from GitHub.

```bash
    pip install git+https://github.com/williamgilpin/dysts
```

And there is a separate installation for the optional precomputed trajectories and benchmark results, described as a large, static dataset, which comes from its own repository.

```bash
    pip install git+https://github.com/williamgilpin/dysts_data
```

A database of precomputed time series from each system is also hosted on HuggingFace, so you can get the data without generating anything locally.

Tests use the standard library unittest framework rather than pytest, and the command to run them is in the README.

```bash
python -m unittest discover tests
```

## What sits outside the package, and why the split exists

The contents section explains the layout, and it is a list of things that are deliberately not in the main package.

Code to generate novel skew-dynamical systems is in the skewgen branch, so the generator for new systems is versioned apart from the library of existing ones. Code to generate benchmark forecasting and training experiments is in a separate benchmarks repository, and the README notes that the benchmarks reported in the publications are stored there, with an overview in BENCHMARKS.md and individual task areas summarised in Jupyter notebooks.

The reason for the split is size and shape. The package is a library, the benchmarks are a body of experiment code and data, and the precomputed trajectories are a large static dataset. Keeping the last two out of the install means pip install dysts stays small and fast, and you opt into the heavy parts explicitly.

The demonstrations are a Jupyter notebook, demos.ipynb, at the repository root, with the full API documentation generated at gilpinlab.github.io/dysts. The repository also has a docs/ directory, a tests/ directory, an assets/ directory holding the logo image which is the montage of attractor plots, and a pyproject.toml with a dev dependency group of ruff, ipykernel and matplotlib.

For a user, the practical guidance is that the notebook is where the examples live, the API documentation is where the reference is, and the benchmarks repository is where the evaluation protocol is, and the last of those is the one to read first if your plan is to publish a comparison.

## Where dysts is the wrong tool

Three cases, and the first is a category error.

It is not a general numerical solver. The implementations are tuned to produce attractors: the integration timestep is chosen per system from the highest significant frequency in its power spectrum, the default initial conditions are generated by running the model until its autocorrelation moments become stationary, and the parameters come from published values. That is exactly what you want for a benchmark and exactly what you do not want if you are solving an initial value problem and checking the answer against an analytical solution.

The second is the optional dependencies as a practical matter. numba is in an optional group, and the compiled right hand sides are the performance story, so a plain install without the numba group gives you a correct but slow library. The same applies to the analysis routines, several of which, the README says, such as the calculation of the correlation dimension, use the nolds library, and if you reuse code that depends on nolds you are asked to credit that library and heed its licence.

The third is a licensing and versioning question that the repository itself leaves slightly open. The project metadata records the licence as Apache-2.0 and the LICENSE.md file is at the top of the repository, but the classifiers in pyproject.toml say License:: OSI Approved:: MIT License. That is a discrepancy worth resolving before you redistribute anything built on top of it.

On maintenance, the repository is not archived and the last push was on 2026-04-15, and the only release listed is 0.95 from 2024-10-03, which is also the version in pyproject.toml. So the code is being touched, but the published version is about two years old.

## Conclusion

Adopt dysts if you are benchmarking forecasting or data driven models on chaotic dynamics and want 135 continuous time systems and 10 discrete maps behind one interface, with trajectories that share a timescale. Do not adopt it as a general numerical solver, since the implementations are tuned to produce attractors rather than to be accurate for arbitrary initial value problems, and note the package metadata and the repository licence field disagree on the licence. Before you build on it, read the implementation notes about dt and period, and check the benchmarks repository for the evaluation protocol your paper needs.

## FAQ

### How do I install dysts?

Run pip install dysts for the published version, or pip install git+https://github.com/williamgilpin/dysts for the latest from GitHub. The optional precomputed trajectories and benchmark results are installed separately from dysts_data, and Python 3.10 or newer is required.

### How many chaotic systems does dysts include?

The implementation notes say there are currently 135 continuous time models, including several delay differential equations, plus a separate module with 10 discrete maps which is currently being expanded. The acknowledgements say the collection includes all systems from the named collections of Jurgen Meier and J. C. Sprott.

### What does the resample option do in dysts?

With resample=True, integration is performed at the model's default dt and the trajectory is then resampled based on the period field, which holds the timescale of the dominant frequency in that system's power spectrum. The result is trajectories with consistent dominant timescales across models despite different integration timesteps.

### What are the optional dependencies of dysts?

There are three optional groups: benchmarks, which pulls in darts, torch and pandas, numba, which enables the compiled right hand sides, and extra, which adds sdeint, hnswlib, statsmodels and scikit-learn for the analysis routines. The core dependencies are numpy, scipy and tqdm.

## Sources

- [GilpinLab/dysts on GitHub](https://github.com/GilpinLab/dysts)
- [Issues](https://github.com/GilpinLab/dysts/issues)
- [License: Apache-2.0](https://github.com/GilpinLab/dysts/blob/master/LICENSE)
- [README](https://github.com/GilpinLab/dysts/blob/master/README.md)
- [Releases](https://github.com/GilpinLab/dysts/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/gilpinlab-dysts
