API Reference
[Some introduction to API. List basic standalone methods.]
Attributes
List of attribute categories.
MathOptInterface.AbstractOptimizerAttribute
— TypeAbstractOptimizerAttribute
Abstract supertype for attribute objects that can be used to set or get attributes (properties) of the optimizer.
Note
The difference between AbstractOptimizerAttribute
and AbstractModelAttribute
lies in the behavior of is_empty
, empty!
and copy_to
. Typically optimizer attributes only affect how the model is solved.
MathOptInterface.AbstractModelAttribute
— TypeAbstractModelAttribute
Abstract supertype for attribute objects that can be used to set or get attributes (properties) of the model.
MathOptInterface.AbstractVariableAttribute
— TypeAbstractVariableAttribute
Abstract supertype for attribute objects that can be used to set or get attributes (properties) of variables in the model.
MathOptInterface.AbstractConstraintAttribute
— TypeAbstractConstraintAttribute
Abstract supertype for attribute objects that can be used to set or get attributes (properties) of constraints in the model.
Attributes can be set in different ways:
- it is either set when the model is created like
SolverName
andRawSolver
, - or explicitly when the model is copied like
ObjectiveSense
, - or implicitly, e.g.,
NumberOfVariables
is implicitly set byadd_variable
andConstraintFunction
is implicitly set byadd_constraint
. - or it is set to contain the result of the optimization during
optimize!
likeVariablePrimal
.
The following functions allow to distinguish between some of these different categories:
MathOptInterface.is_set_by_optimize
— Functionis_set_by_optimize(::AnyAttribute)
Return a Bool
indicating whether the value of the attribute is modified during an optimize!
call, that is, the attribute is used to query the result of the optimization.
Important note when defining new attributes
This function returns false
by default so it should be implemented for attributes that are modified by optimize!
.
MathOptInterface.is_copyable
— Functionis_copyable(::AnyAttribute)
Return a Bool
indicating whether the value of the attribute may be copied during copy_to
using set
.
Important note when defining new attributes
By default is_copyable(attr)
returns !is_set_by_optimize(attr)
. A specific method should be defined for attributes which are copied indirectly during copy_to
. For instance, both is_copyable
and is_set_by_optimize
return false
for the following attributes:
ListOfOptimizerAttributesSet
,ListOfModelAttributesSet
,ListOfConstraintAttributesSet
andListOfVariableAttributesSet
.SolverName
andRawSolver
: these attributes cannot be set.NumberOfVariables
andListOfVariableIndices
: these attributes are set indirectly byadd_variable
andadd_variables
.ObjectiveFunctionType
: this attribute is set indirectly when setting theObjectiveFunction
attribute.NumberOfConstraints
,ListOfConstraintIndices
,ListOfConstraints
,CanonicalConstraintFunction
,ConstraintFunction
andConstraintSet
: these attributes are set indirectly byadd_constraint
andadd_constraints
.
Functions for getting and setting attributes.
MathOptInterface.get
— Functionget(optimizer::AbstractOptimizer, attr::AbstractOptimizerAttribute)
Return an attribute attr
of the optimizer optimizer
.
get(model::ModelLike, attr::AbstractModelAttribute)
Return an attribute attr
of the model model
.
get(model::ModelLike, attr::AbstractVariableAttribute, v::VariableIndex)
If the attribute attr
is set for the variable v
in the model model
, return its value, return nothing
otherwise. If the attribute attr
is not supported by model
then an error should be thrown instead of returning nothing
.
get(model::ModelLike, attr::AbstractVariableAttribute, v::Vector{VariableIndex})
Return a vector of attributes corresponding to each variable in the collection v
in the model model
.
get(model::ModelLike, attr::AbstractConstraintAttribute, c::ConstraintIndex)
If the attribute attr
is set for the constraint c
in the model model
, return its value, return nothing
otherwise. If the attribute attr
is not supported by model
then an error should be thrown instead of returning nothing
.
get(model::ModelLike, attr::AbstractConstraintAttribute, c::Vector{ConstraintIndex{F,S}})
Return a vector of attributes corresponding to each constraint in the collection c
in the model model
.
get(model::ModelLike, ::Type{VariableIndex}, name::String)
If a variable with name name
exists in the model model
, return the corresponding index, otherwise return nothing
. Errors if two variables have the same name.
get(model::ModelLike, ::Type{ConstraintIndex{F,S}}, name::String) where {F<:AbstractFunction,S<:AbstractSet}
If an F
-in-S
constraint with name name
exists in the model model
, return the corresponding index, otherwise return nothing
. Errors if two constraints have the same name.
get(model::ModelLike, ::Type{ConstraintIndex}, name::String)
If any constraint with name name
exists in the model model
, return the corresponding index, otherwise return nothing
. This version is available for convenience but may incur a performance penalty because it is not type stable. Errors if two constraints have the same name.
Examples
get(model, ObjectiveValue())
get(model, VariablePrimal(), ref)
get(model, VariablePrimal(5), [ref1, ref2])
get(model, OtherAttribute("something specific to cplex"))
get(model, VariableIndex, "var1")
get(model, ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}, "con1")
get(model, ConstraintIndex, "con1")
MathOptInterface.get!
— Functionget!(output, model::ModelLike, args...)
An in-place version of get
. The signature matches that of get
except that the the result is placed in the vector output
.
MathOptInterface.set
— Functionset(optimizer::AbstractOptimizer, attr::AbstractOptimizerAttribute, value)
Assign value
to the attribute attr
of the optimizer optimizer
.
set(model::ModelLike, attr::AbstractModelAttribute, value)
Assign value
to the attribute attr
of the model model
.
set(model::ModelLike, attr::AbstractVariableAttribute, v::VariableIndex, value)
Assign value
to the attribute attr
of variable v
in model model
.
set(model::ModelLike, attr::AbstractVariableAttribute, v::Vector{VariableIndex}, vector_of_values)
Assign a value respectively to the attribute attr
of each variable in the collection v
in model model
.
set(model::ModelLike, attr::AbstractConstraintAttribute, c::ConstraintIndex, value)
Assign a value to the attribute attr
of constraint c
in model model
.
set(model::ModelLike, attr::AbstractConstraintAttribute, c::Vector{ConstraintIndex{F,S}}, vector_of_values)
Assign a value respectively to the attribute attr
of each constraint in the collection c
in model model
.
An UnsupportedAttribute
error is thrown if model
does not support the attribute attr
(see supports
) and a SetAttributeNotAllowed
error is thrown if it supports the attribute attr
but it cannot be set.
Replace set in a constraint
set(model::ModelLike, ::ConstraintSet, c::ConstraintIndex{F,S}, set::S)
Change the set of constraint c
to the new set set
which should be of the same type as the original set.
Examples
If c
is a ConstraintIndex{F,Interval}
set(model, ConstraintSet(), c, Interval(0, 5))
set(model, ConstraintSet(), c, GreaterThan(0.0)) # Error
Replace function in a constraint
set(model::ModelLike, ::ConstraintFunction, c::ConstraintIndex{F,S}, func::F)
Replace the function in constraint c
with func
. F
must match the original function type used to define the constraint.
Note
Setting the constraint function is not allowed if F
is SingleVariable
, it throws a SettingSingleVariableFunctionNotAllowed
error. Indeed, it would require changing the index c
as the index of SingleVariable
constraints should be the same as the index of the variable.
Examples
If c
is a ConstraintIndex{ScalarAffineFunction,S}
and v1
and v2
are VariableIndex
objects,
set(model, ConstraintFunction(), c,
ScalarAffineFunction(ScalarAffineTerm.([1.0, 2.0], [v1, v2]), 5.0))
set(model, ConstraintFunction(), c, SingleVariable(v1)) # Error
MathOptInterface.supports
— Functionsupports(model::ModelLike, sub::AbstractSubmittable)::Bool
Return a Bool
indicating whether model
supports the submittable sub
.
supports(model::ModelLike, attr::AbstractOptimizerAttribute)::Bool
Return a Bool
indicating whether model
supports the optimizer attribute attr
. That is, it returns false
if copy_to(model, src)
shows a warning in case attr
is in the ListOfOptimizerAttributesSet
of src
; see copy_to
for more details on how unsupported optimizer attributes are handled in copy.
supports(model::ModelLike, attr::AbstractModelAttribute)::Bool
Return a Bool
indicating whether model
supports the model attribute attr
. That is, it returns false
if copy_to(model, src)
cannot be performed in case attr
is in the ListOfModelAttributesSet
of src
.
supports(model::ModelLike, attr::AbstractVariableAttribute, ::Type{VariableIndex})::Bool
Return a Bool
indicating whether model
supports the variable attribute attr
. That is, it returns false
if copy_to(model, src)
cannot be performed in case attr
is in the ListOfVariableAttributesSet
of src
.
supports(model::ModelLike, attr::AbstractConstraintAttribute, ::Type{ConstraintIndex{F,S}})::Bool where {F,S}
Return a Bool
indicating whether model
supports the constraint attribute attr
applied to an F
-in-S
constraint. That is, it returns false
if copy_to(model, src)
cannot be performed in case attr
is in the ListOfConstraintAttributesSet
of src
.
For all five methods, if the attribute is only not supported in specific circumstances, it should still return true
.
Note that supports
is only defined for attributes for which is_copyable
returns true
as other attributes do not appear in the list of attributes set obtained by ListOf...AttributesSet
.
Fallbacks
The value of some attributes can be inferred from the value of other attributes. For instance, the value of ObjectiveValue
can be computed using ObjectiveFunction
and VariablePrimal
. When a solver gives access to the objective value, it is better to return this value but otherwise, Utilities.get_fallback
can be used.
function MOI.get(optimizer::Optimizer, attr::MOI.ObjectiveValue)
return MOI.Utilities.get_fallback(optimizer, attr)
end
MathOptInterface.Utilities.get_fallback
— Functionget_fallback(model::MOI.ModelLike, ::MOI.ObjectiveValue)
Compute the objective function value using the VariablePrimal
results and the ObjectiveFunction
value.
get_fallback(model::MOI.ModelLike, ::MOI.DualObjectiveValue, T::Type)::T
Compute the dual objective value of type T
using the ConstraintDual
results and the ConstraintFunction
and ConstraintSet
values. Note that the nonlinear part of the model is ignored.
get_fallback(model::MOI.ModelLike, ::MOI.ConstraintPrimal,
constraint_index::MOI.ConstraintIndex)
Compute the value of the function of the constraint of index constraint_index
using the VariablePrimal
results and the ConstraintFunction
values.
get_fallback(model::MOI.ModelLike, attr::MOI.ConstraintDual,
ci::MOI.ConstraintIndex{Union{MOI.SingleVariable,
MOI.VectorOfVariables}})
Compute the dual of the constraint of index ci
using the ConstraintDual
of other constraints and the ConstraintFunction
values. Throws an error if some constraints are quadratic or if there is one another MOI.SingleVariable
-in-S
or MOI.VectorOfVariables
-in-S
constraint with one of the variables in the function of the constraint ci
.
Submit
Objects may be submitted to an optimizer using submit
.
MathOptInterface.AbstractSubmittable
— TypeAbstractSubmittable
Abstract supertype for objects that can be submitted to the model.
MathOptInterface.submit
— Functionsubmit(optimizer::AbstractOptimizer, sub::AbstractSubmittable,
values...)::Nothing
Submit values
to the submittable sub
of the optimizer optimizer
.
An UnsupportedSubmittable
error is thrown if model
does not support the attribute attr
(see supports
) and a SubmitNotAllowed
error is thrown if it supports the submittable sub
but it cannot be submitted.
List of submittables
MathOptInterface.LazyConstraint
— TypeLazyConstraint(callback_data)
Lazy constraint func
-in-set
submitted as func, set
. The optimal solution returned by VariablePrimal
will satisfy all lazy constraints that have been submitted.
This can be submitted only from the LazyConstraintCallback
. The field callback_data
is a solver-specific callback type that is passed as the argument to the feasible solution callback.
Examples
Suppose fx = MOI.SingleVariable(x)
and fx = MOI.SingleVariable(y)
where x
and y
are VariableIndex
s of optimizer
. To add a LazyConstraint
for 2x + 3y <= 1
, write
func = 2.0fx + 3.0fy
set = MOI.LessThan(1.0)
MOI.submit(optimizer, MOI.LazyConstraint(callback_data), func, set)
inside a LazyConstraintCallback
of data callback_data
.
MathOptInterface.HeuristicSolutionStatus
— TypeHeuristicSolutionStatus
An Enum of possible return values for submit
with HeuristicSolution
. This informs whether the heuristic solution was accepted or rejected. Possible values are:
HEURISTIC_SOLUTION_ACCEPTED
: The heuristic solution was accepted.HEURISTIC_SOLUTION_REJECTED
: The heuristic solution was rejected.HEURISTIC_SOLUTION_UNKNOWN
: No information available on the acceptance.
MathOptInterface.HeuristicSolution
— TypeHeuristicSolution(callback_data)
Heuristically obtained feasible solution. The solution is submitted as variables, values
where values[i]
gives the value of variables[i]
, similarly to set
. The submit
call returns a HeuristicSolutionStatus
indicating whether the provided solution was accepted or rejected.
This can be submitted only from the HeuristicCallback
. The field callback_data
is a solver-specific callback type that is passed as the argument to the heuristic callback.
Some solvers require a complete solution, others only partial solutions.
MathOptInterface.UserCut
— TypeUserCut(callback_data)
Constraint func
-to-set
suggested to help the solver detect the solution given by CallbackVariablePrimal
as infeasible. The cut is submitted as func, set
. Typically CallbackVariablePrimal
will violate integrality constraints, and a cut would be of the form ScalarAffineFunction
-in-LessThan
or ScalarAffineFunction
-in-GreaterThan
. Note that, as opposed to LazyConstraint
, the provided constraint cannot modify the feasible set, the constraint should be redundant, e.g., it may be a consequence of affine and integrality constraints.
This can be submitted only from the UserCutCallback
. The field callback_data
is a solver-specific callback type that is passed as the argument to the infeasible solution callback.
Note that the solver may silently ignore the provided constraint.
Model Interface
MathOptInterface.ModelLike
— TypeModelLike
Abstract supertype for objects that implement the "Model" interface for defining an optimization problem.
MathOptInterface.is_empty
— Functionis_empty(model::ModelLike)
Returns false
if the model
has any model attribute set or has any variables or constraints. Note that an empty model can have optimizer attributes set.
MathOptInterface.empty!
— Functionempty!(model::ModelLike)
Empty the model, that is, remove all variables, constraints and model attributes but not optimizer attributes.
MathOptInterface.write_to_file
— Functionwrite_to_file(model::ModelLike, filename::String)
Writes the current model data to the given file. Supported file types depend on the model type.
MathOptInterface.read_from_file
— Functionread_from_file(model::ModelLike, filename::String)
Read the file filename
into the model model
. If model
is non-empty, this may throw an error.
Supported file types depend on the model type.
Note
Once the contents of the file are loaded into the model, users can query the variables via get(model, ListOfVariableIndices())
. However, some filetypes, such as LP files, do not maintain an explicit ordering of the variables. Therefore, the returned list may be in an arbitrary order. To avoid depending on the order of the indices, users should look up each variable index by name: get(model, VariableIndex, "name")
.
Copying
MathOptInterface.copy_to
— Functioncopy_to(dest::ModelLike, src::ModelLike; copy_names=true, warn_attributes=true)
Copy the model from src
into dest
. The target dest
is emptied, and all previous indices to variables or constraints in dest
are invalidated. Returns a dictionary-like object that translates variable and constraint indices from the src
model to the corresponding indices in the dest
model.
If copy_names
is false
, the Name
, VariableName
and ConstraintName
attributes are not copied even if they are set in src
. If a constraint that is copied from src
is not supported by dest
then an UnsupportedConstraint
error is thrown. Similarly, if a model, variable or constraint attribute that is copied from src
is not supported by dest
then an UnsupportedAttribute
error is thrown. Unsupported optimizer attributes are treated differently:
- If
warn_attributes
istrue
, a warning is displayed, otherwise, - the attribute is silently ignored.
Example
# Given empty `ModelLike` objects `src` and `dest`.
x = add_variable(src)
is_valid(src, x) # true
is_valid(dest, x) # false (`dest` has no variables)
index_map = copy_to(dest, src)
is_valid(dest, x) # false (unless index_map[x] == x)
is_valid(dest, index_map[x]) # true
List of model attributes
MathOptInterface.Name
— TypeName()
A model attribute for the string identifying the model. It has a default value of ""
if not set`.
MathOptInterface.ObjectiveSense
— TypeObjectiveSense()
A model attribute for the objective sense of the objective function, which must be an OptimizationSense
: MIN_SENSE
, MAX_SENSE
, or FEASIBILITY_SENSE
. The default is FEASIBILITY_SENSE
.
MathOptInterface.NumberOfVariables
— TypeNumberOfVariables()
A model attribute for the number of variables in the model.
MathOptInterface.ListOfVariableIndices
— TypeListOfVariableIndices()
A model attribute for the Vector{VariableIndex}
of all variable indices present in the model (i.e., of length equal to the value of NumberOfVariables()
) in the order in which they were added.
MathOptInterface.ListOfConstraints
— TypeListOfConstraints()
A model attribute for the list of tuples of the form (F,S)
, where F
is a function type and S
is a set type indicating that the attribute NumberOfConstraints{F,S}()
has value greater than zero.
MathOptInterface.NumberOfConstraints
— TypeNumberOfConstraints{F,S}()
A model attribute for the number of constraints of the type F
-in-S
present in the model.
MathOptInterface.ListOfConstraintIndices
— TypeListOfConstraintIndices{F,S}()
A model attribute for the Vector{ConstraintIndex{F,S}}
of all constraint indices of type F
-in-S
in the model (i.e., of length equal to the value of NumberOfConstraints{F,S}()
) in the order in which they were added.
MathOptInterface.ListOfOptimizerAttributesSet
— TypeListOfOptimizerAttributesSet()
An optimizer attribute for the Vector{AbstractOptimizerAttribute}
of all optimizer attributes that were set.
MathOptInterface.ListOfModelAttributesSet
— TypeListOfModelAttributesSet()
A model attribute for the Vector{AbstractModelAttribute}
of all model attributes attr
such that 1) is_copyable(attr)
returns true
and 2) the attribute was set to the model.
MathOptInterface.ListOfVariableAttributesSet
— TypeListOfVariableAttributesSet()
A model attribute for the Vector{AbstractVariableAttribute}
of all variable attributes attr
such that 1) is_copyable(attr)
returns true
and 2) the attribute was set to variables.
MathOptInterface.ListOfConstraintAttributesSet
— TypeListOfConstraintAttributesSet{F, S}()
A model attribute for the Vector{AbstractConstraintAttribute}
of all constraint attributes attr
such that 1) is_copyable(attr)
returns true
and
- the attribute was set to
F
-in-S
constraints.
Note
The attributes ConstraintFunction
and ConstraintSet
should not be included in the list even if then have been set with set
.
Optimizers
MathOptInterface.AbstractOptimizer
— TypeAbstractOptimizer
Abstract supertype for objects representing an instance of an optimization problem tied to a particular solver. This is typically a solver's in-memory representation. In addition to ModelLike
, AbstractOptimizer
objects let you solve the model and query the solution.
MathOptInterface.optimize!
— Functionoptimize!(optimizer::AbstractOptimizer)
Start the solution procedure.
MathOptInterface.OptimizerWithAttributes
— Typestruct OptimizerWithAttributes
optimizer_constructor
params::Vector{Pair{AbstractOptimizerAttribute,<:Any}}
end
Object grouping an optimizer constructor and a list of optimizer attributes. Instances are created with instantiate
.
MathOptInterface.instantiate
— Functioninstantiate(optimizer_constructor,
with_bridge_type::Union{Nothing, Type}=nothing,
with_names::Bool=false)
Creates an instance of optimizer either by calling optimizer_constructor.optimizer_constructor()
and setting the parameters in optimizer_constructor.params
if optimizer_constructor
is a OptimizerWithAttributes
or by calling optimizer_constructor()
if optimizer_constructor
is callable.
If with_bridge_type
is not nothing
, it enables all the bridges defined in the MathOptInterface.Bridges submodule with coefficient type with_bridge_type
.
If the optimizer created by optimizer_constructor
does not support loading the problem incrementally or does not support names and with_names
is true
(see Utilities.supports_default_copy_to
) then a Utilities.CachingOptimizer
is added to store a cache of the bridged model. Hence set with_names
to true
if names might be set.
List of optimizers attributes
MathOptInterface.SolverName
— TypeSolverName()
An optimizer attribute for the string identifying the solver/optimizer.
MathOptInterface.Silent
— TypeSilent()
An optimizer attribute for silencing the output of an optimizer. When set
to true
, it takes precedence over any other attribute controlling verbosity and requires the solver to produce no output. The default value is false
which has no effect. In this case the verbosity is controlled by other attributes.
Note
Every optimizer should have verbosity on by default. For instance, if a solver has a solver-specific log level attribute, the MOI implementation should set it to 1
by default. If the user sets Silent
to true
, then the log level should be set to 0
, even if the user specifically sets a value of log level. If the value of Silent
is false
then the log level set to the solver is the value given by the user for this solver-specific parameter or 1
if none is given.
MathOptInterface.TimeLimitSec
— TypeTimeLimitSec()
An optimizer attribute for setting a time limit for an optimization. When set
to nothing
, it deactivates the solver time limit. The default value is nothing
. The time limit is in seconds.
MathOptInterface.RawParameter
— TypeRawParameter(name)
An optimizer attribute for the solver-specific parameter identified by name
which is typically an Enum
or a String
.
MathOptInterface.NumberOfThreads
— TypeNumberOfThreads()
An optimizer attribute for setting the number of threads used for an optimization. When set to nothing
uses solver default. Values are positive integers. The default value is nothing
.
List of attributes useful for optimizers
MathOptInterface.RawSolver
— TypeRawSolver()
A model attribute for the object that may be used to access a solver-specific API for this optimizer.
MathOptInterface.ResultCount
— TypeResultCount()
A model attribute for the number of results available.
MathOptInterface.ObjectiveFunction
— TypeObjectiveFunction{F<:AbstractScalarFunction}()
A model attribute for the objective function which has a type F<:AbstractScalarFunction
. F
should be guaranteed to be equivalent but not necessarily identical to the function type provided by the user. Throws an InexactError
if the objective function cannot be converted to F
, e.g. the objective function is quadratic and F
is ScalarAffineFunction{Float64}
or it has non-integer coefficient and F
is ScalarAffineFunction{Int}
.
MathOptInterface.ObjectiveFunctionType
— TypeObjectiveFunctionType()
A model attribute for the type F
of the objective function set using the ObjectiveFunction{F}
attribute.
Examples
In the following code, attr
should be equal to MOI.SingleVariable
:
x = MOI.add_variable(model)
MOI.set(model, MOI.ObjectiveFunction{MOI.SingleVariable}(),
MOI.SingleVariable(x))
attr = MOI.get(model, MOI.ObjectiveFunctionType())
MathOptInterface.ObjectiveValue
— TypeObjectiveValue(resultidx::Int=1)
A model attribute for the objective value of the result_index
th primal result.
MathOptInterface.DualObjectiveValue
— TypeDualObjectiveValue(result_index::Int=1)
A model attribute for the value of the objective function of the dual problem for the result_index
th dual result.
MathOptInterface.ObjectiveBound
— TypeObjectiveBound()
A model attribute for the best known bound on the optimal objective value.
MathOptInterface.RelativeGap
— TypeRelativeGap()
A model attribute for the final relative optimality gap, defined as $\frac{|b-f|}{|f|}$, where $b$ is the best bound and $f$ is the best feasible objective value.
MathOptInterface.SolveTime
— TypeSolveTime()
A model attribute for the total elapsed solution time (in seconds) as reported by the optimizer.
MathOptInterface.SimplexIterations
— TypeSimplexIterations()
A model attribute for the cumulative number of simplex iterations during the optimization process. In particular, for a mixed-integer program (MIP), the total simplex iterations for all nodes.
MathOptInterface.BarrierIterations
— TypeBarrierIterations()
A model attribute for the cumulative number of barrier iterations while solving a problem.
MathOptInterface.NodeCount
— TypeNodeCount()
A model attribute for the total number of branch-and-bound nodes explored while solving a mixed-integer program (MIP).
MathOptInterface.TerminationStatus
— TypeTerminationStatus()
A model attribute for the TerminationStatusCode
explaining why the optimizer stopped.
MathOptInterface.RawStatusString
— TypeRawStatusString()
A model attribute for a solver specific string explaining why the optimizer stopped.
MathOptInterface.PrimalStatus
— TypePrimalStatus(N)
PrimalStatus()
A model attribute for the ResultStatusCode
of the primal result N
. If N
is omitted, it defaults to 1. If N
is larger than the value of ResultCount
then NO_SOLUTION
is returned.
MathOptInterface.DualStatus
— TypeDualStatus(N)
DualStatus()
A model attribute for the ResultStatusCode
of the dual result N
. If N
is omitted, it defaults to 1. If N
is larger than the value of ResultCount
then NO_SOLUTION
is returned.
Attributes relating to solver callbacks:
MathOptInterface.AbstractCallback
— Typeabstract type AbstractCallback <: AbstractModelAttribute end
Abstract type for a model attribute representing a callback function. The value set to subtypes of AbstractCallback
is a function that may be called during optimize!
. As optimize!
is in progress, the result attributes (i.e, the attributes attr
such that is_set_by_optimize(attr)
) may not be accessible from the callback, hence trying to get result attributes might throw a OptimizeInProgress
error.
At most one callback of each type can be registered. If an optimizer already has a function for a callback type, and the user registers a new function, then the old one is replaced.
The value of the attribute should be a function taking only one argument, commonly called callback_data
, that can be used for instance in LazyConstraintCallback
, HeuristicCallback
and UserCutCallback
.
MathOptInterface.LazyConstraintCallback
— TypeLazyConstraintCallback() <: AbstractCallback
The callback can be used to reduce the feasible set given the current primal solution by submitting a LazyConstraint
. For instance, it may be called at an incumbent of a mixed-integer problem. Note that there is no guarantee that the callback is called at every feasible primal solution.
The current primal solution is accessed through CallbackVariablePrimal
. Trying to access other result attributes will throw OptimizeInProgress
as discussed in AbstractCallback
.
Examples
x = MOI.add_variables(optimizer, 8)
MOI.set(optimizer, MOI.LazyConstraintCallback(), callback_data -> begin
sol = MOI.get(optimizer, MOI.CallbackVariablePrimal(callback_data), x)
if # should add a lazy constraint
func = # computes function
set = # computes set
MOI.submit(optimizer, MOI.LazyConstraint(callback_data), func, set)
end
end)
MathOptInterface.HeuristicCallback
— TypeHeuristicCallback() <: AbstractCallback
The callback can be used to submit HeuristicSolution
given the current primal solution. For instance, it may be called at fractional (i.e., non-integer) nodes in the branch and bound tree of a mixed-integer problem. Note that there is not guarantee that the callback is called everytime the solver has an infeasible solution.
The current primal solution is accessed through CallbackVariablePrimal
. Trying to access other result attributes will throw OptimizeInProgress
as discussed in AbstractCallback
.
Examples
x = MOI.add_variables(optimizer, 8)
MOI.set(optimizer, MOI.HeuristicCallback(), callback_data -> begin
sol = MOI.get(optimizer, MOI.CallbackVariablePrimal(callback_data), x)
if # can find a heuristic solution
values = # computes heuristic solution
MOI.submit(optimizer, MOI.HeuristicSolution(callback_data), x,
values)
end
end
MathOptInterface.UserCutCallback
— TypeUserCutCallback() <: AbstractCallback
The callback can be used to submit UserCut
given the current primal solution. For instance, it may be called at fractional (i.e., non-integer) nodes in the branch and bound tree of a mixed-integer problem. Note that there is not guarantee that the callback is called everytime the solver has an infeasible solution.
The infeasible solution is accessed through CallbackVariablePrimal
. Trying to access other result attributes will throw OptimizeInProgress
as discussed in AbstractCallback
.
Examples
x = MOI.add_variables(optimizer, 8)
MOI.set(optimizer, MOI.UserCutCallback(), callback_data -> begin
sol = MOI.get(optimizer, MOI.CallbackVariablePrimal(callback_data), x)
if # can find a user cut
func = # computes function
set = # computes set
MOI.submit(optimizer, MOI.UserCut(callback_data), func, set)
end
end
MathOptInterface.CallbackNodeStatus
— TypeCallbackNodeStatus(callback_data)
An optimizer attribute describing the (in)feasibility of the primal solution available from CallbackVariablePrimal
during a callback identified by callback_data
.
Returns a CallbackNodeStatusCode
Enum.
MathOptInterface.CallbackNodeStatusCode
— TypeCallbackNodeStatusCode
An Enum of possible return values from calling get
with CallbackNodeStatus
.
Possible values are:
CALLBACK_NODE_STATUS_INTEGER
: the primal solution available fromCallbackVariablePrimal
is integer feasible.CALLBACK_NODE_STATUS_FRACTIONAL
: the primal solution available fromCallbackVariablePrimal
is integer infeasible.CALLBACK_NODE_STATUS_UNKNOWN
: the primal solution available fromCallbackVariablePrimal
might be integer feasible or infeasible.
MathOptInterface.CallbackVariablePrimal
— TypeCallbackVariablePrimal(callback_data)
A variable attribute for the assignment to some primal variable's value during the callback identified by callback_data
.
Termination Status
The TerminationStatus
attribute indicates why the optimizer stopped executing. The value of the attribute is of type TerminationStatusCode
.
MathOptInterface.TerminationStatusCode
— TypeTerminationStatusCode
An Enum of possible values for the TerminationStatus
attribute. This attribute is meant to explain the reason why the optimizer stopped executing in the most recent call to optimize!
.
If no call has been made to optimize!
, then the TerminationStatus
is:
OPTIMIZE_NOT_CALLED
: The algorithm has not started.
OK
These are generally OK statuses, i.e., the algorithm ran to completion normally.
OPTIMAL
: The algorithm found a globally optimal solution.INFEASIBLE
: The algorithm concluded that no feasible solution exists.DUAL_INFEASIBLE
: The algorithm concluded that no dual bound exists for the problem. If, additionally, a feasible (primal) solution is known to exist, this status typically implies that the problem is unbounded, with some technical exceptions.LOCALLY_SOLVED
: The algorithm converged to a stationary point, local optimal solution, could not find directions for improvement, or otherwise completed its search without global guarantees.LOCALLY_INFEASIBLE
: The algorithm converged to an infeasible point or otherwise completed its search without finding a feasible solution, without guarantees that no feasible solution exists.INFEASIBLE_OR_UNBOUNDED
: The algorithm stopped because it decided that the problem is infeasible or unbounded; this occasionally happens during MIP presolve.
Solved to relaxed tolerances
ALMOST_OPTIMAL
: The algorithm found a globally optimal solution to relaxed tolerances.ALMOST_INFEASIBLE
: The algorithm concluded that no feasible solution exists within relaxed tolerances.ALMOST_DUAL_INFEASIBLE
: The algorithm concluded that no dual bound exists for the problem within relaxed tolerances.ALMOST_LOCALLY_SOLVED
: The algorithm converged to a stationary point, local optimal solution, or could not find directions for improvement within relaxed tolerances.
Limits
The optimizer stopped because of some user-defined limit.
ITERATION_LIMIT
: An iterative algorithm stopped after conducting the maximum number of iterations.TIME_LIMIT
: The algorithm stopped after a user-specified computation time.NODE_LIMIT
: A branch-and-bound algorithm stopped because it explored a maximum number of nodes in the branch-and-bound tree.SOLUTION_LIMIT
: The algorithm stopped because it found the required number of solutions. This is often used in MIPs to get the solver to return the first feasible solution it encounters.MEMORY_LIMIT
: The algorithm stopped because it ran out of memory.OBJECTIVE_LIMIT
: The algorithm stopped because it found a solution better than a minimum limit set by the user.NORM_LIMIT
: The algorithm stopped because the norm of an iterate became too large.OTHER_LIMIT
: The algorithm stopped due to a limit not covered by one of the above.
Problematic
This group of statuses means that something unexpected or problematic happened.
SLOW_PROGRESS
: The algorithm stopped because it was unable to continue making progress towards the solution.NUMERICAL_ERROR
: The algorithm stopped because it encountered unrecoverable numerical error.INVALID_MODEL
: The algorithm stopped because the model is invalid.INVALID_OPTION
: The algorithm stopped because it was provided an invalid option.INTERRUPTED
: The algorithm stopped because of an interrupt signal.OTHER_ERROR
: The algorithm stopped because of an error not covered by one of the statuses defined above.
Conflict Status
The ConflictStatus
attribute indicates why the conflict finder stopped executing. The value of the attribute is of type ConflictStatusCode
.
MathOptInterface.compute_conflict!
— Functioncompute_conflict!(optimizer::AbstractOptimizer)
Computes a minimal subset of constraints such that the model with the other constraint removed is still infeasible.
Some solvers call a set of conflicting constraints an Irreducible Inconsistent Subsystem (IIS).
See also ConflictStatus
and ConstraintConflictStatus
.
Note
If the model is modified after a call to compute_conflict!
, the implementor is not obliged to purge the conflict. Any calls to the above attributes may return values for the original conflict without a warning. Similarly, when modifying the model, the conflict can be discarded.
MathOptInterface.ConflictStatus
— TypeConflictStatus()
A model attribute for the ConflictStatusCode
explaining why the conflict refiner stopped when computing the conflict.
MathOptInterface.ConflictStatusCode
— TypeConflictStatusCode
An Enum of possible values for the ConflictStatus
attribute. This attribute is meant to explain the reason why the conflict finder stopped executing in the most recent call to compute_conflict!
.
Possible values are:
COMPUTE_CONFLICT_NOT_CALLED
: the functioncompute_conflict!
has not yet been calledNO_CONFLICT_EXISTS
: there is no conflict because the problem is feasibleNO_CONFLICT_FOUND
: the solver could not find a conflictCONFLICT_FOUND
: at least one conflict could be found
MathOptInterface.ConstraintConflictStatus
— TypeConstraintConflictStatus()
A constraint attribute indicating whether the constraint participates in the conflict. Its type is ConflictParticipationStatusCode
.
MathOptInterface.ConflictParticipationStatusCode
— TypeConflictParticipationStatusCode
An Enum of possible values for the ConstraintConflictStatus
attribute. This attribute is meant to indicate whether a given constraint participates or not in the last computed conflict.
Possible values are:
NOT_IN_CONFLICT
: the constraint does not participate in the conflictIN_CONFLICT
: the constraint participates in the conflictMAYBE_IN_CONFLICT
: the constraint may participate in the conflict, the solver was not able to prove that the constraint can be excluded from the conflict
Result Status
The PrimalStatus
and DualStatus
attributes indicate how to interpret the result returned by the solver. The value of the attribute is of type ResultStatusCode
.
MathOptInterface.ResultStatusCode
— TypeResultStatusCode
An Enum of possible values for the PrimalStatus
and DualStatus
attributes. The values indicate how to interpret the result vector.
NO_SOLUTION
: the result vector is empty.FEASIBLE_POINT
: the result vector is a feasible point.NEARLY_FEASIBLE_POINT
: the result vector is feasible if some constraint tolerances are relaxed.INFEASIBLE_POINT
: the result vector is an infeasible point.INFEASIBILITY_CERTIFICATE
: the result vector is an infeasibility certificate. If thePrimalStatus
isINFEASIBILITY_CERTIFICATE
, then the primal result vector is a certificate of dual infeasibility. If theDualStatus
isINFEASIBILITY_CERTIFICATE
, then the dual result vector is a proof of primal infeasibility.NEARLY_INFEASIBILITY_CERTIFICATE
: the result satisfies a relaxed criterion for a certificate of infeasibility.REDUCTION_CERTIFICATE
: the result vector is an ill-posed certificate; see this article for details. If thePrimalStatus
isREDUCTION_CERTIFICATE
, then the primal result vector is a proof that the dual problem is ill-posed. If theDualStatus
isREDUCTION_CERTIFICATE
, then the dual result vector is a proof that the primal is ill-posed.NEARLY_REDUCTION_CERTIFICATE
: the result satisfies a relaxed criterion for an ill-posed certificate.UNKNOWN_RESULT_STATUS
: the result vector contains a solution with an unknown interpretation.OTHER_RESULT_STATUS
: the result vector contains a solution with an interpretation not covered by one of the statuses defined above.
Variables and Constraints
Basis Status
The BasisStatus
attribute of a constraint describes its status with respect to a basis, if one is known. The value of the attribute is of type BasisStatusCode
.
MathOptInterface.BasisStatusCode
— TypeBasisStatusCode
An Enum of possible values for the ConstraintBasisStatus
attribute, explaining the status of a given element with respect to an optimal solution basis.
Possible values are:
BASIC
: element is in the basisNONBASIC
: element is not in the basisNONBASIC_AT_LOWER
: element is not in the basis and is at its lower boundNONBASIC_AT_UPPER
: element is not in the basis and is at its upper boundSUPER_BASIC
: element is not in the basis but is also not at one of its bounds
Notes
NONBASIC_AT_LOWER
andNONBASIC_AT_UPPER
should be used only for constraints with theInterval
set. In this case, they are necessary to distinguish which side of the constraint is active. One-sided constraints (e.g.,LessThan
andGreaterThan
) should useNONBASIC
instead of theNONBASIC_AT_*
values.In general,
SUPER_BASIC
usually occurs when the problem is nonlinear. For linear programs,SUPER_BASIC
variables only occur if the solver returns a solution that is not at a vertex of the feasible region.
Index types
MathOptInterface.VariableIndex
— TypeVariableIndex
A type-safe wrapper for Int64
for use in referencing variables in a model. To allow for deletion, indices need not be consecutive.
MathOptInterface.ConstraintIndex
— TypeConstraintIndex{F, S}
A type-safe wrapper for Int64
for use in referencing F
-in-S
constraints in a model. The parameter F
is the type of the function in the constraint, and the parameter S
is the type of set in the constraint. To allow for deletion, indices need not be consecutive. Indices within a constraint type (i.e. F
-in-S
) must be unique, but non-unique indices across different constraint types are allowed. If F
is SingleVariable
then the index is equal to the index of the variable. That is for an index::ConstraintIndex{SingleVariable}
, we always have
index.value == MOI.get(model, MOI.ConstraintFunction(), index).variable.value
MathOptInterface.is_valid
— Functionis_valid(model::ModelLike, index::Index)::Bool
Return a Bool
indicating whether this index refers to a valid object in the model model
.
MathOptInterface.throw_if_not_valid
— Functionthrow_if_not_valid(model::ModelLike, index::Index)
Throw an InvalidIndex(index)
error if MOI.is_valid(model, index)
returns false
.
MathOptInterface.delete
— Methoddelete(model::ModelLike, index::Index)
Delete the referenced object from the model. Throw DeleteNotAllowed
if if index
cannot be deleted.
The following modifications also take effect if Index
is VariableIndex
:
- If
index
used in the objective function, it is removed from the function, i.e., it is substituted for zero. - For each
func
-in-set
constraint of the model:- If
func isa SingleVariable
andfunc.variable == index
then the constraint is deleted. - If
func isa VectorOfVariables
andindex in func.variable
then- if
length(func.variable) == 1
is one, the constraint is deleted; - if
length(func.variable) > 1
andsupports_dimension_update(set)
then then the variable is removed fromfunc
andset
is replaced byupdate_dimension(set, MOI.dimension(set) - 1)
. - Otherwise, a
DeleteNotAllowed
error is thrown.
- if
- Otherwise, the variable is removed from
func
, i.e., it is substituted for zero.
- If
MathOptInterface.delete
— Methoddelete(model::ModelLike, indices::Vector{R<:Index}) where {R}
Delete the referenced objects in the vector indices
from the model. It may be assumed that R
is a concrete type. The default fallback sequentially deletes the individual items in indices
, although specialized implementations may be more efficient.
Variables
Free variables are the variables created with add_variable
or add_variables
while constrained variables are the variables created with add_constrained_variable
or add_constrained_variables
. Adding constrained variables instead of constraining free variables with add_constraint
allows variable bridges to be used. Note further that free variables that are constrained with add_constraint
may be copied by copy_to
with add_constrained_variable
or add_constrained_variables
by the Utilities.CachingOptimizer
. More precisely, the attributes do not distinguish constraints on variables created with add_constrained_variable(s)
or add_variable(s)
/add_constraint
. When the model is copied, if a variable is constrained in several sets, the implementation of copy_to
can determine whether it is added using add_variable
or add_constrained_variable
with one of the sets. The rest of the constraints on the variables are added with add_constraint
. For deleting, see Index types.
MathOptInterface.add_variable
— Functionadd_variable(model::ModelLike)::VariableIndex
Add a scalar variable to the model, returning a variable index.
A AddVariableNotAllowed
error is thrown if adding variables cannot be done in the current state of the model model
.
MathOptInterface.add_variables
— Functionadd_variables(model::ModelLike, n::Int)::Vector{VariableIndex}
Add n
scalar variables to the model, returning a vector of variable indices.
A AddVariableNotAllowed
error is thrown if adding variables cannot be done in the current state of the model model
.
MathOptInterface.add_constrained_variable
— Functionadd_constrained_variable(
model::ModelLike,
set::AbstractScalarSet
)::Tuple{MOI.VariableIndex,
MOI.ConstraintIndex{MOI.SingleVariable, typeof(set)}}
Add to model
a scalar variable constrained to belong to set
, returning the index of the variable created and the index of the constraint constraining the variable to belong to set
.
By default, this function falls back to creating a free variable with add_variable
and then constraining it to belong to set
with add_constraint
.
MathOptInterface.add_constrained_variables
— Functionadd_constrained_variables(
model::ModelLike,
sets::AbstractVector{<:AbstractScalarSet}
)::Tuple{Vector{MOI.VariableIndex},
Vector{MOI.ConstraintIndex{MOI.SingleVariable, eltype(sets)}}}
Add to model
scalar variables constrained to belong to sets
, returning the indices of the variables created and the indices of the constraints constraining the variables to belong to each set in sets
. That is, if it returns variables
and constraints
, constraints[i]
is the index of the constraint constraining variable[i]
to belong to sets[i]
.
By default, this function falls back to calling add_constrained_variable
on each set.
add_constrained_variables(
model::ModelLike,
set::AbstractVectorSet
)::Tuple{Vector{MOI.VariableIndex},
MOI.ConstraintIndex{MOI.VectorOfVariables, typeof(set)}}
Add to model
a vector of variables constrained to belong to set
, returning the indices of the variables created and the index of the constraint constraining the vector of variables to belong to set
.
By default, this function falls back to creating free variables with add_variables
and then constraining it to belong to set
with add_constraint
.
MathOptInterface.supports_add_constrained_variable
— Functionsupports_add_constrained_variable(
model::ModelLike,
S::Type{<:AbstractScalarSet}
)::Bool
Return a Bool
indicating whether model
supports constraining a variable to belong to a set of type S
either on creation of the variable with add_constrained_variable
or after the variable is created with add_constraint
.
By default, this function falls back to supports_add_constrained_variables(model, Reals) && supports_constraint(model, MOI.SingleVariable, S)
which is the correct definition for most models.
Example
Suppose that a solver supports only two kind of variables: binary variables and continuous variables with a lower bound. If the solver decides not to support SingleVariable
-in-Binary
and SingleVariable
-in-GreaterThan
constraints, it only has to implement add_constrained_variable
for these two sets which prevents the user to add both a binary constraint and a lower bound on the same variable. Moreover, if the user adds a SingleVariable
-in-GreaterThan
constraint, implementing this interface (i.e., supports_add_constrained_variables
) enables the constraint to be transparently bridged into a supported constraint.
MathOptInterface.supports_add_constrained_variables
— Functionsupports_add_constrained_variables(
model::ModelLike,
S::Type{<:AbstractVectorSet}
)::Bool
Return a Bool
indicating whether model
supports constraining a vector of variables to belong to a set of type S
either on creation of the vector of variables with add_constrained_variables
or after the variable is created with add_constraint
.
By default, if S
is Reals
then this function returns true
and otherwise, it falls back to supports_add_constrained_variables(model, Reals) && supports_constraint(model, MOI.VectorOfVariables, S)
which is the correct definition for most models.
Example
In the standard conic form (see Duality), the variables are grouped into several cones and the constraints are affine equality constraints. If Reals
is not one of the cones supported by the solvers then it needs to implement supports_add_constrained_variables(::Optimizer, ::Type{Reals}) = false
as free variables are not supported. The solvers should then implement supports_add_constrained_variables(::Optimizer, ::Type{<:SupportedCones}) = true
where SupportedCones
is the union of all cone types that are supported; it does not have to implement the method supports_constraint(::Type{VectorOfVariables}, Type{<:SupportedCones})
as it should return false
and it's the default. This prevents the user to constrain the same variable in two different cones. When a VectorOfVariables
-in-S
is added, the variables of the vector have already been created so they already belong to given cones. If bridges are enabled, the constraint will therefore be bridged by adding slack variables in S
and equality constraints ensuring that the slack variables are equal to the corresponding variables of the given constraint function.
Note that there may also be sets for which !supports_add_constrained_variables(model, S)
and supports_constraint(model, MOI.VectorOfVariables, S)
. For instance, suppose a solver supports positive semidefinite variable constraints and two types of variables: binary variables and nonnegative variables. Then the solver should support adding VectorOfVariables
-in-PositiveSemidefiniteConeTriangle
constraints, but it should not support creating variables constrained to belong to the PositiveSemidefiniteConeTriangle
because the variables in PositiveSemidefiniteConeTriangle
should first be created as either binary or non-negative.
List of attributes associated with variables. [category AbstractVariableAttribute] Calls to get
and set
should include as an argument a single VariableIndex
or a vector of VariableIndex
objects.
MathOptInterface.VariableName
— TypeVariableName()
A variable attribute for a string identifying the variable. It is valid for two variables to have the same name; however, variables with duplicate names cannot be looked up using get
. It has a default value of ""
if not set`.
MathOptInterface.VariablePrimalStart
— TypeVariablePrimalStart()
A variable attribute for the initial assignment to some primal variable's value that the optimizer may use to warm-start the solve. May be a number or nothing
(unset).
MathOptInterface.VariablePrimal
— TypeVariablePrimal(N)
VariablePrimal()
A variable attribute for the assignment to some primal variable's value in result N
. If N
is omitted, it is 1 by default.
Constraints
Functions for adding and modifying constraints.
MathOptInterface.is_valid
— Methodis_valid(model::ModelLike, index::Index)::Bool
Return a Bool
indicating whether this index refers to a valid object in the model model
.
MathOptInterface.add_constraint
— Functionadd_constraint(model::ModelLike, func::F, set::S)::ConstraintIndex{F,S} where {F,S}
Add the constraint $f(x) \in \mathcal{S}$ where $f$ is defined by func
, and $\mathcal{S}$ is defined by set
.
add_constraint(model::ModelLike, v::VariableIndex, set::S)::ConstraintIndex{SingleVariable,S} where {S}
add_constraint(model::ModelLike, vec::Vector{VariableIndex}, set::S)::ConstraintIndex{VectorOfVariables,S} where {S}
Add the constraint $v \in \mathcal{S}$ where $v$ is the variable (or vector of variables) referenced by v
and $\mathcal{S}$ is defined by set
.
- An
UnsupportedConstraint
error is thrown ifmodel
does not supportF
-in-S
constraints, - a
AddConstraintNotAllowed
error is thrown if it supportsF
-in-S
constraints but it cannot add the constraint(s) in its current state and - a
ScalarFunctionConstantNotZero
error may be thrown iffunc
is anAbstractScalarFunction
with nonzero constant andset
isEqualTo
,GreaterThan
,LessThan
orInterval
. - a
LowerBoundAlreadySet
error is thrown ifF
is aSingleVariable
and a constraint was already added to this variable that sets a lower bound. - a
UpperBoundAlreadySet
error is thrown ifF
is aSingleVariable
and a constraint was already added to this variable that sets an upper bound.
MathOptInterface.add_constraints
— Functionadd_constraints(model::ModelLike, funcs::Vector{F}, sets::Vector{S})::Vector{ConstraintIndex{F,S}} where {F,S}
Add the set of constraints specified by each function-set pair in funcs
and sets
. F
and S
should be concrete types. This call is equivalent to add_constraint.(model, funcs, sets)
but may be more efficient.
MathOptInterface.transform
— FunctionTransform Constraint Set
transform(model::ModelLike, c::ConstraintIndex{F,S1}, newset::S2)::ConstraintIndex{F,S2}
Replace the set in constraint c
with newset
. The constraint index c
will no longer be valid, and the function returns a new constraint index with the correct type.
Solvers may only support a subset of constraint transforms that they perform efficiently (for example, changing from a LessThan
to GreaterThan
set). In addition, set modification (where S1 = S2
) should be performed via the modify
function.
Typically, the user should delete the constraint and add a new one.
Examples
If c
is a ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}
,
c2 = transform(model, c, GreaterThan(0.0))
transform(model, c, LessThan(0.0)) # errors
MathOptInterface.supports_constraint
— Functionsupports_constraint(model::ModelLike, ::Type{F}, ::Type{S})::Bool where {F<:AbstractFunction,S<:AbstractSet}
Return a Bool
indicating whether model
supports F
-in-S
constraints, that is, copy_to(model, src)
does not throw UnsupportedConstraint
when src
contains F
-in-S
constraints. If F
-in-S
constraints are only not supported in specific circumstances, e.g. F
-in-S
constraints cannot be combined with another type of constraint, it should still return true
.
supports_constraint(model::ModelLike, ::Type{VectorOfVariables}, ::Type{Reals})::Bool
Return a Bool
indicating whether model
supports free variables. That is, copy_to(model, src)
does not error when src
contains variables that are not constrained by any SingleVariable
or VectorOfVariables
constraint. By default, this method returns true
so it should only be implemented if model
does not support free variables. For instance, if a solver requires all variables to be nonnegative, it should implement this method and return false
because free variables cannot be copied to the solver.
Note that free variables are not explicitly set to be free by calling add_constraint
with the set Reals
, instead, free variables are created with add_variable
and add_variables
. If model
does not support free variables, it should not implement add_variable
nor add_variables
but should implement this method and return false
. This allows free variables to be bridged as the sum of a nonnegative and a nonpositive variables.
MOI.supports_constraint(BT::Type{<:AbstractBridge}, F::Type{<:MOI.AbstractFunction}, S::Type{<:MOI.AbstractSet})::Bool
Return a Bool
indicating whether the bridges of type BT
support bridging F
-in-S
constraints.
List of attributes associated with constraints. [category AbstractConstraintAttribute] Calls to get
and set
should include as an argument a single ConstraintIndex
or a vector of ConstraintIndex{F,S}
objects.
MathOptInterface.ConstraintName
— TypeConstraintName()
A constraint attribute for a string identifying the constraint. It is valid for constraints variables to have the same name; however, constraints with duplicate names cannot be looked up using get
regardless of if they have the same F
-in-S
type. It has a default value of ""
if not set.
MathOptInterface.ConstraintPrimalStart
— TypeConstraintPrimalStart()
A constraint attribute for the initial assignment to some constraint's primal value(s) that the optimizer may use to warm-start the solve. May be a number or nothing
(unset).
MathOptInterface.ConstraintDualStart
— TypeConstraintDualStart()
A constraint attribute for the initial assignment to some constraint's dual value(s) that the optimizer may use to warm-start the solve. May be a number or nothing
(unset).
MathOptInterface.ConstraintPrimal
— TypeConstraintPrimal(N)
ConstraintPrimal()
A constraint attribute for the assignment to some constraint's primal value(s) in result N
. If N
is omitted, it is 1 by default.
Given a constraint function-in-set
, the ConstraintPrimal
is the value of the function evaluated at the primal solution of the variables. For example, given the constraint ScalarAffineFunction([x,y], [1, 2], 3)
-in-Interval(0, 20)
and a primal solution of (x,y) = (4,5)
, the ConstraintPrimal
solution of the constraint is 1 * 4 + 2 * 5 + 3 = 17
.
MathOptInterface.ConstraintDual
— TypeConstraintDual(N)
ConstraintDual()
A constraint attribute for the assignment to some constraint's dual value(s) in result N
. If N
is omitted, it is 1 by default.
MathOptInterface.ConstraintBasisStatus
— TypeConstraintBasisStatus(result_index)
ConstraintBasisStatus()
A constraint attribute for the BasisStatusCode
of some constraint in result result_index
, with respect to an available optimal solution basis. If result_index
is omitted, it is 1 by default.
For the basis status of a variable, query the corresponding SingleVariable
constraint that enforces the variable's bounds.
MathOptInterface.ConstraintFunction
— TypeConstraintFunction()
A constraint attribute for the AbstractFunction
object used to define the constraint. It is guaranteed to be equivalent but not necessarily identical to the function provided by the user.
MathOptInterface.CanonicalConstraintFunction
— TypeCanonicalConstraintFunction()
A constraint attribute for a canonical representation of the AbstractFunction
object used to define the constraint. Getting this attribute is guaranteed to return a function that is equivalent but not necessarily identical to the function provided by the user.
By default, MOI.get(model, MOI.CanonicalConstraintFunction(), ci)
fallbacks to MOI.Utilities.canonical(MOI.get(model, MOI.ConstraintFunction(), ci))
. However, if model
knows that the constraint function is canonical then it can implement a specialized method that directly return the function without calling Utilities.canonical
. Therefore, the value returned cannot be assumed to be a copy of the function stored in model
. Moreover, Utilities.Model
checks with Utilities.is_canonical
whether the function stored internally is already canonical and if it's the case, then it returns the function stored internally instead of a copy.
MathOptInterface.ConstraintSet
— TypeConstraintSet()
A constraint attribute for the AbstractSet
object used to define the constraint.
Note that setting the ConstraintFunction
of a [SingleVariable
] constraint is not allowed:
MathOptInterface.SettingSingleVariableFunctionNotAllowed
— TypeSettingSingleVariableFunctionNotAllowed()
Error type that should be thrown when the user calls set
to change the ConstraintFunction
of a SingleVariable
constraint.
Functions and function modifications
List of recognized functions.
MathOptInterface.AbstractFunction
— TypeAbstractFunction
Abstract supertype for function objects.
MathOptInterface.AbstractVectorFunction
— TypeAbstractVectorFunction
Abstract supertype for vector-valued function objects.
MathOptInterface.SingleVariable
— TypeSingleVariable(variable)
The function that extracts the scalar variable referenced by variable
, a VariableIndex
. This function is naturally be used for single variable bounds or integrality constraints.
MathOptInterface.VectorOfVariables
— TypeVectorOfVariables(variables)
The function that extracts the vector of variables referenced by variables
, a Vector{VariableIndex}
. This function is naturally be used for constraints that apply to groups of variables, such as an "all different" constraint, an indicator constraint, or a complementarity constraint.
MathOptInterface.ScalarAffineTerm
— Typestruct ScalarAffineTerm{T}
coefficient::T
variable_index::VariableIndex
end
Represents $c x_i$ where $c$ is coefficient
and $x_i$ is the variable identified by variable_index
.
MathOptInterface.ScalarAffineFunction
— TypeScalarAffineFunction{T}(terms, constant)
The scalar-valued affine function $a^T x + b$, where:
- $a$ is a sparse vector specified by a list of
ScalarAffineTerm
structs. - $b$ is a scalar specified by
constant::T
Duplicate variable indices in terms
are accepted, and the corresponding coefficients are summed together.
MathOptInterface.VectorAffineTerm
— Typestruct VectorAffineTerm{T}
output_index::Int64
scalar_term::ScalarAffineTerm{T}
end
A ScalarAffineTerm
plus its index of the output component of a VectorAffineFunction
or VectorQuadraticFunction
. output_index
can also be interpreted as a row index into a sparse matrix, where the scalar_term
contains the column index and coefficient.
MathOptInterface.VectorAffineFunction
— TypeVectorAffineFunction{T}(terms, constants)
The vector-valued affine function $A x + b$, where:
- $A$ is a sparse matrix specified by a list of
VectorAffineTerm
objects. - $b$ is a vector specified by
constants
Duplicate indices in the $A$ are accepted, and the corresponding coefficients are summed together.
MathOptInterface.ScalarQuadraticTerm
— Typestruct ScalarQuadraticTerm{T}
coefficient::T
variable_index_1::VariableIndex
variable_index_2::VariableIndex
end
Represents $c x_i x_j$ where $c$ is coefficient
, $x_i$ is the variable identified by variable_index_1
and $x_j$ is the variable identified by variable_index_2
.
MathOptInterface.ScalarQuadraticFunction
— TypeScalarQuadraticFunction{T}(affine_terms, quadratic_terms, constant)
The scalar-valued quadratic function $\frac{1}{2}x^TQx + a^T x + b$, where:
- $a$ is a sparse vector specified by a list of
ScalarAffineTerm
structs. - $b$ is a scalar specified by
constant
. - $Q$ is a symmetric matrix specified by a list of
ScalarQuadraticTerm
structs.
Duplicate indices in $a$ or $Q$ are accepted, and the corresponding coefficients are summed together. "Mirrored" indices (q,r)
and (r,q)
(where r
and q
are VariableIndex
es) are considered duplicates; only one need be specified.
For example, for two scalar variables $y, z$, the quadratic expression $yz + y^2$ is represented by the terms ScalarQuadraticTerm.([1.0, 2.0], [y, y], [z, y])
.
MathOptInterface.VectorQuadraticTerm
— Typestruct VectorQuadraticTerm{T}
output_index::Int64
scalar_term::ScalarQuadraticTerm{T}
end
A ScalarQuadraticTerm
plus its index of the output component of a VectorQuadraticFunction
. Each output component corresponds to a distinct sparse matrix $Q_i$.
MathOptInterface.VectorQuadraticFunction
— TypeVectorQuadraticFunction{T}(affine_terms, quadratic_terms, constants)
The vector-valued quadratic function with ith
component ("output index") defined as $\frac{1}{2}x^TQ_ix + a_i^T x + b_i$, where:
- $a_i$ is a sparse vector specified by the
VectorAffineTerm
s withoutput_index == i
. - $b_i$ is a scalar specified by
constants[i]
- $Q_i$ is a symmetric matrix specified by the
VectorQuadraticTerm
withoutput_index == i
.
Duplicate indices in $a_i$ or $Q_i$ are accepted, and the corresponding coefficients are summed together. "Mirrored" indices (q,r)
and (r,q)
(where r
and q
are VariableIndex
es) are considered duplicates; only one need be specified.
Functions for getting and setting properties of functions.
MathOptInterface.output_dimension
— Functionoutput_dimension(f::AbstractFunction)
Return 1 if f
has a scalar output and the number of output components if f
has a vector output.
MathOptInterface.constant
— Methodconstant(f::Union{ScalarAffineFunction, ScalarQuadraticFunction})
Returns the constant term of the scalar function
MathOptInterface.constant
— Methodconstant(f::Union{VectorAffineFunction, VectorQuadraticFunction})
Returns the vector of constant terms of the vector function
MathOptInterface.constant
— Methodconstant(f::SingleVariable, T::DataType)
The constant term of a SingleVariable
function is the zero value of the specified type T
.
MathOptInterface.constant
— Methodconstant(f::VectorOfVariables, T::DataType)
The constant term of a VectorOfVariables
function is a vector of zero values of the specified type T
.
Sets
All sets are subtypes of AbstractSet
and they should either be scalar or vector sets.
MathOptInterface.AbstractSet
— TypeAbstractSet
Abstract supertype for set objects used to encode constraints. A set object should not contain any VariableIndex
or ConstraintIndex
as the set is passed unmodifed during copy_to
.
MathOptInterface.AbstractScalarSet
— TypeAbstractScalarSet
Abstract supertype for subsets of $\mathbb{R}$.
MathOptInterface.AbstractVectorSet
— TypeAbstractVectorSet
Abstract supertype for subsets of $\mathbb{R}^n$ for some $n$.
Functions for getting properties of sets.
MathOptInterface.dimension
— Functiondimension(s::AbstractSet)
Return the output_dimension
that an AbstractFunction
should have to be used with the set s
.
Examples
julia> dimension(Reals(4))
4
julia> dimension(LessThan(3.0))
1
julia> dimension(PositiveSemidefiniteConeTriangle(2))
3
MathOptInterface.dual_set
— Functiondual_set(s::AbstractSet)
Return the dual set of s
, that is the dual cone of the set. This follows the definition of duality discussed in Duality.
See Dual cone for more information.
If the dual cone is not defined it returns an error.
Examples
julia> dual_set(Reals(4))
Zeros(4)
julia> dual_set(SecondOrderCone(5))
SecondOrderCone(5)
julia> dual_set(ExponentialCone())
DualExponentialCone()
MathOptInterface.dual_set_type
— Functiondual_set_type(S::Type{<:AbstractSet})
Return the type of dual set of sets of type S
, as returned by dual_set
. If the dual cone is not defined it returns an error.
Examples
julia> dual_set_type(Reals)
Zeros
julia> dual_set_type(SecondOrderCone)
SecondOrderCone
julia> dual_set_type(ExponentialCone)
DualExponentialCone
MathOptInterface.constant
— Methodconstant(s::Union{EqualTo, GreaterThan, LessThan})
Returns the constant of the set.
MathOptInterface.supports_dimension_update
— Functionsupports_dimension_update(S::Type{<:MOI.AbstractVectorSet})
Return a Bool
indicating whether the elimination of any dimension of n
-dimensional sets of type S
give an n-1
-dimensional set S
. By default, this function returns false
so it should only be implemented for sets that supports dimension update.
For instance, supports_dimension_update(MOI.Nonnegatives}
is true
because the elimination of any dimension of the n
-dimensional nonnegative orthant gives the n-1
-dimensional nonnegative orthant. However supports_dimension_update(MOI.ExponentialCone}
is false
.
MathOptInterface.update_dimension
— Functionupdate_dimension(s::AbstractVectorSet, new_dim)
Returns a set with the dimension modified to new_dim
.
Scalar sets
List of recognized scalar sets.
MathOptInterface.GreaterThan
— TypeGreaterThan{T <: Real}(lower::T)
The set $[lower,\infty) \subseteq \mathbb{R}$.
MathOptInterface.LessThan
— TypeLessThan{T <: Real}(upper::T)
The set $(-\infty,upper] \subseteq \mathbb{R}$.
MathOptInterface.EqualTo
— TypeEqualTo{T <: Number}(value::T)
The set containing the single point $x \in \mathbb{R}$ where $x$ is given by value
.
MathOptInterface.Interval
— TypeInterval{T <: Real}(lower::T,upper::T)
The interval $[lower, upper] \subseteq \mathbb{R}$. If lower
or upper
is -Inf
or Inf
, respectively, the set is interpreted as a one-sided interval.
Interval(s::GreaterThan{<:AbstractFloat})
Construct a (right-unbounded) Interval
equivalent to the given GreaterThan
set.
Interval(s::LessThan{<:AbstractFloat})
Construct a (left-unbounded) Interval
equivalent to the given LessThan
set.
Interval(s::EqualTo{<:Real})
Construct a (degenerate) Interval
equivalent to the given EqualTo
set.
MathOptInterface.Integer
— TypeInteger()
The set of integers $\mathbb{Z}$.
MathOptInterface.ZeroOne
— TypeZeroOne()
The set $\{ 0, 1 \}$.
MathOptInterface.Semicontinuous
— TypeSemicontinuous{T <: Real}(lower::T,upper::T)
The set $\{0\} \cup [lower,upper]$.
MathOptInterface.Semiinteger
— TypeSemiinteger{T <: Real}(lower::T,upper::T)
The set $\{0\} \cup \{lower,lower+1,\ldots,upper-1,upper\}$.
Vector sets
List of recognized vector sets.
MathOptInterface.Reals
— TypeReals(dimension)
The set $\mathbb{R}^{dimension}$ (containing all points) of dimension dimension
.
MathOptInterface.Zeros
— TypeZeros(dimension)
The set $\{ 0 \}^{dimension}$ (containing only the origin) of dimension dimension
.
MathOptInterface.Nonnegatives
— TypeNonnegatives(dimension)
The nonnegative orthant $\{ x \in \mathbb{R}^{dimension} : x \ge 0 \}$ of dimension dimension
.
MathOptInterface.Nonpositives
— TypeNonpositives(dimension)
The nonpositive orthant $\{ x \in \mathbb{R}^{dimension} : x \le 0 \}$ of dimension dimension
.
MathOptInterface.NormInfinityCone
— TypeNormInfinityCone(dimension)
The $\ell_\infty$-norm cone $\{ (t,x) \in \mathbb{R}^{dimension} : t \ge \lVert x \rVert_\infty = \max_i \lvert x_i \rvert \}$ of dimension dimension
.
MathOptInterface.NormOneCone
— TypeNormOneCone(dimension)
The $\ell_1$-norm cone $\{ (t,x) \in \mathbb{R}^{dimension} : t \ge \lVert x \rVert_1 = \sum_i \lvert x_i \rvert \}$ of dimension dimension
.
MathOptInterface.SecondOrderCone
— TypeSecondOrderCone(dimension)
The second-order cone (or Lorenz cone or $\ell_2$-norm cone) $\{ (t,x) \in \mathbb{R}^{dimension} : t \ge \lVert x \rVert_2 \}$ of dimension dimension
.
MathOptInterface.RotatedSecondOrderCone
— TypeRotatedSecondOrderCone(dimension)
The rotated second-order cone $\{ (t,u,x) \in \mathbb{R}^{dimension} : 2tu \ge \lVert x \rVert_2^2, t,u \ge 0 \}$ of dimension dimension
.
MathOptInterface.GeometricMeanCone
— TypeGeometricMeanCone(dimension)
The geometric mean cone $\{ (t,x) \in \mathbb{R}^{n+1} : x \ge 0, t \le \sqrt[n]{x_1 x_2 \cdots x_n} \}$ of dimension dimension
${}=n+1$.
Duality note
The dual of the geometric mean cone is $\{ (u, v) \in \mathbb{R}^{n+1} : u \le 0, v \ge 0, -u \le n \sqrt[n]{\prod_i v_i} \}$ of dimension dimension
${}=n+1$.
MathOptInterface.ExponentialCone
— TypeExponentialCone()
The 3-dimensional exponential cone $\{ (x,y,z) \in \mathbb{R}^3 : y \exp (x/y) \le z, y > 0 \}$.
MathOptInterface.DualExponentialCone
— TypeDualExponentialCone()
The 3-dimensional dual exponential cone $\{ (u,v,w) \in \mathbb{R}^3 : -u \exp (v/u) \le \exp(1) w, u < 0 \}$.
MathOptInterface.PowerCone
— TypePowerCone{T <: Real}(exponent::T)
The 3-dimensional power cone $\{ (x,y,z) \in \mathbb{R}^3 : x^{exponent} y^{1-exponent} \ge |z|, x \ge 0, y \ge 0 \}$ with parameter exponent
.
MathOptInterface.DualPowerCone
— TypeDualPowerCone{T <: Real}(exponent::T)
The 3-dimensional power cone $\{ (u,v,w) \in \mathbb{R}^3 : (\frac{u}{exponent})^{exponent} (\frac{v}{1-exponent})^{1-exponent} \ge |w|, u \ge 0, v \ge 0 \}$ with parameter exponent
.
MathOptInterface.RelativeEntropyCone
— TypeRelativeEntropyCone(dimension)
The relative entropy cone $\{ (u, v, w) \in \mathbb{R}^{1+2n} : u \ge \sum_{i=1}^n w_i \log (\frac{w_i}{v_i}), v_i \ge 0, w_i \ge 0 \}$ of dimension dimension
${}=2n+1$.
Duality note
The dual of the relative entropy cone is $\{ (u, v, w) \in \mathbb{R}^{1+2n} : \forall i, w_i \ge u (\log (\frac{u}{v_i}) - 1), v_i \ge 0, u > 0 \}$ of dimension dimension
${}=2n+1$.
MathOptInterface.NormSpectralCone
— TypeNormSpectralCone(row_dim, column_dim)
The epigraph of the matrix spectral norm (maximum singular value function) $\{ (t, X) \in \mathbb{R}^{1 + row_dim \times column_dim} : t \ge \sigma_1(X) \}$ where $\sigma_i$ is the $i$th singular value of the matrix $X$ of row dimension row_dim
and column dimension column_dim
. The matrix X is vectorized by stacking the columns, matching the behavior of Julia's vec
function.
MathOptInterface.NormNuclearCone
— TypeNormNuclearCone(row_dim, column_dim)
The epigraph of the matrix nuclear norm (sum of singular values function) $\{ (t, X) \in \mathbb{R}^{1 + row_dim \times column_dim} : t \ge \sum_i \sigma_i(X) \}$ where $\sigma_i$ is the $i$th singular value of the matrix $X$ of row dimension row_dim
and column dimension column_dim
. The matrix X is vectorized by stacking the columns, matching the behavior of Julia's vec
function.
MathOptInterface.SOS1
— TypeSOS1{T <: Real}(weights::Vector{T})
The set corresponding to the special ordered set (SOS) constraint of type 1. Of the variables in the set, at most one can be nonzero. The weights
induce an ordering of the variables; as such, they should be unique values. The kth element in the set corresponds to the kth weight in weights
. See here for a description of SOS constraints and their potential uses.
MathOptInterface.SOS2
— TypeSOS2{T <: Real}(weights::Vector{T})
The set corresponding to the special ordered set (SOS) constraint of type 2. Of the variables in the set, at most two can be nonzero, and if two are nonzero, they must be adjacent in the ordering of the set. The weights
induce an ordering of the variables; as such, they should be unique values. The kth element in the set corresponds to the kth weight in weights
. See here for a description of SOS constraints and their potential uses.
MathOptInterface.IndicatorSet
— TypeIndicatorSet{A, S <: AbstractScalarSet}(set::S)
$\{(y, x) \in \{0, 1\} \times \mathbb{R}^n : y = 0 \implies x \in set\}$ when A
is ACTIVATE_ON_ZERO
and $\{(y, x) \in \{0, 1\} \times \mathbb{R}^n : y = 1 \implies x \in set\}$ when A
is ACTIVATE_ON_ONE
.
S
has to be a sub-type of AbstractScalarSet
. A
is one of the value of the ActivationCond
enum. IndicatorSet
is used with a VectorAffineFunction
holding the indicator variable first.
Example: $\{(y, x) \in \{0, 1\} \times \mathbb{R}^2 : y = 1 \implies x_1 + x_2 \leq 9 \}$
f = MOI.VectorAffineFunction(
[MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, y)),
MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(1.0, x1)),
MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(1.0, x2)),
],
[0.0, 0.0],
)
indicator_set = MOI.IndicatorSet{MOI.ACTIVATE_ON_ONE}(MOI.LessThan(9.0))
MOI.add_constraint(model, f, indicator_set)
MathOptInterface.Complements
— TypeComplements(dimension::Int)
The set corresponding to a mixed complementarity constraint.
Complementarity constraints should be specified with an AbstractVectorFunction
-in-Complements(dimension)
constraint.
The dimension of the vector-valued function F
must be 2 * dimension
. This defines a complementarity constraint between the scalar function F[i]
and the variable in F[i + dimension]
. Thus, F[i + dimension]
must be interpretable as a single variable x_i
(e.g., 1.0 * x + 0.0
).
The mixed complementarity problem consists of finding x_i
in the interval [lb, ub]
(i.e., in the set Interval(lb, ub)
), such that the following holds:
F_i(x) == 0
iflb_i < x_i < ub_i
F_i(x) >= 0
iflb_i == x_i
F_i(x) <= 0
ifx_i == ub_i
Classically, the bounding set for x_i
is Interval(0, Inf)
, which recovers: 0 <= F_i(x) ⟂ x_i >= 0
, where the ⟂
operator implies F_i(x) * x_i = 0
.
Examples
The problem:
x -in- Interval(-1, 1)
[-4 * x - 3, x] -in- Complements(1)
defines the mixed complementarity problem where the following holds:
-4 * x - 3 == 0
if-1 < x < 1
-4 * x - 3 >= 0
ifx == -1
-4 * x - 3 <= 0
ifx == 1
There are three solutions:
x = -3/4
withF(x) = 0
x = -1
withF(x) = 1
x = 1
withF(x) = -7
The function F
can also be defined in terms of single variables. For example, the problem:
[x_3, x_4] -in- Nonnegatives(2)
[x_1, x_2, x_3, x_4] -in- Complements(2)
defines the complementarity problem where 0 <= x_1 ⟂ x_3 >= 0
and 0 <= x_2 ⟂ x_4 >= 0
.
Matrix sets
Matrix sets are vectorized in order to be subtypes of AbstractVectorSet
. For sets of symmetric matrices, storing both the (i, j)
and (j, i)
elements is redundant so there exists the AbstractSymmetricMatrixSetTriangle
set to represent only the vectorization of the upper triangular part of the matrix. When the matrix of expressions constrained to be in the set is not symmetric and hence the (i, j)
and (j, i)
elements should be constrained to be symmetric, the AbstractSymmetricMatrixSetSquare
set can be used. The Bridges.Constraint.SquareBridge
can transform a set from the square form to the triangular_form
by adding appropriate constraints if the (i, j)
and (j, i)
expressions are different.
MathOptInterface.AbstractSymmetricMatrixSetTriangle
— Typeabstract type AbstractSymmetricMatrixSetTriangle <: AbstractVectorSet end
Abstract supertype for subsets of the (vectorized) cone of symmetric matrices, with side_dimension
rows and columns. The entries of the upper-right triangular part of the matrix are given column by column (or equivalently, the entries of the lower-left triangular part are given row by row). A vectorized cone of dimension
$n$ corresponds to a square matrix with side dimension $\sqrt{1/4 + 2 n} - 1/2$. (Because a $d \times d$ matrix has $d(d + 1) / 2$ elements in the upper or lower triangle.)
Examples
The matrix
\[\begin{bmatrix} 1 & 2 & 4\\ 2 & 3 & 5\\ 4 & 5 & 6 \end{bmatrix}\]
has side_dimension
3 and vectorization $(1, 2, 3, 4, 5, 6)$.
Note
Two packed storage formats exist for symmetric matrices, the respective orders of the entries are:
- upper triangular column by column (or lower triangular row by row);
- lower triangular column by column (or upper triangular row by row).
The advantage of the first format is the mapping between the (i, j)
matrix indices and the k
index of the vectorized form. It is simpler and does not depend on the side dimension of the matrix. Indeed,
- the entry of matrix indices
(i, j)
has vectorized indexk = div((j - 1) * j, 2) + i
if $i \leq j$ andk = div((i - 1) * i, 2) + j
if $j \leq i$; - and the entry with vectorized index
k
has matrix indicesi = div(1 + isqrt(8k - 7), 2)
andj = k - div((i - 1) * i, 2)
orj = div(1 + isqrt(8k - 7), 2)
andi = k - div((j - 1) * j, 2)
.
Duality note
The scalar product for the symmetric matrix in its vectorized form is the sum of the pairwise product of the diagonal entries plus twice the sum of the pairwise product of the upper diagonal entries; see [p. 634, 1]. This has important consequence for duality.
Consider for example the following problem (PositiveSemidefiniteConeTriangle
is a subtype of AbstractSymmetricMatrixSetTriangle
)
\[\begin{align*} & \max_{x \in \mathbb{R}} & x \\ & \;\;\text{s.t.} & (1, -x, 1) & \in \text{PositiveSemidefiniteConeTriangle}(2). \end{align*}\]
The dual is the following problem
\[\begin{align*} & \min_{x \in \mathbb{R}^3} & y_1 + y_3 \\ & \;\;\text{s.t.} & 2y_2 & = 1\\ & & y & \in \text{PositiveSemidefiniteConeTriangle}(2). \end{align*}\]
Why do we use $2y_2$ in the dual constraint instead of $y_2$ ? The reason is that $2y_2$ is the scalar product between $y$ and the symmetric matrix whose vectorized form is $(0, 1, 0)$. Indeed, with our modified scalar products we have
\[\langle (0, 1, 0), (y_1, y_2, y_3) \rangle = \mathrm{trace} \begin{pmatrix} 0 & 1\\ 1 & 0 \end{pmatrix} \begin{pmatrix} y_1 & y_2\\ y_2 & y_3 \end{pmatrix} = 2y_2.\]
References
[1] Boyd, S. and Vandenberghe, L.. Convex optimization. Cambridge university press, 2004.
MathOptInterface.AbstractSymmetricMatrixSetSquare
— Typeabstract type AbstractSymmetricMatrixSetSquare <: AbstractVectorSet end
Abstract supertype for subsets of the (vectorized) cone of symmetric matrices, with side_dimension
rows and columns. The entries of the matrix are given column by column (or equivalently, row by row). The matrix is both constrained to be symmetric and to have its triangular_form
belong to the corresponding set. That is, if the functions in entries $(i, j)$ and $(j, i)$ are different, then a constraint will be added to make sure that the entries are equal.
Examples
PositiveSemidefiniteConeSquare
is a subtype of AbstractSymmetricMatrixSetSquare
and constraining the matrix
\[\begin{bmatrix} 1 & -y\\ -z & 0\\ \end{bmatrix}\]
to be symmetric positive semidefinite can be achieved by constraining the vector $(1, -z, -y, 0)$ (or $(1, -y, -z, 0)$) to belong to the PositiveSemidefiniteConeSquare(2)
. It both constrains $y = z$ and $(1, -y, 0)$ (or $(1, -z, 0)$) to be in PositiveSemidefiniteConeTriangle(2)
, since triangular_form(PositiveSemidefiniteConeSquare)
is PositiveSemidefiniteConeTriangle
.
MathOptInterface.side_dimension
— Functionside_dimension(set::Union{AbstractSymmetricMatrixSetTriangle,
AbstractSymmetricMatrixSetSquare})
Side dimension of the matrices in set
. By convention, it should be stored in the side_dimension
field but if it is not the case for a subtype of AbstractSymmetricMatrixSetTriangle
, the method should be implemented for this subtype.
MathOptInterface.triangular_form
— Functiontriangular_form(S::Type{<:AbstractSymmetricMatrixSetSquare})
triangular_form(set::AbstractSymmetricMatrixSetSquare)
Return the AbstractSymmetricMatrixSetTriangle
corresponding to the vectorization of the upper triangular part of matrices in the AbstractSymmetricMatrixSetSquare
set.
List of recognized matrix sets.
MathOptInterface.PositiveSemidefiniteConeTriangle
— TypePositiveSemidefiniteConeTriangle(side_dimension) <: AbstractSymmetricMatrixSetTriangle
The (vectorized) cone of symmetric positive semidefinite matrices, with side_dimension
rows and columns. See AbstractSymmetricMatrixSetTriangle
for more details on the vectorized form.
MathOptInterface.PositiveSemidefiniteConeSquare
— TypePositiveSemidefiniteConeSquare(side_dimension) <: AbstractSymmetricMatrixSetSquare
The cone of symmetric positive semidefinite matrices, with side length side_dimension
. See AbstractSymmetricMatrixSetSquare
for more details on the vectorized form.
The entries of the matrix are given column by column (or equivalently, row by row). The matrix is both constrained to be symmetric and to be positive semidefinite. That is, if the functions in entries $(i, j)$ and $(j, i)$ are different, then a constraint will be added to make sure that the entries are equal.
Examples
Constraining the matrix
\[\begin{bmatrix} 1 & -y\\ -z & 0\\ \end{bmatrix}\]
to be symmetric positive semidefinite can be achieved by constraining the vector $(1, -z, -y, 0)$ (or $(1, -y, -z, 0)$) to belong to the PositiveSemidefiniteConeSquare(2)
. It both constrains $y = z$ and $(1, -y, 0)$ (or $(1, -z, 0)$) to be in PositiveSemidefiniteConeTriangle(2)
.
MathOptInterface.LogDetConeTriangle
— TypeLogDetConeTriangle(side_dimension)
The log-determinant cone $\{ (t, u, X) \in \mathbb{R}^{2 + d(d+1)/2} : t \le u \log(\det(X/u)), u > 0 \}$ where the matrix X
is represented in the same symmetric packed format as in the PositiveSemidefiniteConeTriangle
. The argument side_dimension
is the side dimension of the matrix X
, i.e., its number of rows or columns.
MathOptInterface.LogDetConeSquare
— TypeLogDetConeSquare(side_dimension)
The log-determinant cone $\{ (t, u, X) \in \mathbb{R}^{2 + d^2} : t \le u \log(\det(X/u)), X \text{ symmetric}, u > 0 \}$ where the matrix X
is represented in the same format as in the PositiveSemidefiniteConeSquare
. Similarly to PositiveSemidefiniteConeSquare
, constraints are added to ensures that X
is symmetric. The argument side_dimension
is the side dimension of the matrix X
, i.e., its number of rows or columns.
MathOptInterface.RootDetConeTriangle
— TypeRootDetConeTriangle(side_dimension)
The root-determinant cone $\{ (t, X) \in \mathbb{R}^{1 + d(d+1)/2} : t \le \det(X)^{1/d} \}$ where the matrix X
is represented in the same symmetric packed format as in the PositiveSemidefiniteConeTriangle
. The argument side_dimension
is the side dimension of the matrix X
, i.e., its number of rows or columns.
MathOptInterface.RootDetConeSquare
— TypeRootDetConeSquare(side_dimension)
The root-determinant cone $\{ (t, X) \in \mathbb{R}^{1 + d^2} : t \le \det(X)^{1/d}, X \text{ symmetric} \}$ where the matrix X
is represented in the same format as in the PositiveSemidefiniteConeSquare
. Similarly to PositiveSemidefiniteConeSquare
, constraints are added to ensure that X
is symmetric. The argument side_dimension
is the side dimension of the matrix X
, i.e., its number of rows or columns.
Modifications
Functions for modifying objective and constraint functions.
MathOptInterface.modify
— FunctionConstraint Function
modify(model::ModelLike, ci::ConstraintIndex, change::AbstractFunctionModification)
Apply the modification specified by change
to the function of constraint ci
.
An ModifyConstraintNotAllowed
error is thrown if modifying constraints is not supported by the model model
.
Examples
modify(model, ci, ScalarConstantChange(10.0))
Objective Function
modify(model::ModelLike, ::ObjectiveFunction, change::AbstractFunctionModification)
Apply the modification specified by change
to the objective function of model
. To change the function completely, call set
instead.
An ModifyObjectiveNotAllowed
error is thrown if modifying objectives is not supported by the model model
.
Examples
modify(model, ObjectiveFunction{ScalarAffineFunction{Float64}}(), ScalarConstantChange(10.0))
MathOptInterface.AbstractFunctionModification
— TypeAbstractFunctionModification
An abstract supertype for structs which specify partial modifications to functions, to be used for making small modifications instead of replacing the functions entirely.
MathOptInterface.ScalarConstantChange
— TypeScalarConstantChange{T}(new_constant::T)
A struct used to request a change in the constant term of a scalar-valued function. Applicable to ScalarAffineFunction
and ScalarQuadraticFunction
.
MathOptInterface.VectorConstantChange
— TypeVectorConstantChange{T}(new_constant::Vector{T})
A struct used to request a change in the constant vector of a vector-valued function. Applicable to VectorAffineFunction
and VectorQuadraticFunction
.
MathOptInterface.ScalarCoefficientChange
— TypeScalarCoefficientChange{T}(variable::VariableIndex, new_coefficient::T)
A struct used to request a change in the linear coefficient of a single variable in a scalar-valued function. Applicable to ScalarAffineFunction
and ScalarQuadraticFunction
.
MathOptInterface.MultirowChange
— TypeMultirowChange{T}(variable::VariableIndex, new_coefficients::Vector{Tuple{Int64, T}})
A struct used to request a change in the linear coefficients of a single variable in a vector-valued function. New coefficients are specified by (output_index, coefficient)
tuples. Applicable to VectorAffineFunction
and VectorQuadraticFunction
.
Nonlinear programming (NLP)
Attributes
MathOptInterface.NLPBlock
— TypeNLPBlock()
Holds the NLPBlockData
that represents a set of nonlinear constraints, and optionally a nonlinear objective.
MathOptInterface.NLPBoundsPair
— TypeNLPBoundsPair(lower,upper)
A struct holding a pair of lower and upper bounds. -Inf
and Inf
can be used to indicate no lower or upper bound, respectively.
MathOptInterface.NLPBlockData
— Typestruct NLPBlockData
constraint_bounds::Vector{NLPBoundsPair}
evaluator::AbstractNLPEvaluator
has_objective::Bool
end
A struct
encoding a set of nonlinear constraints of the form $lb \le g(x) \le ub$ and, if has_objective == true
, a nonlinear objective function $f(x)$. constraint_bounds
holds the pairs of $lb$ and $ub$ elements. Nonlinear objectives override any objective set by using the ObjectiveFunction
attribute. The evaluator
is a callback object that is used to query function values, derivatives, and expression graphs. If has_objective == false
, then it is an error to query properties of the objective function, and in Hessian-of-the-Lagrangian queries, σ
must be set to zero. Throughout the evaluator, all variables are ordered according to ListOfVariableIndices().
MathOptInterface.NLPBlockDual
— TypeNLPBlockDual(N)
NLPBlockDual()
The Lagrange multipliers on the constraints from the NLPBlock
in result N
. If N
is omitted, it is 1 by default.
MathOptInterface.NLPBlockDualStart
— TypeNLPBlockDualStart()
An initial assignment of the Lagrange multipliers on the constraints from the NLPBlock
that the solver may use to warm-start the solve.
NLP evaluator methods
MathOptInterface.AbstractNLPEvaluator
— TypeAbstractNLPEvaluator
Abstract supertype for the callback object used in NLPBlock
.
MathOptInterface.initialize
— Functioninitialize(d::AbstractNLPEvaluator, requested_features::Vector{Symbol})
Must be called before any other methods. The vector requested_features
lists features requested by the solver. These may include :Grad
for gradients of $f$, :Jac
for explicit Jacobians of $g$, :JacVec
for Jacobian-vector products, :HessVec
for Hessian-vector and Hessian-of-Lagrangian-vector products, :Hess
for explicit Hessians and Hessian-of-Lagrangians, and :ExprGraph
for expression graphs.
MathOptInterface.features_available
— Functionfeatures_available(d::AbstractNLPEvaluator)
Returns the subset of features available for this problem instance, as a list of symbols in the same format as in initialize
.
MathOptInterface.eval_objective
— Functioneval_objective(d::AbstractNLPEvaluator, x)
Evaluate the objective $f(x)$, returning a scalar value.
MathOptInterface.eval_constraint
— Functioneval_constraint(d::AbstractNLPEvaluator, g, x)
Evaluate the constraint function $g(x)$, storing the result in the vector g
which must be of the appropriate size.
MathOptInterface.eval_objective_gradient
— Functioneval_objective_gradient(d::AbstractNLPEvaluator, g, x)
Evaluate $\nabla f(x)$ as a dense vector, storing the result in the vector g
which must be of the appropriate size.
MathOptInterface.jacobian_structure
— Functionjacobian_structure(d::AbstractNLPEvaluator)::Vector{Tuple{Int64,Int64}}
Returns the sparsity structure of the Jacobian matrix $J_g(x) = \left[ \begin{array}{c} \nabla g_1(x) \\ \nabla g_2(x) \\ \vdots \\ \nabla g_m(x) \end{array}\right]$ where $g_i$ is the $i\text{th}$ component of $g$. The sparsity structure is assumed to be independent of the point $x$. Returns a vector of tuples, (row, column)
, where each indicates the position of a structurally nonzero element. These indices are not required to be sorted and can contain duplicates, in which case the solver should combine the corresponding elements by adding them together.
MathOptInterface.hessian_lagrangian_structure
— Functionhessian_lagrangian_structure(d::AbstractNLPEvaluator)::Vector{Tuple{Int64,Int64}}
Returns the sparsity structure of the Hessian-of-the-Lagrangian matrix $\nabla^2 f + \sum_{i=1}^m \nabla^2 g_i$ as a vector of tuples, where each indicates the position of a structurally nonzero element. These indices are not required to be sorted and can contain duplicates, in which case the solver should combine the corresponding elements by adding them together. Any mix of lower and upper-triangular indices is valid. Elements (i,j)
and (j,i)
, if both present, should be treated as duplicates.
MathOptInterface.eval_constraint_jacobian
— Functioneval_constraint_jacobian(d::AbstractNLPEvaluator, J, x)
Evaluates the sparse Jacobian matrix $J_g(x) = \left[ \begin{array}{c} \nabla g_1(x) \\ \nabla g_2(x) \\ \vdots \\ \nabla g_m(x) \end{array}\right]$. The result is stored in the vector J
in the same order as the indices returned by jacobian_structure
.
MathOptInterface.eval_constraint_jacobian_product
— Functioneval_constraint_jacobian_product(d::AbstractNLPEvaluator, y, x, w)
Computes the Jacobian-vector product $J_g(x)w$, storing the result in the vector y
.
MathOptInterface.eval_constraint_jacobian_transpose_product
— Functioneval_constraint_jacobian_transpose_product(d::AbstractNLPEvaluator, y, x, w)
Computes the Jacobian-transpose-vector product $J_g(x)^Tw$, storing the result in the vector y
.
MathOptInterface.eval_hessian_lagrangian
— Functioneval_hessian_lagrangian(d::AbstractNLPEvaluator, H, x, σ, μ)
Given scalar weight σ
and vector of constraint weights μ
, computes the sparse Hessian-of-the-Lagrangian matrix $\sigma\nabla^2 f(x) + \sum_{i=1}^m \mu_i \nabla^2 g_i(x)$, storing the result in the vector H
in the same order as the indices returned by hessian_lagrangian_structure
.
MathOptInterface.eval_hessian_lagrangian_product
— Functioneval_hessian_lagrangian_product(d::AbstractNLPEvaluator, h, x, v, σ, μ)
Given scalar weight σ
and vector of constraint weights μ
, computes the Hessian-of-the-Lagrangian-vector product $\left(\sigma\nabla^2 f(x) + \sum_{i=1}^m \mu_i \nabla^2 g_i(x)\right)v$, storing the result in the vector h
.
MathOptInterface.objective_expr
— Functionobjective_expr(d::AbstractNLPEvaluator)
Returns an expression graph for the objective function as a standard Julia Expr
object. All sums and products are flattened out as simple Expr(:+,...)
and Expr(:*,...)
objects. The symbol x
is used as a placeholder for the vector of decision variables. No other undefined symbols are permitted; coefficients are embedded as explicit values. For example, the expression $x_1+\sin(x_2/\exp(x_3))$ would be represented as the Julia object :(x[1] + sin(x[2]/exp(x[3])))
. Each integer index is wrapped in a VariableIndex
. See the Julia manual for more information on the structure of Expr
objects. There are currently no restrictions on recognized functions; typically these will be built-in Julia functions like ^
, exp
, log
, cos
, tan
, sqrt
, etc., but modeling interfaces may choose to extend these basic functions.
MathOptInterface.constraint_expr
— Functionconstraint_expr(d::AbstractNLPEvaluator, i)
Returns an expression graph for the $i\text{th}$ constraint in the same format as described above, with an additional comparison operator indicating the sense of and bounds on the constraint. The right-hand side of the comparison must be a constant; that is, :(x[1]^3 <= 1)
is allowed, while :(1 <= x[1]^3)
is not valid. Double-sided constraints are allowed, in which case both the lower bound and upper bounds should be constants; for example, :(-1 <= cos(x[1]) + sin(x[2]) <= 1)
is valid.
Errors
When an MOI call fails on a model, precise errors should be thrown when possible instead of simply calling error
with a message. The docstrings for the respective methods describe the errors that the implementation should thrown in certain situations. This error-reporting system allows code to distinguish between internal errors (that should be shown to the user) and unsupported operations which may have automatic workarounds.
When an invalid index is used in an MOI call, an InvalidIndex
should be thrown:
MathOptInterface.InvalidIndex
— Typestruct InvalidIndex{IndexType<:Index} <: Exception
index::IndexType
end
An error indicating that the index index
is invalid.
As discussed in JuMP mapping, for scalar constraint with a nonzero function constant, a ScalarFunctionConstantNotZero
exception may be thrown:
MathOptInterface.ScalarFunctionConstantNotZero
— Typestruct ScalarFunctionConstantNotZero{T, F, S} <: Exception
constant::T
end
An error indicating that the constant part of the function in the constraint F
-in-S
is nonzero.
Some SingleVariable
constraints cannot be combined on the same variable:
MathOptInterface.LowerBoundAlreadySet
— TypeLowerBoundAlreadySet{S1, S2}
Error thrown when setting a SingleVariable
-in-S2
when a SingleVariable
-in-S1
has already been added and the sets S1
, S2
both set a lower bound, i.e. they are EqualTo
, GreaterThan
, Interval
, Semicontinuous
or Semiinteger
.
MathOptInterface.UpperBoundAlreadySet
— TypeUpperBoundAlreadySet{S1, S2}
Error thrown when setting a SingleVariable
-in-S2
when a SingleVariable
-in-S1
has already been added and the sets S1
, S2
both set an upper bound, i.e. they are EqualTo
, LessThan
, Interval
, Semicontinuous
or Semiinteger
.
As discussed in AbstractCallback
, trying to get
attributes inside a callback may throw:
MathOptInterface.OptimizeInProgress
— Typestruct OptimizeInProgress{AttrType<:AnyAttribute} <: Exception
attr::AttrType
end
Error thrown from optimizer when MOI.get(optimizer, attr)
is called inside an AbstractCallback
while it is only defined once optimize!
has completed. This can only happen when is_set_by_optimize(attr)
is true
.
Trying to submit the wrong type of AbstractSubmittable
inside an AbstractCallback
(e.g., a UserCut
inside a LazyConstraintCallback
) will throw:
MathOptInterface.InvalidCallbackUsage
— Typestruct InvalidCallbackUsage{C, S} <: Exception
callback::C
submittable::S
end
An error indicating that submittable
cannot be submitted inside callback
.
For example, UserCut
cannot be submitted inside LazyConstraintCallback
.
The rest of the errors defined in MOI fall in two categories represented by the following two abstract types:
MathOptInterface.UnsupportedError
— TypeUnsupportedError <: Exception
Abstract type for error thrown when an element is not supported by the model.
MathOptInterface.NotAllowedError
— TypeNotAllowedError <: Exception
Abstract type for error thrown when an operation is supported but cannot be applied in the current state of the model.
The different UnsupportedError
and NotAllowedError
are the following errors:
MathOptInterface.UnsupportedAttribute
— Typestruct UnsupportedAttribute{AttrType} <: UnsupportedError
attr::AttrType
message::String
end
An error indicating that the attribute attr
is not supported by the model, i.e. that supports
returns false
.
MathOptInterface.SetAttributeNotAllowed
— Typestruct SetAttributeNotAllowed{AttrType} <: NotAllowedError
attr::AttrType
message::String # Human-friendly explanation why the attribute cannot be set
end
An error indicating that the attribute attr
is supported (see supports
) but cannot be set for some reason (see the error string).
MathOptInterface.AddVariableNotAllowed
— Typestruct AddVariableNotAllowed <: NotAllowedError
message::String # Human-friendly explanation why the attribute cannot be set
end
An error indicating that variables cannot be added to the model.
MathOptInterface.UnsupportedConstraint
— Typestruct UnsupportedConstraint{F<:AbstractFunction, S<:AbstractSet} <: UnsupportedError
message::String # Human-friendly explanation why the attribute cannot be set
end
An error indicating that constraints of type F
-in-S
are not supported by the model, i.e. that supports_constraint
returns false
.
MathOptInterface.AddConstraintNotAllowed
— Typestruct AddConstraintNotAllowed{F<:AbstractFunction, S<:AbstractSet} <: NotAllowedError
message::String # Human-friendly explanation why the attribute cannot be set
end
An error indicating that constraints of type F
-in-S
are supported (see supports_constraint
) but cannot be added.
MathOptInterface.ModifyConstraintNotAllowed
— Typestruct ModifyConstraintNotAllowed{F<:AbstractFunction, S<:AbstractSet,
C<:AbstractFunctionModification} <: NotAllowedError
constraint_index::ConstraintIndex{F, S}
change::C
message::String
end
An error indicating that the constraint modification change
cannot be applied to the constraint of index ci
.
MathOptInterface.ModifyObjectiveNotAllowed
— Typestruct ModifyObjectiveNotAllowed{C<:AbstractFunctionModification} <: NotAllowedError
change::C
message::String
end
An error indicating that the objective modification change
cannot be applied to the objective.
MathOptInterface.DeleteNotAllowed
— Typestruct DeleteNotAllowed{IndexType <: Index} <: NotAllowedError
index::IndexType
message::String
end
An error indicating that the index index
cannot be deleted.
MathOptInterface.UnsupportedSubmittable
— Typestruct UnsupportedSubmittable{SubmitType} <: UnsupportedError
sub::SubmitType
message::String
end
An error indicating that the submittable sub
is not supported by the model, i.e. that supports
returns false
.
MathOptInterface.SubmitNotAllowed
— Typestruct SubmitNotAllowed{SubmitTyp<:AbstractSubmittable} <: NotAllowedError
sub::SubmitType
message::String # Human-friendly explanation why the attribute cannot be set
end
An error indicating that the submittable sub
is supported (see supports
) but cannot be added for some reason (see the error string).
Models
Utilities.Model
provides an implementation of a ModelLike
that efficiently supports all functions and sets defined within MOI. However, given the extensibility of MOI, this might not over all use cases.
Utilities.UniversalFallback
is a layer that sits on top of any ModelLike
and provides non-specialized (slower) fallbacks for constraints and attributes that the underlying ModeLike
does not support.
For advanced use cases that need efficient support for functions and sets defined outside of MOI (but still known at compile time), we provide the Utilities.@model
macro.
MathOptInterface.Utilities.Model
— TypeAn implementation of ModelLike
that supports all functions and sets defined in MOI. It is parameterized by the coefficient type.
Examples
model = Model{Float64}()
x = add_variable(model)
MathOptInterface.Utilities.UniversalFallback
— TypeUniversalFallback
The UniversalFallback
can be applied on a MathOptInterface.ModelLike
model
to create the model UniversalFallback(model)
supporting any constraint and attribute. This allows to have a specialized implementation in model
for performance critical constraints and attributes while still supporting other attributes with a small performance penalty. Note that model
is unaware of constraints and attributes stored by UniversalFallback
so this is not appropriate if model
is an optimizer (for this reason, MathOptInterface.optimize!
has not been implemented). In that case, optimizer bridges should be used instead.
MathOptInterface.Utilities.@model
— Macromacro model(
model_name,
scalar_sets,
typed_scalar_sets,
vector_sets,
typed_vector_sets,
scalar_functions,
typed_scalar_functions,
vector_functions,
typed_vector_functions,
is_optimizer = false
)
Creates a type model_name
implementing the MOI model interface and containing scalar_sets
scalar sets typed_scalar_sets
typed scalar sets, vector_sets
vector sets, typed_vector_sets
typed vector sets, scalar_functions
scalar functions, typed_scalar_functions
typed scalar functions, vector_functions
vector functions and typed_vector_functions
typed vector functions. To give no set/function, write ()
, to give one set S
, write (S,)
.
The function MathOptInterface.SingleVariable
should not be given in scalar_functions
. The model supports MathOptInterface.SingleVariable
-in-F
constraints where F
is MathOptInterface.EqualTo
, MathOptInterface.GreaterThan
, MathOptInterface.LessThan
, MathOptInterface.Interval
, MathOptInterface.Integer
, MathOptInterface.ZeroOne
, MathOptInterface.Semicontinuous
or MathOptInterface.Semiinteger
. The sets supported with the MathOptInterface.SingleVariable
cannot be controlled from the macro, use the UniversalFallback
to support more sets.
This macro creates a model specialized for specific types of constraint, by defining specialized structures and methods. To create a model that, in addition to be optimized for specific constraints, also support arbitrary constraints and attributes, use UniversalFallback
.
This implementation of the MOI model certifies that the constraint indices, in addition to being different between constraints F
-in-S
for the same types F
and S
, are also different between constraints for different types F
and S
. This means that for constraint indices ci1
, ci2
of this model, ci1 == ci2
if and only if ci1.value == ci2.value
. This fact can be used to use the the value of the index directly in a dictionary representing a mapping between constraint indices and something else.
If is_optimizer = true
, the resulting struct is a subtype of of MOIU.AbstractOptimizer
, which is a subtype of MathOptInterface.AbstractOptimizer
, otherwise, it is a subtype of MOIU.AbstractModelLike
, which is a subtype of MathOptInterface.ModelLike
.
Examples
The model describing an linear program would be:
@model(LPModel, # Name of model
(), # untyped scalar sets
(MOI.EqualTo, MOI.GreaterThan, MOI.LessThan, MOI.Interval), # typed scalar sets
(MOI.Zeros, MOI.Nonnegatives, MOI.Nonpositives), # untyped vector sets
(), # typed vector sets
(), # untyped scalar functions
(MOI.ScalarAffineFunction,), # typed scalar functions
(MOI.VectorOfVariables,), # untyped vector functions
(MOI.VectorAffineFunction,), # typed vector functions
false
)
Let MOI
denote MathOptInterface
, MOIU
denote MOI.Utilities
and MOIU.ConstraintEntry{F, S}
be defined as MOI.Tuple{MOI.ConstraintIndex{F, S}, F, S}
. The macro would create the types:
struct LPModelScalarConstraints{T, F <: MOI.AbstractScalarFunction} <: MOIU.Constraints{F}
equalto::Vector{MOIU.ConstraintEntry{F, MOI.EqualTo{T}}}
greaterthan::Vector{MOIU.ConstraintEntry{F, MOI.GreaterThan{T}}}
lessthan::Vector{MOIU.ConstraintEntry{F, MOI.LessThan{T}}}
interval::Vector{MOIU.ConstraintEntry{F, MOI.Interval{T}}}
end
struct LPModelVectorConstraints{T, F <: MOI.AbstractVectorFunction} <: MOIU.Constraints{F}
zeros::Vector{MOIU.ConstraintEntry{F, MOI.Zeros}}
nonnegatives::Vector{MOIU.ConstraintEntry{F, MOI.Nonnegatives}}
nonpositives::Vector{MOIU.ConstraintEntry{F, MOI.Nonpositives}}
end
mutable struct LPModel{T} <: MOIU.AbstractModel{T}
name::String
sense::MOI.OptimizationSense
objective::Union{MOI.SingleVariable, MOI.ScalarAffineFunction{T}, MOI.ScalarQuadraticFunction{T}}
num_variables_created::Int64
# If nothing, no variable has been deleted so the indices of the
# variables are VI.(1:num_variables_created)
variable_indices::Union{Nothing, Set{MOI.VariableIndex}}
# Union of flags of `S` such that a `SingleVariable`-in-`S`
# constraint was added to the model and not deleted yet.
single_variable_mask::Vector{UInt8}
# Lower bound set by `SingleVariable`-in-`S` where `S`is
# `GreaterThan{T}`, `EqualTo{T}` or `Interval{T}`.
lower_bound::Vector{T}
# Lower bound set by `SingleVariable`-in-`S` where `S`is
# `LessThan{T}`, `EqualTo{T}` or `Interval{T}`.
upper_bound::Vector{T}
var_to_name::Dict{MOI.VariableIndex, String}
# If `nothing`, the dictionary hasn't been constructed yet.
name_to_var::Union{Dict{String, MOI.VariableIndex}, Nothing}
nextconstraintid::Int64
con_to_name::Dict{MOI.ConstraintIndex, String}
name_to_con::Union{Dict{String, MOI.ConstraintIndex}, Nothing}
constrmap::Vector{Int}
scalaraffinefunction::LPModelScalarConstraints{T, MOI.ScalarAffineFunction{T}}
vectorofvariables::LPModelVectorConstraints{T, MOI.VectorOfVariables}
vectoraffinefunction::LPModelVectorConstraints{T, MOI.VectorAffineFunction{T}}
end
The type LPModel
implements the MathOptInterface API except methods specific to solver models like optimize!
or getattribute
with VariablePrimal
.
Bridges
Bridges can be used for automatic reformulation of constrained variables (i.e. variables added with add_constrained_variable
/add_constrained_variables
) or constraints into equivalent formulations using constrained variables and constraints of different types. There are two important concepts to distinguish:
Bridges.AbstractBridge
s are recipes implementing a specific reformulation. Bridges are not directly subtypes ofBridges.AbstractBridge
, they are eitherBridges.Variable.AbstractBridge
orBridges.Constraint.AbstractBridge
.Bridges.AbstractBridgeOptimizer
is a layer that can be applied to anotherModelLike
to apply the reformulation. TheBridges.LazyBridgeOptimizer
automatically chooses the appropriate bridges to use when a constrained variable or constraint is not supported by using the list of bridges that were added to it byBridges.add_bridge
.Bridges.full_bridge_optimizer
wraps a model in aBridges.LazyBridgeOptimizer
where all the bridges defined in MOI are added. This is the recommended way to use bridges in the Testing guideline, and JuMP automatically callsBridges.full_bridge_optimizer
when attaching an optimizer.Bridges.debug_supports_constraint
andBridges.debug_supports
allow introspection into the bridge selection rationale ofBridges.LazyBridgeOptimizer
.
Most bridges are added by default in Bridges.full_bridge_optimizer
. However, for technical reasons, some bridges are not added by default, for instance: Bridges.Constraint.SOCtoPSDBridge
, Bridges.Constraint.SOCtoNonConvexQuadBridge
and Bridges.Constraint.RSOCtoNonConvexQuadBridge
. See the docs of those bridges for more information.
It is possible to add those bridges and also user defined bridges, following one of the two methods. We present the examples for: Bridges.Constraint.SOCtoNonConvexQuadBridge
.
The first option is to add the specific bridges to a bridged_model
optimizer, with coefficient type T
. The bridged_model
optimizer itself must have been constructed with a Bridges.LazyBridgeOptimizer
. Once such a optimizer is available, we can proceed using using Bridges.add_bridge
:
MOIB.add_bridge(bridged_model, SOCtoNonConvexQuadBridge{T})
Alternatively, it is possible to create a Bridges.Constraint.SingleBridgeOptimizer
and wrap an existing model
with it:
const SOCtoNonConvexQuad{T, OT<:ModelLike} = Bridges.Constraint.SingleBridgeOptimizer{Bridges.Constraint.SOCtoNonConvexQuadBridge{T}, OT}
bridged_model = SOCtoNonConvexQuad{Float64}(model)
Those procedures could be applied to user define bridges. For the bridges defined in MathOptInterface, the Bridges.Constraint.SingleBridgeOptimizer
's are already created, therefore, for the case of Bridges.Constraint.SOCtoNonConvexQuadBridge
, one could simply use the existing optimizer:
bridged_model = Bridges.Constraint.SOCtoNonConvexQuad{Float64}(model)
MathOptInterface.Bridges.AbstractBridge
— TypeAbstractBridge
Represents a bridged constraint or variable in a MathOptInterface.Bridges.AbstractBridgeOptimizer
. It contains the indices of the variables and constraints that it has created in the model. These can be obtained using MathOptInterface.NumberOfVariables
, MathOptInterface.ListOfVariableIndices
, MathOptInterface.NumberOfConstraints
and MathOptInterface.ListOfConstraintIndices
using MathOptInterface.get
with the bridge in place of the MathOptInterface.ModelLike
. Attributes of the bridged model such as MathOptInterface.ConstraintDual
and MathOptInterface.ConstraintPrimal
, can be obtained using MathOptInterface.get
with the bridge in place of the constraint index. These calls are used by the MathOptInterface.Bridges.AbstractBridgeOptimizer
to communicate with the bridge so they should be implemented by the bridge.
MathOptInterface.Bridges.AbstractBridgeOptimizer
— TypeAbstractBridgeOptimizer
A bridge optimizer applies given constraint bridges to a given optimizer thus extending the types of supported constraints. The attributes of the inner optimizer are automatically transformed to make the bridges transparent, e.g. the variables and constraints created by the bridges are hidden.
By convention, the inner optimizer should be stored in a model
field and the dictionary mapping constraint indices to bridges should be stored in a bridges
field. If a bridge optimizer deviates from these conventions, it should implement the functions MOI.optimize!
and bridge
respectively.
MathOptInterface.Bridges.LazyBridgeOptimizer
— TypeLazyBridgeOptimizer{OT<:MOI.ModelLike} <: AbstractBridgeOptimizer
The LazyBridgeOptimizer
combines several bridges, which are added using the add_bridge
function. Whenever a constraint is added, it only attempts to bridge it if it is not supported by the internal model (hence its name Lazy
). When bridging a constraint, it selects the minimal number of bridges needed. For instance, a constraint F
-in-S
can be bridged into a constraint F1
-in-S1
(supported by the internal model) using bridge 1 or bridged into a constraint F2
-in-S2
(unsupported by the internal model) using bridge 2 which can then be bridged into a constraint F3
-in-S3
(supported by the internal model) using bridge 3, it will choose bridge 1 as it allows to bridge F
-in-S
using only one bridge instead of two if it uses bridge 2 and 3.
MathOptInterface.Bridges.add_bridge
— Functionadd_bridge(b::LazyBridgeOptimizer, BT::Type{<:AbstractBridge})
Enable the use of the bridges of type BT
by b
.
MathOptInterface.Bridges.remove_bridge
— Functionremove_bridge(b::LazyBridgeOptimizer, BT::Type{<:AbstractBridge})
Disable the use of the bridges of type BT
by b
.
MathOptInterface.Bridges.has_bridge
— Functionhas_bridge(b::LazyBridgeOptimizer, BT::Type{<:AbstractBridge})
Return a Bool
indicating whether the bridges of type BT
are used by b
.
MathOptInterface.Bridges.full_bridge_optimizer
— Functionfull_bridge_optimizer(model::MOI.ModelLike, ::Type{T}) where T
Returns a LazyBridgeOptimizer
bridging model
for every bridge defined in this package and for the coefficient type T
.
MathOptInterface.Bridges.debug_supports_constraint
— Functiondebug_supports_constraint(
b::LazyBridgeOptimizer, F::Type{<:MOI.AbstractFunction},
S::Type{<:MOI.AbstractSet}; io::IO = Base.stdout)
Prints to io
explanations for the value of MOI.supports_constraint
with the same arguments.
MathOptInterface.Bridges.debug_supports
— Functiondebug_supports(b::LazyBridgeOptimizer, ::MOI.ObjectiveFunction{F}; io::IO = Base.stdout) where F
Prints to io
explanations for the value of MOI.supports
with the same arguments.
Variable bridges
When variables are added, either free with add_variable
/add_variables
, or constrained with add_constrained_variable
/add_constrained_variables
, variable bridges allow to return bridged variables that do not correspond to variables of the underlying model. These variables are parametrized by variables of the underlying model and this parametrization can be obtained with Bridges.bridged_variable_function
. Similarly, the variables of the underlying model that were created by the bridge can be expressed in terms of the bridged variables and this expression can be obtained with Bridges.unbridged_variable_function
. For instance, consider a model bridged by the Bridges.Variable.VectorizeBridge
:
model = MOI.Utilities.Model{Float64}()
bridged_model = MOI.Bridges.Variable.Vectorize{Float64}(model)
bridged_variable, bridged_constraint = MOI.add_constrained_variable(bridged_model, MOI.GreaterThan(1.0))
# output
(VariableIndex(-1), MOI.ConstraintIndex{MOI.SingleVariable,MOI.GreaterThan{Float64}}(-1))
The constrained variable in MOI.GreaterThan(1.0)
returned is a bridged variable as its index in negative. In model
, a constrained variable in MOI.Nonnegatives
is created:
inner_variables = MOI.get(model, MOI.ListOfVariableIndices())
# output
1-element Array{VariableIndex,1}:
VariableIndex(1)
In the functions used for adding constraints or setting the objective to bridged_model
, bridged_variable
is substituted for inner_variables[1]
plus 1:
MOI.Bridges.bridged_variable_function(bridged_model, bridged_variable)
# output
MOI.ScalarAffineFunction{Float64}(MOI.ScalarAffineTerm{Float64}[ScalarAffineTerm{Float64}(1.0, VariableIndex(1))], 1.0)
When getting ConstraintFunction
or ObjectiveFunction
, inner_variables[1]
is substituted for bridged_variable
minus 1:
MOI.Bridges.unbridged_variable_function(bridged_model, inner_variables[1])
# output
MOI.ScalarAffineFunction{Float64}(MOI.ScalarAffineTerm{Float64}[ScalarAffineTerm{Float64}(1.0, VariableIndex(-1))], -1.0)
A notable exception is with Bridges.Variable.ZerosBridge
where no variable is created in the underlying model as the variables are simply transformed to zeros. When this bridge is used, it is not possible to recover functions with bridged variables from functions of the inner model. Consider for instance that we create two zero variables:
model = MOI.Utilities.Model{Float64}()
bridged_model = MOI.Bridges.Variable.Zeros{Float64}(model)
bridged_variables, bridged_constraint = MOI.add_constrained_variables(bridged_model, MOI.Zeros(2))
# output
(MOI.VariableIndex[VariableIndex(-1), VariableIndex(-2)], MOI.ConstraintIndex{MOI.VectorOfVariables,MOI.Zeros}(-1))
Consider the following functions in the variables of bridged_model
:
func = MOI.Utilities.operate(+, Float64, MOI.SingleVariable.(bridged_variables)...)
# output
MOI.ScalarAffineFunction{Float64}(MOI.ScalarAffineTerm{Float64}[ScalarAffineTerm{Float64}(1.0, VariableIndex(-1)), ScalarAffineTerm{Float64}(1.0, VariableIndex(-2))], 0.0)
We can obtain the equivalent function in the variables of model
as follows:
inner_func = MOI.Bridges.bridged_function(bridged_model, func)
# output
MOI.ScalarAffineFunction{Float64}(MOI.ScalarAffineTerm{Float64}[], 0.0)
However, it's not possible to invert this operation. Indeed, since the bridged variables are substituted for zeros, we cannot deduce whether they were present in the initial function.
MOI.Bridges.unbridged_function(bridged_model, inner_func)
# output
ERROR: Cannot unbridge function because some variables are bridged by variable bridges that do not support reverse mapping, e.g., `ZerosBridge`.
Stacktrace:
[1] error(::String, ::String, ::String) at ./error.jl:42
[2] throw_if_cannot_unbridge at /home/blegat/.julia/dev/MathOptInterface/src/Bridges/Variable/map.jl:343 [inlined]
[3] unbridged_function(::MOI.Bridges.Variable.SingleBridgeOptimizer{MOI.Bridges.Variable.ZerosBridge{Float64},MOI.Utilities.Model{Float64}}, ::MOI.ScalarAffineFunction{Float64}) at /home/blegat/.julia/dev/MOI/src/Bridges/bridge_optimizer.jl:920
[4] top-level scope at none:0
MathOptInterface.Bridges.Variable.AbstractBridge
— TypeAbstractBridge
Subtype of MathOptInterface.Bridges.AbstractBridge
for variable bridges.
MathOptInterface.Bridges.bridged_variable_function
— Functionbridged_variable_function(b::AbstractBridgeOptimizer,
vi::MOI.VariableIndex)
Return a MOI.AbstractScalarFunction
of variables of b.model
that equals vi
. That is, if the variable vi
is bridged, it returns its expression in terms of the variables of b.model
. Otherwise, it returns MOI.SingleVariable(vi)
.
MathOptInterface.Bridges.unbridged_variable_function
— Functionunbridged_variable_function(b::AbstractBridgeOptimizer,
vi::MOI.VariableIndex)
Return a MOI.AbstractScalarFunction
of variables of b
that equals vi
. That is, if the variable vi
is an internal variable of b.model
created by a bridge but not visible to the user, it returns its expression in terms of the variables of bridged variables. Otherwise, it returns MOI.SingleVariable(vi)
.
Below is the list of variable bridges implemented in this package.
MathOptInterface.Bridges.Variable.ZerosBridge
— TypeZerosBridge{T} <: Bridges.Variable.AbstractBridge
Transforms constrained variables in MathOptInterface.Zeros
to zeros, which ends up creating no variables in the underlying model. The bridged variables are therefore similar to parameters with zero values. Parameters with non-zero value can be created with constrained variables in MOI.EqualTo
by combining a VectorizeBridge
and this bridge. The functions cannot be unbridged, given a function, we cannot determine, if the bridged variables were used. The dual values cannot be determined by the bridge but they can be determined by the bridged optimizer using MathOptInterface.Utilities.get_fallback
if a CachingOptimizer
is used (since ConstraintFunction
cannot be got as functions cannot be unbridged).
MathOptInterface.Bridges.Variable.FreeBridge
— TypeFreeBridge{T} <: Bridges.Variable.AbstractBridge
Transforms constrained variables in MOI.Reals
to the difference of constrained variables in MOI.Nonnegatives
.
MathOptInterface.Bridges.Variable.NonposToNonnegBridge
— TypeNonposToNonnegBridge{T, F<:MOI.AbstractVectorFunction, G<:MOI.AbstractVectorFunction} <:
FlipSignBridge{T, MOI.Nonpositives, MOI.Nonnegatives, F, G}
Transforms constrained variables in Nonpositives
into constrained variables in Nonnegatives
.
MathOptInterface.Bridges.Variable.VectorizeBridge
— TypeVectorizeBridge{T, S}
Transforms a constrained variable in scalar_set_type(S, T)
where S <: VectorLinearSet
into a constrained vector of one variable in S
. For instance, VectorizeBridge{Float64, MOI.Nonnegatives}
transforms a constrained variable in MOI.GreaterThan{Float64}
into a constrained vector of one variable in MOI.Nonnegatives
.
MathOptInterface.Bridges.Variable.SOCtoRSOCBridge
— TypeSOCtoRSOCBridge{T} <: Bridges.Variable.AbstractBridge
Same transformation as MOI.Bridges.Constraint.SOCRBridge
.
MathOptInterface.Bridges.Variable.RSOCtoSOCBridge
— TypeRSOCtoSOCBridge{T} <: Bridges.Variable.AbstractBridge
Same transformation as MOI.Bridges.Constraint.RSOCBridge
.
MathOptInterface.Bridges.Variable.RSOCtoPSDBridge
— TypeRSOCtoPSDBridge{T} <: Bridges.Variable.AbstractBridge
Transforms constrained variables in MathOptInterface.RotatedSecondOrderCone
to constrained variables in MathOptInterface.PositiveSemidefiniteConeTriangle
.
For each bridge defined in this package, a corresponding Bridges.Variable.SingleBridgeOptimizer
is available with the same name without the "Bridge" suffix, e.g., SplitInterval
is a SingleBridgeOptimizer
for the SplitIntervalBridge
. Moreover, they are all added in the Bridges.LazyBridgeOptimizer
returned by Bridges.full_bridge_optimizer
as it calls Bridges.Variable.add_all_bridges
.
MathOptInterface.Bridges.Variable.SingleBridgeOptimizer
— TypeSingleBridgeOptimizer{BT<:AbstractBridge, OT<:MOI.ModelLike} <: AbstractBridgeOptimizer
The SingleBridgeOptimizer
bridges any constrained variables supported by the bridge BT
. This is in contrast with the MathOptInterface.Bridges.LazyBridgeOptimizer
which only bridges the constrained variables that are unsupported by the internal model, even if they are supported by one of its bridges.
Two bridge optimizers using variable bridges cannot be used together as both of them assume that the underlying model only returns variable indices with nonnegative values.
MathOptInterface.Bridges.Variable.add_all_bridges
— Functionadd_all_bridges(bridged_model, T::Type)
Add all bridges defined in the Bridges.Variable
submodule to bridged_model
. The coefficient type used is T
.
Constraint bridges
When constraints are added with add_constraint
, constraint bridges allow to return bridged constraints that do not correspond to constraints of the underlying model. These constraints were enforced by an equivalent formulation that added constraints (and possibly also variables) in the underlying model. For instance, consider a model bridged by the Bridges.Constraint.SplitIntervalBridge
:
model = MOI.Utilities.Model{Float64}()
bridged_model = MOI.Bridges.Constraint.SplitInterval{Float64}(model)
x, y = MOI.add_variables(bridged_model, 2)
func = MOI.Utilities.operate(+, Float64, MOI.SingleVariable(x), MOI.SingleVariable(y))
c = MOI.add_constraint(bridged_model, func, MOI.Interval(1.0, 2.0))
# output
MOI.ConstraintIndex{MOI.ScalarAffineFunction{Float64},MOI.Interval{Float64}}(1)
We can see the constraint was bridged to two constraints, one for each bound, in the inner model.
MOI.get(model, MOI.ListOfConstraints())
# output
2-element Array{Tuple{DataType,DataType},1}:
(MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64})
(MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64})
However, bridged_model
transparently hides these constraints and creates the illusion that an interval constraint was created.
MOI.get(bridged_model, MOI.ListOfConstraints())
# output
1-element Array{Tuple{DataType,DataType},1}:
(MOI.ScalarAffineFunction{Float64}, MOI.Interval{Float64})
It is nevertheless possible to differentiate this constraint from a constraint added to the inner model by asking whether it is bridged:
MOI.Bridges.is_bridged(bridged_model, c)
# output
true
MathOptInterface.Bridges.Constraint.AbstractBridge
— TypeAbstractBridge
Subtype of MathOptInterface.Bridges.AbstractBridge
for constraint bridges.
Below is the list of constraint bridges implemented in this package.
MathOptInterface.Bridges.Constraint.GreaterToIntervalBridge
— TypeGreaterToIntervalBridge{T, F<:MOI.AbstractScalarFunction} <:
AbstractToIntervalBridge{T, MOI.GreaterThan{T}, F}
Transforms a F
-in-GreaterThan{T}
constraint into an F
-in-Interval{T}
constraint.
MathOptInterface.Bridges.Constraint.LessToIntervalBridge
— TypeLessToIntervalBridge{T, F<:MOI.AbstractScalarFunction} <:
AbstractToIntervalBridge{T, MOI.LessThan{T}, F}
Transforms a F
-in-LessThan{T}
constraint into an F
-in-Interval{T}
constraint.
MathOptInterface.Bridges.Constraint.GreaterToLessBridge
— TypeGreaterToLessBridge{T, F<:MOI.AbstractScalarFunction, G<:MOI.AbstractScalarFunction} <:
FlipSignBridge{T, MOI.GreaterThan{T}, MOI.LessThan{T}, F, G}
Transforms a G
-in-GreaterThan{T}
constraint into an F
-in-LessThan{T}
constraint.
MathOptInterface.Bridges.Constraint.LessToGreaterBridge
— TypeLessToGreaterBridge{T, F<:MOI.AbstractScalarFunction, G<:MOI.AbstractScalarFunction} <:
FlipSignBridge{T, MOI.LessThan{T}, MOI.GreaterThan{T}, F, G}
Transforms a G
-in-LessThan{T}
constraint into an F
-in-GreaterThan{T}
constraint.
MathOptInterface.Bridges.Constraint.NonnegToNonposBridge
— TypeNonnegToNonposBridge{T, F<:MOI.AbstractVectorFunction, G<:MOI.AbstractVectorFunction} <:
FlipSignBridge{T, MOI.Nonnegatives, MOI.Nonpositives, F, G}
Transforms a G
-in-Nonnegatives
constraint into a F
-in-Nonpositives
constraint.
MathOptInterface.Bridges.Constraint.NonposToNonnegBridge
— TypeNonposToNonnegBridge{T, F<:MOI.AbstractVectorFunction, G<:MOI.AbstractVectorFunction} <:
FlipSignBridge{T, MOI.Nonpositives, MOI.Nonnegatives, F, G}
Transforms a G
-in-Nonpositives
constraint into a F
-in-Nonnegatives
constraint.
MathOptInterface.Bridges.Constraint.VectorizeBridge
— TypeVectorizeBridge{T, F, S, G}
Transforms a constraint G
-in-scalar_set_type(S, T)
where S <: VectorLinearSet
to F
-in-S
.
Examples
The constraint SingleVariable
-in-LessThan{Float64}
becomes VectorAffineFunction{Float64}
-in-Nonpositives
, where T = Float64
, F = VectorAffineFunction{Float64}
, S = Nonpositives
, and G = SingleVariable
.
MathOptInterface.Bridges.Constraint.ScalarizeBridge
— TypeScalarizeBridge{T, F, S}
Transforms a constraint AbstractVectorFunction
-in-vector_set_type(S)
where S <: LPCone{T}
to F
-in-S
.
MathOptInterface.Bridges.Constraint.ScalarSlackBridge
— TypeScalarSlackBridge{T, F, S}
The ScalarSlackBridge
converts a constraint G
-in-S
where G
is a function different from SingleVariable
into the constraints F
-in-EqualTo{T}
and SingleVariable
-in-S
. F
is the result of subtracting a SingleVariable
from G
. Typically G
is the same as F
, but that is not mandatory.
MathOptInterface.Bridges.Constraint.VectorSlackBridge
— TypeVectorSlackBridge{T, F, S}
The VectorSlackBridge
converts a constraint G
-in-S
where G
is a function different from VectorOfVariables
into the constraints F
in-Zeros
and VectorOfVariables
-in-S
. F
is the result of subtracting a VectorOfVariables
from G
. Tipically G
is the same as F
, but that is not mandatory.
MathOptInterface.Bridges.Constraint.ScalarFunctionizeBridge
— TypeScalarFunctionizeBridge{T, S}
The ScalarFunctionizeBridge
converts a constraint SingleVariable
-in-S
into the constraint ScalarAffineFunction{T}
-in-S
.
MathOptInterface.Bridges.Constraint.VectorFunctionizeBridge
— TypeVectorFunctionizeBridge{T, S}
The VectorFunctionizeBridge
converts a constraint VectorOfVariables
-in-S
into the constraint VectorAffineFunction{T}
-in-S
.
MathOptInterface.Bridges.Constraint.SplitIntervalBridge
— TypeSplitIntervalBridge{T, F, S, LS, US}
The SplitIntervalBridge
splits a F
-in-S
constraint into a F
-in-LS
and a F
-in-US
constraint where we have either:
S = MOI.Interval{T}
,LS = MOI.GreaterThan{T}
andUS = MOI.LessThan{T}
,S = MOI.EqualTo{T}
,LS = MOI.GreaterThan{T}
andUS = MOI.LessThan{T}
, orS = MOI.Zeros
,LS = MOI.Nonnegatives
andUS = MOI.Nonpositives
.
For instance, if F
is MOI.ScalarAffineFunction
and S
is MOI.Interval
, it transforms the constraint $l ≤ ⟨a, x⟩ + α ≤ u$ into the constraints $⟨a, x⟩ + α ≥ l$ and $⟨a, x⟩ + α ≤ u$.
MathOptInterface.Bridges.Constraint.RSOCBridge
— TypeRSOCBridge{T, F, G}
The RotatedSecondOrderCone
is SecondOrderCone
representable; see [1, p. 104]. Indeed, we have $2tu = (t/√2 + u/√2)^2 - (t/√2 - u/√2)^2$ hence
\[2tu \ge \lVert x \rVert_2^2\]
is equivalent to
\[(t/√2 + u/√2)^2 \ge \lVert x \rVert_2^2 + (t/√2 - u/√2)^2.\]
We can therefore use the transformation $(t, u, x) \mapsto (t/√2+u/√2, t/√2-u/√2, x)$. Note that the linear transformation is a symmetric involution (i.e. it is its own transpose and its own inverse). That means in particular that the norm is of constraint primal and duals are preserved by the tranformation.
[1] Ben-Tal, Aharon, and Arkadi Nemirovski. Lectures on modern convex optimization: analysis, algorithms, and engineering applications. Society for Industrial and Applied Mathematics, 2001.
MathOptInterface.Bridges.Constraint.SOCRBridge
— TypeSOCRBridge{T, F, G}
We simply do the inverse transformation of RSOCBridge
. In fact, as the transformation is an involution, we do the same transformation.
MathOptInterface.Bridges.Constraint.QuadtoSOCBridge
— TypeQuadtoSOCBridge{T}
The set of points x
satisfying the constraint
\[\frac{1}{2}x^T Q x + a^T x + b \le 0\]
is a convex set if Q
is positive semidefinite and is the union of two convex cones if a
and b
are zero (i.e. homogeneous case) and Q
has only one negative eigenvalue. Currently, only the non-homogeneous transformation is implemented, see the Note section below for more details.
Non-homogeneous case
If Q
is positive semidefinite, there exists U
such that $Q = U^T U$, the inequality can then be rewritten as
\[\|U x\|_2^2 \le 2 (-a^T x - b)\]
which is equivalent to the membership of (1, -a^T x - b, Ux)
to the rotated second-order cone.
Homogeneous case
If Q
has only one negative eigenvalue, the set of x
such that $x^T Q x \le 0$ is the union of a convex cone and its opposite. We can choose which one to model by checking the existence of bounds on variables as shown below.
Second-order cone
If Q
is diagonal and has eigenvalues (1, 1, -1)
, the inequality $x^2 + x^2 \le z^2$ combined with $z \ge 0$ defines the Lorenz cone (i.e. the second-order cone) but when combined with $z \le 0$, it gives the opposite of the second order cone. Therefore, we need to check if the variable z
has a lower bound 0 or an upper bound 0 in order to determine which cone is
Rotated second-order cone
The matrix Q
corresponding to the inequality $x^2 \le 2yz$ has one eigenvalue 1 with eigenvectors (1, 0, 0)
and (0, 1, -1)
and one eigenvalue -1
corresponding to the eigenvector (0, 1, 1)
. Hence if we intersect this union of two convex cone with the halfspace $x + y \ge 0$, we get the rotated second-order cone and if we intersect it with the halfspace $x + y \le 0$ we get the opposite of the rotated second-order cone. Note that y
and z
have the same sign since yz
is nonnegative hence $x + y \ge 0$ is equivalent to $x \ge 0$ and $y \ge 0$.
Note
The check for existence of bound can be implemented (but inefficiently) with the current interface but if bound is removed or transformed (e.g. ≤ 0
transformed into ≥ 0
) then the bridge is no longer valid. For this reason the homogeneous version of the bridge is not implemented yet.
MathOptInterface.Bridges.Constraint.SOCtoNonConvexQuadBridge
— TypeSOCtoNonConvexQuadBridge{T}
Constraints of the form VectorOfVariables
-in-SecondOrderCone
can be transformed into a ScalarQuadraticFunction
-in-LessThan
and a ScalarAffineFunction
-in-GreaterThan
. Indeed, the definition of the second-order cone
\[t \ge \lVert x \rVert_2 \ (1)\]
is equivalent to
\[\sum x_i^2 \le t^2 (2)\]
with $t \ge 0$. (3)
WARNING This transformation starts from a convex constraint (1) and creates a non-convex constraint (2), because the Q matrix associated with the constraint 2 has one negative eigenvalue. This might be wrongly interpreted by a solver. Some solvers can look at (2) and understand that it is a second order cone, but this is not a general rule. For these reasons this bridge is not automatically added by MOI.Bridges.full_bridge_optimizer
. Care is recommended when adding this bridge to a optimizer.
MathOptInterface.Bridges.Constraint.RSOCtoNonConvexQuadBridge
— TypeRSOCtoNonConvexQuadBridge{T}
Constraints of the form VectorOfVariables
-in-SecondOrderCone
can be transformed into a ScalarQuadraticFunction
-in-LessThan
and a ScalarAffineFunction
-in-GreaterThan
. Indeed, the definition of the second-order cone
\[2tu \ge \lVert x \rVert_2^2, t,u \ge 0 (1)\]
is equivalent to
\[\sum x_i^2 \le 2tu (2)\]
with $t,u \ge 0$. (3)
WARNING This transformation starts from a convex constraint (1) and creates a non-convex constraint (2), because the Q matrix associated with the constraint 2 has two negative eigenvalues. This might be wrongly interpreted by a solver. Some solvers can look at (2) and understand that it is a rotated second order cone, but this is not a general rule. For these reasons, this bridge is not automatically added by MOI.Bridges.full_bridge_optimizer
. Care is recommended when adding this bridge to an optimizer.
MathOptInterface.Bridges.Constraint.NormInfinityBridge
— TypeNormInfinityBridge{T}
The NormInfinityCone
is representable with LP constraints, since $t \ge \max_i \lvert x_i \rvert$ if and only if $t \ge x_i$ and $t \ge -x_i$ for all $i$.
MathOptInterface.Bridges.Constraint.NormOneBridge
— TypeNormOneBridge{T}
The NormOneCone
is representable with LP constraints, since $t \ge \sum_i \lvert x_i \rvert$ if and only if there exists a vector y such that $t \ge \sum_i y_i$ and $y_i \ge x_i$, $y_i \ge -x_i$ for all $i$.
MathOptInterface.Bridges.Constraint.GeoMeantoRelEntrBridge
— TypeGeoMeantoRelEntrBridge{T}
The geometric mean cone
is representable with a relative entropy constraint and a nonnegative auxiliary variable, since $u \le \prod_{i=1}^n w_i^{1/n}$ is equivalent to $y \ge 0$ and $0 \le u + y \le \prod_{i=1}^n w_i^{1/n}$, and the latter inequality is equivalent to $1 \le \prod_{i=1}^n (\frac{w_i}{u + y})^{1/n}$, which is equivalent to $0 \le \sum_{i=1}^n \log (\frac{w_i}{u + y})^{1/n}$, which is equivalent to $0 \ge \sum_{i=1}^n (u + y) \log (\frac{u + y}{w_i})$. Thus $(u, w) \in GeometricMeanCone(1 + n)$ is representable as $y \ge 0$, $(0, w, (u + y) e) \in RelativeEntropyCone(1 + 2n)$, where $e$ is a vector of ones.
MathOptInterface.Bridges.Constraint.GeoMeanBridge
— TypeGeoMeanBridge{T, F, G, H}
The GeometricMeanCone
is SecondOrderCone
representable; see [1, p. 105]. The reformulation is best described in an example. Consider the cone of dimension 4
\[t \le \sqrt[3]{x_1 x_2 x_3}\]
This can be rewritten as $\exists x_{21} \ge 0$ such that
\[\begin{align*} t & \le x_{21},\\ x_{21}^4 & \le x_1 x_2 x_3 x_{21}. \end{align*}\]
Note that we need to create $x_{21}$ and not use $t^4$ directly as $t$ is allowed to be negative. Now, this is equivalent to
\[\begin{align*} t & \le x_{21}/\sqrt{4},\\ x_{21}^2 & \le 2x_{11} x_{12},\\ x_{11}^2 & \le 2x_1 x_2, & x_{12}^2 & \le 2x_3(x_{21}/\sqrt{4}). \end{align*}\]
[1] Ben-Tal, Aharon, and Arkadi Nemirovski. Lectures on modern convex optimization: analysis, algorithms, and engineering applications. Society for Industrial and Applied Mathematics, 2001.
MathOptInterface.Bridges.Constraint.RelativeEntropyBridge
— TypeRelativeEntropyBridge{T}
The RelativeEntropyCone
is representable with exponential cone and LP constraints, since $u \ge \sum_{i=1}^n w_i \log (\frac{w_i}{v_i})$ if and only if there exists a vector $y$ such that $u \ge \sum_i y_i$ and $y_i \ge w_i \log (\frac{w_i}{v_i})$ or equivalently $v_i \ge w_i \exp (\frac{-y_i}{w_i})$ or equivalently $(-y_i, w_i, v_i) \in ExponentialCone$, for all $i$.
MathOptInterface.Bridges.Constraint.NormSpectralBridge
— TypeNormSpectralBridge{T}
The NormSpectralCone
is representable with a PSD constraint, since $t \ge \sigma_1(X)$ if and only if $[tI X^\top; X tI] \succ 0$.
MathOptInterface.Bridges.Constraint.NormNuclearBridge
— TypeNormNuclearBridge{T}
The NormNuclearCone
is representable with an SDP constraint and extra variables, since $t \ge \sum_i \sigma_i (X)$ if and only if there exists symmetric matrices $U, V$ such that $[U X^\top; X V] \succ 0$ and $t \ge (tr(U) + tr(V)) / 2$.
MathOptInterface.Bridges.Constraint.SquareBridge
— TypeSquareBridge{T, F<:MOI.AbstractVectorFunction,
G<:MOI.AbstractScalarFunction,
TT<:MOI.AbstractSymmetricMatrixSetTriangle,
ST<:MOI.AbstractSymmetricMatrixSetSquare} <: AbstractBridge
The SquareBridge
reformulates the constraint of a square matrix to be in ST
to a list of equality constraints for pair or off-diagonal entries with different expressions and a TT
constraint the upper triangular part of the matrix.
For instance, the constraint for the matrix
\[\begin{pmatrix} 1 & 1 + x & 2 - 3x\\ 1 + x & 2 + x & 3 - x\\ 2 - 3x & 2 + x & 2x \end{pmatrix}\]
to be PSD can be broken down to the constraint of the symmetric matrix
\[\begin{pmatrix} 1 & 1 + x & 2 - 3x\\ \cdot & 2 + x & 3 - x\\ \cdot & \cdot & 2x \end{pmatrix}\]
and the equality constraint between the off-diagonal entries (2, 3) and (3, 2) $2x == 1$. Note that now symmetrization constraint need to be added between the off-diagonal entries (1, 2) and (2, 1) or between (1, 3) and (3, 1) since the expressions are the same.
MathOptInterface.Bridges.Constraint.RootDetBridge
— TypeRootDetBridge{T}
The RootDetConeTriangle
is representable by a PositiveSemidefiniteConeTriangle
and an GeometricMeanCone
constraints; see [1, p. 149]. Indeed, $t \le \det(X)^{1/n}$ if and only if there exists a lower triangular matrix $Δ$ such that
\[\begin{align*} \begin{pmatrix} X & Δ\\ Δ^\top & \mathrm{Diag}(Δ) \end{pmatrix} & \succeq 0\\ t & \le (Δ_{11} Δ_{22} \cdots Δ_{nn})^{1/n} \end{align*}\]
[1] Ben-Tal, Aharon, and Arkadi Nemirovski. Lectures on modern convex optimization: analysis, algorithms, and engineering applications. Society for Industrial and Applied Mathematics, 2001.
MathOptInterface.Bridges.Constraint.LogDetBridge
— TypeLogDetBridge{T}
The LogDetConeTriangle
is representable by a PositiveSemidefiniteConeTriangle
and ExponentialCone
constraints. Indeed, $\log\det(X) = \log(\delta_1) + \cdots + \log(\delta_n)$ where $\delta_1$, ..., $\delta_n$ are the eigenvalues of $X$. Adapting the method from [1, p. 149], we see that $t \le u \log(\det(X/u))$ for $u > 0$ if and only if there exists a lower triangular matrix $Δ$ such that
\[\begin{align*} \begin{pmatrix} X & Δ\\ Δ^\top & \mathrm{Diag}(Δ) \end{pmatrix} & \succeq 0\\ t & \le u \log(Δ_{11}/u) + u \log(Δ_{22}/u) + \cdots + u \log(Δ_{nn}/u) \end{align*}\]
[1] Ben-Tal, Aharon, and Arkadi Nemirovski. Lectures on modern convex optimization: analysis, algorithms, and engineering applications. Society for Industrial and Applied Mathematics, 2001. ```
MathOptInterface.Bridges.Constraint.SOCtoPSDBridge
— TypeThe SOCtoPSDBridge
transforms the second order cone constraint $\lVert x \rVert \le t$ into the semidefinite cone constraints
\[\begin{pmatrix} t & x^\top\\ x & tI \end{pmatrix} \succeq 0\]
Indeed by the Schur Complement, it is positive definite iff
\[\begin{align*} tI & \succ 0\\ t - x^\top (tI)^{-1} x & \succ 0 \end{align*}\]
which is equivalent to
\[\begin{align*} t & > 0\\ t^2 & > x^\top x \end{align*}\]
This bridge is not added by default by MOI.Bridges.full_bridge_optimizer
as bridging second order cone constraints to semidefinite constraints can be achieved by the SOCRBridge
followed by the RSOCtoPSDBridge
while creating a smaller semidefinite constraint.
MathOptInterface.Bridges.Constraint.RSOCtoPSDBridge
— TypeThe RSOCtoPSDBridge
transforms the second order cone constraint $\lVert x \rVert \le 2tu$ with $u \ge 0$ into the semidefinite cone constraints
\[\begin{pmatrix} t & x^\top\\ x & 2uI \end{pmatrix} \succeq 0\]
Indeed by the Schur Complement, it is positive definite iff
\[\begin{align*} uI & \succ 0\\ t - x^\top (2uI)^{-1} x & \succ 0 \end{align*}\]
which is equivalent to
\[\begin{align*} u & > 0\\ 2tu & > x^\top x \end{align*}\]
MathOptInterface.Bridges.Constraint.IndicatorActiveOnFalseBridge
— TypeIndicatorActiveOnFalseBridge{T}
The IndicatorActiveOnFalseBridge
replaces an indicator constraint activated on 0 with a variable $z_0$ with the constraint activated on 1, with a variable $z_1$. It stores the added variable_index
and added constraints:
- $z_1 \in \mathbb{B}$ in
zero_one_cons
- $z_0 + z_1 == 1$ in `
in
disjunction_cons` - The added
ACTIVATE_ON_ONE
indicator constraint inindicator_cons_index
.
MathOptInterface.Bridges.Constraint.IndicatorSOS1Bridge
— TypeIndicatorSOS1Bridge{T, BC <: MOI.AbstractScalarSet}
The IndicatorSOS1Bridge
replaces an indicator constraint of the following form: $z \in \mathbb{B}, z == 1 \implies f(x) \leq b$ with a SOS1 constraint: $z \in \mathbb{B}, w \leq 0, f(x) + w \leq b, SOS1(w, z)$. GreaterThan
constraints are handled in a symmetric way: $z \in \mathbb{B}, z == 1 \implies f(x) \geq b$ is reformulated as: $z \in \mathbb{B}, w \geq 0, f(x) + w \geq b, SOS1(w, z)$. Other scalar sets are handled without a bound constraint: $z \in \mathbb{B}, z == 1 \implies f(x) == b$ is reformulated as: $z \in \mathbb{B}, w \text{ free}, f(x) + w == b, SOS1(w, z)$.
If BC !<: Union{LessThan, GreaterThan}
, bound_constraint_index
is nothing
.
MathOptInterface.Bridges.Constraint.SemiToBinaryBridge
— TypeSemiToBinaryBridge{T, S <: MOI.AbstractScalarSet}
The SemiToBinaryBridge
replaces an Semicontinuous constraint: $x \in \mathsf{Semicontinuous}(l, u)$ is replaced by: $z \in \{0, 1\}$, $x \leq z \cdot u$, $x \geq z \cdot l$.
The SemiToBinaryBridge
replaces an Semiinteger constraint: $x \in Semiinteger(l, u)$ is replaced by: $z \in \{0, 1\}$, $x \in \mathbb{Z}$, $x \leq z \cdot u$, $x \geq z \cdot l$.
MathOptInterface.Bridges.Constraint.ZeroOneBridge
— TypeZeroOneBridge{T}
The ZeroOneBridge
splits a MOI.SingleVariable
-in-MOI.ZeroOne
constraint into a MOI.SingleVariable
-in-MOI.Integer
constraint and a MOI.SingleVariable
-in-MOI.Interval(0, 1)
constraint.
For each bridge defined in this package, a corresponding Bridges.Constraint.SingleBridgeOptimizer
is available with the same name without the "Bridge" suffix, e.g., SplitInterval
is a SingleBridgeOptimizer
for the SplitIntervalBridge
. Moreover, they are all added in the Bridges.LazyBridgeOptimizer
returned by Bridges.full_bridge_optimizer
as it calls Bridges.Constraint.add_all_bridges
.
MathOptInterface.Bridges.Constraint.SingleBridgeOptimizer
— TypeSingleBridgeOptimizer{BT<:AbstractBridge, OT<:MOI.ModelLike} <: AbstractBridgeOptimizer
The SingleBridgeOptimizer
bridges any constraint supported by the bridge BT
. This is in contrast with the MathOptInterface.Bridges.LazyBridgeOptimizer
which only bridges the constraints that are unsupported by the internal model, even if they are supported by one of its bridges.
MathOptInterface.Bridges.Constraint.add_all_bridges
— Functionadd_all_bridges(bridged_model, ::Type{T})
Add all bridges defined in the Bridges.Constraint
submodule to bridged_model
. The coefficient type used is T
.
Objective bridges
When an objective is set with set
, objective bridges allow to set a bridged objective to the underlying model that do not correspond to the objective set by the user. This equivalent formulation may add constraints (and possibly also variables) in the underlying model in addition to setting an objective function.
MathOptInterface.Bridges.Objective.AbstractBridge
— TypeAbstractBridge
Subtype of MathOptInterface.Bridges.AbstractBridge
for objective bridges.
Below is the list of objective bridges implemented in this package.
MathOptInterface.Bridges.Objective.SlackBridge
— TypeSlackBridge{T, F, G}
The SlackBridge
converts an objective function of type G
into a MOI.SingleVariable
objective by creating a slack variable and a F
-in-MOI.LessThan
constraint for minimization or F
-in-MOI.LessThan
constraint for maximization where F
is MOI.Utilities.promote_operation(-, T, G, MOI.SingleVariable}
. Note that when using this bridge, changing the optimization sense is not supported. Set the sense to MOI.FEASIBILITY_SENSE
first to delete the bridge in order to change the sense, then re-add the objective.
MathOptInterface.Bridges.Objective.FunctionizeBridge
— TypeFunctionizeBridge{T}
The FunctionizeBridge
converts a SingleVariable
objective into a ScalarAffineFunction{T}
objective.
For each bridge defined in this package, a corresponding Bridges.Objective.SingleBridgeOptimizer
is available with the same name without the "Bridge" suffix, e.g., Slack
is a SingleBridgeOptimizer
for the SlackBridge
. Moreover, they are all added in the Bridges.LazyBridgeOptimizer
returned by Bridges.full_bridge_optimizer
as it calls Bridges.Objective.add_all_bridges
.
MathOptInterface.Bridges.Objective.SingleBridgeOptimizer
— TypeSingleBridgeOptimizer{BT<:AbstractBridge, OT<:MOI.ModelLike} <: AbstractBridgeOptimizer
The SingleBridgeOptimizer
bridges any objective functions supported by the bridge BT
. This is in contrast with the MathOptInterface.Bridges.LazyBridgeOptimizer
which only bridges the objective functions that are unsupported by the internal model, even if they are supported by one of its bridges.
MathOptInterface.Bridges.Objective.add_all_bridges
— Functionadd_all_bridges(bridged_model, T::Type)
Add all bridges defined in the Bridges.Objective
submodule to bridged_model
. The coefficient type used is T
.
Bridge interface
A bridge should implement the following functions to be usable by a bridge optimizer:
MathOptInterface.Bridges.added_constrained_variable_types
— Functionadded_constrained_variable_types(BT::Type{<:Variable.AbstractBridge})::Vector{Tuple{DataType}}
Return a list of the types of constrained variables that bridges of concrete type BT
add. This is used by the LazyBridgeOptimizer
.
MathOptInterface.Bridges.added_constraint_types
— Functionadded_constraint_types(BT::Type{<:Constraint.AbstractBridge})::Vector{Tuple{DataType, DataType}}
Return a list of the types of constraints that bridges of concrete type BT
add. This is used by the LazyBridgeOptimizer
.
Additionally, variable bridges should implement:
MathOptInterface.Bridges.Variable.supports_constrained_variable
— Functionsupports_constrained_variable(::Type{<:AbstractBridge},
::Type{<:MOI.AbstractSet})::Bool
Return a Bool
indicating whether the bridges of type BT
support bridging constrained variables in S
.
MathOptInterface.Bridges.Variable.concrete_bridge_type
— Functionconcrete_bridge_type(
BT::Type{<:AbstractBridge},
S::Type{<:MOI.AbstractSet},
)::DataType
Return the concrete type of the bridge supporting variables in S
constraints. This function can only be called if MOI.supports_constrained_variable(BT, S)
is true
.
Examples
As a variable in MathOptInterface.GreaterThan
is bridged into variables in MathOptInterface.Nonnegatives
by the VectorizeBridge
:
MOI.Bridges.Variable.concrete_bridge_type(
MOI.Bridges.Variable.VectorizeBridge{Float64},
MOI.GreaterThan{Float64},
)
# output
MathOptInterface.Bridges.Variable.VectorizeBridge{Float64,MathOptInterface.Nonnegatives}
MathOptInterface.Bridges.Variable.bridge_constrained_variable
— Functionbridge_constrained_variable(BT::Type{<:AbstractBridge}, model::MOI.ModelLike,
set::MOI.AbstractSet)
Bridge the constrained variable in set
using bridge BT
to model
and returns a bridge object of type BT
. The bridge type BT
should be a concrete type, that is, all the type parameters of the bridge should be set. Use concrete_bridge_type
to obtain a concrete type for given set types.
constraint bridges should implement:
MathOptInterface.supports_constraint
— MethodMOI.supports_constraint(BT::Type{<:AbstractBridge}, F::Type{<:MOI.AbstractFunction}, S::Type{<:MOI.AbstractSet})::Bool
Return a Bool
indicating whether the bridges of type BT
support bridging F
-in-S
constraints.
MathOptInterface.Bridges.Constraint.concrete_bridge_type
— Functionconcrete_bridge_type(
BT::Type{<:AbstractBridge},
F::Type{<:MOI.AbstractFunction},
S::Type{<:MOI.AbstractSet}
)::DataType
Return the concrete type of the bridge supporting F
-in-S
constraints. This function can only be called if MOI.supports_constraint(BT, F, S)
is true
.
Examples
As a MathOptInterface.SingleVariable
-in-MathOptInterface.Interval
constraint is bridged into a MathOptInterface.SingleVariable
-in-MathOptInterface.GreaterThan
and a MathOptInterface.SingleVariable
-in-MathOptInterface.LessThan
by the SplitIntervalBridge
:
MOI.Bridges.Constraint.concrete_bridge_type(
MOI.Bridges.Constraint.SplitIntervalBridge{Float64},
MOI.SingleVariable,
MOI.Interval{Float64},
)
# output
MathOptInterface.Bridges.Constraint.SplitIntervalBridge{Float64,MathOptInterface.SingleVariable,MathOptInterface.Interval{Float64},MathOptInterface.GreaterThan{Float64},MathOptInterface.LessThan{Float64}}
MathOptInterface.Bridges.Constraint.bridge_constraint
— Functionbridge_constraint(BT::Type{<:AbstractBridge}, model::MOI.ModelLike,
func::AbstractFunction, set::MOI.AbstractSet)
Bridge the constraint func
-in-set
using bridge BT
to model
and returns a bridge object of type BT
. The bridge type BT
should be a concrete type, that is, all the type parameters of the bridge should be set. Use concrete_bridge_type
to obtain a concrete type for given function and set types.
and objective bridges should implement:
MathOptInterface.Bridges.set_objective_function_type
— Functionset_objective_function_type(BT::Type{<:Objective.AbstractBridge})::Type{<:MOI.AbstractScalarFunction}
Return the type of objective function that bridges of concrete type BT
set. This is used by the LazyBridgeOptimizer
.
MathOptInterface.Bridges.Objective.concrete_bridge_type
— Functionconcrete_bridge_type(BT::Type{<:MOI.Bridges.Objective.AbstractBridge},
F::Type{<:MOI.AbstractScalarFunction})::DataType
Return the concrete type of the bridge supporting objective functions of type F
. This function can only be called if MOI.supports_objective_function(BT, F)
is true
.
MathOptInterface.Bridges.Objective.bridge_objective
— Functionbridge_objective(BT::Type{<:MOI.Bridges.Objective.AbstractBridge},
model::MOI.ModelLike,
func::MOI.AbstractScalarFunction)
Bridge the objective function func
using bridge BT
to model
and returns a bridge object of type BT
. The bridge type BT
should be a concrete type, that is, all the type parameters of the bridge should be set. Use concrete_bridge_type
to obtain a concrete type for a given function type.
When querying the NumberOfVariables
, NumberOfConstraints
and ListOfConstraintIndices
, the variables and constraints created by the bridges in the underlying model are hidden by the bridge optimizer. For this purpose, the bridge should provide access to the variables and constraints it has creates by implemented the following methods of get
:
MathOptInterface.get
— MethodMOI.get(b::AbstractBridge, ::MOI.NumberOfVariables)
The number of variables created by the bridge b
in the model.
MathOptInterface.get
— MethodMOI.get(b::AbstractBridge, ::MOI.NumberOfVariables)
The list of variables created by the bridge b
in the model.
MathOptInterface.get
— MethodMOI.get(b::AbstractBridge, ::MOI.NumberOfConstraints{F, S}) where {F, S}
The number of constraints of the type F
-in-S
created by the bridge b
in the model.
MathOptInterface.get
— MethodMOI.get(b::AbstractBridge, ::MOI.ListOfConstraintIndices{F, S}) where {F, S}
A Vector{ConstraintIndex{F,S}}
with indices of all constraints of type F
-inS
created by the bride b
in the model (i.e., of length equal to the value of NumberOfConstraints{F,S}()
).
Copy utilities
The following utilities can be used to implement copy_to
. See Implementing copy for more details.
MathOptInterface.Utilities.automatic_copy_to
— Functionautomatic_copy_to(dest::MOI.ModelLike, src::MOI.ModelLike;
copy_names::Bool=true,
filter_constraints::Union{Nothing, Function}=nothing)
Use Utilities.supports_default_copy_to
and Utilities.supports_allocate_load
to automatically choose between Utilities.default_copy_to
or Utilities.allocate_load
to apply the copy operation.
If the filter_constraints
arguments is given, only the constraints for which this function returns true
will be copied. This function is given a constraint index as argument.
MathOptInterface.Utilities.default_copy_to
— Functiondefault_copy_to(dest::MOI.ModelLike, src::MOI.ModelLike, copy_names::Bool,
filter_constraints::Union{Nothing, Function}=nothing)
Implements MOI.copy_to(dest, src)
by adding the variables and then the constraints and attributes incrementally. The function supports_default_copy_to
can be used to check whether dest
supports the copying a model incrementally.
If the filter_constraints
arguments is given, only the constraints for which this function returns true
will be copied. This function is given a constraint index as argument.
MathOptInterface.Utilities.supports_default_copy_to
— Functionsupports_default_copy_to(model::ModelLike, copy_names::Bool)
Return a Bool
indicating whether the model model
supports default_copy_to(model, src, copy_names=copy_names)
if all the attributes set to src
and constraints added to src
are supported by model
.
This function can be used to determine whether a model can be loaded into model
incrementally or whether it should be cached and copied at once instead. This is used by JuMP to determine whether to add a cache or not in two situations:
- A first cache can be used to store the model as entered by the user as well as the names of variables and constraints. This cache is created if this function returns
false
whencopy_names
istrue
. - If bridges are used, then a second cache can be used to store the bridged model with unnamed variables and constraints. This cache is created if this function returns
false
whencopy_names
isfalse
.
Examples
If MathOptInterface.set
, MathOptInterface.add_variable
and MathOptInterface.add_constraint
are implemented for a model of type MyModel
and names are supported, then MathOptInterface.copy_to
can be implemented as
MOI.Utilities.supports_default_copy_to(model::MyModel, copy_names::Bool) = true
function MOI.copy_to(dest::MyModel, src::MOI.ModelLike; kws...)
return MOI.Utilities.automatic_copy_to(dest, src; kws...)
end
The Utilities.automatic_copy_to
function automatically redirects to Utilities.default_copy_to
.
If names are not supported, simply change the first line by
MOI.supports_default_copy_to(model::MyModel, copy_names::Bool) = !copy_names
The Utilities.default_copy_to
function automatically throws an helpful error in case copy_to
is called with copy_names
equal to true
.
Allocate-Load API
The Allocate-Load API allows solvers that do not support loading the problem incrementally to implement copy_to
in a way that still allows transformations to be applied in the copy between the cache and the model if the transformations are implemented as MOI layers implementing the Allocate-Load API, see Implementing copy for more details.
Loading a model using the Allocate-Load interface consists of two passes through the model data:
- the allocate pass where the model typically records the necessary information about the constraints and attributes such as their number and size. This information may be used by the solver to allocate datastructures of appropriate size.
- the load pass where the model typically loads the constraint and attribute data to the model.
The description above only gives a suggestion of what to achieve in each pass. In fact the exact same constraint and attribute data is provided to each pass, so an implementation of the Allocate-Load API is free to do whatever is more convenient in each pass.
The main difference between each pass, apart from the fact that one is executed before the other during a copy, is that the allocate pass needs to create and return new variable and constraint indices, while during the load pass the appropriate constraint indices are provided.
The Allocate-Load API is not meant to be used outside a copy operation, that is, the interface is not meant to be used to create new constraints with Utilities.allocate_constraint
followed by Utilities.load_constraint
after a solve. This means that the order in which the different functions of the API are called is fixed by Utilities.allocate_load
and models implementing the API can rely on the fact that functions will be called in this order. That is, it can be assumed that the different functions will the called in the following order:
Utilities.allocate_variables
Utilities.allocate
andUtilities.allocate_constraint
Utilities.load_variables
Utilities.load
andUtilities.load_constraint
MathOptInterface.Utilities.allocate_load
— Functionallocate_load(dest::MOI.ModelLike, src::MOI.ModelLike,
filter_constraints::Union{Nothing, Function}=nothing
)
Implements MOI.copy_to(dest, src)
using the Allocate-Load API. The function supports_allocate_load
can be used to check whether dest
supports the Allocate-Load API.
If the filter_constraints
arguments is given, only the constraints for which this function returns true
will be copied. This function is given a constraint index as argument.
MathOptInterface.Utilities.supports_allocate_load
— Functionsupports_allocate_load(model::MOI.ModelLike, copy_names::Bool)::Bool
Return a Bool
indicating whether model
supports allocate_load(model, src, copy_names=copy_names)
if all the attributes set to src
and constraints added to src
are supported by model
.
MathOptInterface.Utilities.allocate_variables
— Functionallocate_variables(model::MOI.ModelLike, nvars::Integer)
Creates nvars
variables and returns a vector of nvars
variable indices.
MathOptInterface.Utilities.allocate
— Functionallocate(model::ModelLike, attr::ModelLikeAttribute, value)
allocate(model::ModelLike, attr::AbstractVariableAttribute, v::VariableIndex, value)
allocate(model::ModelLike, attr::AbstractConstraintAttribute, c::ConstraintIndex, value)
Informs model
that load
will be called with the same arguments after load_variables
is called.
MathOptInterface.Utilities.allocate_constraint
— Functionallocate_constraint(model::MOI.ModelLike, f::MOI.AbstractFunction, s::MOI.AbstractSet)
Returns the index for the constraint to be used in load_constraint
that will be called after load_variables
is called.
MathOptInterface.Utilities.load_variables
— Functionload_variables(model::MOI.ModelLike, nvars::Integer)
Prepares model
for load
and load_constraint
.
MathOptInterface.Utilities.load
— Functionload(model::ModelLike, attr::ModelLikeAttribute, value)
load(model::ModelLike, attr::AbstractVariableAttribute, v::VariableIndex, value)
load(model::ModelLike, attr::AbstractConstraintAttribute, c::ConstraintIndex, value)
This has the same effect that set
with the same arguments except that allocate
should be called first before load_variables
.
MathOptInterface.Utilities.load_constraint
— Functionload_constraint(model::MOI.ModelLike, ci::MOI.ConstraintIndex, f::MOI.AbstractFunction, s::MOI.AbstractSet)
Sets the constraint function and set for the constraint of index ci
.
Caching optimizer
Some solvers do not support incremental definition of optimization models. Nevertheless, you are still able to build incrementally an optimization model with such solvers. MathOptInterface provides a utility, Utilities.CachingOptimizer
, that will store in a ModelLike
the optimization model during its incremental definition. Once the model is completely defined, the CachingOptimizer
specifies all problem information to the underlying solver, all at once.
The function Utilities.state
allows to query the state of the optimizer cached inside a CachingOptimizer
. The state could be:
NO_OPTIMIZER
, if no optimizer is attached;EMPTY_OPTIMIZER
, if the attached optimizer is empty;ATTACHED_OPTIMIZER
, if the attached optimizer is synchronized with the cached model defined inCachingOptimizer
.
The following methods modify the state of the attached optimizer:
Utilities.attach_optimizer
attachs a newoptimizer
to acached_optimizer
with stateEMPTY_OPTIMIZER
. The state ofcached_optimizer
is set toATTACHED_OPTIMIZER
after the call.Utilities.drop_optimizer
drops the underlyingoptimizer
fromcached_optimizer
, without emptying it. The state ofcached_optimizer
is set toNO_OPTIMIZER
after the call.Utilities.reset_optimizer
emptiesoptimizer
insidecached_optimizer
, without droping it. The state ofcached_optimizer
is set toEMPTY_OPTIMIZER
after the call.
The way to operate a CachingOptimizer
depends whether the mode is set to AUTOMATIC
or to MANUAL
.
- In
MANUAL
mode, the state of theCachingOptimizer
changes only if the methodsUtilities.attach_optimizer
,Utilities.reset_optimizer
orUtilities.drop_optimizer
are being called. Any unattended operation results in an error. - In
AUTOMATIC
mode, the state of theCachingOptimizer
changes when necessary. Any modification not supported by the solver (e.g. dropping a constraint) results in a drop to the stateEMPTY_OPTIMIZER
.
When calling Utilities.attach_optimizer
, the CachingOptimizer
copies the cached model to the optimizer with copy_to
. We refer to Implementing copy for more details.
MathOptInterface.Utilities.CachingOptimizer
— TypeCachingOptimizer
CachingOptimizer
is an intermediate layer that stores a cache of the model and links it with an optimizer. It supports incremental model construction and modification even when the optimizer doesn't.
A CachingOptimizer
may be in one of three possible states (CachingOptimizerState
):
NO_OPTIMIZER
: The CachingOptimizer does not have any optimizer.EMPTY_OPTIMIZER
: The CachingOptimizer has an empty optimizer. The optimizer is not synchronized with the cached model.ATTACHED_OPTIMIZER
: The CachingOptimizer has an optimizer, and it is synchronized with the cached model.
A CachingOptimizer
has two modes of operation (CachingOptimizerMode
):
MANUAL
: The only methods that change the state of theCachingOptimizer
areUtilities.reset_optimizer
,Utilities.drop_optimizer
, andUtilities.attach_optimizer
. Attempting to perform an operation in the incorrect state results in an error.AUTOMATIC
: TheCachingOptimizer
changes its state when necessary. For example,optimize!
will automatically callattach_optimizer
(an optimizer must have been previously set). Attempting to add a constraint or perform a modification not supported by the optimizer results in a drop toEMPTY_OPTIMIZER
mode.
MathOptInterface.Utilities.attach_optimizer
— Functionattach_optimizer(model::CachingOptimizer)
Attaches the optimizer to model
, copying all model data into it. Can be called only from the EMPTY_OPTIMIZER
state. If the copy succeeds, the CachingOptimizer
will be in state ATTACHED_OPTIMIZER
after the call, otherwise an error is thrown; see MathOptInterface.copy_to
for more details on which errors can be thrown.
MathOptInterface.Utilities.reset_optimizer
— Functionreset_optimizer(m::CachingOptimizer, optimizer::MOI.AbstractOptimizer)
Sets or resets m
to have the given empty optimizer. Can be called from any state. The CachingOptimizer
will be in state EMPTY_OPTIMIZER
after the call.
reset_optimizer(m::CachingOptimizer)
Detaches and empties the current optimizer. Can be called from ATTACHED_OPTIMIZER
or EMPTY_OPTIMIZER
state. The CachingOptimizer
will be in state EMPTY_OPTIMIZER
after the call.
MathOptInterface.Utilities.drop_optimizer
— Functiondrop_optimizer(m::CachingOptimizer)
Drops the optimizer, if one is present. Can be called from any state. The CachingOptimizer
will be in state NO_OPTIMIZER
after the call.
MathOptInterface.Utilities.state
— Functionstate(m::CachingOptimizer)::CachingOptimizerState
Returns the state of the CachingOptimizer m
. See Utilities.CachingOptimizer
.
MathOptInterface.Utilities.mode
— Functionmode(m::CachingOptimizer)::CachingOptimizerMode
Returns the operating mode of the CachingOptimizer m
. See Utilities.CachingOptimizer
.
Function utilities
The following utilities are available for functions:
MathOptInterface.Utilities.eval_variables
— Functioneval_variables(varval::Function, f::AbstractFunction)
Returns the value of function f
if each variable index vi
is evaluated as varval(vi)
. Note that varval
should return a number, see substitute_variables
for a similar function where varval
returns a function.
MathOptInterface.Utilities.map_indices
— Functionmap_indices(index_map::Function, x)
Substitute any MOI.VariableIndex
(resp. MOI.ConstraintIndex
) in x
by the MOI.VariableIndex
(resp. MOI.ConstraintIndex
) of the same type given by index_map(x)
.
This function is used by implementations of MOI.copy_to
on constraint functions, attribute values and submittable values hence it needs to be implemented for custom types that are meant to be used as attribute or submittable value.
MathOptInterface.Utilities.substitute_variables
— Functionsubstitute_variables(variable_map::Function, x)
Substitute any MOI.VariableIndex
in x
by variable_map(x)
. The variable_map
function returns either MOI.SingleVariable
or MOI.ScalarAffineFunction
, see eval_variables
for a similar function where variable_map
returns a number.
This function is used by bridge optimizers on constraint functions, attribute values and submittable values when at least one variable bridge is used hence it needs to be implemented for custom types that are meant to be used as attribute or submittable value.
MathOptInterface.Utilities.filter_variables
— Functionfilter_variables(keep::Function, f::AbstractFunction)
Return a new function f
with the variable vi
such that !keep(vi)
removed.
MathOptInterface.Utilities.remove_variable
— Functionremove_variable(f::AbstractFunction, vi::VariableIndex)
Return a new function f
with the variable vi removed.
remove_variable(f::MOI.AbstractFunction, s::MOI.AbstractSet, vi::MOI.VariableIndex)
Return a tuple (g, t)
representing the constraint f
-in-s
with the variable vi
removed. That is, the terms containing the variable vi
in the function f
are removed and the dimension of the set s
is updated if needed (e.g. when f
is a VectorOfVariables
with vi
being one of the variables).
MathOptInterface.Utilities.all_coefficients
— Functionall_coefficients(p::Function, f::MOI.AbstractFunction)
Determine whether predicate p
returns true
for all coefficients of f
, returning false
as soon as the first coefficient of f
for which p
returns false
is encountered (short-circuiting). Similar to all
.
MathOptInterface.Utilities.unsafe_add
— Functionunsafe_add(t1::MOI.ScalarAffineTerm, t2::MOI.ScalarAffineTerm)
Sums the coefficients of t1
and t2
and returns an output MOI.ScalarAffineTerm
. It is unsafe because it uses the variable_index
of t1
as the variable_index
of the output without checking that it is equal to that of t2
.
unsafe_add(t1::MOI.ScalarQuadraticTerm, t2::MOI.ScalarQuadraticTerm)
Sums the coefficients of t1
and t2
and returns an output MOI.ScalarQuadraticTerm
. It is unsafe because it uses the variable_index
's of t1
as the variable_index
's of the output without checking that they are the same (up to permutation) to those of t2
.
unsafe_add(t1::MOI.VectorAffineTerm, t2::MOI.VectorAffineTerm)
Sums the coefficients of t1
and t2
and returns an output MOI.VectorAffineTerm
. It is unsafe because it uses the output_index
and variable_index
of t1
as the output_index
and variable_index
of the output term without checking that they are equal to those of t2
.
MathOptInterface.Utilities.isapprox_zero
— Functionisapprox_zero(f::MOI.AbstractFunction, tol)
Return a Bool
indicating whether the function f
is approximately zero using tol
as a tolerance.
Important note
This function assumes that f
does not contain any duplicate terms, you might want to first call canonical
if that is not guaranteed. For instance, given
f = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1, -1], [x, x]), 0)`.
then isapprox_zero(f)
is false
but isapprox_zero(MOIU.canonical(f))
is true
.
MathOptInterface.Utilities.modify_function
— Functionmodify_function(f::AbstractFunction, change::AbstractFunctionModification)
Return a new function f
modified according to change
.
The following functions can be used to canonicalize a function:
MathOptInterface.Utilities.is_canonical
— Functionis_canonical(f::Union{ScalarAffineFunction, VectorAffineFunction})
Returns a Bool indicating whether the function is in canonical form. See canonical
.
is_canonical(f::Union{ScalarQuadraticFunction, VectorQuadraticFunction})
Returns a Bool indicating whether the function is in canonical form. See canonical
.
MathOptInterface.Utilities.canonical
— Functioncanonical(f::Union{ScalarAffineFunction, VectorAffineFunction,
ScalarQuadraticFunction, VectorQuadraticFunction})
Returns the function in a canonical form, i.e.
- A term appear only once.
- The coefficients are nonzero.
- The terms appear in increasing order of variable where there the order of the variables is the order of their value.
- For a
AbstractVectorFunction
, the terms are sorted in ascending order of output index.
The output of canonical
can be assumed to be a copy of f
, even for VectorOfVariables
.
Examples
If x
(resp. y
, z
) is VariableIndex(1)
(resp. 2, 3). The canonical representation of ScalarAffineFunction([y, x, z, x, z], [2, 1, 3, -2, -3], 5)
is ScalarAffineFunction([x, y], [-1, 2], 5)
.
MathOptInterface.Utilities.canonicalize!
— Functioncanonicalize!(f::Union{ScalarAffineFunction, VectorAffineFunction})
Convert a function to canonical form in-place, without allocating a copy to hold the result. See canonical
.
canonicalize!(f::Union{ScalarQuadraticFunction, VectorQuadraticFunction})
Convert a function to canonical form in-place, without allocating a copy to hold the result. See canonical
.
The following functions can be used to manipulate functions with basic algebra:
MathOptInterface.Utilities.scalar_type
— Functionscalar_type(F::Type{<:MOI.AbstractVectorFunction})
Type of functions obtained by indexing objects obtained by calling eachscalar
on functions of type F
.
MathOptInterface.Utilities.promote_operation
— Functionpromote_operation(op::Function, ::Type{T},
ArgsTypes::Type{<:Union{T, MOI.AbstractFunction}}...) where T
Returns the type of the MOI.AbstractFunction
returned to the call operate(op, T, args...)
where the types of the arguments args
are ArgsTypes
.
MathOptInterface.Utilities.operate
— Functionoperate(op::Function, ::Type{T},
args::Union{T, MOI.AbstractFunction}...)::MOI.AbstractFunction where T
Returns an MOI.AbstractFunction
representing the function resulting from the operation op(args...)
on functions of coefficient type T
. No argument can be modified.
MathOptInterface.Utilities.operate!
— Functionoperate!(op::Function, ::Type{T},
args::Union{T, MOI.AbstractFunction}...)::MOI.AbstractFunction where T
Returns an MOI.AbstractFunction
representing the function resulting from the operation op(args...)
on functions of coefficient type T
. The first argument can be modified. The return type is the same than the method operate(op, T, args...)
without !
.
MathOptInterface.Utilities.operate_output_index!
— Functionoperate_output_index!(
op::Function, ::Type{T}, output_index::Integer,
func::MOI.AbstractVectorFunction
args::Union{T, MOI.AbstractScalarFunction}...)::MOI.AbstractFunction where T
Returns an MOI.AbstractVectorFunction
where the function at output_index
is the result of the operation op
applied to the function at output_index
of func
and args
. The functions at output index different to output_index
are the same as the functions at the same output index in func
. The first argument can be modified.
MathOptInterface.Utilities.vectorize
— Functionvectorize(funcs::AbstractVector{MOI.SingleVariable})
Returns the vector of scalar affine functions in the form of a MOI.VectorAffineFunction{T}
.
vectorize(funcs::AbstractVector{MOI.ScalarAffineFunction{T}}) where T
Returns the vector of scalar affine functions in the form of a MOI.VectorAffineFunction{T}
.
vectorize(funcs::AbstractVector{MOI.ScalarQuadraticFunction{T}}) where T
Returns the vector of scalar quadratic functions in the form of a MOI.VectorQuadraticFunction{T}
.
Constraint utilities
The following utilities are available for moving the function constant to the set for scalar constraints:
MathOptInterface.Utilities.shift_constant
— Functionshift_constant(set::MOI.AbstractScalarSet,
offset)
Returns a new scalar set new_set
such that func
-in-set
is equivalent to func + offset
-in-new_set
.
Examples
The call shift_constant(MOI.Interval(-2, 3), 1)
is equal to MOI.Interval(-1, 4)
.
MathOptInterface.Utilities.normalize_and_add_constraint
— Functionnormalize_and_add_constraint(model::MOI.ModelLike,
func::MOI.AbstractScalarFunction,
set::MOI.AbstractScalarSet;
allow_modify_function::Bool=false)
Adds the scalar constraint obtained by moving the constant term in func
to the set in model
. If allow_modify_function
is true
then the function func
can be modified.
MathOptInterface.Utilities.normalize_constant
— Functionnormalize_constant(func::MOI.AbstractScalarFunction,
set::MOI.AbstractScalarSet;
allow_modify_function::Bool=false)
Return the func
-in-set
constraint in normalized form. That is, if func
is MOI.ScalarQuadraticFunction
or MOI.ScalarAffineFunction
, the constant is moved to the set. If allow_modify_function
is true
then the function func
can be modified.
The following utility identifies those constraints imposing bounds on a given variable, and returns those bound values:
MathOptInterface.Utilities.get_bounds
— Functionget_bounds(model::MOI.ModelLike, ::Type{T}, x::MOI.VariableIndex)
Return a tuple (lb, ub)
of type Tuple{T, T}
, where lb
and ub
are lower and upper bounds, respectively, imposed on x
in model
.
The following utilities are useful when working with symmetric matrix cones.
MathOptInterface.Utilities.is_diagonal_vectorized_index
— Functionis_diagonal_vectorized_index(index::Base.Integer)
Return whether index
is the index of a diagonal element in a MOI.AbstractSymmetricMatrixSetTriangle
set.
MathOptInterface.Utilities.side_dimension_for_vectorized_dimension
— Functionside_dimension_for_vectorized_dimension(n::Integer)
Return the dimension d
such that MOI.dimension(MOI.PositiveSemidefiniteConeTriangle(d))
is n
.
Benchmarks
Functions to help benchmark the performance of solver wrappers. See The Benchmarks submodule for more details.
MathOptInterface.Benchmarks.suite
— Functionsuite(
new_model::Function;
exclude::Vector{Regex} = Regex[]
)
Create a suite of benchmarks. new_model
should be a function that takes no arguments, and returns a new instance of the optimizer you wish to benchmark.
Use exclude
to exclude a subset of benchmarks.
Examples
suite() do
GLPK.Optimizer()
end
suite(exclude = [r"delete"]) do
Gurobi.Optimizer(OutputFlag=0)
end
MathOptInterface.Benchmarks.create_baseline
— Functioncreate_baseline(suite, name::String; directory::String = ""; kwargs...)
Run all benchmarks in suite
and save to files called name
in directory
.
Extra kwargs
are based to BenchmarkTools.run
.
Examples
my_suite = suite(() -> GLPK.Optimizer())
create_baseline(my_suite, "glpk_master"; directory = "/tmp", verbose = true)
MathOptInterface.Benchmarks.compare_against_baseline
— Functioncompare_against_baseline(
suite, name::String; directory::String = "",
report_filename::String = "report.txt"
)
Run all benchmarks in suite
and compare against files called name
in directory
that were created by a call to create_baseline
.
A report summarizing the comparison is written to report_filename
in directory
.
Extra kwargs
are based to BenchmarkTools.run
.
Examples
my_suite = suite(() -> GLPK.Optimizer())
compare_against_baseline(
my_suite, "glpk_master"; directory = "/tmp", verbose = true
)
File Formats
Functions to help read and write MOI models to/from various file formats. See The FileFormats submodule for more details.
MathOptInterface.FileFormats.Model
— FunctionModel(
;
format::FileFormat = FORMAT_AUTOMATIC,
filename::Union{Nothing, String} = nothing,
kwargs...
)
Return model corresponding to the FileFormat
format
, or, if format == FORMAT_AUTOMATIC
, guess the format from filename
.
The filename
argument is only needed if format == FORMAT_AUTOMATIC
.
kwargs
are passed to the underlying model constructor.
MathOptInterface.FileFormats.FileFormat
— TypeFileFormat
List of accepted export formats.
FORMAT_AUTOMATIC
: try to detect the file format based on the file nameFORMAT_CBF
: the Conic Benchmark formatFORMAT_LP
: the LP file formatFORMAT_MOF
: the MathOptFormat file formatFORMAT_MPS
: the MPS file formatFORMAT_SDPA
: the SemiDefinite Programming Algorithm format