Standard form
Functions
MathOptInterface.AbstractFunction — TypeAbstractFunctionAbstract supertype for function objects.
Required methods
All functions must implement:
Base.copyBase.isapproxconstant
Abstract subtypes of AbstractFunction may require additional methods to be implemented.
MathOptInterface.output_dimension — Functionoutput_dimension(f::AbstractFunction)Return 1 if f is an AbstractScalarFunction, or the number of output components if f is an AbstractVectorFunction.
MathOptInterface.constant — Functionconstant(f::AbstractFunction[, ::Type{T}]) where {T}Returns the constant term of a scalar-valued function, or the constant vector of a vector-valued function.
If f is untyped and T is provided, returns zero(T).
constant(set::Union{EqualTo,GreaterThan,LessThan,Parameter})Returns the constant term of the set set.
Example
julia> MOI.constant(MOI.GreaterThan(1.0))
1.0
julia> MOI.constant(MOI.LessThan(2.5))
2.5
julia> MOI.constant(MOI.EqualTo(3))
3
julia> MOI.constant(MOI.Parameter(4.5))
4.5Scalar functions
MathOptInterface.AbstractScalarFunction — Typeabstract type AbstractScalarFunction <: AbstractFunctionAbstract supertype for scalar-valued AbstractFunctions.
MathOptInterface.VariableIndex — TypeVariableIndexA type-safe wrapper for Int64 for use in referencing variables in a model. To allow for deletion, indices need not be consecutive.
MathOptInterface.ScalarAffineTerm — TypeScalarAffineTerm{T}(coefficient::T, variable::VariableIndex) where {T}Represents the scalar-valued term coefficient * variable.
Example
julia> x = MOI.VariableIndex(1)
MOI.VariableIndex(1)
julia> MOI.ScalarAffineTerm(2.0, x)
MathOptInterface.ScalarAffineTerm{Float64}(2.0, MOI.VariableIndex(1))MathOptInterface.ScalarAffineFunction — TypeScalarAffineFunction{T}(
terms::Vector{ScalarAffineTerm{T}},
constant::T,
) where {T}Represents the scalar-valued affine function $a^\top x + b$, where:
- $a^\top x$ is represented by the vector of
ScalarAffineTerms - $b$ is a scalar
constant::T
Duplicates
Duplicate variable indices in terms are accepted, and the corresponding coefficients are summed together.
Example
julia> x = MOI.VariableIndex(1)
MOI.VariableIndex(1)
julia> terms = [MOI.ScalarAffineTerm(2.0, x), MOI.ScalarAffineTerm(3.0, x)]
2-element Vector{MathOptInterface.ScalarAffineTerm{Float64}}:
MathOptInterface.ScalarAffineTerm{Float64}(2.0, MOI.VariableIndex(1))
MathOptInterface.ScalarAffineTerm{Float64}(3.0, MOI.VariableIndex(1))
julia> f = MOI.ScalarAffineFunction(terms, 4.0)
4.0 + 2.0 MOI.VariableIndex(1) + 3.0 MOI.VariableIndex(1)MathOptInterface.ScalarQuadraticTerm — TypeScalarQuadraticTerm{T}(
coefficient::T,
variable_1::VariableIndex,
variable_2::VariableIndex,
) where {T}Represents the scalar-valued term $c x_i x_j$ where $c$ is coefficient, $x_i$ is variable_1 and $x_j$ is variable_2.
Example
julia> x = MOI.VariableIndex(1)
MOI.VariableIndex(1)
julia> MOI.ScalarQuadraticTerm(2.0, x, x)
MathOptInterface.ScalarQuadraticTerm{Float64}(2.0, MOI.VariableIndex(1), MOI.VariableIndex(1))MathOptInterface.ScalarQuadraticFunction — TypeScalarQuadraticFunction{T}(
quadratic_terms::Vector{ScalarQuadraticTerm{T}},
affine_terms::Vector{ScalarAffineTerm{T}},
constant::T,
) wher {T}The scalar-valued quadratic function $\frac{1}{2}x^\top Q x + a^\top x + b$, where:
- $Q$ is the symmetric matrix given by the vector of
ScalarQuadraticTerms - $a^\top x$ is a sparse vector given by the vector of
ScalarAffineTerms - $b$ is the scalar
constant::T.
Duplicates
Duplicate indices in quadratic_terms or affine_terms are accepted, and the corresponding coefficients are summed together.
In quadratic_terms, "mirrored" indices, (q, r) and (r, q) where r and q are VariableIndexes, are considered duplicates; only one needs to be specified.
The 0.5 factor
Coupled with the interpretation of mirrored indices, the 0.5 factor in front of the $Q$ matrix is a common source of bugs.
As a rule, to represent $a * x^2 + b * x * y$:
- The coefficient $a$ in front of squared variables (diagonal elements in $Q$) must be doubled when creating a
ScalarQuadraticTerm - The coefficient $b$ in front of off-diagonal elements in $Q$ should be left as $b$, be cause the mirrored index $b * y * x$ will be implicitly added.
Example
To represent the function $f(x, y) = 2 * x^2 + 3 * x * y + 4 * x + 5$, do:
julia> x = MOI.VariableIndex(1);
julia> y = MOI.VariableIndex(2);
julia> constant = 5.0;
julia> affine_terms = [MOI.ScalarAffineTerm(4.0, x)];
julia> quadratic_terms = [
MOI.ScalarQuadraticTerm(4.0, x, x), # Note the changed coefficient
MOI.ScalarQuadraticTerm(3.0, x, y),
]
2-element Vector{MathOptInterface.ScalarQuadraticTerm{Float64}}:
MathOptInterface.ScalarQuadraticTerm{Float64}(4.0, MOI.VariableIndex(1), MOI.VariableIndex(1))
MathOptInterface.ScalarQuadraticTerm{Float64}(3.0, MOI.VariableIndex(1), MOI.VariableIndex(2))
julia> f = MOI.ScalarQuadraticFunction(quadratic_terms, affine_terms, constant)
5.0 + 4.0 MOI.VariableIndex(1) + 2.0 MOI.VariableIndex(1)² + 3.0 MOI.VariableIndex(1)*MOI.VariableIndex(2)MathOptInterface.ScalarNonlinearFunction — TypeScalarNonlinearFunction(head::Symbol, args::Vector{Any})The scalar-valued nonlinear function head(args...), represented as a symbolic expression tree, with the call operator head and ordered arguments in args.
head
The head::Symbol must be an operator supported by the model.
The default list of supported univariate operators is given by:
and the default list of supported multivariate operators is given by:
Additional operators can be registered by setting a UserDefinedFunction attribute.
See the full list of operators supported by a ModelLike by querying ListOfSupportedNonlinearOperators.
args
The vector args contains the arguments to the nonlinear function. If the operator is univariate, it must contain one element. Otherwise, it may contain multiple elements.
Each element must be one of the following:
- A constant value of type
T<:Real - A
VariableIndex - A
ScalarAffineFunction - A
ScalarQuadraticFunction - A
ScalarNonlinearFunction
Unsupported operators
If the optimizer does not support head, an UnsupportedNonlinearOperator error will be thrown.
There is no guarantee about when this error will be thrown; it may be thrown when the function is first added to the model, or it may be thrown when optimize! is called.
Example
To represent the function $f(x) = sin(x)^2$, do:
julia> x = MOI.VariableIndex(1)
MOI.VariableIndex(1)
julia> MOI.ScalarNonlinearFunction(
:^,
Any[MOI.ScalarNonlinearFunction(:sin, Any[x]), 2],
)
^(sin(MOI.VariableIndex(1)), (2))Vector functions
MathOptInterface.AbstractVectorFunction — Typeabstract type AbstractVectorFunction <: AbstractFunctionAbstract supertype for vector-valued AbstractFunctions.
Required methods
All subtypes of AbstractVectorFunction must implement:
MathOptInterface.VectorOfVariables — TypeVectorOfVariables(variables::Vector{VariableIndex}) <: AbstractVectorFunctionThe vector-valued function f(x) = variables, where variables is a subset of VariableIndexes in the model.
The list of variables may contain duplicates.
Example
julia> x = MOI.VariableIndex.(1:2)
2-element Vector{MathOptInterface.VariableIndex}:
MOI.VariableIndex(1)
MOI.VariableIndex(2)
julia> f = MOI.VectorOfVariables([x[1], x[2], x[1]])
┌ ┐
│MOI.VariableIndex(1)│
│MOI.VariableIndex(2)│
│MOI.VariableIndex(1)│
└ ┘
julia> MOI.output_dimension(f)
3MathOptInterface.VectorAffineTerm — TypeVectorAffineTerm{T}(
output_index::Int64,
scalar_term::ScalarAffineTerm{T},
) where {T}A VectorAffineTerm is a scalar_term that appears in the output_index row of the vector-valued VectorAffineFunction or VectorQuadraticFunction.
Example
julia> x = MOI.VariableIndex(1);
julia> MOI.VectorAffineTerm(Int64(2), MOI.ScalarAffineTerm(3.0, x))
MathOptInterface.VectorAffineTerm{Float64}(2, MathOptInterface.ScalarAffineTerm{Float64}(3.0, MOI.VariableIndex(1)))MathOptInterface.VectorAffineFunction — TypeVectorAffineFunction{T}(
terms::Vector{VectorAffineTerm{T}},
constants::Vector{T},
) where {T}The vector-valued affine function $A x + b$, where:
- $A x$ is the sparse matrix given by the vector of
VectorAffineTerms - $b$ is the vector
constants
Duplicates
Duplicate indices in the $A$ are accepted, and the corresponding coefficients are summed together.
Example
julia> x = MOI.VariableIndex(1);
julia> terms = [
MOI.VectorAffineTerm(Int64(1), MOI.ScalarAffineTerm(2.0, x)),
MOI.VectorAffineTerm(Int64(2), MOI.ScalarAffineTerm(3.0, x)),
];
julia> f = MOI.VectorAffineFunction(terms, [4.0, 5.0])
┌ ┐
│4.0 + 2.0 MOI.VariableIndex(1)│
│5.0 + 3.0 MOI.VariableIndex(1)│
└ ┘
julia> MOI.output_dimension(f)
2MathOptInterface.VectorQuadraticTerm — TypeVectorQuadraticTerm{T}(
output_index::Int64,
scalar_term::ScalarQuadraticTerm{T},
) where {T}A VectorQuadraticTerm is a ScalarQuadraticTerm scalar_term that appears in the output_index row of the vector-valued VectorQuadraticFunction.
Example
julia> x = MOI.VariableIndex(1);
julia> MOI.VectorQuadraticTerm(Int64(2), MOI.ScalarQuadraticTerm(3.0, x, x))
MathOptInterface.VectorQuadraticTerm{Float64}(2, MathOptInterface.ScalarQuadraticTerm{Float64}(3.0, MOI.VariableIndex(1), MOI.VariableIndex(1)))MathOptInterface.VectorQuadraticFunction — TypeVectorQuadraticFunction{T}(
quadratic_terms::Vector{VectorQuadraticTerm{T}},
affine_terms::Vector{VectorAffineTerm{T}},
constants::Vector{T},
) where {T}The vector-valued quadratic function with ith component ("output index") defined as $\frac{1}{2}x^\top Q_i x + a_i^\top x + b_i$, where:
- $\frac{1}{2}x^\top Q_i x$ is the symmetric matrix given by the
VectorQuadraticTermelements inquadratic_termswithoutput_index == i - $a_i^\top x$ is the sparse vector given by the
VectorAffineTermelements inaffine_termswithoutput_index == i - $b_i$ is a scalar given by
constants[i]
Duplicates
Duplicate indices in quadratic_terms and affine_terms with the same output_index are handled in the same manner as duplicates in ScalarQuadraticFunction.
Example
julia> x = MOI.VariableIndex(1);
julia> y = MOI.VariableIndex(2);
julia> constants = [4.0, 5.0];
julia> affine_terms = [
MOI.VectorAffineTerm(Int64(1), MOI.ScalarAffineTerm(2.0, x)),
MOI.VectorAffineTerm(Int64(2), MOI.ScalarAffineTerm(3.0, x)),
];
julia> quad_terms = [
MOI.VectorQuadraticTerm(Int64(1), MOI.ScalarQuadraticTerm(2.0, x, x)),
MOI.VectorQuadraticTerm(Int64(2), MOI.ScalarQuadraticTerm(3.0, x, y)),
];
julia> f = MOI.VectorQuadraticFunction(quad_terms, affine_terms, constants)
┌ ┐
│4.0 + 2.0 MOI.VariableIndex(1) + 1.0 MOI.VariableIndex(1)² │
│5.0 + 3.0 MOI.VariableIndex(1) + 3.0 MOI.VariableIndex(1)*MOI.VariableIndex(2)│
└ ┘
julia> MOI.output_dimension(f)
2MathOptInterface.VectorNonlinearFunction — TypeVectorNonlinearFunction(args::Vector{ScalarNonlinearFunction})The vector-valued nonlinear function composed of a vector of ScalarNonlinearFunction.
args
The vector args contains the scalar elements of the nonlinear function. Each element must be a ScalarNonlinearFunction, but if you pass a Vector{Any}, the elements can be automatically converted from one of the following:
- A constant value of type
T<:Real - A
VariableIndex - A
ScalarAffineFunction - A
ScalarQuadraticFunction - A
ScalarNonlinearFunction
Example
To represent the function $f(x) = [sin(x)^2, x]$, do:
julia> x = MOI.VariableIndex(1)
MOI.VariableIndex(1)
julia> g = MOI.ScalarNonlinearFunction(
:^,
Any[MOI.ScalarNonlinearFunction(:sin, Any[x]), 2.0],
)
^(sin(MOI.VariableIndex(1)), 2.0)
julia> MOI.VectorNonlinearFunction([g, x])
┌ ┐
│^(sin(MOI.VariableIndex(1)), 2.0)│
│+(MOI.VariableIndex(1)) │
└ ┘Note the automatic conversion from x to +(x).
Sets
MathOptInterface.AbstractSet — TypeAbstractSetAbstract supertype for set objects used to encode constraints.
Required methods
For sets of type S with isbitstype(S) == false, you must implement:
Base.copy(set::S)Base.:(==)(x::S, y::S)
Subtypes of AbstractSet such as AbstractScalarSet and AbstractVectorSet may prescribe additional required methods.
Optional methods
You may optionally implement:
Note for developers
When creating a new set, the set struct must not contain any VariableIndex or ConstraintIndex objects.
MathOptInterface.AbstractScalarSet — TypeAbstractScalarSetAbstract supertype for subsets of $\mathbb{R}$.
MathOptInterface.AbstractVectorSet — TypeAbstractVectorSetAbstract supertype for subsets of $\mathbb{R}^n$ for some $n$.
Required methods
All AbstractVectorSets of type S must implement:
dimension, unless the dimension is stored in theset.dimensionfieldUtilities.set_dot, unless the dot product between two vectors in the set is equivalent toLinearAlgebra.dot.
Utilities
MathOptInterface.dimension — Functiondimension(set::AbstractSet)Return the output_dimension that an AbstractFunction should have to be used with the set set.
Example
julia> MOI.dimension(MOI.Reals(4))
4
julia> MOI.dimension(MOI.LessThan(3.0))
1
julia> MOI.dimension(MOI.PositiveSemidefiniteConeTriangle(2))
3MathOptInterface.dual_set — Functiondual_set(set::AbstractSet)Return the dual set of set, 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.
Example
julia> MOI.dual_set(MOI.Reals(4))
MathOptInterface.Zeros(4)
julia> MOI.dual_set(MOI.SecondOrderCone(5))
MathOptInterface.SecondOrderCone(5)
julia> MOI.dual_set(MOI.ExponentialCone())
MathOptInterface.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.
Example
julia> MOI.dual_set_type(MOI.Reals)
MathOptInterface.Zeros
julia> MOI.dual_set_type(MOI.SecondOrderCone)
MathOptInterface.SecondOrderCone
julia> MOI.dual_set_type(MOI.ExponentialCone)
MathOptInterface.DualExponentialConeMathOptInterface.constant — Methodconstant(set::Union{EqualTo,GreaterThan,LessThan,Parameter})Returns the constant term of the set set.
Example
julia> MOI.constant(MOI.GreaterThan(1.0))
1.0
julia> MOI.constant(MOI.LessThan(2.5))
2.5
julia> MOI.constant(MOI.EqualTo(3))
3
julia> MOI.constant(MOI.Parameter(4.5))
4.5MathOptInterface.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::Int)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}$.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> MOI.add_constraint(model, x, MOI.GreaterThan(0.0))
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.GreaterThan{Float64}}(1)MathOptInterface.LessThan — TypeLessThan{T<:Real}(upper::T)The set $(-\infty, upper] \subseteq \mathbb{R}$.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> MOI.add_constraint(model, x, MOI.LessThan(2.0))
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.LessThan{Float64}}(1)MathOptInterface.EqualTo — TypeEqualTo{T<:Number}(value::T)The set containing the single point $\{value\} \subseteq \mathbb{R}$.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> MOI.add_constraint(model, x, MOI.EqualTo(2.0))
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.EqualTo{Float64}}(1)MathOptInterface.Interval — TypeInterval{T<:Real}(lower::T, upper::T)The interval $[lower, upper] \subseteq \mathbb{R} \cup \{-\infty, +\infty\}$.
If lower or upper is -Inf or Inf, respectively, the set is interpreted as a one-sided interval.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> MOI.add_constraint(model, x, MOI.Interval(1.0, 2.0))
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Interval{Float64}}(1)MathOptInterface.Integer — TypeInteger()The set of integers, $\mathbb{Z}$.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> MOI.add_constraint(model, x, MOI.Integer())
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Integer}(1)MathOptInterface.ZeroOne — TypeZeroOne()The set $\{0, 1\}$.
Variables belonging to the ZeroOne set are also known as "binary" variables.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> MOI.add_constraint(model, x, MOI.ZeroOne())
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.ZeroOne}(1)MathOptInterface.Semicontinuous — TypeSemicontinuous{T<:Real}(lower::T, upper::T)The set $\{0\} \cup [lower, upper]$.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> MOI.add_constraint(model, x, MOI.Semicontinuous(2.0, 3.0))
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Semicontinuous{Float64}}(1)MathOptInterface.Semiinteger — TypeSemiinteger{T<:Real}(lower::T, upper::T)The set $\{0\} \cup \{lower, lower+1, \ldots, upper-1, upper\}$.
Note that if lower and upper are not equivalent to an integer, then the solver may throw an error, or it may round up lower and round down upper to the nearest integers.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> MOI.add_constraint(model, x, MOI.Semiinteger(2.0, 3.0))
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Semiinteger{Float64}}(1)MathOptInterface.Parameter — TypeParameter{T<:Number}(value::T)The set containing the single point $\{value\} \subseteq \mathbb{R}$.
The Parameter set is conceptually similar to the EqualTo set, except that a variable constrained to the Parameter set cannot have other constraints added to it, and the Parameter set can never be deleted. Thus, solvers are free to treat the variable as a constant, and they need not add it as a decision variable to the model.
Because of this behavior, you must add parameters using add_constrained_variable, and solvers should declare supports_add_constrained_variable and not supports_constraint for the Parameter set.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> p, ci = MOI.add_constrained_variable(model, MOI.Parameter(2.5))
(MOI.VariableIndex(1), MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Parameter{Float64}}(1))
julia> MOI.set(model, MOI.ConstraintSet(), ci, MOI.Parameter(3.0))
julia> MOI.get(model, MOI.ConstraintSet(), ci)
MathOptInterface.Parameter{Float64}(3.0)Vector sets
List of recognized vector sets.
MathOptInterface.Reals — TypeReals(dimension::Int)The set $\mathbb{R}^{dimension}$ (containing all points) of non-negative dimension dimension.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variables(model, 3);
julia> MOI.add_constraint(model, MOI.VectorOfVariables(x), MOI.Reals(3))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.Reals}(1)MathOptInterface.Zeros — TypeZeros(dimension::Int)The set $\{ 0 \}^{dimension}$ (containing only the origin) of non-negative dimension dimension.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variables(model, 3);
julia> MOI.add_constraint(model, MOI.VectorOfVariables(x), MOI.Zeros(3))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.Zeros}(1)MathOptInterface.Nonnegatives — TypeNonnegatives(dimension::Int)The nonnegative orthant $\{ x \in \mathbb{R}^{dimension} : x \ge 0 \}$ of non-negative dimension dimension.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variables(model, 3);
julia> MOI.add_constraint(model, MOI.VectorOfVariables(x), MOI.Nonnegatives(3))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.Nonnegatives}(1)MathOptInterface.Nonpositives — TypeNonpositives(dimension::Int)The nonpositive orthant $\{ x \in \mathbb{R}^{dimension} : x \le 0 \}$ of non-negative dimension dimension.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variables(model, 3);
julia> MOI.add_constraint(model, MOI.VectorOfVariables(x), MOI.Nonpositives(3))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.Nonpositives}(1)MathOptInterface.NormInfinityCone — TypeNormInfinityCone(dimension::Int)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.
The dimension must be at least 1.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> t = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> x = MOI.add_variables(model, 3);
julia> MOI.add_constraint(model, MOI.VectorOfVariables([t; x]), MOI.NormInfinityCone(4))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.NormInfinityCone}(1)MathOptInterface.NormOneCone — TypeNormOneCone(dimension::Int)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.
The dimension must be at least 1.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> t = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> x = MOI.add_variables(model, 3);
julia> MOI.add_constraint(model, MOI.VectorOfVariables([t; x]), MOI.NormOneCone(4))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.NormOneCone}(1)MathOptInterface.NormCone — TypeNormCone(p::Float64, dimension::Int)The $\ell_p$-norm cone $\{ (t,x) \in \mathbb{R}^{dimension} : t \ge \left(\sum\limits_i |x_i|^p\right)^{\frac{1}{p}} \}$ of dimension dimension.
The dimension must be at least 1.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> t = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> x = MOI.add_variables(model, 3);
julia> MOI.add_constraint(model, MOI.VectorOfVariables([t; x]), MOI.NormCone(3, 4))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.NormCone}(1)MathOptInterface.SecondOrderCone — TypeSecondOrderCone(dimension::Int)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.
The dimension must be at least 1.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> t = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> x = MOI.add_variables(model, 3);
julia> MOI.add_constraint(model, MOI.VectorOfVariables([t; x]), MOI.SecondOrderCone(4))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.SecondOrderCone}(1)MathOptInterface.RotatedSecondOrderCone — TypeRotatedSecondOrderCone(dimension::Int)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.
The dimension must be at least 2.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> t = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> u = MOI.add_variable(model)
MOI.VariableIndex(2)
julia> x = MOI.add_variables(model, 3);
julia> MOI.add_constraint(
model,
MOI.VectorOfVariables([t; u; x]),
MOI.RotatedSecondOrderCone(5),
)
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.RotatedSecondOrderCone}(1)MathOptInterface.GeometricMeanCone — TypeGeometricMeanCone(dimension::Int)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} \}$, where dimension = n + 1 >= 2.
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} \}$, where dimension = n + 1 >= 2.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> t = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> x = MOI.add_variables(model, 3);
julia> MOI.add_constraint(
model,
MOI.VectorOfVariables([t; x]),
MOI.GeometricMeanCone(4),
)
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.GeometricMeanCone}(1)MathOptInterface.ExponentialCone — TypeExponentialCone()The 3-dimensional exponential cone $\{ (x,y,z) \in \mathbb{R}^3 : y \exp (x/y) \le z, y > 0 \}$.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variables(model, 3);
julia> MOI.add_constraint(model, MOI.VectorOfVariables(x), MOI.ExponentialCone())
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.ExponentialCone}(1)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 \}$.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variables(model, 3);
julia> MOI.add_constraint(model, MOI.VectorOfVariables(x), MOI.DualExponentialCone())
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.DualExponentialCone}(1)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.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variables(model, 3);
julia> MOI.add_constraint(model, MOI.VectorOfVariables(x), MOI.PowerCone(0.5))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.PowerCone{Float64}}(1)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.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variables(model, 3);
julia> MOI.add_constraint(model, MOI.VectorOfVariables(x), MOI.DualPowerCone(0.5))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.DualPowerCone{Float64}}(1)MathOptInterface.RelativeEntropyCone — TypeRelativeEntropyCone(dimension::Int)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 \}$, where dimension = 2n + 1 >= 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$.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> u = MOI.add_variable(model);
julia> v = MOI.add_variables(model, 3);
julia> w = MOI.add_variables(model, 3);
julia> MOI.add_constraint(
model,
MOI.VectorOfVariables([u; v; w]),
MOI.RelativeEntropyCone(7),
)
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.RelativeEntropyCone}(1)MathOptInterface.NormSpectralCone — TypeNormSpectralCone(row_dim::Int, column_dim::Int)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 non-negative 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.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> t = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> X = reshape(MOI.add_variables(model, 6), 2, 3)
2×3 Matrix{MathOptInterface.VariableIndex}:
MOI.VariableIndex(2) MOI.VariableIndex(4) MOI.VariableIndex(6)
MOI.VariableIndex(3) MOI.VariableIndex(5) MOI.VariableIndex(7)
julia> MOI.add_constraint(
model,
MOI.VectorOfVariables([t; vec(X)]),
MOI.NormSpectralCone(2, 3),
)
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.NormSpectralCone}(1)MathOptInterface.NormNuclearCone — TypeNormNuclearCone(row_dim::Int, column_dim::Int)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 non-negative 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.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> t = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> X = reshape(MOI.add_variables(model, 6), 2, 3)
2×3 Matrix{MathOptInterface.VariableIndex}:
MOI.VariableIndex(2) MOI.VariableIndex(4) MOI.VariableIndex(6)
MOI.VariableIndex(3) MOI.VariableIndex(5) MOI.VariableIndex(7)
julia> MOI.add_constraint(
model,
MOI.VectorOfVariables([t; vec(X)]),
MOI.NormNuclearCone(2, 3),
)
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.NormNuclearCone}(1)MathOptInterface.SOS1 — TypeSOS1{T<:Real}(weights::Vector{T})The set corresponding to the Special Ordered Set (SOS) constraint of Type I.
Of the variables in the set, at most one can be nonzero.
The weights induce an ordering of the variables such that the kth element in the set corresponds to the kth weight in weights. Solvers may use these weights to improve the efficiency of the solution process, but the ordering does not change the set of feasible solutions.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variables(model, 3);
julia> MOI.add_constraint(
model,
MOI.VectorOfVariables(x),
MOI.SOS1([1.0, 3.0, 2.5]),
)
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.SOS1{Float64}}(1)MathOptInterface.SOS2 — TypeSOS2{T<:Real}(weights::Vector{T})The set corresponding to the Special Ordered Set (SOS) constraint of Type II.
The weights induce an ordering of the variables such that the kth element in the set corresponds to the kth weight in weights. Therefore, the weights must be unique.
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.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variables(model, 3);
julia> MOI.add_constraint(
model,
MOI.VectorOfVariables(x),
MOI.SOS2([1.0, 3.0, 2.5]),
)
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.SOS2{Float64}}(1)MathOptInterface.Indicator — TypeIndicator{ACTIVATE_ON_ZERO}(set::AbstractScalarSet)
Indicator{ACTIVATE_ON_ONE}(set::AbstractScalarSet)The set corresponding to an indicator constraint.
The type parameter must be an ActivationCondition.
When the type parameter is ACTIVATE_ON_ZERO, this means:
$\{(y, x) \in \{0, 1\} \times \mathbb{R} : y = 0 \implies x \in set\}$
When the type parameter is ACTIVATE_ON_ONE, this means:
$\{(y, x) \in \{0, 1\} \times \mathbb{R} : y = 1 \implies x \in set\}$
Notes
Most solvers expect that the first row of the function is interpretable as a VariableIndex (for example, 1.0 * x + 0.0), and that the variable is constrained to the ZeroOne set. An error will be thrown if this is not the case.
Example
The constraint $\{(y, x) \in \{0, 1\} \times \mathbb{R}^2 : y = 1 \implies x_1 + x_2 \leq 9 \}$ is defined as
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variables(model, 2);
julia> y, _ = MOI.add_constrained_variable(model, MOI.ZeroOne());
julia> f = MOI.Utilities.vectorize([y, 1.0 * x[1] + 1.0 * x[2]])
┌ ┐
│0.0 + 1.0 MOI.VariableIndex(3) │
│0.0 + 1.0 MOI.VariableIndex(1) + 1.0 MOI.VariableIndex(2)│
└ ┘
julia> s = MOI.Indicator{MOI.ACTIVATE_ON_ONE}(MOI.LessThan(9.0))
MathOptInterface.Indicator{MathOptInterface.ACTIVATE_ON_ONE, MathOptInterface.LessThan{Float64}}(MathOptInterface.LessThan{Float64}(9.0))
julia> MOI.add_constraint(model, f, s)
MathOptInterface.ConstraintIndex{MathOptInterface.VectorAffineFunction{Float64}, MathOptInterface.Indicator{MathOptInterface.ACTIVATE_ON_ONE, MathOptInterface.LessThan{Float64}}}(1)The constraint $\{(y, x) \in \{0, 1\} \times \mathbb{R} : y = 0 \implies x = 0 \}$ is defined as
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variable(model);
julia> y, _ = MOI.add_constrained_variable(model, MOI.ZeroOne());
julia> f = MOI.VectorOfVariables([y, x]);
julia> s = MOI.Indicator{MOI.ACTIVATE_ON_ZERO}(MOI.EqualTo(0.0))
MathOptInterface.Indicator{MathOptInterface.ACTIVATE_ON_ZERO, MathOptInterface.EqualTo{Float64}}(MathOptInterface.EqualTo{Float64}(0.0))
julia> MOI.add_constraint(model, f, s)
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.Indicator{MathOptInterface.ACTIVATE_ON_ZERO, MathOptInterface.EqualTo{Float64}}}(1)MathOptInterface.ActivationCondition — TypeActivationConditionActivation condition for an indicator constraint.
The enum value is used as first type parameter of Indicator{A,S}.
Values
The indicator constraint holds when the binary variable is zero.
The indicator constraint holds when the binary variable is one.
MathOptInterface.ACTIVATE_ON_ZERO — ConstantACTIVATE_ON_ZERO::ActivationConditionAn instance of the ActivationCondition enum.
About
The indicator constraint holds when the binary variable is zero.
MathOptInterface.ACTIVATE_ON_ONE — ConstantACTIVATE_ON_ONE::ActivationConditionAn instance of the ActivationCondition enum.
About
The indicator constraint holds when the binary variable is one.
MathOptInterface.Complements — TypeComplements(dimension::Base.Integer)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 dimension. This defines a complementarity constraint between the scalar function F[i] and the variable in F[i + dimension/2]. Thus, F[i + dimension/2] must be interpretable as a single variable x_i (for example, 1.0 * x + 0.0), and dimension must be even.
The mixed complementarity problem consists of finding x_i in the interval [lb, ub] (that is, in the set Interval(lb, ub)), such that the following holds:
F_i(x) == 0iflb_i < x_i < ub_iF_i(x) >= 0iflb_i == x_iF_i(x) <= 0ifx_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.
Example
The problem:
x -in- Interval(-1, 1)
[-4 * x - 3, x] -in- Complements(2)defines the mixed complementarity problem where the following holds:
-4 * x - 3 == 0if-1 < x < 1-4 * x - 3 >= 0ifx == -1-4 * x - 3 <= 0ifx == 1
There are three solutions:
x = -3/4withF(x) = 0x = -1withF(x) = 1x = 1withF(x) = -7
julia> model = MOI.Utilities.Model{Float64}();
julia> x, _ = MOI.add_constrained_variable(model, MOI.Interval(-1.0, 1.0));
julia> MOI.add_constraint(
model,
MOI.Utilities.vectorize([-4.0 * x - 3.0, x]),
MOI.Complements(2),
)
MathOptInterface.ConstraintIndex{MathOptInterface.VectorAffineFunction{Float64}, MathOptInterface.Complements}(1)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(4)defines the complementarity problem where 0 <= x_1 ⟂ x_3 >= 0 and 0 <= x_2 ⟂ x_4 >= 0.
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variables(model, 4);
julia> MOI.add_constraint(model, MOI.VectorOfVariables(x[3:4]), MOI.Nonnegatives(2))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.Nonnegatives}(1)
julia> MOI.add_constraint(
model,
MOI.VectorOfVariables(x),
MOI.Complements(4),
)
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.Complements}(1)MathOptInterface.HyperRectangle — TypeHyperRectangle(lower::Vector{T}, upper::Vector{T}) where {T}The set $\{x \in \bar{\mathbb{R}}^d: x_i \in [lower_i, upper_i] \forall i=1,\ldots,d\}$.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variables(model, 3)
3-element Vector{MathOptInterface.VariableIndex}:
MOI.VariableIndex(1)
MOI.VariableIndex(2)
MOI.VariableIndex(3)
julia> MOI.add_constraint(
model,
MOI.VectorOfVariables(x),
MOI.HyperRectangle(zeros(3), ones(3)),
)
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.HyperRectangle{Float64}}(1)MathOptInterface.Scaled — Typestruct Scaled{S<:AbstractVectorSet} <: AbstractVectorSet
set::S
endGiven a vector $a \in \mathbb{R}^d$ and a set representing the set $\mathcal{S} \in \mathbb{R}^d$ such that Utilities.set_dot for $x \in \mathcal{S}$ and $y \in \mathcal{S}^*$ is
\[\sum_{i=1}^d a_i x_i y_i\]
the set Scaled(set) is defined as
\[\{ (\sqrt{a_1} x_1, \sqrt{a_2} x_2, \ldots, \sqrt{a_d} x_d) : x \in S \}\]
Example
This can be used to scale a vector of numbers
julia> set = MOI.PositiveSemidefiniteConeTriangle(2)
MathOptInterface.PositiveSemidefiniteConeTriangle(2)
julia> a = MOI.Utilities.SetDotScalingVector{Float64}(set)
3-element MathOptInterface.Utilities.SetDotScalingVector{Float64, MathOptInterface.PositiveSemidefiniteConeTriangle}:
1.0
1.4142135623730951
1.0
julia> using LinearAlgebra
julia> MOI.Utilities.operate(*, Float64, Diagonal(a), ones(3))
3-element Vector{Float64}:
1.0
1.4142135623730951
1.0It can be also used to scale a vector of function
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variables(model, 3);
julia> func = MOI.VectorOfVariables(x)
┌ ┐
│MOI.VariableIndex(1)│
│MOI.VariableIndex(2)│
│MOI.VariableIndex(3)│
└ ┘
julia> set = MOI.PositiveSemidefiniteConeTriangle(2)
MathOptInterface.PositiveSemidefiniteConeTriangle(2)
julia> MOI.Utilities.operate(*, Float64, Diagonal(a), func)
┌ ┐
│0.0 + 1.0 MOI.VariableIndex(1) │
│0.0 + 1.4142135623730951 MOI.VariableIndex(2)│
│0.0 + 1.0 MOI.VariableIndex(3) │
└ ┘MathOptInterface.VectorNonlinearOracle — TypeVectorNonlinearOracle(;
dimension::Int,
l::Vector{Float64},
u::Vector{Float64},
eval_f::Function,
jacobian_structure::Vector{Tuple{Int,Int}},
eval_jacobian::Function,
hessian_lagrangian_structure::Vector{Tuple{Int,Int}} = Tuple{Int,Int}[],
eval_hessian_lagrangian::Union{Nothing,Function} = nothing,
) <: AbstractVectorSetThe set:
\[S = \{x \in \mathbb{R}^{dimension}: l \le f(x) \le u\}\]
where $f$ is defined by the vectors l and u, and the callback oracles eval_f, eval_jacobian, and eval_hessian_lagrangian.
f
The eval_f function must have the signature
eval_f(ret::AbstractVector, x::AbstractVector)::Nothingwhich fills $f(x)$ into the dense vector ret.
Jacobian
The eval_jacobian function must have the signature
eval_jacobian(ret::AbstractVector, x::AbstractVector)::Nothingwhich fills the sparse Jacobian $\nabla f(x)$ into ret.
The one-indexed sparsity structure must be provided in the jacobian_structure argument.
Hessian
The eval_hessian_lagrangian function is optional.
If eval_hessian_lagrangian === nothing, Ipopt will use a Hessian approximation instead of the exact Hessian.
If eval_hessian_lagrangian is a function, it must have the signature
eval_hessian_lagrangian(
ret::AbstractVector,
x::AbstractVector,
μ::AbstractVector,
)::Nothingwhich fills the sparse Hessian of the Lagrangian $\sum \mu_i \nabla^2 f_i(x)$ into ret.
The one-indexed sparsity structure must be provided in the hessian_lagrangian_structure argument.
Example
To model the set:
\[\begin{align} 0 \le & x^2 \le 1 0 \le & y^2 + z^3 - w \le 0 \end{align}\]
do
julia> import MathOptInterface as MOI
julia> set = MOI.VectorNonlinearOracle(;
dimension = 3,
l = [0.0, 0.0],
u = [1.0, 0.0],
eval_f = (ret, x) -> begin
ret[1] = x[2]^2
ret[2] = x[3]^2 + x[4]^3 - x[1]
return
end,
jacobian_structure = [(1, 2), (2, 1), (2, 3), (2, 4)],
eval_jacobian = (ret, x) -> begin
ret[1] = 2.0 * x[2]
ret[2] = -1.0
ret[3] = 2.0 * x[3]
ret[4] = 3.0 * x[4]^2
return
end,
hessian_lagrangian_structure = [(2, 2), (3, 3), (4, 4)],
eval_hessian_lagrangian = (ret, x, u) -> begin
ret[1] = 2.0 * u[1]
ret[2] = 2.0 * u[2]
ret[3] = 6.0 * x[4] * u[2]
return
end,
);
julia> set
VectorNonlinearOracle{Float64}(;
dimension = 3,
l = [0.0, 0.0],
u = [1.0, 0.0],
...,
)Constraint programming sets
MathOptInterface.AllDifferent — TypeAllDifferent(dimension::Int)The set $\{x \in \mathbb{Z}^{d}\}$ such that no two elements in $x$ take the same value and dimension = d.
Also known as
This constraint is called all_different in MiniZinc, and is sometimes also called distinct.
Example
To enforce x[1] != x[2] AND x[1] != x[3] AND x[2] != x[3]:
julia> model = MOI.Utilities.Model{Float64}();
julia> x = [MOI.add_constrained_variable(model, MOI.Integer())[1] for _ in 1:3]
3-element Vector{MathOptInterface.VariableIndex}:
MOI.VariableIndex(1)
MOI.VariableIndex(2)
MOI.VariableIndex(3)
julia> MOI.add_constraint(model, MOI.VectorOfVariables(x), MOI.AllDifferent(3))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.AllDifferent}(1)MathOptInterface.BinPacking — TypeBinPacking(c::T, w::Vector{T}) where {T}The set $\{x \in \mathbb{Z}^d\}$ where d = length(w), such that each item i in 1:d of weight w[i] is put into bin x[i], and the total weight of each bin does not exceed c.
There are additional assumptions that the capacity, c, and the weights, w, must all be non-negative.
The bin numbers depend on the bounds of x, so they may be something other than the integers 1:d.
Also known as
This constraint is called bin_packing in MiniZinc.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> bins = MOI.add_variables(model, 5)
5-element Vector{MathOptInterface.VariableIndex}:
MOI.VariableIndex(1)
MOI.VariableIndex(2)
MOI.VariableIndex(3)
MOI.VariableIndex(4)
MOI.VariableIndex(5)
julia> weights = Float64[1, 1, 2, 2, 3]
5-element Vector{Float64}:
1.0
1.0
2.0
2.0
3.0
julia> MOI.add_constraint.(model, bins, MOI.Integer())
5-element Vector{MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Integer}}:
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Integer}(1)
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Integer}(2)
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Integer}(3)
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Integer}(4)
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Integer}(5)
julia> MOI.add_constraint.(model, bins, MOI.Interval(4.0, 6.0))
5-element Vector{MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Interval{Float64}}}:
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Interval{Float64}}(1)
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Interval{Float64}}(2)
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Interval{Float64}}(3)
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Interval{Float64}}(4)
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Interval{Float64}}(5)
julia> MOI.add_constraint(model, MOI.VectorOfVariables(bins), MOI.BinPacking(3.0, weights))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.BinPacking{Float64}}(1)MathOptInterface.Circuit — TypeCircuit(dimension::Int)The set $\{x \in \{1..d\}^d\}$ that constraints $x$ to be a circuit, such that $x_i = j$ means that $j$ is the successor of $i$, and dimension = d.
Graphs with multiple independent circuits, such as [2, 1, 3] and [2, 1, 4, 3], are not valid.
Also known as
This constraint is called circuit in MiniZinc, and it is equivalent to forming a (potentially sub-optimal) tour in the travelling salesperson problem.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = [MOI.add_constrained_variable(model, MOI.Integer())[1] for _ in 1:3]
3-element Vector{MathOptInterface.VariableIndex}:
MOI.VariableIndex(1)
MOI.VariableIndex(2)
MOI.VariableIndex(3)
julia> MOI.add_constraint(model, MOI.VectorOfVariables(x), MOI.Circuit(3))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.Circuit}(1)MathOptInterface.CountAtLeast — TypeCountAtLeast(n::Int, d::Vector{Int}, set::Set{Int})The set $\{x \in \mathbb{Z}^{d_1 + d_2 + \ldots d_N}\}$, where x is partitioned into N subsets ($\{x_1, \ldots, x_{d_1}\}$, $\{x_{d_1 + 1}, \ldots, x_{d_1 + d_2}\}$ and so on), and at least $n$ elements of each subset take one of the values in set.
Also known as
This constraint is called at_least in MiniZinc.
Example
To ensure that 3 appears at least once in each of the subsets {a, b} and {b, c}:
julia> model = MOI.Utilities.Model{Float64}();
julia> a, _ = MOI.add_constrained_variable(model, MOI.Integer())
(MOI.VariableIndex(1), MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Integer}(1))
julia> b, _ = MOI.add_constrained_variable(model, MOI.Integer())
(MOI.VariableIndex(2), MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Integer}(2))
julia> c, _ = MOI.add_constrained_variable(model, MOI.Integer())
(MOI.VariableIndex(3), MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Integer}(3))
julia> x, d, set = [a, b, b, c], [2, 2], [3]
(MathOptInterface.VariableIndex[MOI.VariableIndex(1), MOI.VariableIndex(2), MOI.VariableIndex(2), MOI.VariableIndex(3)], [2, 2], [3])
julia> MOI.add_constraint(model, MOI.VectorOfVariables(x), MOI.CountAtLeast(1, d, Set(set)))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.CountAtLeast}(1)MathOptInterface.CountBelongs — TypeCountBelongs(dimenson::Int, set::Set{Int})The set $\{(n, x) \in \mathbb{Z}^{1+d}\}$, such that n elements of the vector x take on of the values in set and dimension = 1 + d.
Also known as
This constraint is called among by MiniZinc.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> n, _ = MOI.add_constrained_variable(model, MOI.Integer())
(MOI.VariableIndex(1), MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Integer}(1))
julia> x = [MOI.add_constrained_variable(model, MOI.Integer())[1] for _ in 1:3]
3-element Vector{MathOptInterface.VariableIndex}:
MOI.VariableIndex(2)
MOI.VariableIndex(3)
MOI.VariableIndex(4)
julia> set = Set([3, 4, 5])
Set{Int64} with 3 elements:
5
4
3
julia> MOI.add_constraint(model, MOI.VectorOfVariables([n; x]), MOI.CountBelongs(4, set))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.CountBelongs}(1)MathOptInterface.CountDistinct — TypeCountDistinct(dimension::Int)The set $\{(n, x) \in \mathbb{Z}^{1+d}\}$, such that the number of distinct values in x is n and dimension = 1 + d.
Also known as
This constraint is called nvalues in MiniZinc.
Example
To model:
- if
n == 1, thenx[1] == x[2] == x[3] - if
n == 2, thenx[1] == x[2] != x[3]orx[1] != x[2] == x[3]orx[1] == x[3] != x[2]
- if
n == 3, thenx[1] != x[2],x[2] != x[3]andx[3] != x[1]
julia> model = MOI.Utilities.Model{Float64}();
julia> n, _ = MOI.add_constrained_variable(model, MOI.Integer())
(MOI.VariableIndex(1), MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Integer}(1))
julia> x = [MOI.add_constrained_variable(model, MOI.Integer())[1] for _ in 1:3]
3-element Vector{MathOptInterface.VariableIndex}:
MOI.VariableIndex(2)
MOI.VariableIndex(3)
MOI.VariableIndex(4)
julia> MOI.add_constraint(model, MOI.VectorOfVariables(vcat(n, x)), MOI.CountDistinct(4))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.CountDistinct}(1)Relationship to AllDifferent
When the first element is d, CountDistinct is equivalent to an AllDifferent constraint.
MathOptInterface.CountGreaterThan — TypeCountGreaterThan(dimension::Int)The set $\{(c, y, x) \in \mathbb{Z}^{1+1+d}\}$, such that c is strictly greater than the number of occurences of y in x and dimension = 1 + 1 + d.
Also known as
This constraint is called count_gt in MiniZinc.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> c, _ = MOI.add_constrained_variable(model, MOI.Integer())
(MOI.VariableIndex(1), MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Integer}(1))
julia> y, _ = MOI.add_constrained_variable(model, MOI.Integer())
(MOI.VariableIndex(2), MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Integer}(2))
julia> x = [MOI.add_constrained_variable(model, MOI.Integer())[1] for _ in 1:3]
3-element Vector{MathOptInterface.VariableIndex}:
MOI.VariableIndex(3)
MOI.VariableIndex(4)
MOI.VariableIndex(5)
julia> MOI.add_constraint(model, MOI.VectorOfVariables([c; y; x]), MOI.CountGreaterThan(5))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.CountGreaterThan}(1)MathOptInterface.Cumulative — TypeCumulative(dimension::Int)The set $\{(s, d, r, b) \in \mathbb{Z}^{3n+1}\}$, representing the cumulative global constraint, where n == length(s) == length(r) == length(b) and dimension = 3n + 1.
Cumulative requires that a set of tasks given by start times $s$, durations $d$, and resource requirements $r$, never requires more than the global resource bound $b$ at any one time.
Also known as
This constraint is called cumulative in MiniZinc.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> s = [MOI.add_constrained_variable(model, MOI.Integer())[1] for _ in 1:3]
3-element Vector{MathOptInterface.VariableIndex}:
MOI.VariableIndex(1)
MOI.VariableIndex(2)
MOI.VariableIndex(3)
julia> d = [MOI.add_constrained_variable(model, MOI.Integer())[1] for _ in 1:3]
3-element Vector{MathOptInterface.VariableIndex}:
MOI.VariableIndex(4)
MOI.VariableIndex(5)
MOI.VariableIndex(6)
julia> r = [MOI.add_constrained_variable(model, MOI.Integer())[1] for _ in 1:3]
3-element Vector{MathOptInterface.VariableIndex}:
MOI.VariableIndex(7)
MOI.VariableIndex(8)
MOI.VariableIndex(9)
julia> b, _ = MOI.add_constrained_variable(model, MOI.Integer())
(MOI.VariableIndex(10), MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Integer}(10))
julia> MOI.add_constraint(model, MOI.VectorOfVariables([s; d; r; b]), MOI.Cumulative(10))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.Cumulative}(1)MathOptInterface.Path — TypePath(from::Vector{Int}, to::Vector{Int})Given a graph comprised of a set of nodes 1..N and a set of arcs 1..E represented by an edge from node from[i] to node to[i], Path constrains the set $(s, t, ns, es) \in (1..N)\times(1..E)\times\{0,1\}^N\times\{0,1\}^E$, to form subgraph that is a path from node s to node t, where node n is in the path if ns[n] is 1, and edge e is in the path if es[e] is 1.
The path must be acyclic, and it must traverse all nodes n for which ns[n] is 1, and all edges e for which es[e] is 1.
Also known as
This constraint is called path in MiniZinc.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> N, E = 4, 5
(4, 5)
julia> from = [1, 1, 2, 2, 3]
5-element Vector{Int64}:
1
1
2
2
3
julia> to = [2, 3, 3, 4, 4]
5-element Vector{Int64}:
2
3
3
4
4
julia> s, _ = MOI.add_constrained_variable(model, MOI.Integer())
(MOI.VariableIndex(1), MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Integer}(1))
julia> t, _ = MOI.add_constrained_variable(model, MOI.Integer())
(MOI.VariableIndex(2), MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Integer}(2))
julia> ns = MOI.add_variables(model, N)
4-element Vector{MathOptInterface.VariableIndex}:
MOI.VariableIndex(3)
MOI.VariableIndex(4)
MOI.VariableIndex(5)
MOI.VariableIndex(6)
julia> MOI.add_constraint.(model, ns, MOI.ZeroOne())
4-element Vector{MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.ZeroOne}}:
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.ZeroOne}(3)
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.ZeroOne}(4)
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.ZeroOne}(5)
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.ZeroOne}(6)
julia> es = MOI.add_variables(model, E)
5-element Vector{MathOptInterface.VariableIndex}:
MOI.VariableIndex(7)
MOI.VariableIndex(8)
MOI.VariableIndex(9)
MOI.VariableIndex(10)
MOI.VariableIndex(11)
julia> MOI.add_constraint.(model, es, MOI.ZeroOne())
5-element Vector{MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.ZeroOne}}:
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.ZeroOne}(7)
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.ZeroOne}(8)
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.ZeroOne}(9)
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.ZeroOne}(10)
MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.ZeroOne}(11)
julia> MOI.add_constraint(model, MOI.VectorOfVariables([s; t; ns; es]), MOI.Path(from, to))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.Path}(1)MathOptInterface.Reified — TypeReified(set::AbstractSet)The constraint $[z; f(x)] \in Reified(S)$ ensures that $f(x) \in S$ if and only if $z == 1$, where $z \in \{0, 1\}$.
julia> model = MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}());
julia> z, _ = MOI.add_constrained_variable(model, MOI.ZeroOne())
(MOI.VariableIndex(1), MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.ZeroOne}(1))
julia> x = MOI.add_variable(model)
MOI.VariableIndex(2)
julia> MOI.add_constraint(
model,
MOI.Utilities.vectorize([z, 2.0 * x]),
MOI.Reified(MOI.GreaterThan(1.0)),
)
MathOptInterface.ConstraintIndex{MathOptInterface.VectorAffineFunction{Float64}, MathOptInterface.Reified{MathOptInterface.GreaterThan{Float64}}}(1)MathOptInterface.Table — TypeTable(table::Matrix{T}) where {T}The set $\{x \in \mathbb{R}^d\}$ where d = size(table, 2), such that x belongs to one row of table. That is, there exists some j in 1:size(table, 1), such that x[i] = table[j, i] for all i=1:size(table, 2).
Also known as
This constraint is called table in MiniZinc.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> x = MOI.add_variables(model, 3)
3-element Vector{MathOptInterface.VariableIndex}:
MOI.VariableIndex(1)
MOI.VariableIndex(2)
MOI.VariableIndex(3)
julia> table = Float64[1 1 0; 0 1 1; 1 0 1; 1 1 1]
4×3 Matrix{Float64}:
1.0 1.0 0.0
0.0 1.0 1.0
1.0 0.0 1.0
1.0 1.0 1.0
julia> MOI.add_constraint(model, MOI.VectorOfVariables(x), MOI.Table(table))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.Table{Float64}}(1)Matrix sets
Matrix sets are vectorized to be subtypes of AbstractVectorSet.
For sets of symmetric matrices, storing both the (i, j) and (j, i) elements is redundant. Use 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 additional constraints are needed to force the equality of the (i, j) and (j, i) elements, use the AbstractSymmetricMatrixSetSquare set.
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 endAbstract 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.)
Example
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) + iif $i \leq j$ andk = div((i - 1) * i, 2) + jif $j \leq i$; - and the entry with vectorized index
khas 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 endAbstract 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.
Example
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,
HermitianPositiveSemidefiniteConeTriangle,
},
)Side dimension of the matrices in set.
Convention
By convention, the side dimension should be stored in the side_dimension field. If this is not the case for a subtype of AbstractSymmetricMatrixSetTriangle, or AbstractSymmetricMatrixSetSquare you must implement this method.
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::Int) <: AbstractSymmetricMatrixSetTriangleThe (vectorized) cone of symmetric positive semidefinite matrices, with non-negative side_dimension rows and columns.
See AbstractSymmetricMatrixSetTriangle for more details on the vectorized form.
MathOptInterface.PositiveSemidefiniteConeSquare — TypePositiveSemidefiniteConeSquare(side_dimension::Int) <: AbstractSymmetricMatrixSetSquareThe cone of symmetric positive semidefinite matrices, with non-negative 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.
Example
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.HermitianPositiveSemidefiniteConeTriangle — TypeHermitianPositiveSemidefiniteConeTriangle(side_dimension::Int) <: AbstractVectorSetThe (vectorized) cone of Hermitian positive semidefinite matrices, with non-negative side_dimension rows and columns.
Becaue the matrix is Hermitian, the diagonal elements are real, and the complex-valued lower triangular entries are obtained as the conjugate of corresponding upper triangular entries.
Vectorization format
The vectorized form starts with real part of the entries of the upper triangular part of the matrix, given column by column as explained in AbstractSymmetricMatrixSetSquare.
It is then followed by the imaginary part of the off-diagonal entries of the upper triangular part, also given column by column.
For example, the matrix
\[\begin{bmatrix} 1 & 2 + 7im & 4 + 8im\\ 2 - 7im & 3 & 5 + 9im\\ 4 - 8im & 5 - 9im & 6 \end{bmatrix}\]
has side_dimension 3 and is represented as the vector $[1, 2, 3, 4, 5, 6, 7, 8, 9]$.
MathOptInterface.LogDetConeTriangle — TypeLogDetConeTriangle(side_dimension::Int)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 non-negative argument side_dimension is the side dimension of the matrix X, that is, its number of rows or columns.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> t = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> X = MOI.add_variables(model, 3);
julia> MOI.add_constraint(
model,
MOI.VectorOfVariables([t; X]),
MOI.LogDetConeTriangle(2),
)
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.LogDetConeTriangle}(1)MathOptInterface.LogDetConeSquare — TypeLogDetConeSquare(side_dimension::Int)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 ensure that X is symmetric.
The non-negative argument side_dimension is the side dimension of the matrix X, that is, its number of rows or columns.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> t = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> X = reshape(MOI.add_variables(model, 4), 2, 2)
2×2 Matrix{MathOptInterface.VariableIndex}:
MOI.VariableIndex(2) MOI.VariableIndex(4)
MOI.VariableIndex(3) MOI.VariableIndex(5)
julia> MOI.add_constraint(
model,
MOI.VectorOfVariables([t; vec(X)]),
MOI.LogDetConeSquare(2),
)
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.LogDetConeSquare}(1)MathOptInterface.RootDetConeTriangle — TypeRootDetConeTriangle(side_dimension::Int)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 non-negative argument side_dimension is the side dimension of the matrix X, that is, its number of rows or columns.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> t = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> X = MOI.add_variables(model, 3);
julia> MOI.add_constraint(
model,
MOI.VectorOfVariables([t; X]),
MOI.RootDetConeTriangle(2),
)
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.RootDetConeTriangle}(1)MathOptInterface.RootDetConeSquare — TypeRootDetConeSquare(side_dimension::Int)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 PositiveSemidefiniteConeSquare.
Similarly to PositiveSemidefiniteConeSquare, constraints are added to ensure that X is symmetric.
The non-negative argument side_dimension is the side dimension of the matrix X, that is, its number of rows or columns.
Example
julia> model = MOI.Utilities.Model{Float64}();
julia> t = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> X = reshape(MOI.add_variables(model, 4), 2, 2)
2×2 Matrix{MathOptInterface.VariableIndex}:
MOI.VariableIndex(2) MOI.VariableIndex(4)
MOI.VariableIndex(3) MOI.VariableIndex(5)
julia> MOI.add_constraint(
model,
MOI.VectorOfVariables([t; vec(X)]),
MOI.RootDetConeSquare(2),
)
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.RootDetConeSquare}(1)