Φferromotion · textbook · chapter 9 rust → wasm · on-device

Make it linear

Linear systems are the ones we can actually predict and control — but almost nothing is linear. This chapter is about a trick that gets the good behaviour anyway: look at a nonlinear system through the right variables, and it moves in a straight line after all. It runs the same Rust operator-learning code the native tools use.

01 — the problemLinear is the easy case, and rare

If a system is linear, you own it: you can predict it arbitrarily far ahead by multiplying by a matrix, and a century of control theory applies directly. Real dynamics — a pendulum, a fluid, a leg — are nonlinear, and the standard response is to linearize around a point and accept that the model is only good nearby. But there is another option that gives up nothing.

02 — the liftThe nonlinearity was in your coordinates

Koopman's insight: instead of tracking the state x, track some observables of it — functions like . In that lifted space the dynamics can be exactly linear, ψ(x_{k+1}) = A ψ(x_k), even though the system is not. The curvature you were fighting was an artifact of watching only x.

Below is a genuinely nonlinear system in its state plane. The gold curve is the truth. The other line is a linear model's prediction. Toggle the one extra observable x₁² and watch what the linear model can do.

the linear model
prediction error
operator recovery

with x₁² the linear prediction lies exactly on the true curve; without it, the same linear machinery drifts off — drag the start anywhere and it holds

03 — exact, not approximateA linear model that never drifts

This is not a linearization that is good near a point and bad elsewhere. With the right observables the linear operator is exact, so its prediction tracks the true nonlinear trajectory to machine precision no matter how far you roll it out or where you start. And the operator itself is learned purely from data — snapshot pairs of the lifted state — by least squares (Extended Dynamic Mode Decomposition). On load, this page fit it from data and checked it against the analytic answer:

learned operator vs the exact Koopman operator
lifted model — peak prediction error over 60 steps
naive linear model (no x₁²) — peak error, same run
verdict

04 — where it wentOne well-chosen observable

The whole difference is the single function x₁². The x₁ channel was linear all along, so the naive model nails it; all the error lives in x₂, which couples to x₁². Add that one observable to your dictionary and the coupling becomes just another linear coordinate. Choosing the dictionary is the real work — but when a finite one closes, as here, the payoff is a globally exact linear model of a nonlinear system, fit from data.

05 — the pointBorrow the linear toolbox

Change coordinates, keep the theory.

Lift a nonlinear system into observables where it moves linearly, and every linear method — long-horizon prediction, optimal control, spectral analysis — applies to it unchanged, learned from measurements rather than derived from a model.

This is why Koopman methods spread so fast across robotics and fluids: they are a bridge from messy real dynamics, which you can measure but not cleanly write down, to the linear tools that actually work. Fit the operator from data, and a soft robot or a gust-buffeted drone gets a predictor you can drop an optimal controller straight onto. It is the data-driven member of this series — where the other chapters found the one quantity that governs a system, this one finds the coordinates in which the system is simple, and then the simplicity is exact.

What you just drove: edmd and Koopman from ferromotion-control, compiled to WebAssembly — the same code the native tools link against. The operator is fit by least squares from lifted snapshot pairs of Brunton's slow-manifold system, which has an exact finite Koopman invariant subspace; predictions roll the learned linear operator forward. Nothing precomputed — every drag re-fits nothing but re-rolls live.

Verified in the library: EDMD recovers the exact Koopman operator (≈1e-9) · the lifted model predicts the nonlinear trajectory to machine precision while the naive linear model drifts >50× more · the drift lives entirely in the x₂ channel that couples to the missing x₁². Each is a test in cargo test, not a claim in prose. See also ch.1 · ch.2 · ch.3 · ch.4 · ch.5 · ch.6 · ch.7 · ch.8.

Institute for Physical AI · the Rust library · crates.io