/
particle-constructor.jl
124 lines (101 loc) · 3.77 KB
/
particle-constructor.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# Declare types and structs
"""
Particle{T}
An abstract type with subtypes
- StaticParticle{T}
- DynamicParticle{T}
"""
abstract type Particle{T} end
"""
StaticParticle{T} <: Particle{T}
- ```x``` Location of particle
- ```ℓw``` Log weight of particle (possibly unnormalised)
"""
struct StaticParticle{T} <: Particle{T}
x::T # location
ℓw::Real # log weight
end
"""
DynamicParticle{T} <: Particle{T}
- ```x``` Location of particle
- ```ℓw``` Log weight of particle (possibly unnormalised)
- ```ℓdens``` Log density function
- ```τ``` Temperature (or index) for ℓdens
- ```cacheℓdens``` Cache of log density at current temperature (or index)
"""
struct DynamicParticle{T} <: Particle{T}
x::T # location
ℓw::Real # log weight
ℓdens::Function # log density (functions by reference)
τ::Real # temperature (or index) for ℓdens
cacheℓdens::Real # cache of log density at current temperature (or index)
end
# Constructors - 'DynamicParticle'
"""
Particle(x::T, w::Real, ℓdens::Function, τ::Real, logweight::Bool = false) where {T<:Any}
Explicit constructor for Particle with type ```DynamicParticle```.
Auto calculates cached log density ```cacheℓdens```
- ```x``` Location of particle
- ```w``` Weight of particle (possibly unnormalised)
- ```ℓdens``` Log density function
- ```τ``` Temperature (or index) for ℓdens
-- ```logweight``` Is ```w``` on log scale? Default is ```false```
"""
function Particle(x::T, w::Real, ℓdens::Function, τ::Real, logweight::Bool = false) where {T<:Any}
if hasmethod(ℓdens, (T, Real))
cacheℓdens = ℓdens(x, τ)
elseif hasmethod(ℓdens, Tuple{T})
cacheℓdens = ℓdens(x)
else
cacheℓdens = nothing
end
if logweight
DynamicParticle(x, w, ℓdens, τ, real(cacheℓdens))
else
DynamicParticle(x, log(w), ℓdens, τ, real(cacheℓdens))
end
end
"""
Particle(initial::D, ℓdens::Function, w::Real = 0.0, τ::Real = 0.0, logweight::Bool = false) where {D<:Distribution}
Constructor Particle with type ```DynamicParticle``` from initial distribution ```init_distribution```.
Draws sample from ```init_distribution``` and
Auto calculates cached log density ```cacheℓdens```
- ```initial``` Initial distribution
- ```ℓdens``` Log density function
- ```w``` Weight of particle (possibly unnormalised)
- ```τ``` Temperature (or index) for ℓdens
- ```logweight``` Is ```w``` on log scale? Default is ```false```
"""
#Particle generated from intial distribution
function Particle(initial::D, ℓdens::Function, w::Real = 1.0, τ::Real = 0.0, logweight::Bool = false) where {D<:Distribution}
x = rand(initial, 1)
Particle(x, w, ℓdens, τ, logweight)
end
# Constructors - 'SimpleParticle'
"""
Particle(x::T, w::Real, logweight::Bool = false) where {T<:Any}
Explicit constructor for Particle with type ```StaticParticle```.
- ```x``` Location of particle
- ```w``` Weight of particle (possibly unnormalised)
- ```logweight``` Is ```w``` on log scale? Default is ```false```
"""
function Particle(x::T, w::Real, logweight::Bool = false) where {T<:Any}
if logweight
StaticParticle(x, w)
else
StaticParticle(x, log(w))
end
end
"""
Particle(initial::D, w::Real = 1.0, logweight::Bool = false) where {D<:Distribution}
Constructor Particle with type ```StaticParticle``` from initial distribution ```init_distribution```.
Draws sample from ```init_distribution```
- ```initial``` Initial distribution
- ```w``` Weight of particle (possibly unnormalised)
- ```logweight``` Is ```w``` on log scale? Default is ```false```
"""
#Particle generated from intial distribution
function Particle(initial::D, w::Real = 1.0, logweight::Bool = false) where {D<:Distribution}
x = rand(initial, 1)
Particle(x, w, logweight)
end