FFT on low sample count signal

I have sampled data of a slowly variating signal, about 1.85e-4 Hz . However since the variation is so slow I only have about 1.5 periods of data sampled at a rate about 28 times higher, so every 188 seconds I take a sample of the signal for a total of 9600 seconds. I want to do a fft analysis on this data to find the most important spectral component.
This gives a good approximation of the data I have:
Fs = 0.0053; % Sampling frequency
T = 1/Fs; % Sampling period
L = 9800; % Length of signal
t=0:T:L; % Time Vector
freq=1/5400;
X = (0.06*sin(2*pi*freq*t)+15.3)+(0.08*(rand(size(t))-0.5));
figure;
plot(t,X)
title('Signal')
xlabel('t (seconds)')
ylabel('X(t)')
I tried an FFT on this, but could nog get any good results. The highest spectral component is in the same order of magnitute as the original signal, but not exactly what I hoped for. I'm only interested in the frequency of the component.
Y = fft(X);
f=linspace(0, fs/2, N/2);
figure;
plot(f,abs(Y(1:N/2)))
title('Single-Sided Amplitude Spectrum of X(t)')
xlabel('f (Hz)')
xlim([0 0.001]);
ylim([0 5]);
is there any way to improve without increasing the number of effective signal samples??

 Accepted Answer

Star Strider
Star Strider on 8 Jan 2019
Without seeing your signal, it is not possible to suggest a specif approach. One option may be doiing a nonlinear regression on your signal, using the approach in Curve fitting to a sinusoidal function (link).

4 Comments

Thank you for your answer
to explain a bit where the data is comming from. We are doing aperture photometry on asteroids to extract the rotational period of the asteroid observed. So we take a picture every 2-3 minutes for at least 1 full cycle. These rotational periods are about 1 to 3 hours. So we must count on clear skies for at least 3 hours or more to get a proper set of data, but we are limited in time due to day / night,...
I've included the .mat file of the processed data
if I use cftool to fit a sine to the data, this is the result. Which is close, but I hope to improve with an fft.
curve fitted.jpg
Here is one approach:
The Code —
D = load('data.mat');
dates = D.dates;
p_mean = D.p_mean;
G = findgroups(dates); % Unique Time Values
p_meanu = splitapply(@mean, p_mean, G); % Take Mean Of Values For Each ‘date’ Element
N = numel(p_meanu); % Number Of Samples
datesv = linspace(min(dates), max(dates), N); % Create Uniformly-Sampled Vector For Resampling Interpolation
Ts = datenum(mean(diff(datesv))); % Sampling Interval (Days)
Fs = 1/Ts; % Sampling Frequency (Samples/Day)
Fn = Fs/2; % Nyquist Frequency (Samples/Day)
p_meanur = resample(p_meanu, datesv); % Resample To Uniformly-Sampled Time Vector
NFFT = 2*nextpow2(N); % Length Of Fourier Transform
p_meanurm = p_meanur - mean(p_meanur); % Subtreact Mean
FTp_meanur = fft(p_meanurm, 2^NFFT)/N; % Fourier Transform
Fv = linspace(0, 1, fix(numel(FTp_meanur)/2)+1)*Fn; % Frequency Vector
Iv = 1:numel(Fv); % Correspoinding Index Vector
[pks, loc] = findpeaks(abs(FTp_meanur(Iv)), 'MinPeakHeight',0.0075); % Fourier Transform Peak Am,plitudes & Locations
figure
plot(Fv, abs(FTp_meanur(Iv)))
hold on
plot(Fv(loc), pks, '^r', 'MarkerFaceColor','r')
grid
pklblc = compose('Amp = %6.4f\nPerd = %6.4f', [pks; 1./Fv(loc)]');
text(Fv(loc), pks, pklblc, 'HorizontalAlignment','left', 'VerticalAlignment','bottom')
ylim([0 0.04])
The Plot —
FFT on low sample count signal - 2019 01 11.png
The approach is straightforward. The Fourier Transfomr prefers uniformly-sampled signals, so I created a uniform vector of dates, and then used the resample function to resample it. (This is preferable to simple interpolation, because the resample funciton uses an anti-aliasing filter to remove unwanted frequencies from the the resampled signal.) The rest is relatively straightforward fft code, with a longer Fourier transform to provide improved frequency resolution. The plot presents the amplitude and the calculated period for each peak.
I did my best to comment-document it, so it should be relatively easy for you to experiment with it.
Thanks,
This is indeed what I was looking for. I didn't think about resampling the data.
Jona
As always, my pleasure.
Resampling to uniform sampling intervals is necessary in order to get reliable results from the fft.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!