forked from JuliaArrays/InfiniteArrays.jl
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Infinite random sequences (JuliaArrays#181)
* InfRandVector * Remove export * prefix * add prefix to docstring example * add prefix to docstring example
- Loading branch information
1 parent
c45ae5f
commit 8865985
Showing
5 changed files
with
120 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
""" | ||
InfRandVector([rng=default_rng()], [dist=Float64]) | ||
Represents a random infinite sequence. The random number generator can be specified | ||
by the first argument `rng`, which defaults to `Random.default_rng()`, and the distribution | ||
to generate from can be specified using the `dist` argument, which defaults to `Float64`. | ||
```julia-repl | ||
julia> using InfiniteArrays | ||
julia> seq = InfiniteArrays.InfRandVector(); | ||
julia> seq[1] | ||
0.6947847847152157 | ||
julia> seq[1:5] | ||
5-element Vector{Float64}: | ||
0.6947847847152157 | ||
0.49859004150722164 | ||
0.31559745572937126 | ||
0.5338596092137163 | ||
0.14792462133894646 | ||
julia> using Distributions, Random | ||
julia> seq = InfiniteArrays.InfRandVector(MersenneTwister(123), Normal(0.3, 1.7)) | ||
ℵ₀-element InfRandVector{Float64, Normal{Float64}, MersenneTwister} with indices 1:∞: | ||
2.3234553976766703 | ||
3.7819055032417075 | ||
2.242506534874238 | ||
1.0810065546920364 | ||
-0.3743544348018791 | ||
-0.8300113268258689 | ||
1.967645305489507 | ||
⋮ | ||
``` | ||
""" | ||
mutable struct InfRandVector{T,D,RNG} <: AbstractCachedVector{T} | ||
const rng::RNG | ||
const dist::D | ||
const data::Vector{T} | ||
datasize::Int | ||
end | ||
function InfRandVector(rng=default_rng(), dist=Float64) | ||
T = typeof(rand(copy(rng), dist)) | ||
_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) = ℵ₀ | ||
function resizedata!(seq::InfRandVector, inds) | ||
newlen = maximum(inds) | ||
curlen = length(seq.data) | ||
newlen > curlen || return seq | ||
resize!(seq.data, newlen) | ||
# rand!(seq.rng, view(seq.data, curlen+1:newlen), seq.dist) | ||
# ^ rand() is not actually sequential.. rand(Random.seed!(123), 1000) ≠ (rng = Random.seed!(123); [rand(rng) for _ in 1:1000]) | ||
for i in (curlen+1):newlen | ||
seq.data[i] = rand(seq.rng, seq.dist) | ||
end | ||
seq.datasize = newlen | ||
return seq | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
@testset "InfRandVector" begin | ||
@testset "Default constructor" begin | ||
Random.seed!(123) | ||
seq = InfiniteArrays.InfRandVector() | ||
val = seq[1] | ||
@test seq[1] == val # constant | ||
@test seq[1:10000] == seq[1:10000] | ||
@test seq[1] == val # didn't change after resizing | ||
@inferred seq[1] | ||
Random.seed!(123) | ||
_seq = [rand() for _ in 1:1000] | ||
@test seq[1:1000] == _seq[1:1000] | ||
@test size(seq) == (ℵ₀,) | ||
@test length(seq) == ℵ₀ | ||
@test axes(seq) == (1:ℵ₀,) | ||
end | ||
|
||
@testset "Providing an RNG and a distribution" begin | ||
rng = MersenneTwister(123) | ||
seq = InfiniteArrays.InfRandVector(rng, 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) # 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 |