From fa799fb1156cfbc7df8505463cccbc1331b3546d Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sat, 3 Dec 2022 21:25:53 +0000 Subject: [PATCH 1/5] Start Bi-infinite ranges --- src/InfiniteArrays.jl | 2 +- src/biinfrange.jl | 21 +++++++++++++++++++++ test/test_biinfrange.jl | 8 ++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 src/biinfrange.jl create mode 100644 test/test_biinfrange.jl diff --git a/src/InfiniteArrays.jl b/src/InfiniteArrays.jl index abf3a8c..7765b6c 100644 --- a/src/InfiniteArrays.jl +++ b/src/InfiniteArrays.jl @@ -211,7 +211,7 @@ end return LazyArrays.searchsortedlast_recursive(n, x, args...) end - +include("biinfrange.jl") end # module diff --git a/src/biinfrange.jl b/src/biinfrange.jl new file mode 100644 index 0000000..bdc8f52 --- /dev/null +++ b/src/biinfrange.jl @@ -0,0 +1,21 @@ +""" +BiInfUnitRange() + +Represent -∞:∞ with offset indexing +""" +struct BiInfUnitRange{T<:Real} <: AbstractInfUnitRange{T} end + +BiInfUnitRange() = BiInfUnitRange{Int}() + +AbstractArray{T}(a::BiInfUnitRange) where T<:Real = BiInfUnitRange{T}(a) +AbstractVector{T}(a::BiInfUnitRange) where T<:Real = BiInfUnitRange{T}(a) + +unitrange(a::BiInfUnitRange) = a +Base.has_offset_axes(::BiInfUnitRange) = true + +getindex(v::BiInfUnitRange{T}, i::Integer) where T = convert(T, i) +axes(::BiInfUnitRange) = (BiInfUnitRange(),) +first(::BiInfUnitRange) = -∞ +show(io::IO, ::BiInfUnitRange{Int}) = print(io, "BiInfUnitRange()") + +getindex(r::BiInfUnitRange{T}, s::AbstractUnitRange{<:Integer}) where T = convert(AbstractVector{T}, s) \ No newline at end of file diff --git a/test/test_biinfrange.jl b/test/test_biinfrange.jl new file mode 100644 index 0000000..0a2b3d3 --- /dev/null +++ b/test/test_biinfrange.jl @@ -0,0 +1,8 @@ +using InfiniteArrays, Base64, Test +using InfiniteArrays: BiInfUnitRange + +@testset "-∞:∞" begin + r = BiInfUnitRange() + @test stringmime("text/plain", r) == "BiInfUnitRange()" + +end \ No newline at end of file From 85b07b44732dab1bee37760aaa78ef76da83efee Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sun, 14 Dec 2025 07:39:38 +0000 Subject: [PATCH 2/5] Update test_biinfrange.jl --- test/test_biinfrange.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_biinfrange.jl b/test/test_biinfrange.jl index 0a2b3d3..ca35566 100644 --- a/test/test_biinfrange.jl +++ b/test/test_biinfrange.jl @@ -4,5 +4,5 @@ using InfiniteArrays: BiInfUnitRange @testset "-∞:∞" begin r = BiInfUnitRange() @test stringmime("text/plain", r) == "BiInfUnitRange()" - + @test Fill(1, (r,))[-5] == 1 end \ No newline at end of file From 34f57c3a2d00a9d075a634b936924d23bda5e403 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sun, 14 Dec 2025 07:49:41 +0000 Subject: [PATCH 3/5] try to fix printing --- src/biinfrange.jl | 1 + src/infrange.jl | 1 + test/runtests.jl | 4 ++++ test/test_biinfrange.jl | 1 + 4 files changed, 7 insertions(+) diff --git a/src/biinfrange.jl b/src/biinfrange.jl index bdc8f52..28ba42c 100644 --- a/src/biinfrange.jl +++ b/src/biinfrange.jl @@ -14,6 +14,7 @@ unitrange(a::BiInfUnitRange) = a Base.has_offset_axes(::BiInfUnitRange) = true getindex(v::BiInfUnitRange{T}, i::Integer) where T = convert(T, i) +getindex(v::BiInfUnitRange{T}, i::RealInfinity) where T = i axes(::BiInfUnitRange) = (BiInfUnitRange(),) first(::BiInfUnitRange) = -∞ show(io::IO, ::BiInfUnitRange{Int}) = print(io, "BiInfUnitRange()") diff --git a/src/infrange.jl b/src/infrange.jl index b551551..61ea4c1 100644 --- a/src/infrange.jl +++ b/src/infrange.jl @@ -29,6 +29,7 @@ _range(a::Real, ::Nothing, ::Nothing, len::InfiniteCardinal{0}) _range(a::AbstractFloat, ::Nothing, ::Nothing, len::InfiniteCardinal{0}) = _range(a, oftype(a, 1), nothing, len) _range(a::T, st::T, ::Nothing, ::InfiniteCardinal{0}) where T<:IEEEFloat = InfStepRange{T,T}(a, st) _range(a::T, st::T, ::Nothing, ::InfiniteCardinal{0}) where T<:AbstractFloat = InfStepRange{T,T}(a, st) +_range(a::Infinities.AllInfinities, ::Nothing, ::Nothing, length::Int) = Fill(a, length) range_start_step_length(a, st, ::InfiniteCardinal{0}) = InfStepRange(a, st) range_start_step_length(a::Real, st::IEEEFloat, len::InfiniteCardinal{0}) = range_start_step_length(promote(a, st)..., len) range_start_step_length(a::IEEEFloat, st::Real, len::InfiniteCardinal{0}) = range_start_step_length(promote(a, st)..., len) diff --git a/test/runtests.jl b/test/runtests.jl index cdeebe4..aa49614 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -564,6 +564,10 @@ end @test_throws ArgumentError [1:∞; [1.0]; 1:∞] @test_throws ArgumentError [1:∞; 1; [1]] end + + @testset "range from ∞" begin + @test range(ℵ₀; length=5) ≡ Fill(ℵ₀, 5) + end end @testset "fill" begin diff --git a/test/test_biinfrange.jl b/test/test_biinfrange.jl index ca35566..c8b7ded 100644 --- a/test/test_biinfrange.jl +++ b/test/test_biinfrange.jl @@ -5,4 +5,5 @@ using InfiniteArrays: BiInfUnitRange r = BiInfUnitRange() @test stringmime("text/plain", r) == "BiInfUnitRange()" @test Fill(1, (r,))[-5] == 1 + @test exp.(r)[-3] == exp(-3) end \ No newline at end of file From a33a187b6adff1cd0b362b4e452ad6fbf0d452d2 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Mon, 15 Dec 2025 09:08:22 +0000 Subject: [PATCH 4/5] Update runtests.jl --- test/runtests.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index aa49614..268a28a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1300,7 +1300,8 @@ end @test !checkbounds(Bool, r, Fill(true, 1)) end +include("test_biinfrange.jl") include("test_infconv.jl") include("test_infblock.jl") include("test_infbanded.jl") -include("test_infblockbanded.jl") +include("test_infblockbanded.jl") \ No newline at end of file From 7649693c6818295059b938bd96a769bbcd86291f Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Mon, 15 Dec 2025 10:44:54 +0000 Subject: [PATCH 5/5] add print --- src/InfiniteArrays.jl | 2 +- src/biinfrange.jl | 82 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/InfiniteArrays.jl b/src/InfiniteArrays.jl index 2a92ec8..11bcb60 100644 --- a/src/InfiniteArrays.jl +++ b/src/InfiniteArrays.jl @@ -14,7 +14,7 @@ import Base: *, +, -, /, <, ==, >, \, ≤, ≥, (:), @propagate_inbounds, searchsortedfirst, searchsortedlast, setindex!, show, show_circular, show_delim_array, sign, signbit, similar, size, sort, sort!, step, sum, tail, to_shape, transpose, unaliascopy, union, unitrange_last, unsafe_convert, unsafe_indices, unsafe_length, - vcat, zeros, copyto!, range_start_step_length + vcat, zeros, copyto!, range_start_step_length, undef_ref_str, alignment if VERSION ≥ v"1.11.0-DEV.21" using LinearAlgebra: UpperOrLowerTriangular diff --git a/src/biinfrange.jl b/src/biinfrange.jl index 28ba42c..8647741 100644 --- a/src/biinfrange.jl +++ b/src/biinfrange.jl @@ -19,4 +19,84 @@ axes(::BiInfUnitRange) = (BiInfUnitRange(),) first(::BiInfUnitRange) = -∞ show(io::IO, ::BiInfUnitRange{Int}) = print(io, "BiInfUnitRange()") -getindex(r::BiInfUnitRange{T}, s::AbstractUnitRange{<:Integer}) where T = convert(AbstractVector{T}, s) \ No newline at end of file +getindex(r::BiInfUnitRange{T}, s::AbstractUnitRange{<:Integer}) where T = convert(AbstractVector{T}, s) + + + +function Base._print_matrix(io, @nospecialize(X::AbstractVecOrMat), pre, sep, post, hdots, vdots, ddots, hmod, vmod, rowsA::BiInfUnitRange, colsA) + hmod, vmod = Int(hmod)::Int, Int(vmod)::Int + ncols, idxlast = length(colsA), last(colsA) + if !(get(io, :limit, false)::Bool) + screenheight = screenwidth = typemax(Int) + else + sz = displaysize(io)::Tuple{Int,Int} + screenheight, screenwidth = sz[1] - 4, sz[2] + end + screenwidth -= length(pre)::Int + length(post)::Int + presp = repeat(" ", length(pre)::Int) # indent each row to match pre string + postsp = "" + @assert textwidth(hdots) == textwidth(ddots) + sepsize = length(sep)::Int + m, n = length(rowsA), length(colsA) + # To figure out alignments, only need to look at as many rows as could + # fit down screen. If screen has at least as many rows as A, look at A. + # If not, then we only need to look at the first and last chunks of A, + # each half a screen height in size. + quarterheight = div(screenheight,4) + halfheight = 2quarterheight+1 + rowsA = -quarterheight:quarterheight + # Similarly for columns, only necessary to get alignments for as many + # columns as could conceivably fit across the screen + maxpossiblecols = div(screenwidth, 1+sepsize) + if n > maxpossiblecols + colsA = [colsA[(0:maxpossiblecols-1) .+ firstindex(colsA)]; colsA[(end-maxpossiblecols+1):end]] + else + colsA = [colsA;] + end + A = alignment(io, X, rowsA, colsA, screenwidth, screenwidth, sepsize, ncols) + # Nine-slicing is accomplished using print_matrix_row repeatedly + if n <= length(A) # rows don't fit, cols do, so only vertical ellipsis + print_matrix_vdots(io, vdots, A, sep, vmod, 1, false) + print(io, postsp * '\n') + for i in rowsA + print(io, i == first(rowsA) ? pre : presp) + i == 0 && print(io, "\e[1m") + print_matrix_row(io, X,A,i,colsA,sep,idxlast) + i == 0 && print(io, "\e[0m") + print(io, i == last(rowsA) ? post : postsp) + if i != rowsA[end] || i == rowsA[halfheight]; println(io); end + if i == rowsA[halfheight] + print(io, i == first(rowsA) ? pre : presp) + print_matrix_vdots(io, vdots, A, sep, vmod, 1, false) + print(io, i == last(rowsA) ? post : postsp * '\n') + end + end + else # neither rows nor cols fit, so use all 3 kinds of dots + c = div(screenwidth-length(hdots)::Int+1,2)+1 + Ralign = reverse(alignment(io, X, rowsA, reverse(colsA), c, c, sepsize, ncols)) + c = screenwidth - sum(map(sum,Ralign)) - (length(Ralign)-1)*sepsize - length(hdots)::Int + Lalign = alignment(io, X, rowsA, colsA, c, c, sepsize, ncols) + r = mod((length(Ralign)-n+1),vmod) # where to put dots on right half + for i in rowsA + print(io, i == first(rowsA) ? pre : presp) + print_matrix_row(io, X,Lalign,i,colsA[1:length(Lalign)],sep,idxlast) + print(io, (i - first(rowsA)) % hmod == 0 ? hdots : repeat(" ", length(hdots)::Int)) + print_matrix_row(io, X,Ralign,i,(n-length(Ralign)).+colsA,sep,idxlast) + print(io, i == last(rowsA) ? post : postsp) + if i != rowsA[end] || i == rowsA[halfheight]; println(io); end + if i == rowsA[halfheight] + print(io, i == first(rowsA) ? pre : presp) + print_matrix_vdots(io, vdots, Lalign, sep, vmod, 1, true) + print(io, ddots) + print_matrix_vdots(io, vdots, Ralign, sep, vmod, r, false) + print(io, i == last(rowsA) ? post : postsp * '\n') + end + end + end + if isempty(rowsA) + print(io, pre) + print(io, vdots) + length(colsA) > 1 && print(io, " ", ddots) + print(io, post) + end +end