# Constrain a parameter in a fit?

3 views (last 30 days)
Alberto Paniate on 8 Oct 2020
Edited: John D'Errico on 9 Oct 2020
Hi, i have
f=fit(media(:), dev(:), 'a*x+x^2')
plot(f,media,dev)
I want to constrain a between 2 and 4 how can I do?
Thanks

Ameer Hamza on 8 Oct 2020
What is 2 and 4? The curve fitting toolbox does not support constrained curve fitting. You will need to use an optimizer, such as fmincon().
Alberto Paniate on 9 Oct 2020
I want to fit the points with the curve : "a*x+x^2" with a John D'Errico on 9 Oct 2020
Actually, the CFT does support bound constraints, as I show. fmincon would not be necessary. slightly simpler tools such as lsqnonlin or lsqcurvefit also do. And of course, since the indicated model is a linear model in the parameter, lsqlin would be best, IF you were going to use the optimization toolbox.

John D'Errico on 9 Oct 2020
Edited: John D'Errico on 9 Oct 2020
Simple enough. You could do this using lsqcurvefit or lsnonlin from the optimization toolbox, which do allow bound constraints on the parameters. And god only knows why you would wish to use that model. In fact, it is trivially linear, where lsqlin would suffice. So my guess is this is not your real model. But since I don't have your data, who cares anyway? :)
Since you have the curve fitting toolbox, we will do it there.
x = rand(10,1);
y = rand(10,1);
As you can see, my data building is not terribly creative. :)
First, I'll try it without any bounds.
ft = fittype('a*x+x.^2','indep','x');
mdl = fit(x,y,ft)
Warning: Start point not provided, choosing random start point.
mdl =
General model: mdl(x) = a*x+x.^2 Coefficients (with 95% confidence bounds): a = -0.05402 (-0.6045, 0.4965)
We clearly are way outside the bounds [2,4]. I was not even worried about that. Now apply bounds on the same data.
mdl = fit(x,y,ft,'lower',2,'upper',4)
Warning: Start point not provided, choosing random start point.
mdl =
General model: mdl(x) = a*x+x.^2 Coefficients (with 95% confidence bounds): a = 2 (fixed at bound)
And as you see, a is now limited by the bound I applied.
Finally, to show you how to apply bounds to multiple parameters, only one of which is constrained...
ft = fittype('a*x+b*x.^2','indep','x');
mdl = fit(x,y,ft,'lower',[2 -inf],'upper',[4,inf])
Warning: Start point not provided, choosing random start point.
mdl =
General model: mdl(x) = a*x+b*x.^2 Coefficients (with 95% confidence bounds): a = 2 (0.1055, 3.894) b = -1.714 (-4.156, 0.7284)
So a was bound constrained, but b was completely unconstrained.
As I said, other tools would work. I think nlinfit from the stats toolbox also accepts simple bound constraints. Best of course for these models would have been lsqlin, since it is not overtly iterative as are the other tools, and requires no starting values. Since the models you have given are linear models in the parameters, starting values should be irrelevant. But fit complains, even when in theory it could know better. Tough life, but I was not the author of the CFT. :) Had that been the case, I'd probably have written some code to parse the model, checking for linear models, or even separable models with various classes of parameters, in which case better estimation techniques are available. At the same time, perhaps that might be confusing to some users, who would not understand why fit might sometimes not care if starting values are provided or not. Oh well, irrelevant, since I was not consulted. :)
set('IrrelevantRantMode','off')
Be careful in reading the confidence limits though, because the algorithm to determine confidence limits in the CFT is not something that has a clue about bounds. Simetimes the real world is too complicated for the algorithms we use. Que sera, sera...