-
Notifications
You must be signed in to change notification settings - Fork 78
/
homogeneous.jl
73 lines (60 loc) · 2.21 KB
/
homogeneous.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# ------------------------------------------------------------------
# Licensed under the MIT License. See LICENSE in the project root.
# ------------------------------------------------------------------
"""
HomogeneousSampling(size, [weights])
Generate sample of given `size` from geometric object
according to a homogeneous density. Optionally, provide `weights`
to specify custom sampling weights for the elements of a domain.
"""
struct HomogeneousSampling{W} <: ContinuousSamplingMethod
size::Int
weights::W
end
HomogeneousSampling(size::Int) = HomogeneousSampling(size, nothing)
function sample(rng::AbstractRNG, d::Domain, method::HomogeneousSampling)
size = method.size
weights = isnothing(method.weights) ? measure.(d) : method.weights
# sample elements with weights
w = WeightedSampling(size, weights, replace=true)
# within each element sample a single point
h = HomogeneousSampling(1)
(first(sample(rng, e, h)) for e in sample(rng, d, w))
end
function sample(rng::AbstractRNG, geom::Geometry{Dim,T}, method::HomogeneousSampling) where {Dim,T}
if isparametrized(geom)
randpoint() = geom(rand(rng, T, paramdim(geom))...)
(randpoint() for _ in 1:(method.size))
else
sample(rng, discretize(geom), method)
end
end
# --------------
# SPECIAL CASES
# --------------
function sample(rng::AbstractRNG, triangle::Triangle{Dim,T}, method::HomogeneousSampling) where {Dim,T}
function randpoint()
# sample barycentric coordinates
u₁, u₂ = rand(rng, T, 2)
λ₁, λ₂ = 1 - √u₁, u₂ * √u₁
triangle(λ₁, λ₂)
end
(randpoint() for _ in 1:(method.size))
end
function sample(rng::AbstractRNG, tetrahedron::Tetrahedron{Dim,T}, method::HomogeneousSampling) where {Dim,T}
@error "not implemented"
end
function sample(rng::AbstractRNG, ball::Ball{2,T}, method::HomogeneousSampling) where {T}
function randpoint()
u₁, u₂ = rand(rng, T, 2)
ball(√u₁, u₂)
end
(randpoint() for _ in 1:(method.size))
end
function sample(rng::AbstractRNG, ball::Ball{3,T}, method::HomogeneousSampling) where {T}
function randpoint()
u₁, u₂, u₃ = rand(rng, T, 3)
ball(∛u₁, acos(1 - 2u₂) / T(π), u₃)
end
(randpoint() for _ in 1:(method.size))
end