# Ellipsoidal Toolbox for Python

A Python port of the [MATLAB Ellipsoidal Toolbox](https://code.google.com/archive/p/ellipsoids/) (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

```bash
# 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

```python
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

```python
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:

```bash
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

```bash
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](LICENSE).
