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