# Optimization

A technical manual for optimizing (solving) `InfiniteOpt`

models. See the respective guide for more information.

## Optimize

`JuMP.optimize!`

— Method`JuMP.optimize!(model::InfiniteModel; [kwargs...])`

Extend `JuMP.optimize!`

to optimize infinite models using the internal optimizer model. Will call `build_optimizer_model!`

if the optimizer model isn't up to date. The `kwargs`

correspond to keyword arguments passed to `build_optimizer_model!`

if any are defined.

**Example**

```
julia> optimize!(model)
julia> has_values(model)
true
```

## Optimizer Settings

`JuMP.set_optimizer`

— Method```
JuMP.set_optimizer(model::InfiniteModel,
[optimizer_constructor;
add_bridges::Bool = true])
```

Extend `JuMP.set_optimizer`

to set optimizer of infinite models. Specifically, the optimizer of the optimizer model is modified.

**Example**

```
julia> set_optimizer(model, Clp.Optimizer)
julia> optimizer_model(model)
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: EMPTY_OPTIMIZER
Solver name: SolverName() attribute not implemented by the optimizer.
```

`JuMP.set_silent`

— Method`JuMP.set_silent(model::InfiniteModel)`

Extend `JuMP.set_silent`

for infinite models to take precedence over any other attribute controlling verbosity and requires the solver to produce no output.

**Example**

```
julia> set_silent(model)
true
```

`JuMP.unset_silent`

— Method`JuMP.unset_silent(model::InfiniteModel)`

Extend `JuMP.unset_silent`

for infinite models to neutralize the effect of the `set_silent`

function and let the solver attributes control the verbosity.

**Example**

```
julia> unset_silent(model)
false
```

`JuMP.set_time_limit_sec`

— Method`JuMP.set_time_limit_sec(model::InfiniteModel, limit)`

Extend `set_time_limit_sec`

to set the time limit (in seconds) of the solver. Can be unset using `unset_time_limit_sec`

or with `limit`

set to `nothing`

.

**Example**

```
julia> set_time_limit_sec(model, 100)
100
```

`JuMP.unset_time_limit_sec`

— Method`JuMP.unset_time_limit_sec(model::InfiniteModel)`

Extend `unset_time_limit_sec`

to unset the time limit of the solver. Can be set using `set_time_limit_sec`

.

**Example**

`julia> unset_time_limit_sec(model)`

`JuMP.time_limit_sec`

— Method`JuMP.time_limit_sec(model::InfiniteModel)`

Extend `time_limit_sec`

to get the time limit (in seconds) of the solve used by the optimizer model (`nothing`

if unset). Can be set using `set_time_limit_sec`

.

**Example**

```
julia> time_limit_sec(model)
100
```

`JuMP.set_optimizer_attribute`

— Method`JuMP.set_optimizer_attribute(model::InfiniteModel, name::String, value)`

Extend `set_optimizer_attribute`

to specify a solver-specific attribute identified by `name`

to `value`

.

**Example**

```
julia> set_optimizer_attribute(model, "SolverSpecificAttributeName", true)
true
```

`JuMP.set_optimizer_attribute`

— Method```
JuMP.set_optimizer_attribute(model::InfiniteModel,
attr::MOI.AbstractOptimizerAttribute,
value)
```

Extend `set_optimizer_attribute`

to set the solver-specific attribute `attr`

in `model`

to `value`

.

**Example**

```
julia> set_optimizer_attribute(model, MOI.Silent(), true)
true
```

`JuMP.set_optimizer_attributes`

— Method`JuMP.set_optimizer_attributes(model::InfiniteModel, pairs::Pair...)`

Extend `set_optimizer_attributes`

to set multiple solver attributes given a list of `attribute => value`

pairs. Calls `set_optimizer_attribute(model, attribute, value)`

for each pair.

**Example**

```
julia> model = Model(Ipopt.Optimizer);
julia> set_optimizer_attributes(model, "tol" => 1e-4, "max_iter" => 100)
```

is equivalent to:

```
julia> set_optimizer_attribute(model, "tol", 1e-4);
julia> set_optimizer_attribute(model, "max_iter", 100);
```

`JuMP.get_optimizer_attribute`

— Method`JuMP.get_optimizer_attribute(model::InfiniteModel, name::String)`

Extend `get_optimizer_attribute`

to return the value associated with the solver-specific attribute named `name`

.

**Example** `julia-repl julia> get_optimizer_attribute(model, "tol") 0.0001`

`

`JuMP.get_optimizer_attribute`

— Method```
JuMP.get_optimizer_attribute(model::InfiniteModel,
attr::MOI.AbstractOptimizerAttribute)
```

Extend `get_optimizer_attribute`

to return the value of the solver-specific attribute `attr`

in `model`

.

**Example** `julia-repl julia> get_optimizer_attribute(model, MOI.Silent()) true`

`

`JuMP.add_bridge`

— Method```
JuMP.add_bridge(model::InfiniteModel,
BridgeType::Type{<:MOI.Bridges.AbstractBridge})
```

Extend `JuMP.add_bridge`

to add `BridgeType`

to the list of bridges that can be used by the optimizer model to transform unsupported constraints into an equivalent formulation using only constraints supported by the optimizer.

## Optimizer Queries

`JuMP.solver_name`

— Method`JuMP.solver_name(model::InfiniteModel)`

Extend `solver_name`

to return the name of the solver being used if there is an optimizer selected and it has a name attribute. Otherwise, an error is thrown.

**Example**

```
julia> solver_name(model)
"Gurobi"
```

`JuMP.backend`

— Method`JuMP.backend(model::InfiniteModel)`

Extend `backend`

to return the `MathOptInterface`

backend associated with the optimizer model. Note this will be empty if the optimizer model has not been build yet.

**Example**

`julia> moi_model = backend(model);`

`JuMP.mode`

— Method`JuMP.mode(model::InfiniteModel)`

Extend `mode`

to return the `MathOptInterface`

mode the optimizer model is in.

**Example**

```
julia> mode(model)
AUTOMATIC::ModelMode = 0
```

`JuMP.bridge_constraints`

— Method`JuMP.bridge_constraints(model::InfiniteModel)::Bool`

Extend `JuMP.bridge_constraints`

to return if an infinite model `model`

has an optimizer model where the optimizer is set and unsupported constraints are automatically bridged to equivalent supported constraints when an appropriate transformation is available.

**Example**

```
julia> bridge_constraints(model)
false
```

## Optimizer Model API

`InfiniteOpt.optimizer_model`

— Function`optimizer_model(model::InfiniteModel)::JuMP.Model`

Return the JuMP model stored in `model`

that is used to solve it.

**Example**

```
julia> opt_model = optimizer_model(model)
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: NO_OPTIMIZER
Solver name: No optimizer attached.
```

`InfiniteOpt.set_optimizer_model`

— Function```
set_optimizer_model(inf_model::InfiniteModel, opt_model::JuMP.Model;
inherit_optimizer::Bool = true)
```

Specify the JuMP model that is used to solve `inf_model`

. This is intended for internal use and extensions. Note that `opt_model`

should contain extension data to allow it to map to `inf_model`

in a manner similar to `TranscriptionModel`

. `inherit_optimizer`

indicates whether `add_infinite_model_optimizer`

should be invoked on the new optimizer mode to inherit the optimizer constuctor and attributes currently stored in `inf_model`

.

**Example**

```
julia> set_optimizer_model(model, TranscriptionModel())
julia> optimizer_model(model)
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: NO_OPTIMIZER
Solver name: No optimizer attached.
```

`InfiniteOpt.optimizer_model_key`

— Method`optimizer_model_key(model::InfiniteModel)::Any`

Return the extension key used in the optimizer model of `model`

. Errors if `optimizer_model.ext`

contains more than one key. This is intended for internal use and extensions. For extensions this is used to dispatch to the appropriate optmizer model functions such as extensions to `build_optimizer_model!`

.

**Example**

```
julia> optimizer_model_key(model)
:TransData
```

`InfiniteOpt.optimizer_model_key`

— Method`optimizer_model_key(model::JuMP.Model)::Any`

Return the extension key used in the optimizer model `model`

. Errors if `model.ext`

contains more than one key. This is intended for internal use and extensions. For extensions this is used to dispatch to the appropriate optmizer model functions such as extensions to `build_optimizer_model!`

. This is intended as an internal method. See `optimizer_model_key`

for the public method

`InfiniteOpt.build_optimizer_model!`

— Method`build_optimizer_model!(model::InfiniteModel; [kwargs...])`

Build the optimizer model stored in `model`

such that it can be treated as a normal JuMP model. Specifically, translate the variables and constraints stored in `model`

into ones that are stored in the optimizer model and can be solved. This is provided generally to accomodate extensions that use custom optimizer model types in accordance with `optimizer_model_key`

. However, it may be useful in certain applications when the user desires to force a build without calling `optimize!`

. Extensions will need to implement their own version of the function `build_optimizer_model!(model::InfiniteModel, key::Val{ext_key_name}; kwargs...)`

.

**Example**

```
julia> build_optimizer_model!(model)
julia> optimizer_model_ready(model)
true
```

`InfiniteOpt.build_optimizer_model!`

— Function```
build_optimizer_model!(model::InfiniteModel, key::Val{ext_key_name};
[kwargs...])
```

Build the optimizer model stored in `model`

such that it can be treated as a normal JuMP model, where the `Model.ext`

field contains a key that points to a datastructure that appropriately maps the data between the two models. The key argument should be be typed to `Val{ext_key_name}`

. This should also use `clear_optimizer_model_build!`

to empty the out the current optimizer model. Ultimately, `set_optimizer_model`

should be called to insert the build optimizer model into `model`

and `set_optimizer_model_ready`

should be used to update the optimizer model's status.

`InfiniteOpt.clear_optimizer_model_build!`

— Method`clear_optimizer_model_build!(model::InfiniteModel)::JuMP.Model`

Empty the optimizer model using appropriate calls of `Base.empty!`

. This effectively resets `model.optimizer_model`

except the optimizer, its attributes, and an an emptied optimizer model data struct are maintained. This is intended as an internal method for use by `build_optimizer_model!`

.

`InfiniteOpt.clear_optimizer_model_build!`

— Method`clear_optimizer_model_build!(model::JuMP.Model)::JuMP.Model`

Empty the optimizer model using appropriate calls of `Base.empty!`

. This effectively resets `model`

except the optimizer, its attributes, and an an emptied optimizer model data struct are maintained. This is intended as an internal method for use by `build_optimizer_model!`

.

`InfiniteOpt.add_infinite_model_optimizer`

— Function`add_infinite_model_optimizer(opt_model::JuMP.Model, inf_model::InfiniteModel)`

Parse the current optimizer and its attributes associated with `inf_model`

and load them into `opt_model`

. This is intended to be used as an internal method for `set_optimizer_model`

.

`InfiniteOpt.optimizer_model_variable`

— Method```
optimizer_model_variable(vref::GeneralVariableRef;
[label::Type{<:AbstractSupportLabel} = PublicLabel,
ndarray::Bool = false,
kwargs...])
```

Return the reformulation variable(s) stored in the optimizer model that correspond to `vref`

. Also errors if no such variable can be found in the optimizer model.

The keyword arugments `label`

and `ndarray`

are what `TranscriptionOpt`

employ and `kwargs`

denote extra ones that user extensions may employ in accordance with their implementation of `optimizer_model_variable`

. Errors if such an extension has not been written.

By default only the variables associated with public supports are returned, the full set can be accessed via `label = All`

. Moreover, infinite variables are returned as a list corresponding to their supports. However, a n-dimensional array can be obtained via `ndarray = true`

which is handy when the variable has multiple infinite parameter dependencies. The corresponding supports are obtained via `supports`

using the same keyword arguments.

**Example**

```
julia> optimizer_model_variable(x) # infinite variable
2-element Array{VariableRef,1}:
x(support: 1)
x(support: 2)
julia> optimizer_model_variable(z) # finite variable
z
```

`InfiniteOpt.optimizer_model_variable`

— Function```
optimizer_model_variable(vref::GeneralVariableRef, key::Val{ext_key_name};
[kwargs...])
```

Return the reformulation variable(s) stored in the optimizer model that correspond to `vref`

. This needs to be defined for extensions that implement a custom optimizer model type. Principally, this is accomplished by typed the `key`

argument to `Val{ext_key_name}`

. Keyword arguments can be added as needed.

`InfiniteOpt.supports`

— Method```
supports(vref::DecisionVariableRef;
[label::Type{<:AbstractSupportLabel} = PublicLabel,
ndarray::Bool = false,
kwargs...])
```

Return the supports associated with `vref`

in the optimizer model. Errors if `InfiniteOpt.variable_supports`

has not been extended for the optimizer model type or if `vref`

is not be reformulated in the optimizer model.

The keyword arugments `label`

and `ndarray`

are what `TranscriptionOpt`

employ and `kwargs`

denote extra ones that user extensions may employ in accordance with their implementation of `variable_supports`

. Errors if such an extension has not been written.

By default only the public supports are returned, the full set can be accessed via `label = All`

. Moreover, the supports of infinite variables are returned as a list. However, a n-dimensional array can be obtained via `ndarray = true`

which is handy when the variable has multiple infinite parameter dependencies.

**Example**

```
julia> supports(vref)
2-element Array{Tuple{Float64},1}:
(0.0,)
(1.0,)
```

```
supports(expr::JuMP.AbstractJuMPScalar;
[label::Type{<:AbstractSupportLabel} = PublicLabel,
ndarray::Bool = false,
kwargs...])
```

Return the support associated with `expr`

. Errors if `expr`

is not associated with the constraint mappings stored in `optimizer_model`

.

The keyword arugments `label`

and `ndarray`

are what `TranscriptionOpt`

employ and `kwargs`

denote extra ones that user extensions may employ in accordance with their implementation of `expression_supports`

. Errors if such an extension has not been written.

By default only the public supports are returned, the full set can be accessed via `label = All`

. Moreover, the supports of infinite expressions are returned as a list. However, a n-dimensional array can be obtained via `ndarray = true`

which is handy when the expression has multiple infinite parameter dependencies.

**Example**

```
julia> supports(cref)
2-element Array{Tuple{Float64},1}:
(0.0,)
(1.0,)
```

`InfiniteOpt.variable_supports`

— Function```
variable_supports(optimizer_model::JuMP.Model, vref,
key::Val{ext_key_name};
[kwargs...])::Vector
```

Return the supports associated with the mappings of `vref`

in `optimizer_model`

. This dispatches off of `key`

which permits optimizer model extensions. This should throw an error if `vref`

is not associated with the variable mappings stored in `optimizer_model`

. Keyword arguments can be added as needed. Note that no extension is necessary for point or finite variables.

`InfiniteOpt.optimizer_model_expression`

— Method```
optimizer_model_expression(expr::JuMP.AbstractJuMPScalar;
[label::Type{<:AbstractSupportLabel} = PublicLabel,
ndarray::Bool = false,
kwargs...])
```

Return the reformulation expression(s) stored in the optimizer model that correspond to `expr`

. Also errors if no such expression can be found in the optimizer model (meaning one or more of the underlying variables have not been transcribed).

The keyword arugments `label`

and `ndarray`

are what `TranscriptionOpt`

employ and `kwargs`

denote extra ones that user extensions may employ in accordance with their implementation of `optimizer_model_expression`

. Errors if such an extension has not been written.

By default only the expressions associated with public supports are returned, the full set can be accessed via `label = All`

. Moreover, infinite expressions are returned as a list corresponding to their supports. However, a n-dimensional array can be obtained via `ndarray = true`

which is handy when the expression has multiple infinite parameter dependencies. The corresponding supports are obtained via `supports`

using the same keyword arguments.

**Example**

```
julia> optimizer_model_expression(my_expr) # finite expression
x(support: 1) - y
```

`InfiniteOpt.optimizer_model_expression`

— Function`optimizer_model_expression(expr, key::Val{ext_key_name}; [kwargs...])`

Return the reformulation expression(s) stored in the optimizer model that correspond to `expr`

. This needs to be defined for extensions that implement a custom optimizer model type. Principally, this is accomplished by typed the `key`

argument to `Val{ext_key_name}`

. Keyword arguments can be added as needed. Note that if `expr`

is a `GeneralVariableRef`

this just dispatches to `optimizer_model_variable`

.

`InfiniteOpt.supports`

— Method```
supports(expr::JuMP.AbstractJuMPScalar;
[label::Type{<:AbstractSupportLabel} = PublicLabel,
ndarray::Bool = false,
kwargs...])
```

Return the support associated with `expr`

. Errors if `expr`

is not associated with the constraint mappings stored in `optimizer_model`

.

The keyword arugments `label`

and `ndarray`

are what `TranscriptionOpt`

employ and `kwargs`

denote extra ones that user extensions may employ in accordance with their implementation of `expression_supports`

. Errors if such an extension has not been written.

By default only the public supports are returned, the full set can be accessed via `label = All`

. Moreover, the supports of infinite expressions are returned as a list. However, a n-dimensional array can be obtained via `ndarray = true`

which is handy when the expression has multiple infinite parameter dependencies.

**Example**

```
julia> supports(cref)
2-element Array{Tuple{Float64},1}:
(0.0,)
(1.0,)
```

`InfiniteOpt.expression_supports`

— Function```
expression_supports(optimizer_model::JuMP.Model, expr,
key::Val{ext_key_name}; [kwargs...])
```

Return the supports associated with the mappings of `expr`

in `optimizer_model`

. This dispatches off of `key`

which permits optimizer model extensions. This should throw an error if `expr`

is not associated with the variable mappings stored in `optimizer_model`

. Keyword arguments can be added as needed. Note that if `expr`

is a `GeneralVariableRef`

this just dispatches to `variable_supports`

.

`InfiniteOpt.optimizer_model_constraint`

— Method```
optimizer_model_constraint(cref::InfOptConstraintRef;
[label::Type{<:AbstractSupportLabel} = PublicLabel,
ndarray::Bool = false,
kwargs...])
```

Return the reformulation constraint(s) stored in the optimizer model that correspond to `cref`

. Errors if no such constraint can be found in the optimizer model.

The keyword arugments `label`

and `ndarray`

are what `TranscriptionOpt`

employ and `kwargs`

denote extra ones that user extensions may employ in accordance with their implementation of `optimizer_model_constraint`

. Errors if such an extension has not been written.

By default only the constraints associated with public supports are returned, the full set can be accessed via `label = All`

. Moreover, infinite constraints are returned as a list corresponding to their supports. However, a n-dimensional array can be obtained via `ndarray = true`

which is handy when the constraint has multiple infinite parameter dependencies. The corresponding supports are obtained via `supports`

using the same keyword arguments.

**Example**

```
julia> optimizer_model_constraint(c1) # finite constraint
c1 : x(support: 1) - y <= 3.0
```

`InfiniteOpt.optimizer_model_constraint`

— Function```
optimizer_model_constraint(cref::InfOptConstraintRef,
key::Val{ext_key_name}; [kwargs...])
```

Return the reformulation constraint(s) stored in the optimizer model that correspond to `cref`

. This needs to be defined for extensions that implement a custom optimizer model type. Principally, this is accomplished by typed the `key`

argument to `Val{ext_key_name}`

. Keyword arguments can be added as needed.

`InfiniteOpt.supports`

— Method```
supports(cref::InfOptConstraintRef;
[label::Type{<:AbstractSupportLabel} = PublicLabel,
ndarray::Bool = false,
kwargs...])
```

Return the support associated with `cref`

. Errors if `cref`

is not associated with the constraint mappings stored in `optimizer_model`

.

The keyword arugments `label`

and `ndarray`

are what `TranscriptionOpt`

employ and `kwargs`

denote extra ones that user extensions may employ in accordance with their implementation of `constraint_supports`

. Errors if such an extension has not been written.

By default only the public supports are returned, the full set can be accessed via `label = All`

. Moreover, the supports of infinite constraints are returned as a list. However, a n-dimensional array can be obtained via `ndarray = true`

which is handy when the constraint has multiple infinite parameter dependencies.

**Example**

```
julia> supports(cref)
2-element Array{Tuple{Float64},1}:
(0.0,)
(1.0,)
```

`InfiniteOpt.constraint_supports`

— Function```
constraint_supports(optimizer_model::JuMP.Model,
cref::InfOptConstraintRef,
key::Val{ext_key_name}; [kwargs...])
```

Return the supports associated with the mappings of `cref`

in `optimizer_model`

. This dispatches off of `key`

which permits optimizer model extensions. This should throw an error if `cref`

is not associated with the variable mappings stored in `optimizer_model`

. Keyword arguments can be added as needed.

`InfiniteOpt.optimizer_model_ready`

— Function`optimizer_model_ready(model::InfiniteModel)::Bool`

Return `Bool`

if the optimizer model is up to date with `model`

.

**Example**

```
julia> optimizer_model_ready(model)
false
```

`InfiniteOpt.set_optimizer_model_ready`

— Function`set_optimizer_model_ready(model::InfiniteModel, status::Bool)`

Set the status of the optimizer model to whether it is up to date or not. Note is more intended as an internal function, but is useful for extensions.

**Example**

```
julia> set_optimizer_model_ready(model, true)
julia> optimizer_model_ready(model)
true
```