Whiteness test on the difference between the measured G (nonparametric estimate) and modeled Gest (parametric estimate) frequency response matrix, taking into account the possible correlation over the frequency (CL) and the variability (dof) of the noise covariance estimate varG. function [Auto_Corr, Lags, Conf_Bound] = WhitenessTestResiduals(G, varG, Gest, CL, dof, PlotFig); References: Pintelon, R., G. Vandersteen, J. Schoukens, and Y. Rolain (2011). Improved (non-)parametric identification of dynamic systems excited by periodic signals - The multivariate case, Mechanical Systems and Signal Processing, vol. 25, no. 8, pp. 2892-2922. Pintelon, R., and J. Schoukens (2012). System Identification: A Frequency Domain Approach, second edition, IEEE Press-Wiley, Piscataway (USA). Output Auto_Corr = autocorrelation of each entry of the residuals (G-Gest)/std(G) size ny x nu x 2*floor(F/(CL+1))+1 Lags = lags (in multiples of CL+1) over which the auto-correlation is calculated Conf_Bound = 50% (Conf_Bound(1,:)) and 95% (Conf_Bound(2,:)) confidence bound auto-correlation size 2 x 2*floor(F/(CL+1))+1 Fractions = fraction in % outside the 50% and 95% confidence bounds size ny x nu x 2 Input G = measured frequency response matrix (FRM) size ny x nu x F varG = either: variance of each entry of the measured FRM G size ny x nu x F or: covariance of vec(G) size ny*nu x ny*nu x F Gest = estimated plant transfer function model size ny x nu x F CL = � CL is the correlation length over the frequency of the measured FRM G (optional, default = 0 = no correlation) dof = degrees of freedom of the variance estimate varG, optional parameter (optional, default = inf) PlotFig = plot auto-correlation if 1, else no figures (optional, default = 1) Copyright (c) Rik Pintelon, Vrije Universiteit Brussel - dept. ELEC, 19 November 2009 All rights reserved. Software can be used freely for non-commercial applications only. Version 10 October 2011
0001 function [Auto_Corr, Lags, Conf_Bound, Fraction] = WhitenessTestResiduals(G, varG, Gest, CL, dof, PlotFig); 0002 % 0003 % Whiteness test on the difference between the measured G (nonparametric estimate) and modeled Gest 0004 % (parametric estimate) frequency response matrix, taking into account the possible correlation over the 0005 % frequency (CL) and the variability (dof) of the noise covariance estimate varG. 0006 % 0007 % function [Auto_Corr, Lags, Conf_Bound] = WhitenessTestResiduals(G, varG, Gest, CL, dof, PlotFig); 0008 % 0009 % References: 0010 % 0011 % Pintelon, R., G. Vandersteen, J. Schoukens, and Y. Rolain (2011). Improved (non-)parametric identification of dynamic 0012 % systems excited by periodic signals - The multivariate case, Mechanical Systems and Signal Processing, vol. 25, no. 8, 0013 % pp. 2892-2922. 0014 % 0015 % Pintelon, R., and J. Schoukens (2012). System Identification: A Frequency Domain Approach, second edition, 0016 % IEEE Press-Wiley, Piscataway (USA). 0017 % 0018 % 0019 % Output 0020 % 0021 % Auto_Corr = autocorrelation of each entry of the residuals (G-Gest)/std(G) 0022 % size ny x nu x 2*floor(F/(CL+1))+1 0023 % 0024 % Lags = lags (in multiples of CL+1) over which the auto-correlation is calculated 0025 % 0026 % Conf_Bound = 50% (Conf_Bound(1,:)) and 95% (Conf_Bound(2,:)) confidence bound auto-correlation 0027 % size 2 x 2*floor(F/(CL+1))+1 0028 % 0029 % Fractions = fraction in % outside the 50% and 95% confidence bounds 0030 % size ny x nu x 2 0031 % 0032 % 0033 % Input 0034 % 0035 % G = measured frequency response matrix (FRM) 0036 % size ny x nu x F 0037 % 0038 % varG = either: variance of each entry of the measured FRM G 0039 % size ny x nu x F 0040 % or: covariance of vec(G) 0041 % size ny*nu x ny*nu x F 0042 % 0043 % Gest = estimated plant transfer function model 0044 % size ny x nu x F 0045 % 0046 % CL = � CL is the correlation length over the frequency of the measured FRM G 0047 % (optional, default = 0 = no correlation) 0048 % 0049 % dof = degrees of freedom of the variance estimate varG, optional parameter 0050 % (optional, default = inf) 0051 % 0052 % PlotFig = plot auto-correlation if 1, else no figures 0053 % (optional, default = 1) 0054 % 0055 % 0056 % Copyright (c) Rik Pintelon, Vrije Universiteit Brussel - dept. ELEC, 19 November 2009 0057 % All rights reserved. 0058 % Software can be used freely for non-commercial applications only. 0059 % Version 10 October 2011 0060 % 0061 0062 0063 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0064 % initialisation of the variables % 0065 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0066 0067 try 0068 if isempty(CL) 0069 CL = 0; 0070 end % if 0071 catch 0072 CL = 0; 0073 end % try 0074 0075 [ny, nu, F] = size(G); 0076 Res = zeros(ny, nu, F); 0077 % F1 = number of independent FRM measurements 0078 % if no correlation (CL = 0), then F1 = F 0079 F1 = floor((F-1)/(CL+1))+1; 0080 Auto_Corr = zeros(ny, nu, 2*F1-1); 0081 Fraction = zeros(ny, nu, 2); 0082 Lags = [-F1+1:1:F1-1]; 0083 0084 try 0085 if isempty(dof) 0086 dof = inf; 0087 end % if 0088 catch 0089 dof = inf; 0090 end % try 0091 0092 try 0093 if isempty(PlotFig) 0094 PlotFig = 1; 0095 end % if 0096 catch 0097 PlotFig = 1; 0098 end % try 0099 0100 % check whether variance of each entry FRM or covariance vec(G) is provided 0101 rows = size(varG, 1); 0102 columns = size(varG, 2); 0103 0104 if (rows-ny+columns-nu) > 0 0105 % keep the diagonal of CvecG only 0106 dummy = varG; 0107 varG = zeros(ny,nu,F); 0108 for kk = 1:F 0109 varG(:,:,kk) = reshape(diag(dummy(:,:,kk)), [ny, nu]); 0110 end % kk 0111 clear dummy 0112 end % if cov(vec(G)) is provided 0113 0114 0115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0116 % calculation of the auto-correlation % 0117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0118 0119 % normalised residuals 0120 for kk = 1:F 0121 Res(:,:,kk) = (G(:,:,kk) - Gest(:,:,kk))./varG(:,:,kk).^0.5; 0122 end % kk, frequencies 0123 0124 % auto-correlation 0125 for ii = 1:nu 0126 for jj = 1:ny 0127 Auto_Corr(jj,ii,:) = xcorr(squeeze(Res(jj,ii,1:CL+1:end)),'unbiased'); 0128 end % jj, outputs 0129 end % ii, inputs 0130 0131 % scaling auto-correlation to account for the degrees of freedom of the 0132 % variance estimate varG 0133 switch isinf(dof) 0134 case 0 0135 scale0 = (dof-1)/dof; 0136 scale = (dof-2/3)/(dof+1/12); 0137 % factor 3 for noise models from LocalPoly and FastLocalPoly 0138 % for RobustLocalPoly => 3 is an upperbound 0139 Conf_scale0 = scale0*sqrt(3*dof^3/(dof-1)^2/(dof-2)); 0140 Conf_scale = scale*dof/(dof-1); 0141 case 1 0142 scale0 = 1; 0143 scale = 1; 0144 Conf_scale0 = 1; 0145 Conf_scale = 1; 0146 end % switch 0147 TheScale = scale*ones(size(Lags)); 0148 TheScale(F1) = scale0; 0149 Auto_Corr = Auto_Corr .* repmat(reshape(TheScale, [1,1,2*F1-1]), [ny, nu, 1]); 0150 0151 % std auto-correlation 0152 p50 = sqrt(-log(1-0.5)); 0153 p95 = sqrt(-log(1-0.95)); 0154 ConfScale = Conf_scale*ones(size(Lags)); 0155 ConfScale(F1) = Conf_scale0; 0156 Conf_Bound = repmat(ConfScale./(F1-abs(Lags)).^0.5, [2,1]); 0157 Conf_Bound(1,:) = p50*Conf_Bound(1,:); 0158 Conf_Bound(2,:) = p95*Conf_Bound(2,:); 0159 0160 % fractions outside p% confidence bounds 0161 Select = [1:1:2*F1-1]; 0162 Select(F1) = []; 0163 for ii = 1:nu 0164 for jj = 1:ny 0165 Fraction(jj,ii,1) = length(find(squeeze(abs(Auto_Corr(jj,ii,Select))) - Conf_Bound(1,Select).' > 0))/(2*F1-2)*100; 0166 Fraction(jj,ii,2) = length(find(squeeze(abs(Auto_Corr(jj,ii,Select))) - Conf_Bound(2,Select).' > 0))/(2*F1-2)*100; 0167 end % jj, outputs 0168 end % ii, inputs 0169 0170 0171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0172 % plot the auto-correlation % 0173 %%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0174 0175 if PlotFig == 1 0176 figure 0177 mm = 0; 0178 for jj = 1:ny 0179 for ii = 1:nu 0180 mm = mm+1; 0181 subplot(ny,nu,mm); 0182 plot(Lags, squeeze(abs(Auto_Corr(jj,ii,:))), '*', Lags, Conf_Bound(1,:), 'k', ... 0183 Lags, Conf_Bound(2,:), 'k--') 0184 xlabel('{\itk}') 0185 Rlabel = ['[',num2str(jj),',',num2str(ii),']']; 0186 ylabel(['{\itR}_{',Rlabel,'}({\itk})']) 0187 end % jj, outputs 0188 end % ii, inputs 0189 zoom on 0190 shg 0191 end % if auto-correlation should be plotted 0192