## Utilities.Model

`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)
```

## Utilities.UniversalFallback

`MathOptInterface.Utilities.UniversalFallback`

— Type`UniversalFallback`

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.

## Utilities.@model

`MathOptInterface.Utilities.@model`

— Macro```
macro 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.VariableIndex`

should not be given in `scalar_functions`

. The model supports `MathOptInterface.VariableIndex`

-in-`S`

constraints where `S`

is `MathOptInterface.EqualTo`

, `MathOptInterface.GreaterThan`

, `MathOptInterface.LessThan`

, `MathOptInterface.Interval`

, `MathOptInterface.Integer`

, `MathOptInterface.ZeroOne`

, `MathOptInterface.Semicontinuous`

or `MathOptInterface.Semiinteger`

. The sets supported with the `MathOptInterface.VariableIndex`

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`

.

If `is_optimizer = true`

, the resulting struct is a of `GenericOptimizer`

, which is a subtype of `MathOptInterface.AbstractOptimizer`

, otherwise, it is a `GenericModel`

, 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`

. The macro would create the following types with `struct_of_constraint_code`

:

```
struct LPModelScalarConstraints{T, C1, C2, C3, C4} <: MOIU.StructOfConstraints
moi_equalto::C1
moi_greaterthan::C2
moi_lessthan::C3
moi_interval::C4
end
struct LPModelVectorConstraints{T, C1, C2, C3} <: MOIU.StructOfConstraints
moi_zeros::C1
moi_nonnegatives::C2
moi_nonpositives::C3
end
struct LPModelFunctionConstraints{T} <: MOIU.StructOfConstraints
moi_scalaraffinefunction::LPModelScalarConstraints{
T,
MOIU.VectorOfConstraints{MOI.ScalarAffineFunction{T}, MOI.EqualTo{T}},
MOIU.VectorOfConstraints{MOI.ScalarAffineFunction{T}, MOI.GreaterThan{T}},
MOIU.VectorOfConstraints{MOI.ScalarAffineFunction{T}, MOI.LessThan{T}},
MOIU.VectorOfConstraints{MOI.ScalarAffineFunction{T}, MOI.Interval{T}}
}
moi_vectorofvariables::LPModelVectorConstraints{
T,
MOIU.VectorOfConstraints{MOI.VectorOfVariables, MOI.Zeros},
MOIU.VectorOfConstraints{MOI.VectorOfVariables, MOI.Nonnegatives},
MOIU.VectorOfConstraints{MOI.VectorOfVariables, MOI.Nonpositives}
}
moi_vectoraffinefunction::LPModelVectorConstraints{
T,
MOIU.VectorOfConstraints{MOI.VectorAffineFunction{T}, MOI.Zeros},
MOIU.VectorOfConstraints{MOI.VectorAffineFunction{T}, MOI.Nonnegatives},
MOIU.VectorOfConstraints{MOI.VectorAffineFunction{T}, MOI.Nonpositives}
}
end
const LPModel{T} = MOIU.GenericModel{T,MOIU.ObjectiveContainer{T},MOIU.VariablesContainer{T},LPModelFunctionConstraints{T}}
```

The type `LPModel`

implements the MathOptInterface API except methods specific to optimizers like `optimize!`

or `get`

with `VariablePrimal`

.

`MathOptInterface.Utilities.GenericModel`

— Type`mutable struct GenericModel{T,O,V,C} <: AbstractModelLike{T}`

Implements a model supporting coefficients of type `T`

and:

- An objective function stored in
`.objective::O`

- Variables and
`VariableIndex`

constraints stored in`.variable_bounds::V`

`F`

-in-`S`

constraints (excluding`VariableIndex`

constraints) stored in`.constraints::C`

All interactions should take place via the MOI interface, so the types `O`

, `V`

, and `C`

should implement the API as needed for their functionality.

`MathOptInterface.Utilities.GenericOptimizer`

— Type`mutable struct GenericOptimizer{T,O,V,C} <: AbstractOptimizer{T}`

Implements a model supporting coefficients of type `T`

and:

- An objective function stored in
`.objective::O`

- Variables and
`VariableIndex`

constraints stored in`.variable_bounds::V`

`F`

-in-`S`

constraints (excluding`VariableIndex`

constraints) stored in`.constraints::C`

All interactions should take place via the MOI interface, so the types `O`

, `V`

, and `C`

should implement the API as needed for their functionality.

`MathOptInterface.Utilities.@struct_of_constraints_by_function_types`

— Macro`Utilities.@struct_of_constraints_by_function_types(name, func_types...)`

Given a vector of `n`

function types `(F1, F2,..., Fn)`

in `func_types`

, defines a subtype of `StructOfConstraints`

of name `name`

and which type parameters `{T, C1, C2, ..., Cn}`

. It contains `n`

field where the `i`

th field has type `Ci`

and stores the constraints of function type `Fi`

.

The expression `Fi`

can also be a union in which case any constraint for which the function type is in the union is stored in the field with type `Ci`

.

`MathOptInterface.Utilities.@struct_of_constraints_by_set_types`

— Macro`Utilities.@struct_of_constraints_by_set_types(name, func_types...)`

Given a vector of `n`

set types `(S1, S2,..., Sn)`

in `func_types`

, defines a subtype of `StructOfConstraints`

of name `name`

and which type parameters `{T, C1, C2, ..., Cn}`

. It contains `n`

field where the `i`

th field has type `Ci`

and stores the constraints of set type `Si`

. The expression `Si`

can also be a union in which case any constraint for which the set type is in the union is stored in the field with type `Ci`

. This can be useful if `Ci`

is a `MatrixOfConstraints`

in order to concatenate the coefficients of constraints of several different set types in the same matrix.

`MathOptInterface.Utilities.struct_of_constraint_code`

— Function`struct_of_constraint_code(struct_name, types, field_types = nothing)`

Given a vector of `n`

`Union{SymbolFun,_UnionSymbolFS{SymbolFun}}`

or `Union{SymbolSet,_UnionSymbolFS{SymbolSet}}`

in `types`

, defines a subtype of `StructOfConstraints`

of name `name`

and which type parameters `{T, F1, F2, ..., Fn}`

if `field_types`

is `nothing`

and a `{T}`

otherwise. It contains `n`

field where the `i`

th field has type `Ci`

if `field_types`

is `nothing`

and type `field_types[i]`

otherwise. If `types`

is vector of `Union{SymbolFun,_UnionSymbolFS{SymbolFun}}`

(resp. `Union{SymbolSet,_UnionSymbolFS{SymbolSet}}`

) then the constraints of that function (resp. set) type are stored in the corresponding field.

This function is used by the macros `@model`

, `@struct_of_constraints_by_function_types`

and `@struct_of_constraints_by_set_types`

.

### Caching optimizer

`MathOptInterface.Utilities.CachingOptimizer`

— Type`CachingOptimizer`

`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 the`CachingOptimizer`

are`Utilities.reset_optimizer`

,`Utilities.drop_optimizer`

, and`Utilities.attach_optimizer`

. Attempting to perform an operation in the incorrect state results in an error.`AUTOMATIC`

: The`CachingOptimizer`

changes its state when necessary. For example,`optimize!`

will automatically call`attach_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 to`EMPTY_OPTIMIZER`

mode.

`MathOptInterface.Utilities.attach_optimizer`

— Function`attach_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.

`MOIU.attach_optimizer(model::Model)`

Call `MOIU.attach_optimizer`

on the backend of `model`

.

Cannot be called in direct mode.

`MathOptInterface.Utilities.reset_optimizer`

— Function`reset_optimizer(m::CachingOptimizer, optimizer::MOI.AbstractOptimizer)`

Sets or resets `m`

to have the given empty optimizer `optimizer`

.

Can be called from any state. An assertion error will be thrown if `optimizer`

is not empty.

The `CachingOptimizer`

`m`

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.

`MOIU.reset_optimizer(model::Model, optimizer::MOI.AbstractOptimizer)`

Call `MOIU.reset_optimizer`

on the backend of `model`

.

Cannot be called in direct mode.

`MOIU.reset_optimizer(model::Model)`

Call `MOIU.reset_optimizer`

on the backend of `model`

.

Cannot be called in direct mode.

`MathOptInterface.Utilities.drop_optimizer`

— Function`drop_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.

`MOIU.drop_optimizer(model::Model)`

Call `MOIU.drop_optimizer`

on the backend of `model`

.

Cannot be called in direct mode.

`MathOptInterface.Utilities.state`

— Function`state(m::CachingOptimizer)::CachingOptimizerState`

Returns the state of the CachingOptimizer `m`

. See `Utilities.CachingOptimizer`

.

`MathOptInterface.Utilities.mode`

— Function`mode(m::CachingOptimizer)::CachingOptimizerMode`

Returns the operating mode of the CachingOptimizer `m`

. See `Utilities.CachingOptimizer`

.

### Mock optimizer

`MathOptInterface.Utilities.MockOptimizer`

— Type`MockOptimizer`

`MockOptimizer`

is a fake optimizer especially useful for testing. Its main feature is that it can store the values that should be returned for each attribute.

## Printing

`MathOptInterface.Utilities.latex_formulation`

— Function`latex_formulation(model::MOI.ModelLike; kwargs...)`

Wrap `model`

in a type so that it can be pretty-printed as `text/latex`

in a notebook like IJulia, or in Documenter.

To render the model, end the cell with `latex_formulation(model)`

, or call `display(latex_formulation(model))`

in to force the display of the model from inside a function.

Possible keyword arguments are:

`simplify_coefficients`

: Simplify coefficients if possible by omitting them or removing trailing zeros.`default_name`

: The name given to variables with an empty name.`print_types`

: Print the MOI type of each function and set for clarity.

## Copy utilities

`MathOptInterface.Utilities.default_copy_to`

— Function`default_copy_to(dest::MOI.ModelLike, src::MOI.ModelLike)`

A default implementation of `MOI.copy_to(dest, src)`

for models that implement the incremental interface, i.e., `MOI.supports_incremental_interface`

returns `true`

.

`MathOptInterface.Utilities.IndexMap`

— Type`IndexMap()`

The dictionary-like object returned by `MathOptInterface.copy_to`

.

`MathOptInterface.Utilities.identity_index_map`

— Function`identity_index_map(model::MOI.ModelLike)`

Return an `IndexMap`

that maps all variable and constraint indices of `model`

to themselves.

`MathOptInterface.Utilities.ModelFilter`

— Type`ModelFilter(filter::Function, model::MOI.ModelLike)`

A layer to filter out various components of `model`

.

The filter function takes a single argument, which is eacy element from the list returned by the attributes below. It returns `true`

if the element should be visible in the filtered model and `false`

otherwise.

The components that are filtered are:

- Entire constraint types via:
`MOI.ListOfConstraintTypesPresent`

- Individual constraints via:
`MOI.ListOfConstraintIndices{F,S}`

- Specific attributes via:
`MOI.ListOfModelAttributesSet`

`MOI.ListOfConstraintAttributesSet`

`MOI.ListOfVariableAttributesSet`

The list of attributes filtered may change in a future release. You should write functions that are generic and not limited to the five types listed above. Thus, you should probably define a fallback `filter(::Any) = true`

.

See below for examples of how this works.

This layer has a limited scope. It is intended by be used in conjunction with `MOI.copy_to`

.

**Example: copy model excluding integer constraints**

Use the `do`

syntax to provide a single function.

```
filtered_src = MOI.Utilities.ModelFilter(src) do item
return item != (MOI.VariableIndex, MOI.Integer)
end
MOI.copy_to(dest, filtered_src)
```

**Example: copy model excluding names**

Use type dispatch to simplify the implementation:

```
my_filter(::Any) = true # Note the generic fallback!
my_filter(::MOI.VariableName) = false
my_filter(::MOI.ConstraintName) = false
filtered_src = MOI.Utilities.ModelFilter(my_filter, src)
MOI.copy_to(dest, filtered_src)
```

**Example: copy irreducible infeasible subsystem**

```
my_filter(::Any) = true # Note the generic fallback!
function my_filter(ci::MOI.ConstraintIndex)
status = MOI.get(dest, MOI.ConstraintConflictStatus(), ci)
return status != MOI.NOT_IN_CONFLICT
end
filtered_src = MOI.Utilities.ModelFilter(my_filter, src)
MOI.copy_to(dest, filtered_src)
```

## MatrixOfConstraints

`MathOptInterface.Utilities.MatrixOfConstraints`

— Type```
mutable struct MatrixOfConstraints{T,AT,BT,ST} <: MOI.ModelLike
coefficients::AT
constants::BT
sets::ST
caches::Vector{Any}
are_indices_mapped::Vector{BitSet}
final_touch::Bool
end
```

Represent `ScalarAffineFunction`

and `VectorAffinefunction`

constraints in a matrix form where the linear coefficients of the functions are stored in the `coefficients`

field, the constants of the functions or sets are stored in the `constants`

field. Additional information about the sets are stored in the `sets`

field.

This model can only be used as the `constraints`

field of a `MOI.Utilities.AbstractModel`

.

When the constraints are added, they are stored in the `caches`

field. They are only loaded in the `coefficients`

and `constants`

fields once `MOI.Utilities.final_touch`

is called. For this reason, `MatrixOfConstraints`

should not be used by an incremental interface. Use `MOI.copy_to`

instead.

The constraints can be added in two different ways:

- With
`add_constraint`

, in which case a canonicalized copy of the function is stored in`caches`

. - With
`pass_nonvariable_constraints`

, in which case the functions and sets are stored themselves in`caches`

without mapping the variable indices. The corresponding index in`caches`

is added in`are_indices_mapped`

. This avoids doing a copy of the function in case the getter of`CanonicalConstraintFunction`

does not make a copy for the source model, e.g., this is the case of`VectorOfConstraints`

.

We illustrate this with an example. Suppose a model is copied from a `src::MOI.Utilities.Model`

to a bridged model with a `MatrixOfConstraints`

. For all the types that are not bridged, the constraints will be copied with `pass_nonvariable_constraints`

. Hence the functions stored in `caches`

are exactly the same as the ones stored in `src`

. This is ok since this is only during the `copy_to`

operation during which `src`

cannot be modified. On the other hand, for the types that are bridged, the functions added may contain duplicates even if the functions did not contain duplicates in `src`

so duplicates are removed with `MOI.Utilities.canonical`

.

**Interface**

The `.coefficients::AT`

type must implement:

`AT()`

`MOI.empty(::AT)!`

`MOI.Utilities.add_column`

`MOI.Utilities.set_number_of_rows`

`MOI.Utilities.allocate_terms`

`MOI.Utilities.load_terms`

`MOI.Utilities.final_touch`

The `.constants::BT`

type must implement:

`BT()`

`Base.empty!(::BT)`

`Base.resize(::BT)`

`MOI.Utilities.load_constants`

`MOI.Utilities.function_constants`

`MOI.Utilities.set_from_constants`

The `.sets::ST`

type must implement:

`ST()`

`MOI.is_empty(::ST)`

`MOI.empty(::ST)`

`MOI.dimension(::ST)`

`MOI.is_valid(::ST, ::MOI.ConstraintIndex)`

`MOI.get(::ST, ::MOI.ListOfConstraintTypesPresent)`

`MOI.get(::ST, ::MOI.NumberOfConstraints)`

`MOI.get(::ST, ::MOI.ListOfConstraintIndices)`

`MOI.Utilities.set_types`

`MOI.Utilities.set_index`

`MOI.Utilities.add_set`

`MOI.Utilities.rows`

`MOI.Utilities.final_touch`

`.coefficients`

`MathOptInterface.Utilities.add_column`

— Function`add_column(coefficients)::Nothing`

Tell `coefficients`

to pre-allocate datastructures as needed to store one column.

`MathOptInterface.Utilities.allocate_terms`

— Function`allocate_terms(coefficients, index_map, func)::Nothing`

Tell `coefficients`

that the terms of the function `func`

where the variable indices are mapped with `index_map`

will be loaded with `load_terms`

.

The function `func`

must be canonicalized before calling `allocate_terms`

. See `is_canonical`

.

`MathOptInterface.Utilities.set_number_of_rows`

— Function`set_number_of_rows(coefficients, n)::Nothing`

Tell `coefficients`

to pre-allocate datastructures as needed to store `n`

rows.

`MathOptInterface.Utilities.load_terms`

— Function`load_terms(coefficients, index_map, func, offset)::Nothing`

Loads the terms of `func`

to `coefficients`

, mapping the variable indices with `index_map`

.

The `i`

th dimension of `func`

is loaded at the `(offset + i)`

th row of `coefficients`

.

The function must be allocated first with `allocate_terms`

.

The function `func`

must be canonicalized, see `is_canonical`

.

`MathOptInterface.Utilities.final_touch`

— Function`final_touch(coefficients)::Nothing`

Informs the `coefficients`

that all functions have been added with `load_terms`

. No more modification is allowed unless `MOI.empty!`

is called.

`final_touch(sets)::Nothing`

Informs the `sets`

that all functions have been added with `add_set`

. No more modification is allowed unless `MOI.empty!`

is called.

`MathOptInterface.Utilities.extract_function`

— Function`extract_function(coefficients, row::Integer, constant::T) where {T}`

Return the `MOI.ScalarAffineFunction{T}`

function corresponding to row `row`

in `coefficients`

.

```
extract_function(
coefficients,
rows::UnitRange,
constants::Vector{T},
) where{T}
```

Return the `MOI.VectorAffineFunction{T}`

function corresponding to rows `rows`

in `coefficients`

.

`MathOptInterface.Utilities.MutableSparseMatrixCSC`

— Type```
mutable struct MutableSparseMatrixCSC{Tv,Ti<:Integer,I<:AbstractIndexing}
indexing::I
m::Int
n::Int
colptr::Vector{Ti}
rowval::Vector{Ti}
nzval::Vector{Tv}
end
```

Matrix type loading sparse matrices in the Compressed Sparse Column format. The indexing used is `indexing`

, see `AbstractIndexing`

. The other fields have the same meaning than for `SparseArrays.SparseMatrixCSC`

except that the indexing is different unless `indexing`

is `OneBasedIndexing`

.

The matrix is loaded in 5 steps:

`MOI.empty!`

is called.`MOI.Utilities.add_column`

and`MOI.Utilities.allocate_terms`

are called in any order.`MOI.Utilities.set_number_of_rows`

is called.`MOI.Utilities.load_terms`

is called for each affine function.`MOI.Utilities.final_touch`

is called.

`MathOptInterface.Utilities.AbstractIndexing`

— Type`abstract type AbstractIndexing end`

Indexing to be used for storing the row and column indices of `MutableSparseMatrixCSC`

. See `ZeroBasedIndexing`

and `OneBasedIndexing`

.

`MathOptInterface.Utilities.ZeroBasedIndexing`

— Type`struct ZeroBasedIndexing <: AbstractIndexing end`

Zero-based indexing: the `i`

th row or column has index `i - 1`

. This is useful when the vectors of row and column indices need to be communicated to a library using zero-based indexing such as C libraries.

`MathOptInterface.Utilities.OneBasedIndexing`

— Type`struct ZeroBasedIndexing <: AbstractIndexing end`

One-based indexing: the `i`

th row or column has index `i`

. This enables an allocation-free conversion of `MutableSparseMatrixCSC`

to `SparseArrays.SparseMatrixCSC`

.

`.constants`

`MathOptInterface.Utilities.load_constants`

— Function`load_constants(constants, offset, func_or_set)::Nothing`

This function loads the constants of `func_or_set`

in `constants`

at an offset of `offset`

. Where `offset`

is the sum of the dimensions of the constraints already loaded. The storage should be preallocated with `resize!`

before calling this function.

This function should be implemented to be usable as storage of constants for `MatrixOfConstraints`

.

The constants are loaded in three steps:

`Base.empty!`

is called.`Base.resize!`

is called with the sum of the dimensions of all constraints.`MOI.Utilities.load_constants`

is called for each function for vector constraint or set for scalar constraint.

`MathOptInterface.Utilities.function_constants`

— Function`function_constants(constants, rows)`

This function returns the function constants that were loaded with `load_constants`

at the rows `rows`

.

This function should be implemented to be usable as storage of constants for `MatrixOfConstraints`

.

`MathOptInterface.Utilities.set_from_constants`

— Function`set_from_constants(constants, S::Type, rows)::S`

This function returns an instance of the set `S`

for which the constants where loaded with `load_constants`

at the rows `rows`

.

This function should be implemented to be usable as storage of constants for `MatrixOfConstraints`

.

`MathOptInterface.Utilities.Hyperrectangle`

— Type```
struct Hyperrectangle{T} <: AbstractVectorBounds
lower::Vector{T}
upper::Vector{T}
end
```

A struct for the .constants field in MatrixOfConstraints.

`.sets`

`MathOptInterface.Utilities.set_index`

— Function`set_index(sets, ::Type{S})::Union{Int,Nothing} where {S<:MOI.AbstractSet}`

Return an integer corresponding to the index of the set type in the list given by `set_types`

.

If `S`

is not part of the list, return `nothing`

.

`MathOptInterface.Utilities.set_types`

— Function`set_types(sets)::Vector{Type}`

Return the list of the types of the sets allowed in `sets`

.

`MathOptInterface.Utilities.add_set`

— Function`add_set(sets, i)::Int64`

Add a scalar set of type index `i`

.

`add_set(sets, i, dim)::Int64`

Add a vector set of type index `i`

and dimension `dim`

.

Both methods return a unique `Int64`

of the set that can be used to reference this set.

`MathOptInterface.Utilities.rows`

— Function`rows(sets, ci::MOI.ConstraintIndex)::Union{Int,UnitRange{Int}}`

Return the rows in `1:MOI.dimension(sets)`

corresponding to the set of id `ci.value`

.

For scalar sets, this returns an `Int`

. For vector sets, this returns an `UnitRange{Int}`

.

`MathOptInterface.Utilities.set_with_dimension`

— Function`set_with_dimension(::Type{S}, dim) where {S<:MOI.AbstractVectorSet}`

Returns the instance of `S`

of `MathOptInterface.dimension`

`dim`

. This needs to be implemented for sets of type `S`

to be useable with `MatrixOfConstraints`

.

`MathOptInterface.Utilities.ProductOfSets`

— Type`abstract type ProductOfSets{T} end`

Represents a cartesian product of sets of given types.

`MathOptInterface.Utilities.MixOfScalarSets`

— Type`abstract type MixOfScalarSets{T} <: ProductOfSets{T} end`

Product of scalar sets in the order the constraints are added, mixing the constraints of different types.

Use `@mix_of_scalar_sets`

to generate a new subtype.

`MathOptInterface.Utilities.@mix_of_scalar_sets`

— Macro`@mix_of_scalar_sets(name, set_types...)`

Generate a new `MixOfScalarSets`

subtype.

**Example**

```
@mix_of_scalar_sets(
MixedIntegerLinearProgramSets,
MOI.GreaterThan{T},
MOI.LessThan{T},
MOI.EqualTo{T},
MOI.Integer,
)
```

`MathOptInterface.Utilities.OrderedProductOfSets`

— Type`abstract type OrderedProductOfSets{T} <: ProductOfSets{T} end`

Product of sets in the order the constraints are added, grouping the constraints of the same types contiguously.

Use `@product_of_sets`

to generate new subtypes.

`MathOptInterface.Utilities.@product_of_sets`

— Macro`@product_of_sets(name, set_types...)`

Generate a new `OrderedProductOfSets`

subtype.

**Example**

```
@product_of_sets(
LinearOrthants,
MOI.Zeros,
MOI.Nonnegatives,
MOI.Nonpositives,
MOI.ZeroOne,
)
```

## Fallbacks

`MathOptInterface.Utilities.get_fallback`

— Function`get_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.VariableIndex,
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.VariableIndex`

-in-`S`

or `MOI.VectorOfVariables`

-in-`S`

constraint with one of the variables in the function of the constraint `ci`

.

## Function utilities

The following utilities are available for functions:

`MathOptInterface.Utilities.eval_variables`

— Function`eval_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`

— Function`map_indices(index_map::Function, x::X)::X where {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`

— Function`substitute_variables(variable_map::Function, x)`

Substitute any `MOI.VariableIndex`

in `x`

by `variable_map(x)`

. The `variable_map`

function returns either `MOI.VariableIndex`

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.

WARNING: Don't use `substitude_variables(::Function, ...)`

because Julia will not specialize on this. Use instead `substitude_variables(::F, ...) where {F<:Function}`

.

`MathOptInterface.Utilities.filter_variables`

— Function`filter_variables(keep::Function, f::AbstractFunction)`

Return a new function `f`

with the variable `vi`

such that `!keep(vi)`

removed.

WARNING: Don't define `filter_variables(::Function, ...)`

because Julia will not specialize on this. Define instead `filter_variables(::F, ...) where {F<:Function}`

.

`MathOptInterface.Utilities.remove_variable`

— Function`remove_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`

— Function`all_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`

— Function`unsafe_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`

of `t1`

as the `variable`

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`

's of `t1`

as the `variable`

'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`

of `t1`

as the `output_index`

and `variable`

of the output term without checking that they are equal to those of `t2`

.

`MathOptInterface.Utilities.isapprox_zero`

— Function`isapprox_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`

— Function`modify_function(f::AbstractFunction, change::AbstractFunctionModification)`

Return a new function `f`

modified according to `change`

.

`MathOptInterface.Utilities.zero_with_output_dimension`

— Function`zero_with_output_dimension(::Type{T}, output_dimension::Integer) where {T}`

Create an instance of type `T`

with the output dimension `output_dimension`

.

This is mostly useful in Bridges, when code needs to be agnostic to the type of vector-valued function that is passed in.

The following functions can be used to canonicalize a function:

`MathOptInterface.Utilities.is_canonical`

— Function`is_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`

— Function```
canonical(
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!`

— Function`canonicalize!(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`

— Function`scalar_type(F::Type{<:MOI.AbstractVectorFunction})`

Type of functions obtained by indexing objects obtained by calling `eachscalar`

on functions of type `F`

.

`MathOptInterface.Utilities.scalarize`

— Function`scalarize(func::MOI.VectorOfVariables, ignore_constants::Bool = false)`

Returns a vector of scalar functions making up the vector function in the form of a `Vector{MOI.SingleVariable}`

.

See also `eachscalar`

.

`scalarize(func::MOI.VectorAffineFunction{T}, ignore_constants::Bool = false)`

Returns a vector of scalar functions making up the vector function in the form of a `Vector{MOI.ScalarAffineFunction{T}}`

.

See also `eachscalar`

.

`scalarize(func::MOI.VectorQuadraticFunction{T}, ignore_constants::Bool = false)`

Returns a vector of scalar functions making up the vector function in the form of a `Vector{MOI.ScalarQuadraticFunction{T}}`

.

See also `eachscalar`

.

`MathOptInterface.Utilities.eachscalar`

— Function`eachscalar(f::MOI.AbstractVectorFunction)`

Returns an iterator for the scalar components of the vector function.

See also `scalarize`

.

`eachscalar(f::MOI.AbstractVector)`

Returns an iterator for the scalar components of the vector.

`MathOptInterface.Utilities.promote_operation`

— Function```
promote_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`

— Function```
operate(
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!`

— Function```
operate!(
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!`

— Function```
operate_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`

— Function`vectorize(x::AbstractVector{MOI.VariableIndex})`

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`

— Function`shift_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`

.

Only define this function if it makes sense to!

Use `supports_shift_constant`

to check if the set supports shifting:

```
if supports_shift_constant(typeof(old_set))
new_set = shift_constant(old_set, offset)
f.constant = 0
add_constraint(model, f, new_set)
else
add_constraint(model, f, old_set)
end
```

See also `supports_shift_constant`

.

**Examples**

The call `shift_constant(MOI.Interval(-2, 3), 1)`

is equal to `MOI.Interval(-1, 4)`

.

`MathOptInterface.Utilities.supports_shift_constant`

— Function`supports_shift_constant(::Type{S}) where {S<:MOI.AbstractSet}`

Return `true`

if `shift_constant`

is defined for set `S`

.

See also `shift_constant`

.

`MathOptInterface.Utilities.normalize_and_add_constraint`

— Function```
normalize_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`

— Function```
normalize_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`

— Function`get_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`

— Function`is_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`

— Function`side_dimension_for_vectorized_dimension(n::Integer)`

Return the dimension `d`

such that `MOI.dimension(MOI.PositiveSemidefiniteConeTriangle(d))`

is `n`

.

## DoubleDicts

`MathOptInterface.Utilities.DoubleDicts.DoubleDict`

— Type`DoubleDict{V}`

An optimized dictionary to map `MOI.ConstraintIndex`

to values of type `V`

.

Works as a `AbstractDict{MOI.ConstraintIndex,V}`

with minimal differences.

If `V`

is also a `MOI.ConstraintIndex`

, use `IndexDoubleDict`

.

Note that `MOI.ConstraintIndex`

is not a concrete type, opposed to `MOI.ConstraintIndex{MOI.VariableIndex, MOI.Integers}`

, which is a concrete type.

When looping through multiple keys of the same Function-in-Set type, use

`inner = dict[F, S]`

to return a type-stable `DoubleDictInner`

.

`MathOptInterface.Utilities.DoubleDicts.DoubleDictInner`

— Type`DoubleDictInner{F,S,V}`

A type stable inner dictionary of `DoubleDict`

.

`MathOptInterface.Utilities.DoubleDicts.IndexDoubleDict`

— Type`IndexDoubleDict`

A specialized version of [`DoubleDict`

] in which the values are of type `MOI.ConstraintIndex`

When looping through multiple keys of the same Function-in-Set type, use

`inner = dict[F, S]`

to return a type-stable `IndexDoubleDictInner`

.

`MathOptInterface.Utilities.DoubleDicts.IndexDoubleDictInner`

— Type`IndexDoubleDictInner{F,S}`

A type stable inner dictionary of `IndexDoubleDict`

.