Is it possible to select the parameters in the approximation equation using MATLAB?
Show older comments
I have a set of empirical data that is displayed on a graph (figure). There is an equation describing the dependence y=a*exp(b*x+c*x^2), you need to select the constants a, b, c. Is it possible to do this using MATLAB tools?

Answers (2)
Yes. Use the curve fitting toolbox.
help fittype
help fit
Note that the estimates of these coefficients will be very uncertain, due to the highly noisy data.
6 Comments
Darya
on 16 Nov 2024
Walter Roberson
on 16 Nov 2024
Note that that is not the equation of a guassian. A guassian would involve exp(-(x-B)^2/(2*C^2)) . If you expand that then you get a coefficient for x^2 and a coefficient for x -- but you also get a constant coefficient. In order for that constant coefficient to vanish, B would have to be 0.. in which case there would be no a*x coefficient.
John D'Errico
on 16 Nov 2024
Edited: John D'Errico
on 16 Nov 2024
Well, actually, that IS an equation of a Gaussian. Just not in the standard form you expect to see. That is, start with this expression:
F*exp(a*x-b*x.^2)
Complete the square inside the parens. You will find that indeed, it does fall into a Gaussian form.
A constant term inside the parens can be absorbed into the coefficient outside the exponential, given the identity:
exp(-b*x^2 + a) == exp(a)*exp(-b*x^2)
So even though it does not look like a Gaussian model, it is one.
I don't have your data. I don't see you attached it anywhere. And, while a picture may say a thousand words, it lacks a little when we start to talk about numbers.
Regardless, the problem is, you did not provide starting values for the parameters. If you don't do so, then fit uses random numbers. And those random numbers are NEVER going to be very good. You need to provide good starting values. At least something in the right ballpark.
If you do provide the data, I might still suggest you have a problem, because that curve just does not look like a gaussian bell curve. And it looks like you have seriously noisy data, so any result you get will be a poor predictor. If you want me to go into more depth, I would need to have your data.
Walter Roberson
on 16 Nov 2024
Oh, good point about the term being movable to the outside!
data = xlsread('data.xlsx');
x=(data(:,1))';
y=(data(:,2))';
ALWAYS PLOT YOUR DATA! Actually, plot everything. (Well, you did plot it, so well done there.)
plot(x,y,'o')
I would note this does not show the classical bell shaped curve. Not even remotely close. It has a peak near x=26, but it is not at all symmetric. And that is a problem.
Regardless, I want you to see the warning you got.
"Warning: Start point not provided, choosing random start point."
And that should tell you to at least try to do better.
In that model, b will be related to the variance, but it will be roughly inversely proportional to that parameter. (With an extra factor of 2 thrown in.) If the standard deviation might be around 3 or so, then an estimate for b might be around 0.05. This is a parameter we will care about.
But what should a be? If the peak is around 26, then a classical Gaussian form would look like this:
exp(-((X-26)/sigma)^2/2)
If we expand that form with sigma around 3, then we would see this:
exp(-X^2/18 + (26*X)/9 - 338/9)
That suggests a should be roughly 3, thus 26/9. The problem is, that constant term will kill you, because it will look like exp(-338/9)
exp(-338/9)
And that means we will have serious variable scaling problems. However, we MIGHT just survive.
myfittype = fittype('F*exp(a*x-b*x.^2)', 'dependent',{'y'},'independent',{'x'}, 'coefficients',{'a','b','F'});
myfit = fit(x',y',myfittype,'start',[3 0.05 1e-17])
plot(myfit,x,y)
grid on
ylim([0,4])
And we see a fit now. Looks like complete absolute crapola on a shingle. You should see it tries to go down to zero at the right.
The problem is, your model simply does not fit the data. A true Gaussian model will go to zero in the tails. And it will be symmetric around the peak. Your data does not show anything of the sort. If you allow me to change the model of course, we can do something a little better. I would add an offset in y, allowing the entire model to translate up and down in y.
myfittype2 = fittype('F*exp(a*x-b*x.^2) + c', 'dependent',{'y'},'independent',{'x'}, 'coefficients',{'a','b','F','c'});
myfit2 = fit(x',y',myfittype2,'start',[3 0.05 1e-17 2])
plot(myfit2,x,y)
Still complete crap. Though I do observe that the parameters c and a have not changed at all from their start points. That gets into the serious issues we have with parameter scaling.
Sorry. I'm not at all sure why you think anything of the sort should fit your data.
Walter Roberson
on 12 Nov 2024
If you do not have the curve fitting toolbox, then you can try
x = %...
y = %...
objfun = @(abc) sum( (abc(1).*exp(abc(2).*x+abc(3).*x.^2) - y).^2 );
abc0 = [.1 .3 .4];
ABC = fminunc(objfun, abc0);
a = ABC(1); b = ABC(2); c = ABC(3);
Do not expect the fit to be all that good.
2 Comments
data = readmatrix('data.xlsx');
x = data(:,1);
y = data(:,2);
objfun = @(abc) sum( (abc(1).*exp(abc(2).*x+abc(3).*x.^2) - y).^2 );
abc0 = [.001 .003 .004];
objfun(abc0)
ABC = fminunc(objfun, abc0);
a = ABC(1); b = ABC(2); c = ABC(3);
[a, b, c]
F = @(x) a.*exp(b.*x + c.*x.^2);
[xs, xorder] = sort(x);
ys = y(xorder);
Y = F(xs);
plot(xs, Y, '-', xs, ys, 'b.')
Walter Roberson
on 16 Nov 2024
Fitting the first two points would require a guassian that rises sharply -- and consequently also falls sharply. It would fall to near the level of the first point, and stay low from there. The sum of squares of distance from that low value to the rest of the points would add up to a fair bit.
Whereas, the fit that is being generated here looks somewhat reasonable. The first two points are roughly the same distance from the line, so they balance out. The rest is similar to a linear fit in effect. You can see how this curve is a plausible fit.
Categories
Find more on Get Started with Curve Fitting Toolbox in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!



