Abstract supertype of AbstractAlgebra.jl polynomials and Floats

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?

Just drop the <:Real

1 Like

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

No :slight_smile:

1 Like