I have a struct that contains a real number describing some probability. The algorithm that uses this struct performs fairly simple arithmetic that I would like to be able to track both numerically (Floats) and symbolically (e.g. by using AbstractAlgebra.jl).
Initially I started with
struct MyPhysicsModel
prob::Float64
end
which was then updated to
struct MyPhysicsModel{T<:Real}
prob::T
end
At this point I am able to use Float64, BigFloat, etc. However what about having a probability which is a symbolic expression. I want to be able to do
R, (e,) = PolynomialRing(RealField, ["e"])
model = MyPhysicsModel(e)
However, this does not work because typeof(e)
is AbstractAlgebra.Generic.MPoly{BigFloat}
which is not a subtype of Real
.
Any idea how to proceed such that MyModel
can support both numeric reals and symbolic polynomials?
oh… That sounds kinda obvious now that you said it. Would I suffer any performance or compilation penalties?
My understanding is that any methods that use MyPhysicsModel
will be compiled for precisely the concrete types that you actually use. So if, for example you have a MyPhysicsModel{Float64}
, the compiler has access to any benefit of realness whether or not you’ve annotated with <:Real
. The polynomial version will be slower than the float version, but still as individually fast as possible, and could still end up faster than something like Rational{BigInt}
which is a subtype of Real
.
The gotcha’s won’t start popping up until you start making things like mixed containers, say an Array
or Dict
that holds some Float
and some Polynomial
objects, but again, this happens whether or not you’ve forced yourself to subtype Real
.
You’d also open the possibility of someone making a MyPhysicsModel{IO}
or of some other completely ludicrous type, but it seems unlikely that said person would be surprised by the resulting errors.
3 Likes