Annotating arguments with their type in Julia is optional:
using JuMP
function reformulate_mod_vec(model, x, v)
n = length(x)
mult = @variable(model, [1:n], integer = true)
rem = @variable(
model,
[1:n],
integer = true,
lower_bound = 0,
upper_bound = v - 1,
)
@constraint(model, x .== v .* mult + rem)
return rem
end
m, n = 2, 2
A = [1 1 1 1; 1 1 1 1; 1 1 1 1]
v = 3
model = Model()
@variable(model, x[1:n])
@variable(model, y[1:m])
rem = reformulate_mod_vec(model, A * [x; y], v)
Annotations have no impact on performance, but they two main benefits:
- It can help document the function
- It can be used for multiple dispatch.
As an example, you might have something like this:
function reformulate_mod_vec_2(model, x, v)
mult = @variable(model, integer = true)
rem = @variable(model, integer = true, lower_bound = 0, upper_bound = v - 1)
@constraint(model, x == v * mult + rem)
return rem
end
rem = reformulate_mod_vec_2.(model, A * [x; y], v)
Here the reformulate_mod_vec_2
needs a scalar valued x
, and we need to use broadcasting reformulate_mod_vec_2.(
for it to work on our vector. But it’s hard to tell that just from the signature.
You might do instead:
function reformulate_mod_vec_3(model, x::AbstractJuMPScalar, v)
mult = @variable(model, integer = true)
rem = @variable(model, integer = true, lower_bound = 0, upper_bound = v - 1)
@constraint(model, x == v * mult + rem)
return rem
end
so that not using broadcasting fails:
julia> rem = reformulate_mod_vec_3(model, A * [x; y], v)
ERROR: MethodError: no method matching reformulate_mod_vec_3(::Model, ::Vector{AffExpr}, ::Int64)
Closest candidates are:
reformulate_mod_vec_3(::Any, ::AbstractJuMPScalar, ::Any) at REPL[12]:1
Stacktrace:
[1] top-level scope
@ REPL[14]:1
julia> rem = reformulate_mod_vec_3.(model, A * [x; y], v)
3-element Vector{VariableRef}:
_[18]
_[20]
_[22]