|
1 | 1 | # Infinite Arrays implementation from
|
2 | 2 | # https://github.com/JuliaLang/julia/blob/master/test/testhelpers/InfiniteArrays.jl
|
3 | 3 | module InfiniteArrays
|
4 |
| - using Infinities |
5 |
| - export OneToInf |
| 4 | + using Infinities, LinearAlgebra, Random |
| 5 | + using ..ArrayLayouts: ArrayLayouts, LayoutVector, LayoutMatrix, Mul, DenseColumnMajor |
| 6 | + export OneToInf, |
| 7 | + InfSymTridiagonal, |
| 8 | + InfTridiagonal, |
| 9 | + InfBidiagonal, |
| 10 | + InfUnitUpperTriangular, |
| 11 | + InfUnitLowerTriangular, |
| 12 | + InfUpperTriangular, |
| 13 | + InfLowerTriangular, |
| 14 | + InfDiagonal |
6 | 15 |
|
7 | 16 | abstract type AbstractInfUnitRange{T<:Real} <: AbstractUnitRange{T} end
|
8 | 17 | Base.length(r::AbstractInfUnitRange) = ℵ₀
|
@@ -48,4 +57,69 @@ module InfiniteArrays
|
48 | 57 | @boundscheck checkbounds(v, first(i))
|
49 | 58 | v[first(i)]:ℵ₀
|
50 | 59 | end
|
| 60 | + |
| 61 | + ## Methods for testing infinite arrays |
| 62 | + struct InfVec{RNG} <: LayoutVector{Float64} # show is broken for InfVec |
| 63 | + rng::RNG |
| 64 | + data::Vector{Float64} |
| 65 | + end |
| 66 | + InfVec() = InfVec(copy(Random.seed!(Random.default_rng(), rand(UInt64))), Float64[]) |
| 67 | + function resizedata!(v::InfVec, i) |
| 68 | + n = length(v.data) |
| 69 | + i ≤ n && return v |
| 70 | + resize!(v.data, i) |
| 71 | + for j in (n+1):i |
| 72 | + v[j] = rand(v.rng) |
| 73 | + end |
| 74 | + return v |
| 75 | + end |
| 76 | + Base.getindex(v::InfVec, i::Int) = (resizedata!(v, i); v.data[i]) |
| 77 | + Base.setindex!(v::InfVec, r, i::Int) = setindex!(v.data, r, i) |
| 78 | + Base.size(v::InfVec) = (ℵ₀,) |
| 79 | + Base.axes(v::InfVec) = (OneToInf(),) |
| 80 | + ArrayLayouts.MemoryLayout(::Type{<:InfVec}) = DenseColumnMajor() |
| 81 | + Base.similar(v::InfVec, ::Type{T}, ::Tuple{OneToInf{Int}}) where {T} = InfVec() |
| 82 | + Base.copy(v::InfVec) = InfVec(copy(v.rng), copy(v.data)) |
| 83 | + |
| 84 | + struct InfMat{RNG} <: LayoutMatrix{Float64} # show is broken for InfMat |
| 85 | + vec::InfVec{RNG} |
| 86 | + end |
| 87 | + InfMat() = InfMat(InfVec()) |
| 88 | + function diagtrav_idx(i, j) |
| 89 | + band = i + j - 1 |
| 90 | + nelm = (band * (band - 1)) ÷ 2 |
| 91 | + return nelm + i |
| 92 | + end |
| 93 | + Base.getindex(A::InfMat, i::Int, j::Int) = A.vec[diagtrav_idx(i, j)] |
| 94 | + Base.setindex!(A::InfMat, r, i::Int, j::Int) = setindex!(A.vec, r, diagtrav_idx(i, j)) |
| 95 | + Base.size(A::InfMat) = (ℵ₀, ℵ₀) |
| 96 | + Base.axes(v::InfMat) = (OneToInf(), OneToInf()) |
| 97 | + ArrayLayouts.MemoryLayout(::Type{<:InfMat}) = DenseColumnMajor() |
| 98 | + Base.copy(A::InfMat) = InfMat(copy(A.vec)) |
| 99 | + |
| 100 | + const InfSymTridiagonal = SymTridiagonal{Float64,<:InfVec} |
| 101 | + const InfTridiagonal = Tridiagonal{Float64,<:InfVec} |
| 102 | + const InfBidiagonal = Bidiagonal{Float64,<:InfVec} |
| 103 | + const InfUnitUpperTriangular = UnitUpperTriangular{Float64,<:InfMat} |
| 104 | + const InfUnitLowerTriangular = UnitLowerTriangular{Float64,<:InfMat} |
| 105 | + const InfUpperTriangular = UpperTriangular{Float64,<:InfMat} |
| 106 | + const InfLowerTriangular = LowerTriangular{Float64,<:InfMat} |
| 107 | + const InfDiagonal = Diagonal{Float64,<:InfVec} |
| 108 | + InfSymTridiagonal() = SymTridiagonal(InfVec(), InfVec()) |
| 109 | + InfTridiagonal() = Tridiagonal(InfVec(), InfVec(), InfVec()) |
| 110 | + InfBidiagonal(uplo) = Bidiagonal(InfVec(), InfVec(), uplo) |
| 111 | + InfUnitUpperTriangular() = UnitUpperTriangular(InfMat()) |
| 112 | + InfUnitLowerTriangular() = UnitLowerTriangular(InfMat()) |
| 113 | + InfUpperTriangular() = UpperTriangular(InfMat()) |
| 114 | + InfLowerTriangular() = LowerTriangular(InfMat()) |
| 115 | + InfDiagonal() = Diagonal(InfVec()) |
| 116 | + Base.copy(D::InfDiagonal) = Diagonal(copy(D.diag)) |
| 117 | + |
| 118 | + # Without LazyArrays we have no access to the lazy machinery, so we must define copy(::Mul) to leave mul(A, B) as a lazy Mul(A, B) |
| 119 | + const InfNamedMatrix = Union{InfSymTridiagonal,InfTridiagonal,InfBidiagonal, |
| 120 | + InfUnitUpperTriangular,InfUnitLowerTriangular, |
| 121 | + InfUpperTriangular,InfLowerTriangular, |
| 122 | + InfDiagonal} |
| 123 | + const InfMul{L1,L2} = Mul{L1,L2,<:InfNamedMatrix,<:InfNamedMatrix} |
| 124 | + Base.copy(M::InfMul{L1,L2}) where {L1,L2} = Mul{L1,L2}(copy(M.A), copy(M.B)) |
51 | 125 | end
|
0 commit comments