Skip to content

Commit a0536ea

Browse files
authored
Support InfiniteArrays.jl (#10)
* Changes to support InfiniteArrays.jl * isinf/isfninite for Cardinal * More combined infinities * Update runtests.jl * Increase coverage * improve inequalities * increase coverage * Update test_cardinality.jl
1 parent f1ad8fb commit a0536ea

File tree

5 files changed

+317
-109
lines changed

5 files changed

+317
-109
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "Infinities"
22
uuid = "e1ba4f0e-776d-440f-acd9-e1d2e9742647"
33
authors = ["Sheehan Olver <[email protected]>"]
4-
version = "0.0.1"
4+
version = "0.0.2"
55

66
[compat]
77
julia = "1"

src/Infinities.jl

Lines changed: 27 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Base: angle, isone, iszero, isinf, isfinite, abs, one, zero, isless,
44
+, -, *, ==, <, , >, , fld, cld, div, mod, min, max, sign, signbit,
55
string, show, promote_rule, convert
66

7-
export ∞, ℵ₀, ℵ₁, RealInfinity, ComplexInfinity, NotANumber
7+
export ∞, ℵ₀, ℵ₁, RealInfinity, ComplexInfinity, InfiniteCardinal, NotANumber
88
# The following is commented out for now to avoid conflicts with Infinity.jl
99
# export Infinity
1010

@@ -41,25 +41,45 @@ convert(::Type{AF}, ::Infinity) where AF<:AbstractFloat = convert(AF, Inf)
4141
sign(y::Infinity) = 1
4242
angle(x::Infinity) = 0
4343

44-
==(x::Infinity, y::Infinity) = true
45-
4644
one(::Type{Infinity}) = 1
4745
zero(::Infinity) = 0
4846

4947
isinf(::Infinity) = true
5048
isfinite(::Infinity) = false
5149

50+
==(x::Infinity, y::Infinity) = true
5251
==(x::Infinity, y::Number) = isinf(y) && angle(y) == angle(x)
5352
==(y::Number, x::Infinity) = x == y
5453

55-
56-
5754
isless(x::Infinity, y::Infinity) = false
58-
isless(x::Real, y::Infinity) = isfinite(x) || sign(y) == -1
55+
isless(x::Real, y::Infinity) = isfinite(x) || signbit(x)
5956
isless(x::AbstractFloat, y::Infinity) = isless(x, convert(typeof(x), y))
6057
isless(x::Infinity, y::AbstractFloat) = false
6158
isless(x::Infinity, y::Real) = false
6259

60+
(::Infinity, ::Infinity) = true
61+
<(::Infinity, ::Infinity) = false
62+
(::Infinity, ::Infinity) = true
63+
>(::Infinity, ::Infinity) = false
64+
65+
<(x::Real, ::Infinity) = isfinite(x) || signbit(x)
66+
(::Real, ::Infinity) = true
67+
<(::Infinity, ::Real) = false
68+
(::Infinity, y::Real) = isinf(y) && !signbit(y)
69+
70+
>(::Real, ::Infinity) = false
71+
(x::Real, ::Infinity) = isinf(x) && !signbit(x)
72+
>(::Infinity, y::Real) = isfinite(y) || signbit(y)
73+
(::Infinity, y::Real) = true
74+
75+
76+
min(::Infinity, ::Infinity) =
77+
max(::Infinity, ::Infinity) =
78+
min(x::Real, ::Infinity) = x
79+
max(::Real, ::Infinity) =
80+
min(::Infinity, x::Real) = x
81+
max(::Infinity, ::Real) =
82+
6383
+(::Infinity) =
6484
+(::Infinity, ::Infinity) =
6585
+(::Number, y::Infinity) =
@@ -96,31 +116,6 @@ function mod(x::Real, ::Infinity)
96116
x
97117
end
98118

99-
min(::Infinity, ::Infinity) =
100-
max(::Infinity, ::Infinity) =
101-
min(x::Real, ::Infinity) = x
102-
max(::Real, ::Infinity) =
103-
min(::Infinity, x::Real) = x
104-
max(::Infinity, ::Real) =
105-
106-
(::Infinity, ::Infinity) = true
107-
<(::Infinity, ::Infinity) = false
108-
(::Infinity, ::Infinity) = true
109-
>(::Infinity, ::Infinity) = false
110-
111-
for OP in (:<, :)
112-
@eval begin
113-
$OP(::Real, ::Infinity) = true
114-
$OP(::Infinity, ::Real) = false
115-
end
116-
end
117-
118-
for OP in (:>, :)
119-
@eval begin
120-
$OP(::Real, ::Infinity) = false
121-
$OP(::Infinity, ::Real) = true
122-
end
123-
end
124119

125120

126121
struct RealInfinity <: Real
@@ -389,28 +384,8 @@ for OP in (:>, :≥)
389384
end
390385
end
391386

392-
##
393-
# Checked
394-
##
395-
396-
Base.Checked.checked_sub(::Integer, ::Infinity) = -
397-
Base.Checked.checked_sub(::Infinity, ::Integer) =
398-
Base.Checked.checked_add(::Integer, ::Infinity) =
399-
Base.Checked.checked_add(::Infinity, ::Integer) =
400-
401-
Base.Checked.checked_sub(::Integer, x::RealInfinity) = -x
402-
Base.Checked.checked_sub(x::RealInfinity, ::Integer) = x
403-
Base.Checked.checked_add(::Integer, x::RealInfinity) = x
404-
Base.Checked.checked_add(x::RealInfinity, ::Integer) = x
405-
406-
Base.Checked.checked_mul(x::Integer, ::Infinity) = sign(x)*
407-
Base.Checked.checked_mul(::Infinity, x::Integer) = sign(x)*
408-
Base.Checked.checked_mul(x::Integer, y::RealInfinity) = sign(x)*y
409-
Base.Checked.checked_mul(y::RealInfinity, x::Integer) = y*sign(x)
410-
411-
387+
Base.hash(::Infinity) = 0x020113134b21797f # made up
412388

413-
Base.to_index(::Infinity) =
414389

415390
include("cardinality.jl")
416391
end # module

src/cardinality.jl

Lines changed: 154 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,116 @@ being treated as a length in array machinier.
1010
"""
1111
struct InfiniteCardinal{N} <: Integer end
1212

13+
const ℵ₀ = InfiniteCardinal{0}()
14+
const ℵ₁ = InfiniteCardinal{1}()
15+
16+
string(::InfiniteCardinal{0}) = "ℵ₀"
17+
string(::InfiniteCardinal{1}) = "ℵ₁"
18+
19+
show(io::IO, F::InfiniteCardinal{0}) where N = print(io, "ℵ₀")
20+
show(io::IO, F::InfiniteCardinal{1}) where N = print(io, "ℵ₁")
21+
22+
1323
isone(::InfiniteCardinal) = false
1424
iszero(::InfiniteCardinal) = false
1525

26+
signbit(::InfiniteCardinal) = false
27+
sign(::InfiniteCardinal) = 1
28+
angle(::InfiniteCardinal) = 0
29+
abs(a::InfiniteCardinal) = a
30+
zero(::InfiniteCardinal) = 0
31+
one(::InfiniteCardinal) = 1
32+
33+
isinf(::InfiniteCardinal) = true
34+
isfinite(::InfiniteCardinal) = false
35+
36+
Integer(::Infinity) = InfiniteCardinal{0}()
37+
38+
==(::InfiniteCardinal{N}, ::InfiniteCardinal{N}) where N = true
39+
==(::InfiniteCardinal, ::InfiniteCardinal)= false
1640
==(::InfiniteCardinal, ::Int) = false
1741
==(::Int, ::InfiniteCardinal) = false
42+
==(x::InfiniteCardinal, ::Infinity) = x == ℵ₀
43+
==(::Infinity, y::InfiniteCardinal) = ℵ₀ == y
44+
==(::InfiniteCardinal{0}, y::RealInfinity) === y
45+
==(x::RealInfinity, ::InfiniteCardinal{0}) = x ==
46+
==(::InfiniteCardinal, y::Real) === y
47+
==(x::Real, ::InfiniteCardinal) = x ==
48+
49+
@generated isless(::InfiniteCardinal{N}, ::InfiniteCardinal{M}) where {N,M} = :($(isless(N, M)))
50+
isless(::InfiniteCardinal{0}, ::InfiniteCardinal{0}) = false
51+
isless(x::Real, ::InfiniteCardinal{0}) = isfinite(x)
52+
isless(x::Real, ::InfiniteCardinal) = true
53+
isless(x::AbstractFloat, ::InfiniteCardinal{0}) = isfinite(x)
54+
isless(x::AbstractFloat, ::InfiniteCardinal) = true
55+
isless(::InfiniteCardinal, y::Real) = false
56+
isless(x::InfiniteCardinal, y::AbstractFloat) = false
57+
58+
@generated <(::InfiniteCardinal{N}, ::InfiniteCardinal{M}) where {N,M} = :($(N < M))
59+
@generated (::InfiniteCardinal{N}, ::InfiniteCardinal{M}) where {N,M} = :($(N M))
60+
@generated >(::InfiniteCardinal{N}, ::InfiniteCardinal{M}) where {N,M} = :($(N > M))
61+
@generated (::InfiniteCardinal{N}, ::InfiniteCardinal{M}) where {N,M} = :($(N M))
62+
63+
(::InfiniteCardinal{0}, ::InfiniteCardinal) = true
64+
>(::InfiniteCardinal{0}, ::InfiniteCardinal) = false
65+
(::InfiniteCardinal, ::InfiniteCardinal{0}) = true
66+
<(::InfiniteCardinal, ::InfiniteCardinal{0}) = false
67+
68+
69+
<(x::Real, ::InfiniteCardinal{0}) = x <
70+
<(x::Real, ::InfiniteCardinal) = true
71+
(x::Real, ::InfiniteCardinal) = true
72+
<(::InfiniteCardinal, x::Real) = false
73+
(::InfiniteCardinal{0}, x::Real) = x
74+
(::InfiniteCardinal, x::Real) = false
75+
>(::InfiniteCardinal{0}, y::Real) => y
76+
>(::InfiniteCardinal, ::Real) = true
77+
(::InfiniteCardinal, ::Real) = true
78+
>(::Real, ::InfiniteCardinal) = false
79+
(x::Real, ::InfiniteCardinal{0}) = x  ∞
80+
(x::Real, ::InfiniteCardinal) = false
81+
82+
83+
<(::Infinity, ::InfiniteCardinal{0}) = false
84+
<(::Infinity, ::InfiniteCardinal) = true
85+
(::Infinity, ::InfiniteCardinal) = true
86+
<(::InfiniteCardinal, ::Infinity) = false
87+
(::InfiniteCardinal{0}, ::Infinity) = true
88+
(::InfiniteCardinal, ::Infinity) = false
89+
>(::InfiniteCardinal{0}, ::Infinity) = false
90+
>(::InfiniteCardinal, ::Infinity) = true
91+
(::InfiniteCardinal, ::Infinity) = true
92+
>(::Infinity, ::InfiniteCardinal) = false
93+
(::Infinity, ::InfiniteCardinal{0}) = true
94+
(::Infinity, ::InfiniteCardinal) = false
95+
1896

97+
<(x::RealInfinity, ::InfiniteCardinal{0}) = x <
98+
<(x::RealInfinity, ::InfiniteCardinal) = true
99+
(x::RealInfinity, ::InfiniteCardinal) = true
100+
>(::InfiniteCardinal{0}, y::RealInfinity) => y
101+
>(::InfiniteCardinal, ::RealInfinity) = true
102+
(::InfiniteCardinal, ::RealInfinity) = true
103+
104+
105+
@generated min(::InfiniteCardinal{N}, ::InfiniteCardinal{M}) where {N,M} = :(InfiniteCardinal{$(min(N,M))}())
106+
@generated max(::InfiniteCardinal{N}, ::InfiniteCardinal{M}) where {N,M} = :(InfiniteCardinal{$(max(N,M))}())
107+
min(x::Real, ::InfiniteCardinal) = x
108+
max(::Real, ℵ::InfiniteCardinal) =
109+
min(::InfiniteCardinal, x::Real) = x
110+
max(ℵ::InfiniteCardinal, ::Real) =
111+
112+
min(x::RealInfinity, ::InfiniteCardinal) = min(x, ∞)
113+
max(::RealInfinity, ℵ::InfiniteCardinal) =
114+
min(::InfiniteCardinal, y::RealInfinity) = min(∞, y)
115+
max(ℵ::InfiniteCardinal, ::RealInfinity) =
116+
117+
min(::Infinity, ::InfiniteCardinal) =
118+
min(::InfiniteCardinal, ::Infinity) =
119+
max(::Infinity, ℵ::InfiniteCardinal) =
120+
max(ℵ::InfiniteCardinal, ::Infinity) =
121+
122+
*(x::InfiniteCardinal) = x
19123
*(::InfiniteCardinal{N}, ::InfiniteCardinal{N}) where N = InfiniteCardinal{N}()
20124
*(::InfiniteCardinal{N}, ::Infinity) where N = InfiniteCardinal{N}()
21125
*(::Infinity, ::InfiniteCardinal{N}) where N = InfiniteCardinal{N}()
@@ -24,32 +128,63 @@ function *(a::Integer, b::InfiniteCardinal)
24128
b
25129
end
26130

131+
*(a::Number, b::InfiniteCardinal) = a *
132+
27133
*(a::InfiniteCardinal, b::Integer) = b*a
134+
*(a::InfiniteCardinal, b::Number) = b*a
28135

136+
+(x::InfiniteCardinal) = x
137+
+(x::InfiniteCardinal, y::InfiniteCardinal) = max(x,y)
29138

30-
abs(a::InfiniteCardinal) = a
31-
zero(::InfiniteCardinal) = 0
32-
one(::InfiniteCardinal) = 1
139+
+(::Integer, y::InfiniteCardinal) = y
140+
+(x::InfiniteCardinal, ::Integer) = x
141+
-(x::InfiniteCardinal, ::Integer) = x
33142

34-
for OP in (:<, :)
35-
@eval begin
36-
$OP(::Real, ::InfiniteCardinal) = true
37-
$OP(::InfiniteCardinal, ::Real) = false
38-
end
143+
-(::InfiniteCardinal{N}, ::InfiniteCardinal{N}) where N = NotANumber()
144+
145+
-(::InfiniteCardinal) = -
146+
-(x::Integer, ::InfiniteCardinal) = x -
147+
148+
for OP in (:fld,:cld,:div)
149+
@eval begin
150+
$OP(x::InfiniteCardinal, ::Real) = x
151+
$OP(::InfiniteCardinal, ::InfiniteCardinal) = NotANumber()
152+
end
39153
end
40154

41-
for OP in (:>, :)
42-
@eval begin
43-
$OP(::Real, ::InfiniteCardinal) = false
44-
$OP(::InfiniteCardinal, ::Real) = true
45-
end
155+
div(::T, ::InfiniteCardinal) where T<:Real = zero(T)
156+
fld(x::T, ::InfiniteCardinal) where T<:Real = signbit(x) ? -one(T) : zero(T)
157+
cld(x::T, ::InfiniteCardinal) where T<:Real = signbit(x) ? zero(T) : one(T)
158+
159+
mod(::InfiniteCardinal, ::InfiniteCardinal) = NotANumber()
160+
mod(::InfiniteCardinal, ::Real) = NotANumber()
161+
function mod(x::Real, ::InfiniteCardinal)
162+
x 0 || throw(ArgumentError("mod(x,∞) is unbounded for x < 0"))
163+
x
46164
end
47165

48-
const ℵ₀ = InfiniteCardinal{0}()
49-
const ℵ₁ = InfiniteCardinal{1}()
50166

51-
string(::InfiniteCardinal{0}) = "ℵ₀"
52-
string(::InfiniteCardinal{1}) = "ℵ₁"
167+
Base.to_index(::Union{Infinity,InfiniteCardinal{0}}) = ℵ₀
168+
Base.to_shape(::Union{Infinity,InfiniteCardinal{0}}) = ℵ₀
169+
Base.to_shape(dims::Tuple{Vararg{Union{Infinity, Integer, AbstractUnitRange}}}) = map(Base.to_shape, dims)
53170

54-
show(io::IO, F::InfiniteCardinal{0}) where N = print(io, "ℵ₀")
55-
show(io::IO, F::InfiniteCardinal{1}) where N = print(io, "ℵ₁")
171+
172+
##
173+
# Checked
174+
##
175+
176+
Base.Checked.checked_sub(::Integer, ::InfiniteCardinal{0}) = -
177+
Base.Checked.checked_sub(::InfiniteCardinal{0}, ::Integer) = ℵ₀
178+
Base.Checked.checked_add(::Integer, ::InfiniteCardinal{0}) = ℵ₀
179+
Base.Checked.checked_add(::InfiniteCardinal{0}, ::Integer) = ℵ₀
180+
181+
Base.Checked.checked_mul(x::Integer, ::InfiniteCardinal{0}) = sign(x)*
182+
Base.Checked.checked_mul(::InfiniteCardinal{0}, x::Integer) = sign(x)*
183+
184+
185+
##
186+
# hash
187+
##
188+
189+
Base.hash(::InfiniteCardinal{0}) = 0x775431eef01bca90 # made up
190+
Base.hash(::InfiniteCardinal{1}) = 0x55437c69b794f8ce # made up

0 commit comments

Comments
 (0)