diff --git a/src/integrator.jl b/src/integrator.jl index 004028e1..449154c5 100644 --- a/src/integrator.jl +++ b/src/integrator.jl @@ -89,14 +89,14 @@ Leapfrog integrator with randomly "jittered" step size `ϵ` for every trajectory $(TYPEDFIELDS) # Description -This is the same as `LeapFrog`(@ref) but with a "jittered" step size. This means -that at the beginning of each trajectory we sample a step size `ϵ` by adding or -subtracting from the nominal/base step size `ϵ0` some random proportion of `ϵ0`, +This is the same as `LeapFrog`(@ref) but with a "jittered" step size. This means +that at the beginning of each trajectory we sample a step size `ϵ` by adding or +subtracting from the nominal/base step size `ϵ0` some random proportion of `ϵ0`, with the proportion specified by `jitter`, i.e. `ϵ = ϵ0 - jitter * ϵ0 * rand()`. p Jittering might help alleviate issues related to poor interactions with a fixed step size: -- In regions with high "curvature" the current choice of step size might mean over-shoot - leading to almost all steps being rejected. Randomly sampling the step size at the +- In regions with high "curvature" the current choice of step size might mean over-shoot + leading to almost all steps being rejected. Randomly sampling the step size at the beginning of the trajectories can therefore increase the probability of escaping such high-curvature regions. - Exact periodicity of the simulated trajectories might occur, i.e. you might be so @@ -168,7 +168,7 @@ $(TYPEDFIELDS) # Description -Tempering can potentially allow greater exploration of the posterior, e.g. +Tempering can potentially allow greater exploration of the posterior, e.g. in a multi-modal posterior jumps between the modes can be more likely to occur. """ struct TemperedLeapfrog{FT<:AbstractFloat,T<:AbstractScalarOrVec{FT}} <: AbstractLeapfrog{T} @@ -226,9 +226,7 @@ function step( ϵ = fwd ? step_size(lf) : -step_size(lf) ϵ = ϵ' - if FullTraj - res = Vector{P}(undef, n_steps) - end + res = FullTraj ? Vector{P}(undef, n_steps) : nothing (; θ, r) = z (; value, gradient) = z.ℓπ @@ -248,12 +246,12 @@ function step( # Create a new phase point by caching the logdensity and gradient z = phasepoint(h, θ, r; ℓπ=DualValue(value, gradient)) # Update result - if FullTraj + if !isnothing(res) res[i] = z end if !isfinite(z) # Remove undef - if FullTraj + if !isnothing(res) resize!(res, i) end break diff --git a/src/riemannian/integrator.jl b/src/riemannian/integrator.jl index 6ce59476..a6d2de5f 100644 --- a/src/riemannian/integrator.jl +++ b/src/riemannian/integrator.jl @@ -8,7 +8,7 @@ Generalized leapfrog integrator with fixed step size `ϵ`. $(TYPEDFIELDS) -## References +## References 1. Girolami, Mark, and Ben Calderhead. "Riemann manifold Langevin and Hamiltonian Monte Carlo methods." Journal of the Royal Statistical Society Series B: Statistical Methodology 73, no. 2 (2011): 123-214. """ @@ -29,7 +29,7 @@ end # TODO(Kai) make sure vectorization works # TODO(Kai) check if tempering is valid -# TODO(Kai) abstract out the 3 main steps and merge with `step` in `integrator.jl` +# TODO(Kai) abstract out the 3 main steps and merge with `step` in `integrator.jl` function step( lf::GeneralizedLeapfrog{T}, h::Hamiltonian, @@ -59,7 +59,7 @@ function step( #r = temper(lf, r, (i=i, is_half=true), n_steps) # eq (16) of Girolami & Calderhead (2011) r_half = r_init - local cache + local cache = nothing for j in 1:(lf.n) # Reuse cache for the first iteration if j == 1