Skip to content

Commit 79158c3

Browse files
committed
add OpenClose, OpenOpen, CloseClose
1 parent ead5106 commit 79158c3

4 files changed

Lines changed: 84 additions & 7 deletions

File tree

src/RandomExtensions.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module RandomExtensions
22

3-
export make, Uniform, Normal, Exponential, CloseOpen, Rand, Bernoulli
3+
export make, Uniform, Normal, Exponential, CloseOpen, OpenClose, OpenOpen, CloseClose, Rand, Bernoulli
44

55
# re-exports from Random, which don't overlap with new functionality and not from misc.jl
66
export rand!, AbstractRNG, MersenneTwister, RandomDevice

src/distributions.jl

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,16 +155,39 @@ Exponential(θ::T) where {T<:AbstractFloat} = Exponentialθ(θ)
155155
## floats
156156

157157
abstract type FloatInterval{T<:AbstractFloat} <: Uniform{T} end
158-
abstract type CloseOpen{T<:AbstractFloat} <: FloatInterval{T} end
159158

160-
struct CloseOpen01{T<:AbstractFloat} <: CloseOpen{T} end # interval [0,1)
159+
abstract type CloseOpen{ T<:AbstractFloat} <: FloatInterval{T} end
160+
abstract type OpenClose{ T<:AbstractFloat} <: FloatInterval{T} end
161+
abstract type CloseClose{T<:AbstractFloat} <: FloatInterval{T} end
162+
abstract type OpenOpen{ T<:AbstractFloat} <: FloatInterval{T} end
163+
161164
struct CloseOpen12{T<:AbstractFloat} <: CloseOpen{T} end # interval [1,2)
162165

166+
struct CloseOpen01{ T<:AbstractFloat} <: CloseOpen{T} end # interval [0,1)
167+
struct OpenClose01{ T<:AbstractFloat} <: OpenClose{T} end # interval (0,1]
168+
struct CloseClose01{T<:AbstractFloat} <: CloseClose{T} end # interval [0,1]
169+
struct OpenOpen01{ T<:AbstractFloat} <: OpenOpen{T} end # interval (0,1)
170+
163171
struct CloseOpenAB{T<:AbstractFloat} <: CloseOpen{T} # interval [a,b)
164172
a::T
165173
b::T
166174
end
167175

176+
struct OpenCloseAB{T<:AbstractFloat} <: OpenClose{T} # interval (a,b]
177+
a::T
178+
b::T
179+
end
180+
181+
struct CloseCloseAB{T<:AbstractFloat} <: CloseClose{T} # interval [a,b]
182+
a::T
183+
b::T
184+
end
185+
186+
struct OpenOpenAB{T<:AbstractFloat} <: OpenOpen{T} # interval (a,b)
187+
a::T
188+
b::T
189+
end
190+
168191
const FloatInterval_64 = FloatInterval{Float64}
169192
const CloseOpen01_64 = CloseOpen01{Float64}
170193
const CloseOpen12_64 = CloseOpen12{Float64}
@@ -175,10 +198,29 @@ CloseOpen12(::Type{T}=Float64) where {T<:AbstractFloat} = CloseOpen12{T}()
175198
CloseOpen(::Type{T}=Float64) where {T<:AbstractFloat} = CloseOpen01{T}()
176199
CloseOpen(a::T, b::T) where {T<:AbstractFloat} = CloseOpenAB{T}(a, b)
177200

201+
OpenClose(::Type{T}=Float64) where {T<:AbstractFloat} = OpenClose01{T}()
202+
OpenClose(a::T, b::T) where {T<:AbstractFloat} = OpenCloseAB{T}(a, b)
203+
204+
CloseClose(::Type{T}=Float64) where {T<:AbstractFloat} = CloseClose01{T}()
205+
CloseClose(a::T, b::T) where {T<:AbstractFloat} = CloseCloseAB{T}(a, b)
206+
207+
OpenOpen(::Type{T}=Float64) where {T<:AbstractFloat} = OpenOpen01{T}()
208+
OpenOpen(a::T, b::T) where {T<:AbstractFloat} = OpenOpenAB{T}(a, b)
209+
178210
# convenience functions
211+
179212
CloseOpen(a, b) = CloseOpen(AbstractFloat(a), AbstractFloat(b))
180213
CloseOpen(a::AbstractFloat, b::AbstractFloat) = CloseOpen(promote(a, b)...)
181214

215+
OpenClose(a, b) = OpenClose(AbstractFloat(a), AbstractFloat(b))
216+
OpenClose(a::AbstractFloat, b::AbstractFloat) = OpenClose(promote(a, b)...)
217+
218+
CloseClose(a, b) = CloseClose(AbstractFloat(a), AbstractFloat(b))
219+
CloseClose(a::AbstractFloat, b::AbstractFloat) = CloseClose(promote(a, b)...)
220+
221+
OpenOpen(a, b) = OpenOpen(AbstractFloat(a), AbstractFloat(b))
222+
OpenOpen(a::AbstractFloat, b::AbstractFloat) = OpenOpen(promote(a, b)...)
223+
182224
## Bernoulli
183225

184226
struct Bernoulli{T<:Number} <: Distribution{T}

src/sampling.jl

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,47 @@ for CO in (:CloseOpen01, :CloseOpen12)
2727
end
2828

2929
### fall-back on Random definitions
30+
3031
rand(r::AbstractRNG, ::SamplerTrivial{CloseOpen01{T}}) where {T} =
3132
rand(r, SamplerTrivial(Random.CloseOpen01{T}()))
3233

3334
rand(r::AbstractRNG, ::SamplerTrivial{CloseOpen12{T}}) where {T} =
3435
rand(r, SamplerTrivial(Random.CloseOpen12{T}()))
3536

37+
### new intervals 01
38+
39+
# TODO: optimize for BigFloat
40+
41+
for CO = (:OpenClose01, :OpenOpen01, :CloseClose01)
42+
@eval Sampler(RNG::Type{<:AbstractRNG}, I::$CO{T}, n::Repetition) where {T} =
43+
SamplerSimple(I, CloseOpen01(T))
44+
end
45+
46+
rand(r::AbstractRNG, sp::SamplerSimple{OpenClose01{T}}) where {T} =
47+
one(T) - rand(r, sp.data)
48+
49+
rand(r::AbstractRNG, sp::SamplerSimple{OpenOpen01{T}}) where {T} =
50+
while true
51+
x = rand(r, sp.data)
52+
x != zero(T) && return x
53+
end
54+
55+
rand(r::AbstractRNG, sp::SamplerSimple{CloseClose01{T}}) where {T} =
56+
rand(r, sp.data) / prevfloat(one(T))
57+
3658
### CloseOpenAB
3759

38-
Sampler(RNG::Type{<:AbstractRNG}, d::CloseOpenAB{T}, n::Repetition) where {T} =
39-
SamplerTag{CloseOpenAB{T}}((a=d.a, d=d.b - d.a, sp=Sampler(RNG, CloseOpen01{T}(), n)))
60+
for (CO, CO01) = (CloseOpenAB => CloseOpen01,
61+
OpenCloseAB => OpenClose01,
62+
CloseCloseAB => CloseClose01,
63+
OpenOpenAB => OpenOpen01)
4064

41-
rand(rng::AbstractRNG, sp::SamplerTag{CloseOpenAB{T}}) where {T} =
42-
sp.data.a + sp.data.d * rand(rng, sp.data.sp)
65+
@eval Sampler(RNG::Type{<:AbstractRNG}, d::$CO{T}, n::Repetition) where {T} =
66+
SamplerTag{$CO{T}}((a=d.a, d=d.b - d.a, sp=Sampler(RNG, $CO01{T}(), n)))
4367

68+
@eval rand(rng::AbstractRNG, sp::SamplerTag{$CO{T}}) where {T} =
69+
sp.data.a + sp.data.d * rand(rng, sp.data.sp)
70+
end
4471

4572
## Normal & Exponential
4673

test/runtests.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,14 @@ end
247247
sp = Random.Sampler(MersenneTwister, RandomExtensions.CloseOpen01(F))
248248
@test rand(m, sp) isa F
249249
@test 0 <= rand(m, sp) < 1
250+
for (CO, (l, r)) = (CloseOpen => (<=, <),
251+
CloseClose => (<=, <=),
252+
OpenOpen => (<, <),
253+
OpenClose => (<, <=))
254+
f = rand(CO(F))
255+
@test f isa F
256+
@test l(0, f) && r(f, 1)
257+
end
250258
F (Float64, BigFloat) || continue # only types implemented in Random
251259
sp = Random.Sampler(MersenneTwister, RandomExtensions.CloseOpen12(F))
252260
@test rand(m, sp) isa F

0 commit comments

Comments
 (0)