Combine with InfiniteArrays.Infinity?
dlfivefifty opened this issue · 12 comments
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:
- Rename Infinity.jl as Infinities.jl
- Move to JuliaMath
- Rename
Infinite
asInfinity
(adjective -> noun) - Decide whether
Infinity <: Integer
makes sense, or whether that should be another type calledInfiniteCardinality
.
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
(essentiallyUnion{T,Infinite}
)InfExtendedTime{T<:TimeType} <: TimeType
(essentiallyUnion{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:
- I don't know how to change the name of a registered package, but I assume it's possible. Or perhaps you add a new one and depracate the old one? Also see 3.
- Yes that makes sense. Again, I don't know how you move a registered package.
- I went with the current naming scheme because the
Number
hierarchy already uses adjectives likeReal
andRational
, but then I supposeFloat
is a verb and all of these terms are colloquially also used as nouns, so I'm happy to changeInfinite
toInfinity
andInfinity
toInfinities
- I don't think the base
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 asignbit::Bool
field, and-∞ = SignedInfinity(true)
.URealInfinity <: Real
andRealInfinity <: Real
are the unsigned and signed real infinity types.- (Perhaps
UIntegerInfinity <: Unsigned
andIntegerInfinity <: Signed
for unsigned and signed integer infinities.) ComplexInfinity{T} <: Number
for complex infinities with a phase of typeT
.- All the
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:
- It's not clear to me if having
IntegerInfinity
is useful in addition toRealInfinity
. You might suggest havingRealInfinity <: Signed
but infinity isn't really a (mathematical) integer, and in the absence of an official interface forInteger
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 ofmod(∞,10)
so that the identitymod(∞+1,10) == mod(mod(∞,10)+1,10)
holds. On the other hand, theReal
interface already contains infinities (Inf
and1//0
). - We could supply helper unions, such as
IntegerOrInfinity = Union{Integer, RealInfinity, URealInfinity, InfExtended{<:Integer}}
. - Perhaps
ComplexInfinity{T}
should not store the phase as aT
but the sign as aComplex{T}
? Then we could havez*∞ = Complex(sign(z))
wherez::Complex
, analagously to-∞ = SignedInfinity(true)
. - If so, then for consistence perhaps
SignedInfinity
should be represented not by itssignbit::Bool
but by itssign::Int8 ∈ {-1,1}
.
#In my usage I absolutely need an infinity that's a subtype or 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
forz * ∞
wherez
is a complex unit, represented bysign(z)
.InfiniteCardinal <: Integer
for infinite cardinals. AlsoSignedInfiniteCardinal
if you need negative ones.InfiniteTime <: TimeType
for infinite times (i.e.∞
means "infinitely far in the future"), represented by aSignedInfinity
. Also maybeUInfiniteTime
for the unsigned version. Construct likeTime(∞)
or something.- All the
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.