Closed dlfivefifty closed 5 years ago
Yes, HyperSphere
seems more correct terminology, good point.
There could be a Sphere
with radius and centre at some point. For the time being, many domains simply have a "basic" type that contains no data, like UnitSphere
and ChebyshevInterval
. They come with zero memory overhead and a simple, clean and efficient implementation that does not implicitly favour one affine map over another one. But I agree one would also expect a more fully featured sphere in a package like this.
I digress, but that is something I had in mind with the DerivedDomain
type, which I think is currently never used and isn't even fully implemented (it should perhaps be removed). The idea is that a domain that derives from DerivedDomain
has its own type, yet it simply contains some other domain. A sphere could be a DerivedDomain
, that contains a mapped domain consisting of a UnitSphere
and an affine map. That's perhaps more complicated than it should be for this use case, but it is a generic way of making domains with more functionality and a richer interface (using dispatch on the new type), while reusing existing (efficient) implementation.
Note that affine translations and domains with parameters are slightly different in IEEE, take the ball defined by: x^2 + y^2 ≤ r^2
vs the affine version (x/r)^2 + (y/r)^2 ≤ 1
:
julia> x,y
(2.1213203608786055, 2.1213203262406797)
julia> x^2 + y^2 ≤ 9
true
julia> (x/3)^2 + (y/3)^2 ≤ 1
false
So I think both versions should exist without viewing it as too redundant.
Are we going to distinguish between an n-ball and an (n-1)-sphere?
Also, is the current "3-sphere" is embedded in R3 or R4? I don't know the design well enough to distinguish whether or not the super type is supposed to be the ambient domain or something that the instance looks like locally. This is rather picky, but there may be ways around this like overriding supertype
julia> struct MyType{N, T}
center::T
radius::T
end
julia> abstract type MyAbstractType{N, T} end
julia> Base.supertype(::MyType{N, T}) where {N, T} = MyAbstractType{N + 1, T}
julia> sph = MyType{2, Float64}(0.0, 1.0)
MyType{2,Float64}(0.0, 1.0)
julia> supertype(sph)
MyAbstractType{3,Float64}
The N
refers to the ambient space:
const UnitCircle{T} = UnitSphere{2,T} # <: Domain{SVector{2,T}}
const UnitSphere{T} = UnitHyperSphere{3,T} # <: Domain{SVector{3,T}}
A domain is defined by its implementation of in
, so the T
in Domain{T}
above refers to the fact that
SVector(1,0,0) in UnitSphere() # returns true
This definition extends to promotion: so even though eltype(UnitSphere{Int}()) ==Int
we have
x = prevfloat(sqrt(2)/2)
y = sqrt(2)/2
SVector(x,y,0) in UnitSphere() # since x^2 + y^2 === 1.0
We have yet to settle on "fuzzyness" of a domain: here x = y = sqrt(2)/2
as calculated by IEEE is approximately in the unit sphere. I've come around to the idea of using interval arithmetic (as in https://github.com/JuliaIntervals/IntervalArithmetic.jl) to do this properly: that is, we can use
Sphere(0.0, interval(prevfloat(1.0),nextfloat(1.0)) # <: Domain{SVector{3,Interval{Float64}}
and then we get everything "for free", without having to worry about things like housedorf metrics.
For spherical coordinates there could be a special number type that stores r
, centre
, θ
and φ
.
What about spheres and balls with different, possibly user-defined, norms? I think generic balls are then closed convex domains, so not sure how much would be gained from this.
It's not clear why
UnitSphere
refers to an N-sphere whileSphere
is a 3-sphere. I'd expect aSphere
to also have a radius and centre (down the line). So maybeUnitSphere
->UnitHyperSphere
whileSphere
->UnitSphere
.