Constraints
Types
MathOptInterface.ConstraintIndex — Type
ConstraintIndex{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 (that is, F-in-S) must be unique, but non-unique indices across different constraint types are allowed.
If F is VariableIndex then the index is equal to the index of the variable. That is for an index::ConstraintIndex{VariableIndex}, we always have
index.value == MOI.get(model, MOI.ConstraintFunction(), index).valueFunctions
MathOptInterface.is_valid — Method
is_valid(model::ModelLike, index::Index)::BoolReturn a Bool indicating whether this index refers to a valid object in the model model.
MathOptInterface.add_constraint — Function
MOI.add_constraint(map::Map, vi::MOI.VariableIndex, set::MOI.AbstractScalarSet)Record that a constraint vi-in-set is added and throws if a lower or upper bound is set by this constraint and such bound has already been set for vi.
add_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{VariableIndex,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
UnsupportedConstrainterror is thrown ifmodeldoes not supportF-in-Sconstraints, - a
AddConstraintNotAllowederror is thrown if it supportsF-in-Sconstraints but it cannot add the constraint in its current state and - a
ScalarFunctionConstantNotZeroerror may be thrown iffuncis anAbstractScalarFunctionwith nonzero constant andsetisEqualTo,GreaterThan,LessThanorInterval. - a
LowerBoundAlreadySeterror is thrown ifFis aVariableIndexand a constraint was already added to this variable that sets a lower bound. - a
UpperBoundAlreadySeterror is thrown ifFis aVariableIndexand a constraint was already added to this variable that sets an upper bound.
MathOptInterface.add_constraints — Function
add_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 — Function
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.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variable(model);
julia> c = MOI.add_constraint(model, 1.0 * x, MOI.LessThan(2.0));
julia> print(model)
Feasibility
Subject to:
ScalarAffineFunction{Float64}-in-LessThan{Float64}
0.0 + 1.0 v[1] <= 2.0
julia> c2 = MOI.transform(model, c, MOI.GreaterThan(0.0))
MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.GreaterThan{Float64}}(1)
julia> print(model)
Feasibility
Subject to:
ScalarAffineFunction{Float64}-in-GreaterThan{Float64}
0.0 + 1.0 v[1] >= 0.0
julia> MOI.is_valid(model, c)
falseMathOptInterface.supports_constraint — Function
MOI.supports_constraint(
BT::Type{<:AbstractBridge},
F::Type{<:MOI.AbstractFunction},
S::Type{<:MOI.AbstractSet},
)::BoolReturn a Bool indicating whether the bridges of type BT support bridging F-in-S constraints.
Implementation notes
- This method depends only on the type of the inputs, not the runtime values.
- There is a default fallback, so you need only implement this method for constraint types that the bridge implements.
supports_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, for example, F-in-S constraints cannot be combined with another type of constraint, it should still return true.
Attributes
MathOptInterface.AbstractConstraintAttribute — Type
AbstractConstraintAttributeAbstract supertype for attribute objects that can be used to set or get attributes (properties) of constraints in the model.
MathOptInterface.ConstraintName — Type
ConstraintName()An AbstractConstraintAttribute for a String identifying the constraint.
The default name is "" if not set by the user.
Duplicate names
Two constraints may have the same name; however, constraints with duplicate names cannot be looked up using get, regardless of whether they have the same F-in-S type.
VariableIndex connstraints
You should not implement ConstraintName for VariableIndex constraints.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variable(model);
julia> c = MOI.add_constraint(model, 1.0 * x, MOI.EqualTo(1.0));
julia> MOI.supports(model, MOI.ConstraintName(), typeof(c))
true
julia> MOI.get(model, MOI.ConstraintName(), c)
""
julia> MOI.set(model, MOI.ConstraintName(), c, "c")
julia> MOI.get(model, MOI.ConstraintName(), c)
"c"
julia> MOI.get(model, MOI.ConstraintIndex, "c")
MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.EqualTo{Float64}}(1)
julia> F, S = MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64};
julia> MOI.get(model, MOI.ConstraintIndex{F,S}, "c")
MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.EqualTo{Float64}}(1)Implementation
Optimizers should implement the following methods:
MOI.get(::Optimizer, ::MOI.ConstraintName, ::MOI.ConstraintIndex)::String
MOI.set(::Optimizer, ::MOI.ConstraintName, ::MOI.ConstraintIndex, ::String)::Nothing
MOI.supports(::Optimizer, ::MOI.ConstraintName, ::Type{<:MOI.ConstraintIndex})::Bool
MOI.get(::Optimizer, ::MOI.ConstraintIndex, ::MOI.ConstraintIndex, ::String)::MOI.ConstraintIndexMathOptInterface.ConstraintPrimalStart — Type
ConstraintPrimalStart()An AbstractConstraintAttribute for the initial assignment to the constraint's ConstraintPrimal that the optimizer may use to warm-start the solve.
May be nothing (unset), a number for AbstractScalarFunction, or a vector for AbstractVectorFunction.
MathOptInterface.ConstraintDualStart — Type
ConstraintDualStart()An AbstractConstraintAttribute for the initial assignment to the constraint's ConstraintDual that the optimizer may use to warm-start the solve.
May be nothing (unset), a number for AbstractScalarFunction, or a vector for AbstractVectorFunction.
MathOptInterface.ConstraintPrimal — Type
ConstraintPrimal(result_index::Int = 1)An AbstractConstraintAttribute for the constraint's primal value in result result_index.
Definition
If the constraint is $f(x) \in S$, then in most cases the ConstraintPrimal is the value of $f$, evaluated at the corresponding VariablePrimal solution.
However, some conic solvers reformulate $b - Ax \in S$ to $s = b - Ax$ and $s \in S$. These solvers may return the value of s for ConstraintPrimal, rather than b - Ax. (Although these are constrained by an equality constraint, due to numerical tolerances they may not be identical.)
PrimalStatus
Before quering this attribute you should first check PrimalStatus to confirm that a primal solution is avaiable.
If the PrimalStatus is NO_SOLUTION the result of querying this attribute is undefined.
result_index
The optimizer may return multiple primal solutions. See ResultCount for information on how the results are ordered.
If the solver does not have a primal value for the constraint because the result_index is beyond the available solutions (whose number is indicated by the ResultCount attribute), getting this attribute must throw a ResultIndexBoundsError.
Implementation
Optimizers should implement the following methods:
MOI.get(
::Optimizer,
::MOI.ConstraintPrimal,
::MOI.ConstraintIndex{<:MOI.AbstractScalarFunction}
)::T
MOI.get(
::Optimizer,
::MOI.ConstraintPrimal,
::MOI.ConstraintIndex{<:MOI.AbstractVectorFunction}
)::Vector{T}MathOptInterface.ConstraintDual — Type
ConstraintDual(result_index::Int = 1)An AbstractConstraintAttribute for the constraint's dual value in result result_index.
DualStatus
Before quering this attribute you should first check DualStatus to confirm that a dual solution is avaiable.
If the DualStatus is NO_SOLUTION the result of querying this attribute is undefined.
result_index
The optimizer may return multiple dual solutions. See ResultCount for information on how the results are ordered.
If the solver does not have a dual value for the constraint because the result_index is beyond the available solutions (whose number is indicated by the ResultCount attribute), getting this attribute must throw a ResultIndexBoundsError.
Implementation
Optimizers should implement the following methods:
MOI.get(
::Optimizer,
::MOI.ConstraintDual,
::MOI.ConstraintIndex{<:MOI.AbstractScalarFunction}
)::T
MOI.get(
::Optimizer,
::MOI.ConstraintDual,
::MOI.ConstraintIndex{<:MOI.AbstractVectorFunction}
)::Vector{T}MathOptInterface.ConstraintBasisStatus — Type
ConstraintBasisStatus(result_index::Int = 1)An AbstractConstraintAttribute for the BasisStatusCode of the constraint in result result_index, with respect to a basic solution.
If result_index is omitted, it is 1 by default.
If the solver does not have a basis status for the constraint because the result_index is beyond the available solutions (whose number is indicated by the ResultCount attribute), getting this attribute must throw a ResultIndexBoundsError. Otherwise, if the result is unavailable for another reason (for instance, only a dual solution is available), the result is undefined. Users should first check PrimalStatus before accessing the ConstraintBasisStatus attribute.
See ResultCount for information on how the results are ordered.
Notes
For the basis status of a variable, query VariableBasisStatus.
ConstraintBasisStatus does not apply to VariableIndex constraints. You can infer the basis status of a VariableIndex constraint by looking at the result of VariableBasisStatus.
MathOptInterface.ConstraintFunction — Type
ConstraintFunction()An AbstractConstraintAttribute 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.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variable(model);
julia> c = MOI.add_constraint(model, 1.0 * x, MOI.GreaterThan(0.0));
julia> MOI.get(model, MOI.ConstraintFunction(), c)
0.0 + 1.0 MOI.VariableIndex(1)
julia> MOI.set(model, MOI.ConstraintFunction(), c, 2.0 * x)
julia> MOI.get(model, MOI.ConstraintFunction(), c)
0.0 + 2.0 MOI.VariableIndex(1)Implementation
Optimizers should implement the following methods:
MOI.get(
::Optimizer,
::MOI.ConstraintFunction,
::MOI.ConstraintIndex{F,S},
)::F where {F,S}If the optimizer supports modifying an existing function, it should implement:
MOI.set(
::Optimizer,
::MOI.ConstraintFunction,
::MOI.ConstraintIndex{F,S},
::F,
)::Nothing where {F,S}It should not implement supports.
MathOptInterface.CanonicalConstraintFunction — Type
CanonicalConstraintFunction()An AbstractConstraintAttribute 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.
Fallback
By default, MOI.get(model, MOI.CanonicalConstraintFunction(), ci) falls back 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.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variable(model);
julia> c = MOI.add_constraint(model, 1.0 * x + 1.0 * x, MOI.GreaterThan(0.0));
julia> MOI.get(model, MOI.CanonicalConstraintFunction(), c)
0.0 + 2.0 MOI.VariableIndex(1)Implementation
Optimizers should implement the following methods:
MOI.get(
::Optimizer,
::MOI.CanonicalConstraintFunction,
::MOI.ConstraintIndex{F,S},
)::F where {F,S}MathOptInterface.ConstraintSet — Type
ConstraintSet()An AbstractConstraintAttribute for the AbstractSet object used to define the constraint.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variable(model);
julia> c = MOI.add_constraint(model, x, MOI.GreaterThan(0.0));
julia> MOI.get(model, MOI.ConstraintSet(), c)
MathOptInterface.GreaterThan{Float64}(0.0)
julia> MOI.set(model, MOI.ConstraintSet(), c, MOI.GreaterThan(1.0))
julia> MOI.get(model, MOI.ConstraintSet(), c)
MathOptInterface.GreaterThan{Float64}(1.0)Implementation
Optimizers should implement the following methods:
MOI.get(
::Optimizer,
::MOI.ConstraintSet,
::MOI.ConstraintIndex{F,S},
)::S where {F,S}If the optimizer supports modifying an existing set, it should implement:
MOI.set(
::Optimizer,
::MOI.ConstraintSet,
::MOI.ConstraintIndex{F,S},
::S,
)::Nothing where {F,S}It should not implement supports.
MathOptInterface.BasisStatusCode — Type
BasisStatusCodeAn Enum for the value of the ConstraintBasisStatus and VariableBasisStatus attributes, explaining the status of a given element with respect to an optimal solution basis.
Notes
When queried as part of ConstraintBasisStatus, NONBASIC_AT_LOWER and NONBASIC_AT_UPPER should be returned only for constraints with the Interval set. In this case, they are necessary to distinguish which side of the constraint is active. One-sided constraints (for example, LessThan and GreaterThan) should use NONBASIC instead of the NONBASIC_AT_* values.
This restriction does not apply to VariableBasisStatus, which should return NONBASIC_AT_* regardless of whether the alternative bound exists.
Values
The element is in the basis.
The element is not in the basis.
The element is not in the basis and is at its lower bound.
The element is not in the basis and is at its upper bound.
The element is not in the basis but is also not at one of its bounds.
In a linear program, this status occurs when a variable with no bounds is not in the basis, for example, because it takes the value 0.0.
MathOptInterface.BASIC — Constant
MathOptInterface.NONBASIC — Constant
NONBASIC::BasisStatusCodeAn instance of the BasisStatusCode enum.
About
The element is not in the basis.
MathOptInterface.NONBASIC_AT_LOWER — Constant
NONBASIC_AT_LOWER::BasisStatusCodeAn instance of the BasisStatusCode enum.
About
The element is not in the basis and is at its lower bound.
MathOptInterface.NONBASIC_AT_UPPER — Constant
NONBASIC_AT_UPPER::BasisStatusCodeAn instance of the BasisStatusCode enum.
About
The element is not in the basis and is at its upper bound.
MathOptInterface.SUPER_BASIC — Constant
SUPER_BASIC::BasisStatusCodeAn instance of the BasisStatusCode enum.
About
The element is not in the basis but is also not at one of its bounds.
In a linear program, this status occurs when a variable with no bounds is not in the basis, for example, because it takes the value 0.0.
MathOptInterface.LagrangeMultiplier — Type
LagrangeMultiplier(result_index::Int = 1)An AbstractConstraintAttribute for the Lagrange multiplier associated with a constraint.
Relationship to ConstraintDual
This attribute differs from ConstraintDual in one important case. When there is a VectorNonlinearOracle constraint of the form:
\[x \in VectorNonlinearOracle\]
the associated ConstraintDual is $\mu^\top \nabla f(x)$, and the value of LagrangeMultiplier is the vector $\mu$ directly.
Both values are useful in different circumstances.
DualStatus
Before quering this attribute you should first check DualStatus to confirm that a dual solution is avaiable.
If the DualStatus is NO_SOLUTION the result of querying this attribute is undefined.
result_index
The optimizer may return multiple dual solutions. See ResultCount for information on how the results are ordered.
If the solver does not have a dual value for the constraint because the result_index is beyond the available solutions (whose number is indicated by the ResultCount attribute), getting this attribute must throw a ResultIndexBoundsError.
Implementation
Optimizers should implement the following methods:
MOI.get(::Optimizer, ::MOI.LagrangeMultiplier, ::MOI.ConstraintIndex)They should not implement set or supports.
Solvers should implement LagrangeMultiplier only if they also implement the ConstraintDual, and only if the two values are different.
MathOptInterface.LagrangeMultiplierStart — Type
LagrangeMultiplierStart()An AbstractConstraintAttribute for the initial assignment to the constraint's LagrangeMultiplier that the optimizer may use to warm-start the solve.
May be nothing (unset), a number for AbstractScalarFunction, or a vector for AbstractVectorFunction.