can any one help me to find simple empirical model (equation) with a little parameters for this data
3 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
Mushtaq Al-Jubbori
il 5 Apr 2024
Modificato: John D'Errico
il 7 Apr 2024
x=[31.96 30.25 28.27 26.84 25.4 24 23.27 21.89 20.85 18.6 17.02 16 15.81 13.6 12 11.19 9.8 8.8 7.07 5.7 4.6 4.36 3.2 2.6 2.15 1.5 1 0.75 0.35 0.1 ]; y=[1.18 1.26 1.38 1.5 1.63 1.75 1.89 2.068 2.21 2.55 2.8 2.99 3 3.43 3.7 3.89 4.1 4.3 4.7 5 5.2 5.3 5.5 5.6 5.7 5.7 5.4 4.9 3.2 1.16]; plot(x,y,'o')
Risposta accettata
John D'Errico
il 6 Apr 2024
Modificato: John D'Errico
il 7 Apr 2024
As an alternate model, one that employs the assumption that the curve passes through the point (0,1), can we find a different fit? For example, we could try a sum of exponentials, but with that assumption built in.
x=[31.96 30.25 28.27 26.84 25.4 24 23.27 21.89 20.85 18.6 17.02 16 15.81 13.6 12 11.19 9.8 8.8 7.07 5.7 4.6 4.36 3.2 2.6 2.15 1.5 1 0.75 0.35 0.1 ];
y=[1.18 1.26 1.38 1.5 1.63 1.75 1.89 2.068 2.21 2.55 2.8 2.99 3 3.43 3.7 3.89 4.1 4.3 4.7 5 5.2 5.3 5.5 5.6 5.7 5.7 5.4 4.9 3.2 1.16];
mdl = fittype('a*exp(-b*x) + (1-a)*exp(-c*x)',indep = 'x')
fittedmdl = fit(x',y',mdl,start = [6 2 1])
plot(fittedmdl,x,y,'bo')
And again, we can see the curve now passes exactly through (0,1).
fittedmdl(0)
As well though, you can see the fit is rather poor. I could throw another exponential term in there of course, with the result that now the model gets more complex.
mdl = fittype('a*exp(-b*x) + (c)*exp(-d*x) + (1-a-c)*exp(-e*x)',indep = 'x')
fittedmdl = fit(x',y',mdl,start = [5 2 1 .1 .2])
plot(fittedmdl,x,y,'bo')
With total crap for a result, based on wild guesses for starting values.
Is there a valid reason to chase down this rabbit hole?
Ok. For kicks, to make it easy to understand how this was done, I'll use GA, coupled with an optimproblem to estimate the parameters.
prob = optimproblem;
linv = optimvar('linv',[1,3],LowerBound = -10,UpperBound = 10);
ratev = optimvar('ratev',[1,3],LowerBound = 0);
Prob.constraints.MyConstraint1 = sum(linv) == 1;
% the objective function is simple.
prob.Objective = sum((linv(1)*exp(-ratev(1)*x) + linv(2)*exp(-ratev(2)*x) + linv(3)*exp(-ratev(3)*x) - y).^2);
sol = solve(prob,Solver = 'ga')
plot(x,y,'bo')
hold on
fplot(@(x) exp(-x(:).*sol.ratev)*sol.linv',[0,max(x)])
hold off
grid on
Honestly, that took me a few tries to get even GA to find a decent solution.
3 Commenti
John D'Errico
il 7 Apr 2024
Modificato: John D'Errico
il 7 Apr 2024
The other models I also show, ALSO satisy that condition! And all of them fit your data far better. Only the very first one I built did not use that condition, BECAUSE you never told me that was a requirement.
Make up your mind! Do you want a fit with few parameters? Do you want a fit that fits excruciatingly well, with many parameters? It seems that you are asking for both of these things, at different times.
I understand now that you want a fit that passes through the point (0,1), but I have shown many ways to do that fit. Do you want a fit that can be extrapolated for large x? Or do you only care what it does within the support of your data?
Più risposte (1)
John D'Errico
il 6 Apr 2024
Modificato: John D'Errico
il 6 Apr 2024
Why not try it? This seems adequate:
x=[31.96 30.25 28.27 26.84 25.4 24 23.27 21.89 20.85 18.6 17.02 16 15.81 13.6 12 11.19 9.8 8.8 7.07 5.7 4.6 4.36 3.2 2.6 2.15 1.5 1 0.75 0.35 0.1 ];
y=[1.18 1.26 1.38 1.5 1.63 1.75 1.89 2.068 2.21 2.55 2.8 2.99 3 3.43 3.7 3.89 4.1 4.3 4.7 5 5.2 5.3 5.5 5.6 5.7 5.7 5.4 4.9 3.2 1.16];
So I'll put a negative exponential in there for the fast transient in the beginning, then a simple polynomial that will take over when x grows large.
mdl = fittype('a + b*x + c*x^2 + d*x.^3+ e*exp(-f*x)',indep = 'x')
fittedmdl = fit(x',y',mdl,start = [1 1 .1 .1 -6 2])
plot(fittedmdl,x,y,'bo')
4 Commenti
John D'Errico
il 6 Apr 2024
Sigh. Exactly how do the words "little parameters" imply the curve must pass through (0,1)?
You say that you want FEWER parameters. I want to see world peace in my lifetime. Does my wanting something make it come true? Why should that be true for you?
We can add extra terms of course.
x=[31.96 30.25 28.27 26.84 25.4 24 23.27 21.89 20.85 18.6 17.02 16 15.81 13.6 12 11.19 9.8 8.8 7.07 5.7 4.6 4.36 3.2 2.6 2.15 1.5 1 0.75 0.35 0.1 ];
y=[1.18 1.26 1.38 1.5 1.63 1.75 1.89 2.068 2.21 2.55 2.8 2.99 3 3.43 3.7 3.89 4.1 4.3 4.7 5 5.2 5.3 5.5 5.6 5.7 5.7 5.4 4.9 3.2 1.16];
mdl = fittype('a + b*x + c*x^2 + d*x.^3 + e*x.^4 + (1-a)*exp(-f*x)',indep = 'x')
fittedmdl = fit(x',y',mdl,start = [6 -0.2 0.002 0.0001 0.000001 1.5])
plot(fittedmdl,x,y,'bo')
That seems to follow the data better in some places, but it also may be chasing noise in the curve too.
I wold go with the model in this form, as you saw in my last comment.
mdl = fittype('a + b*x + c*x^2 + d*x.^3 + (1-a)*exp(-f*x)',indep = 'x')
It satisfies the requirement that is passes through (0,1), but it is not chasing noise in your data. Higher order models do that.
If you want a simpler model, for gods sake, you asked for an empirical model. Simple does not always equate to good in terms of fit. In fact, very often you will find a tradeoff. Simpler models are aften less good models.
Vedere anche
Categorie
Scopri di più su Discriminant Analysis in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!