@@ -15,8 +15,8 @@ DocTestFilters = [r"MathOptInterface|MOI"]
15
15
MathOptInterface.
16
16
17
17
The ` Nonlinear ` submodule contains data structures and functions for
18
- working with a nonlinear program in the form of an expression tree. This page
19
- explains the API and describes the rationale behind its design.
18
+ working with a nonlinear optimization problem in the form of an expression
19
+ graph. This page explains the API and describes the rationale behind its design.
20
20
21
21
## Standard form
22
22
@@ -49,12 +49,13 @@ nonlinear information added to the model.
49
49
50
50
### Decision variables
51
51
52
- Decision variables are represented by [ ` VariableIndex ` ] ( @ref ) s. The user is
53
- responsible for creating these.
52
+ Decision variables are represented by [ ` VariableIndex ` ] ( @ref ) es. The user is
53
+ responsible for creating these using ` MOI.VariableIndex(i) ` , where ` i ` is the
54
+ column associated with the variable.
54
55
55
56
### [ Expressions] (@id Nonlinear_Expressions)
56
57
57
- The input data- structure is a Julia ` Expr ` . The input expressions can
58
+ The input data structure is a Julia ` Expr ` . The input expressions can
58
59
incorporate [ ` VariableIndex ` ] ( @ref ) es, but these must be interpolated into
59
60
the expression with ` $ ` :
60
61
``` jldoctest nonlinear_developer
@@ -83,9 +84,9 @@ then be interpolated into other input expressions.
83
84
### [ Parameters] (@id Nonlinear_Parameters)
84
85
85
86
In addition to constant literals like ` 1 ` or ` 1.23 ` , you can create parameters.
86
- Parameter are constants that you can change before passing the expression to the
87
- solver. Create a parameter using [ ` Nonlinear.add_parameter ` ] ( @ref ) , which
88
- accepts a default value:
87
+ Parameters are placeholders whose values can change before passing the
88
+ expression to the solver. Create a parameter using
89
+ [ ` Nonlinear.add_parameter ` ] ( @ref ) , which accepts a default value:
89
90
``` jldoctest nonlinear_developer
90
91
julia> p = Nonlinear.add_parameter(data, 1.23)
91
92
MathOptInterface.Nonlinear.ParameterIndex(1)
@@ -111,6 +112,10 @@ Set a nonlinear objective using [`Nonlinear.set_objective`](@ref):
111
112
``` jldoctest nonlinear_developer
112
113
julia> Nonlinear.set_objective(data, :($p + $expr + $x))
113
114
```
115
+ Clear a nonlinear objective by passing ` nothing ` :
116
+ ``` jldoctest nonlinear_developer
117
+ julia> Nonlinear.set_objective(data, nothing)
118
+ ```
114
119
115
120
### [ Constraints] (@id Nonlinear_Constraints)
116
121
@@ -186,7 +191,7 @@ MathOptInterface.Nonlinear.ExpressionIndex(3)
186
191
```
187
192
By default, ` Nonlinear ` will compute the gradient of the registered
188
193
operator using ` ForwardDiff.jl ` . (Hessian information is not supported.)
189
- Over-ride this by passing a function to compute the gradient:
194
+ Override this by passing a function to compute the gradient:
190
195
``` jldoctest nonlinear_developer
191
196
julia> function ∇g(ret, x...)
192
197
ret[1] = 2 * x[1] + x[2]
@@ -200,43 +205,61 @@ julia> Nonlinear.register_operator(data, :my_g2, 2, g, ∇g)
200
205
201
206
### [ MathOptInterface] (@id Nonlinear_MOI_interface)
202
207
203
- ` Nonlinear ` implements the MathOptInterface API to allow solvers to query the
204
- function and derivative information of our nonlinear model ` data ` . However,
205
- before we can call [ ` initialize ` ] ( @ref ) , we need to set an
206
- [ ` Nonlinear.AbstractAutomaticDifferentiation ` ] ( @ref ) .
208
+ MathOptInterface communicates the nonlinear portion of an optimization problem
209
+ to solvers using concrete subtypes of [ ` AbstractNLPEvaluator ` ] ( @ref ) , which
210
+ implement the [ Nonlinear programming] ( @ref ) API.
211
+
212
+ [ ` NonlinearData ` ] ( @ref ) is a subtype of [ ` AbstractNLPEvaluator ` ] ( @ref ) , but the
213
+ functions of the [ Nonlinear programming] ( @ref ) API that it implements depends
214
+ upon the chosen [ ` Nonlinear.AbstractAutomaticDifferentiation ` ] ( @ref ) backend.
207
215
208
216
There are two to choose from within MOI, although other packages may add more
209
217
options by sub-typing [ ` Nonlinear.AbstractAutomaticDifferentiation ` ] ( @ref ) :
210
218
* [ ` Nonlinear.ExprGraphOnly ` ] ( @ref )
211
219
220
+ Set the differentiation backend using [ ` Nonlinear.set_differentiation_backend ` ] ( @ref ) .
212
221
If we set [ ` Nonlinear.ExprGraphOnly ` ] ( @ref ) , then we get access to ` :ExprGraph ` :
213
222
``` jldoctest nonlinear_developer
214
- julia> Nonlinear.set_differentiation_backend(data, Nonlinear.ExprGraphOnly(), [x])
223
+ julia> Nonlinear.set_differentiation_backend(
224
+ data,
225
+ Nonlinear.ExprGraphOnly(),
226
+ [x],
227
+ )
215
228
216
229
julia> data
217
230
NonlinearData with available features:
218
231
* :ExprGraph
219
232
```
220
- !!! note
221
- [ ` Nonlinear.set_differentiation_backend ` ] ( @ref ) requires an ordered list of
222
- the variables that are included in the model. This order corresponds to the
223
- the order of the primal decision vector ` x ` which is passed to the various
224
- functions in MOI's nonlinear API.
233
+
234
+ [ ` Nonlinear.set_differentiation_backend ` ] ( @ref ) requires an ordered list of the
235
+ variables that are included in the model. This order corresponds to the order of
236
+ the primal decision vector ` x ` which is passed to the various functions in MOI's
237
+ nonlinear API.
225
238
226
239
The ` :ExprGraph ` feature means we can call [ ` objective_expr ` ] ( @ref ) and
227
240
[ ` constraint_expr ` ] ( @ref ) to retrieve the expression graph of the problem.
228
241
However, we cannot call gradient terms such as
229
242
[ ` eval_objective_gradient ` ] ( @ref ) because [ ` Nonlinear.ExprGraphOnly ` ] ( @ref ) does
230
- not know how to differentiate a nonlinear expression.
243
+ not have the capability to differentiate a nonlinear expression.
244
+
245
+ Instead of passing [ ` AbstractNLPEvaluator ` ] ( @ref ) s directly to solvers,
246
+ MathOptInterface instead passes an [ ` NLPBlockData ` ] ( @ref ) , which wraps an
247
+ [ ` AbstractNLPEvaluator ` ] ( @ref ) and includes other information such as constraint
248
+ bounds and whether the evaluator has a nonlinear objective. Create an
249
+ ` NLPBlockData ` ] ( @ref ) as follows:
250
+ ``` jldoctest nonlinear_developer
251
+ julia> MOI.NLPBlockData(data)
252
+ ```
231
253
232
254
## Expression-graph representation
233
255
234
256
[ ` Nonlinear.NonlinearData ` ] ( @ref ) stores nonlinear expressions in
235
257
[ ` Nonlinear.NonlinearExpression ` ] ( @ref ) s. This section explains the design of
236
258
the expression graph datastructure in [ ` Nonlinear.NonlinearExpression ` ] ( @ref ) .
237
259
238
- Given a nonlinear function like ` f(x) = sin(x)^2 + x ` , the first step is to
239
- convert it into [ Polish prefix notation] ( https://en.wikipedia.org/wiki/Polish_notation ) :
260
+ Given a nonlinear function like ` f(x) = sin(x)^2 + x ` , a conceptual aid for
261
+ thinking about the graph representation of the expression is to convert it into
262
+ [ Polish prefix notation] ( https://en.wikipedia.org/wiki/Polish_notation ) :
240
263
```
241
264
f(x, y) = (+ (^ (sin x) 2) x)
242
265
```
@@ -365,7 +388,7 @@ each expression, `nodes` and `values`, as well as two constant vectors for the
365
388
For our third goal, it is not easy to identify the children of a node, but it is
366
389
easy to identify the _ parent_ of any node. Therefore, we can use
367
390
[ ` Nonlinear.adjacency_matrix ` ] ( @ref ) to compute a sparse matrix that maps
368
- children to their parents .
391
+ parents to their children .
369
392
370
393
The tape is also ordered topologically, so that a reverse pass of the nodes
371
394
evaluates all children nodes before their parent.
@@ -374,7 +397,7 @@ evaluates all children nodes before their parent.
374
397
375
398
In practice, ` Node ` and ` NonlinearExpression ` are exactly [ ` Nonlinear.Node ` ] ( @ref )
376
399
and [ ` Nonlinear.NonlinearExpression ` ] ( @ref ) . However, [ ` Nonlinear.NodeType ` ] ( @ref )
377
- has more terms to account for comparison operators such as ` :>= ` and ` :<= ` ,
400
+ has more fields to account for comparison operators such as ` :>= ` and ` :<= ` ,
378
401
logic operators such as ` :&& ` and ` :|| ` , nonlinear parameters, and nested
379
402
subexpressions.
380
403
0 commit comments