Skip to content

Commit ea3b3e6

Browse files
committed
Implement InfRandMatrix
1 parent 8865985 commit ea3b3e6

File tree

2 files changed

+62
-6
lines changed

2 files changed

+62
-6
lines changed

src/infrand.jl

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ function InfRandVector(rng=default_rng(), dist=Float64)
4646
_rng = copy(rng)
4747
return InfRandVector{T,typeof(dist),typeof(_rng)}(_rng, dist, T[], 0)
4848
end
49-
Base.size(::InfRandVector) = (ℵ₀,)
50-
Base.axes(::InfRandVector) = (1:ℵ₀,)
51-
Base.length(::InfRandVector) = ℵ₀
49+
size(::InfRandVector) = (ℵ₀,)
50+
axes(::InfRandVector) = (1:ℵ₀,)
51+
length(::InfRandVector) = ℵ₀
5252
function resizedata!(seq::InfRandVector, inds)
5353
newlen = maximum(inds)
5454
curlen = length(seq.data)
@@ -61,4 +61,26 @@ function resizedata!(seq::InfRandVector, inds)
6161
end
6262
seq.datasize = newlen
6363
return seq
64-
end
64+
end
65+
66+
"""
67+
InfRandMatrix([rng=default_rng()], n; dist=Float64])
68+
69+
Represents a random infinite matrix with `n` rows. The random number generator
70+
can be specified by the first argument `rng`, which defaults to `Random.default_rng()`, and the number of
71+
rows is given by the `n` argument. The `dist` keyword argument (default `Float64`)
72+
can be used to specify the distribution to sample from.
73+
"""
74+
struct InfRandMatrix{T, S <: InfRandVector{T}} <: LazyMatrix{T}
75+
seq::S
76+
n::Int
77+
end
78+
InfRandMatrix(n::Int; dist=Float64) = InfRandMatrix(default_rng(), n; dist)
79+
InfRandMatrix(rng, n::Int; dist=Float64) = InfRandMatrix(InfRandVector(rng, dist), n)
80+
function Base.getindex(A::InfRandMatrix, i::Int, j::Int)
81+
((i < 1) || (i > A.n) || (j < 0)) && throw(BoundsError(A, (i, j)))
82+
lin = (j - 1) * A.n + i
83+
return A.seq[lin]
84+
end
85+
size(A::InfRandMatrix) = (A.n, ∞)
86+

test/test_infrand.jl

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,47 @@
2020
seq = InfiniteArrays.InfRandVector(rng, Float16)
2121
rng2 = MersenneTwister(123)
2222
@test seq[1:10000] == [rand(rng2, Float16) for _ in 1:10000]
23-
end
23+
end
2424

25-
@testset "Distributions.jl" begin
25+
@testset "Distributions.jl" begin
2626
dist = Normal(0.3, 1.7) # do Normal{Float32} for example if you want that number type
2727
rng = Xoshiro(5)
2828
seq = InfiniteArrays.InfRandVector(rng, dist)
2929
rng2 = Xoshiro(5)
3030
@test seq[1:100] == [0.3 + 1.7randn(rng2) for _ in 1:100]
3131
end
32+
end
33+
34+
@testset "InfRandMatrix" begin
35+
@testset "Default constructor" begin
36+
Random.seed!(123)
37+
A = InfiniteArrays.InfRandMatrix(5)
38+
@test size(A) == (5, ∞)
39+
@test axes(A) == (1:5, 1:∞)
40+
val = A[1, 1]
41+
@inferred A[5, 5]
42+
@test A[1:3, 1:100] == A[1:3, 1:100]
43+
@test_throws BoundsError A[0, 1]
44+
Random.seed!(123)
45+
_A = [rand() for _ in 1:5, _ in 1:1000]
46+
@test _A == A[1:5, 1:1000]
47+
@test (A+A)[1:5, 1:1000] 2_A
48+
@test (A'+A')[1:1000, 1:5] 2_A'
49+
@test A[11] A.seq[11] A[1, 3]
50+
end
51+
52+
@testset "Providing an RNG and a distribution" begin
53+
rng = MersenneTwister(123)
54+
seq = InfiniteArrays.InfRandMatrix(rng, 10; dist=Float16)
55+
rng2 = MersenneTwister(123)
56+
@test seq[1:10000] == [rand(rng2, Float16) for _ in 1:10000]
57+
end
58+
59+
@testset "Distributions.jl" begin
60+
dist = Normal(0.3, 1.7)
61+
rng = Xoshiro(5)
62+
seq = InfiniteArrays.InfRandMatrix(rng, 2; dist)
63+
rng2 = Xoshiro(5)
64+
@test seq[1:1000] == [0.3 + 1.7randn(rng2) for _ in 1:1000]
65+
end
3266
end

0 commit comments

Comments
 (0)