How to find fit for function with exponential and oscillation term?

22 views (last 30 days)
Hello,
I'm trying to fit a measured signal with cftool. Normally, the function should have the expression: f(x) = A+B*exp(-x/C). Unfortunatly, an oscillation is overlapping this signal. I thought about simply adding an oscillation term +D*cos(w*x+E), which is not working.
Has anyone an idea, how I could fit this signal?
Thanks in advance and have a nice day
Markus

Answers (1)

John D'Errico
John D'Errico on 18 Jan 2023
Edited: John D'Errico on 18 Jan 2023
Why is it not working? First, you NEED good startign values. ALWAYS. Whenever you have exponential models and trig models. What really matters is a good estimate of the rate parameter and the frequency or period of the trig terms. Get them wrong, and fugetaboutit.
So, first, some data.
x = linspace(0,2,2041); % roughly the same curve as you have is my goal
y = .1*exp(-x*4) + .01*cos(50*x + randn(1)) + 1.1 + randn(size(x))/1000;
plot(x,y,'-')
I did not honestly try that hard to get the coefficients exactly as they would be for the data you show, but the qualitative shape is at least similar.
Now let me try to fit it, and see how well we do.
mdl = fittype('a + b*exp(-x/c) + d*cos(e*x+f)','indep','x')
mdl =
General model: mdl(a,b,c,d,e,f,x) = a + b*exp(-x/c) + d*cos(e*x+f)
% c and e here should be at least correct to within a factor of about 2 up or down
% the other parameters are far less sensitive.
% The MOST important feature about the exponential rate parameter is you
% get the sign correct. THe trig rate parameter is the most sensitive.
% Since I see 17 peaks in a span of 2, That would suggest the period
% is approximately 2/(17-1). But the period of a sine (or cosine) function
% of the form sin(e*x) is 2*pi/e. Therfore I would estimate the parameter e as
% e = 2*pi*(17-1)/2 = 50.2654824574367
params0 = [1 .01 1 .01 50.265 1];
fittedmdl = fit(x',y',mdl,'start',params0)
fittedmdl =
General model: fittedmdl(x) = a + b*exp(-x/c) + d*cos(e*x+f) Coefficients (with 95% confidence bounds): a = 1.1 (1.1, 1.1) b = 0.1 (0.09975, 0.1003) c = 0.25 (0.249, 0.2511) d = 0.01 (0.009942, 0.01007) e = 50.01 (50, 50.02) f = 0.2381 (0.2256, 0.2507)
plot(fittedmdl,x,y)
And I got a marvelous fit. However, try it again, but with a poor estimate of the period of that cosine function? CRAP.
params0 = [1 .01 1 .01 45 1];
fittedmdl2 = fit(x',y',mdl,'start',params0)
fittedmdl2 =
General model: fittedmdl2(x) = a + b*exp(-x/c) + d*cos(e*x+f) Coefficients (with 95% confidence bounds): a = 145.5 (-5.626e+04, 5.655e+04) b = -144.4 (-5.655e+04, 5.626e+04) c = -5599 (-2.193e+06, 2.181e+06) d = -0.0036 (-0.00457, -0.00263) e = 54.65 (54.18, 55.12) f = 1.85 (1.307, 2.393)
plot(fittedmdl2,x,y)
As you can see, I was wrong only by a factor of 10% on the period for the starting estimate. But I got complete crap as a result.
All of the other initial parameters need only be in the correct ballpark. But screw up the period on the trig term and you are wasting your time.

Products


Release

R2020b

Community Treasure Hunt

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

Start Hunting!