@@ -36,15 +36,18 @@ best dealt with by other components of MathOptInterface.
3636## API overview
3737
3838The core element of the ` Nonlinear ` submodule is
39- [ ` Nonlinear.NonlinearData ` ] ( @ref ) :
39+ [ ` Nonlinear.Model ` ] ( @ref ) :
4040``` jldoctest nonlinear_developer
4141julia> const Nonlinear = MathOptInterface.Nonlinear;
4242
43- julia> data = Nonlinear.NonlinearData()
44- NonlinearData with available features:
45- * :ExprGraph
43+ julia> model = Nonlinear.Model()
44+ A Nonlinear.Model with:
45+ 0 objectives
46+ 0 parameters
47+ 0 expressions
48+ 0 constraints
4649```
47- [ ` Nonlinear.NonlinearData ` ] ( @ref ) is a mutable struct that stores all of the
50+ [ ` Nonlinear.Model ` ] ( @ref ) is a mutable struct that stores all of the
4851nonlinear information added to the model.
4952
5053### Decision variables
@@ -75,65 +78,126 @@ There are a number of restrictions on the input `Expr`:
7578Given an input expression, add an expression using
7679[ ` Nonlinear.add_expression ` ] ( @ref ) :
7780``` jldoctest nonlinear_developer
78- julia> expr = Nonlinear.add_expression(data , input)
81+ julia> expr = Nonlinear.add_expression(model , input)
7982MathOptInterface.Nonlinear.ExpressionIndex(1)
8083```
8184The return value, ` expr ` , is a [ ` Nonlinear.ExpressionIndex ` ] ( @ref ) that can
8285then be interpolated into other input expressions.
8386
87+ Looking again at ` model ` , we see:
88+ ``` jldoctest nonlinear_developer
89+ julia> model
90+ A Nonlinear.Model with:
91+ 0 objectives
92+ 0 parameters
93+ 1 expression
94+ 0 constraints
95+ ```
96+
8497### [ Parameters] (@id Nonlinear_Parameters)
8598
8699In addition to constant literals like ` 1 ` or ` 1.23 ` , you can create parameters.
87100Parameters are placeholders whose values can change before passing the
88101expression to the solver. Create a parameter using
89102[ ` Nonlinear.add_parameter ` ] ( @ref ) , which accepts a default value:
90103``` jldoctest nonlinear_developer
91- julia> p = Nonlinear.add_parameter(data , 1.23)
104+ julia> p = Nonlinear.add_parameter(model , 1.23)
92105MathOptInterface.Nonlinear.ParameterIndex(1)
93106```
94107The return value, ` p ` , is a [ ` Nonlinear.ParameterIndex ` ] ( @ref ) that can then be
95108interpolated into other input expressions.
96109
110+ Looking again at ` model ` , we see:
111+ ``` jldoctest nonlinear_developer
112+ julia> model
113+ A Nonlinear.Model with:
114+ 0 objectives
115+ 1 parameter
116+ 1 expression
117+ 0 constraints
118+ ```
119+
97120Update a parameter as follows:
98121``` jldoctest nonlinear_developer
99- julia> data [p]
122+ julia> model [p]
1001231.23
101124
102- julia> data [p] = 4.56
125+ julia> model [p] = 4.56
1031264.56
104127
105- julia> data [p]
128+ julia> model [p]
1061294.56
107130```
108131
109132### [ Objectives] (@id Nonlinear_Objectives)
110133
111134Set a nonlinear objective using [ ` Nonlinear.set_objective ` ] ( @ref ) :
112135``` jldoctest nonlinear_developer
113- julia> Nonlinear.set_objective(data, :($p + $expr + $x))
136+ julia> Nonlinear.set_objective(model, :($p + $expr + $x))
137+
138+ julia> model
139+ A Nonlinear.Model with:
140+ 1 objective
141+ 1 parameter
142+ 1 expression
143+ 0 constraints
114144```
145+
115146Clear a nonlinear objective by passing ` nothing ` :
116147``` jldoctest nonlinear_developer
117- julia> Nonlinear.set_objective(data, nothing)
148+ julia> Nonlinear.set_objective(model, nothing)
149+
150+ julia> model
151+ A Nonlinear.Model with:
152+ 0 objectives
153+ 1 parameter
154+ 1 expression
155+ 0 constraints
156+ ```
157+
158+ But we'll re-add the objective for later:
159+ ``` jldoctest nonlinear_developer
160+ julia> Nonlinear.set_objective(model, :($p + $expr + $x));
118161```
119162
120163### [ Constraints] (@id Nonlinear_Constraints)
121164
122165Add a constraint using [ ` Nonlinear.add_constraint ` ] ( @ref ) :
123166``` jldoctest nonlinear_developer
124- julia> c = Nonlinear.add_constraint(data , :(1 + sqrt($x) <= 2.0))
167+ julia> c = Nonlinear.add_constraint(model , :(1 + sqrt($x) <= 2.0))
125168MathOptInterface.Nonlinear.ConstraintIndex(1)
169+
170+ julia> model
171+ A Nonlinear.Model with:
172+ 1 objective
173+ 1 parameter
174+ 1 expression
175+ 1 constraint
126176```
127177The return value, ` c ` , is a [ ` Nonlinear.ConstraintIndex ` ] ( @ref ) that is a unique
128178identifier for the constraint. Interval constraints are also supported:
129179``` jldoctest nonlinear_developer
130- julia> c2 = Nonlinear.add_constraint(data , :(-1.0 <= 1 + sqrt($x) <= 2.0))
180+ julia> c2 = Nonlinear.add_constraint(model , :(-1.0 <= 1 + sqrt($x) <= 2.0))
131181MathOptInterface.Nonlinear.ConstraintIndex(2)
182+
183+ julia> model
184+ A Nonlinear.Model with:
185+ 1 objective
186+ 1 parameter
187+ 1 expression
188+ 2 constraints
132189```
133190
134191Delete a constraint using [ ` Nonlinear.delete ` ] ( @ref ) :
135192``` jldoctest nonlinear_developer
136- julia> Nonlinear.delete(data, c2)
193+ julia> Nonlinear.delete(model, c2)
194+
195+ julia> model
196+ A Nonlinear.Model with:
197+ 1 objective
198+ 1 parameter
199+ 1 expression
200+ 1 constraint
137201```
138202
139203### User-defined operators
@@ -150,11 +214,11 @@ Register a univariate user-defined operator using
150214julia> f(x) = 1 + sin(x)^2
151215f (generic function with 1 method)
152216
153- julia> Nonlinear.register_operator(data , :my_f, 1, f)
217+ julia> Nonlinear.register_operator(model , :my_f, 1, f)
154218```
155219Now, you can use ` :my_f ` in expressions:
156220``` jldoctest nonlinear_developer
157- julia> new_expr = Nonlinear.add_expression(data , :(my_f($x + 1)))
221+ julia> new_expr = Nonlinear.add_expression(model , :(my_f($x + 1)))
158222MathOptInterface.Nonlinear.ExpressionIndex(2)
159223```
160224By default, ` Nonlinear ` will compute first- and second-derivatives of the
@@ -164,14 +228,14 @@ which compute the respective derivative:
164228julia> f′(x) = 2 * sin(x) * cos(x)
165229f′ (generic function with 1 method)
166230
167- julia> Nonlinear.register_operator(data , :my_f2, 1, f, f′)
231+ julia> Nonlinear.register_operator(model , :my_f2, 1, f, f′)
168232```
169233or
170234``` jldoctest nonlinear_developer
171235julia> f′′(x) = 2 * (cos(x)^2 - sin(x)^2)
172236f′′ (generic function with 1 method)
173237
174- julia> Nonlinear.register_operator(data , :my_f3, 1, f, f′, f′′)
238+ julia> Nonlinear.register_operator(model , :my_f3, 1, f, f′, f′′)
175239```
176240
177241#### Multivariate operators
@@ -182,11 +246,11 @@ Register a multivariate user-defined operator using
182246julia> g(x...) = x[1]^2 + x[1] * x[2] + x[2]^2
183247g (generic function with 1 method)
184248
185- julia> Nonlinear.register_operator(data , :my_g, 2, g)
249+ julia> Nonlinear.register_operator(model , :my_g, 2, g)
186250```
187251Now, you can use ` :my_f ` in expressions:
188252``` jldoctest nonlinear_developer
189- julia> new_expr = Nonlinear.add_expression(data , :(my_g($x + 1, $x)))
253+ julia> new_expr = Nonlinear.add_expression(model , :(my_g($x + 1, $x)))
190254MathOptInterface.Nonlinear.ExpressionIndex(3)
191255```
192256By default, ` Nonlinear ` will compute the gradient of the registered
@@ -200,7 +264,7 @@ julia> function ∇g(ret, x...)
200264 end
201265∇g (generic function with 1 method)
202266
203- julia> Nonlinear.register_operator(data , :my_g2, 2, g, ∇g)
267+ julia> Nonlinear.register_operator(model , :my_g2, 2, g, ∇g)
204268```
205269
206270### [ MathOptInterface] (@id Nonlinear_MOI_interface)
@@ -209,57 +273,47 @@ MathOptInterface communicates the nonlinear portion of an optimization problem
209273to solvers using concrete subtypes of [ ` AbstractNLPEvaluator ` ] ( @ref ) , which
210274implement the [ Nonlinear programming] ( @ref ) API.
211275
212- [ ` Nonlinear.NonlinearData ` ] ( @ref ) is a subtype of [ ` AbstractNLPEvaluator ` ] ( @ref ) ,
213- but the functions of the [ Nonlinear programming] ( @ref ) API that it implements
214- depends upon the chosen [ ` Nonlinear.AbstractAutomaticDifferentiation ` ] (@ref
215- backend.
276+ Create an [ ` AbstractNLPEvaluator ` ] ( @ref ) from [ ` Nonlinear.Model ` ] ( @ref ) using
277+ [ ` Nonlinear.Evaluator ` ] ( @ref ) .
278+
279+ [ ` Nonlinear.Evaluator ` ] ( @ref ) requires an
280+ [ ` Nonlinear.AbstractAutomaticDifferentiation ` ] ( @ref ) backend and an ordered list
281+ of the variables that are included in the model.
216282
217283There following backends are available to choose from within MOI, although other
218284packages may add more options by sub-typing
219285[ ` Nonlinear.AbstractAutomaticDifferentiation ` ] ( @ref ) :
220286 * [ ` Nonlinear.ExprGraphOnly ` ] ( @ref )
221287
222- Set the differentiation backend using
223- ` Nonlinear.set_differentiation_backend ` ] ( @ref ) .
224-
225- If we set [ ` Nonlinear.ExprGraphOnly ` ] ( @ref ) , then we get access to ` :ExprGraph ` :
226288``` jldoctest nonlinear_developer
227- julia> Nonlinear.set_differentiation_backend(
228- data,
229- Nonlinear.ExprGraphOnly(),
230- [x],
231- )
232-
233- julia> data
234- NonlinearData with available features:
289+ julia> evaluator = Nonlinear.Evaluator(model, Nonlinear.ExprGraphOnly(), [x])
290+ Nonlinear.Evaluator with available features:
235291 * :ExprGraph
236292```
237-
238- [ ` Nonlinear.set_differentiation_backend ` ] ( @ref ) requires an ordered list of the
239- variables that are included in the model. This order corresponds to the order of
240- the primal decision vector ` x ` which is passed to the various functions in MOI's
241- nonlinear API.
293+ The functions of the [ Nonlinear programming] ( @ref ) API implemented by
294+ [ ` Nonlinear.Evaluator ` ] ( @ref ) depends upon the chosen
295+ [ ` Nonlinear.AbstractAutomaticDifferentiation ` ] (@ref backend.
242296
243297The ` :ExprGraph ` feature means we can call [ ` objective_expr ` ] ( @ref ) and
244298[ ` constraint_expr ` ] ( @ref ) to retrieve the expression graph of the problem.
245299However, we cannot call gradient terms such as
246300[ ` eval_objective_gradient ` ] ( @ref ) because [ ` Nonlinear.ExprGraphOnly ` ] ( @ref ) does
247301not have the capability to differentiate a nonlinear expression.
248302
249- Instead of passing [ ` AbstractNLPEvaluator ` ] ( @ref ) s directly to solvers,
303+ Instead of passing [ ` Nonlinear.Evaluator ` ] ( @ref ) directly to solvers,
250304MathOptInterface instead passes an [ ` NLPBlockData ` ] ( @ref ) , which wraps an
251- [ ` AbstractNLPEvaluator ` ] ( @ref ) and includes other information such as constraint
305+ [ ` Nonlinear.Evaluator ` ] ( @ref ) and includes other information such as constraint
252306bounds and whether the evaluator has a nonlinear objective. Create an
253- ` NLPBlockData ` ] ( @ref ) as follows:
307+ [ ` NLPBlockData ` ] ( @ref ) as follows:
254308``` jldoctest nonlinear_developer
255- julia> MOI.NLPBlockData(data );
309+ julia> MOI.NLPBlockData(evaluator );
256310```
257311
258312## Expression-graph representation
259313
260- [ ` Nonlinear.NonlinearData ` ] ( @ref ) stores nonlinear expressions in
261- [ ` Nonlinear.NonlinearExpression ` ] ( @ref ) s. This section explains the design of
262- the expression graph datastructure in [ ` Nonlinear.NonlinearExpression ` ] ( @ref ) .
314+ [ ` Nonlinear.Model ` ] ( @ref ) stores nonlinear expressions in
315+ [ ` Nonlinear.Expression ` ] ( @ref ) s. This section explains the design of
316+ the expression graph datastructure in [ ` Nonlinear.Expression ` ] ( @ref ) .
263317
264318Given a nonlinear function like ` f(x) = sin(x)^2 + x ` , a conceptual aid for
265319thinking about the graph representation of the expression is to convert it into
@@ -350,7 +404,7 @@ julia> struct Node
350404 index::Int
351405 end
352406
353- julia> struct NonlinearExpression
407+ julia> struct Expression
354408 nodes::Vector{Node}
355409 values::Vector{Float64}
356410 end
@@ -368,7 +422,7 @@ The `.parent` field of each node is the integer index of the parent node in
368422
369423Therefore, we can represent our function as:
370424``` jldoctest expr_graph
371- julia> expr = NonlinearExpression (
425+ julia> expr = Expression (
372426 [
373427 Node(NODE_CALL_MULTIVARIATE, 1, -1),
374428 Node(NODE_CALL_MULTIVARIATE, 2, 1),
@@ -399,8 +453,8 @@ evaluates all children nodes before their parent.
399453
400454### The design in practice
401455
402- In practice, ` Node ` and ` NonlinearExpression ` are exactly [ ` Nonlinear.Node ` ] ( @ref )
403- and [ ` Nonlinear.NonlinearExpression ` ] ( @ref ) . However, [ ` Nonlinear.NodeType ` ] ( @ref )
456+ In practice, ` Node ` and ` Expression ` are exactly [ ` Nonlinear.Node ` ] ( @ref )
457+ and [ ` Nonlinear.Expression ` ] ( @ref ) . However, [ ` Nonlinear.NodeType ` ] ( @ref )
404458has more fields to account for comparison operators such as ` :>= ` and ` :<= ` ,
405459logic operators such as ` :&& ` and ` :|| ` , nonlinear parameters, and nested
406460subexpressions.
@@ -412,6 +466,6 @@ operators and a vector of comparison operators. In addition to
412466[ ` Nonlinear.DEFAULT_MULTIVARIATE_OPERATORS ` ] ( @ref ) , you can register
413467user-defined functions using [ ` Nonlinear.register_operator ` ] ( @ref ) .
414468
415- [ ` Nonlinear.NonlinearData ` ] ( @ref ) is a struct that stores the
469+ [ ` Nonlinear.Model ` ] ( @ref ) is a struct that stores the
416470[ ` Nonlinear.OperatorRegistry ` ] ( @ref ) , as well as a list of parameters and
417471subexpressions in the model.
0 commit comments