(Weighted) generalised total least squares estimate plant model parameters from noisy input-output data:
0001 function [Theta, smax, smin, wscale] = MIMO_WGTLS(data, Sel, ModelVar); 0002 % 0003 % (Weighted) generalised total least squares estimate plant model 0004 % parameters from noisy input-output data: 0005 0006 % 0007 % sum (A(f)*Y(f) - B(f)*U(f))^H * W(f)^(-1) * (A(f)*Y(f) - B(f)*U(f)) 0008 % f 0009 % 0010 % The following cases can be handled: 0011 % 0012 % 1. 1 MIMO experiment with random excitations; or the concatenation of several data records 0013 % (see the ArbLocalPolyAnal function). 0014 % 2. 1 MIMO experiment with periodic excitations 0015 % (see the FastLocalPolyAnal function). 0016 % 3. nexp >=1 MIMO experiments with periodic excitations 0017 % (see the RobustLocalPolyAnal function for the case nu = 0018 % nexp). 0019 % 0020 % 0021 % [Theta, smax, smin, wscale] = MIMO_WGTLS(data, Sel, ModelVar); 0022 % 0023 % 0024 % Stochastic framework: errors-in-variables 0025 % Y = B/A U0 + Ig/A + NY 0026 % U = U0 + NU 0027 % 0028 % System with nu inputs and ny outputs 0029 % Y: ny x 1 observed output 0030 % U: nu x 1 observed input 0031 % NY: ny x 1 output noise 0032 % NU: nu x 1 input noise 0033 % 0034 % Model class: common denominator model 0035 % G = B/A: ny x nu plant transfer function 0036 % Tg = Ig/A: ny x 1 plant transient term 0037 % A: polynomial of order OrderA 0038 % B: ny x nu matrix polynomial of order OrderB 0039 % Ig: ny x 1 vector polynomial of order OrderIg 0040 % 0041 % Coefficients polynomials in raising powers of Omega, where 0042 % s-domain Omega = j*2*pi*freq 0043 % sqrt(s)-domain Omega = sqrt(j*2*pi*freq) 0044 % z-domain Omega = exp(-j*2*pi*freq*Ts) 0045 % 0046 % Reference: 0047 % 0048 % Pintelon R., P. Guillaume, G. Vandersteen and Y. Rolain (1998). Analyses, development and applications of TLS 0049 % algorithms in frequency-Domain System Identification, SIAM J. Matrix Anal. Appl., vol. 19, no. 4, pp. 983-1004. 0050 % 0051 % 0052 % Output parameters 0053 % 0054 % Theta = estimated value plant, noise, and initial conditions parameters 0055 % structure with fields 'A', 'B', 'Ig' 0056 % Theta = struct('A',[],'B',[], 'Ig', []) 0057 % Theta.A = 1 x (OrderA+1) 0058 % Theta.A(r) = coefficient a(r-1) of Omega^(r-1) 0059 % Theta.B = ny x nu x (OrderB+1) 0060 % Theta.B(i,j,r) = coefficient b(i,j,r-1) of Omega^(r-1) 0061 % Theta.Ig = ny x (OrderIg+1) 0062 % Theta.Ig(i,r) = coefficient ig(i,r-1) of Omega^(r-1) 0063 % Note: all coefficients (except those for which Sel = 0) are free 0064 % during the minimization + in each iteration step the following 0065 % constraints are imposed: 0066 % norm([a, vec(b), vec(ig)] = 1 0067 % 0068 % smax = largest singular value of the Jacobian matrix 0069 % 0070 % smin = smallest singular value of the Jacobian matrix 0071 % 0072 % wscale = angular frequency scaling 0073 % 0074 % 0075 % Input parameters 0076 % 0077 % data = structure containing the non-parametric data required for the identification 0078 % data.Y = output DFT spectra of 1 or nu independent MIMO experiments 0079 % 1 MIMO experiment: ny x F 0080 % nexp MIMO experiments: ny x nexp x F with nexp >= 1 0081 % data.U = input DFT spectra of 1 or nu independent MIMO experiments 0082 % 1 MIMO experiment: nu x F 0083 % nexp MIMO experiments: nu x nexp x F with nexp >= 1 0084 % data.freq = vector of frequency values (Hz), size: F x 1 or 1 x F 0085 % data.Ts = sampling time (s) 0086 % data.CY = (sample) noise covariance matrix of Y 0087 % 1 MIMO experiment: ny x ny x F 0088 % nexp MIMO experiments: ny x ny x nexp x F with nexp >= 1 0089 % data.CU = (sample) noise covariance matrix of U 0090 % 1 MIMO experiment: nu x nu x F 0091 % nexp MIMO experiments: nu x nu x nexp x F with nexp >= 1 0092 % data.CYU = (sample) noise covariance matrix of U 0093 % 1 MIMO experiment: ny x nu x F 0094 % nexp MIMO experiments: ny x nu x nexp x F with nexp >= 1 0095 % 0096 % Sel = structure with fields 'A', 'B', 'Ig' 0097 % Sel = struct('A',[],'B',[], 'Ig', []) 0098 % Sel.A = 1 x (OrderA+1) 0099 % Sel.A(r) = 1 if coeff. a(r-1) is unknown 0100 % Sel.A(r) = 0 if coeff. a(r-1) = 0 0101 % Sel.B = ny x nu x (OrderB+1) 0102 % Sel.B(i,j,r) = 1 if coeff. b(i,j,r-1) is unknown 0103 % Sel.B(i,j,r) = 0 if coeff. b(i,j,r-1) = 0 0104 % Sel.Ig = ny x (OrderIg+1) 0105 % Sel.Ig(i,r) = 1 if coeff. ig(i,r-1) is unknown 0106 % Sel.Ig(i,r) = 0 if coeff. ig(i,r-1) = 0 0107 % 0108 % ModelVar = contains the information about the model to be identified 0109 % structure with fields 'Transient', 'ThePlane', 'TheModel', 'RecipPlant' 0110 % ModelVar = struct('Transient', [], 'PlantPlane', [], 'NoisePlane', [], 'RecipPlant', []) 0111 % ModelVar.Transient = 1 then the initial conditions of the plant and/or noise are estimated 0112 % ModelVar.PlantPlane = plane of the plant model 0113 % 's': continuous-time; 0114 % 'w': sqrt(s)-domain 0115 % 'z': discrete-time; 0116 % '': plane not defined 0117 % ModelVar.RecipPlant = 1 if plant model is reciprocal: G(i,j) = G(j,i) 0118 % 0119 % 0120 % Copyright (c) Rik Pintelon, Vrije Universiteit Brussel - dept. ELEC, 30 November 2009 0121 % All rights reserved. 0122 % Software can be used freely for non-commercial applications only. 0123 % Version 24 October 2011 0124 % 0125 0126 0127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0128 % initialisation of the variables, and compatibility check of the input arguments % 0129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0130 0131 % model structure variables 0132 ModelVar.PlantPlane = lower(ModelVar.PlantPlane); 0133 ModelVar.Struct = 'EIV'; 0134 0135 % add number of inputs and outputs to ModelVar 0136 ModelVar.ny = size(data.Y,1); 0137 ModelVar.nu = size(data.U,1); 0138 ny = ModelVar.ny; 0139 nu = ModelVar.nu; 0140 0141 % 1. imposes the compatibility of the the free model parameters 0142 % with the model structure 0143 % 2. puts the order of the polynomials in ModelVar 0144 [Sel, ModelVar] = MIMO_WTLS_ModelCompatibility(Sel, ModelVar); 0145 0146 % check if DC and Nyquist belong to the frequency set 0147 if data.freq(1) == 0, data.DC = 1; else data.DC = 0; end 0148 if data.freq(end) == 1/(2*data.Ts), data.Nyquist = 1; else data.Nyquist = 0; end 0149 data.freq = data.freq(:); 0150 0151 % determine the number of MIMO experiments 0152 NumberDim = length(size(data.U)); % number of matrix dimensions 0153 if NumberDim == 2 0154 data.NumberExp = 1; % number of MIMO experiments 0155 elseif NumberDim == 3 0156 data.NumberExp = size(data.U, 2); % number of MIMO experiments 0157 end % if 0158 0159 % hermitian symmetric square root inverse output covariance matrix 0160 F = length(data.freq); 0161 try 0162 Weighting = ~isempty(data.W); 0163 catch 0164 Weighting = 0; 0165 end 0166 if Weighting 0167 data.sqrtWinv = zeros(size(data.W)); 0168 % relative upper limit under which the singular values are set to zero 0169 % in the pseudo-inverse of the square root of the weighting matrix 0170 delta = 1e-6; 0171 if data.NumberExp == 1 0172 % pseudo-inverse in case of singular weighting 0173 data.sqrtWinv = Sqrt_Inv(data.W, delta); 0174 else % more than 1 MIMO experiment 0175 for ee = 1:data.NumberExp 0176 % pseudo-inverse in case of singular weighting 0177 data.sqrtWinv(:,:,ee,:) = Sqrt_Inv(reshape(data.W(:,:,ee,:), [ny,ny,F]), delta); 0178 end % ee, MIMO experiments 0179 end % if 1 MIMO experiment 0180 else 0181 ny = ModelVar.ny; 0182 nu = ModelVar.nu; 0183 if data.NumberExp == 1 0184 % if empty put eye(ny, ny) for every frequency in data.sqrtWinv 0185 data.sqrtWinv = repmat(eye(ny),[1,1,F]); 0186 else % more than 1 MIMO experiment 0187 % if empty put eye(ny, ny) for every experiment and frequency in data.sqrtWinv 0188 data.sqrtWinv = repmat(eye(ny),[1,1,nu,F]); 0189 end % if 1 MIMO experiment 0190 end 0191 0192 % jw, sqrt(jw), or exp(-jwTs) values for plant and noise model 0193 x = struct('Plant', []); 0194 % matrix of powers of x 0195 xMat = struct('Plant', []); 0196 0197 0198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0199 % domain of the plant model % 0200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0201 0202 % the vector s represents z^-1, s, or sqrt(s) of the plant model 0203 switch ModelVar.PlantPlane 0204 case {'s','w'} 0205 if ModelVar.PlantPlane == 's' 0206 x.Plant = sqrt(-1)*2*pi*data.freq; 0207 elseif ModelVar.PlantPlane == 'w' 0208 x.Plant = (sqrt(-1)*2*pi*data.freq).^(0.5); 0209 end; 0210 wscale = median(abs(x.Plant)); 0211 x.Plant = x.Plant/wscale; 0212 case 'z' 0213 x.Plant = exp(-sqrt(-1)*2*pi*data.freq*data.Ts); 0214 wscale = 1; 0215 case '' 0216 x.Plant = ones(size(data.freq)); 0217 wscale = 1; 0218 otherwise, disp('Invalid plant plane ...'), return 0219 end 0220 0221 nmax = max([ModelVar.na, ModelVar.nb, ModelVar.nig]); 0222 xMat.Plant = MIMO_ML_CalcOmegaMat(x.Plant, nmax); 0223 0224 0225 %%%%%%%%%%%%%%%%% 0226 % WTLS estimate % 0227 %%%%%%%%%%%%%%%%% 0228 0229 [Theta, smax, smin] = MIMO_WGTLS_Step(data, x, xMat, Sel, ModelVar); 0230 0231 0232 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0233 % denormalize the estimated parameters for s-, and sqrt(s)-domains % 0234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0235 0236 Theta = MIMO_ML_DeNormalise(Theta, wscale, ModelVar);