Skip to main content

Contrax

Differentiable control theory primitives for JAX.

CI Docs PyPI Downloads Python License: MIT

Contrax is a JAX-native systems, estimation, and control toolbox. MATLAB-familiar names at the API surface — ss, lqr, kalman, place — with jit, vmap, and grad behavior underneath.

Documentation · Getting started · API reference

Differentiable LQR tuning loop


Install

pip install contrax

Requires Python 3.11+ and JAX 0.9.2+. For GPU support, install JAX separately per the JAX installation guide before installing Contrax.

Upgrading from 0.1.0? Version 0.2.0 changes filter signatures, result fields, solver configuration and MHE indexing. Read the breaking changes and migration notes before updating callers.

Why Contrax

A controller design step can sit inside an ordinary differentiable objective instead of being a separate offline calculation:

import jax
jax.config.update("jax_enable_x64", True)

import jax.numpy as jnp
import contrax as cx

A = jnp.array([[1.0, 0.05], [0.0, 1.0]])
B = jnp.array([[0.0], [0.05]])
SYS = cx.dss(A, B, jnp.eye(2), jnp.zeros((2, 1)), dt=0.05)
X0 = jnp.array([1.0, 0.0])


def closed_loop_cost(log_q_diag, log_r):
    K = cx.lqr(SYS, jnp.diag(jnp.exp(log_q_diag)), jnp.exp(log_r)[None, None]).K
    _, xs, _ = cx.simulate(SYS, X0, lambda t, x: -K @ x, num_steps=80)
    return jnp.sum(xs**2) + 1e-2 * jnp.sum((xs[:-1] @ K.T) ** 2)


cost, (dq, dr) = jax.jit(jax.value_and_grad(closed_loop_cost, argnums=(0, 1)))(
    jnp.zeros(2), jnp.array(0.0)
)

This is the central Contrax idea: control primitives that behave like normal JAX building blocks.

Scope

Systems ss, dss, c2d, nonlinear_system, phs_system, canonical_J, schedule_phs, linearize, linearize_ss, phs_to_ss, series, parallel

Simulation lsim, simulate, rollout, step_response, impulse_response, initial_response, sample_system, foh_inputs

Continuous LTI lsim accepts an explicit sample grid with ZOH or FOH inputs. Simulation results report numerical status and step counts; sampled models retain integration diagnostics through model.step(t, x, u). Native Diffrax solvers and step-size controllers configure continuous integration.

Control lqr, lqi, dare, care, place, feedback, state_feedback, augment_integrator

Estimation kalman, ekf, ukf, rts, uks kalman_predict, kalman_update, kalman_step ekf_predict, ekf_update, ekf_step kalman_gain, mhe_objective, mhe, mhe_warm_start

Analysis ctrb, obsv, poles, evalfr, freqresp, dcgain, ctrb_gramian, obsv_gramian, lyap, dlyap, zeros, quadratic_rollout_cost

Diagnostics innovation_diagnostics, likelihood_diagnostics, ukf_diagnostics, smoother_diagnostics, phs_diagnostics, innovation_rms

Parameterization positive_exp, positive_softplus, spd_from_cholesky_raw, diagonal_spd, lower_triangular

Interoperability contrax.compat.python_control — optional bidirectional conversion with python-control (uv add control)

Lyapunov solvers return a validated result bundle:

result = cx.dlyap(A, Q, solver=cx.solvers.Lyapunov())
X = result.X  # Check result.successful before using an unfamiliar equation.

lyap and dlyap support implicit forward/reverse differentiation, stable-system doubling and explicit general dense solves. Automatic dense fallback is bounded to eight states. See analysis for the equation and failure contracts.

Solver Status

  • dare — structured doubling with implicit JVP/VJP, scale-aware residual and stability checks.
  • care — Hamiltonian stable-subspace solve with accepted Newton corrections and implicit JVP/VJP. Closely separated subspaces can limit accuracy.
  • place — design-time KNV0/YT pole placement with achieved-assignment and conditioning checks, solver configuration, and bounded SISO fallback.
  • ekf / ukf / rts / uks — linear and nonlinear filtering and smoothing with JIT, batching and differentiation support.
  • mhe — LBFGS-backed fixed-window MHE. Useful optimization-based estimation primitive; not a full NLP framework.

LTI workflows are the most mature slice. Nonlinear models, PHS support, and fixed-window MHE are real public capabilities, but they should be read with more explicit solver-maturity caution than the core discrete design path.

Development

git clone https://github.com/givani30/Contrax.git
cd Contrax
uv sync --group dev
uv run pre-commit install
uv run pytest tests/ -q

See CONTRIBUTING.md for contribution guidelines.

Acknowledgements

Contrax is built on top of several excellent JAX-ecosystem libraries:

  • JAX — the foundation: JIT compilation, autodiff, and vectorization.
  • Equinox — pytree-compatible modules used for all result bundles and system types.
  • Diffrax — ODE solvers powering simulate() on continuous-time models.
  • Optimistix — LBFGS solver backing mhe().
  • Lineax — linear solvers used in the estimation and Riccati paths.

The DARE implicit differentiation approach draws on trajax (Google) and the DiLQR approach (ICML 2025). The UKF sigma-point rules follow Wan & van der Merwe (2000).

Metadata

Release files for contrax 0.2.1

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

Source distribution (sdist)

Source distribution for contrax 0.2.1
File Size Uploaded Provenance Actions
contrax-0.2.1.tar.gz 128.9 kB Without provenance Details for contrax-0.2.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for contrax 0.2.1
File Interpreter ABI Platform Actions
contrax-0.2.1-py3-none-any.whl Python 3 none any Details for contrax-0.2.1-py3-none-any.whl

Total release size: 232.9 kB

Release files / contrax-0.2.1.tar.gz

Download URL contrax-0.2.1.tar.gz
Size 128.9 kB
Tags Source
SHA-256 checksum
How to use checksums
5bb2e0efd1afd6e1b688644fdeb115603d46c9c493370a9f17b688e99bd0a39c
BLAKE2b-256 checksum
How to use checksums
1b3660f2bcd5e0070d41c8122f0993ba582677b9fc71f125260b69123c3731d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / contrax-0.2.1-py3-none-any.whl

Download URL contrax-0.2.1-py3-none-any.whl
Size 104.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9323be8a28699b596a43f7acebab37a2b72d5d613eb4352e491c80638075a022
BLAKE2b-256 checksum
How to use checksums
f27caf7f685bb943b23752da743188ceb68461b174819fd4e51d6ad064de0b34
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for contrax 0.2.1

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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