Problems w/ power spectra?
Contents
Getting started
load SynthSig;
Aliasing
Here we need to generate another peak.
om_peak= 4.4*2*pi; ph = rand(1,1)*2*pi; sig.x_peak2 = 2*10.*cos(om_peak*sig.t+ph)/10; [p,f]=rawPowerSpec(sig.x_peak2+sig.x_peak+sig.x_w,dt); % Now, suppose that we can only sample at 0.25 Hz (i.e. 1/4 of the time) xx = sig.x_peak2+sig.x_peak+sig.x_w; x=xx(1:4:end); t = sig.t(1:4:end); [pn,fn]=rawPowerSpec(x,median(diff(t))); jmkfigure(100,2,0.6);clf subplot(2,1,1); plot(x(1:100)); hold on; plot(1:4:100,x(1:4:100),'b.','markersi',10); xlabel('t [s]'); ylabel('x [m]'); subplot(2,1,2); loglog(f,p,fn,pn) axis tight; yl = get(gca,'ylim'); xlabel('f [Hz]'); ylabel('\phi_x [m^2 s^{-1}]'); axis tight print -dpng -r250 doc/Aliasing

here we see the result of aliasing, where the peak has wrapped around to a harmonic in the resolved spectrum. To stop this we should smooth the new signal first:
[b,a]=butter(2,0.3); x = filtfilt(b,a,xx); subplot(2,1,1); plot(1:4:100,x(1:4:100),'r.','markersize',10) plot(x(1:100),'g') xlabel('t [s]'); ylabel('x [m]'); [pnp,fnp]=rawPowerSpec(x,median(diff(sig.t))); x = x(1:4:end); t = sig.t(1:4:end); [pnn,fnn]=rawPowerSpec(x,median(diff(t))); subplot(2,1,2); loglog(f,p,fn,pn,fnp,pnp,fnn,pnn) set(gca,'ylim',yl); xlabel('f [Hz]'); ylabel('\phi_x [m^2 s^{-1}]'); axis tight print -dpng -r250 doc/AliasingFixed

Finite record length
The last foible is finite record length. The difference between frequency bins is df = 1/T where T is the length of the record. Shorter records, the longer df.
To see the effect make a second peak very close to the first, but far enough apart that they can be distinguished in the full time-series.
om = th.f*2*pi; om_peak = find(om>0.4*2*pi); f0=om(om_peak(1))/2/pi; om_peak=om(om_peak(1)+3); % chose a peak 4 bins higher. ff = om_peak/2/pi; 1./abs(ff-f0) ph = rand(1,1)*2*pi; sig.x_peak2 = A_peak.*cos(om_peak*sig.t+ph)/10; x = sig.x_peak2+sig.x_peak+sig.x_w; jmkfigure(3,2,0.7);clf subplot(3,1,1); plot(x); hold on; plot(x(1:1500),'b'); plot(x(1:1000),'r'); ylabel('x [m]'); subplot(3,1,[2 3]); sty = {'k-','b-','r-'}; N = length(x); for i=1:3; [p,f]=rawPowerSpec(x(1:N-0.35*N*(i-1)),dt); loglog(f,p,sty{i}); hold on; h(i)=loglog(f,p,'o','markersi',6,'col',sty{i}(1)); set(gca,'xlim',[1.1*10^(-0.5) 1.7*10^(-0.5)]); df(i)=median(diff(f)); nn(i) = length(x(1:N-0.25*N*(i-1))); str{i}=sprintf('N=%d; \\Delta f=%1.2e [Hz]',nn(i),df(i)); end; xlabel('f [Hz]'); ylabel('\phi_x [m^2 Hz^{-1}]'); legend(h(1:3),str{1:3}) title(sprintf('Peaks separated by \\Delta f=%1.2e',abs(ff-f0))); print -dpng -r400 doc/FiniteRecord.jpg
ans = 66.6667

Here it is clear that fewer data points means poorer peak resolution. Once df rises above the peak separation they merge.
A trick to get better frequency resolution is to zero-pad the data. However, in this case, even if we do this, we do not improve resolution between the peaks, just the centering of the peaks.
jmkfigure(4,2,0.6);clf sty = {'k-','b-','r-'}; N = length(x); for i=1:3; subplot3(1,3,i,'xscale','log','yscale','log'); [p,f]=rawPowerSpec(x(1:N-0.35*N*(i-1)),dt); loglog(f,p,sty{i}); xx = x(1:N-0.35*N*(i-1)); xxx = zeros(1,floor(5*N)); xxx(1:length(xx)) =xx; [pp,ff]=rawPowerSpec(xxx,dt); h(i)=loglog(ff,pp,sty{i}); hold on; h(i)=loglog(f,p,sty{i}); hold on; % h(i)=loglog(f,p,'o','markersi',6,'col',sty{i}(1)); set(gca,'xlim',[1.1*10^(-0.5) 1.7*10^(-0.5)]); df(i)=median(diff(f)); nn(i) = length(x(1:N-0.25*N*(i-1))); str{i}=sprintf('N=%d',nn(i)); if i==1 ylabel('\phi_x [m^2 Hz^{-1}]'); end; end; %legend(h(1:3),str{1:3}) title('Zero-padded data'); xlabel('f [Hz]'); print -dpng -r400 doc/ZeroPad.jpg

Note in this example how the poorly-resolved peaks (blue) have better peak localization than if we don't zero pad. However, this doesn't help separate peaks that aren't resolved in the unpadded timeseries.
Spectral Leakage:
Compute a raw fft of a strong peak with white noise. Note that we have put the steps from the previous tutorial into a function.
dt = median(diff(sig.t)) [p,f]=rawPowerSpec(sig.x_peak*10,dt); [p_w,f]=rawPowerSpec(sig.x_w,dt); [p_p,f]=rawPowerSpec(sig.x_peak*10+sig.x_w,dt); figure(1);clf semilogy(f,p,f,p_w,f,p_p);
dt = 0.1000

Next
Next we consider ways to reduce smearing of peaks in the spectra and ways to improve the signal-to-noise of spectral extimates.