| cmtm(x,y,dt,NW,qbias,confn,qplot);
|
%function [s, c, ph, ci, phi] = cmtm(x,y,dt,NW,qbias,confn,qplot);
%
%Multi-taper method coherence using adaptive weighting and correcting
%for the bias inherent to coherence estimates. The 95% coherence
%confidence level is computed by cohconf.m. In addition, a built-in
%Monte Carlo estimation procedure is available to estimate phase 95%
%confidence limits.
%
% Inputs:
% x - Input data vector 1.
% y - Input data vector 2.
% dt - Sampling interval (default 1)
% NW - Number of windows to use (default 8)
% qbias - Correct coherence estimate for bias (yes, 1) (no, 0, default).
% confn - Number of iterations to use in estimating phase uncertainty using a Monte Carlo
% method. (default 0)
% qplot - Plot the results, (yes, 1), (No, 0, default). The upper tickmarks indicate the
% bandwidth of the coherence and phase estimates.
%
% Outputs:
% s - frequency
% c - coherence
% ph - phase
% ci - 95% coherence confidence level
% phi - 95% phase confidence interval, bias corrected
% (add and subtract phi from ph).
%
%
%required files: cohconf.m, cohbias.m, cohbias.mat, Matlab signal processing toolbox.
%
%Peter Huybers
%MIT, 2003
%phuyber@mit.edu
function [s, c, ph, ci, phi] = cmtm(x,y,dt,NW,qbias,confn,qplot);
%check input
if nargin<2, help cmtm; return; end;
if nargin<7, qplot=0; end;
if nargin<6, confn=0; end;
if nargin<5, qbias=0; end;
if nargin<4, NW=8; end;
if length(NW)==0, NW=8;end;
if nargin<3, dt=1; end;
if length(dt)==0, dt=1;end;
if NW<1.5, disp('Warning: NW must be greater or equal to 1.5'); return; end;
if nargin>4,
disp('-------------------------');
disp(['Number of windows: ',num2str(NW)]);
if qbias==1, disp('Bias correction: On');
else, disp('Bias correction: Off'); end;
disp(['Confidence Itera.: ',num2str(confn)]);
if qplot==1, disp('Plotting: On');
else, disp('Plotting: Off'); end;
disp('-------------------------');
end;
x=x(:)-mean(x);
y=y(:)-mean(y);
if length(x)~=length(y), disp('Warning: the lengths of x and y must be equal.'); return; end;
%define some parameters
N = length(x);
k = min(round(2*NW),N);
k = max(k-1,1);
s = (0:1/(N*dt):1/dt-1/(N*dt))';
pls=2:(N+1)/2+1;
v = (2*NW-1); %approximate degrees of freedom
if rem(length(y),2)==1; pls=pls(1:end-1); end;
%Compute the discrete prolate spheroidal sequences, requires the spectral analysis toolbox.
[E,V]=dpss(N,NW,k);
%Compute the windowed DFTs.
fkx=fft(E(:,1:k).*x(:,ones(1,k)),N);
fky=fft(E(:,1:k).*y(:,ones(1,k)),N);
Pkx=abs(fkx).^2;
Pky=abs(fky).^2;
%Itteration to determine adaptive weights:
for i1=1:2,
if i1==1, vari=x'*x/N; Pk=Pkx; end;
if i1==2, vari=y'*y/N; Pk=Pky; end;
P = (Pk(:,1)+Pk(:,2))/2; % initial spectrum estimate
Ptemp= zeros(N,1);
P1 = zeros(N,1);
tol = .0005*vari/N; % usually within 'tol'erance in about three iterations, see equations from [2] (P&W pp 368-370).
a = vari*(1-V);
while sum(abs(P-P1)/N)>tol
b=(P*ones(1,k))./(P*V'+ones(N,1)*a'); % weights
wk=(b.^2).*(ones(N,1)*V'); % new spectral estimate
P1=(sum(wk'.*Pk')./ sum(wk'))';
Ptemp=P1; P1=P; P=Ptemp; % swap P and P1
end
if i1==1,
fkx=sqrt(k)*sqrt(wk).*fkx./repmat(sum(sqrt(wk'))',1,k);
Fx=P; %Power density spectral estimate of x
end;
if i1==2,
fky=sqrt(k)*sqrt(wk).*fky./repmat(sum(sqrt(wk'))',1,k);
Fy=P; %Power density spectral estimate of y
end;
end;
%As a check, the quantity sum(abs(fkx(pls,:))'.^2) is the same as Fx and
%the spectral estimate from pmtmPH.
%Compute coherence
Cxy= sum([fkx.*conj(fky)]');
ph = angle(Cxy)*180/pi;
c = abs(Cxy)./sqrt(sum(abs(fkx').^2).*sum(abs(fky').^2));
%correct for the bias of the estimate
if qbias==1,
c=cohbias(v,c)';
end;
%Phase uncertainty estimates via Monte Carlo analysis.
if confn>1,
cb=cohbias(v,c)';
for iter=1:confn;
if rem(iter,10)==0, disp(['phase confidence iteration: ',num2str(iter)]); end;
fx=fft(randn(size(x))+1);
fx=fx/sum(abs(fx));
fy=fft(randn(size(y))+1);
fy=fy/sum(abs(fy));
ys =real(ifft(fy.*sqrt(1-cb'.^2)));
ys =ys+real(ifft(fx.*cb'));
xs =real(ifft(fx));
[si, ciph(iter,:), phi(iter,:)]=cmtm(xs,ys,dt,NW);
end;
pl=round(.975*iter); %sorting and averaging to determine confidence levels.
phi=sort(phi);
phi=[phi(pl,:); -phi(iter-pl+1,:)];
phi=mean(phi);
phi=conv(phi(1:end),[1 1 1]/3);
phi=phi(2:end-1);
else,
phi=zeros(size(pls));
end;
%Cut to one-sided funtions
c = c(pls);
s = s(pls)';
ph=ph(pls);
phl=ph-phi;
phu=ph+phi;
%Coherence confidence level
ci=cohconf(v,.95); %not corrected for bias, this is conservative.
ci=ci*ones(size(c));
%plotting
if qplot==1,
%coherence
figure(gcf); clf;
subplot(211); hold on;
plot(s,c);
h=ylabel('coherence');
h=xlabel('frequency');
plot(s,ci,'k--');
pl=find(c>ci(1));
title(['mean is ',num2str(mean(c),2),' ',num2str(100*length(pl)/length(c),2),'% of estimates above 95% confidence level']);
axis tight; h=axis; axis([h(1:2) 0 1.025]);
w = NW/(dt*N); %half-bandwidth of the dpss
plot([s(1) h(2)],[1.02 1.02],'k');
for ds=min(s):2*w:max(s);
plot([ds ds],[.98 1.02],'k');
end;
%phase
subplot(212); hold on;
plot(s,ph);
if confn>0,
col=[.9 .9 .9];
h=fill([s(1) s(1:end) fliplr([s(1:end) s(end)])],[phu(1) phl fliplr([phu phl(end)])],col);
set(h,'edgecolor',col);
pl=find(phu<=180); phu(pl)=-180;
pl=find(phu> 180); phu(pl)=phu(pl)-360;
phlt=-180*ones(size(phl));
h=fill([s(1) s(1:end) fliplr([s(1:end) s(end)])],[phu(1) phlt fliplr([phu phlt(end)])],col);
set(h,'edgecolor',col);
pl=find(phl>=-180); phl(pl)=180;
pl=find(phl< -180); phl(pl)=phl(pl)+360;
phut=180*ones(size(phl));
h=fill([s(1) s(1:end) fliplr([s(1:end) s(end)])],[phut(1) phl fliplr([phut phl(end)])],col);
set(h,'edgecolor',col);
end;
h=plot(s,ph);
plot(s,zeros(size(s)),'k--');
axis tight; h=axis; axis([h(1:2) -180 180]);
h=xlabel('frequency');
h=ylabel('phase');
end;
|
|