@@ -191,6 +191,41 @@ function AbstractMCMC.step(
191
191
return transition, transition
192
192
end
193
193
194
+ """
195
+ is_symmetric_proposal(proposal::P) where P
196
+
197
+ # Example:
198
+
199
+ ```julia
200
+ using Distributions, AdvancedMH
201
+
202
+ # Model definition.
203
+ model = DensityModel(s -> logpdf(Normal(), s.x) + logpdf(Normal(5,.7), s.y))
204
+
205
+ # Set up the proposal.
206
+ p = (x=RandomWalkProposal(Normal(0,.5)), y=RandomWalkProposal(Normal(0,.5)))
207
+
208
+ # Implementing this will skip the computation of the Hastings ratio.
209
+ AdvancedMH.is_symmetric_proposal(proposal::typeof(p)) = true
210
+
211
+ # Sample from the posterior with initial parameters.
212
+ chain = sample(m1, MetropolisHastings(p), 100000; chain_type=Vector{NamedTuple})
213
+ ```
214
+ """
215
+ is_symmetric_proposal (proposal:: P ) where P = false
216
+
217
+ # The following univariate random walk proposals are symmetric.
218
+ is_symmetric_proposal (proposal:: RandomWalkProposal{<:Normal} ) = true
219
+ is_symmetric_proposal (proposal:: RandomWalkProposal{<:MvNormal} ) = true
220
+ is_symmetric_proposal (proposal:: RandomWalkProposal{<:TDist} ) = true
221
+ is_symmetric_proposal (proposal:: RandomWalkProposal{<:Cauchy} ) = true
222
+
223
+ # The following multivariate random walk proposals are symmetric.
224
+ is_symmetric_proposal (proposal:: RandomWalkProposal{AbstractArray{<:Normal}} ) = true
225
+ is_symmetric_proposal (proposal:: RandomWalkProposal{AbstractArray{<:MvNormal}} ) = true
226
+ is_symmetric_proposal (proposal:: RandomWalkProposal{AbstractArray{<:TDist}} ) = true
227
+ is_symmetric_proposal (proposal:: RandomWalkProposal{AbstractArray{<:Cauchy}} ) = true
228
+
194
229
# Define the other sampling steps.
195
230
# Return a 2-tuple consisting of the next sample and the the next state.
196
231
# In this case they are identical, and either a new proposal (if accepted)
@@ -206,8 +241,10 @@ function AbstractMCMC.step(
206
241
params = propose (rng, spl, model, params_prev)
207
242
208
243
# Calculate the log acceptance probability.
209
- logα = logdensity (model, params) - logdensity (model, params_prev) +
210
- q (spl, params_prev, params) - q (spl, params, params_prev)
244
+ logα = logdensity (model, params) - logdensity (model, params_prev)
245
+ if is_symmetric_proposal (spl. proposal)
246
+ logα += q (spl, params_prev, params) - q (spl, params, params_prev)
247
+ end
211
248
212
249
# Decide whether to return the previous params or the new one.
213
250
if - Random. randexp (rng) < logα
0 commit comments