%% Nonlinear System of Equations with Constraints, Problem-Based
% This example shows how to attempt to solve a nonlinear system of equations with constraints by using the problem-based approach.
%% Bound Constraints
% When your problem has only bound constraints, the process for solving the problem is straightforward. For example, to find the solution with positive components to the system of equations
% \begin{array}{l}
% \left(x_1 +1\right)\left(10-x_1 \right)\frac{1+x_2^2 }{1+x_2^2 +x_2 }=0\\
% \left(x_2 +2\right)\left(20-x_2 \right)\frac{1+x_1^2 }{1+x_1^2 +x_1 }=0,
% \end{array}
% simply create optimization variables with lower bounds of 0. (These equations have four solutions: where x_1 = -1 or x_1 = 10, and where x_2 = -2 or x_2 = 20.)

x = optimvar('x',2,"LowerBound",0);
expr1 = (x(1) + 1)*(10 - x(1))*((1 + x(2)^2))/(1 + x(2)^2 + x(2));
expr2 = (x(2) + 2)*(20 - x(2))*((1 + x(1)^2))/(1 + x(1)^2 + x(1));
eqn1 = expr1 == 0;
eqn2 = expr2 == 0;
prob = eqnproblem;
prob.Equations.eqn1 = eqn1;
prob.Equations.eqn2 = eqn2;
x0.x = [15,15];
[sol,fval,exitflag] = solve(prob,x0)

% View the solution.

sol.x

%
%% General Constraints
% When your problem has general constraints, formulate the problem as an optimization problem, not an equation problem. Set the equations as equality constraints. For example, to solve the preceding equations subject to the nonlinear inequality constraint \|x\|^2 \le 10, remove the bounds on x and formulate the problem as an optimization problem with no objective function.

x.LowerBound = [];
circlecons = x(1)^2 + x(2)^2 <= 10;
prob2 = optimproblem;
prob2.Constraints.circlecons = circlecons;
prob2.Constraints.eqn1 = eqn1;
prob2.Constraints.eqn2 = eqn2;
[sol2,fval2,exitflag2] = solve(prob2,x0)

% View the solution.

sol2.x

%
%% General Constraints Using Least Squares Objective
% You can also formulate the problem by setting the objective function as a sum of squares, and the general constraints as a constraint. This alternative formulation gives a mathematically equivalent problem, but can result in a different solution because the change in formulation leads the solver to different iterations.

prob3 = optimproblem;
prob3.Objective = expr1^2 + expr2^2;
prob3.Constraints.circlecons = circlecons;
[sol3,fval3,exitflag3] = solve(prob3,x0)

% View the solution.

sol3.x

% In this case, the least squares objective leads to the same solution as the previous formulation, which uses only constraints.
%
%% More About Solving Equations with Constraints
% Generally, solve attempts to solve a nonlinear system of equations by minimizing the sum of squares of the equation components. In other words, if LHS(i) is the left-side expression for equation i, and RHS(i) is the right-side expression, then solve attempts to minimize sum((LHS – RHS).^2).
% In contrast, when attempting to satisfy nonlinear constraint expressions, solve generally uses fmincon, and tries to satisfy the constraints by using different strategies.
% In both cases, the solver can fail to solve the equations. For strategies you can use to attempt to find a solution when the solver fails, see fsolve Could Not Solve Equation.
%
% Copyright 2019 The MathWorks, Inc.