Skip to content

Commit 5ca8c03

Browse files
authored
implement Make via tuples (#8)
1 parent 7e966c0 commit 5ca8c03

2 files changed

Lines changed: 41 additions & 101 deletions

File tree

src/distributions.jl

Lines changed: 24 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -7,106 +7,46 @@ abstract type Distribution{T} end
77

88
Base.eltype(::Type{<:Distribution{T}}) where {T} = T
99

10-
abstract type Make{T} <: Distribution{T} end
11-
12-
struct Make0{T} <: Make{T} end
13-
14-
Make( ::Type{T}) where {T} = Make0{T}()
15-
Make0(::Type{T}) where {T} = Make0{T}()
16-
make(::Type{T}) where {T} = Make0{maketype(T)}()
10+
struct Make{T,X<:Tuple, XX<:Tuple} <: Distribution{T}
11+
# XX is X with Type{A} replaced by Nothing (otherwise, X (e.g. Tuple{Type{Int}}) can't have instances)
12+
x::XX
13+
end
1714

18-
# default
19-
maketype(::Type{T}) where {T} = T
15+
# @inline necessary for one @inferred test on arrays
16+
@inline Base.getindex(m::Make{T,X}, i::Int) where {T,X} =
17+
fieldtype(X, i) <: Type ?
18+
fieldtype(X, i).parameters[1] :
19+
m.x[i]
2020

21-
struct Make1{T,X} <: Make{T}
22-
x::X
21+
@generated function Make{T}(X...) where T
22+
XX = Tuple{(x <: Type ? Nothing : x for x in X)...}
23+
y = [x <: Type ? nothing : :(X[$i]) for (i, x) in enumerate(X)]
24+
:(Make{T,Tuple{$X...},$XX}(tuple($(y...))))
2325
end
2426

25-
Make{T}(x::X) where {T,X} = Make1{T,X}( x)
26-
Make{T}(::Type{X}) where {T,X} = Make1{T,Type{X}}(X)
27+
Make0{T} = Make{T,Tuple{}}
28+
Make1{T} = Make{T,Tuple{X}} where X
29+
Make2{T} = Make{T,Tuple{X,Y}} where {X, Y}
30+
Make3{T} = Make{T,Tuple{X,Y,Z}} where {X, Y, Z}
2731

28-
# for expliciteness (allows using Make1 instead of Make)
29-
Make1{T}(x::X) where {T,X} = Make1{T,X}( x)
30-
Make1{T}(::Type{X}) where {T,X} = Make1{T,Type{X}}(X)
32+
Make0{T}() where {T} = Make{T}()
33+
Make1{T}(x) where {T} = Make{T}(x)
34+
Make2{T}(x, y) where {T} = Make{T}(x, y)
35+
Make3{T}(x, y, z) where {T} = Make{T}(x, y, z)
3136

32-
make(::Type{T}, x::X) where {T,X} = Make{maketype(T,x)}(x)
33-
make(::Type{T}, ::Type{X}) where {T,X} = Make{maketype(T,X)}(X)
37+
# default maketype & make
38+
maketype(::Type{T}, x...) where {T} = T
3439

35-
# default
36-
maketype(::Type{T}, x) where {T} = T
40+
make(::Type{T}, x...) where {T} = Make{maketype(T, x...)}(x...)
3741

3842
find_deduced_type(::Type{T}, ::X, ) where {T,X} = deduce_type(T, gentype(X))
3943
find_deduced_type(::Type{T}, ::Type{X}) where {T,X} = deduce_type(T, X)
4044

41-
struct Make2{T,X,Y} <: Make{T}
42-
x::X
43-
y::Y
44-
end
45-
46-
Make{T}(x::X, y::Y) where {T,X,Y} = Make2{T,X, Y}( x, y)
47-
Make{T}(::Type{X}, y::Y) where {T,X,Y} = Make2{T,Type{X},Y}( X, y)
48-
Make{T}(x::X, ::Type{Y}) where {T,X,Y} = Make2{T,X, Type{Y}}(x, Y)
49-
Make{T}(::Type{X}, ::Type{Y}) where {T,X,Y} = Make2{T,Type{X},Type{Y}}(X, Y)
50-
51-
# for expliciteness (allows using Make2 instead of Make)
52-
Make2{T}(x::X, y::Y) where {T,X,Y} = Make2{T,X, Y}( x, y)
53-
Make2{T}(::Type{X}, y::Y) where {T,X,Y} = Make2{T,Type{X},Y}( X, y)
54-
Make2{T}(x::X, ::Type{Y}) where {T,X,Y} = Make2{T,X, Type{Y}}(x, Y)
55-
Make2{T}(::Type{X}, ::Type{Y}) where {T,X,Y} = Make2{T,Type{X},Type{Y}}(X, Y)
56-
57-
make(::Type{T}, x::X, y::Y) where {T,X,Y} = Make{maketype(T,x,y)}(x, y)
58-
make(::Type{T}, ::Type{X}, y::Y) where {T,X,Y} = Make{maketype(T,X,y)}(X, y)
59-
make(::Type{T}, x::X, ::Type{Y}) where {T,X,Y} = Make{maketype(T,x,Y)}(x, Y)
60-
make(::Type{T}, ::Type{X}, ::Type{Y}) where {T,X,Y} = Make{maketype(T,X,Y)}(X, Y)
61-
62-
# default
63-
maketype(::Type{T}, x, y) where {T} = T
64-
6545
find_deduced_type(::Type{T}, ::X, ::Y) where {T,X,Y} = deduce_type(T, gentype(X), gentype(Y))
6646
find_deduced_type(::Type{T}, ::Type{X}, ::Y) where {T,X,Y} = deduce_type(T, X, gentype(Y))
6747
find_deduced_type(::Type{T}, ::X, ::Type{Y}) where {T,X,Y} = deduce_type(T, gentype(X), Y)
6848
find_deduced_type(::Type{T}, ::Type{X}, ::Type{Y}) where {T,X,Y} = deduce_type(T, X, Y)
6949

70-
struct Make3{T,X,Y,Z} <: Make{T}
71-
x::X
72-
y::Y
73-
z::Z
74-
end
75-
76-
Make{T}(x::X, y::Y, z::Z) where {T,X,Y,Z} = Make3{T,X, Y, Z }(x, y, z)
77-
Make{T}(::Type{X}, y::Y, z::Z) where {T,X,Y,Z} = Make3{T,Type{X},Y, Z }(X, y, z)
78-
Make{T}(x::X, ::Type{Y}, z::Z) where {T,X,Y,Z} = Make3{T,X, Type{Y},Z }(x, Y, z)
79-
Make{T}(::Type{X}, ::Type{Y}, z::Z) where {T,X,Y,Z} = Make3{T,Type{X},Type{Y},Z }(X, Y, z)
80-
Make{T}(x::X, y::Y, ::Type{Z}) where {T,X,Y,Z} = Make3{T,X, Y, Type{Z}}(x, y, Z)
81-
Make{T}(::Type{X}, y::Y, ::Type{Z}) where {T,X,Y,Z} = Make3{T,Type{X},Y, Type{Z}}(X, y, Z)
82-
Make{T}(x::X, ::Type{Y}, ::Type{Z}) where {T,X,Y,Z} = Make3{T,X, Type{Y},Type{Z}}(x, Y, Z)
83-
Make{T}(::Type{X}, ::Type{Y}, ::Type{Z}) where {T,X,Y,Z} = Make3{T,Type{X},Type{Y},Type{Z}}(X, Y, Z)
84-
85-
# for expliciteness (allows using Make3 instead of Make)
86-
Make3{T}(x::X, y::Y, z::Z) where {T,X,Y,Z} = Make3{T,X, Y, Z }(x, y, z)
87-
Make3{T}(::Type{X}, y::Y, z::Z) where {T,X,Y,Z} = Make3{T,Type{X},Y, Z }(X, y, z)
88-
Make3{T}(x::X, ::Type{Y}, z::Z) where {T,X,Y,Z} = Make3{T,X, Type{Y},Z }(x, Y, z)
89-
Make3{T}(::Type{X}, ::Type{Y}, z::Z) where {T,X,Y,Z} = Make3{T,Type{X},Type{Y},Z }(X, Y, z)
90-
Make3{T}(x::X, y::Y, ::Type{Z}) where {T,X,Y,Z} = Make3{T,X, Y, Type{Z}}(x, y, Z)
91-
Make3{T}(::Type{X}, y::Y, ::Type{Z}) where {T,X,Y,Z} = Make3{T,Type{X},Y, Type{Z}}(X, y, Z)
92-
Make3{T}(x::X, ::Type{Y}, ::Type{Z}) where {T,X,Y,Z} = Make3{T,X, Type{Y},Type{Z}}(x, Y, Z)
93-
Make3{T}(::Type{X}, ::Type{Y}, ::Type{Z}) where {T,X,Y,Z} = Make3{T,Type{X},Type{Y},Type{Z}}(X, Y, Z)
94-
95-
96-
make(::Type{T}, x::X, y::Y, z::Z) where {T,X,Y,Z} = Make3{maketype(T, x, y, z)}(x, y, z)
97-
make(::Type{T}, ::Type{X}, y::Y, z::Z) where {T,X,Y,Z} = Make3{maketype(T, X, y, z)}(X, y, z)
98-
make(::Type{T}, x::X, ::Type{Y}, z::Z) where {T,X,Y,Z} = Make3{maketype(T, x, Y, z)}(x, Y, z)
99-
make(::Type{T}, ::Type{X}, ::Type{Y}, z::Z) where {T,X,Y,Z} = Make3{maketype(T, X, Y, z)}(X, Y, z)
100-
make(::Type{T}, x::X, y::Y, ::Type{Z}) where {T,X,Y,Z} = Make3{maketype(T, x, y, Z)}(x, y, Z)
101-
make(::Type{T}, ::Type{X}, y::Y, ::Type{Z}) where {T,X,Y,Z} = Make3{maketype(T, X, y, Z)}(X, y, Z)
102-
make(::Type{T}, x::X, ::Type{Y}, ::Type{Z}) where {T,X,Y,Z} = Make3{maketype(T, x, Y, Z)}(x, Y, Z)
103-
make(::Type{T}, ::Type{X}, ::Type{Y}, ::Type{Z}) where {T,X,Y,Z} = Make3{maketype(T, X, Y, Z)}(X, Y, Z)
104-
105-
# default
106-
maketype(::Type{T}, x, y, z) where {T} = T
107-
108-
# deduce_type
109-
11050
deduce_type(::Type{T}, ::Type{X}, ::Type{Y}) where {T,X,Y} = _deduce_type(T, Val(isconcretetype(T)), X, Y)
11151
deduce_type(::Type{T}, ::Type{X}) where {T,X} = _deduce_type(T, Val(isconcretetype(T)), X)
11252

src/sampling.jl

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Sampler(RNG::Type{<:AbstractRNG}, ::Make0{X}, n::Repetition) where {X} =
2323
### object
2424

2525
# like Make1
26-
struct MakeWrap{T,X} <: Make{T}
26+
struct MakeWrap{T,X} <: Distribution{T}
2727
x::X
2828
end
2929

@@ -161,8 +161,8 @@ maketype(::Type{Complex}, x, y) = Complex{promote_type(val_gentype(x), val_ge
161161
maketype(T::Type{<:Complex}, _, _) = T
162162

163163
function Sampler(RNG::Type{<:AbstractRNG}, u::Make2{T}, n::Repetition) where T <: Union{Pair,Complex}
164-
sp1 = sampler(RNG, u.x, n)
165-
sp2 = u.x == u.y ? sp1 : sampler(RNG, u.y, n)
164+
sp1 = sampler(RNG, u[1], n)
165+
sp2 = u[1] == u[2] ? sp1 : sampler(RNG, u[2], n)
166166
SamplerTag{Cont{T}}((sp1, sp2))
167167
end
168168

@@ -178,7 +178,7 @@ Sampler(RNG::Type{<:AbstractRNG}, ::Type{Pair{A,B}}, n::Repetition) where {A,B}
178178

179179
# rand(make(Complex, x)) => rand(make(Complex, x, x))
180180
Sampler(RNG::Type{<:AbstractRNG}, u::Make1{T}, n::Repetition) where {T<:Complex} =
181-
Sampler(RNG, make(T, u.x, u.x), n)
181+
Sampler(RNG, make(T, u[1], u[1]), n)
182182

183183
# rand(Complex{T}) => rand(make(Complex{T}, T, T)) (redundant with implem in Random)
184184
Sampler(RNG::Type{<:AbstractRNG}, ::Type{Complex{T}}, n::Repetition) where {T<:Real} =
@@ -281,7 +281,7 @@ end
281281

282282
@generated function Sampler(RNG::Type{<:AbstractRNG}, c::Make1{T,X}, n::Repetition) where {T<:Tuple,X<:Tuple}
283283
@assert fieldcount(T) == fieldcount(X)
284-
sps = [:(sampler(RNG, c.x[$i], n)) for i in 1:length(T.parameters)]
284+
sps = [:(sampler(RNG, c[1][$i], n)) for i in 1:length(T.parameters)]
285285
:(SamplerTag{Cont{T}}(tuple($(sps...))))
286286
end
287287

@@ -318,7 +318,7 @@ end
318318
# should catch Tuple{Integer,Integer} which is not NTuple, or even Tuple{Int,UInt}, when only one sampler was passed
319319

320320
Sampler(RNG::Type{<:AbstractRNG}, c::Make1{T,X}, n::Repetition) where {T<:Tuple,X} =
321-
SamplerTag{Cont{T}}(sampler(RNG, c.x, n))
321+
SamplerTag{Cont{T}}(sampler(RNG, c[1], n))
322322

323323
@generated function rand(rng::AbstractRNG, sp::SamplerTag{Cont{T},S}) where {T<:Tuple,S<:Sampler}
324324
rands = [:(convert($(T.parameters[i]), rand(rng, sp.data))) for i in 1:fieldcount(T)]
@@ -350,7 +350,7 @@ Sampler(RNG::Type{<:AbstractRNG}, m::Make0{NamedTuple}, n::Repetition) =
350350
SamplerType{NamedTuple}()
351351

352352
Sampler(RNG::Type{<:AbstractRNG}, m::Make1{T}, n::Repetition) where T <: NamedTuple =
353-
SamplerTag{Cont{T}}(Sampler(RNG, m.x , n))
353+
SamplerTag{Cont{T}}(Sampler(RNG, m[1] , n))
354354

355355
rand(rng::AbstractRNG, sp::SamplerType{NamedTuple{}}) = NamedTuple()
356356

@@ -369,8 +369,8 @@ make(T::Type{<:SetDict}, ::Type{X}, n::Integer) where {X} = Make2{maketype(T, X,
369369
make(T::Type{<:SetDict}, n::Integer) = make(T, default_sampling(T), Int(n))
370370

371371
Sampler(RNG::Type{<:AbstractRNG}, c::Make2{T}, n::Repetition) where {T<:SetDict} =
372-
SamplerTag{Cont{T}}((sp = sampler(RNG, c.x, n),
373-
len = c.y))
372+
SamplerTag{Cont{T}}((sp = sampler(RNG, c[1], n),
373+
len = c[2]))
374374

375375
function rand(rng::AbstractRNG, sp::SamplerTag{Cont{S}}) where {S<:SetDict}
376376
# assuming S() creates an empty set/dict
@@ -439,7 +439,7 @@ if VERSION < v"1.1.0"
439439
end
440440

441441
Sampler(RNG::Type{<:AbstractRNG}, c::Make2{A}, n::Repetition) where {A<:AbstractArray} =
442-
SamplerTag{A}((sampler(RNG, c.x, n), c.y))
442+
SamplerTag{A}((sampler(RNG, c[1], n), c[2]))
443443

444444
rand(rng::AbstractRNG, sp::SamplerTag{A}) where {A<:AbstractArray} =
445445
rand!(rng, A(undef, sp.data[2]), sp.data[1])
@@ -484,9 +484,9 @@ make(T::Type{SparseMatrixCSC}, p::AbstractFloat, dims::Dims{2}) = make(T, defaul
484484

485485

486486
Sampler(RNG::Type{<:AbstractRNG}, c::Make3{A}, n::Repetition) where {A<:AbstractSparseArray} =
487-
SamplerTag{Cont{A}}((sp = sampler(RNG, c.x, n),
488-
p = c.y,
489-
dims = c.z))
487+
SamplerTag{Cont{A}}((sp = sampler(RNG, c[1], n),
488+
p = c[2],
489+
dims = c[3]))
490490

491491
rand(rng::AbstractRNG, sp::SamplerTag{Cont{A}}) where {A<:SparseVector} =
492492
sprand(rng, sp.data.dims[1], sp.data.p, (r, n)->rand(r, sp.data.sp, n))
@@ -505,7 +505,7 @@ function random_staticarrays()
505505
maketype(::Type{<:$Arr{S,T}}, _) where {S<:Tuple,T} = $Arr{S,T,tuple_length(S),tuple_prod(S)}
506506

507507
Sampler(RNG::Type{<:AbstractRNG}, c::Make1{A}, n::Repetition) where {A<:$Arr} =
508-
SamplerTag{Cont{A}}(Sampler(RNG, c.x, n))
508+
SamplerTag{Cont{A}}(Sampler(RNG, c[1], n))
509509

510510
rand(rng::AbstractRNG, sp::SamplerTag{Cont{$Arr{S,T,N,L}}}) where {S,T,N,L} =
511511
$Arr{S,T,N,L}(rand(rng, make(NTuple{L}, sp.data)))
@@ -536,9 +536,9 @@ let b = UInt8['0':'9';'A':'Z';'a':'z'],
536536
SamplerTag{Cont{String}}((RNG === MersenneTwister ? s : Sampler(RNG, b, n)) => 8)
537537

538538
function Sampler(RNG::Type{<:AbstractRNG}, c::Make2{String}, n::Repetition)
539-
sp = RNG === MersenneTwister && c.y === b ?
540-
s : sampler(RNG, c.y, n)
541-
SamplerTag{Cont{String}}(sp => c.x)
539+
sp = RNG === MersenneTwister && c[2] === b ?
540+
s : sampler(RNG, c[2], n)
541+
SamplerTag{Cont{String}}(sp => c[1])
542542
end
543543

544544
rand(rng::AbstractRNG, sp::SamplerTag{Cont{String}}) = String(rand(rng, sp.data.first, sp.data.second))

0 commit comments

Comments
 (0)