系统辨识,即在已知系统阶次的情况下辨识出系统的参数或辨识系统阶次,一般用到的方法有最小二乘法、辅助变量法等,对于离线与在线辨识,只是加入一个递推的问题。下面本文给出系统辨识方法的实现代码。
首先是处理数据:
U1=importdata('uy1.txt');
W1=U1.data;%第一列u,第二列y
s=length(W1(:,1));n=2;N=s-n;
A1=zeros(N,1);B1=zeros(N,4);
for i=1:N
A1(i)=W1(i+2,2);%y3,y4,y5,....
B1(i,:)=[-W1(i+1,2),-W1(i,2),W1(i+1,1),W1(i,1)];%[-y2,-y1,u2,u1]...
end
%解析法
for i=1:N
X1(:,i)=A1(i)*pinv(B1(i,:));
end
a1=sum(X1(1,:));a2=sum(X1(2,:));
b1=sum(X1(3,:));b2=sum(X1(4,:));
X=[a1/N,a2/N,b1/N,b2/N]';
%最小二乘法
% fi=B;y=A;
Xls=inv((B1'*B1))*B1'*A1;
%递推最小二乘法
c=100;
Xdls=[0;0;0;0];P=c^2*eye(4);
for i=1:N
ps=B1(i,:)';
K=P*ps*1/(1+ps'*P*ps);
P=P-P*ps*1/(1+ps'*P*ps)*ps'*P;
Xdls=Xdls+K*(A1(i)-ps'*Xdls);
end
%辅助变量法
Xiv=Xls;
u1=W1(:,1);
Z1=B1;
for j=1:1000
y1=Z1*Xiv;
y1=cat(1,W1(1:2,2),y1);
for i=1:N
Z1(i,:)=[-y1(i+1),-y1(i),u1(i+1),u1(i)];
end
Xiv0=Xiv;
Xiv=inv((Z1'*B1))*Z1'*A1;
if sum(abs(Xiv0-Xiv))<0.1%收敛
break
end
end
%递推辅助变量法
c=100;
Xdiv=Xls;P=c^2*eye(4);
u1=W1(:,1);
Z1=B1;
for i=1:N
ps=B1(i,:)';
y1=Z1*Xdiv;
y1=cat(1,W1(1:2,2),y1);
Z1(i,:)=[-y1(i+1),-y1(i),u1(i+1),u1(i)];
K=P*Z1(i,:)'*1/(1+ps'*P*Z1(i,:)');
P=P-K*ps'*P;
Xdiv=Xdiv+K*(A1(i)-ps'*Xdiv);
end
%广义最小二乘法
m=2;
Xols=Xls;
e1(1)=0;e1(2)=0;
for p=1:100
for k=n+1:n+N
e1(k)=A1(k-2)-B1(k-2,:)*Xols;
end
for i=1:N
for j=1:m
O1(i,j)=-e1(n+i-j);
end
end
f1=inv((O1'*O1))*O1'