Controllability of dynamical systems on graphs — who drives, who follows, and how much it costs.
Pure Rust, zero dependencies. Given a graph and a set of input (driver) nodes, compute whether the system is controllable, how much energy it takes to reach any state, and which nodes are the optimal drivers.
- Controllability rank — is the graph controllable from a given set of driver nodes?
- Controllability matrix — full
C = [B, AB, A²B, ..., Aⁿ⁻¹B]via Laplacian dynamics - Gramian matrix —
W = ∫ e^{At} B B^T e^{A^Tt} dtfor energy-optimal control - Control energy — minimum energy to transition between any two states
- Optimal driver selection — greedy algorithm to pick the best k drivers
- Zero dependencies — Jacobi eigenvalues, Gaussian elimination, all from scratch
A dynamical system on a graph evolves as dx/dt = -Lx + Bu, where L is the graph Laplacian and B maps control inputs to nodes. The controllability question: starting from any initial state, can you reach any target state by choosing the right inputs?
The answer depends on the graph's eigenvalues and eigenvectors. Distinct eigenvalues of -L + nonzero B participation in every eigenvector = full controllability from a single node on a path graph.
use spectral_control::{SpectralControl, path_graph, star_graph, complete_graph};
// Path graph: 0—1—2—3
let adj = path_graph(4);
let sc = SpectralControl::from_graph(adj);
// Single endpoint driver on a path gives full controllability
assert!(sc.is_controllable(&[0]));
// All nodes controlled → always full controllability
assert!(sc.is_controllable(&[0, 1, 2, 3]));
// Control energy from state A to state B
let energy = sc.control_energy(&[0, 1], &[0.0, 0.0, 0.0], &[1.0, 1.0, 1.0]);
// Find the optimal single driver node
let drivers = sc.optimal_driver_nodes(1);
// Star graph: hub should be a good driver
let star = star_graph(5);
let sc_star = SpectralControl::from_graph(star);
let best = sc_star.optimal_driver_nodes(1);| Method | Returns | Description |
|---|---|---|
SpectralControl::from_graph(adj) |
SpectralControl |
Build from adjacency matrix |
.controllability_rank(&inputs) |
usize |
Rank of controllability matrix |
.is_controllable(&inputs) |
bool |
Full controllability check |
.gramian(&inputs) |
Vec<Vec<f64>> |
Controllability Gramian |
.control_energy(&inputs, x0, xf) |
f64 |
Minimum energy for state transfer |
.optimal_driver_nodes(k) |
Vec<usize> |
Best k driver nodes (greedy) |
| Function | Description |
|---|---|
path_graph(n) |
Line graph |
star_graph(n) |
Star with hub at node 0 |
complete_graph(n) |
Fully connected |
Part of the SuperInstance spectral ecosystem:
- spectral-graph-core — Eigenvalues, CR, Fiedler vectors
- spectral-control — Who can steer the system and at what cost (this repo)
- spectral-transport — Random walk and diffusion distances
cargo test[dependencies]
spectral-control = { git = "https://github.com/SuperInstance/spectral-control" }MIT
Part of the SuperInstance ecosystem.