how to use fitnlm with constraints

I have a custom equation and want to fit its coeffients.
coefficients are k
x is data
Equation is as follows:
modelfun = @(k,x) k(1).*x(:,1)+k(2).*log10(x(:,2) +k(3).*x(:,3)^2)
Kinit is vector of initial variables that I give
tbl contains my data x
I fit like this:
mdl = fitnlm(tbl,modelfun,Kinit);
I want to impose certain contraints on coefficients,
i.e.,
k(1) should be between 20 and 40
k(2) should be positive
k(3) should be negative.
How can I do that?
Thanks a lot for helping me out.

2 Comments

log10*x(:,2)
could you confirm that you assigned a value to log10 such that you can multiply it by an input? Or did you miss some () ?
@Walter Roberson sorry, i missed brackets..the function is definitely non-linear.
modelfun = @(k,x) k(1).*x(:,1)+k(2).*log10(x(:,2) +k(3).*x(:,3)^2)

Sign in to comment.

 Accepted Answer

No, fitnlm does not provide any way to put in constraitns.
You might consider lsqcurvefit from the Optimization Toolbox. Or you could consider using the Curve Fitting Toolbox; https://www.mathworks.com/help/curvefit/linear-and-nonlinear-regression.html

9 Comments

Torsten
Torsten on 11 Mar 2023
Edited: Torsten on 11 Mar 2023
The model function is linear in the parameters to be fitted. Thus using "lsqlin" should suffice.
hmmm... if log10 is a constant ???
All models of the form
y = k(1)*f1(xdata)+k(2)*f2(xdata)+...+k(n)*fn(xdata)
are linear in the parameters independent of the functions f1,f2,...,fn (which can be nonlinear).
"lsqlin" can be used for all of these model functions.
However we can suspect that the actual function might possibly be
modelfun = @(k,x) k(1).*x(:,1)+k(2).*log10(x(:,2) +k(3).*x(:,3)^2)
which would not be linear in the parameters.
I would have thought
modelfun = @(k,x) k(1)*x(:,1)+k(2)*log10(x(:,2)) +k(3)*x(:,3).^2
but I'm not sure.
@Torsten can't use lsqlin as function is non-linear. Sorry i missed brackets, have edited my question to make it correct.
@Walter Roberson i did try Curve Fitting Toolbox, but looks like it takes only 1 input, i.e., y=f(x). My equation is of form f(x1,x2,x3), it has 3 inputs.
Ah, yes. Curve Fitting Toolbox can support functions of two variables, creating a surface fit, but that is not enough for your purposes.
You could consider creating a residue function,
residue = @(k) sum((k(1) * x(:,1) + k(2) * log10(x(:,2)) + k(3)*x(:,3).^2) - Y).^2)
and minimizing that sum-of-squares using fmincon.
Got it, makes sense! Thanks so much!

Sign in to comment.

More Answers (0)

Categories

Community Treasure Hunt

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

Start Hunting!