No BSD License  

Highlights from
Subspace Identification for Linear Systems

image thumbnail
sto_stat(y,i,n,AUXin,W,sil);
% 
%   Stochastic subspace identification (Algorithm 1)
%
%           [A,K,C,R] = sto_stat(y,i);
% 
%   Inputs:
%           y: matrix of measured outputs
%           i: number of block rows in Hankel matrices 
%              (i * #outputs) is the max. order that can be estimated 
%              Typically: i = 2 * (max order)/(#outputs)
%           
%   Outputs:
%           A,K,C,R: stochastic state space system
%           
%                 x_{k+1} = A x_k + K e_k
%                   y_k   = C x_k + e_k
%                cov(e_k) = R
%                
%   Optional:
%
%           [A,K,C,R,AUX,G,L0,ss] = sto_stat(y,i,n,AUX,W,sil);
%   
%           n:    optional order estimate (default [])
%           AUX:  optional auxilary variable to increase speed (default [])
%           W:    optional weighting flag
%                    CVA: canonical variate analysis (default)
%                    PC:  principal components
%                    UPC: unweighted principal components
%           G,L0: covariance model
%           ss:   column vector with singular values
%           sil:  when equal to 1 no text output is generated
%           
%   Example:
%   
%           [A,K,C,R,AUX] = sto_stat(y,10,2);
%           for k=3:6
%              [A,K,C,R] = sto_stat(y,10,k,AUX);
%           end
%           
%   Reference:
%   
%           Subspace Identification for Linear Systems
%           Theory - Implementation - Applications
%           Peter Van Overschee / Bart De Moor
%           Kluwer Academic Publishers, 1996, Page 86 (Fig 3.11)
%           
%   Copyright:
%   
%           Peter Van Overschee, December 1995
%           peter.vanoverschee@esat.kuleuven.ac.be
%
%

function [A,K,C,Ro,AUX,G,L0,ss] = sto_stat(y,i,n,AUXin,W,sil);

if (nargin < 6);sil = 0;end

mydisp(sil,' ');
mydisp(sil,'   Stochastic algorithm 1');
mydisp(sil,'   ----------------------');

% Check the arguments
if (nargin < 2);error('sto_stat needs at least two arguments');end
if (nargin < 3);n = [];end
if (nargin < 4);AUXin = [];end
if (nargin < 5);W = [];end
if (W == []);W = 'CVA';end

% Turn the data into row vectors and check
[l,ny] = size(y);if (ny < l);y = y';[l,ny] = size(y);end
if (i < 0);error('Number of block rows should be positive');end
if (l < 0);error('Need a non-empty output vector');end
if ((ny-2*i+1) < (2*l*i));error('Not enough data points');end
Wn = 0;
if (length(W) == 3) 
  if (prod(W == 'CVA') | prod(W == 'cva') | prod(W == 'Cva'));Wn = 1;end 
  if (prod(W == 'UPC') | prod(W == 'upc') | prod(W == 'Upc'));Wn = 3;end
end    
if (length(W) == 2) 
  if (prod(W == 'PC') | prod(W == 'pc') | prod(W == 'Pc'));Wn = 2;end 
end
if (Wn == 0);error('W should be CVA, PC or UPC');end
W = Wn;

% Determine the number of columns in Hankel matrices
j = ny-2*i+1;

% Check compatibility of AUXin
[AUXin,Wflag] = chkaux(AUXin,i,[],y(1,1),2,W,sil); 

% Compute the R factor
if AUXin == []
  Y = blkhank(y/sqrt(j),2*i,j); 		% Output block Hankel
  mydisp(sil,'      Computing ... R factor');
  R = triu(qr(Y'))'; 			% R factor
  R = R(1:2*i*l,1:2*i*l); 		% Truncate
  clear Y
else
  R = AUXin(2:2*i*l+1,1:2*i*l);
  bb = 2*i*l+1;
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%                                  BEGIN ALGORITHM
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%




% **************************************
%               STEP 1 
% **************************************

% First compute the orthogonal projections Ob and Obm
if (AUXin == [])
  Ob  = R(l*i+1:2*l*i,1:l*i);
else
  Ob  = AUXin(bb+1:bb+l*i,1:l*i);
  bb  = bb+l*i;
end



% **************************************
%               STEP 2 
% **************************************



% Compute the SVD
if (AUXin == []) | (Wflag == 1)
  mydisp(sil,'      Computing ... SVD');
  % Compute the matrix WOW we want to take an svd off
  % W == 1 (CVA), W == 2 (PC), W == 3 (UPC)
  if (W == 1)
    W1i = triu(qr(R(l*i+1:2*l*i,1:2*l*i)'));
    W1i = W1i(1:l*i,1:l*i)';
    WOW = W1i\Ob;
  end
  if (W == 2)
    WOW = R(l*i+1:2*l*i,1:l*i)*R(1:l*i,1:l*i)';
  end
  if (W == 3)
    WOW = Ob;
  end
  [U,S,V] = svd(WOW);
  if (W == 1);U = W1i*U;end 		% CVA
  ss = diag(S);
  clear V S WOW
else
  U = AUXin(bb+1:bb+l*i,1:l*i);
  ss = AUXin(bb+1:bb+l*i,l*i+1);
end




% **************************************
%               STEP 3 
% **************************************

% Determine the order from the singular values
if (n == [])
  figure(gcf);hold off;subplot
  if (W == 1)
    bar([1:l*i],real(acos(ss))*180/pi);
    title('Principal Angles');
    ylabel('degrees');
  else
    [xx,yy] = bar([1:l*i],ss);
    semilogy(xx,yy+10^(floor(log10(min(ss)))));
    axis([0,length(ss)+1,10^(floor(log10(min(ss)))),10^(ceil(log10(max(ss))))]);
    title('Singular Values');
  end
  xlabel('Order');
  n = 0;
  while (n < 1) | (n > l*i-1)
    n = input('      System order ? ');
    if (n == []);n = -1;end
  end
  mydisp(sil,' ');
end

U1 = U(:,1:n); 				% Determine U1



% **************************************
%               STEP 4 
% **************************************

% Determine gam and gamm
gam  = U1*diag(sqrt(ss(1:n)));
gamm = U1(1:l*(i-1),:)*diag(sqrt(ss(1:n)));
% And their pseudo inverses
gam_inv  = pinv(gam);
gamm_inv = pinv(gamm);
clear gam gamm



% **************************************
%               STEP 5 
% **************************************

% Determine the states Xi and Xip
Xi  = gam_inv  * Ob;
Xip = gamm_inv * R(l*(i+1)+1:2*l*i,1:l*(i+1));;
clear gamm_inv



% **************************************
%               STEP 6 
% **************************************

% Determine the state matrices A and C
mydisp(sil,['      Computing ... System matrices A,C (Order ',num2str(n),')']); 
Rhs = [       Xi , zeros(n,l)  ]; 	% Right hand side
Lhs = [      Xip   ;  R(l*i+1:l*(i+1),1:l*(i+1))]; % Left hand side

% Solve least squares
sol = Lhs/Rhs;

% Extract the system matrices
A = sol(1:n,1:n);
C = sol(n+1:n+l,1:n);


% **************************************
%               STEP 7 
% **************************************

% Determine delta
mydisp(sil,['      Computing ... System matrices G,L0 (Order ',num2str(n),')']); 
delta = gam_inv*(R(l*i+1:2*l*i,1:l*i)*R(1:l*i,1:l*i)');
G = delta(:,l*(i-1)+1:l*i); 		% G = last l columns


% **************************************
%               STEP 8 
% **************************************

% Determine L0
L0 = R(l*i+1:l*(i+1),:)*R(l*i+1:l*(i+1),:)';


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%                                  END ALGORITHM
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Determine K and Ro
mydisp(sil,'      Computing ... Riccati solution')
[K,Ro] = gl2kr(A,G,C,L0);


% Make AUX when needed
if nargout > 4
  AUX = zeros((4*l)*i+1,2*l*i);
  info = [2,i,0,y(1,1),W]; % in/out - i - u(1,1) - y(1,1) - W
  AUX(1,1:5) = info;
  bb = 1;
  AUX(bb+1:bb+2*l*i,1:2*l*i) = R;
  bb = bb+2*l*i;
  AUX(bb+1:bb+l*i,1:l*i) = Ob;
  bb = bb+l*i;
  AUX(bb+1:bb+l*i,1:l*i) = U;
  AUX(bb+1:bb+l*i,l*i+1) = ss;
end





Contact us at files@mathworks.com