Mercurial > hg > ltpda
diff m-toolbox/classes/+utils/@math/SFtest.m @ 0:f0afece42f48
Import.
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Wed, 23 Nov 2011 19:22:13 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m-toolbox/classes/+utils/@math/SFtest.m Wed Nov 23 19:22:13 2011 +0100 @@ -0,0 +1,185 @@ +% SFtest perfomes a Spectral F-Test on PSDs. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% DESCRIPTION: SFtest performes a Spectral F-Test on two input PSD objects. +% The null hypothesis H0 (the two PSDs belong to the same +% statistical distribution) is rejected at the confidence +% level for the alternative hypotheis H1 (the two PSDs belong +% to different statistical distributions) if the test +% statistic falls in the critical region. +% SFtest uses utils.math.Ftest which does the test at each +% frequency bin. +% +% VERSION: $Id: SFtest.m,v 1.3 2011/03/07 17:38:05 congedo Exp $ +% +% HISTORY: 18-02-2011 G. Congedo +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function test = SFtest(X,Y,alpha,showPlots) + + % Assume a two-tailed test + twoTailed = 1; + + % Extract the degree of freedom + dofX = X.getdof.y; + dofY = Y.getdof.y; + + % Ratio of the two spectra: this test statistic is F-distributed + F = X/Y; + F.setYunits(''); + F.setName('F statistic'); + + n = numel(F.y); + + % Interquartile range + Fy = sort(F.y); + m = median(Fy); + q1 = median(Fy(Fy<=m)); + q3 = median(Fy(Fy>=m)); + iqr = q3 - q1; + + % Freedman–Diaconis rule + binSz = 2*iqr*n^(-1/3); + nBin = round((max(Fy)-min(Fy))/binSz); + + % Sample PDF + samplePDF = hist(F,plist('N',nBin,'norm',1)); + samplePDF.setName('sample PDF'); + + % Sample PDF moments +% sampleK = utils.math.Kurt(samplePDF.x); +% sampleS = utils.math.Skew(samplePDF.x); + + % Theor PDF + theorPDF = copy(samplePDF,1); + theorPDF.setY(Fpdf(samplePDF.x,dofX,dofY)); + theorPDF.setName('theor. PDF'); + + % Theor PDF moments +% theorK = utils.math.Kurt(samplePDF.x); +% theorS = utils.math.Skew(samplePDF.x); + + % Plot PDFs + if showPlots + iplot(samplePDF,theorPDF); + set(get(gca,'YLabel'),'String','PDF') + set(get(gca,'XLabel'),'String','F statistic') + end + + % Perform test on the hypothesis that both distributions should be + % chi2-distributed or, equivalently, that the ratio of the two spectra + % should be F-distributed. The comparison is actually done in chi2 sense. + sampleHIST = hist(F,plist('N',nBin)); + ix = sampleHIST.y>=5; + C = sum(sampleHIST.y)*mean(diff(sampleHIST.x)); + NN = sampleHIST.y(ix); + nn = C*theorPDF.y(ix); + r = (NN-nn).^2./nn; + chi2 = sum(r); + dof = numel(NN) - 1; + Y2 = dof + sqrt(2*dof/(2*dof+sum(1./nn)))*(chi2-dof); + critValue(1) = utils.math.Chi2inv(alpha/2,dof); + critValue(2) = utils.math.Chi2inv(1-alpha/2,dof); + + % Perform the test on PDFs + Chi2test = Y2<critValue(1) | Y2>critValue(2); + +% % Sample CDF +% samplePDF = hist(F,plist('N',1000)); +% sampleCDF = copy(samplePDF,1); +% sampleCDF.setY(cumsum(samplePDF.y)/sum(samplePDF.y)); +% sampleCDF.setName('sample CDF'); +% +% % Theor CDF +% theorCDF = copy(samplePDF,1); +% theorCDF.setY(Fcdf(samplePDF.x,dofX,dofY)); +% theorCDF.setName('theoretical CDF'); +% +% % Plot CDFs +% iplot(sampleCDF,theorCDF); +% set(get(gca,'YLabel'),'String','CDF') +% set(get(gca,'XLabel'),'String','F statistic') + + % Critical values + [test,critValue,pValue] = utils.math.Ftest(F.y,dofX,dofY,alpha,twoTailed); + + % Build AOs for critical values +% if twoTailed + critValueLB = ao(plist('xvals',X.x,'yvals',repmat(critValue(1),size(X.x)),... + 'type','fsdata','fs',X.fs,'xunits',X.xunits,'name','critical values')); + critValueUB = ao(plist('xvals',X.x,'yvals',repmat(critValue(2),size(X.x)),... + 'type','fsdata','fs',X.fs,'xunits',X.xunits,'name','critical values')); +% else +% critValue = ao(plist('xvals',X.x,'yvals',repmat(critValue,size(X.x)),... +% 'type','fsdata','fs',X.fs,'xunits',X.xunits,'name','critical values')); +% end + +% % Build AOs for p-values and confidence levels +% pValue = ao(plist('xvals',X.x,'yvals',pValue,... +% 'type','fsdata','fs',X.fs,'xunits',X.xunits,'name','p-values')); +% % pValue.setDy(pValueDy); +% +% if twoTailed +% confLevelUB = ao(plist('xvals',X.x,'yvals',repmat(1-alpha/2/numel(F.y),size(X.x)),... +% 'type','fsdata','fs',X.fs,'xunits',X.xunits,'name','confidence level')); +% confLevelLB = ao(plist('xvals',X.x,'yvals',repmat(alpha/2/numel(F.y),size(X.x)),... +% 'type','fsdata','fs',X.fs,'xunits',X.xunits,'name','confidence level')); +% else +% confLevel = ao(plist('xvals',X.x,'yvals',repmat(1-alpha/n,size(X.x)),... +% 'type','fsdata','fs',X.fs,'xunits',X.xunits,'name','confidence level')); +% end + + % Rejection index + ix = find(test); + if ~isempty(ix) + H1 = F.setXY(plist('x',F.x(ix),'y',F.y(ix))); + H1.setDy([]); + H1.setName('H0 rejected'); + end + + % Compute the number of sigmal corresponding to the confidence level +% Ns = erfinv(1-alpha)*sqrt(2); + + % Make the test: H0 rejected? +% if twoTailed +% % test = any( (F.y-Ns.*F.dy)>critValueUB.y | (F.y+Ns.*F.dy)<critValueLB.y ); +% test = any( F.y>critValueUB.y | F.y<critValueLB.y ); +% else +% % test = any( (F.y-Ns.*F.dy)>critValue.y ); +% test = any( F.y>critValue.y ); +% end + + % Perform the F-test on spectra + Ftest = any(test); + + % Plot results + pl = plist('yscales',{'All', 'log'},'autoerrors',0); +% if twoTailed + if showPlots + if Ftest + [hfig, hax, hli] = iplot(F,critValueLB,critValueUB,H1,pl); + set(hli(4),'linestyle','none','marker','s','MarkerSize',10,'MarkerEdgeColor','r'); + else + [hfig, hax, hli] = iplot(F,critValueLB,critValueUB,pl); + end + set(hli(2:3),'color','r'); +% h2 = iplot(pValue,confLevelLB,confLevelUB,pl); +% else +% if Ftest +% [hfig, hax, hli] = iplot(F,critValue,H1,pl); +% set(hli(3),'linestyle','none','marker','s','MarkerSize',10,'MarkerEdgeColor','r'); +% else +% [hfig, hax, hli] = iplot(F,critValue,pl); +% end +% set(hli(2),'color','r'); +% % h2 = iplot(pValue,confLevel,pl); +% end + set(get(gca,'YLabel'),'String','F statistic') + end + + % Output final result + test = any(Chi2test | Ftest); + +end +