From fa799fb1156cfbc7df8505463cccbc1331b3546d Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sat, 3 Dec 2022 21:25:53 +0000 Subject: [PATCH 01/12] 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 02/12] 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 03/12] 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 04/12] 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 05/12] 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 From 514a43357cacda68197dfdce582e1a79e6e2ce2d Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Mon, 15 Dec 2025 15:02:32 +0000 Subject: [PATCH 06/12] =?UTF-8?q?bi-=E2=88=9E=20banded=20matrices?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Project.toml | 2 +- src/biinfrange.jl | 70 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/Project.toml b/Project.toml index 79dc748..3c1423b 100644 --- a/Project.toml +++ b/Project.toml @@ -26,7 +26,7 @@ InfiniteArraysStatisticsExt = "Statistics" [compat] Aqua = "0.8" ArrayLayouts = "1.8" -BandedMatrices = "1.7.6" +BandedMatrices = "1.11" Base64 = "1" BlockArrays = "1.0" BlockBandedMatrices = "0.13" diff --git a/src/biinfrange.jl b/src/biinfrange.jl index 8647741..86d65ed 100644 --- a/src/biinfrange.jl +++ b/src/biinfrange.jl @@ -23,7 +23,7 @@ getindex(r::BiInfUnitRange{T}, s::AbstractUnitRange{<:Integer}) where T = conver -function Base._print_matrix(io, @nospecialize(X::AbstractVecOrMat), pre, sep, post, hdots, vdots, ddots, hmod, vmod, rowsA::BiInfUnitRange, colsA) +function Base._print_matrix(io, @nospecialize(X::AbstractVecOrMat), pre, sep, post, hdots, vdots, ddots, hmod, vmod, ::BiInfUnitRange, colsA) hmod, vmod = Int(hmod)::Int, Int(vmod)::Int ncols, idxlast = length(colsA), last(colsA) if !(get(io, :limit, false)::Bool) @@ -37,7 +37,7 @@ function Base._print_matrix(io, @nospecialize(X::AbstractVecOrMat), pre, sep, po postsp = "" @assert textwidth(hdots) == textwidth(ddots) sepsize = length(sep)::Int - m, n = length(rowsA), length(colsA) + n = 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, @@ -100,3 +100,69 @@ function Base._print_matrix(io, @nospecialize(X::AbstractVecOrMat), pre, sep, po print(io, post) end end + + + +function Base._print_matrix(io, @nospecialize(X::AbstractVecOrMat), pre, sep, post, hdots, vdots, ddots, hmod, vmod, ::BiInfUnitRange, ::BiInfUnitRange) + hmod, vmod = Int(hmod)::Int, Int(vmod)::Int + 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 + + # 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 + + halfmaxpossiblecols = div(screenwidth, 4*(1+sepsize)) + maxpossiblecols = 2halfmaxpossiblecols + 1 + colsA = -halfmaxpossiblecols:halfmaxpossiblecols + + A = alignment(io, X, rowsA, colsA, screenwidth, screenwidth, sepsize, ℵ₀) + c = div(screenwidth-length(hdots)::Int+1,2)+1 + Ralign = reverse(alignment(io, X, rowsA, reverse(colsA), c, c, sepsize, ℵ₀)) + c = screenwidth - sum(map(sum,Ralign)) - (length(Ralign)-1)*sepsize - length(hdots)::Int + Lalign = alignment(io, X, rowsA, colsA, c, c, sepsize, ℵ₀) + r = 1 # where to put dots on right half + + for i in rowsA + if i == rowsA[1] + print(io, i == first(rowsA) ? pre : presp) + print_matrix_vdots(io, vdots, Lalign, sep, vmod, 1, true) + print(io, ddots) + print(io, i == last(rowsA) ? post : postsp * '\n') + end + + print(io, i == first(rowsA) ? pre : presp) + print_matrix_row(io, X,Lalign,i,colsA,sep,ℵ₀) + print(io, (i - first(rowsA)) % hmod == 0 ? hdots : repeat(" ", length(hdots)::Int)) + # print_matrix_row(io, X,Ralign,i,colsA,sep,ℵ₀) + 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(io, i == last(rowsA) ? post : postsp * '\n') + end + end + if isempty(rowsA) + print(io, pre) + print(io, vdots) + length(colsA) > 1 && print(io, " ", ddots) + print(io, post) + end +end From 5e129bae046678f18e6a17658844b58d7ef5defc Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sun, 21 Dec 2025 14:55:08 +0000 Subject: [PATCH 07/12] add print test --- test/runtests.jl | 4 ++-- test/test_biinfrange.jl | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 268a28a..145c026 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1300,8 +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") \ No newline at end of file +include("test_infblockbanded.jl") +include("test_biinfrange.jl") \ No newline at end of file diff --git a/test/test_biinfrange.jl b/test/test_biinfrange.jl index c8b7ded..bfed651 100644 --- a/test/test_biinfrange.jl +++ b/test/test_biinfrange.jl @@ -1,4 +1,4 @@ -using InfiniteArrays, Base64, Test +using InfiniteArrays, BandedMatrices, Base64, Test using InfiniteArrays: BiInfUnitRange @testset "-∞:∞" begin @@ -6,4 +6,5 @@ using InfiniteArrays: BiInfUnitRange @test stringmime("text/plain", r) == "BiInfUnitRange()" @test Fill(1, (r,))[-5] == 1 @test exp.(r)[-3] == exp(-3) + @test stringmime("text/plain", r.^2; context= IOContext(IOBuffer(), :limit=>true)) == "(ℵ₀-element BiInfUnitRange{$Int} with indices BiInfUnitRange()) .^ 2 with indices BiInfUnitRange():\n ⋮\n 25\n 16\n 9\n 4\n 1\n \e[1m 0\e[0m\n 1\n 4\n 9\n 16\n 25\n ⋮" end \ No newline at end of file From 4558fcb60dc354f80f52a1b66127d10c11fee8e9 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sun, 21 Dec 2025 18:35:40 +0000 Subject: [PATCH 08/12] =?UTF-8?q?=E2=88=9E=20columns=20finite=20rows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/InfiniteArrays.jl | 4 +-- src/biinfrange.jl | 57 ++++++++++++++++++++++++++++++++++++++++- test/test_biinfrange.jl | 5 ++++ 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/src/InfiniteArrays.jl b/src/InfiniteArrays.jl index 11bcb60..c49b72b 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, undef_ref_str, alignment + vcat, zeros, copyto!, range_start_step_length, undef_ref_str, alignment, IndexStyle, IndexCartesian if VERSION ≥ v"1.11.0-DEV.21" using LinearAlgebra: UpperOrLowerTriangular @@ -41,7 +41,7 @@ import LazyArrays: AbstractLazyLayout, AbstractCachedVector, ApplyLayout, Cached LazyArrayStyle, LazyLayout, LazyMatrix, PaddedColumns, _padded_sub_materialize, sub_paddeddata, ApplyBandedLayout, BroadcastBandedLayout, islazy_layout -import LinearAlgebra: AdjOrTrans, HermOrSym, diag, norm, norm1, norm2, normp +import LinearAlgebra: AdjOrTrans, HermOrSym, diag, norm, norm1, norm2, normp, AdjOrTransAbsVec import LazyArrays: AbstractPaddedLayout diff --git a/src/biinfrange.jl b/src/biinfrange.jl index 86d65ed..337c973 100644 --- a/src/biinfrange.jl +++ b/src/biinfrange.jl @@ -14,6 +14,10 @@ unitrange(a::BiInfUnitRange) = a Base.has_offset_axes(::BiInfUnitRange) = true getindex(v::BiInfUnitRange{T}, i::Integer) where T = convert(T, i) +function getindex(x::BiInfUnitRange, i::PosInfinity) + isinf(length(x)) || throw(BoundsError(x,y)) + ℵ₀ +end getindex(v::BiInfUnitRange{T}, i::RealInfinity) where T = i axes(::BiInfUnitRange) = (BiInfUnitRange(),) first(::BiInfUnitRange) = -∞ @@ -21,7 +25,7 @@ show(io::IO, ::BiInfUnitRange{Int}) = print(io, "BiInfUnitRange()") getindex(r::BiInfUnitRange{T}, s::AbstractUnitRange{<:Integer}) where T = convert(AbstractVector{T}, s) - +IndexStyle(::Type{<:AdjOrTransAbsVec{<:Any,<:BiInfUnitRange}}) = IndexCartesian() function Base._print_matrix(io, @nospecialize(X::AbstractVecOrMat), pre, sep, post, hdots, vdots, ddots, hmod, vmod, ::BiInfUnitRange, colsA) hmod, vmod = Int(hmod)::Int, Int(vmod)::Int @@ -102,6 +106,57 @@ function Base._print_matrix(io, @nospecialize(X::AbstractVecOrMat), pre, sep, po end +function Base._print_matrix(io, @nospecialize(X::AbstractVecOrMat), pre, sep, post, hdots, vdots, ddots, hmod, vmod, rowsA, ::BiInfUnitRange) + hmod, vmod = Int(hmod)::Int, Int(vmod)::Int + 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 = length(rowsA) + + # 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. + halfheight = div(screenheight,2) + if m > screenheight + rowsA = [rowsA[(0:halfheight-1) .+ firstindex(rowsA)]; rowsA[(end-div(screenheight-1,2)+1):end]] + else + rowsA = [rowsA;] + end + + # Similarly for columns, only necessary to get alignments for as many + # columns as could conceivably fit across the screen + + halfmaxpossiblecols = div(screenwidth, 4*(1+sepsize)) + maxpossiblecols = 2halfmaxpossiblecols + 1 + colsA = -halfmaxpossiblecols:halfmaxpossiblecols + + A = alignment(io, X, rowsA, colsA, screenwidth, screenwidth, sepsize, ℵ₀) + c = div(screenwidth-length(hdots)::Int+1,2)+1 # what goes to right of ellipsis + Ralign = reverse(alignment(io, X, rowsA, reverse(colsA), c, c, sepsize, ℵ₀)) # alignments for right + c = screenwidth - sum(map(sum,Ralign)) - (length(Ralign)-1)*sepsize - length(hdots)::Int + Lalign = alignment(io, X, rowsA, colsA, c, c, sepsize, ℵ₀) # alignments for left of ellipsis + + print(io, hdots) + for i in rowsA + print(io, i == first(rowsA) ? pre : presp) + print_matrix_row(io, X,Lalign,i,colsA[1:length(Lalign)],sep,ℵ₀) + print(io, (i - first(rowsA)) % hmod == 0 ? hdots : repeat(" ", length(hdots)::Int)) + print_matrix_row(io, X, Ralign, i, ℵ₀ .+ colsA, sep, ℵ₀) + print(io, i == last(rowsA) ? post : postsp) + if i != last(rowsA); println(io); end + end +end + + function Base._print_matrix(io, @nospecialize(X::AbstractVecOrMat), pre, sep, post, hdots, vdots, ddots, hmod, vmod, ::BiInfUnitRange, ::BiInfUnitRange) hmod, vmod = Int(hmod)::Int, Int(vmod)::Int diff --git a/test/test_biinfrange.jl b/test/test_biinfrange.jl index bfed651..8f20bc1 100644 --- a/test/test_biinfrange.jl +++ b/test/test_biinfrange.jl @@ -7,4 +7,9 @@ using InfiniteArrays: BiInfUnitRange @test Fill(1, (r,))[-5] == 1 @test exp.(r)[-3] == exp(-3) @test stringmime("text/plain", r.^2; context= IOContext(IOBuffer(), :limit=>true)) == "(ℵ₀-element BiInfUnitRange{$Int} with indices BiInfUnitRange()) .^ 2 with indices BiInfUnitRange():\n ⋮\n 25\n 16\n 9\n 4\n 1\n \e[1m 0\e[0m\n 1\n 4\n 9\n 16\n 25\n ⋮" + + @test isassigned(r', 1,-12) + @test stringmime("text/plain", r'; context= IOContext(IOBuffer(), :limit=>true)) == "1×ℵ₀ adjoint(::BiInfUnitRange{$Int}) with eltype Int64 with indices Base.OneTo(1)×BiInfUnitRange():\n … -6 -5 -4 -3 -2 -1 0 1 2 3 … " + + # _BandedMatrix( end \ No newline at end of file From bc6dd60c4780c5ffb4cdc3467541d60041f20814 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sun, 21 Dec 2025 18:39:19 +0000 Subject: [PATCH 09/12] Update biinfrange.jl --- src/biinfrange.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/biinfrange.jl b/src/biinfrange.jl index 337c973..182bbb3 100644 --- a/src/biinfrange.jl +++ b/src/biinfrange.jl @@ -27,6 +27,8 @@ getindex(r::BiInfUnitRange{T}, s::AbstractUnitRange{<:Integer}) where T = conver IndexStyle(::Type{<:AdjOrTransAbsVec{<:Any,<:BiInfUnitRange}}) = IndexCartesian() +Base.Broadcast.axistype(a::BiInfUnitRange, ::OneTo) = a + function Base._print_matrix(io, @nospecialize(X::AbstractVecOrMat), pre, sep, post, hdots, vdots, ddots, hmod, vmod, ::BiInfUnitRange, colsA) hmod, vmod = Int(hmod)::Int, Int(vmod)::Int ncols, idxlast = length(colsA), last(colsA) From 7e075d675028468d470c77801758203d139c6b15 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sun, 21 Dec 2025 18:54:59 +0000 Subject: [PATCH 10/12] =?UTF-8?q?bi-=E2=88=9E=20matrix=20printing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/infrange.jl | 1 + test/test_biinfrange.jl | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/infrange.jl b/src/infrange.jl index 61ea4c1..ea6f426 100644 --- a/src/infrange.jl +++ b/src/infrange.jl @@ -443,6 +443,7 @@ sum(r::InfRanges{<:Real}) = last(r) in(x::Union{Infinity,RealInfinity}, r::InfRanges) = false # never reach it... in(x::Infinity, r::InfRanges{<:Integer}) = false # never reach it... in(x::Real, r::InfRanges{<:Real}) = _in_range(x, r) +in(x::Integer, r::InfUnitRange) = x ≥ first(r) # This method needs to be defined separately since -(::T, ::T) can be implemented # even if -(::T, ::Real) is not in(x::T, r::InfRanges{T}) where {T} = _in_range(x, r) diff --git a/test/test_biinfrange.jl b/test/test_biinfrange.jl index 8f20bc1..5c077c5 100644 --- a/test/test_biinfrange.jl +++ b/test/test_biinfrange.jl @@ -9,7 +9,7 @@ using InfiniteArrays: BiInfUnitRange @test stringmime("text/plain", r.^2; context= IOContext(IOBuffer(), :limit=>true)) == "(ℵ₀-element BiInfUnitRange{$Int} with indices BiInfUnitRange()) .^ 2 with indices BiInfUnitRange():\n ⋮\n 25\n 16\n 9\n 4\n 1\n \e[1m 0\e[0m\n 1\n 4\n 9\n 16\n 25\n ⋮" @test isassigned(r', 1,-12) - @test stringmime("text/plain", r'; context= IOContext(IOBuffer(), :limit=>true)) == "1×ℵ₀ adjoint(::BiInfUnitRange{$Int}) with eltype Int64 with indices Base.OneTo(1)×BiInfUnitRange():\n … -6 -5 -4 -3 -2 -1 0 1 2 3 … " + @test stringmime("text/plain", r'; context= IOContext(IOBuffer(), :limit=>true)) == "1×ℵ₀ adjoint(::BiInfUnitRange{$Int}) with eltype $Int with indices Base.OneTo(1)×BiInfUnitRange():\n … -6 -5 -4 -3 -2 -1 0 1 2 3 … " - # _BandedMatrix( + @test stringmime("text/plain", r * r'; context= IOContext(IOBuffer(), :limit=>true)) == "(ℵ₀-element BiInfUnitRange{$Int} with indices BiInfUnitRange()) .* (1×ℵ₀ adjoint(::BiInfUnitRange{$Int}) with eltype $Int with indices Base.OneTo(1)×BiInfUnitRange()) with indices BiInfUnitRange()×BiInfUnitRange():\n ⋮ ⋮ ⋱ \n 30 25 20 15 10 5 0 -5 … \n 24 20 16 12 8 4 0 -4 \n 18 15 12 9 6 3 0 -3 \n 12 10 8 6 4 2 0 -2 \n 6 5 4 3 2 1 0 -1 \n 0 0 0 0 0 0 0 0 … \n -6 -5 -4 -3 -2 -1 0 1 \n -12 -10 -8 -6 -4 -2 0 2 \n -18 -15 -12 -9 -6 -3 0 3 \n -24 -20 -16 -12 -8 -4 0 4 \n -30 -25 -20 -15 -10 -5 0 5 … \n ⋮ ⋮ ⋱ " end \ No newline at end of file From fd8ce619c52d1f71379a1e28a3497f0488c696dc Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sun, 21 Dec 2025 20:46:14 +0000 Subject: [PATCH 11/12] increase cov --- src/biinfrange.jl | 9 +++++++-- test/test_biinfrange.jl | 27 ++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/biinfrange.jl b/src/biinfrange.jl index 182bbb3..2364e33 100644 --- a/src/biinfrange.jl +++ b/src/biinfrange.jl @@ -7,8 +7,8 @@ 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) +AbstractArray{T}(::BiInfUnitRange) where T<:Real = BiInfUnitRange{T}() +AbstractVector{T}(::BiInfUnitRange) where T<:Real = BiInfUnitRange{T}() unitrange(a::BiInfUnitRange) = a Base.has_offset_axes(::BiInfUnitRange) = true @@ -18,6 +18,11 @@ function getindex(x::BiInfUnitRange, i::PosInfinity) isinf(length(x)) || throw(BoundsError(x,y)) ℵ₀ end +function getindex(x::BiInfUnitRange, i::Infinity) + isinf(length(x)) || throw(BoundsError(x,y)) + ℵ₀ +end + getindex(v::BiInfUnitRange{T}, i::RealInfinity) where T = i axes(::BiInfUnitRange) = (BiInfUnitRange(),) first(::BiInfUnitRange) = -∞ diff --git a/test/test_biinfrange.jl b/test/test_biinfrange.jl index 5c077c5..5f0fcdb 100644 --- a/test/test_biinfrange.jl +++ b/test/test_biinfrange.jl @@ -1,11 +1,36 @@ -using InfiniteArrays, BandedMatrices, Base64, Test +using InfiniteArrays, Base64, Test using InfiniteArrays: BiInfUnitRange @testset "-∞:∞" begin r = BiInfUnitRange() + + @test AbstractArray{Int}(r) ≡ AbstractVector{Int}(r) ≡ r + @test r[-∞] ≡ -∞ + @test r[∞] ≡ r[ℵ₀] ≡ ℵ₀ + + @test r[-3:3] ≡ -3:3 + @test stringmime("text/plain", r) == "BiInfUnitRange()" + @test Fill(1, (r,))[-5] == 1 @test exp.(r)[-3] == exp(-3) + + + @test stringmime("text/plain", r * (1:10)'; context= IOContext(IOBuffer(), :limit=>true)) == "(ℵ₀-element BiInfUnitRange{$Int} with indices BiInfUnitRange()) .* (1×10 adjoint(::UnitRange{$Int}) with eltype $Int) with indices BiInfUnitRange()×Base.OneTo(10):\n ⋮ ⋮ \n -5 -10 -15 -20 -25 -30 -35 -40 -45 -50\n -4 -8 -12 -16 -20 -24 -28 -32 -36 -40\n -3 -6 -9 -12 -15 -18 -21 -24 -27 -30\n -2 -4 -6 -8 -10 -12 -14 -16 -18 -20\n -1 -2 -3 -4 -5 -6 -7 -8 -9 -10\n \e[1m 0 0 0 0 0 0 0 0 0 0\e[0m\n 1 2 3 4 5 6 7 8 9 10\n 2 4 6 8 10 12 14 16 18 20\n 3 6 9 12 15 18 21 24 27 30\n 4 8 12 16 20 24 28 32 36 40\n 5 10 15 20 25 30 35 40 45 50\n ⋮ ⋮ " + @test stringmime("text/plain", r * (1:1000)'; context= IOContext(IOBuffer(), :limit=>true)) == "(ℵ₀-element BiInfUnitRange{$Int} with indices BiInfUnitRange()) .* (1×1000 adjoint(::UnitRange{$Int}) with eltype $Int) with indices BiInfUnitRange()×Base.OneTo(1000): + -5 -10 -15 -20 -25 -30 -35 -40 … -4980 -4985 -4990 -4995 -5000 + -4 -8 -12 -16 -20 -24 -28 -32 -3984 -3988 -3992 -3996 -4000 + -3 -6 -9 -12 -15 -18 -21 -24 -2988 -2991 -2994 -2997 -3000 + -2 -4 -6 -8 -10 -12 -14 -16 -1992 -1994 -1996 -1998 -2000 + -1 -2 -3 -4 -5 -6 -7 -8 -996 -997 -998 -999 -1000 + 0 0 0 0 0 0 0 0 … 0 0 0 0 0 + 1 2 3 4 5 6 7 8 996 997 998 999 1000 + 2 4 6 8 10 12 14 16 1992 1994 1996 1998 2000 + 3 6 9 12 15 18 21 24 2988 2991 2994 2997 3000 + 4 8 12 16 20 24 28 32 3984 3988 3992 3996 4000 + 5 10 15 20 25 30 35 40 … 4980 4985 4990 4995 5000 + ⋮ ⋮ ⋱ ⋮ " + @test stringmime("text/plain", r.^2; context= IOContext(IOBuffer(), :limit=>true)) == "(ℵ₀-element BiInfUnitRange{$Int} with indices BiInfUnitRange()) .^ 2 with indices BiInfUnitRange():\n ⋮\n 25\n 16\n 9\n 4\n 1\n \e[1m 0\e[0m\n 1\n 4\n 9\n 16\n 25\n ⋮" @test isassigned(r', 1,-12) From 40042eef88a4b42384cf0d62fed61ceb79dea972 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sun, 21 Dec 2025 21:30:51 +0000 Subject: [PATCH 12/12] v0.15.11 --- Project.toml | 2 +- test/test_biinfrange.jl | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Project.toml b/Project.toml index 3c1423b..adb199d 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "InfiniteArrays" uuid = "4858937d-0d70-526a-a4dd-2d5cb5dd786c" -version = "0.15.10" +version = "0.15.11" [deps] ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" diff --git a/test/test_biinfrange.jl b/test/test_biinfrange.jl index 5f0fcdb..67b094a 100644 --- a/test/test_biinfrange.jl +++ b/test/test_biinfrange.jl @@ -3,19 +3,22 @@ using InfiniteArrays: BiInfUnitRange @testset "-∞:∞" begin r = BiInfUnitRange() - + @test AbstractArray{Int}(r) ≡ AbstractVector{Int}(r) ≡ r + @test Base.has_offset_axes(r) + @test r[-∞] ≡ -∞ @test r[∞] ≡ r[ℵ₀] ≡ ℵ₀ - @test r[-3:3] ≡ -3:3 - + + + @test stringmime("text/plain", r) == "BiInfUnitRange()" - + @test Fill(1, (r,))[-5] == 1 @test exp.(r)[-3] == exp(-3) - - + + @test stringmime("text/plain", r * (1:10)'; context= IOContext(IOBuffer(), :limit=>true)) == "(ℵ₀-element BiInfUnitRange{$Int} with indices BiInfUnitRange()) .* (1×10 adjoint(::UnitRange{$Int}) with eltype $Int) with indices BiInfUnitRange()×Base.OneTo(10):\n ⋮ ⋮ \n -5 -10 -15 -20 -25 -30 -35 -40 -45 -50\n -4 -8 -12 -16 -20 -24 -28 -32 -36 -40\n -3 -6 -9 -12 -15 -18 -21 -24 -27 -30\n -2 -4 -6 -8 -10 -12 -14 -16 -18 -20\n -1 -2 -3 -4 -5 -6 -7 -8 -9 -10\n \e[1m 0 0 0 0 0 0 0 0 0 0\e[0m\n 1 2 3 4 5 6 7 8 9 10\n 2 4 6 8 10 12 14 16 18 20\n 3 6 9 12 15 18 21 24 27 30\n 4 8 12 16 20 24 28 32 36 40\n 5 10 15 20 25 30 35 40 45 50\n ⋮ ⋮ " @test stringmime("text/plain", r * (1:1000)'; context= IOContext(IOBuffer(), :limit=>true)) == "(ℵ₀-element BiInfUnitRange{$Int} with indices BiInfUnitRange()) .* (1×1000 adjoint(::UnitRange{$Int}) with eltype $Int) with indices BiInfUnitRange()×Base.OneTo(1000): -5 -10 -15 -20 -25 -30 -35 -40 … -4980 -4985 -4990 -4995 -5000 @@ -30,11 +33,11 @@ using InfiniteArrays: BiInfUnitRange 4 8 12 16 20 24 28 32 3984 3988 3992 3996 4000 5 10 15 20 25 30 35 40 … 4980 4985 4990 4995 5000 ⋮ ⋮ ⋱ ⋮ " - + @test stringmime("text/plain", r.^2; context= IOContext(IOBuffer(), :limit=>true)) == "(ℵ₀-element BiInfUnitRange{$Int} with indices BiInfUnitRange()) .^ 2 with indices BiInfUnitRange():\n ⋮\n 25\n 16\n 9\n 4\n 1\n \e[1m 0\e[0m\n 1\n 4\n 9\n 16\n 25\n ⋮" - + @test isassigned(r', 1,-12) @test stringmime("text/plain", r'; context= IOContext(IOBuffer(), :limit=>true)) == "1×ℵ₀ adjoint(::BiInfUnitRange{$Int}) with eltype $Int with indices Base.OneTo(1)×BiInfUnitRange():\n … -6 -5 -4 -3 -2 -1 0 1 2 3 … " - + @test stringmime("text/plain", r * r'; context= IOContext(IOBuffer(), :limit=>true)) == "(ℵ₀-element BiInfUnitRange{$Int} with indices BiInfUnitRange()) .* (1×ℵ₀ adjoint(::BiInfUnitRange{$Int}) with eltype $Int with indices Base.OneTo(1)×BiInfUnitRange()) with indices BiInfUnitRange()×BiInfUnitRange():\n ⋮ ⋮ ⋱ \n 30 25 20 15 10 5 0 -5 … \n 24 20 16 12 8 4 0 -4 \n 18 15 12 9 6 3 0 -3 \n 12 10 8 6 4 2 0 -2 \n 6 5 4 3 2 1 0 -1 \n 0 0 0 0 0 0 0 0 … \n -6 -5 -4 -3 -2 -1 0 1 \n -12 -10 -8 -6 -4 -2 0 2 \n -18 -15 -12 -9 -6 -3 0 3 \n -24 -20 -16 -12 -8 -4 0 4 \n -30 -25 -20 -15 -10 -5 0 5 … \n ⋮ ⋮ ⋱ " end \ No newline at end of file