Skip to main content

koopman-dmd

PyPI Python versions License: MIT

Dynamic Mode Decomposition (DMD) with Koopman operator theory extensions, with a Rust core.

DMD extracts spatiotemporal coherent structures from time-series data, giving a linear operator that approximates the dynamics of a possibly nonlinear system. This package wraps the koopman-dmd Rust crate via PyO3, so the numerics run at native speed with no BLAS/LAPACK installation required.

Installation

pip install koopman-dmd

The distribution is named koopman-dmd; the import name is koopman_dmd:

import koopman_dmd

Prebuilt wheels are published for Linux (x86_64, aarch64), macOS (x86_64, arm64), and Windows (x86_64) on Python 3.9+. Installing from source requires a Rust toolchain.

Quick start

Data is passed as a NumPy array with one row per variable and one column per time step.

import numpy as np
import koopman_dmd

# A 2-variable oscillating signal, shape (2, 100)
t = np.linspace(0, 10, 100)
x = np.vstack([np.sin(t), np.cos(t)])

d = koopman_dmd.DMD(x, rank=2, dt=t[1] - t[0])

print(d.eigenvalues)      # (r, 2) array of [real, imag]
print(d.modes)            # DMD modes
print(d.singular_values)

# Forecast 10 steps beyond the input
future = d.predict(10)

# Per-mode frequency, growth rate, amplitude, and stability
for mode in d.spectrum():
    print(mode)

Note that the data is passed to the constructor — there is no separate fit() step.

DMD

koopman_dmd.DMD(x, rank=None, center=False, dt=1.0, lifting=None, lifting_param=None)

rank=None selects a truncation rank automatically (99% of variance). lifting enables Extended DMD and accepts "polynomial", "polynomial_cross", "trigonometric", or "delay", with the degree / harmonic count / delay count given by lifting_param.

Properties: rank, data_dim, center, dt, eigenvalues, modes, amplitudes, singular_values

Methods:

Method Returns
predict(n_ahead, x0=None, method="modes") forecast array; method is "modes" or "matrix"
reconstruct(n_steps, modes_subset=None) reconstruction from all or selected modes
spectrum() per-mode frequency, growth rate, amplitude, stability — uses the dt given at construction
stability() (is_stable, is_unstable, is_marginal, spectral_radius)
error() (rmse, mae, mape, rel_err)
dominant_modes(n, criterion="amplitude") indices of the n most significant modes
residual() (absolute, relative)

Extended DMD with lifting

d = koopman_dmd.DMD(x, lifting="polynomial", lifting_param=2)

DMDc

DMD with control (Proctor, Brunton & Kutz 2016) — identifies the forced linear system x_{t+1} = A x_t + B u_t from snapshot pairs and control inputs.

koopman_dmd.DMDc(x1, x2, u=None, rank_input=None, rank_output=None, dt=1.0, known_b=None)

Unlike DMD, which takes one contiguous trajectory, DMDc takes explicit pair matrices: x1 holds states at time t, x2 the states one step later, and u the input applied during each transition, so columns may come from many concatenated trajectories. u=None fits an autonomous multi-trajectory model from the pairs. Passing known_b pins the input matrix and estimates only A — preferred whenever the input coupling is known by construction, and required for closed-loop (state-feedback) data, where joint identification is biased. rank_output optionally projects onto the leading SVD basis of x2, giving reduced operators a_tilde, b_tilde for model reduction.

Properties: a, b, a_tilde, b_tilde, basis, eigenvalues, singular_values, rank_input, rank_output, dt, n_states, n_inputs

Methods:

Method Returns
predict(u=None, x0=None, n_ahead=None) states from stepping x_{t+1} = A x_t + B u_t; the columns of u set the horizon, or n_ahead steps of zero input
spectrum() per-mode frequency, growth rate, stability of the identified operator
stability() (is_stable, is_unstable, is_marginal, spectral_radius)
# Recover A and B from a forced linear system driven by a probe input
d = koopman_dmd.DMDc(x1, x2, u, rank_input=3)
print(d.a)                     # state-transition matrix
print(d.b)                     # input matrix
pred = d.predict(u=u_future)   # simulate under a new input sequence

The input must be persistently exciting (and not pure state feedback) for the joint identification to be well-posed.

HankelDMD

Time-delay embedding, for scalar signals or systems with few measured variables.

koopman_dmd.HankelDMD(y, delays=None, rank=None, dt=1.0)

Properties: rank, delays, n_obs, residual, eigenvalues Methods: predict(n_ahead), reconstruct(n_steps)

y = np.sin(np.linspace(0, 4 * np.pi, 200)).reshape(1, -1)
h = koopman_dmd.HankelDMD(y, delays=20)
print(h.rank)          # 2 — chosen automatically
print(h.predict(10))

Leaving rank=None is usually right. Requesting a rank higher than the signal actually supports (a pure sinusoid is rank 2) leaves the reduced operator near-singular, and the eigendecomposition can fail with NoConvergence.

GLA

Generalized Laplace Analysis — computes Koopman eigenfunctions directly via weighted time averages.

koopman_dmd.GLA(y, eigenvalues=None, n_eigenvalues=5, tol=1e-6, max_iter=None)

Properties: n_obs, n_time, eigenvalues, convergence, residuals Methods: predict(n_ahead), reconstruct(modes_to_use=None)

Phase space analysis

For area-preserving and chaotic maps.

Maps and their params keys — params is a dict, and omitting it uses defaults:

map_name State dim Parameters
"standard" (Chirikov) 2 epsilon
"froeschle" 4 epsilon, eta
"extended_standard" 3 epsilon, delta
"henon" 2 a, b
"logistic" 1 r

Observables: "identity", "sin_pi", "cos_pi", "sin_pi_xy", "cos_pi_xy", "sin_2pi", "cos_2pi", "trig_product"

Initial conditions are NumPy arrays, not lists.

ic = np.array([0.5, 0.3])

# Iterate a map from an initial condition
traj = koopman_dmd.generate_trajectory("standard", ic, 1000, {"epsilon": 0.12})

# Harmonic time average at a single initial condition
mag, phase, hta_re, hta_im = koopman_dmd.harmonic_time_average(
    "standard", ic, "sin_pi", 0.5, 10000, {"epsilon": 0.12}
)

# Mesochronic plot over a grid (parallelized in Rust).
# Returns (hta_magnitude, phase, x_coords, y_coords).
hta, phase, x_coords, y_coords = koopman_dmd.mesochronic_compute(
    "standard", (0.0, 1.0), (0.0, 1.0), 100, "sin_pi", 0.5, 10000, {"epsilon": 0.12}
)

# Classify orbits as regular, resonating, or chaotic from HTA magnitudes
labels = koopman_dmd.classify_phase_space(hta.ravel())

# Convergence history of the time average
conv = koopman_dmd.hta_convergence("standard", ic, "sin_pi", 0.5, 10000, {"epsilon": 0.12})

Other languages

Development

pip install maturin pytest numpy
maturin develop --release
pytest tests/

References

  • Schmid, P.J. (2010). Dynamic mode decomposition of numerical and experimental data. Journal of Fluid Mechanics, 656, 5–28.
  • Kutz, J.N., Brunton, S.L., Brunton, B.W., & Proctor, J.L. (2016). Dynamic Mode Decomposition: Data-Driven Modeling of Complex Systems. SIAM.
  • Mezić, I. (2020). Spectrum of the Koopman operator, spectral expansions in functional spaces, and state-space geometry. arXiv:2009.05883
  • Levnajić, Z. & Mezić, I. (2014). Ergodic theory and visualization. arXiv:0808.2182v2

License

MIT — see LICENSE.

Release files for koopman-dmd 0.2.0

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

Source distribution (sdist)

Source distribution for koopman-dmd 0.2.0
File Size Uploaded
koopman_dmd-0.2.0.tar.gz 81.5 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for koopman-dmd 0.2.0
File
koopman_dmd-0.2.0-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details
koopman_dmd-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.9 abi3 Linux glibc 2.17+ x86-64 Details
koopman_dmd-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.9 abi3 Linux glibc 2.17+ ARM64 Details
koopman_dmd-0.2.0-cp39-abi3-macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64 Details
koopman_dmd-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl CPython 3.9 abi3 macOS 10.12+ x86-64 Details

Total release size: 5.1 MB

Release files / koopman_dmd-0.2.0.tar.gz

Download URL koopman_dmd-0.2.0.tar.gz
Size 81.5 kB
Tags Source
SHA-256 checksum
How to use checksums
230eed428da55b7357d2792075808642314cf6b1dd2de958d690f9e8dd9424cd
BLAKE2b-256 checksum
How to use checksums
10297ff2baa1836c0cd947d62804d6f99117acabcbecc484bffc046c0d1cff82
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 Aug 20, 2026.

Transparency log

Release files / koopman_dmd-0.2.0-cp39-abi3-win_amd64.whl

Download URL koopman_dmd-0.2.0-cp39-abi3-win_amd64.whl
Size 999.9 kB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
4ce9b0bb53b0c0d02fd33471b4640463364a68f2ceaf37318520363b96d241fa
BLAKE2b-256 checksum
How to use checksums
3b99dbe05d9120092ad584d110e3590f8174fb713f02e545cd3e65997f0b3990
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 Aug 20, 2026.

Transparency log

Release files / koopman_dmd-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL koopman_dmd-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 1.3 MB
Tags CPython 3.9 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
baf91c92c6320582ef5c0c018484c23e307d5a5f3a8781632c91245b8da947d4
BLAKE2b-256 checksum
How to use checksums
a6e4833767cec3707e1d66f62e3a4cdea90928903d199b38bb6bd19cf288b4ae
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 Aug 20, 2026.

Transparency log

Release files / koopman_dmd-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL koopman_dmd-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 887.4 kB
Tags CPython 3.9 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
198a17904a2ce65615506c8f755ed3cfcecdbb54e0234c5eb2ab310896ab8875
BLAKE2b-256 checksum
How to use checksums
e65119018ca0dbe905b61d659969d0af3734cc6c3891775eb3772fb430ef44dc
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 Aug 20, 2026.

Transparency log

Release files / koopman_dmd-0.2.0-cp39-abi3-macosx_11_0_arm64.whl

Download URL koopman_dmd-0.2.0-cp39-abi3-macosx_11_0_arm64.whl
Size 762.7 kB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
eea54f3e15895522398a57d6476725982cbc87134ffaf8874cf07c71a512ee5e
BLAKE2b-256 checksum
How to use checksums
23a9b57e4860dd2f85ef128c7911c5680002130ae3e8592d336ae5be9056cfed
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 Aug 20, 2026.

Transparency log

Release files / koopman_dmd-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl

Download URL koopman_dmd-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl
Size 1.1 MB
Tags CPython 3.9 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
097514ac879fbb0cad12bfb8c313be01fb004a80ef53a6bb406845437767f2ec
BLAKE2b-256 checksum
How to use checksums
a7f9d86e8647815db2d86ebf2a6ca05bc5a18485183c81f3bde28bfe11da0b88
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 Aug 20, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

6 release files

0.1.0

6 release files

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