@rfateman: I agree that there are some tricky questions, but the first thing to do is to make it easy to implement and experiment with.
Here is a first example of using a polar type with intervals. I believe this is an illustrative example of Julia’s flexibility.
First we define a generic, parametrised Polar
type, and conversions to and from Julia’s standard Complex
type:
struct Polar{T}
r::T
θ::T
end
Base.Complex(p::Polar) = p.r * cis(p.θ)
function Polar(z::Complex)
x, y = reim(z)
r = sqrt(x^2 + y^2)
θ = atan(y, x)
return Polar(r, θ)
end
We define +
by converting to rectangular form, then converting back:
function Base.:+(p1::Polar, p2::Polar)
z1 = Complex(p1)
z2 = Complex(p2)
return Polar(z1 + z2)
end
The above definitions and functions are generic – they will work with any type. (We may want to restrict them to e.g. accept only subtypes of Real
, but for clarity I have not done so.)
Now we load the IntervalArithmetic.jl
package, which represents intervals using endpoints (rather than midpoint + radius, for which we could use Arb via the Arblib.jl
wrapper), and define some objects and add them
using IntervalArithmetic
p1 = Polar(1..2, 3..4)
p2 = Polar(3..4, 5..6)
p1 + p2
This produces an object of type Polar{Interval{Float64}}
;
Julia has automatically generated compiled, specialised code for the sum of two Polar
s containing Interval
s. (Currently two-argument atan
calls into MPFR for correct rounding, so it is rather slow.)
We can easily use intervals of BigFloat
s (i.e. MPFR floats with 256 bits of precision by default) instead:
p1 = Polar(big(1..2), big(3..4))
p2 = Polar(big(3..4), big(5..6))
p1 + p2
which produces an object of type Polar{Interval{BigFloat}}
instead (and all necessary methods have again been specialised for the new type).
If at some point we came up with a better algorithm for the sum of two Polar
s containing Interval
s, we could specialise just that method as
function Base.:+(p1::Polar{<:Interval}, p2::Polar{<:Interval})
...
end
In most of this code types are not mentioned, but nonetheless they just flow through the code, and the correct methods / versions of each function are called automatically. This is one of the places where Julia shines.