Skip to main content

Exact custom-gradient ops for the linear Koopman recurrence (PyTorch + JAX)

Project description

koopman

CI PyPI

Exact, closed-form custom-gradient ops for the linear Koopman recurrence z_{t+1} = K @ z_t. Computes the full state sequence

Z = [z_0, K z_0, K^2 z_0, ..., K^T z_0]

with a single forward scan and an exact adjoint backwardO(T n^2) time and O(T n) memory — instead of taping every per-step matmul through autodiff. Available in a PyTorch flavor (torch.autograd.Function) and a JAX flavor (jax.custom_vjp).

Installation

Install only the backend you need:

pip install koopman[torch]      # PyTorch (CPU or GPU)
pip install koopman[jax-cpu]    # JAX on CPU
pip install koopman[jax-gpu]    # JAX on GPU (CUDA 12)

For a CPU-only PyTorch wheel (e.g. on free CI runners), install torch from the CPU index first, then the package:

pip install torch --index-url https://download.pytorch.org/whl/cpu
pip install koopman

Requires Python 3.10+.

Usage

PyTorch

import torch
from koopman.torch import linear_powers_sequence

n, T = 16, 1024
K = torch.randn(n, n, dtype=torch.float64, requires_grad=True)
z0 = torch.randn(n, dtype=torch.float64, requires_grad=True)

Z = linear_powers_sequence(K, z0, T)   # [T+1, n]
Z.sum().backward()                     # exact grad_K, grad_z0 via adjoint recurrence

There is also a torch.nn.Module wrapper, LinearPowersSequence(T), and the raw LinearPowersSequenceFn autograd function.

JAX

import jax
jax.config.update("jax_enable_x64", True)
import jax.numpy as jnp
from koopman.jax import linear_powers_sequence

n, T = 16, 1024
K = jax.random.normal(jax.random.PRNGKey(0), (n, n))
z0 = jax.random.normal(jax.random.PRNGKey(1), (n,))

Z = linear_powers_sequence(K, z0, T)   # [T+1, n]
loss = lambda K_, z0_: jnp.sum(linear_powers_sequence(K_, z0_, T))
gK, gz0 = jax.grad(loss, argnums=(0, 1))(K, z0)   # jit/vmap-friendly

Why a custom gradient?

Naive autodiff through the Python/lax.scan loop tapes all T matmuls and their activations, costing O(T n^2) memory. The backward here is the closed-form adjoint recurrence:

a_T      = grad_Z[T]
a_t      = grad_Z[t] + Kᵀ @ a_{t+1}        (t = T-1, ..., 0)
grad_K  += outer(a_{t+1}, z_t)
grad_z0  = a_0

It reuses the forward states (O(T n) memory) and avoids materializing the autodiff tape. See benchmarks/ for the comparison against naive autograd and expm-based baselines.

Development

pip install -e ".[dev]"
pytest tests/test_linear_powers_torch.py -v   # PyTorch
JAX_PLATFORMS=cpu pytest tests/test_linear_powers_jax.py -v   # JAX

License

Apache-2.0.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

koopman-0.1.0.tar.gz (11.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

koopman-0.1.0-py3-none-any.whl (10.9 kB view details)

Uploaded Python 3

File details

Details for the file koopman-0.1.0.tar.gz.

File metadata

  • Download URL: koopman-0.1.0.tar.gz
  • Upload date:
  • Size: 11.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for koopman-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c980b452d9c9821398db61507c539229e22a479362d1f7f274fdf3c90cccb7a7
MD5 8d9b6a0dfe5a6c7fa590a498a72bedf2
BLAKE2b-256 fffa535c58a4d140925a9c25f145b585b66e0bfea774ee330fcac4bfa4ada07e

See more details on using hashes here.

Provenance

The following attestation bundles were made for koopman-0.1.0.tar.gz:

Publisher: pypi.yaml on geekbeast/koopman

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file koopman-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: koopman-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for koopman-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 68dc9dc41f2a563e9bdc98041e2c6d16c079e83bbf82048cba5c167c32051884
MD5 3b7f0707e2b3973294fadc67b232be85
BLAKE2b-256 3eebd80512267d98eaee8a9ad4cc9f97a662ca027e2eee8b1eb1ded9a32ddc49

See more details on using hashes here.

Provenance

The following attestation bundles were made for koopman-0.1.0-py3-none-any.whl:

Publisher: pypi.yaml on geekbeast/koopman

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page