Engee documentation
Notebook

Solving systems of nonlinear equations

This example demonstrates how to solve systems of nonlinear equations using a problem-based approach.

We will use the functions of the library JuMP.jl to formulate the optimisation problem and the nonlinear optimisation library Ipopt.jl.

Installing the libraries

If your environment does not have the latest version of the JuMP package installed , uncomment and run the box below:

In [ ]:
Pkg.add(["Ipopt", "JuMP"])
In [ ]:
#Pkg.add("JuMP");

To launch a new version of the library after the installation is complete, click on the "My Account" button:

screenshot_20240710_134852.png Then click on the "Stop" button:

screenshot_20240710_2.png

Restart the session by pressing the "Start Engee" button:

screenshot_20240710_135431.png

Task Description

Let's find solutions $x_1$ and $x_2$ for the system of nonlinear equations presented below, using the problem-oriented approach:

\begin{cases} exp(-exp(-(x_1+x_2)))=x_2(1+x_1^2) \\ \\x_1cos(x_2)+x_2sin(x_1)={\frac{{1}}{2}}\end{cases}

Connecting libraries

Connect the library JuMP:

In [ ]:
using JuMP;

Connect the nonlinear solver library Ipopt:

In [ ]:
using Ipopt;

Creating an optimisation problem

Create an optimisation problem using the function Model() and specify the name of the solver in brackets:

In [ ]:
sys_prob = Model(Ipopt.Optimizer)
Out[0]:
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: EMPTY_OPTIMIZER
Solver name: Ipopt

Create a variable x, containing two values - $x_1$ and $x_2$:

In [ ]:
@variable(sys_prob, x[1:2]);

Set the first non-linear condition using the macro @NLconstraint:

In [ ]:
@NLconstraint(sys_prob, exp(-exp(-(x[1] + x[2]))) == x[2] * (1 + x[1]^2))
Out[0]:
$$ (exp(-(exp(-((x[1] + x[2]))))) - x[2] * (1.0 + x[1] ^ {2.0})) - 0.0 = 0 $$

Set the second non-linear condition using the macro @NLconstraint:

In [ ]:
@NLconstraint(sys_prob, x[1] * cos(x[2]) + x[2] * sin(x[1]) == 1/2)
Out[0]:
$$ ((x[1] * cos(x[2]) + x[2] * sin(x[1])) - 1.0 / 2.0) - 0.0 = 0 $$

Setting initial values for the optimisation variables can help to control the optimisation process more efficiently. Solve the problem starting from the point [0,0]. To do this, use the function set_start_value() and set initial values for $x_1$ и $x_2$:

In [ ]:
set_start_value(x[1], 0.0);
set_start_value(x[2], 0.0);

Solving an optimisation problem

Solve the optimisation problem:

In [ ]:
optimize!(sys_prob)
This is Ipopt version 3.14.13, running with linear solver MUMPS 5.6.1.

Number of nonzeros in equality constraint Jacobian...:        4
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:        6

Total number of variables............................:        2
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        0
                     variables with only upper bounds:        0
Total number of equality constraints.................:        2
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0  0.0000000e+00 5.00e-01 0.00e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  0.0000000e+00 3.15e-01 0.00e+00  -1.7 8.73e-01    -  1.00e+00 1.00e+00h  1
   2  0.0000000e+00 5.73e-02 0.00e+00  -1.7 1.98e-01    -  1.00e+00 1.00e+00h  1
   3  0.0000000e+00 8.66e-04 0.00e+00  -2.5 6.84e-02    -  1.00e+00 1.00e+00h  1
   4  0.0000000e+00 2.66e-07 0.00e+00  -5.7 6.23e-04    -  1.00e+00 1.00e+00h  1
   5  0.0000000e+00 2.28e-14 0.00e+00  -8.6 3.20e-07    -  1.00e+00 1.00e+00h  1

Number of Iterations....: 5

                                   (scaled)                 (unscaled)
Objective...............:   0.0000000000000000e+00    0.0000000000000000e+00
Dual infeasibility......:   0.0000000000000000e+00    0.0000000000000000e+00
Constraint violation....:   2.2759572004815709e-14    2.2759572004815709e-14
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   0.0000000000000000e+00    0.0000000000000000e+00
Overall NLP error.......:   2.2759572004815709e-14    2.2759572004815709e-14


Number of objective function evaluations             = 6
Number of objective gradient evaluations             = 6
Number of equality constraint evaluations            = 6
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 6
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 5
Total seconds in IPOPT                               = 0.003

EXIT: Optimal Solution Found.

Store the values of x in a variable:

In [ ]:
sol_x = value.(x);

Output the results of the optimisation:

In [ ]:
println("Solution: x = ", sol_x)
Solution: x = [0.35324661959670156, 0.6060817366414603]

The solutions we found for the system of nonlinear equations:

$$x_1 = 0.35324661959670156$$ $$x_2 = 0.6060817366414603$$

Conclusion

In this example, we found solutions to a system of nonlinear equations using a problem-oriented approach. We used the library JuMP to formulate our problem and the nonlinear solver library Ipopt to find solutions to the problem.