Nonlinear Modeling

More information can be found in the Nonlinear section of the manual.

MathOptInterface.NonlinearModule
Nonlinear
Warning

The Nonlinear submodule is experimental. Until this message is removed, breaking changes may be introduced in any minor or patch release of MathOptInterface.

MathOptInterface.Nonlinear.ModelType
Model()

The core datastructure for representing a nonlinear optimization problem.

It has the following fields:

  • objective::Union{Nothing,Expression} : holds the nonlinear objective function, if one exists, otherwise nothing.
  • expressions::Vector{Expression} : a vector of expressions in the model.
  • constraints::OrderedDict{ConstraintIndex,Constraint} : a map from ConstraintIndex to the corresponding Constraint. An OrderedDict is used instead of a Vector to support constraint deletion.
  • parameters::Vector{Float64} : holds the current values of the parameters.
  • operators::OperatorRegistry : stores the operators used in the model.

Expressions

MathOptInterface.Nonlinear.add_expressionFunction
add_expression(model::Model, expr)::ExpressionIndex

Parse expr into a Expression and add to model. Returns an ExpressionIndex that can be interpolated into other input expressions.

expr must be a type that is supported by parse_expression.

Examples

model = Model()
x = MOI.VariableIndex(1)
ex = add_expression(model, :($x^2 + 1))
set_objective(model, :(sqrt($ex)))

Parameters

MathOptInterface.Nonlinear.ParameterIndexType
ParameterIndex

An index to a nonlinear parameter that is returned by add_parameter. Given data::Model and p::ParameterIndex, use data[p] to retrieve the current value of the parameter and data[p] = value to set a new value.

MathOptInterface.Nonlinear.add_parameterFunction
add_parameter(model::Model, value::Float64)::ParameterIndex

Add a new parameter to model with the default value value. Returns a ParameterIndex that can be interpolated into other input expressions and used to modify the value of the parameter.

Examples

model = Model()
x = MOI.VariableIndex(1)
p = add_parameter(model, 1.2)
c = add_constraint(model, :($x^2 - $p), MOI.LessThan(0.0))

Objectives

MathOptInterface.Nonlinear.set_objectiveFunction
set_objective(model::Model, obj)::Nothing

Parse obj into a Expression and set as the objective function of model.

obj must be a type that is supported by parse_expression.

To remove the objective, pass nothing.

Examples

model = Model()
x = MOI.VariableIndex(1)
set_objective(model, :($x^2 + 1))
set_objective(model, x)
set_objective(model, nothing)

Constraints

MathOptInterface.Nonlinear.add_constraintFunction
add_constraint(
    model::Model,
    func,
    set::Union{
        MOI.GreaterThan{Float64},
        MOI.LessThan{Float64},
        MOI.Interval{Float64},
        MOI.EqualTo{Float64},
    },
)

Parse func and set into a Constraint and add to model. Returns a ConstraintIndex that can be used to delete the constraint or query solution information.

Examples

model = Model()
x = MOI.VariableIndex(1)
c = add_constraint(model, :($x^2), MOI.LessThan(1.0))
MathOptInterface.Nonlinear.deleteFunction
delete(model::Model, c::ConstraintIndex)::Nothing

Delete the constraint index c from model.

Examples

model = Model()
x = MOI.VariableIndex(1)
c = add_constraint(model, :($x^2), MOI.LessThan(1.0))
delete(model, c)

User-defined operators

MathOptInterface.Nonlinear.register_operatorFunction
register_operator(
    model::Model,
    op::Symbol,
    nargs::Int,
    f::Function,
    [∇f::Function],
    [∇²f::Function],
)

Register the user-defined operator op with nargs input arguments in model.

Univariate functions

  • f(x::T)::T must be a function that takes a single input argument x and returns the function evaluated at x. If ∇f and ∇²f are not provided, f must support any Real input type T.
  • ∇f(x::T)::T is a function that takes a single input argument x and returns the first derivative of f with respect to x. If ∇²f is not provided, ∇f must support any Real input type T.
  • ∇²f(x::T)::T is a function that takes a single input argument x and returns the second derivative of f with respect to x.

Multivariate functions

  • f(x::T...)::T must be a function that takes a nargs input arguments x and returns the function evaluated at x. If ∇f and ∇²f are not provided, f must support any Real input type T.
  • ∇f(g::AbstractVector{T}, x::T...)::T is a function that takes a cache vector g of length length(x), and fills each element g[i] with the partial derivative of f with respect to x[i].
  • ∇²f(H::AbstractMatrix, x::T...)::T is a function that takes a matrix H and fills the lower-triangular components H[i, j] with the Hessian of f with respect to x[i] and x[j] for i >= j.

Notes for multivariate Hessians

  • H has size(H) == (length(x), length(x)), but you must not access elements H[i, j] for i > j.
  • H is dense, but you do not need to fill structural zeros.
MathOptInterface.Nonlinear.check_return_typeFunction
check_return_type(::Type{T}, ret::S) where {T,S}

Overload this method for new types S to throw an informative error if a user-defined function returns the type S instead of T.

MathOptInterface.Nonlinear.eval_multivariate_gradientFunction
eval_multivariate_gradient(
    registry::OperatorRegistry,
    op::Symbol,
    g::AbstractVector{T},
    x::AbstractVector{T},
) where {T}

Evaluate the gradient of operator g .= ∇op(x), where op is a multivariate function in registry.

MathOptInterface.Nonlinear.eval_multivariate_hessianFunction
eval_multivariate_hessian(
    registry::OperatorRegistry,
    op::Symbol,
    H::AbstractMatrix,
    x::AbstractVector{T},
) where {T}

Evaluate the Hessian of operator ∇²op(x), where op is a multivariate function in registry.

The Hessian is stored in the lower-triangular part of the matrix H.

Note

Implementations of the Hessian operators will not fill structural zeros. Therefore, before calling this function you should pre-populate the matrix H with 0.

Automatic-differentiation backends

MathOptInterface.Nonlinear.EvaluatorType
Evaluator(
    model::Model,
    backend::AbstractAutomaticDifferentiation,
    ordered_variables::Vector{MOI.VariableIndex},
)

Create Evaluator, a subtype of MOI.AbstractNLPEvaluator, from Model.

MathOptInterface.Nonlinear.ExprGraphOnlyType
ExprGraphOnly() <: AbstractAutomaticDifferentiation

The default implementation of AbstractAutomaticDifferentiation. The only supported feature is :ExprGraph.

MathOptInterface.Nonlinear.SparseReverseModeType
SparseReverseMode() <: AbstractAutomaticDifferentiation

An implementation of AbstractAutomaticDifferentiation that uses sparse reverse-mode automatic differentiation to compute derivatives. Supports all features in the MOI nonlinear interface.

Data-structure

MathOptInterface.Nonlinear.NodeType
struct Node
    type::NodeType
    index::Int
    parent::Int
end

A single node in a nonlinear expression tree. Used by Expression.

See the MathOptInterface documentation for information on how the nodes and values form an expression tree.

MathOptInterface.Nonlinear.NodeTypeType
NodeType

An enum describing the possible node types. Each Node has a .index field, which should be interpreted as follows:

  • NODE_CALL_MULTIVARIATE: the index into operators.multivariate_operators
  • NODE_CALL_UNIVARIATE: the index into operators.univariate_operators
  • NODE_LOGIC: the index into operators.logic_operators
  • NODE_COMPARISON: the index into operators.comparison_operators
  • NODE_MOI_VARIABLE: the value of MOI.VariableIndex(index) in the user's space of the model.
  • NODE_VARIABLE: the 1-based index of the internal vector
  • NODE_VALUE: the index into the .values field of Expression
  • NODE_PARAMETER: the index into data.parameters
  • NODE_SUBEXPRESSION: the index into data.expressions
MathOptInterface.Nonlinear.ExpressionType
struct Expression
    nodes::Vector{Node}
    values::Vector{Float64}
end

The core type that represents a nonlinear expression. See the MathOptInterface documentation for information on how the nodes and values form an expression tree.

MathOptInterface.Nonlinear.ConstraintType
struct Constraint
    expression::Expression
    set::Union{
        MOI.LessThan{Float64},
        MOI.GreaterThan{Float64},
        MOI.EqualTo{Float64},
        MOI.Interval{Float64},
    }
end

A type to hold information relating to the nonlinear constraint f(x) in S, where f(x) is defined by .expression, and S is .set.

MathOptInterface.Nonlinear.adjacency_matrixFunction
adjacency_matrix(nodes::Vector{Node})

Compute the sparse adjacency matrix describing the parent-child relationships in nodes.

The element (i, j) is true if there is an edge from node[j] to node[i]. Since we get a column-oriented matrix, this gives us a fast way to look up the edges leaving any node (i.e., the children).

MathOptInterface.Nonlinear.parse_expressionFunction
parse_expression(data::Model, input)::Expression

Parse input into a Expression.

parse_expression(
    data::Model,
    expr::Expression,
    input::Any,
    parent_index::Int,
)::Expression

Parse input into a Expression, and add it to expr as a child of expr.nodes[parent_index]. Existing subexpressions and parameters are stored in data.

You can extend parsing support to new types of objects by overloading this method with a different type on input::Any.

MathOptInterface.Nonlinear.convert_to_exprFunction
convert_to_expr(data::Model, expr::Expression)

Convert the Expression expr into a Julia Expr.

convert_to_expr(
    evaluator::Evaluator,
    expr::Expression;
    moi_output_format::Bool,
)

Convert the Expression expr into a Julia Expr.

If moi_output_format = true:

  • subexpressions will be converted to Julia Expr and substituted into the output expression.
  • the current value of each parameter will be interpolated into the expression
  • variables will be represented in the form x[MOI.VariableIndex(i)]

If moi_output_format = false:

Warning

To use moi_output_format = true, you must have first called MOI.initialize with :ExprGraph as a requested feature.

MathOptInterface.Nonlinear.ordinal_indexFunction
ordinal_index(evaluator::Evaluator, c::ConstraintIndex)::Int

Return the 1-indexed value of the constraint index c in evaluator.

Examples

model = Model()
x = MOI.VariableIndex(1)
c1 = add_constraint(model, :($x^2), MOI.LessThan(1.0))
c2 = add_constraint(model, :($x^2), MOI.LessThan(1.0))
evaluator = Evaluator(model)
MOI.initialize(evaluator, Symbol[])
ordinal_index(evaluator, c2)  # Returns 2
delete(model, c1)
evaluator = Evaluator(model)
MOI.initialize(evaluator, Symbol[])
ordinal_index(model, c2)  # Returns 1