%% Detect Closely Spaced Sinusoids
% Consider a sinusoid, f(x)=e^{j2\pi\nu x}, windowed with a Gaussian window, g(t)=e^{-\pi t^2}. The short-time transform is
% V_gf(t,\eta)=e^{j2\pi\nu t}\int_{-\infty }^\infty
% e^{-\pi(x-t)^2}e^{-j2\pi(x-t)(\eta-\nu)}\,dx =
% e^{-\pi(\eta-\nu)^2}e^{j2\pi\nu t}.
% When viewed as a function of frequency, the transform combines a constant (in time) oscillation at \nu with Gaussian decay away from it. The synchrosqueezing estimate of the instantaneous frequency,
% \Omega_gf(t,\eta)={1\over{j2\pi}}
% {{e^{-\pi(\eta-\nu)^2}{\displaystyle{\partial}\over{\displaystyle\partial
% t}}e^{j2\pi\nu t}}\over{e^{-\pi(\eta-\nu)^2}e^{j2\pi\nu t}}}=\nu,
% equals the value obtained by using the standard definition, (2\pi)^{-1}d\arg f(x)/dx. For a superposition of sinusoids,
% f(x)=\sum_{k=1}^KA_ke^{j2\pi\nu_k x},
% the short-time transform becomes
% V_gf(t,\eta)=\sum_{k=1}^KA_ke^{-\pi(\eta-\nu_k)^2}e^{j2\pi\nu_k t}.
% Create 1024 samples of a signal consisting of two sinusoids. One sinusoid has a normalized frequency of \omega_0=\pi/5 rad/sample. The other sinusoid has three times the frequency and three times the amplitude.

N = 1024;
n = 0:N-1;

w0 = pi/5;
x = exp(1j*w0*n)+3*exp(1j*3*w0*n);

%
% Compute the short-time Fourier transform of the signal. Use a 256-sample Gaussian window with \alpha=20, 255 samples of overlap between adjoining sections, and 1024 DFT points. Plot the absolute value of the transform.

Nw = 256;
nfft = 1024;
alpha = 20;

[s,w,t] = spectrogram(x,gausswin(Nw,alpha),Nw-1,nfft,'centered');

surf(t,w/pi,abs(s),'EdgeColor','none')
view(2)
axis tight
xlabel('Samples')
ylabel('Normalized Frequency (\times\pi rad/sample)')

%
% The Fourier synchrosqueezed transform results in a sharper, better localized estimate of the spectrum.

[ss,sw,st] = fsst(x,[],gausswin(Nw,alpha));

fsst(x,'yaxis')

%
% The sinusoids are visible as constant oscillations at the expected frequency values. To see that the decay away from the ridges is Gaussian, plot an instantaneous value of the transform and overlay two instances of a Gaussian. Express the Gaussian amplitude and standard deviation in terms of \alpha and the window length. Recall that the standard deviation of the frequency-domain window is the reciprocal of the standard deviation of the time-domain window.

rstdev = (Nw-1)/(2*alpha);
amp = rstdev*sqrt(2*pi);

instransf = abs(s(:,128));

plot(w/pi,instransf)
hold on
plot(w/pi,[1 3]*amp.*exp(-rstdev^2/2*(w-[1 3]*w0).^2),'--')
hold off
xlabel('Normalized Frequency (\times\pi rad/sample)')
lg = legend('Transform','First sinusoid','Second sinusoid');
lg.Location = 'best';

%
% The Fourier synchrosqueezed transform concentrates the energy content of the signal at the estimated instantaneous frequencies.

stem(sw/pi,abs(ss(:,128)))
xlabel('Normalized Frequency (\times\pi rad/sample)')
title('Synchrosqueezed Transform')

%
% The synchrosqueezed estimates of instantaneous frequency are valid only if the sinusoids are separated by more than 2\Delta, where
% \Delta={\displaystyle1\over\displaystyle\sigma}\sqrt{2\log2}
% for a Gaussian window and \sigma is the standard deviation.
% Repeat the previous calculation, but now specify that the second sinusoid has a normalized frequency of \omega_0+1.9\Delta rad/sample.

D = sqrt(2*log(2))/rstdev;

w1 = w0+1.9*D;

x = exp(1j*w0*n)+3*exp(1j*w1*n);

[s,w,t] = spectrogram(x,gausswin(Nw,alpha),Nw-1,nfft,'centered');
instransf = abs(s(:,20));

plot(w/pi,instransf)
hold on
plot(w/pi,[1 3]*amp.*exp(-rstdev^2/2*(w-[w0 w1]).^2),'--')
hold off
xlabel('Normalized Frequency (\times\pi rad/sample)')
lg = legend('Transform','First sinusoid','Second sinusoid');
lg.Location = 'best';

%
% The Fourier synchrosqueezed transform cannot resolve the sinusoids well because \left|\omega_1-\omega_0\right|<2\Delta. The spectral estimates decrease significantly in value.

[ss,sw,st] = fsst(x,[],gausswin(Nw,alpha));

stem(sw/pi,abs(ss(:,128)))
xlabel('Normalized Frequency (\times\pi rad/sample)')
title('Synchrosqueezed Transform')

% Copyright 2012 The MathWorks, Inc.