Skip to main content

DiffiLQRax logo

Pylint Python Package Python Publish PyPI version DOI Documentation Documentation Status

Diffilqrax: Differentiable optimal control

What is it?

Diffilqrax is a JAX library for LQR and iterative LQR (iLQR) optimal control. It provides:

  • Sequential and parallel solvers. The sequential solvers use a Riccati recursion (lqr.solve_lqr, ilqr.ilqr_solver). The parallel solvers use an associative scan with O(log T) depth (plqr.solve_plqr, parallel_ilqr.pilqr_solver).
  • Robust iLQR. It uses adaptive Levenberg–Marquardt regularisation and an Armijo line search, and stops based on the KKT conditions.
  • Exact implicit gradients. diff_lqr.dlqr, diff_ilqr.dilqr and their parallel versions pdlqr and pdilqr define custom VJPs, so jax.grad differentiates the optimal trajectory with respect to the dynamics and cost parameters without backpropagating through the solver iterations.
  • Batched solves. batch.batched_ilqr_solver and batch.batched_dilqr solve many problems that share a model, with vmap, chunked lax.map or shard_map across devices.

Note on reverse mode. The solvers run as a lax.while_loop by default (loop="while"), so jax.grad cannot backpropagate through ilqr_solver or pilqr_solver directly. To get gradients of the solution, use dilqr, pdilqr or batched_dilqr. To backpropagate through the iterations themselves, pass loop="scan". This stores every iteration and always runs all max_iter of them under vmap.

Installation

From PyPI, with pip or uv:

pip install diffilqrax
uv pip install diffilqrax       # into the active environment
uv add diffilqrax               # as a dependency of a uv project

The latest version straight from GitHub:

uv pip install "git+https://github.com/ThomasMullen/diffilqrax"

For development, from a local clone:

git clone git@github.com:ThomasMullen/diffilqrax.git
cd diffilqrax
uv pip install -e ".[dev]"      # or: pip install -e ".[dev]"   (tests and linting)
uv pip install -e ".[doc]"      # documentation
uv build                        # sdist + wheel in dist/

Importing diffilqrax enables JAX double precision (jax_enable_x64).

Quick example

This example swings a pendulum up from hanging down to upright:

import jax.numpy as jnp
from diffilqrax.ilqr import ilqr_solver
from diffilqrax.diff_ilqr import dilqr
from diffilqrax.typs import System, ModelDims, iLQRParams, PendulumParams

dims = ModelDims(n=2, m=1, horizon=100, dt=0.05)

def dynamics(t, x, u, theta):          # x = [angle, angular velocity]
    acc = -theta.g / theta.l * jnp.sin(x[0]) + u[0] / (theta.m * theta.l**2)
    return x + dims.dt * jnp.stack([x[1], acc])

def cost(t, x, u, theta):
    return 0.01 * jnp.sum(u**2)

def costf(x, theta):
    return 10.0 * ((x[0] - jnp.pi) ** 2 + x[1] ** 2)

model = System(cost, costf, dynamics, dims)
params = iLQRParams(x0=jnp.zeros(2), theta=PendulumParams(m=1.0, l=1.0, g=9.81))
Us_init = jnp.zeros((dims.horizon, dims.m))

(Xs, Us, lambdas), total_cost, cost_history = ilqr_solver(model, params, Us_init, max_iter=200)

# differentiable version: tau = [x_t, u_t], with implicit gradients w.r.t. params
tau = dilqr(model, params, Us_init, max_iter=200)

More examples are in the documentation notebooks (docs/source/examples/) and in examples/.

Documentation

The documentation is hosted at https://thomasmullen.github.io/diffilqrax/.

Build the docs locally (this also needs pandoc, for example brew install pandoc):

pip install -e ".[doc]"
make -C docs html
open docs/build/html/index.html

Tests

pytest tests/ -m "not slow and not heavy"   # quick tier, as run in CI
pytest tests/ -m "not slow"                  # fast suite: adds the heavy cases
pytest tests/ -m slow                        # large-dimension tests

The heavy cases (listed in tests/conftest.py) are too slow or memory-hungry for a GitHub runner and re-check properties that a cheaper test already covers. CI runs the quick tier; the full tiers can be started by hand from the "Python package" workflow.

Benchmarks import the shared test problems from tests/, so run them as modules from the repository root, for example python -m benchmarks.timing --quick.

The tests run on the CPU by default. Set DIFFILQRAX_TEST_PLATFORM=gpu to run them on a GPU instead.

Design principle

DiffiLQRax Deisgn Principle

License

This project is licensed under the Apache License 2.0. See the LICENSE file for details.

Acknowledgments

This project has received funding from the European Union’s Horizon 2020 research and innovation programme under the Marie Skłodowska-Curie grant agreement #813457.

Metadata

Release files for diffilqrax 1.0.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 diffilqrax 1.0.0
File Size Uploaded Provenance Actions
diffilqrax-1.0.0.tar.gz 83.9 kB Without provenance Details for diffilqrax-1.0.0.tar.gz

Built distribution (wheel)

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

Total release size: 137.5 kB

Release files / diffilqrax-1.0.0.tar.gz

Download URL diffilqrax-1.0.0.tar.gz
Size 83.9 kB
Tags Source
SHA-256 checksum
How to use checksums
7a0ebb3d9fda60585808d6408e4f6af225edb2a16dab016763b0e18fffce0776
BLAKE2b-256 checksum
How to use checksums
c80290860f637e608b6c7db208101ac57bd5129cf113247ceb488de4f653cc94
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / diffilqrax-1.0.0-py3-none-any.whl

Download URL diffilqrax-1.0.0-py3-none-any.whl
Size 53.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
488aef22cc88b22d367d52903f1ab575de385a3eb5d668b63ba13e7a0485cb02
BLAKE2b-256 checksum
How to use checksums
66803a2c0cfbf7c34cde5d9ae51a232b83d1cdb5d7c60a2a742b4c1ae8216caa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for diffilqrax 1.0.0

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