19 — Control and Learning: A Synthesis

Mathematical Foundations of Control and Machine Learning — Winter 2026

Central question. Which mathematical connections between controlling systems and training models are exact, which are analogies, which hold only under hypotheses, and where do they stop?

This notebook adds no new theory. It says what kind of statement each connection of the course is and where it ends, pointing to the notebook where it was proved, transcribed or measured. The figure re-runs existing procedures and selects nothing; all other numbers are quoted from earlier notebooks.

Table of Contents

  1. Three threads, and where each one stops
  2. The dictionary, with its scope
  3. One oscillator, four different problems
  4. Capacity, optimization, generalization: three different questions
  5. Checking the discrete identity numerically
  6. Open questions
  7. Exercises

Notation. As in the rest of the course; no new symbols. The harmonic oscillator \(x_1''+x_1=u\) is written as \(x'=Ax+Bu\) with \(A=\begin{pmatrix}0&1\\-1&0\end{pmatrix}\), \(B=\begin{pmatrix}0\\1\end{pmatrix}\), state \(x=(x_1,x_2)\).

%matplotlib inline
import numpy as np
import torch
import matplotlib.pyplot as plt
from scipy.linalg import expm
import plotting as P           # the course palette, the house style, and the figure helpers

torch.manual_seed(0);

Where are we?

Part I of the course closed with four statements: controllability and observability are equivalent notions (Wiener’s cybernetics); both hold if and only if the Kalman rank condition is fulfilled; controls may be obtained as minimizers of suitable quadratic functionals over the space of solutions of the adjoint system; and controllable systems are stabilizable by feedback. The fusion part then set out to open the black box of machine learning with control-theoretical tools: explainability, generalization, robustness, complexity, computational cost — with lots still to do. Along the way the course also met the stochastic side of transport (diffusion models, notebook 17) and closed the loop with learning-based control (reinforcement learning, notebook 18).

This notebook collects the threads, with their scope.

1. Three threads, and where each one stops

Thread 1: adjoints and gradients

Duality, stated precisely. For a finite-dimensional linear time-invariant system \(x'=Ax+Bu\), the pair \((A,B)\) is controllable (on any \([0,T]\), \(T>0\)) if and only if the pair \((A^\top,B^\top)\) is observable. Both are equivalent to the Kalman rank condition: the Kalman matrix of \((A,B)\) is, up to transposition, the observability matrix of \((A^\top,B^\top)\). This is the precise content of the “equivalent notions”, and the basis of HUM in notebook 03: the controls are built from solutions of the adjoint system \(-\varphi'=A^\top\varphi\), and the functional is coercive exactly when the adjoint is observable. In infinite dimension, as for the heat equation of notebook 07, exact, null and approximate controllability correspond to different observability (or unique-continuation) properties of the adjoint. There is no single “equivalence” there.

The adjoint method, with its hypotheses (07). Let a scalar cost \(J(u)=j(x(u),u)\) be constrained by a state equation \(e(x,u)=0\) that has a unique solution \(x(u)\), with \(e\) and \(j\) continuously differentiable and \(\partial_xe\) invertible (so that \(u\mapsto x(u)\) is differentiable, by the implicit function theorem). Then \(\nabla J\) is obtained from one state solve and one adjoint solve, whatever the number of controls. That is the computational structure for one scalar objective. It is not a constant cost: each solve costs as much as the problem size dictates, and \(m\) scalar outputs need \(m\) adjoint solves.

The discrete adjoint of a residual network, derived once (the computation of notebook 13, §5, for one sample). Take the explicit scheme \(x_{k+1}=x_k+hf(x_k,\theta_k)\), \(k=0,\dots,K-1\), \(x_0\) given, and the training objective \[ J(\Theta)=\Phi(x_K)+h\sum_{k=0}^{K-1}\ell(x_k)+\alpha h\sum_{k=0}^{K-1}|\theta_k|^2 , \] with \(f\), \(\Phi\), \(\ell\) continuously differentiable. The scheme is explicit, so the states are well defined for every \(\Theta\). Adjoin each step with a multiplier \(p_{k+1}\): \[ \mathscr L=J(\Theta)-\sum_{k=0}^{K-1}p_{k+1}\cdot\big(x_{k+1}-x_k-hf(x_k,\theta_k)\big). \] On trajectories of the scheme, \(\mathscr L=J\) for any multipliers. Choosing them so that \(\partial\mathscr L/\partial x_k=0\) for \(k=K,\dots,1\) gives the discrete adjoint recursion \[ p_K=\nabla\Phi(x_K),\qquad p_k=\big(I+hD_xf(x_k,\theta_k)\big)^{\!\top}p_{k+1}+h\nabla\ell(x_k), \] and what remains is the parameter gradient \[ \nabla_{\theta_k}J=h\,D_\theta f(x_k,\theta_k)^{\top}p_{k+1}+2\alpha h\,\theta_k . \] This is backpropagation. With \(N\) samples, the data terms are averaged, \(p_K=\nabla\Phi_n/N\) per sample, and the regularization is counted once (13).

Where it stops. - The identity is exact for one specified discrete cost and scheme. Whether discretizing the continuous adjoint system gives the same vector depends on the discretization. A compatible discretization reproduces the recursion above exactly. The natural choice of notebook 13, §10 — Jacobian at \(x_{k+1}\), gradient with \(p_k\) — is observed to differ from the discrete one by an amount of order \(h\) in relative Euclidean norm, at a fixed horizon with piecewise-constant controls identified across nested meshes (13 §10, and §5 below). A theoretical bound would naturally be an absolute one, of order \(h\) for smooth fields and this parametrization; a relative statement also needs the reference gradient to stay away from zero. - “One forward and one backward pass” fixes the number of passes, not the work. The work grows with the number of samples, layers, width and dimension, and the forward states must be stored or recomputed.

Thread 2: gradient dynamics and training

  • 06: gradient descent is the explicit Euler scheme of the gradient flow, stable only for small enough steps.
  • 10: stochastic gradient descent replaces the gradient by a sampled one, which is unbiased conditionally on the current iterate when the indices are drawn independently of the past, as with sampling with replacement. With epoch-wise reshuffling (without replacement) this holds for the first step of each epoch, not for later steps conditionally on the earlier ones. With a constant step and nonzero gradient noise at the optimum, the iterates were seen to settle in a neighbourhood whose size depends on the step and the batch. An upper bound on that residual does not prove a positive floor in general.
  • 11: momentum and adaptive methods add memory and coordinate-wise scaling.
  • 18: stochastic approximation returns one more time: Q-learning and policy gradients are noisy fixed-point and gradient iterations, with step conditions of the same Robbins–Monro type.

The heavy ball is a discretized damped oscillator for any differentiable \(F\): the scheme \[ \frac{w_{k+1}-2w_k+w_{k-1}}{h^2}+\nu\,\frac{w_k-w_{k-1}}{h}+\nabla F(w_k)=0 \] is exactly the heavy-ball update with \(\eta=h^2\) and \(\beta=1-\nu h\) (11). What requires a quadratic \(F\) is the next step: the reduction to independent linear oscillator modes, and the spectral tuning results of 11, such as the critical momentum and its rate.

Where it stops. Continuous time, discrete steps, sampling noise and stability conditions are four different layers of the same picture. A decreasing training loss is a statement about optimization, never by itself about generalization (09).

Thread 3: controllability, representation, transport

  • 02: Kalman’s rank condition decides controllability of a linear system.
  • 12: one hidden layer represents finitely many distinct data points exactly.
  • 13: a ResNet is the Euler scheme of a controlled ODE.
  • 14: a ReLU neural ODE steers finitely many points into their label regions (simultaneous control).
  • 15: attention makes the points interact.
  • 16: a flow transports measures, and the same fields can learn a vector field from trajectories.
  • 17: the transport becomes stochastic: a diffusion model runs a noising SDE backwards, and the single object the reversal needs, the score, is learned from samples.

Where it stops: - Kalman says nothing about controllability of a nonlinear network. - Interpolating or classifying a finite set exactly does not guarantee predicting well (12, 14). - A ResNet trained with large steps need not be an injective flow (13). - Hardmax leadership can appear after layer \(0\), and the clustering theorem does not describe practical transformers with softmax and feed-forward blocks (15). - Matching atoms exactly does not transport the law they were drawn from (16). - A field that depends affinely on a relaxed control (a measure) does not make the dynamic problem convex (12, 14). - Time reversal of a diffusion is exact only with the exact score; a learned score makes the generative process an approximation whose error must be measured, not assumed (17).

2. The dictionary, with its scope

The table classifies each connection in one of three ways: - DIRECT CONNECTION: an identity in a specified model, exact once the model is fixed; - MATHEMATICAL ANALOGY: the same structure, different objects, no theorem transferred; - RESULT UNDER HYPOTHESES: a theorem, transcribed or proved in the course, valid only under the hypotheses listed.

None of these is a universal equivalence between control and machine learning.

Control Machine learning Kind Scope and hypotheses Where
state \(x_k\), dynamics \(x_{k+1}=x_k+hf(x_k,\theta_k)\) features through the layers of a ResNet DIRECT CONNECTION the ResNet is this Euler scheme; it approximates the flow map only at a fixed horizon, with small steps and regular controls 13
adjoint state \(p_k\) backpropagated sensitivity DIRECT CONNECTION exact gradient of the specified discrete cost (\(C^1\) data); a discretized continuous adjoint agrees only if the discretization is compatible (13’s natural choice: observed about \(O(h)\) apart) 07, 13
control cost \(\alpha\int\|\theta\|^2\) \(L^2\) penalty on parameters DIRECT CONNECTION as a term of the objective; decoupled weight decay (AdamW) is a different update 13
gradient flow and its Euler scheme gradient descent on a loss DIRECT CONNECTION step condition for stability; SGD adds sampling noise 06, 10
damped oscillator \(w''+\nu w'+\nabla F(w)=0\) heavy-ball momentum DIRECT CONNECTION (scheme) / MATHEMATICAL ANALOGY (behaviour) the discretization identity holds for differentiable \(F\); mode decomposition and spectral tuning need a quadratic \(F\) 05, 11
controllability of \((A,B)\) ⇔ observability of \((A^\top,B^\top)\) — RESULT UNDER HYPOTHESES finite-dimensional, linear, time-invariant; different notions in infinite dimension 02, 03, 07
Kalman controllability expressivity of networks MATHEMATICAL ANALOGY Kalman is linear; network results need their own hypotheses 02, 14
simultaneous control into open sets exact classification of training points RESULT UNDER HYPOTHESES ReLU NODE, \(d\ge2\), distinct or compatible inputs; nothing about new points 14
turnpike over long horizons very deep networks MATHEMATICAL ANALOGY proved in 08 for linear-quadratic problems penalizing state and control, with \((A,B)\) controllable and \((A,C)\) observable: sufficient, not necessary, hypotheses; no universal theorem for trained networks 08, 13
consensus / interacting particles hardmax self-attention RESULT UNDER HYPOTHESES clustering for nonzero distinct tokens, \(A\) symmetric positive definite, \(V=\alpha I\), pure hardmax; leadership can emerge 15
transport equation, characteristics normalizing flows RESULT UNDER HYPOTHESES \(W_1\)-approximation for compactly supported absolutely continuous laws; atoms are not laws 16
reverse-time SDE (time reversal of diffusions) generative denoising, score matching RESULT UNDER HYPOTHESES Anderson’s reversal needs the true score \(\nabla\log p_t\); learning replaces it by an estimate, and the generative error depends on that estimate 17
dynamic programming / HJB Bellman equation, Q-learning DIRECT CONNECTION (known model) / MATHEMATICAL ANALOGY (learned) value iteration is dynamic programming on a known MDP; Q-learning removes the model, and its guarantees are stochastic-approximation theorems with their own step and exploration conditions 07, 18
feedback law \(u=F(x)\) learned policy MATHEMATICAL ANALOGY a feedback is designed from a model; a policy is learned from rewards; they are different objects with different guarantees 01, 05, 18
relaxed controls (measures) mean-field networks RESULT UNDER HYPOTHESES static no-gap theorem for shallow networks; in dynamics the field is linear in the measure, the flow is not 12, 14

3. One oscillator, four different problems

Figure 1 shows four problems posed on the harmonic oscillator. They are not four methods competing for one objective: each panel has its own question, horizon and criterion, and two of them use different matrices.

Panel System Initial state, horizon Control or criterion Question answered Where
(a) oscillator: \(x'=Ax+Bu\) \(x^0=(1,0)\), \(T=5\) the minimal-\(L^2\) steering control (Gramian) can the oscillator be steered exactly to \(x^1=0\) in time \(T\)? 02, 03
(b) oscillator under \(u=-kx_2\): \(A_k=\begin{pmatrix}0&1\\-1&-k\end{pmatrix}\) \(x^0=(1,0)\), \(t\in[0,20]\) feedback gain \(k=0.5,2,8\) does the closed loop decay, and how fast? 05
(c) oscillator with cost \(\frac12\int_0^T(\|u\|^2+\|x-x^*\|^2)\,dt\) \(x^0=0\), \(T=20\), \(x^*=(2,7)\) optimal control (optimality system) does the optimal trajectory stay near the steady optimum? 08
(d) \(z'=A_{\rm cl}z\), \(A_{\rm cl}=A+B(-1,-3)=\begin{pmatrix}0&1\\-2&-3\end{pmatrix}\) 3 validation initial conditions of 16, \(T=3\) SA-NODE: outer weights fitted by least squares on fixed random features can a neural field reproduce this vector field along trajectories? 16

Panel (d), precisely. It is the oscillator under \(u=-x_1-3x_2\), not one of the damped oscillators of (b): its \((2,1)\) entry is \(-2\) (Exercise 3). - What is fitted. Only the outer weights \(W\) of \(x'=W\sigma(A_1x+a_2t+b)\) are fitted, by ridge least squares, over fixed random inner features. The fit uses privileged derivative targets: the true field \(A_{\rm cl}z\) at points of the 20 training trajectories. - What it is not. This is not end-to-end training of a neural ODE from trajectory observations. That would adjust all parameters through the flow, typically with adjoint gradients (13), from states alone. - Frozen choices. Notebook 16’s choices are reused unchanged: its selected width and regularization, and its random features, reproduced by drawing from the same generators in the same order. The evaluation generator of 16 is not touched. - What the curves are. They are 16’s validation trajectories, already used to choose \(P\) and \(\lambda\): an illustration of the fit, not an independent test.

Predict. (i) Which of the four problems prescribes a terminal state? (ii) Does increasing the feedback gain \(k\) always make the closed loop converge faster? (iii) Why can the steady optimum of (c) differ from the tracking target \(x^*=(2,7)\)? (iv) Does accurate fitting of the validation trajectories in (d) establish that the learned model is stable?

A = np.array([[0.0, 1.0], [-1.0, 0.0]])                     # the harmonic oscillator x1'' + x1 = u
B = np.array([[0.0], [1.0]])
damped = lambda k: np.array([[0.0, 1.0], [-1.0, -k]])       # the oscillator under u = -k x2

def simulate(A_, B_, u, x0, ts):
    # RK4 for x' = A x + B u(t) along the grid ts
    f = lambda t, x: A_ @ x + B_ @ u(t)
    xs = [np.asarray(x0, float)]
    for t0, t1 in zip(ts[:-1], ts[1:]):
        x, h = xs[-1], t1 - t0
        k1 = f(t0, x); k2 = f(t0 + h / 2, x + h / 2 * k1)
        k3 = f(t0 + h / 2, x + h / 2 * k2); k4 = f(t0 + h, x + h * k3)
        xs.append(x + h / 6 * (k1 + 2 * k2 + 2 * k3 + k4))
    return np.array(xs)

def gramian_control(A_, B_, T, x0, x1, n_quad=600):
    # the minimal-L2 steering control u(t) = B^T e^{A^T (T-t)} G^{-1} (x1 - e^{AT} x0)
    taus, dt = np.linspace(0, T, n_quad + 1), T / n_quad
    integ = np.array([(E := expm(A_ * tau)) @ B_ @ B_.T @ E.T for tau in taus])
    G = (integ[0] / 2 + integ[1:-1].sum(axis=0) + integ[-1] / 2) * dt          # trapezoid rule
    c = np.linalg.solve(G, x1 - expm(A_ * T) @ x0)
    return lambda t: B_.T @ expm(A_.T * (T - t)) @ c

def lq_optimality_system(A_, B_, x_star, T, n_steps):
    # two-point boundary value problem: x' = Ax - BB^T p, -p' = A^T p + (x - x*), x(0)=0, p(T)=0.
    # Solved exactly through the augmented linear system z' = M z + c with z = (x, p).
    M = np.block([[A_, -B_ @ B_.T], [-np.eye(2), -A_.T]])
    c = np.concatenate([np.zeros(2), x_star])
    Mt = np.zeros((5, 5)); Mt[:4, :4] = M; Mt[:4, 4] = c                       # homogeneous 5x5 form
    PhiT = expm(Mt * T)
    p0 = -np.linalg.solve(PhiT[2:4, 2:4], PhiT[2:4, 4])                        # enforce p(T) = 0 (x(0) = 0)
    step = expm(Mt * (T / n_steps))
    z, Z = np.concatenate([np.zeros(2), p0, [1.0]]), []
    for _ in range(n_steps + 1):
        Z.append(z.copy()); z = step @ z
    Z = np.array(Z)
    return Z[:, :2], -Z[:, 2:4] @ B_                                           # x(t), u(t) = -B^T p(t)

# Panel (d) reproduces notebook 16's development data exactly: same generators, same draw order
# (16's Gaussian-to-uniform transport atoms are drawn and discarded first); the evaluation generator of 16 is not created.
rng_data, rng_features = np.random.default_rng(1601), np.random.default_rng(1602)
_ = 0.5 + 0.15 * rng_data.standard_normal((8, 2)); _ = rng_data.uniform(0, 1, size=(8, 2))   # atoms of 16
ic_train = rng_data.uniform(-1, 1, size=(20, 2))
ic_val = rng_data.uniform(-1, 1, size=(10, 2))
A1_all = rng_features.normal(size=(320, 2))
a2_all = rng_features.normal(size=320)
b_all = rng_features.uniform(-1, 1, size=320)

relu = lambda z: np.maximum(z, 0.0)
sa_features = lambda Z, t, A1, a2, b: relu(Z @ A1.T + np.outer(np.atleast_1d(t), a2) + b)

def sa_node_rollout(z0, W, A1, a2, b, ts, substeps=2):
    f = lambda t, x: W @ relu(A1 @ x + a2 * t + b)
    xs = [np.asarray(z0, float)]
    for t0, t1 in zip(ts[:-1], ts[1:]):
        x, h = xs[-1], (t1 - t0) / substeps
        for s in range(substeps):
            t = t0 + s * h
            k1 = f(t, x); k2 = f(t + h / 2, x + h / 2 * k1)
            k3 = f(t + h / 2, x + h / 2 * k2); k4 = f(t + h, x + h * k3)
            x = x + h / 6 * (k1 + 2 * k2 + 2 * k3 + k4)
        xs.append(x)
    return np.array(xs)
fig, axes = P.panels(2, 2, figsize=(11.6, 8.4))

# (a) Steering the oscillator from (1, 0) to 0 in T = 5 with the minimal-energy control.
T_a, x0_a, x1_a = 5.0, np.array([1.0, 0.0]), np.zeros(2)
t_a = np.linspace(0, T_a, 501)
u_a = gramian_control(A, B, T_a, x0_a, x1_a)
x_a = simulate(A, B, u_a, x0_a, t_a)
ax = axes[0, 0]
ax.plot(x_a[:, 0], x_a[:, 1], color=P.BLUE, label="controlled trajectory")
ax.plot(*x0_a, "o", color=P.ORANGE, label="$x^0=(1,0)$")
ax.plot(*x1_a, "*", ms=12, color=P.INK, label="target $x^1=0$")
P.label(ax, "$x_1$", "$x_2$", equal=True, title="(a) oscillator, open loop: steer to 0 in $T=5$ (02, 03)")

# (b) Feedback u = -k x2: three gains, same initial state.
t_b = np.linspace(0, 20, 2001)
ax = axes[0, 1]
for k, col in zip((0.5, 2.0, 8.0), (P.BLUE, P.ORANGE, P.MAGENTA)):
    A_k = damped(k)
    x_b = simulate(A_k, B, lambda s: np.zeros(1), [1.0, 0.0], t_b)
    ax.plot(t_b, x_b[:, 0], color=col,
            label=f"$k={k:g}$ (spectral abscissa {np.linalg.eigvals(A_k).real.max():.2f})")
P.label(ax, "$t$", "$x_1$", title="(b) oscillator under $u=-kx_2$: decay from $(1,0)$ (05)")

# (c) Turnpike: LQ cost with target x* = (2, 7), x0 = 0, T = 20.
x_star, T_c = np.array([2.0, 7.0]), 20.0
x_bar, u_bar = np.array([x_star[0] / 2, 0.0]), x_star[0] / 2    # best equilibrium: x=(x1,0), u=x1
t_c = np.linspace(0, T_c, 4001)
x_c, u_c = lq_optimality_system(A, B, x_star, T_c, 4000)
ax = axes[1, 0]
for i, col in ((0, P.BLUE), (1, P.AQUA)):
    ax.plot(t_c, x_c[:, i], color=col, label=f"$x_{i + 1}(t)$")
    ax.axhline(x_bar[i], color=col, ls=":", lw=1)
ax.plot(t_c, u_c[:, 0], color=P.ORANGE, label="$u(t)$")
ax.axhline(u_bar, color=P.ORANGE, ls=":", lw=1)
P.label(ax, "$t$", title=r"(c) oscillator, LQ cost, $x^*=(2,7)$, $T=20$: turnpike (08; dotted: steady optimum)")

# (d) The closed loop of notebook 16, fitted by an SA-NODE with 16's frozen choices (P = 160, lambda = 1e-8).
A_cl = A + B @ np.array([[-1.0, -3.0]])
t_d = np.linspace(0.0, 3.0, 31)
exact = lambda z0: np.array([expm(A_cl * t) @ z0 for t in t_d])
Z_train = np.array([exact(z0) for z0 in ic_train])
Pw, lam = 160, 1e-8
inner = (A1_all[:Pw], a2_all[:Pw], b_all[:Pw])                  # fixed random features: not trained
Phi_d = sa_features(Z_train.reshape(-1, 2), np.tile(t_d, len(ic_train)), *inner)
F_d = Z_train.reshape(-1, 2) @ A_cl.T                           # privileged targets f(z) = A_cl z
W = np.linalg.solve(Phi_d.T @ Phi_d / len(F_d) + lam * np.eye(Pw), Phi_d.T @ F_d / len(F_d)).T
val_errors = np.array([np.linalg.norm(exact(z0) - sa_node_rollout(z0, W, *inner, t_d), axis=1).max()
                       for z0 in ic_val])
ax = axes[1, 1]
for z0 in ic_val[:3]:
    ax.plot(*exact(z0).T, color=P.GREY, lw=2.5)
    ax.plot(*sa_node_rollout(z0, W, *inner, t_d).T, "--", color=P.BLUE, lw=1.3)
    ax.plot(*z0, "o", color=P.ORANGE, ms=4)
ax.plot([], [], color=P.GREY, lw=2.5, label="true closed loop")
ax.plot([], [], "--", color=P.BLUE, label="SA-NODE (outer weights only)")
P.label(ax, "$z_1$", "$z_2$", legend={"fontsize": 8.5, "loc": "lower right"},
        title="(d) $z'=A_{\\rm cl}z$ (oscillator under $u=-x_1-3x_2$): learned field (16)")
plt.show()

Figure 1. Four problems on the harmonic oscillator. (a) Open-loop steering of the oscillator from \((1,0)\) to \(0\) in \(T=5\) with the minimal-\(L^2\) control. (b) The closed loops \(u=-kx_2\) for three gains, first coordinate against time. (c) The optimal trajectory and control for the linear-quadratic cost with target \(x^*=(2,7)\) on \([0,20]\), with the steady optimum dotted. (d) The closed loop \(z'=A_{\rm cl}z\) (\(u=-x_1-3x_2\), a different matrix from (b)) and its SA-NODE model (outer weights fitted over fixed random features, privileged derivative targets, notebook 16’s frozen choices) on three validation trajectories.

Interpretation. Each panel answers its own question, and the panels are not ranked. The diagnostics are printed by the next cell.

print(f"(a) |x(T) - x1| = {np.linalg.norm(x_a[-1] - x1_a):.1e}")
for k in (0.5, 2.0, 8.0):
    lam_k = np.linalg.eigvals(damped(k))
    print(f"(b) k = {k:3.1f}: eigenvalues {np.round(lam_k, 4)}, spectral abscissa {lam_k.real.max():.3f}")
dev_c = np.linalg.norm(x_c - x_bar, axis=1) + np.abs(u_c[:, 0] - u_bar)        # |x - x_bar|_2 + |u - u_bar|
print(f"(c) steady optimum x_bar = {x_bar}, u_bar = {u_bar:.3f} (target x* = {x_star});  "
      f"deviation at t = T/2: {dev_c[len(t_c) // 2]:.1e}")
for a in (0.25, 0.3, 0.4):
    window = (t_c >= a * T_c) & (t_c <= (1 - a) * T_c)
    print(f"    max of |x - x_bar| + |u - u_bar| on [{a:.2f} T, {1 - a:.2f} T] = "
          f"[{a * T_c:4.1f}, {(1 - a) * T_c:4.1f}]: {dev_c[window].max():.1e}")
print(f"(d) eigenvalues of A_cl: {np.sort(np.linalg.eigvals(A_cl).real)};  mean trajectory error on the 10 "
      f"validation trajectories {val_errors.mean():.2e} (already used for selection in 16; not an independent test)")
(a) |x(T) - x1| = 4.4e-06
(b) k = 0.5: eigenvalues [-0.25+0.9682j -0.25-0.9682j], spectral abscissa -0.250
(b) k = 2.0: eigenvalues [-1.+0.j -1.+0.j], spectral abscissa -1.000
(b) k = 8.0: eigenvalues [-0.127+0.j -7.873+0.j], spectral abscissa -0.127
(c) steady optimum x_bar = [1. 0.], u_bar = 1.000 (target x* = [2. 7.]);  deviation at t = T/2: 5.9e-03
    max of |x - x_bar| + |u - u_bar| on [0.25 T, 0.75 T] = [ 5.0, 15.0]: 3.9e-01
    max of |x - x_bar| + |u - u_bar| on [0.30 T, 0.70 T] = [ 6.0, 14.0]: 1.1e-01
    max of |x - x_bar| + |u - u_bar| on [0.40 T, 0.60 T] = [ 8.0, 12.0]: 5.2e-02
(d) eigenvalues of A_cl: [-2. -1.];  mean trajectory error on the 10 validation trajectories 3.83e-04 (already used for selection in 16; not an independent test)

Reading Figure 1 (answers to the predictions). - (i) A terminal state is prescribed only in (a): the control must bring the state exactly to \(x^1=0\) at \(T=5\), and does so up to the integrator’s accuracy. Problem (c) penalizes the distance to \(x^*\) along the whole interval but imposes no terminal state. Problem (b) has no horizon at all, and (d) is a fitting problem. - (ii) No: a larger gain does not always mean faster convergence. The spectral abscissa, the largest real part of the eigenvalues, gives the asymptotic exponential rate: \(|x(t)|\le C_\varepsilon e^{(\alpha+\varepsilon)t}\) for every \(\varepsilon>0\), where \(\alpha\) is the abscissa. Here \(\alpha=-0.25\), \(-1\) and \(\approx-0.13\) for \(k=0.5,2,8\) (printed): the overdamping paradox of notebooks 01 and 05. - At critical damping \(k=2\) the eigenvalue \(-1\) is double and the matrix is not diagonalizable, so solutions behave like \((c_1+c_2t)e^{-t}\). The rate is \(e^{-t}\) with a polynomial prefactor, which is why \(\varepsilon>0\) is needed in the bound. - The abscissa says nothing about the transient, which can grow before it decays when the matrix is non-normal (Exercise 3). - (iii) The steady optimum differs from \(x^*\) because \(x^*=(2,7)\) is not an equilibrium of the oscillator with any constant control: an equilibrium needs \(x_2=0\) and \(x_1=u\). The steady optimum is the best compromise between the state and control costs, \(\bar x=(1,0)\), \(\bar u=1\) (printed). Over a long horizon the optimal solution stays near it in the interior: the turnpike of 08. - The printed deviation \(|x-\bar x|_2+|u-\bar u|\) shrinks as the interval moves away from both ends, consistently with deviations that decay exponentially away from both ends. - It illustrates, for one horizon, the theorem of 08: linear-quadratic cost on state and control, \((A,B)\) controllable, \((A,C)\) observable, here with \(C=I\). It does not prove it. - (iv) No: accurate trajectory fitting does not establish stability. The validation errors are small (printed), on initial conditions in \([-1,1]^2\) over \([0,3]\), and on trajectories already used for the choice. The learned field is a ReLU field with time as an input. Nothing shown here bounds its behaviour for larger times or outside the training region, where notebook 16’s frozen final evaluation found errors about thirty times larger. Stability of the learned model would need its own argument, which was not given.

4. Capacity, optimization, generalization: three different questions

Three questions recur under different names: - Capacity: can some parameters (controls) achieve the goal on the given data? - Optimization: does the procedure find such parameters? - Generalization: do the parameters found predict well on new data from the same law?

They are related but distinct. Achieving a fit presupposes enough capacity for that fit. Beyond that, expressive capacity alone does not guarantee that training finds a good model, and a small training loss alone does not guarantee generalization. The course has examples of each gap; the numbers below are quoted from the frozen protocols of the notebooks.

  • 12. The exact interpolant \(P_0\) represents all 36 noisy training points with 36 neurons. The sparse regression chosen on validation data (\(\lambda=1000\), 15 neurons) had the smaller validation error. On 500 new samples the mean absolute errors were \(0.470\) (\(P_0\)) against \(0.308\). Exactness and sparsity are statements about the training data; validation decided.
  • 13–14. Both the trained network of 13 and the constructed control of 14 classify the 72 training points of the two-class point cloud perfectly. On 2000 new observations of its declared law, the joint evaluation counted 42 errors against 760 (error rates \(0.021\) and \(0.380\); balanced labels make \(0.5\) the level of guessing). The comparison concerns these two procedures and this law only. It is not a ranking of control against machine learning: the construction was designed to steer the training points, not to predict.
  • 16. The atomic transport sends 8 atoms exactly onto 8 targets, yet moves new samples of the same law to \(W_1\approx166\) from the target sample. The SA-NODE’s final trajectory errors were about thirty times larger outside the training region than inside.
  • 09–11. A training loss can keep decreasing while the validation error rises; this is the reason for early stopping.
  • 18. A policy that maximizes return on the training environment is a statement about that environment; transfer to a perturbed one is a separate question, as for every model above.

Training, validation, test, and what “leakage” means. Training data fit the parameters, validation data choose among models (hyperparameters, stopping, architecture), and test or final data, drawn once from a reserved source, measure the chosen model. Recomputing a frozen final metric is harmless arithmetic. What invalidates a final evaluation is letting it inform a decision: a model, a hyperparameter, a stopping time, or which result to report. The protocols of 12–16 froze every decision before their final data existed. Earlier exposures of development data are documented where they happened, and are not rewritten: the test split and holdout of the regression dataset in 09–10, the test split of the two-class point cloud in 11. This notebook makes no decision and creates no evaluation data: panel (d) uses training data for the fit and validation data for the picture.

5. Checking the discrete identity numerically

The first entry of thread 1 can be checked with the machinery of notebook 13 (§5 for the discrete adjoint, §10 for the discretized continuous one). The model is a small residual network with fixed, hand-chosen parameters: width \(P=2\) in \(\mathbb R^2\), two control pieces of duration \(\frac12\) on \([0,1]\), three samples and a quadratic terminal cost. It has 20 piece parameters. The cell runs two checks.

  1. The full gradient with respect to all 20 piece parameters. The discrete adjoint is compared with central differences of the discrete cost, coordinate by coordinate, over a sweep of \(\varepsilon\). Truncation decreases like \(\varepsilon^2\) until floating-point cancellation, of order \(\varepsilon_{\rm mach}/\varepsilon\), takes over.
  2. The gap to the discretized continuous adjoint of notebook 13, §10, in relative Euclidean norm, on nested meshes at a fixed horizon, with the pieces identified across meshes. The table gives the observed order between successive meshes.

Agreement “within finite-difference and floating-point error” is what one can expect. One example illustrates the statements of §1; it does not prove a general theorem.

# The machinery of notebook 13, sections 5 and 11, for the tanh neuron field f = W tanh(A x + b).
def field(X, W_, A_, b_):
    return np.tanh(X @ A_.T + b_) @ W_.T

def euler_flow(X0, Theta, h):
    xs = [X0]
    for W_, A_, b_ in zip(*Theta):
        xs.append(xs[-1] + h * field(xs[-1], W_, A_, b_))
    return np.array(xs)

piecewise_constant = lambda pieces, s: tuple(np.repeat(p, s, axis=0) for p in pieces)
pack = lambda Theta: np.concatenate([t.ravel() for t in Theta])
sum_over_pieces = lambda grads, s: tuple(g.reshape(-1, s, *g.shape[1:]).sum(axis=1) for g in grads)

def objective(X0, Theta, h, Phi_term):
    return float(Phi_term(euler_flow(X0, Theta, h)[-1]).mean())

def discrete_adjoint(X0, Theta, h, dPhi_term):
    Ws, As, bs = Theta
    xs = euler_flow(X0, Theta, h)
    n, K = len(X0), len(bs)
    p = dPhi_term(xs[-1]) / n
    gW, gA, gb = [], [], []
    for k in reversed(range(K)):
        x, W_, A_, b_ = xs[k], Ws[k], As[k], bs[k]
        z = x @ A_.T + b_
        s, ds = np.tanh(z), 1 - np.tanh(z) ** 2
        Wp = ds * (p @ W_)
        gW.append(h * p.T @ s); gA.append(h * Wp.T @ x); gb.append(h * Wp.sum(0))
        p = p + h * (Wp @ A_)
    return np.array(gW[::-1]), np.array(gA[::-1]), np.array(gb[::-1])

def continuous_adjoint_gradient(X0, Theta, h, dPhi_term):
    # differentiate-then-discretize: Jacobian at x_{k+1}, gradient with p_k (notebook 13, section 11)
    Ws, As, bs = Theta
    xs = euler_flow(X0, Theta, h)
    n, K = len(X0), len(bs)
    p = dPhi_term(xs[-1]) / n
    gW, gA, gb = [], [], []
    for k in reversed(range(K)):
        x1 = xs[k + 1]
        Wp1 = (1 - np.tanh(x1 @ As[k].T + bs[k]) ** 2) * (p @ Ws[k])
        p = p + h * (Wp1 @ As[k])
        x = xs[k]
        z = x @ As[k].T + bs[k]
        s, ds = np.tanh(z), 1 - np.tanh(z) ** 2
        Wp = ds * (p @ Ws[k])
        gW.append(h * p.T @ s); gA.append(h * Wp.T @ x); gb.append(h * Wp.sum(0))
    return np.array(gW[::-1]), np.array(gA[::-1]), np.array(gb[::-1])

pieces = (np.array([[[0.5, -0.3], [0.2, 0.4]], [[0.1, 0.6], [-0.4, 0.2]]]),    # W: (pieces, d, P), hand-chosen
          np.array([[[1.0, 0.0], [0.3, 1.0]], [[0.8, -0.5], [0.2, 0.9]]]),     # A: (pieces, P, d)
          np.array([[0.1, -0.2], [0.0, 0.3]]))                                 # b: (pieces, P)
shapes = [p.shape for p in pieces]
sizes = [p.size for p in pieces]
unpack = lambda vec: tuple(seg.reshape(sh) for seg, sh in zip(np.split(vec, np.cumsum(sizes)[:-1]), shapes))
X_d = np.array([[0.5, 0.1], [-0.3, 0.8], [0.9, -0.4]])
target = np.array([[1.0, 0.0], [0.0, 1.0], [0.5, 0.5]])
Phi_term = lambda X: 0.5 * np.sum((X - target) ** 2, axis=1)
grad_term = lambda X: X - target
n_pieces = 2

cost = lambda vec, s: objective(X_d, piecewise_constant(unpack(vec), s), 1.0 / (n_pieces * s), Phi_term)

s0, v0 = 8, pack(pieces)
g_adj = pack(sum_over_pieces(discrete_adjoint(X_d, piecewise_constant(pieces, s0), 1.0 / (n_pieces * s0), grad_term), s0))
print(f"full gradient check, {len(v0)} parameters, h = {1 / (n_pieces * s0)}:")
print("   eps      max |g_fd - g_adj|    |g_fd - g_adj| / |g_adj|")
fd_errors = []
for eps in 10.0 ** -np.arange(1, 9):
    g_fd = np.array([(cost(v0 + eps * e, s0) - cost(v0 - eps * e, s0)) / (2 * eps) for e in np.eye(len(v0))])
    fd_errors.append(np.abs(g_fd - g_adj).max())
    print(f"{eps:7.0e}   {fd_errors[-1]:18.1e}   {np.linalg.norm(g_fd - g_adj) / np.linalg.norm(g_adj):24.1e}")
print("observed truncation order for eps = 1e-1 ... 1e-4:", np.round(-np.diff(np.log10(fd_errors[:4])), 2))

print("\ngap to the discretized continuous adjoint, fixed horizon T = 1:")
print("     h       |g_disc - g_cont| / |g_disc|   observed order")
gaps = []
for s in (2, 4, 8, 16, 32, 64, 128):
    Th, h = piecewise_constant(pieces, s), 1.0 / (n_pieces * s)
    g_d = pack(sum_over_pieces(discrete_adjoint(X_d, Th, h, grad_term), s))
    g_c = pack(sum_over_pieces(continuous_adjoint_gradient(X_d, Th, h, grad_term), s))
    gaps.append(np.linalg.norm(g_d - g_c) / np.linalg.norm(g_d))
    order = "" if len(gaps) == 1 else f"{np.log2(gaps[-2] / gaps[-1]):.3f}"
    print(f"{h:9.5f}   {gaps[-1]:27.3e}   {order:>14s}")
full gradient check, 20 parameters, h = 0.0625:
   eps      max |g_fd - g_adj|    |g_fd - g_adj| / |g_adj|
  1e-01              4.0e-04                    2.4e-03
  1e-02              4.0e-06                    2.4e-05
  1e-03              4.0e-08                    2.4e-07
  1e-04              4.0e-10                    2.4e-09
  1e-05              9.3e-12                    6.6e-11
  1e-06              8.4e-11                    6.1e-10
  1e-07              1.4e-09                    8.9e-09
  1e-08              8.9e-09                    6.2e-08
observed truncation order for eps = 1e-1 ... 1e-4: [2. 2. 2.]

gap to the discretized continuous adjoint, fixed horizon T = 1:
     h       |g_disc - g_cont| / |g_disc|   observed order
  0.25000                     8.555e-02                 
  0.12500                     4.325e-02            0.984
  0.06250                     2.174e-02            0.992
  0.03125                     1.090e-02            0.996
  0.01562                     5.458e-03            0.998
  0.00781                     2.731e-03            0.999
  0.00391                     1.366e-03            1.000

Reading the output. - Full gradient check. The error falls by a factor of about \(100\) per decade of \(\varepsilon\) (observed order \(2\)), as truncation of central differences predicts, reaches its minimum, then grows again as rounding dominates. The adjoint gradient agrees with the full finite-difference gradient within finite-difference and floating-point error. - Continuous–discrete gap. It halves with \(h\) (observed order \(\to1\)). For this model, this discretization and this norm, the two gradients are observed to be first-order apart; this illustrates §1, it does not prove a bound. A compatible discretization would remove the gap.

6. Open questions

The course ends with questions rather than theorems. We record the main ones, separating the questions from the results reported with them, without claiming that each is still open at the time of reading.

  • Turnpike. The turnpike property for nonlinear PDEs without smallness conditions on the target; optimal control of time-dependent diffusivity coefficients; a global picture combining local analysis with dissipativity; periodic turnpike; turnpike for optimal shape design; turnpike as a tool for constrained controllability in large time. Reported result: turnpike for ResNets and beyond (Geshkovski and Zuazua, 2022). The course itself proves no turnpike theorem for trained networks (08, 13).
  • Complexity and dimension. Width–depth and clustering bounds under stated hypotheses (14, 15); some printed counts could not be verified as stated (14, 16).
  • Generalization of training algorithms. Implicit regularization, flat versus sharp minima, the role of noise (10, 11): heuristics with partial results and known counterexamples.
  • Digital twins and reliability. Scalability, adaptivity, personalized and goal-oriented modelling (model predictive control appears as a question, not a method developed here), reliability, generalization, synthetic data, merging with physics and mechanics.
  • Other directions: momentum ResNets and relaxed neural ODEs (13, 14, as reported results), federated learning (09, as a laboratory only), diffusion as stochastic control (17), offline and safe reinforcement learning (18).
  • A proposed extension (ours). Learning a controlled model and checking that a controller designed on it works on the true plant is a natural next step after 16 (Exercise 4).

Key takeaways

  1. Three threads run through the course: adjoints and gradients (03 → 07 → 08 → 13), gradient dynamics (05 → 06 → 10 → 11 → 18), controllability, representation and transport (02 → 12 → 13 → 14 → 15 → 16 → 17).
  2. In finite dimension, controllability of \((A,B)\) is equivalent to observability of \((A^\top,B^\top)\). The adjoint method gives a gradient by one state and one adjoint solve per scalar objective, under differentiability and well-posedness assumptions.
  3. Backpropagation is the discrete adjoint of a specified discrete cost. Whether a discretized continuous adjoint coincides with it depends on the discretization.
  4. The heavy-ball scheme is a discretized damped oscillator for any differentiable loss; its mode-by-mode analysis needs a quadratic.
  5. One system can host different problems: steering, stabilization, long-horizon optimality and learning a field ask different questions.
  6. Capacity, optimization and generalization are distinct: capacity alone does not guarantee successful training, and a small training loss alone does not guarantee generalization.

7. Exercises

★ conceptual · ★★ mathematical · ★★★ computational / project

  1. Backpropagation for a control theorist. ★ In at most one page, explain backpropagation to a student who knows notebooks 03 and 07 but no machine learning. (a) State precisely the identity of §1: which cost, which scheme, which multipliers. (b) Give two cautions about discretization: one about which gradient is computed, one about its cost.
  2. Which question? ★★ Classify each statement as capacity, optimization or generalization, and explain what it does and does not guarantee about the other two: (a) “with \(P\ge N\) neurons and distinct inputs, one hidden layer interpolates any labels” (12); (b) “SGD with a decreasing step reaches a small expected gradient norm” (10); (c) “the classifier chosen on validation made 42 errors in 2000 new observations” (13–14); (d) “a ReLU neural ODE can steer \(N\) distinct points into open target sets” (14).
  3. The closed loop of notebook 16, and its transient. ★★ Form \(A+BK\) with \(K=(-1,-3)\) for the oscillator matrices above. (a) Check that it equals \(\begin{pmatrix}0&1\\-2&-3\end{pmatrix}\) and compute its eigenvalues. (b) Show that it is not \(A_k=\begin{pmatrix}0&1\\-1&-k\end{pmatrix}\) for any \(k\). (c) Find the feedback \(K\) that gives \(A_3\). (d) For both closed loops, estimate \(\max_{t\in[0,10]}\|e^{(A+BK)t}\|_2\) on a fine time grid, and compute the eigenvalues of the symmetric part \(\frac12\big((A+BK)+(A+BK)^\top\big)\). Explain why one of them can amplify some initial states for a short time although both are asymptotically stable, and why this is invisible in the spectral abscissa.
  4. A project, designed before it is run. ★★★ Choose one mini-project and write, before any experiment, a one-page protocol with hypotheses, observables, computational cost, data streams and a frozen final evaluation. Do not run a new benchmark and do not use any final evaluation data of the course while writing it.
    1. Turnpike in trained residual networks: do the layer parameters of a ResNet trained with a running cost settle in the middle layers as the depth grows at a fixed step (13, 08)?
    2. SA-NODEs without privileged targets: how much does notebook 16’s Laboratory B degrade when the derivative targets are estimated from the trajectories by finite differences, inside and outside the training region?
# TODO: student exercise (Exercise 3)
# Return the closed-loop matrix A + B K for a row vector K of shape (1, 2).

def closed_loop(K):
    ...  # your code here
    return None

Where are we going?

This is the last notebook of the course. The open questions of §6 are where the mathematics continues; the protocol of notebooks 09–16, which fixes every decision before the final data exist, is the tool the course offers for studying such questions honestly. For a review of the whole route, notebook 00 gives the map of the course and its glossary; this notebook gives the connections with their scope.

References

  1. E. Sontag, Mathematical Control Theory: Deterministic Finite Dimensional Systems, 2nd ed., Springer, 1998.
  2. B. Geshkovski, E. Zuazua, Turnpike in optimal control of PDEs, ResNets, and beyond, Acta Numerica 31 (2022), 135–263.
  3. D. Ruiz-Balet, E. Zuazua, Neural ODE control for classification, approximation, and transport, SIAM Review 65 (2023), 735–773.
  4. C. Esteve-Yagüe, B. Geshkovski, D. Pighin, E. Zuazua, Turnpike in Lipschitz-nonlinear optimal control, Nonlinearity 35 (2022), 1652–1701.
  5. R. S. Sutton, A. G. Barto, Reinforcement Learning: An Introduction, 2nd ed., MIT Press, 2018.
  6. E. Zuazua, Controllability and observability of partial differential equations: some results and open problems, Handbook of Differential Equations: Evolutionary Equations 3 (2007), 527–621.