1
- module RobustAdaptiveMetropolis
2
-
3
- using Random, LogDensityProblems, LinearAlgebra, AbstractMCMC
4
- using DocStringExtensions: FIELDS
5
-
6
- using AdvancedMH: AdvancedMH
7
-
8
- export RAM
9
-
10
1
# TODO : Should we generalise this arbitrary symmetric proposals?
11
2
"""
12
- RAM
3
+ RobustAdaptiveMetropolis
13
4
14
5
Robust Adaptive Metropolis-Hastings (RAM).
15
6
@@ -56,7 +47,7 @@ julia> # Set the seed so get some consistency.
56
47
Random.seed!(1234);
57
48
58
49
julia> # Sample!
59
- chain = sample(model, RAM (), 10_000; chain_type=Chains, num_warmup, progress=false, initial_params=zeros(2));
50
+ chain = sample(model, RobustAdaptiveMetropolis (), 10_000; chain_type=Chains, num_warmup, progress=false, initial_params=zeros(2));
60
51
61
52
julia> isapprox(cov(Array(chain)), model.A; rtol = 0.2)
62
53
true
@@ -67,7 +58,7 @@ It's also possible to restrict the eigenvalues to avoid either too small or too
67
58
```jldoctest ram-gaussian`
68
59
julia> chain = sample(
69
60
model,
70
- RAM (eigenvalue_lower_bound=0.1, eigenvalue_upper_bound=2.0),
61
+ RobustAdaptiveMetropolis (eigenvalue_lower_bound=0.1, eigenvalue_upper_bound=2.0),
71
62
10_000;
72
63
chain_type=Chains, num_warmup, progress=false, initial_params=zeros(2)
73
64
);
79
70
# References
80
71
[^VIH12]: Vihola (2012) Robust adaptive Metropolis algorithm with coerced acceptance rate, Statistics and computing.
81
72
"""
82
- Base. @kwdef struct RAM {T,A<: Union{Nothing,AbstractMatrix{T}} } <: AdvancedMH.MHSampler
73
+ Base. @kwdef struct RobustAdaptiveMetropolis {T,A<: Union{Nothing,AbstractMatrix{T}} } <: AdvancedMH.MHSampler
83
74
" target acceptance rate. Default: 0.234."
84
75
α:: T = 0.234
85
76
" negative exponent of the adaptation decay rate. Default: `0.6`."
@@ -93,16 +84,16 @@ Base.@kwdef struct RAM{T,A<:Union{Nothing,AbstractMatrix{T}}} <: AdvancedMH.MHSa
93
84
end
94
85
95
86
"""
96
- RAMState
87
+ RobustAdaptiveMetropolisState
97
88
98
89
State of the Robust Adaptive Metropolis-Hastings (RAM) algorithm.
99
90
100
- See also: [`RAM `](@ref).
91
+ See also: [`RobustAdaptiveMetropolis `](@ref).
101
92
102
93
# Fields
103
94
$(FIELDS)
104
95
"""
105
- struct RAMState {T1,L,A,T2,T3}
96
+ struct RobustAdaptiveMetropolisState {T1,L,A,T2,T3}
106
97
" current realization of the chain."
107
98
x:: T1
108
99
" log density of `x` under the target model."
@@ -119,14 +110,14 @@ struct RAMState{T1,L,A,T2,T3}
119
110
isaccept:: Bool
120
111
end
121
112
122
- AbstractMCMC. getparams (state:: RAMState ) = state. x
123
- AbstractMCMC. setparams!! (state:: RAMState , x) = RAMState (x, state. logprob, state. S, state. logα, state. η, state. iteration, state. isaccept)
113
+ AbstractMCMC. getparams (state:: RobustAdaptiveMetropolisState ) = state. x
114
+ AbstractMCMC. setparams!! (state:: RobustAdaptiveMetropolisState , x) = RobustAdaptiveMetropolisState (x, state. logprob, state. S, state. logα, state. η, state. iteration, state. isaccept)
124
115
125
- function step_inner (
116
+ function ram_step_inner (
126
117
rng:: Random.AbstractRNG ,
127
118
model:: AbstractMCMC.LogDensityModel ,
128
- sampler:: RAM ,
129
- state:: RAMState
119
+ sampler:: RobustAdaptiveMetropolis ,
120
+ state:: RobustAdaptiveMetropolisState
130
121
)
131
122
# This is the initial state.
132
123
f = model. logdensity
@@ -146,8 +137,7 @@ function step_inner(
146
137
return x_new, lp_new, U, logα, isaccept
147
138
end
148
139
149
- function adapt (sampler:: RAM , state:: RAMState , logα:: Real , U:: AbstractVector )
150
- # Update `
140
+ function ram_adapt (sampler:: RobustAdaptiveMetropolis , state:: RobustAdaptiveMetropolisState , logα:: Real , U:: AbstractVector )
151
141
Δα = exp (logα) - sampler. α
152
142
S = state. S
153
143
# TODO : Make this configurable by defining a more general path.
167
157
function AbstractMCMC. step (
168
158
rng:: Random.AbstractRNG ,
169
159
model:: AbstractMCMC.LogDensityModel ,
170
- sampler:: RAM ;
160
+ sampler:: RobustAdaptiveMetropolis ;
171
161
initial_params= nothing ,
172
162
kwargs...
173
163
)
@@ -183,22 +173,22 @@ function AbstractMCMC.step(
183
173
184
174
# Construct the initial state.
185
175
lp = LogDensityProblems. logdensity (f, x)
186
- state = RAMState (x, lp, S, zero (T), 0 , 1 , true )
176
+ state = RobustAdaptiveMetropolisState (x, lp, S, zero (T), 0 , 1 , true )
187
177
188
178
return AdvancedMH. Transition (x, lp, true ), state
189
179
end
190
180
191
181
function AbstractMCMC. step (
192
182
rng:: Random.AbstractRNG ,
193
183
model:: AbstractMCMC.LogDensityModel ,
194
- sampler:: RAM ,
195
- state:: RAMState ;
184
+ sampler:: RobustAdaptiveMetropolis ,
185
+ state:: RobustAdaptiveMetropolisState ;
196
186
kwargs...
197
187
)
198
188
# Take the inner step.
199
- x_new, lp_new, U, logα, isaccept = step_inner (rng, model, sampler, state)
189
+ x_new, lp_new, U, logα, isaccept = ram_step_inner (rng, model, sampler, state)
200
190
# Accept / reject the proposal.
201
- state_new = RAMState (isaccept ? x_new : state. x, isaccept ? lp_new : state. logprob, state. S, logα, state. η, state. iteration + 1 , isaccept)
191
+ state_new = RobustAdaptiveMetropolisState (isaccept ? x_new : state. x, isaccept ? lp_new : state. logprob, state. S, logα, state. η, state. iteration + 1 , isaccept)
202
192
return AdvancedMH. Transition (state_new. x, state_new. logprob, state_new. isaccept), state_new
203
193
end
204
194
@@ -213,23 +203,22 @@ end
213
203
function AbstractMCMC. step_warmup (
214
204
rng:: Random.AbstractRNG ,
215
205
model:: AbstractMCMC.LogDensityModel ,
216
- sampler:: RAM ,
217
- state:: RAMState ;
206
+ sampler:: RobustAdaptiveMetropolis ,
207
+ state:: RobustAdaptiveMetropolisState ;
218
208
kwargs...
219
209
)
220
210
# Take the inner step.
221
- x_new, lp_new, U, logα, isaccept = step_inner (rng, model, sampler, state)
211
+ x_new, lp_new, U, logα, isaccept = ram_step_inner (rng, model, sampler, state)
222
212
# Adapt the proposal.
223
- S_new, η = adapt (sampler, state, logα, U)
213
+ S_new, η = ram_adapt (sampler, state, logα, U)
224
214
# Check that `S_new` has eigenvalues in the desired range.
225
215
if ! valid_eigenvalues (S_new, sampler. eigenvalue_lower_bound, sampler. eigenvalue_upper_bound)
226
216
# In this case, we just keep the old `S` (p. 13 in Vihola, 2012).
227
217
S_new = state. S
228
218
end
229
219
230
220
# Update state.
231
- state_new = RAMState (isaccept ? x_new : state. x, isaccept ? lp_new : state. logprob, S_new, logα, η, state. iteration + 1 , isaccept)
221
+ state_new = RobustAdaptiveMetropolisState (isaccept ? x_new : state. x, isaccept ? lp_new : state. logprob, S_new, logα, η, state. iteration + 1 , isaccept)
232
222
return AdvancedMH. Transition (state_new. x, state_new. logprob, state_new. isaccept), state_new
233
223
end
234
224
235
- end
0 commit comments