From 38c22a4c7f32bcc19ef2a06703197826cc31efe8 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Wed, 29 Nov 2023 17:58:09 +0530 Subject: [PATCH 1/4] Define axes for Accumulate --- Project.toml | 2 +- src/lazyoperations.jl | 1 + test/cachetests.jl | 6 ++++ test/infinitearrays.jl | 67 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 test/infinitearrays.jl diff --git a/Project.toml b/Project.toml index 235ee341..036d0dc7 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "LazyArrays" uuid = "5078a376-72f3-5289-bfd5-ec5146d43c02" -version = "1.8.2" +version = "1.8.3" [deps] ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" diff --git a/src/lazyoperations.jl b/src/lazyoperations.jl index e0b37c6a..6ff3fcd8 100644 --- a/src/lazyoperations.jl +++ b/src/lazyoperations.jl @@ -428,6 +428,7 @@ Cumsum(v::AbstractArray; dims::Integer=1) = Accumulate(+, v; dims=dims) IndexStyle(::Type{<:Accumulate{<:Any,1}}) = IndexLinear() size(Q::Accumulate) = size(Q.v) +axes(Q::Accumulate) = axes(Q.v) copy(Q::Accumulate) = Accumulate(Q.op, copy(Q.data), copy(Q.v), Q.dims, Q.datasize) diff --git a/test/cachetests.jl b/test/cachetests.jl index 2b57914d..da83dcb5 100644 --- a/test/cachetests.jl +++ b/test/cachetests.jl @@ -2,6 +2,8 @@ using LazyArrays, FillArrays, LinearAlgebra, ArrayLayouts, StaticArrays, SparseA import LazyArrays: CachedArray, CachedMatrix, CachedVector, PaddedLayout, CachedLayout, resizedata!, zero!, CachedAbstractArray, CachedAbstractVector, CachedAbstractMatrix, AbstractCachedArray, AbstractCachedMatrix +include("infinitearrays.jl") + @testset "Cache" begin @testset "basics" begin A = 1:10 @@ -172,6 +174,10 @@ import LazyArrays: CachedArray, CachedMatrix, CachedVector, PaddedLayout, Cached c = cache(Fill(1,10)) @test c[2:3] isa LazyArrays.CachedVector{Int,Vector{Int},Fill{Int,1,Tuple{Base.OneTo{Int}}}} @test c[[2,4,6]] isa LazyArrays.CachedVector{Int,Vector{Int},Fill{Int,1,Tuple{Base.OneTo{Int}}}} + + F = Fill(2, InfiniteArrays.Infinity()) + C = cumsum(cache(F)) + @test axes(C) == (InfiniteArrays.OneToInf(),) end @testset "linalg" begin diff --git a/test/infinitearrays.jl b/test/infinitearrays.jl new file mode 100644 index 00000000..0b6f62db --- /dev/null +++ b/test/infinitearrays.jl @@ -0,0 +1,67 @@ +# Infinite Arrays implementation from +# https://github.com/JuliaLang/julia/blob/master/test/testhelpers/InfiniteArrays.jl +module InfiniteArrays + export OneToInf, Infinity + + """ + Infinity() + Represents infinite cardinality. Note that `Infinity <: Integer` to support + being treated as an index. + """ + struct Infinity <: Integer end + + Base.:(==)(::Infinity, ::Int) = false + Base.:(==)(::Int, ::Infinity) = false + Base.:(<)(::Int, ::Infinity) = true + Base.:(<)(::Infinity, ::Int) = false + Base.:(≤)(::Int, ::Infinity) = true + Base.:(≤)(::Infinity, ::Int) = false + Base.:(≤)(::Infinity, ::Infinity) = true + Base.:(-)(::Infinity, ::Int) = Infinity() + Base.:(+)(::Infinity, ::Int) = Infinity() + Base.:(:)(::Infinity, ::Infinity) = 1:0 + + Base.:(+)(::Integer, ::Infinity) = Infinity() + Base.:(+)(::Infinity, ::Integer) = Infinity() + Base.:(*)(::Integer, ::Infinity) = Infinity() + Base.:(*)(::Infinity, ::Integer) = Infinity() + + Base.isinf(::Infinity) = true + + abstract type AbstractInfUnitRange{T<:Real} <: AbstractUnitRange{T} end + Base.length(r::AbstractInfUnitRange) = Infinity() + Base.size(r::AbstractInfUnitRange) = (Infinity(),) + Base.unitrange(r::AbstractInfUnitRange) = InfUnitRange(r) + Base.last(r::AbstractInfUnitRange) = Infinity() + Base.axes(r::AbstractInfUnitRange) = (OneToInf(),) + + Base.IteratorSize(::Type{<:AbstractInfUnitRange}) = Base.IsInfinite() + + """ + OneToInf(n) + Define an `AbstractInfUnitRange` that behaves like `1:∞`, with the added + distinction that the limits are guaranteed (by the type system) to + be 1 and ∞. + """ + struct OneToInf{T<:Integer} <: AbstractInfUnitRange{T} end + + OneToInf() = OneToInf{Int}() + + Base.axes(r::OneToInf) = (r,) + Base.first(r::OneToInf{T}) where {T} = oneunit(T) + Base.oneto(::Infinity) = OneToInf() + + struct InfUnitRange{T<:Real} <: AbstractInfUnitRange{T} + start::T + end + Base.first(r::InfUnitRange) = r.start + InfUnitRange(a::InfUnitRange) = a + InfUnitRange{T}(a::AbstractInfUnitRange) where T<:Real = InfUnitRange{T}(first(a)) + InfUnitRange(a::AbstractInfUnitRange{T}) where T<:Real = InfUnitRange{T}(first(a)) + unitrange(a::AbstractInfUnitRange) = InfUnitRange(a) + Base.:(:)(start::T, stop::Infinity) where {T<:Integer} = InfUnitRange{T}(start) + function getindex(v::InfUnitRange{T}, i::Integer) where T + @boundscheck i > 0 || Base.throw_boundserror(v, i) + convert(T, first(v) + i - 1) + end +end From 8cecd58eb7bfb6ff6b5bfe52a9ced1d74659418d Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Thu, 30 Nov 2023 23:31:41 +0530 Subject: [PATCH 2/4] Use Infinities --- Project.toml | 4 +++- test/cachetests.jl | 4 +++- test/infinitearrays.jl | 38 +++++--------------------------------- 3 files changed, 11 insertions(+), 35 deletions(-) diff --git a/Project.toml b/Project.toml index 036d0dc7..a3a6581b 100644 --- a/Project.toml +++ b/Project.toml @@ -23,6 +23,7 @@ ArrayLayouts = "1.4.1" Base64 = "1" FillArrays = "1.0" LinearAlgebra = "1" +Infinities = "0.1" MacroTools = "0.5" MatrixFactorizations = "1.0, 2.0" SparseArrays = "1" @@ -34,9 +35,10 @@ julia = "1.9" [extras] Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +Infinities = "e1ba4f0e-776d-440f-acd9-e1d2e9742647" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" [targets] -test = ["Aqua", "Base64", "StaticArrays", "Tracker", "Test"] +test = ["Aqua", "Base64", "StaticArrays", "Tracker", "Test", "Infinities"] diff --git a/test/cachetests.jl b/test/cachetests.jl index da83dcb5..334027d5 100644 --- a/test/cachetests.jl +++ b/test/cachetests.jl @@ -3,6 +3,8 @@ import LazyArrays: CachedArray, CachedMatrix, CachedVector, PaddedLayout, Cached CachedAbstractArray, CachedAbstractVector, CachedAbstractMatrix, AbstractCachedArray, AbstractCachedMatrix include("infinitearrays.jl") +using .InfiniteArrays +using Infinities @testset "Cache" begin @testset "basics" begin @@ -175,7 +177,7 @@ include("infinitearrays.jl") @test c[2:3] isa LazyArrays.CachedVector{Int,Vector{Int},Fill{Int,1,Tuple{Base.OneTo{Int}}}} @test c[[2,4,6]] isa LazyArrays.CachedVector{Int,Vector{Int},Fill{Int,1,Tuple{Base.OneTo{Int}}}} - F = Fill(2, InfiniteArrays.Infinity()) + F = Fill(2, ℵ₀) C = cumsum(cache(F)) @test axes(C) == (InfiniteArrays.OneToInf(),) end diff --git a/test/infinitearrays.jl b/test/infinitearrays.jl index 0b6f62db..753561a0 100644 --- a/test/infinitearrays.jl +++ b/test/infinitearrays.jl @@ -1,38 +1,12 @@ # Infinite Arrays implementation from # https://github.com/JuliaLang/julia/blob/master/test/testhelpers/InfiniteArrays.jl module InfiniteArrays - export OneToInf, Infinity - - """ - Infinity() - Represents infinite cardinality. Note that `Infinity <: Integer` to support - being treated as an index. - """ - struct Infinity <: Integer end - - Base.:(==)(::Infinity, ::Int) = false - Base.:(==)(::Int, ::Infinity) = false - Base.:(<)(::Int, ::Infinity) = true - Base.:(<)(::Infinity, ::Int) = false - Base.:(≤)(::Int, ::Infinity) = true - Base.:(≤)(::Infinity, ::Int) = false - Base.:(≤)(::Infinity, ::Infinity) = true - Base.:(-)(::Infinity, ::Int) = Infinity() - Base.:(+)(::Infinity, ::Int) = Infinity() - Base.:(:)(::Infinity, ::Infinity) = 1:0 - - Base.:(+)(::Integer, ::Infinity) = Infinity() - Base.:(+)(::Infinity, ::Integer) = Infinity() - Base.:(*)(::Integer, ::Infinity) = Infinity() - Base.:(*)(::Infinity, ::Integer) = Infinity() - - Base.isinf(::Infinity) = true + using Infinities abstract type AbstractInfUnitRange{T<:Real} <: AbstractUnitRange{T} end - Base.length(r::AbstractInfUnitRange) = Infinity() - Base.size(r::AbstractInfUnitRange) = (Infinity(),) - Base.unitrange(r::AbstractInfUnitRange) = InfUnitRange(r) - Base.last(r::AbstractInfUnitRange) = Infinity() + Base.length(r::AbstractInfUnitRange) = ℵ₀ + Base.size(r::AbstractInfUnitRange) = (ℵ₀,) + Base.last(r::AbstractInfUnitRange) = ℵ₀ Base.axes(r::AbstractInfUnitRange) = (OneToInf(),) Base.IteratorSize(::Type{<:AbstractInfUnitRange}) = Base.IsInfinite() @@ -49,7 +23,6 @@ module InfiniteArrays Base.axes(r::OneToInf) = (r,) Base.first(r::OneToInf{T}) where {T} = oneunit(T) - Base.oneto(::Infinity) = OneToInf() struct InfUnitRange{T<:Real} <: AbstractInfUnitRange{T} start::T @@ -58,8 +31,7 @@ module InfiniteArrays InfUnitRange(a::InfUnitRange) = a InfUnitRange{T}(a::AbstractInfUnitRange) where T<:Real = InfUnitRange{T}(first(a)) InfUnitRange(a::AbstractInfUnitRange{T}) where T<:Real = InfUnitRange{T}(first(a)) - unitrange(a::AbstractInfUnitRange) = InfUnitRange(a) - Base.:(:)(start::T, stop::Infinity) where {T<:Integer} = InfUnitRange{T}(start) + Base.:(:)(start::T, stop::InfiniteCardinal{0}) where {T<:Integer} = InfUnitRange{T}(start) function getindex(v::InfUnitRange{T}, i::Integer) where T @boundscheck i > 0 || Base.throw_boundserror(v, i) convert(T, first(v) + i - 1) From b51b39f70be9205c90873ac0f2f1e1325e3f3f83 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Wed, 6 Dec 2023 00:32:08 +0530 Subject: [PATCH 3/4] Add methods to infinitearrays --- test/infinitearrays.jl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/infinitearrays.jl b/test/infinitearrays.jl index 753561a0..b2767ae9 100644 --- a/test/infinitearrays.jl +++ b/test/infinitearrays.jl @@ -24,6 +24,10 @@ module InfiniteArrays Base.axes(r::OneToInf) = (r,) Base.first(r::OneToInf{T}) where {T} = oneunit(T) + Base.oneto(::InfiniteCardinal{0}) = OneToInf() + + Base.axes(::AbstractInfUnitRange) = OneToInf() + struct InfUnitRange{T<:Real} <: AbstractInfUnitRange{T} start::T end @@ -32,8 +36,8 @@ module InfiniteArrays InfUnitRange{T}(a::AbstractInfUnitRange) where T<:Real = InfUnitRange{T}(first(a)) InfUnitRange(a::AbstractInfUnitRange{T}) where T<:Real = InfUnitRange{T}(first(a)) Base.:(:)(start::T, stop::InfiniteCardinal{0}) where {T<:Integer} = InfUnitRange{T}(start) - function getindex(v::InfUnitRange{T}, i::Integer) where T - @boundscheck i > 0 || Base.throw_boundserror(v, i) + function Base.getindex(v::InfUnitRange{T}, i::Integer) where T + checkbounds(v, i) convert(T, first(v) + i - 1) end end From 37b362d92bbca6c5c6f4e2ffee5d37acb6055049 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Wed, 6 Dec 2023 00:32:37 +0530 Subject: [PATCH 4/4] Fix axes --- test/infinitearrays.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/infinitearrays.jl b/test/infinitearrays.jl index b2767ae9..71ab3809 100644 --- a/test/infinitearrays.jl +++ b/test/infinitearrays.jl @@ -26,7 +26,7 @@ module InfiniteArrays Base.oneto(::InfiniteCardinal{0}) = OneToInf() - Base.axes(::AbstractInfUnitRange) = OneToInf() + Base.axes(::AbstractInfUnitRange) = (OneToInf(),) struct InfUnitRange{T<:Real} <: AbstractInfUnitRange{T} start::T