This is as close as I can get to a decent fit:
D = load('data_fft_peak6.mat');
t = D.data_fft_peak(:,1);
s = D.data_fft_peak(:,2);
figure
plot(t, s)
grid
L = numel(t);
Ts = mean(diff(t));
Fs = 1/Ts;
Fn = Fs/2;
N = 2^(nextpow2(L)+2);
FTs = fft(s,N)/L;
Fv = linspace(0, 1, fix(numel(FTs)/2)+1)*Fn;
Iv = 1:numel(Fv);
[pks,locs] = findpeaks(abs(FTs(Iv))*2, 'MinPeakHeight',0.02);
figure
plot(Fv, abs(FTs(Iv))*2)
hold on
plot(Fv(locs), abs(FTs(locs))*2, 'r^')
hold off
grid
pklbls = compose('\\leftarrow Freq = %8.5f Hz\n Ampl = %8.5f', [Fv(locs).', pks]);
text(Fv(locs), pks, pklbls, 'HorizontalAlignment','left', 'VerticalAlignment','top')
objfcn = @(b,t) b(1).*cos(b(2)*t) + b(3).*cos(b(4).*t) .* b(5).*t.*exp(b(6).*t);
B0 = [pks(1) Fv(locs(1))*2*pi pks(2) Fv(locs(2))*2*pi 0.5 -0.01].';
B = lsqcurvefit(objfcn, B0, t, s)
fitfcn = objfcn(B, t);
figure
plot(t, s)
hold on
plot(t, fitfcn, '-r')
hold off
grid
Note — I included an extended version of ‘objfcn’ for you to experiment with.
The estimated parameters are:
B =
0.022930977208190
0.106707811047044
-0.000717587879530
0.112740321550530
1.119470956816299
-0.002453356895356
EDIT — (29 Dec 2020 at 17:29)
Also experiment with:
[pks,locs] = findpeaks(abs(FTs(Iv))*2, 'MinPeakProminence',0.008);
and:
objfcn = @(b,t) b(1).*cos(b(2)*t) + b(3).*cos(b(4).*t) .* b(7).*t.*exp(b(8).*t) + b(5).*cos(b(6).*t);
B0 = [pks(1) Fv(locs(1))*2*pi pks(2) Fv(locs(2))*2*pi pks(3) Fv(locs(3))*2*pi 0.5 -0.01].';
producing:
B =
0.007599194766653
0.010943887298747
-0.000688462858777
0.112676604541936
0.035329767711197
0.118358798142968
1.119527877005960
-0.002418300550008
.
Best Answer