|
| 1 | +import numpy as np |
| 2 | + |
| 3 | +# ───────────────────────────────────────────────────────────────────────────── |
| 4 | +# helpers |
| 5 | +# ───────────────────────────────────────────────────────────────────────────── |
| 6 | + |
| 7 | +def _random_orthonormal(n, k, seed=0): |
| 8 | + """Return an (n, k) matrix with orthonormal columns.""" |
| 9 | + rng = np.random.default_rng(seed) |
| 10 | + A = rng.standard_normal((n, k)) |
| 11 | + Q, _ = np.linalg.qr(A) |
| 12 | + return Q[:, :k] |
| 13 | + |
| 14 | + |
| 15 | +def _make_synthetic_data(n_state=30, n_ctrl=15, n_samples=40, n_params=3, |
| 16 | + seed=0): |
| 17 | + """ |
| 18 | + Build synthetic state-space / control-input datasets for p parameter points. |
| 19 | +
|
| 20 | + Returns |
| 21 | + ------- |
| 22 | + state_data : list[ndarray], each (n_state, n_samples) |
| 23 | + prev_state_data : list[ndarray], each (n_state, n_samples) |
| 24 | + ctrl_data : list[ndarray], each (n_ctrl, n_samples) |
| 25 | + params : ndarray (1, n_params) – 1-d parameter space |
| 26 | + """ |
| 27 | + rng = np.random.default_rng(seed) |
| 28 | + params = np.linspace(0.5, 1.5, n_params)[None, :] # shape (1, p) |
| 29 | + |
| 30 | + state_data, prev_state_data, ctrl_data = [], [], [] |
| 31 | + for i in range(n_params): |
| 32 | + mu = params[0, i] |
| 33 | + # simple smooth synthetic trajectories that depend on mu |
| 34 | + t = np.linspace(0, 2 * np.pi, n_samples) |
| 35 | + x = np.linspace(0, 1, n_state) |
| 36 | + tt, xx = np.meshgrid(t, x) |
| 37 | + snap = mu * np.sin(xx * tt) + 0.1 * rng.standard_normal((n_state, n_samples)) |
| 38 | + state_data.append(snap) |
| 39 | + prev_state_data.append(np.roll(snap, 1, axis=1)) # shift by one time step |
| 40 | + |
| 41 | + ctrl = mu * np.cos(np.linspace(0, np.pi, n_ctrl)[:, None] * t[None, :]) |
| 42 | + ctrl_data.append(ctrl) |
| 43 | + |
| 44 | + return state_data, prev_state_data, ctrl_data, params |
0 commit comments