Controle Baseado em Dados
Universidade Federal do Pará
Em DeePC — Introdução, previmos a resposta de um sistema resolvendo \(g\) em \([U_p;Y_p;U_f]g=[u_{\text{ini}};y_{\text{ini}};u]\) e predizendo \(y=Y_fg\) — sem estimar \((A,B,C,D)\), e sem ruído.
Aqui, adicionamos ruído de medição: a formulação crua falha, e a regularização de Tikhonov resolve (Coulson et al. 2019).
\(A=[U_p;Y_p;U_f]\) tem mais colunas que linhas — \(g\) não é único.
\[ \min_{g} \; \|Ag - r\|_2^2 + \lambda \|g\|_2^2 \quad \Longrightarrow \quad g_\lambda = (A^\top A + \lambda I)^{-1} A^\top r \]
def hankel(x, L):
T = len(x) - L + 1
return np.array([x[i:i+T] for i in range(L)])
Tini, N = 2, 10
Hu, Hy = hankel(u_d, Tini+N), hankel(y_d, Tini+N)
Up, Uf, Yp, Yf = Hu[:Tini], Hu[Tini:], Hy[:Tini], Hy[Tini:]
u_ini = rng.choice([-1.0, 1.0], size=Tini)
y_ini = simulate(u_ini, noise=0.05)
u_fut = np.ones(N)
y_true = simulate(u_fut, y0=y_ini[-1])
A = np.vstack([Up, Yp, Uf])
r = np.concatenate([u_ini, y_ini, u_fut])
def solve_ridge(lam):
return Yf @ np.linalg.solve(A.T@A + lam*np.eye(A.shape[1]), A.T@r)import matplotlib.pyplot as plt
lambdas = np.logspace(-8, 1, 40)
rmse = [np.sqrt(np.mean((solve_ridge(lam) - y_true)**2)) for lam in lambdas]
fig, ax = plt.subplots()
_ = ax.plot(lambdas, rmse, "o-"); _ = ax.set_xscale("log")
_ = ax.set_xlabel(r"$\lambda$"); _ = ax.set_ylabel("RMSE")
plt.tight_layout(); plt.show()Amplo platô de bons \(\lambda\) entre \(10^{-8}\) e \(10^{-2}\); depois o erro cresce (regularização demais ignora os dados). Em \(\lambda=0\) exato, \(A^\top A\) é singular — qualquer regularização pequena já estabiliza.