How to use lsqnonlin with multiple constraints?

16 views (last 30 days)
Hello,
I want to run non-linear regression with multiple constraints. I found that I should use lsqnonlin function.
My function is
((b(1) + b(2)*log(CBd(:,2))).*(CBd(:,4).^(b(3)+b(4).*((CBd(:,6)-T0)/T0))).*(CBd(:,5).^b(5)))+((b(6) + b(7)*log(CBd(:,3))).*(CBd(:,4).^(b(8)+b(9).*((CBd(:,7)-T0)/T0))).*(CBd(:,5).^b(10)))
and CBd is data.
I want to have b(3) & b(8) as negative value and b(5) & b(10) as positive.
How can I do that?
Thanks in advance.

Accepted Answer

John D'Errico
John D'Errico on 23 Apr 2023
Edited: John D'Errico on 23 Apr 2023
These are not so much constraints, as bounds. They are simpler things. lsqnonlin allows bounds, but not equality or inequality constraints.
help lsqnonlin
LSQNONLIN solves non-linear least squares problems. LSQNONLIN attempts to solve problems of the form: min sum {FUN(X).^2} where X and the values returned by FUN can be X vectors or matrices. subject to: A*X <= B, Aeq*X = Beq (linear constraints) C(X) <= 0, Ceq(X) = 0 (nonlinear constraints) LB <= X <= UB (bounds) LSQNONLIN implements three different algorithms: trust region reflective, Levenberg-Marquardt, and Interior-Point. Choose one via the option Algorithm: for instance, to choose Levenberg-Marquardt, set OPTIONS = optimoptions('lsqnonlin', 'Algorithm','levenberg-marquardt'), and then pass OPTIONS to LSQNONLIN. X = LSQNONLIN(FUN,X0) starts at the matrix X0 and finds a minimum X to the sum of squares of the functions in FUN. FUN accepts input X and returns a vector (or matrix) of function values F evaluated at X. NOTE: FUN should return FUN(X) and not the sum-of-squares sum(FUN(X).^2)). (FUN(X) is summed and squared implicitly in the algorithm.) X = LSQNONLIN(FUN,X0,LB,UB) defines a set of lower and upper bounds on the design variables, X, so that the solution is in the range LB <= X <= UB. Use empty matrices for LB and UB if no bounds exist. Set LB(i) = -Inf if X(i) is unbounded below; set UB(i) = Inf if X(i) is unbounded above. X = LSQNONLIN(FUN,X0,LB,UB,A,B,Aeq,Beq) finds a minimum X to the sum of squares of the functions in FUN subject to the linear inequalities A*X <= B and linear equalities Aeq*X = Beq. X = LSQNONLIN(FUN,X0,LB,UB,A,B,Aeq,Beq,NONLCON) subjects the minimization to the constraints defined in NONLCON. The function NONLCON accepts X and returns the vectors C and Ceq, representing the nonlinear inequalities and equalities respectively. LSQNONLIN minimizes FUN such that C(X) <= 0 and Ceq(X) = 0. X = LSQNONLIN(FUN,X0,LB,UB,A,B,Aeq,Beq,NONLCON,OPTIONS) minimizes with the default optimization parameters replaced by values in OPTIONS, an argument created with the OPTIMOPTIONS function. See OPTIMOPTIONS for details. Use the SpecifyObjectiveGradient option to specify that FUN also returns a second output argument J that is the Jacobian matrix at the point X. If FUN returns a vector F of m components when X has length n, then J is an m-by-n matrix where J(i,j) is the partial derivative of F(i) with respect to x(j). (Note that the Jacobian J is the transpose of the gradient of F.) X = LSQNONLIN(PROBLEM) solves the non-linear least squares problem defined in PROBLEM. PROBLEM is a structure with the function FUN in PROBLEM.objective, the start point in PROBLEM.x0, the linear inequality constraints in PROBLEM.Aineq and PROBLEM.bineq, the linear equality constraints in PROBLEM.Aeq and PROBLEM.beq, the lower bounds in PROBLEM.lb, the upper bounds in PROBLEM.ub, the nonlinear constraint function in PROBLEM.nonlcon, the options structure in PROBLEM.options, and solver name 'lsqnonlin' in PROBLEM.solver. [X,RESNORM] = LSQNONLIN(FUN,X0,...) returns the value of the squared 2-norm of the residual at X: sum(FUN(X).^2). [X,RESNORM,RESIDUAL] = LSQNONLIN(FUN,X0,...) returns the value of the residual at the solution X: RESIDUAL = FUN(X). [X,RESNORM,RESIDUAL,EXITFLAG] = LSQNONLIN(FUN,X0,...) returns an EXITFLAG that describes the exit condition. Possible values of EXITFLAG and the corresponding exit conditions are listed below. See the documentation for a complete description. 1 LSQNONLIN converged to a solution. 2 Change in X too small. 3 Change in RESNORM too small. 4 Computed search direction too small. 0 Too many function evaluations or iterations. -1 Stopped by output/plot function. -2 Bounds are inconsistent. [X,RESNORM,RESIDUAL,EXITFLAG,OUTPUT] = LSQNONLIN(FUN,X0,...) returns a structure OUTPUT with the number of iterations taken in OUTPUT.iterations, the number of function evaluations in OUTPUT.funcCount, the algorithm used in OUTPUT.algorithm, the number of CG iterations (if used) in OUTPUT.cgiterations, the first-order optimality (if used) in OUTPUT.firstorderopt, and the exit message in OUTPUT.message. [X,RESNORM,RESIDUAL,EXITFLAG,OUTPUT,LAMBDA] = LSQNONLIN(FUN,X0,...) returns the set of Lagrangian multipliers, LAMBDA, at the solution: LAMBDA.lower for LB, LAMBDA.upper for UB, LAMBDA.ineqlin is for the linear inequalities, LAMBDA.eqlin is for the linear equalities, LAMBDA.ineqnonlin is for the nonlinear inequalities, and LAMBDA.eqnonlin is for the nonlinear equalities. [X,RESNORM,RESIDUAL,EXITFLAG,OUTPUT,LAMBDA,JACOBIAN] = LSQNONLIN(FUN, X0,...) returns the Jacobian of FUN at X. Examples FUN can be specified using @: x = lsqnonlin(@myfun,[2 3 4]) where myfun is a MATLAB function such as: function F = myfun(x) F = sin(x); FUN can also be an anonymous function: x = lsqnonlin(@(x) sin(3*x),[1 4]) If FUN is parameterized, you can use anonymous functions to capture the problem-dependent parameters. Suppose you want to solve the non-linear least squares problem given in the function myfun, which is parameterized by its second argument c. Here myfun is a MATLAB file function such as function F = myfun(x,c) F = [ 2*x(1) - exp(c*x(1)) -x(1) - exp(c*x(2)) x(1) - x(2) ]; To solve the least squares problem for a specific value of c, first assign the value to c. Then create a one-argument anonymous function that captures that value of c and calls myfun with two arguments. Finally, pass this anonymous function to LSQNONLIN: c = -1; % define parameter first x = lsqnonlin(@(x) myfun(x,c),[1;1]) See also OPTIMOPTIONS, LSQCURVEFIT, FSOLVE, @. Documentation for lsqnonlin doc lsqnonlin
The third and 4th arguments to lsqnonlin are LB and UB, respectively, as you can see in the help.
If a variable is constrained to be positive, then use a lower bound for that variable of 0. If negative, then the upper bound is zero. And if a variable has no bounds at all, then supply -inf and inf for those variables. But don't think you can just pass in a scalar value of zero, and hope that lsqnonlin will apply that value to ALL of your unknowns. For example, of LB and UB are:
LB = [-inf, 0 , 3, -inf, -inf];
UB = [inf, inf, 5, 0, inf];
Then you have 5 variables. The bounds would be:
Variable 1 has no bounds at all.
Variable 2 is constrained to be positive.
Variable 3 Must lie in the interval [3,5].
Variable 4 Is constrained yto be negative.
Variable 5 has no bounds at all.
Finally, you need to understand that just because you tell lsqnonlin to bound a variable to be strictly positive, that the solver will only obey that to within a constraint tolerance. SO you might see something on the order of -1e-12, even if the number was bounded above zero.
If you truly, absolutely cannot tolerate a slightly nevegative result, ever, then use a bound that is just a wee bit higher than zero, so sufficiently larger than the constraint tolerance. (I don't recall the default there.)
Even at that, if you want something to be strictly positive, then it might be best to use a transformation of the variable. Thus if a MUST be positve in the function a*x, then consider using a form like exp(a)*x. Now the solver can estimate a as any value, positive or negative. All that matters is exp(a) is indeed always positive. Then when the solver returns a result, exponentiate that parameter. Another transformation that can work as well is a^2 to force a variable to be non-negative.

More Answers (1)

Torsten
Torsten on 23 Apr 2023
Use lb and ub in the list of inputs to "lsqnonlin".

Categories

Find more on Systems of Nonlinear Equations in Help Center and File Exchange

Products


Release

R2023a

Community Treasure Hunt

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

Start Hunting!