TheJacob = MIMO_LS_Jacob(data, xMat, ModelVar) Calculates the jacobian matrix w.r.t. ALL the plant and transient model parameters. The selection of the free model parameters, and the imposition of the model constraints (reciprocity) is done in the routine MIMO_ML_AddSelectColumns Output parameters TheJacob = jacobian matrix, size: ny x ntheta x F Input parameters data = structure containing the non-parametric data data.Y = DFT spectrum ny x 1 output signal, size: ny x F data.U = DFT spectrum nu x 1 input signal, size: nu x F data.freq = vector of frequency values (Hz), size: F x 1 data.Ts = sampling time (s) data.sqrtWinv = square root of the inverse of the weighting matrix W, size: ny x ny x F data.DC = 1 if DC present otherwise 0 data.Nyquist = 1 if Nyquist frequency present otherwise 0 xMat = structure with tables of powers of (jwk)^r or (zk^-r) xMat.Plant = plant model, size: F x max order ModelVar = contains the information about the model to be identified structure with fields 'Transient', 'ThePlane', 'TheModel', 'Reciprocal', ... ModelVar.Transient = 1 then the initial conditions of the plant and/or noise are estimated ModelVar.PlantPlane = plane of the plant model 's': continuous-time; 'w': sqrt(s)-domain 'z': discrete-time; '': plane not defined ModelVar.Struct = model structure 'EIV': errors-in-variables (noisy input-output data) 'OE': generalised output error (known input, noisy output) ModelVar.RecipPlant = 1 if plant model is reciprocal: G(i,j) = G(j,i) ModelVar.nu = number of inputs ModelVar.ny = number of outputs ModelVar.na = order polynomial A ModelVar.nb = order matrix polynomial B ModelVar.nig = order vector polynomial Ig Copyright (c) Rik Pintelon, Vrije Universiteit Brussel - dept. ELEC, 27 November 2009 All rights reserved. Software can be used freely for non-commercial applications only. Version 6 October 2011
0001 function TheJacob = MIMO_LS_Jacob(data, xMat, ModelVar); 0002 % 0003 % TheJacob = MIMO_LS_Jacob(data, xMat, ModelVar) 0004 % 0005 % Calculates the jacobian matrix w.r.t. ALL the plant and transient model parameters. 0006 % The selection of the free model parameters, and the imposition of the model constraints 0007 % (reciprocity) is done in the routine MIMO_ML_AddSelectColumns 0008 % 0009 % 0010 % Output parameters 0011 % 0012 % TheJacob = jacobian matrix, size: ny x ntheta x F 0013 % 0014 % 0015 % Input parameters 0016 % 0017 % data = structure containing the non-parametric data 0018 % data.Y = DFT spectrum ny x 1 output signal, size: ny x F 0019 % data.U = DFT spectrum nu x 1 input signal, size: nu x F 0020 % data.freq = vector of frequency values (Hz), size: F x 1 0021 % data.Ts = sampling time (s) 0022 % data.sqrtWinv = square root of the inverse of the weighting matrix W, size: ny x ny x F 0023 % data.DC = 1 if DC present otherwise 0 0024 % data.Nyquist = 1 if Nyquist frequency present otherwise 0 0025 % 0026 % xMat = structure with tables of powers of (jwk)^r or (zk^-r) 0027 % xMat.Plant = plant model, size: F x max order 0028 % 0029 % ModelVar = contains the information about the model to be identified 0030 % structure with fields 'Transient', 'ThePlane', 'TheModel', 'Reciprocal', ... 0031 % ModelVar.Transient = 1 then the initial conditions of the plant and/or noise are estimated 0032 % ModelVar.PlantPlane = plane of the plant 0033 % model 0034 % 's': continuous-time; 0035 % 'w': sqrt(s)-domain 0036 % 'z': discrete-time; 0037 % '': plane not defined 0038 % ModelVar.Struct = model structure 0039 % 'EIV': errors-in-variables (noisy input-output data) 0040 % 'OE': generalised output error (known input, noisy output) 0041 % ModelVar.RecipPlant = 1 if plant model is reciprocal: G(i,j) = G(j,i) 0042 % ModelVar.nu = number of inputs 0043 % ModelVar.ny = number of outputs 0044 % ModelVar.na = order polynomial A 0045 % ModelVar.nb = order matrix polynomial B 0046 % ModelVar.nig = order vector polynomial Ig 0047 % 0048 % 0049 % Copyright (c) Rik Pintelon, Vrije Universiteit Brussel - dept. ELEC, 27 November 2009 0050 % All rights reserved. 0051 % Software can be used freely for non-commercial applications only. 0052 % Version 6 October 2011 0053 % 0054 0055 % note that DC and Nyquist have a contribution 1/2 to the cost function 0056 % therefore the appropriate variables must be scaled by 1/sqrt(2) at DC 0057 % and Nyquist; this is already done for the variable Error 0058 0059 0060 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0061 % derivative prediction error w.r.t. ALL model parameters % 0062 % a = Theta.A(:) % 0063 % b = reshape(permute(Theta.B, [3,1,2]), [ny*nu*(nb+1),1]) % 0064 % ig = reshape(permute(Theta.Ig, [2,1]), [ny*(nig+1),1]) % 0065 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0066 0067 % number of frequencies 0068 F = size(xMat.Plant,1); 0069 0070 % order polynomials 0071 na = ModelVar.na; 0072 nb = ModelVar.nb; 0073 nig = ModelVar.nig; 0074 0075 % number of outputs and inputs 0076 ny = ModelVar.ny; 0077 nu = ModelVar.nu; 0078 0079 % total number of model parameters 0080 ntheta = (na+1) + (nb+1)*nu*ny + (nig+1)*ny; 0081 0082 TheJacob = zeros(ny, ntheta, F); 0083 0084 Deriv.Aa = xMat.Plant(:, 1:na+1).'; % derivative A w.r.t. a 0085 0086 Hinv = data.sqrtWinv; 0087 % Hinv = repmat(eye(ny),[1,1,F]); 0088 switch ModelVar.PlantPlane 0089 case 'z' 0090 % best approximation true denominator = constant 0091 Scale = 1; 0092 case {'s', 'w'} 0093 % mimics the true denominator in s- and sqrt(s)-domains 0094 Scale = sum(abs(xMat.Plant(:,1:na+1)),2); 0095 end 0096 TheScale = zeros(1,1,F); 0097 TheScale(1,1,:) = Scale; 0098 Hinv = Hinv./repmat(TheScale,ny,ny); 0099 0100 0101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0102 % Fast calculation of the derivative of vec(B) w.r.t. b. The lines below are equivalent with % 0103 % for kk = 1:F % 0104 % Deriv.vecBb(:,:,kk) = kron(eye(nu*ny, nu*ny), xMat.Plant(kk, 1:nb+1)); % 0105 % end % 0106 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0107 0108 Deriv.vecBb = zeros(ny*nu, ny*nu*(nb+1), F); 0109 for ii = 1:nu*ny 0110 0111 vii = zeros(nu*ny, 1); 0112 vii(ii) = 1; 0113 Deriv.vecBb(ii,:,:) = kron(vii, (xMat.Plant(:, 1:nb+1)).'); 0114 0115 end % ii 0116 0117 0118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0119 % Fast calculation of the derivative of Ig w.r.t. ig. The lines below are equivalent with % 0120 % for kk = 1:F % 0121 % Deriv.Igig(:,:,kk) = kron(eye(ny, ny), xMat.Plant(kk, 1:nig+1)); % 0122 % end % 0123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0124 0125 Deriv.Igig = zeros(ny, ny*(nig+1), F); 0126 for ii = 1:ny 0127 0128 vii = zeros(ny, 1); 0129 vii(ii) = 1; 0130 Deriv.Igig(ii,:,:) = kron(vii, (xMat.Plant(:, 1:nig+1)).'); 0131 0132 end % ii 0133 0134 0135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0136 % Fast calculation of the derivative w.r.t. a. The lines below are equivalent with % 0137 % for kk = 1:F % 0138 % Low = 1; % 0139 % Upp = (na+1); % 0140 % TheJacob(:,Low:Upp,kk) = (Hinv(:,:,kk) * data.Y(:,kk)) * (Deriv.Aa(:,kk).'); % 0141 % end % 0142 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0143 0144 % calculation of the derivative of the residual w.r.t. a for all frequencies 0145 DerivResa = zeros(ny,na+1,F); 0146 for ii = 1:ny 0147 dataY = data.Y(ii, :).'; 0148 DerivResa(ii,:,:) = (Deriv.Aa(1:na+1,:).' .* repmat(dataY, [1, na+1])).'; 0149 end % ii 0150 0151 % derivative w.r.t. a 0152 Low = 1; 0153 Upp = (na+1); 0154 for ii = 1:ny 0155 0156 Hinvii = squeeze(Hinv(ii,:,:)); 0157 if ny == 1 0158 Hinvii = Hinvii.'; % squeeze on 1 x 1 x F gives F x 1 !!! 0159 end % if 0160 0161 for jj = Low:Upp 0162 0163 jk = jj-Low+1; 0164 DerivResajj = squeeze(DerivResa(:,jk,:)); 0165 if ny == 1 0166 DerivResajj = DerivResajj.'; % squeeze on 1 x 1 x F gives F x 1 !!! 0167 end % if 0168 TheJacob(ii,jj,:) = sum(Hinvii.*DerivResajj, 1); 0169 0170 end %jj 0171 end % ii 0172 0173 0174 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0175 % Fast calculation of the derivative w.r.t. b. The lines below are equivalent with % 0176 % for kk = 1:F % 0177 % Low = Upp+1; % 0178 % Upp = Low + (nb+1)*ny*nu - 1; % 0179 % Mat = kron(data.U(:,kk).', squeeze(Hinv(:,:,kk))); % 0180 % TheJacob(:,Low:Upp,kk) = - Mat * Deriv.vecBb(:,:,kk); % 0181 % end % 0182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0183 0184 % calculation of the matrix Mat for all frequencies 0185 Uii = zeros(1,1,F); 0186 Mat = zeros(ny, nu*ny, F); 0187 for ii = 1:nu 0188 Uii(1,1,:) = data.U(ii,:); 0189 columns = [(ii-1)*ny+1:ii*ny]; 0190 Mat(:, columns, :) = Hinv .* repmat(Uii, [ny, ny, 1]); 0191 end % ii 0192 0193 % derivative w.r.t. b 0194 Low = Upp+1; 0195 Upp = Low + (nb+1)*ny*nu - 1; 0196 for ii = 1:ny 0197 0198 Matii = squeeze(Mat(ii,:,:)); 0199 if ny*nu == 1 0200 Matii = Matii.'; % squeeze on 1 x 1 x F gives F x 1 !!! 0201 end % if 0202 Hinvii = squeeze(Hinv(ii,:,:)); 0203 if ny == 1 0204 Hinvii = Hinvii.'; % squeeze on 1 x 1 x F gives F x 1 !!! 0205 end % if 0206 0207 for jj = Low:Upp 0208 0209 jk = jj-Low+1; 0210 DerivvecBbjj = squeeze(Deriv.vecBb(:,jk,:)); 0211 if nu*ny == 1 0212 DerivvecBbjj = DerivvecBbjj.'; % squeeze on 1 x 1 x F gives F x 1 !!! 0213 end % if 0214 TheJacob(ii,jj,:) = - sum(Matii.*DerivvecBbjj, 1); 0215 0216 end %jj 0217 end % ii 0218 0219 0220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0221 % Fast calculation of the derivative w.r.t. ig. The lines below are equivalent with % 0222 % for kk = 1:F % 0223 % Low = Upp+1; % 0224 % Upp = Low + (nig+1)*ny - 1; % 0225 % TheJacob(:,Low:Upp,kk) = - Hinv(:,:,kk) * Deriv.Igig(:,:,kk); % 0226 % end % 0227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0228 0229 % derivative w.r.t. ig 0230 Low = Upp+1; 0231 Upp = Low + (nig+1)*ny - 1; 0232 for ii = 1:ny 0233 0234 Hinvii = squeeze(Hinv(ii,:,:)); 0235 if ny == 1 0236 Hinvii = Hinvii.'; % squeeze on 1 x 1 x F gives F x 1 !!! 0237 end % if 0238 0239 for jj = Low:Upp 0240 0241 jk = jj-Low+1; 0242 DerivIgigjj = squeeze(Deriv.Igig(:,jk,:)); 0243 if ny == 1 0244 DerivIgigjj = DerivIgigjj.'; % squeeze on 1 x 1 x F gives F x 1 !!! 0245 end % if 0246 TheJacob(ii,jj,:) = - sum(Hinvii.*DerivIgigjj, 1); 0247 0248 end %jj 0249 end % ii 0250 0251 % DC and Nyquist count for 1/sqrt(2) 0252 if data.DC == 1 0253 TheJacob(:,:,1) = TheJacob(:,:,1)/sqrt(2); 0254 end 0255 if data.Nyquist == 1 0256 TheJacob(:,:,end) = TheJacob(:,:,end)/sqrt(2); 0257 end