Skip to content
Open
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
7883d49
Add Riemannian manifold HMC
ErikQQY May 5, 2025
d0191cf
Merge branch 'main' into qqy/NEW_RMHMC
ErikQQY May 10, 2025
1fcdd09
Format
ErikQQY May 10, 2025
5f9592f
Merge branch 'main' into qqy/NEW_RMHMC
ErikQQY Jun 29, 2025
567e2a8
format
ErikQQY Jun 29, 2025
6df40b5
Merge branch 'main' into qqy/NEW_RMHMC
ErikQQY Nov 21, 2025
c9e6b0a
Include Riemannian HMC tests
ErikQQY Nov 21, 2025
26266c7
Merge branch 'main' into ns/rhmc
nsiccha Dec 16, 2025
280ca15
start minimal refactor for merging into main
nsiccha Dec 18, 2025
6421310
Implement unified Riemannian metric
THargreaves Jan 7, 2026
840cd2d
Fix for compilation
J-Price-3 Jan 13, 2026
cbba891
Fix dHdr to allow Generalised NUTS
J-Price-3 Jan 13, 2026
0c9e825
Add basic validity test for RHMC
J-Price-3 Jan 13, 2026
909d72a
Format
J-Price-3 Jan 14, 2026
642585f
Add funnel test and fix gaussian validation test
J-Price-3 Jan 17, 2026
effb115
Format test/riemannian.jl
J-Price-3 Jan 17, 2026
cb43e2a
Update validation tests to both use w1 distance and a more logical to…
J-Price-3 Jan 19, 2026
3680b87
Reduce validation test tolerance
J-Price-3 Jan 19, 2026
7e91495
Increase validation test tolerance slightly
J-Price-3 Jan 19, 2026
af46f2e
Prevent test type instability
J-Price-3 Jan 21, 2026
41267f1
Fix tests
J-Price-3 Jan 21, 2026
c9d3016
Fix flaky test
J-Price-3 Jan 21, 2026
6494b34
Fix flaky test (I promise it works this time)
J-Price-3 Jan 22, 2026
037aac1
Merge remote-tracking branch 'origin/main' into th/unified-rhmc
THargreaves May 19, 2026
92ac4c6
Make SoftAbs numerically stable
THargreaves May 19, 2026
efd0824
Formatting
THargreaves May 19, 2026
3f7de10
Cached G_eval for use in phasepoint
THargreaves May 19, 2026
21f48c2
Add error for mass-matrix adaptation with RHMC
THargreaves May 19, 2026
686d1a6
Add warning for partial refreshment with RHMC
THargreaves May 19, 2026
f211632
Correct update function signatures
THargreaves May 19, 2026
ad06769
Improve RiemannianMetric type stability
THargreaves May 19, 2026
60291d6
Updated documentation
THargreaves May 19, 2026
632a71d
Deprecate old RHMC interface
THargreaves May 25, 2026
b14dbad
Improve caching for generalised leapfrog integrator
THargreaves May 25, 2026
7677bc3
Fix MacOS unit test by removing warm-up samples
THargreaves May 25, 2026
95788e9
Add canonicalisation of softabs metric
THargreaves May 25, 2026
f6aff9c
Merge remote-tracking branch 'origin/main' into th/unified-rhmc
yebai Jul 9, 2026
8574988
Apply suggestions from code review
yebai Jul 9, 2026
f38d55a
Merge remote-tracking branch 'origin/main' into th/unified-rhmc
yebai Jul 9, 2026
c4314f3
Drop MCMCLogDensityProblems test dep; inline toy targets
yebai Jul 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 24 additions & 8 deletions docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,22 @@ This modularity means that different HMC variants can be easily constructed by c
- Dense metric: `DenseEuclideanMetric(dim)`
- Rank update metric: `RankUpdateEuclideanMetric(dim)`

where `dim` is the dimensionality of the sampling space.
where `dim` is the dimension of the sampling space.

Two experimental position-dependent (Riemannian) metrics are also available:

- `RiemannianMetric((dim,), calc_G, calc_∂G∂θ)` — for user-supplied positive-definite
metrics `G(θ)` (e.g. Fisher information). `calc_G` should return either a plain
`Matrix` or an `AbstractPDMat` (preferred — reuses the stored Cholesky). `calc_∂G∂θ`
returns the `(d, d, d)` tensor `∂G/∂θ`.
- `SoftAbsRiemannianMetric((dim,), calc_H, calc_∂H∂θ, α)` — for Hessian-based metrics
where `H(θ)` is not guaranteed to be positive definite. The SoftAbs transformation
`G = Q · diag(λ · coth(αλ)) · Qᵀ` (Betancourt, 2012) regularises `H`'s eigenvalues
to a strictly positive spectrum. `α` controls how closely SoftAbs approximates `|λ|`.

The legacy `DenseRiemannianMetric(dim, G, ∂G∂θ[, map])` constructor is deprecated and
forwards to the appropriate type above based on whether `map` is `IdentityMap()` or
`SoftAbsMap(α)`.

### [Integrator (`integrator`)](@id integrator)

Expand All @@ -32,17 +47,17 @@ where `ϵ` is the step size of leapfrog integration.
### Adaptor (`adaptor`)

- Adapt the mass matrix `metric` of the Hamiltonian dynamics: `mma = MassMatrixAdaptor(metric)`

+ This is lowered to `UnitMassMatrix`, `WelfordVar` or `WelfordCov` based on the type of the mass matrix `metric`
Comment thread
yebai marked this conversation as resolved.
+ There is an experimental way to improve the *diagonal* mass matrix adaptation using gradient information (similar to [nutpie](https://github.com/pymc-devs/nutpie)),
currently to be initialized for a `metric` of type `DiagEuclideanMetric`
via `mma = AdvancedHMC.NutpieVar(size(metric); var=copy(metric.M⁻¹))`
until a new interface is introduced in an upcoming breaking release to specify the method of adaptation.
currently to be initialized for a `metric` of type `DiagEuclideanMetric`
via `mma = AdvancedHMC.NutpieVar(size(metric); var=copy(metric.M⁻¹))`
until a new interface is introduced in an upcoming breaking release to specify the method of adaptation.

- Adapt the step size of the leapfrog integrator `integrator`: `ssa = StepSizeAdaptor(δ, integrator)`

+ It uses Nesterov's dual averaging with `δ` as the target acceptance rate.
Comment thread
yebai marked this conversation as resolved.

- Combine the two above *naively*: `NaiveHMCAdaptor(mma, ssa)`

- Combine the first two using Stan's windowed adaptation: `StanHMCAdaptor(mma, ssa)`

## The `sample` functions
Expand All @@ -65,14 +80,15 @@ sample(
Draw `n_samples` samples using the kernel `κ` under the Hamiltonian system `h`

- The randomness is controlled by `rng`.

+ If `rng` is not provided, the default random number generator (`Random.default_rng()`) will be used.
Comment thread
yebai marked this conversation as resolved.

- The initial point is given by `θ`.
- The adaptor is set by `adaptor`, for which the default is no adaptation.

- The adaptor is set by `adaptor`, for which the default is no adaptation.
+ It will perform `n_adapts` steps of adaptation, for which the default is `1_000` or 10% of `n_samples`, whichever is lower.
Comment thread
yebai marked this conversation as resolved.

- `drop_warmup` specifies whether to drop samples.

- `verbose` controls the verbosity.
- `progress` controls whether to show the progress meter or not.
Comment thread
yebai marked this conversation as resolved.

Expand Down
13 changes: 12 additions & 1 deletion src/AdvancedHMC.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ using LinearAlgebra:
Diagonal,
AbstractQ,
qr,
lmul!
lmul!,
logdet,
tr,
eigen,
diagm
using IrrationalConstants: loghalf
using LogExpFunctions: logaddexp, logsumexp
using Random: Random, AbstractRNG
Expand Down Expand Up @@ -71,6 +75,13 @@ export Leapfrog, JitteredLeapfrog, TemperedLeapfrog
include("riemannian/integrator.jl")
export GeneralizedLeapfrog

include("riemannian/metric.jl")
export RiemannianMetric, SoftAbsRiemannianMetric
# Deprecated exports (for backward compatibility)
export IdentityMap, SoftAbsMap, DenseRiemannianMetric

include("riemannian/hamiltonian.jl")

include("trajectory.jl")
export Trajectory,
HMCKernel,
Expand Down
8 changes: 6 additions & 2 deletions src/hamiltonian.jl
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,11 @@ function Base.similar(z::PhasePoint{<:AbstractVecOrMat{T}}) where {T<:AbstractFl
end

function phasepoint(
h::Hamiltonian, θ::T, r::T; ℓπ=∂H∂θ(h, θ), ℓκ=DualValue(neg_energy(h, r, θ), ∂H∂r(h, r))
h::Hamiltonian,
θ::T,
r::T;
ℓπ=∂H∂θ(h, θ),
ℓκ=DualValue(neg_energy(h, r, θ), ∂H∂r(h, θ, r)),
) where {T<:AbstractVecOrMat}
return PhasePoint(θ, r, ℓπ, ℓκ)
end
Expand All @@ -127,7 +131,7 @@ function phasepoint(
_r::T2;
r=safe_rsimilar(θ, _r),
ℓπ=∂H∂θ(h, θ),
ℓκ=DualValue(neg_energy(h, r, θ), ∂H∂r(h, r)),
ℓκ=DualValue(neg_energy(h, r, θ), ∂H∂r(h, θ, r)),
) where {T1<:AbstractVecOrMat,T2<:AbstractVecOrMat}
return PhasePoint(θ, r, ℓπ, ℓκ)
end
Expand Down
Loading
Loading