@@ -11,30 +11,11 @@ import MCMCChains: Chains
11
11
import AbstractMCMC: step!, AbstractSampler, AbstractTransition, transition_type, bundle_samples
12
12
13
13
# Exports
14
- export MetropolisHastings, DensityModel, sample
14
+ export MetropolisHastings, DensityModel, sample, psample, RWMH, StaticMH
15
15
16
- """
17
- MetropolisHastings{T, F<:Function}
18
-
19
- Fields:
20
-
21
- - `init_θ` is the vector form of the parameters needed for the likelihood function.
22
- - `proposal` is a function that dynamically constructs a conditional distribution.
23
-
24
- Example:
25
-
26
- ```julia
27
- MetropolisHastings([0.0, 0.0], x -> MvNormal(x, 1.0))
28
- ````
29
- """
30
- struct MetropolisHastings{T, D} <: AbstractSampler
31
- init_θ :: T
32
- proposal :: D
33
- end
34
-
35
- # Default constructors.
36
- MetropolisHastings (init_θ:: Real ) = MetropolisHastings (init_θ, Normal (0 ,1 ))
37
- MetropolisHastings (init_θ:: Vector{<:Real} ) = MetropolisHastings (init_θ, MvNormal (length (init_θ),1 ))
16
+ # Abstract type for MH-style samplers.
17
+ abstract type Metropolis <: AbstractSampler end
18
+ abstract type ProposalStyle end
38
19
39
20
# Define a model type. Stores the log density function and the data to
40
21
# evaluate the log density on.
65
46
Transition (model:: M , θ:: T ) where {M<: DensityModel , T} = Transition (θ, ℓπ (model, θ))
66
47
67
48
# Tell the interface what transition type we would like to use.
68
- transition_type (model:: DensityModel , spl:: MetropolisHastings ) = typeof (Transition (spl. init_θ, ℓπ (model, spl. init_θ)))
69
-
70
- # Define a function that makes a basic proposal depending on a univariate
71
- # parameterization or a multivariate parameterization.
72
- propose (spl:: MetropolisHastings , model:: DensityModel , θ:: Real ) =
73
- Transition (model, θ + rand (spl. proposal))
74
- propose (spl:: MetropolisHastings , model:: DensityModel , θ:: Vector{<:Real} ) =
75
- Transition (model, θ + rand (spl. proposal))
76
- propose (spl:: MetropolisHastings , model:: DensityModel , t:: Transition ) = propose (spl, model, t. θ)
77
-
78
- """
79
- q(θ::Real, dist::Sampleable)
80
- q(θ::Vector{<:Real}, dist::Sampleable)
81
- q(t1::Transition, dist::Sampleable)
82
-
83
- Calculates the probability `q(θ | θcond)`, using the proposal distribution `spl.proposal`.
84
- """
85
- q (spl:: MetropolisHastings , θ:: Real , θcond:: Real ) = logpdf (spl. proposal, θ - θcond)
86
- q (spl:: MetropolisHastings , θ:: Vector{<:Real} , θcond:: Vector{<:Real} ) = logpdf (spl. proposal, θ - θcond)
87
- q (spl:: MetropolisHastings , t1:: Transition , t2:: Transition ) = q (spl, t1. θ, t2. θ)
49
+ transition_type (model:: DensityModel , spl:: Metropolis ) = typeof (Transition (spl. init_θ, ℓπ (model, spl. init_θ)))
88
50
89
51
# Calculate the density of the model given some parameterization.
90
52
ℓπ (model:: DensityModel , θ:: T ) where T = model. ℓπ (θ)
91
53
ℓπ (model:: DensityModel , t:: Transition ) = t. lp
92
54
93
- # Define the first step! function, which is called at the
94
- # beginning of sampling. Return the initial parameter used
95
- # to define the sampler.
96
- function step! (
97
- rng:: AbstractRNG ,
98
- model:: DensityModel ,
99
- spl:: MetropolisHastings ,
100
- N:: Integer ;
101
- kwargs...
102
- )
103
- return Transition (model, spl. init_θ)
104
- end
105
-
106
- # Define the other step functions. Returns a Transition containing
107
- # either a new proposal (if accepted) or the previous proposal
108
- # (if not accepted).
109
- function step! (
110
- rng:: AbstractRNG ,
111
- model:: DensityModel ,
112
- spl:: MetropolisHastings ,
113
- :: Integer ,
114
- θ_prev:: Transition ;
115
- kwargs...
116
- )
117
- # Generate a new proposal.
118
- θ = propose (spl, model, θ_prev)
119
-
120
- # Calculate the log acceptance probability.
121
- α = ℓπ (model, θ) - ℓπ (model, θ_prev) + q (spl, θ_prev, θ) - q (spl, θ, θ_prev)
122
-
123
- # Decide whether to return the previous θ or the new one.
124
- if log (rand (rng)) < min (α, 0.0 )
125
- return θ
126
- else
127
- return θ_prev
128
- end
129
- end
130
-
131
55
# A basic chains constructor that works with the Transition struct we defined.
132
56
function bundle_samples (
133
57
rng:: AbstractRNG ,
134
58
ℓ:: DensityModel ,
135
- s:: MetropolisHastings ,
59
+ s:: Metropolis ,
136
60
N:: Integer ,
137
61
ts:: Vector{T} ;
138
62
param_names= missing ,
@@ -143,7 +67,10 @@ function bundle_samples(
143
67
144
68
# Check if we received any parameter names.
145
69
if ismissing (param_names)
146
- param_names = [" Parameter $i " for i in 1 : (length (first (vals))- 1 )]
70
+ param_names = [" Parameter $i " for i in 1 : length (s. init_θ)]
71
+ else
72
+ # Deepcopy to be thread safe.
73
+ param_names = deepcopy (param_names)
147
74
end
148
75
149
76
# Add the log density field to the parameter names.
@@ -153,4 +80,9 @@ function bundle_samples(
153
80
return Chains (vals, param_names, (internals= [" lp" ],))
154
81
end
155
82
156
- end # module AdvancedMH
83
+ # Include inference methods.
84
+ include (" mh-core.jl" )
85
+ include (" rwmh.jl" )
86
+ include (" staticmh.jl" )
87
+
88
+ end # module AdvancedMH
0 commit comments