Skip to content

Commit

Permalink
Implement InfRandMatrix
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielVandH committed Jun 30, 2024
1 parent 8865985 commit ea3b3e6
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 6 deletions.
30 changes: 26 additions & 4 deletions src/infrand.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ function InfRandVector(rng=default_rng(), dist=Float64)
_rng = copy(rng)
return InfRandVector{T,typeof(dist),typeof(_rng)}(_rng, dist, T[], 0)
end
Base.size(::InfRandVector) = (ℵ₀,)
Base.axes(::InfRandVector) = (1:ℵ₀,)
Base.length(::InfRandVector) = ℵ₀
size(::InfRandVector) = (ℵ₀,)
axes(::InfRandVector) = (1:ℵ₀,)
length(::InfRandVector) = ℵ₀
function resizedata!(seq::InfRandVector, inds)
newlen = maximum(inds)
curlen = length(seq.data)
Expand All @@ -61,4 +61,26 @@ function resizedata!(seq::InfRandVector, inds)
end
seq.datasize = newlen
return seq
end
end

"""
InfRandMatrix([rng=default_rng()], n; dist=Float64])
Represents a random infinite matrix with `n` rows. The random number generator
can be specified by the first argument `rng`, which defaults to `Random.default_rng()`, and the number of
rows is given by the `n` argument. The `dist` keyword argument (default `Float64`)
can be used to specify the distribution to sample from.
"""
struct InfRandMatrix{T, S <: InfRandVector{T}} <: LazyMatrix{T}
seq::S
n::Int
end
InfRandMatrix(n::Int; dist=Float64) = InfRandMatrix(default_rng(), n; dist)
InfRandMatrix(rng, n::Int; dist=Float64) = InfRandMatrix(InfRandVector(rng, dist), n)
function Base.getindex(A::InfRandMatrix, i::Int, j::Int)
((i < 1) || (i > A.n) || (j < 0)) && throw(BoundsError(A, (i, j)))
lin = (j - 1) * A.n + i
return A.seq[lin]
end
size(A::InfRandMatrix) = (A.n, ∞)

38 changes: 36 additions & 2 deletions test/test_infrand.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,47 @@
seq = InfiniteArrays.InfRandVector(rng, Float16)
rng2 = MersenneTwister(123)
@test seq[1:10000] == [rand(rng2, Float16) for _ in 1:10000]
end
end

@testset "Distributions.jl" begin
@testset "Distributions.jl" begin
dist = Normal(0.3, 1.7) # do Normal{Float32} for example if you want that number type
rng = Xoshiro(5)
seq = InfiniteArrays.InfRandVector(rng, dist)
rng2 = Xoshiro(5)
@test seq[1:100] == [0.3 + 1.7randn(rng2) for _ in 1:100]
end
end

@testset "InfRandMatrix" begin
@testset "Default constructor" begin
Random.seed!(123)
A = InfiniteArrays.InfRandMatrix(5)
@test size(A) == (5, ∞)
@test axes(A) == (1:5, 1:∞)
val = A[1, 1]
@inferred A[5, 5]
@test A[1:3, 1:100] == A[1:3, 1:100]
@test_throws BoundsError A[0, 1]
Random.seed!(123)
_A = [rand() for _ in 1:5, _ in 1:1000]
@test _A == A[1:5, 1:1000]
@test (A+A)[1:5, 1:1000] 2_A
@test (A'+A')[1:1000, 1:5] 2_A'
@test A[11] A.seq[11] A[1, 3]
end

@testset "Providing an RNG and a distribution" begin
rng = MersenneTwister(123)
seq = InfiniteArrays.InfRandMatrix(rng, 10; dist=Float16)
rng2 = MersenneTwister(123)
@test seq[1:10000] == [rand(rng2, Float16) for _ in 1:10000]
end

@testset "Distributions.jl" begin
dist = Normal(0.3, 1.7)
rng = Xoshiro(5)
seq = InfiniteArrays.InfRandMatrix(rng, 2; dist)
rng2 = Xoshiro(5)
@test seq[1:1000] == [0.3 + 1.7randn(rng2) for _ in 1:1000]
end
end

0 comments on commit ea3b3e6

Please sign in to comment.