I'm trying to compute the highest frequency (as can be sampled) in some pretty manky looking discrete time-dependent signals. My current method - a discrete fourier analysis - fails for some pretty awful looking but clearly oscillating signals (with discernable highest frequencies).
My current method is to compute the discrete fourier transform, locate the local maxima, and perform weighted averages around these peaks (to undo the 'smearing' of the dft across the discrete sample frequency bins). Here it is in MATLAB.
% compute spectrum
dft = abs(fft(weight)); % real response
dft = dft(1:floor(end/2) + 1); % keep only pos freqs
dft = dft/sum(dft); % normalise
% find present modes modes
mode = zeros(0, 2);
[pks, locs, widths, ~] = findpeaks(dft);
for k=1:length(locs)
% only consider significant peaks
if pks(k) > 0.1
av_width = min([floor(peak_width_factor*widths(k)), locs(k)-1, length(dft)-locs(k)]);
inds = (locs(k)-av_width):(locs(k)+av_width);
av_ind = (inds * dft(inds)) / sum(dft(inds));
av_freq = (av_ind - 1)/T;
mode = [mode;
av_freq, pks(k)];
end
end
This produces a matrix of present modes (of a spectral significance above 0.1/1) where each row is the frequency and significance of the mode.
This works great for signals like this (time signal left, dft right with the frequencies of detected modes labeled):
but fails for signals like these (where we see and expect frequencies close to 2; not an order of magnitude smaller!)
Often I expect a certain frequency (e.g f=2.6 in the above signals) and can judge myself the mode is present by the average period between the local maxima. I tried codifying this - computing the average time between local maxima - in MATLAB, but it was pretty unreliable:
[~, peak_inds] = findpeaks(weight);
cycle_periods = diff(peak_inds) * dt;
av_cycle_period = sum(cycle_periods)/length(cycle_periods);
av_freq = 1/av_cycle_period;
My signals are well enough sampled (around 15 to 20 values per observable manky period) to resolve these manky modes visually. I've studied time series and random processes at an undergraduate level, but we never really went too deep into spectral analysis. So:
How can I reliably compute these highest-frequency modes in my very 'unfourier' signals?
Why does my current DFT analysis incorrectly deduce very low frequency modes in these manky signals?
Why would, if multiple present modes have dissimilar frequencies, my naive distance-between-local-maxima-average method fail at extracting the highest frequency?