Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 27 additions & 27 deletions tutorials/introduction-to-adnlpmodels/index.jmd
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,29 @@ author: "Abel Soares Siqueira and Dominique Orban"
---

ADNLPModel is simple to use and is useful for classrooms.
It only needs the objective function ``f`` and a starting point ``x^0`` to be
It only needs the objective function $f$ and a starting point $x^0$ to be
well-defined.
For constrained problems, you'll also need the constraints function ``c``, and
the constraints vectors ``c_L`` and ``c_U``, such that ``c_L \leq c(x) \leq c_U``.
Equality constraints will be automatically identified as those indices ``i`` for
which ``c_{L_i} = c_{U_i}``.
For constrained problems, you'll also need the constraints function $c$, and
the constraints vectors $c_L$ and $c_U$, such that $c_L \leq c(x) \leq c_U$.
Equality constraints will be automatically identified as those indices $i$ for
which $c_{L_i} = c_{U_i}$.

Let's define the famous Rosenbrock function
```math
$$
f(x) = (x_1 - 1)^2 + 100(x_2 - x_1^2)^2,
```
with starting point ``x^0 = (-1.2,1.0)``.
$$
with starting point $x^0 = (-1.2,1.0)$.

```@example adnlp
```julia
using ADNLPModels

nlp = ADNLPModel(x->(x[1] - 1.0)^2 + 100*(x[2] - x[1]^2)^2 , [-1.2; 1.0])
```

This is enough to define the model.
Let's get the objective function value at ``x^0``, using only `nlp`.
Let's get the objective function value at $x^0$, using only `nlp`.

```@example adnlp
```julia
using NLPModels # To access the API

fx = obj(nlp, nlp.meta.x0)
Expand All @@ -37,7 +37,7 @@ println("fx = $fx")
Done.
Let's try the gradient and Hessian.

```@example adnlp
```julia
gx = grad(nlp, nlp.meta.x0)
Hx = hess(nlp, nlp.meta.x0)
println("gx = $gx")
Expand All @@ -51,14 +51,14 @@ Let's do something a little more complex here, defining a function to try to
solve this problem through steepest descent method with Armijo search.
Namely, the method

1. Given ``x^0``, ``\varepsilon > 0``, and ``\eta \in (0,1)``. Set ``k = 0``;
2. If ``\Vert \nabla f(x^k) \Vert < \varepsilon`` STOP with ``x^* = x^k``;
3. Compute ``d^k = -\nabla f(x^k)``;
4. Compute ``\alpha_k \in (0,1]`` such that ``f(x^k + \alpha_kd^k) < f(x^k) + \alpha_k\eta \nabla f(x^k)^Td^k``
5. Define ``x^{k+1} = x^k + \alpha_kx^k``
6. Update ``k = k + 1`` and go to step 2.
1. Given $x^0$, $\varepsilon > 0$, and $\eta \in (0,1)$. Set $k = 0$;
2. If $\Vert \nabla f(x^k) \Vert < \varepsilon$ STOP with $x^* = x^k$;
3. Compute $d^k = -\nabla f(x^k)$;
4. Compute $\alpha_k \in (0,1]$ such that $f(x^k + \alpha_kd^k) < f(x^k) + \alpha_k\eta \nabla f(x^k)^Td^k$
5. Define $x^{k+1} = x^k + \alpha_kx^k$
6. Update $k = k + 1$ and go to step 2.

```@example adnlp
```julia
using LinearAlgebra

function steepest(nlp; itmax=100000, eta=1e-4, eps=1e-6, sigma=0.66)
Expand Down Expand Up @@ -99,7 +99,7 @@ println("iter = $iter")
Maybe this code is too complicated? If you're in a class you just want to show a
Newton step.

```@example adnlp
```julia
g(x) = grad(nlp, x)
H(x) = hess(nlp, x)
x = nlp.meta.x0
Expand All @@ -108,7 +108,7 @@ d = -H(x)\g(x)

or a few

```@example adnlp
```julia
for i = 1:5
global x
x = x - H(x)\g(x)
Expand All @@ -118,7 +118,7 @@ end

Also, notice how we can reuse the method.

```@example adnlp
```julia
f(x) = (x[1]^2 + x[2]^2 - 5)^2 + (x[1]*x[2] - 2)^2
x0 = [3.0; 2.0]
nlp = ADNLPModel(f, x0)
Expand All @@ -131,7 +131,7 @@ External models can be tested with `steepest` as well, as long as they implement
For constrained minimization, you need the constraints vector and bounds too.
Bounds on the variables can be passed through a new vector.

```@example adnlp2
```julia
using NLPModels, ADNLPModels # hide
f(x) = (x[1] - 1.0)^2 + 100*(x[2] - x[1]^2)^2
x0 = [-1.2; 1.0]
Expand All @@ -150,23 +150,23 @@ println("Jx = $(jac(nlp, nlp.meta.x0))")

In addition to the general nonlinear model, we can define the residual function for a
nonlinear least-squares problem. In other words, the objective function of the problem
is of the form ``f(x) = \tfrac{1}{2}\|F(x)\|^2``, and we can define the function ``F``
is of the form $f(x) = \tfrac{1}{2}\|F(x)\|^2$, and we can define the function $F$
and its derivatives.

A simple way to define an NLS problem is with `ADNLSModel`, which uses automatic
differentiation.

```@example nls
```julia
using NLPModels, ADNLPModels # hide
F(x) = [x[1] - 1.0; 10 * (x[2] - x[1]^2)]
x0 = [-1.2; 1.0]
nls = ADNLSModel(F, x0, 2) # 2 nonlinear equations
```

```@example nls
```julia
residual(nls, x0)
```

```@example nls
```julia
jac_residual(nls, x0)
```