# Extensions

More information can be found in the Extensions section of the manual.

## Define a new set

`JuMP.AbstractVectorSet`

— Type`AbstractVectorSet`

An abstract type for defining new sets in JuMP.

Implement `moi_set(::AbstractVectorSet, dim::Int)`

to convert the type into an MOI set.

See also: `moi_set`

.

## Extend `@variable`

`JuMP.ScalarVariable`

— Type`ScalarVariable{S,T,U,V} <: AbstractVariable`

A struct used when adding variables.

See also: `add_variable`

.

`JuMP.VariableInfo`

— Type`VariableInfo{S,T,U,V}`

A struct by JuMP internally when creating variables. This may also be used by JuMP extensions to create new types of variables.

See also: `ScalarVariable`

.

`JuMP.add_variable`

— Function`add_variable(m::Model, v::AbstractVariable, name::String="")`

Add a variable `v`

to `Model m`

and sets its name.

`JuMP.build_variable`

— Function`build_variable(_error::Function, variables, ::SymMatrixSpace)`

Return a `VariablesConstrainedOnCreation`

of shape `SymmetricMatrixShape`

creating variables in `MOI.Reals`

, i.e. "free" variables unless they are constrained after their creation.

This function is used by the `@variable`

macro as follows:

`@variable(model, Q[1:2, 1:2], Symmetric)`

`build_variable(_error::Function, variables, ::SkewSymmetricMatrixSpace)`

Return a `VariablesConstrainedOnCreation`

of shape `SkewSymmetricMatrixShape`

creating variables in `MOI.Reals`

, i.e. "free" variables unless they are constrained after their creation.

This function is used by the `@variable`

macro as follows:

`@variable(model, Q[1:2, 1:2] in SkewSymmetricMatrixSpace())`

`build_variable(_error::Function, variables, ::PSDCone)`

Return a `VariablesConstrainedOnCreation`

of shape `SymmetricMatrixShape`

constraining the variables to be positive semidefinite.

This function is used by the `@variable`

macro as follows:

`@variable(model, Q[1:2, 1:2], PSD)`

`build_variable(_error::Function, info::VariableInfo; extra_kw_args...)`

Returns a new variable.

Extensions should define a method with additional positional arguments to dispatch the call to a different method. The return type should only depend on the positional arguments for `variable_type`

to make sense.

As an example, `@variable(model, x, foo)`

foo will call `build_variable(_error, info, foo)`

See the `@variable`

macro doc for more details.

## Extend `@constraint`

`JuMP.build_constraint`

— Function```
build_constraint(_error::Function, Q::Symmetric{V, M},
::PSDCone) where {V <: AbstractJuMPScalar,
M <: AbstractMatrix{V}}
```

Return a `VectorConstraint`

of shape `SymmetricMatrixShape`

constraining the matrix `Q`

to be positive semidefinite.

This function is used by the `@constraint`

macros as follows:

`@constraint(model, Symmetric(Q) in PSDCone())`

The form above is usually used when the entries of `Q`

are affine or quadratic expressions, but it can also be used when the entries are variables to get the reference of the semidefinite constraint, e.g.,

```
@variable model Q[1:2,1:2] Symmetric
# The type of `Q` is `Symmetric{VariableRef, Matrix{VariableRef}}`
var_psd = @constraint model Q in PSDCone()
# The `var_psd` variable contains a reference to the constraint
```

```
build_constraint(_error::Function,
Q::AbstractMatrix{<:AbstractJuMPScalar},
::PSDCone)
```

Return a `VectorConstraint`

of shape `SquareMatrixShape`

constraining the matrix `Q`

to be symmetric and positive semidefinite.

This function is used by the `@constraint`

and `@SDconstraint`

macros as follows:

```
@constraint(model, Q in PSDCone())
@SDconstraint(model, P ⪰ Q)
```

The `@constraint`

call above is usually used when the entries of `Q`

are affine or quadratic expressions, but it can also be used when the entries are variables to get the reference of the semidefinite constraint, e.g.,

```
@variable model Q[1:2,1:2]
# The type of `Q` is `Matrix{VariableRef}`
var_psd = @constraint model Q in PSDCone()
# The `var_psd` variable contains a reference to the constraint
```

`JuMP.add_constraint`

— Function`add_constraint(model::Model, con::AbstractConstraint, name::String="")`

Add a constraint `con`

to `Model model`

and sets its name.

`JuMP.sense_to_set`

— Function`sense_to_set(_error::Function, ::Val{sense_symbol})`

Converts a sense symbol to a set `set`

such that `@constraint(model, func sense_symbol 0)`

is equivalent to `@constraint(model, func in set)`

for any `func::AbstractJuMPScalar`

.

**Example**

Once a custom set is defined you can directly create a JuMP constraint with it:

```
julia> struct CustomSet{T} <: MOI.AbstractScalarSet
value::T
end
julia> Base.copy(x::CustomSet) = CustomSet(x.value)
julia> model = Model();
julia> @variable(model, x)
x
julia> cref = @constraint(model, x in CustomSet(1.0))
x ∈ CustomSet{Float64}(1.0)
```

However, there might be an appropriate sign that could be used in order to provide a more convenient syntax:

```
julia> JuMP.sense_to_set(::Function, ::Val{:⊰}) = CustomSet(0.0)
julia> MOIU.shift_constant(set::CustomSet, value) = CustomSet(set.value + value)
julia> cref = @constraint(model, x ⊰ 1)
x ∈ CustomSet{Float64}(1.0)
```

Note that the whole function is first moved to the right-hand side, then the sign is transformed into a set with zero constant and finally the constant is moved to the set with `MOIU.shift_constant`

.

`JuMP.AbstractShape`

— Type`AbstractShape`

Abstract vectorizable shape. Given a flat vector form of an object of shape `shape`

, the original object can be obtained by `reshape_vector`

.

`JuMP.shape`

— Function`shape(c::AbstractConstraint)::AbstractShape`

Return the shape of the constraint `c`

.

`JuMP.reshape_vector`

— Function`reshape_vector(vectorized_form::Vector, shape::AbstractShape)`

Return an object in its original shape `shape`

given its vectorized form `vectorized_form`

.

**Examples**

Given a `SymmetricMatrixShape`

of vectorized form `[1, 2, 3]`

, the following code returns the matrix `Symmetric(Matrix[1 2; 2 3])`

:

```
julia> reshape_vector([1, 2, 3], SymmetricMatrixShape(2))
2×2 LinearAlgebra.Symmetric{Int64,Array{Int64,2}}:
1 2
2 3
```

`JuMP.reshape_set`

— Function`reshape_set(vectorized_set::MOI.AbstractSet, shape::AbstractShape)`

Return a set in its original shape `shape`

given its vectorized form `vectorized_form`

.

**Examples**

Given a `SymmetricMatrixShape`

of vectorized form `[1, 2, 3] in MOI.PositiveSemidefinieConeTriangle(2)`

, the following code returns the set of the original constraint `Symmetric(Matrix[1 2; 2 3]) in PSDCone()`

:

```
julia> reshape_set(MOI.PositiveSemidefiniteConeTriangle(2), SymmetricMatrixShape(2))
PSDCone()
```

`JuMP.dual_shape`

— Function`dual_shape(shape::AbstractShape)::AbstractShape`

Returns the shape of the dual space of the space of objects of shape `shape`

. By default, the `dual_shape`

of a shape is itself. See the examples section below for an example for which this is not the case.

**Examples**

Consider polynomial constraints for which the dual is moment constraints and moment constraints for which the dual is polynomial constraints. Shapes for polynomials can be defined as follows:

```
struct Polynomial
coefficients::Vector{Float64}
monomials::Vector{Monomial}
end
struct PolynomialShape <: AbstractShape
monomials::Vector{Monomial}
end
JuMP.reshape_vector(x::Vector, shape::PolynomialShape) = Polynomial(x, shape.monomials)
```

and a shape for moments can be defined as follows:

```
struct Moments
coefficients::Vector{Float64}
monomials::Vector{Monomial}
end
struct MomentsShape <: AbstractShape
monomials::Vector{Monomial}
end
JuMP.reshape_vector(x::Vector, shape::MomentsShape) = Moments(x, shape.monomials)
```

Then `dual_shape`

allows the definition of the shape of the dual of polynomial and moment constraints:

```
dual_shape(shape::PolynomialShape) = MomentsShape(shape.monomials)
dual_shape(shape::MomentsShape) = PolynomialShape(shape.monomials)
```

`JuMP.ScalarShape`

— Type`ScalarShape`

Shape of scalar constraints.

`JuMP.VectorShape`

— Type`VectorShape`

Vector for which the vectorized form corresponds exactly to the vector given.

`JuMP.SquareMatrixShape`

— Type`SquareMatrixShape`

Shape object for a square matrix of `side_dimension`

rows and columns. The vectorized form contains the entries of the the matrix given column by column (or equivalently, the entries of the lower-left triangular part given row by row).

`JuMP.SymmetricMatrixShape`

— Type`SymmetricMatrixShape`

Shape object for a symmetric square matrix of `side_dimension`

rows and columns. The vectorized form contains the entries of the upper-right triangular part of the matrix given column by column (or equivalently, the entries of the lower-left triangular part given row by row).