First we create a composite type AffineExpression using struct
struct AffineExpression
variables::Vector{Variable}
coeffs::Vector{Float64}
constant::Float64
end
Then we define the expression “+” as AffineExpression
import Base: +
+(x::Real,y::Union{Real,Variable}) = AffineExpression([y],[x],0.0)
So “x+2” can be taken as an affine expression
But how to define “+” then if one input has several types in the form of union?
+(x::Variable,y::Union{Real,Variable,AffineExpression}) =
I think I can make it separately without union, repeat each case of y as Real, Variable, AffineExpression
However, I guess using union will provide a more elegant approach.
Any hint will be much appreciated!!!
Overriding a method defined outside your module for types not defined in your module is generally a bad idea.
That +(::Real, ::Real)
returns a real number, not AffineExpression
, is probably relied upon in more than one place inside Base
, so that I very much suspect the effect of such override would be disastrous.
Now, on the question (because it still makes sense when not coupled with a careless override). One way is repeat each case, another one is to define promotions from all those types to AffineExpression
and then basically only define +(::AffineExpression, ::AffineExpression)
(cf. https://github.com/jmxpearson/julia-for-pythonistas/blob/master/dual.jl)
1 Like
Thank you Vasily! Yes you are right that I am actually working within a new module. As you mentioned, [quote=“Vasily_Pisarev, post:2, topic:30375”]
define promotions from all those types to AffineExpression
and then basically only define +(::AffineExpression, ::AffineExpression)
[/quote]
I define a convert function to get
::Real
and ::Variable
to AffineExpression and it works as expected, promote seems error though.
You need both promotion and conversion rules.
promote
is to define what common type two arguments of a built-in mathematical function must be converted to, convert
is to define how exactly to do that.
1 Like