主要参考:《基于子空间辨识的船舶微电网模型预测控制策略研究》- 金慧敏
# 一、MOESP 算法概述
MOESP (Multivariable Output Error State Space, 多变量输出误差状态空间) 方法是系统辨识领域中一种常用的子空间方法,其于 1993 年由
Verhaegen 提出。MOESP 算法的辨识过程包含两个步骤。首先是通过给定的 I/O 数据构造 Hankel 矩阵,对其进行实施 QR 分解技术,然后由分解得到的子空间对扩展观测矩阵进行估计。其次是通过估计扩展的观测矩阵来获取辨识对象的状态空间模型的系数。虽然 MOESP 算法在求解输入矩阵 B 和反馈矩阵 D 时需要构造一个较大的矩阵,但与使用最小二乘求解系统矩阵和输出矩阵的 N4SID 算法的过程相比,该方法求解过程更加简洁、方便,其准确性也同样可以得到保证。
# 二、MOESP 算法主要流程
# 2.1 数据预处理
考虑一个 输入, 输出的离散线性时不变系统:
假设 是可达的且 是可观的,简单的定义上式所表达的 LTI 系统描述为。通过求解上式,可以得到:
如果,上式可以化简为:
上式称为零输入响应。此外,如果,则有:
上式表示由外部输入 引起的响应,这种称为零状态响应。因此,线性状态空间方程的响应可以表示为零输入响应和零状态响应两者之和。
对于零状态响应,定义 维矩阵:
其中 被称作 LTI 系统的脉冲响应,或者马尔可夫参数。
MOESP 算法要解决的问题是:假设给定输入输出数据,问题是确定系统维数 和系统矩阵。这正是确定性 LTI 系统的子空间辨识问题。
假设给定输入输出数据,其中 足够大,然后对于 有:
假设右侧由输入构成的宽矩阵是满秩的,然后通过最小二乘法求解上述方程可以得到脉冲响应。这表明在一定的假设下,可以通过使用输入输出数据,而不适用脉冲响应来计算 LTI 系统的最小实现。
# 2.2 构造 Hankel 矩阵
假设给定输入和输出:
其中 严格大于状态向量的维数, 为 Hankel 矩阵的列数。由这些数据,形成块 Hankel 矩阵:
其中索引 和 分别表示第一列的首元素和末元素下标。块 Hankel 矩阵的列数通常确定为,且 足够大。
原始系统的 Toeplitz 矩阵为:
扩展可观性矩阵为:
由此,可以得到如下关系式:
其中 为初始状态矩阵。
# 2.3 假设
(1);
(2),其中;
(3);
其中假设(1)的含义是状态向量是充分激励的,或者系统是可达的。假设(2)表明输入序列应满足 阶的持续激励(PE)条件。如果以上假设以及 都满足,那么下列秩条件成立:
# 2.4 LQ 分解
通过对 Hankel 矩阵进行 LQ 分解可以得到:
LQ 分解的实际计算是通过对矩阵的 QR 分解进行转置来完成的。在假设 2.3 下, 矩阵的每一列是一个输入输出对,尤其 的每一列都包含系统的一个零输入响应,此外有,即系统的维数。由上式可知:
易得 是非奇异的,所以可以得到,因此可以得到:
由于 和 是相互正交的矩阵,上式右边的首项是由 中的行向量组成的,第二项和它正交。因此, 的行空间在 上的正交投影为:
向量 的行空间在 的行空间的补集 上的正交投影为:
由于,可以得到:
值得注意的是,虽然右边是一个正交和,但左边是一个直接和,因此左边的两个量不一定是正交的,这表明,。将上式右乘 得到:
在的假设下,可知 行满秩并且,等于。因此,由 SVD 分解 得到维数。
# 2.5 SVD 分解
将 进行 SVD 得到:
从而有:
从而有:
其余的步骤与 N4SID 方法一致。
# 三、参考 matlab 程序
% -------------------------------------------------------- | |
% Author: Alexander Robles | |
% Feec-UNICAMP | |
% --------------------------------------------------------- | |
clear all;clc; | |
run('systemdata.m') | |
% Script for comparing MOESP and N4SID outputs | |
clc; | |
% Inputs of functions N, R, k | |
% Form Hankel matrices U,Y from system data (u,y) see blkhank.m | |
% R=input('Block_MOESP rows: '); | |
% k=input('Block_N4SID rows: '); | |
R=20; | |
k=20; | |
% call functions | |
[A1,B1,C1,D1,n1]=moespar(u,y,R); | |
[A2,B2,C2,D2,n2] = n4sidkatamodar(u,y,k); | |
[A3,B3,C3,D3,n3] = n4sid_self(u,y,k); | |
%Check Markov parameters (impulse responseof of MIMO system): | |
% Dr, Cr*Br, Cr*Ar*Br, Cr*Ar^2*Br ... | |
% D1, C1*B1, C1*A1*B1, C1*A1^2*B1 ... | |
% Graphics of system outputs and model outputs (estimate outputs) | |
run('modeloutputs.m') |
% ------------------------------------------------------- | |
% Generate system data (inputs and outputs) | |
% -------------------------------------------------------- | |
% Author: Alexander Robles | |
% FEEC-UNICAMP | |
% --------------------------------------------------------- | |
clear all | |
clc | |
% The state space system equations: | |
% x_k+1 = A x_k + B u_k | |
% y_k = C x_k + D u_k | |
Ar=[0.2128 0.1360 0.1979 -0.0836; | |
0.1808 0.4420 -0.3279 0.2344; | |
-0.5182 0.1728 -0.5448 -0.3083; | |
0.2252 -0.0541 -0.4679 0.8290]; | |
Br=[-0.0101 0.0317 -0.9347; | |
-0.0600 0.5621 0.1657; | |
-0.3310 -0.3712 -0.5846; | |
-0.2655 0.4255 0.2204]; | |
Cr=[0.6557 -0.2502 -0.5188 -0.1229; | |
0.6532 -0.1583 -0.0550 -0.2497]; | |
Dr=[-0.4326 0.1253 -1.1465 | |
-1.6656 0.2877 1.1909]; | |
%-------------- | |
% N=input('Size of data N:'); | |
N=500; | |
tt = 0:1:(N-1); | |
% -------------Input, u (white noise), is persistently exciting -------------- | |
u1 = randn(1,N); | |
u2 = randn(1,N); | |
u3 = randn(1,N); | |
u = [u1; u2; u3]; | |
%-------------Desing state-space model and outputs------ | |
X0=zeros(4,1); % first state | |
%%%----- | |
x(:,1) = X0; | |
xc(:,1) = x(:,1); | |
yc(:,1) = Cr * xc(:,1) + Dr*u(:,1); | |
for i = 1:length(tt) | |
xc(:,i+1) = Ar * xc(:,i) + Br* u(:,i); | |
yc(:,i) = Cr * xc(:,i) + Dr*u(:,i); | |
y = yc; | |
end | |
%-------------Plot inputs------------------------- | |
% figure (1) | |
% plot(tt,u1,'r',tt,u2,'c',tt,u3,'k'); | |
% title('Inputs'); | |
% legend('u1', 'u2', 'u3'); | |
%-------------Plot outputs------------------------- | |
% figure (2) | |
% plot(tt,y(1,:),'g',tt,yc(1,:),'*b'); | |
% title('Outputs'); | |
% legend('y1', 'y1c'); | |
% | |
% figure (3) | |
% plot(tt,y(2,:),'g',tt,yc(2,:),'*b'); | |
% title('Outputs'); | |
% legend('y2', 'y2c'); |
% MOESP Function | |
% m = dim(u), p = dim(y), n = dim(x); R = Numero de filas de blocos | |
% U = km x N Matriz de Entradas | |
% Y = kp x N Matriz de Saidas | |
% Number of columns depends number of Hankel blocks R--- N=ndat-R+1 | |
% If R ups >>j will decrease !DO NOT FORGET! 07/11/16 | |
function [A,B,C,D,n] = moespar(u,y,R) | |
%Number of inputs and outputs: | |
[m,nu] = size(u); | |
if nu < m;u = u';[m,nu] = size(u);end | |
[p,ny] = size(y); | |
if ny < p;y = y';[p,ny] = size(y);end | |
Ncol=ny-R+1;% Calculate number of COLUMNS BLOCK HANKEL | |
%Make BLOCK HANKEL INPUTS U-OUTPUTS Y | |
U= blkhank(u,R,Ncol); | |
Y= blkhank(y,R,Ncol); | |
km = size(U,1); kp = size(Y,1); % Rows of U and Y | |
L = triu(qr([U;Y]'))'; % LQ decomposition %Eq. 3.45 qr: Orthogonal-triangular decomposition. | |
L11 = L(1:km,1:km); | |
L21 = L(km+1:km+kp,1:km); | |
L22 = L(km+1:km+kp,km+1:km+kp); | |
[UU,SS,VV] = svd(L22); % Eq. 3.48 Singular Value Descomposition | |
s1 = diag(SS); | |
n=find(cumsum(s1)>0.8*sum(s1),1); | |
%n=4; | |
U1 = UU(:,1:n); % n is known, as you can see last equation | |
Ok = U1*sqrtm(SS(1:n,1:n)); % SQRTM Matrix square root. %Eq. 3.49 | |
% Matrices A and C | |
C = Ok(1:p,1:n); % Eq. (6.41) | |
A = pinv(Ok(1:p*(R-1),1:n))*Ok(p+1:p*R,1:n); % Eq.3.51 | |
% Matrices B and D | |
U2 = UU(:,n+1:size(UU',1)); | |
Z = U2'*L21/L11; % Eq. 3.53 | |
XX = []; RR = []; | |
for j = 1:R | |
XX = [XX; Z(:,m*(j-1)+1:m*j)]; | |
Okj = Ok(1:p*(R-j),:); | |
Rj = [zeros(p*(j-1),p) zeros(p*(j-1),n); | |
eye(p) zeros(p,n); zeros(p*(R-j),p) Okj]; | |
RR = [RR; U2'*Rj]; | |
end | |
DB = pinv(RR)*XX; % Eq. 3.57 | |
D = DB(1:p,:); | |
B = DB(p+1:size(DB,1),:); |
% Algoritmo do metodo N4SID modificado, com dados de entrada u, | |
% saida y, e k a ordem dos blocos de Hankel | |
function [A,B,C,D,n] = n4sidkatamodar(u,y,k) | |
[l,ny] = size(y);if (ny < l);y = y';[l,ny] = size(y);end | |
[m,nu] = size(u);if (nu < m);u = u';[m,nu] = size(u);end | |
% Determinar o numero de columns para as matrizes de Hankel | |
N = ny-2*k+1; | |
%Constroir as matrizes de dados, bloco de Hankel | |
U = blkhank(u,2*k,N); | |
Y = blkhank(y,2*k,N); | |
Up=U(1:k*m,:); | |
Uf=U(k*m+1:2*k*m,:); | |
Yp=Y(1:k*l,:); | |
Yf=Y(k*l+1:2*k*l,:); | |
km = size(Up,1); | |
kl = size(Yp,1); | |
Wp = [Up;Yp]; | |
% *********** ALGORITMO *********** | |
%Passo 1 | |
%decomposicao LQ | |
[Q,L] = qr([Uf;Up;Yp;Yf]',0); | |
Q=Q'; L=L'; | |
L11 = L(1:km,1:km); | |
L21 = L(km+1:2*km,1:km); | |
L22 = L(km+1:2*km,km+1:2*km); | |
L31 = L(2*km+1:2*km+kl,1:km); | |
L32 = L(2*km+1:2*km+kl,km+1:2*km); | |
L33 = L(2*km+1:2*km+kl,2*km+1:2*km+kl); | |
L41 = L(2*km+kl+1:2*km+2*kl,1:km); | |
L42 = L(2*km+kl+1:2*km+2*kl,km+1:2*km); | |
L43 = L(2*km+kl+1:2*km+2*kl,2*km+1:2*km+kl); | |
L44 = L(2*km+kl+1:2*km+2*kl,2*km+kl+1:2*km+2*kl); | |
R11 = L11; | |
R21 = [L21;L31]; | |
R22 = [L22 zeros(km,kl); L32 L33]; | |
R31 = L41; | |
R32 = [L42 L43]; | |
xi = R32*pinv(R22)*Wp; | |
%Passo 2 | |
[UU,SS,VV] = svd(xi); | |
ss = diag(SS); | |
n=find(cumsum(ss)>0.85*sum(ss),1); | |
%n=4; | |
% hold off | |
% figure(1) | |
% title('Valores singulares'); | |
% xlabel('Ordem'); | |
% plot(ss) | |
% pause; | |
% figure(2) | |
% title('Valores singulares'); | |
% xlabel('Ordem'); | |
% bar(ss) | |
% n = input(' Ordem do sistema ? '); | |
% while isempty(n) | |
% n = input(' Ordem do sistema ? '); | |
% end | |
U1 = UU(:,1:n); | |
S1 = SS(1:n,1:n); | |
V1 = VV(:,1:n); | |
%Matrizes A e C | |
Ok = U1*sqrtm(S1); | |
C = Ok(1:l,1:n); | |
A = pinv(Ok(1:l*(k-1),1:n))*Ok(l+1:l*k,1:n); | |
%Passo 3 | |
%Matrizes B e D | |
TOEP = (R31 - R32*pinv(R22)*R21)*pinv(R11); | |
G = TOEP(:,1:m); | |
G0 = G(1:l,:); | |
G1 = G(l+1:2*l,:); | |
G2 = G(2*l+1:3*l,:); | |
G3 = G(3*l+1:4*l,:); | |
G4 = G(4*l+1:5*l,:); | |
D = G0; | |
Hk = [G1 G2;G2 G3;G3 G4]; | |
Ok1 = Ok(1:3*l,:); | |
Ck = pinv(Ok1)*Hk; | |
B = Ck(:,1:m); | |
%% 自己尝试估计状态序列向量 | |
X_f_estimate = sqrtm(S1) * V1'; | |
X_f_fzy = X_f_estimate(:,2:end); | |
X_p_fzy = X_f_estimate(:,1:end-1); | |
u_fzy = Uf(1:m,1:end-1); | |
y_fzy = Yf(1:l,1:end-1); | |
input_fzy = [X_p_fzy;u_fzy]; | |
output_fzy = [X_f_fzy;y_fzy]; | |
predict_sys = output_fzy*input_fzy'/(input_fzy*input_fzy'); | |
predict_A = predict_sys(1:n,1:n); | |
predict_B = predict_sys(1:n,n+1:end); | |
predict_C = predict_sys(n+1:end,1:n); | |
predict_D = predict_sys(n+1:end,n+1:end); | |
% disp(norm(predict_A-A)) | |
% disp(norm(predict_B-B)) | |
% disp(norm(predict_C-C)) | |
% disp(norm(predict_D-D)) |
% | |
% H = blkhank(y,i,j) | |
% | |
% Description: | |
% Make a block Hankel matrix with the data y | |
% containing i block-rows and j columns | |
% | |
function H = blkhank(y,i,j) % i=k=R is an abritary positive | |
% Make a (block)-row vector out of y | |
[l,nd] = size(y); | |
if nd < l;y = y';[l,nd] = size(y);end | |
% Check dimensions | |
if i < 0;error('blkHank: i should be positive');end | |
if j < 0;error('blkHank: j should be positive');end | |
if j > nd-i+1;error('blkHank: j too big');end % j is less or iqual nd-i+1 | |
% Make a block-Hankel matrix | |
H=zeros(l*i,j); | |
for k=1:i | |
H((k-1)*l+1:k*l,:)=y(:,k:k+j-1); | |
end |
%Benchmarck : | |
% Consider a multivariable fourth order system a,b,c,d | |
% with 3 inputs and 2 outputs: | |
clc; | |
u1 = u; | |
% The state space system equations: | |
% x_{k+1) = A x_k + B u_k | |
% y_k = C x_k + D u_k | |
% Model output: | |
ym = dlsim(A1,B1,C1,D1,u1)'; % MOESP output | |
yn = dlsim(A2,B2,C2,D2,u1)'; % N4SID output | |
y_self = dlsim(A3,B3,C3,D3,u1)'; % N4SID output | |
%-------------Plot system outputs and model outputs------------------------- | |
figure (1) | |
hold off;subplot;clf; | |
subplot(211);plot(tt,y(1,:),'r',tt,ym(1,:),'*b'); | |
title('First ouput'); | |
legend('System output', 'MOESP output'); | |
subplot(212);plot(tt,y(2,:),'r',tt,ym(2,:),'*b'); | |
legend('System output', 'MOESP output'); | |
title('Second output'); | |
figure (2) | |
hold off;subplot;clf; | |
subplot(211);plot(tt,y(1,:),'r',tt,yn(1,:),'*b'); | |
title('First ouput'); | |
legend('System output', 'M4SID output'); | |
subplot(212);plot(tt,y(2,:),'r',tt,yn(2,:),'*b'); | |
legend('System output', 'N4SID output'); | |
title('Second output'); | |
figure (3) | |
hold off;subplot;clf; | |
subplot(211);plot(tt,y(1,:),'r',tt,y_self(1,:),'*b'); | |
title('First ouput'); | |
legend('System output', 'M4SID output'); | |
subplot(212);plot(tt,y(2,:),'r',tt,y_self(2,:),'*b'); | |
legend('System output', 'N4SID output'); | |
title('Second output'); | |
%----------------Mean square error-------------------------------------------- | |
errMOESP = (sum((y(1,:)-ym(1,:)).^2)+sum((y(2,:)-ym(2,:)).^2))/N | |
errN4SID = (sum((y(1,:)-yn(1,:)).^2)+sum((y(2,:)-yn(2,:)).^2))/N | |
errN4SID_self = (sum((y(1,:)-y_self(1,:)).^2)+sum((y(2,:)-y_self(2,:)).^2))/N |