Ellipsoidal calculus and reachability analysis for linear dynamical systems
Project description
Ellipsoidal Toolbox for Python
A Python port of the MATLAB Ellipsoidal Toolbox (v3), originally developed by Alex A. Kurzhanskiy and Pravin Varaiya at UC Berkeley.
This package provides ellipsoidal calculus and reachability analysis for linear dynamical systems — the same functionality as the original MATLAB toolbox, rebuilt for modern Python.
Features
- Ellipsoid class — create, transform, compare, and query ellipsoids in any dimension
- Hyperplane class — define halfspaces for intersection operations
- Minkowski sum & difference — tight external and internal ellipsoidal approximations
- Intersection approximations — ellipsoid–ellipsoid, ellipsoid–halfspace, multi-ellipsoid
- Distance computation — point, hyperplane, and ellipsoid-to-ellipsoid distances
- Linear systems — continuous-time (LTI/LTV) and discrete-time, with control and disturbance bounds
- Reachability analysis — external and internal reach set/tube approximations via ODE integration or matrix recurrences
- Reach tube operations — cut, projection, evolve, refine, intersect
- Visualization — 1D intervals, 2D boundaries, 3D surfaces, reach tube plots
Installation
# Clone the repository
git clone https://github.com/pranavbhatt/ellipsoidal-toolbox.git
cd ellipsoidal-toolbox
# Install in editable mode with all dependencies
pip install -e ".[all]"
# Or install just the core (numpy + scipy only)
pip install -e .
Dependency groups
| Install command | What you get |
|---|---|
pip install -e . |
Core: numpy, scipy |
pip install -e ".[sdp]" |
+ cvxpy (for SDP-based intersection/union) |
pip install -e ".[viz]" |
+ matplotlib (for plotting) |
pip install -e ".[all]" |
Everything above |
pip install -e ".[dev]" |
Everything + pytest |
Quick Start
import numpy as np
from ellipsoidal_toolbox.core.ellipsoid import Ellipsoid
from ellipsoidal_toolbox.visualization import plot_ellipsoid
# Create a 2D ellipsoid
E = Ellipsoid([2.0, -1.0], [[2, -1], [-1, 1]])
# Support function
val, boundary_pt = E.rho(np.array([1.0, 0.0]))
# Affine transformation
A = np.array([[0.5, -1], [0, 1]])
E_mapped = A @ E + np.array([3.0, 0.0])
# Plot
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
plot_ellipsoid(E, ax=ax, color="blue", label="Original")
plot_ellipsoid(E_mapped, ax=ax, color="red", label="Transformed")
ax.legend(); ax.set_aspect("equal"); plt.show()
Reachability analysis
from ellipsoidal_toolbox.systems.linsys import LinSys
from ellipsoidal_toolbox.systems.reach import reach_ea, reach_ia
from ellipsoidal_toolbox.visualization import plot_ea_tube, plot_ia_tube
# Define a 2D linear system
A = np.array([[0, -10], [2, -8]])
B = np.array([[10, 0], [0, 2]])
U = Ellipsoid(np.zeros(2), np.eye(2))
sys = LinSys(A, B, U)
# Compute reach tubes
X0 = Ellipsoid(np.zeros(2), 1e-5 * np.eye(2))
L0 = np.eye(2)
rs_ea = reach_ea(sys, X0, L0, (0, 10), N_steps=80)
rs_ia = reach_ia(sys, X0, L0, (0, 10), N_steps=80)
# Plot
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(10, 7))
ax = fig.add_subplot(111, projection="3d")
plot_ea_tube(rs_ea, ax=ax, color="C0", alpha=0.12)
plot_ia_tube(rs_ia, ax=ax, color="C2", alpha=0.12)
plt.show()
Demos
Three demo scripts (mirroring the original MATLAB ell_demo1/2/3) are included:
python demos/demo1_ellipsoidal_calculus.py # Core operations (10 figures)
python demos/demo2_visualization.py # Plotting showcase (5 figures)
python demos/demo3_reachability.py # Reach sets & tubes (12 figures)
Figures are saved to demos/output/.
Running Tests
pip install -e ".[dev]"
pytest
520 tests, all passing.
Documentation
- User Guide:
docs/user_guide.tex— comprehensive usage guide with math background, API reference, code examples, and MATLAB migration guide - Porting Guide:
docs/porting_guide.tex— developer-facing: porting phases, bug log, technical decisions
Both are LaTeX files ready for Overleaf compilation.
Project Structure
ellipsoidal-toolbox/
├── src/ellipsoidal_toolbox/ # Installable package
│ ├── core/ # Ellipsoid, Hyperplane, helpers
│ ├── calculus/ # Minkowski ops, intersection, distance
│ ├── systems/ # LinSys, ODE utils, reach computation
│ └── visualization/ # Plotting (ellipsoids + reach tubes)
├── tests/ # 520 unit tests
├── demos/ # 3 demo scripts + output figures
├── docs/ # LaTeX documentation
├── pyproject.toml # Package metadata & build config
└── README.md
Credits
- Python port: Pranav Bhatt
- Original MATLAB Toolbox: Alex A. Kurzhanskiy and Pravin Varaiya, UC Berkeley
- Reference: A. A. Kurzhanskiy and P. Varaiya, "Ellipsoidal Toolbox," Technical Report EECS-2006-46, UC Berkeley, 2006
License
BSD 3-Clause License. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ellipsoidal_toolbox-1.0.0.tar.gz.
File metadata
- Download URL: ellipsoidal_toolbox-1.0.0.tar.gz
- Upload date:
- Size: 77.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2edc1c45a90cb64e77bc92b550022f770389348343625cefefe8ec2d8aa31af2
|
|
| MD5 |
0008670ac3753aaf78eeb140fe163aab
|
|
| BLAKE2b-256 |
f44c4ca7a86871e51fff1fd763b095b633de9823d29e252209bf59492a4a6bcb
|
Provenance
The following attestation bundles were made for ellipsoidal_toolbox-1.0.0.tar.gz:
Publisher:
workflow.yml on Pranman1/ellipsoidal-toolbox
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ellipsoidal_toolbox-1.0.0.tar.gz -
Subject digest:
2edc1c45a90cb64e77bc92b550022f770389348343625cefefe8ec2d8aa31af2 - Sigstore transparency entry: 1109414375
- Sigstore integration time:
-
Permalink:
Pranman1/ellipsoidal-toolbox@54a38e1f8b69b724756708668f14e5b8f6c8a377 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/Pranman1
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@54a38e1f8b69b724756708668f14e5b8f6c8a377 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ellipsoidal_toolbox-1.0.0-py3-none-any.whl.
File metadata
- Download URL: ellipsoidal_toolbox-1.0.0-py3-none-any.whl
- Upload date:
- Size: 50.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f5acc43cf2c25d153e55f39512fde8e7fb815e4711806fc268bbf48548a32f14
|
|
| MD5 |
dd4ffd2ed35f0278ab2d2bc1311f91a2
|
|
| BLAKE2b-256 |
0cc57628920bcd1d48d92fb8bc77227b9ab2441ffa7b012736d9e6ca5867d747
|
Provenance
The following attestation bundles were made for ellipsoidal_toolbox-1.0.0-py3-none-any.whl:
Publisher:
workflow.yml on Pranman1/ellipsoidal-toolbox
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ellipsoidal_toolbox-1.0.0-py3-none-any.whl -
Subject digest:
f5acc43cf2c25d153e55f39512fde8e7fb815e4711806fc268bbf48548a32f14 - Sigstore transparency entry: 1109414378
- Sigstore integration time:
-
Permalink:
Pranman1/ellipsoidal-toolbox@54a38e1f8b69b724756708668f14e5b8f6c8a377 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/Pranman1
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@54a38e1f8b69b724756708668f14e5b8f6c8a377 -
Trigger Event:
push
-
Statement type: