I have a vector a
that can contain several different types of elements of the expressions QuadExpr, NonlinearExpression, AffExpr, VariableRef
. However, I want that if one of the elements (expressions) in a
is a NonlinearExpression
or a QuadExpression
this function should be used:
function add_pen!(pen, model::JuMP.Model, a::Union{Vector{QuadExpr}, Vector{NonlinearExpression}}, b, i,len)
pen[i] = @NLexpression(model, sum(a[j] * b[j] for j in 1:len));
end
If a
contains neither NonlinearExpression
nor QuadExpression
this function should be used:
function add_pen!(pen, model::JuMP.Model, a, b, i,len)
pen[i] = @expression(model, sum(a[j] * b[j] for j in 1:len));
end
I know this will not work as a::Union{Vector{QuadExpr}, Vector{NonlinearExpression}}
means that a
is either a Vector of only QuadExpression
or NonlinearExpressions
. Is it possible to use multiple-dispatch functions in this case or do I need to use the if and else statements instead? Like,
if any(x -> typeof(x) == NonlinearExpression, a)
pen[i] = @NLexpression ...
end
You could dispatch on types of varargs
.
I will make the example code without JuMP
so it is easier to replicate (you can of course change to your JuMP types).
Consider the following two types:
TypesA = Union{Int,Float64,Rational{Int}}
TypesB = Union{TypesA,String,Char}
You can define the following functions:
g(a::TypesA...) = println("running A")
g(a::TypesB...) = println("running B")
Now let us test it:
julia> g([1,2,3//4]...)
running A
julia> g([1,2,3//4,"hello"]...)
running B
You can see that varags
makes it possible to dispatch on the various combination of Vector
elements.
Note that this works correctly regardless the fact the the type of elements of Vector
above is Any
:
julia> eltype([1,2,3//4,"hello"])
Any
In your add_pen!
you will need to move a
to the end to be the last parameter.