Open dlfivefifty opened 4 years ago
Hi @dlfivefifty, thanks for your message. I've been mulling it over. Yes I'm favour of your proposal in general.
Currently this package has the following types:
Infinite <: Real
(signed infinity)InfExtendedReal{T<:Real} <: Real
(essentially Union{T,Infinite}
)InfExtendedTime{T<:TimeType} <: TimeType
(essentially Union{T,Infinite}
)The original motivation for the package was the InfExtendedReal
type, not Infinite
itself, hence why Infinite
is not as well thought through --- it basically only exists to be coerced to another type.
Over on #11 I was already considering making Infinity
non-real (so Infinite <: Any
) because the package now supports non-number kinds of infinity, like infinite time, and also adding more specialised types like InfiniteReal <: Real
, InfiniteTime <: TimeType
so that we can support sensible default promotions like promote_rule(InfiniteReal, T<:Real) = InfExtendedReal{T}
.
In response to your proposals:
Number
hierarchy already uses adjectives like Real
and Rational
, but then I suppose Float
is a verb and all of these terms are colloquially also used as nouns, so I'm happy to change Infinite
to Infinity
and Infinity
to Infinities
Infinity
type should have any supertypes, because there are different sorts of non-integer infinity (e.g. infinite time), but I'd be happy to have more specialised infinite types.So I think the types should look like this:
Infinity <: Any
, a singleton type with ∞ = Infinity()
.SignedInfinity <: Any
, a signed type with a signbit::Bool
field, and -∞ = SignedInfinity(true)
.URealInfinity <: Real
and RealInfinity <: Real
are the unsigned and signed real infinity types.UIntegerInfinity <: Unsigned
and IntegerInfinity <: Signed
for unsigned and signed integer infinities.)ComplexInfinity{T} <: Number
for complex infinities with a phase of type T
.InfExtended*
types we currently support.It sounds like a lot, but for most users it suffices to just use ∞
and coercion will deal with the rest.
Some things I'm not sure about:
IntegerInfinity
is useful in addition to RealInfinity
. You might suggest having RealInfinity <: Signed
but infinity isn't really a (mathematical) integer, and in the absence of an official interface for Integer
I don't think we should add a non-integer type to it. I don't think it could satisfy any reasonable interface anyway --- e.g. there is no choice of mod(∞,10)
so that the identity mod(∞+1,10) == mod(mod(∞,10)+1,10)
holds. On the other hand, the Real
interface already contains infinities (Inf
and 1//0
).IntegerOrInfinity = Union{Integer, RealInfinity, URealInfinity, InfExtended{<:Integer}}
.ComplexInfinity{T}
should not store the phase as a T
but the sign as a Complex{T}
? Then we could have z*∞ = Complex(sign(z))
where z::Complex
, analagously to -∞ = SignedInfinity(true)
.SignedInfinity
should be represented not by its signbit::Bool
but by its sign::Int8 ∈ {-1,1}
.Integer
to interface with the array interface successfully. Note I also use aleph infinities in ContinuumArrays.jl for higher order cardinalities.So perhaps we do this:
const InfiniteCardinality{K} <: Integer end
const ℵ₀ = InfiniteCardinality{0}()
Do you just need infinite cardinalities, or do you also need the IntegerInfinity
type I suggested above, because they are different things? Some use cases might be helpful for me to understand.
For the most part, just infinite cardinalities. Though there was a need to negate them ( probably somewhere in the array code it called -length(a)
) so I also have SignedInfinity <: Integer
. I could probably live without this being an Integer
though we'd have to experiment with the code to see if that breaks anything.
We should think if there's a cleaner way to extend number systems. For reals and integers there's always a choice between adding two or one infinity. For complex's there's a choice between one infinity and an infinity from each direction.
The main goal of this package is to provide a useful notion of infinity that sits within the existing base Julia types. The existing infinities Inf
and 1//0
are signed and represent the directional notion of infinity, so this is what Infinity
does too. I think its most natural/useful for users of this package, and extends naturally to types which are ordered but have no ring structure, such as Date
(and it preserves the ordering).
If you want the unique projective infinity, then I suppose we could have a singleton type ProjectiveInfinity <: ProjectiveNumber <: Number
and also extension types ProjectiveInteger, ProjectiveReal, ProjectiveComplex <: ProjectiveNumber
.
As for infinite cardinals, it seems reasonable to have something like InfiniteCardinal <: Unsigned
(and SignedInfiniteCardinal <: Signed
). I'm a bit confused why it's so important that these are Integer
s though: ContinuumArrays is build on QuasiArrays, and those by design allow more general indexing, so you aren't restricted to integers?
Because InfiniteArrays.jl supports infinite sized AbstractArray
s. Julia's array code assumes length
returns an Integer
so it is essential that the infinite cardinalities are <: Integer
Makes sense. So what do you think of my earlier 6 point proposal?
Ahhh!!! Accidentally closed the window with a detailed response to all your comments 😰
The main point: I think Infinity <: Number
makes sense, and things like "infinite time" handled via units, e.g.:
julia> using InfiniteArrays, Unitful, Unitful.DefaultSymbols
julia> ∞ * hr
∞ hr
That would not be possible if Infinity <: Any
.
Oh no!!!
I think you might be right --- overloading the meaning of ∞
to mean other sorts of infinities does seem wrong.
I think we'll still need something like InfiniteTime <: TimeType
for interoperability with DateTime
though, and reasonable conversions like Time(∞)
or something.
So the proposal becomes:
Infinity <: Real
, singleton type, ∞=Infinity()
, representing the positive real infinity.SignedInfinity <: Real
for ∞
and -∞
, represented by its sign.ComplexInfinity <: Number
for z * ∞
where z
is a complex unit, represented by sign(z)
.InfiniteCardinal <: Integer
for infinite cardinals. Also SignedInfiniteCardinal
if you need negative ones.InfiniteTime <: TimeType
for infinite times (i.e. ∞
means "infinitely far in the future"), represented by a SignedInfinity
. Also maybe UInfiniteTime
for the unsigned version. Construct like Time(∞)
or something.InfExtended*
stuff.Yes I like this
@fchorney @omus FYI the plan is to move this package over to https://github.com/JuliaMath/Infinities.jl. It is being renamed to Infinities
, what is currently Infinite
will be renamed to SignedInfinity
, we'll be adding a singleton ∞=Infinity()
and some other purely-infinite types. All the InfExtended*
stuff will remain as-is. See my previous comment here for details.
Let me know if you have any more PRs soon. If not, I'll release a version and that will be the last one on this repo. Then we'll copy the repo to its new home, make the planned changes, and register it.
@dlfivefifty Sounds reasonable?
I'll copy over my code now with the new naming scheme.
InfiniteArrays.jl currently has several infinite types and could make sense to unify this with this package. In particular I have
Infinity <: Integer
. This is because it represents cardinality, and so need it to be anInteger
to work with the array interfaces. Note I believe in interpretingInteger
as an an interface, not a mathematical definition, so sinceInfinity
conforms to theInteger
interface this is a valid definition.SignedInfinity <: Integer
, to support+∞
and-∞
.OrientedInfinity{T<:Real} <: Number
. This is for infinities in the complex plane (unfortunately there's noAbstractComplex
to subtype)What do you think? It will take some thought, in particular I would propose at least:
Infinite
asInfinity
(adjective -> noun)Infinity <: Integer
makes sense, or whether that should be another type calledInfiniteCardinality
.