Skip to content

Commit cdef753

Browse files
Apply suggestions from code review
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 3bbb17f commit cdef753

File tree

3 files changed

+52
-35
lines changed

3 files changed

+52
-35
lines changed

src/relativistic/hamiltonian.jl

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,10 @@ struct RelativisticKinetic{T} <: AbstractRelativisticKinetic{T}
77
c::T
88
end
99

10-
relativistic_mass(kinetic::RelativisticKinetic, r, r′ = r) =
11-
kinetic.m * sqrt(dot(r, r′) / (kinetic.m ^ 2 * kinetic.c ^ 2) + 1)
12-
relativistic_energy(kinetic::RelativisticKinetic, r, r′ = r) = sum(
13-
kinetic.c ^ 2 * relativistic_mass(kinetic, r, r′)
14-
)
10+
relativistic_mass(kinetic::RelativisticKinetic, r, r′ = r) =
11+
kinetic.m * sqrt(dot(r, r′) / (kinetic.m^2 * kinetic.c^2) + 1)
12+
relativistic_energy(kinetic::RelativisticKinetic, r, r′ = r) =
13+
sum(kinetic.c^2 * relativistic_mass(kinetic, r, r′))
1514

1615
struct DimensionwiseRelativisticKinetic{T} <: AbstractRelativisticKinetic{T}
1716
"Mass"
@@ -20,11 +19,10 @@ struct DimensionwiseRelativisticKinetic{T} <: AbstractRelativisticKinetic{T}
2019
c::T
2120
end
2221

23-
relativistic_mass(kinetic::DimensionwiseRelativisticKinetic, r, r′ = r) =
22+
relativistic_mass(kinetic::DimensionwiseRelativisticKinetic, r, r′ = r) =
2423
kinetic.m .* sqrt.(r .* r′ ./ (kinetic.m .^ 2 .* kinetic.c .^ 2) .+ 1)
25-
relativistic_energy(kinetic::DimensionwiseRelativisticKinetic, r, r′ = r) = sum(
26-
kinetic.c .^ 2 .* relativistic_mass(kinetic, r, r′)
27-
)
24+
relativistic_energy(kinetic::DimensionwiseRelativisticKinetic, r, r′ = r) =
25+
sum(kinetic.c .^ 2 .* relativistic_mass(kinetic, r, r′))
2826

2927
function ∂H∂r(
3028
h::Hamiltonian{<:UnitEuclideanMetric,<:AbstractRelativisticKinetic},
@@ -42,7 +40,10 @@ function ∂H∂r(
4240
red_term = r ./ mass # red part of (15)
4341
return h.metric.sqrtM⁻¹ .* red_term # (15)
4442
end
45-
function ∂H∂r(h::Hamiltonian{<:DenseEuclideanMetric, <:AbstractRelativisticKinetic}, r::AbstractVecOrMat)
43+
function ∂H∂r(
44+
h::Hamiltonian{<:DenseEuclideanMetric,<:AbstractRelativisticKinetic},
45+
r::AbstractVecOrMat,
46+
)
4647
r = h.metric.cholM⁻¹ * r
4748
mass = relativistic_mass(h.kinetic, r)
4849
red_term = r ./ mass
@@ -67,7 +68,7 @@ end
6768
function neg_energy(
6869
h::Hamiltonian{<:DenseEuclideanMetric,<:AbstractRelativisticKinetic},
6970
r::T,
70-
θ::T
71+
θ::T,
7172
) where {T<:AbstractVector}
7273
r = h.metric.cholM⁻¹ * r
7374
return -relativistic_energy(h.kinetic, r)

src/riemannian/hamiltonian.jl

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,22 @@ phasepoint(
1111
# Negative kinetic energy
1212
#! Eq (13) of Girolami & Calderhead (2011)
1313
function neg_energy(
14-
h::Hamiltonian{<:DenseRiemannianMetric, <:GaussianKinetic},
14+
h::Hamiltonian{<:DenseRiemannianMetric,<:GaussianKinetic},
1515
r::T,
1616
θ::T,
1717
) where {T<:AbstractVecOrMat}
1818
G = h.metric.map(h.metric.G(θ))
1919
# Need to consider the normalizing term as it is no longer same for different θs
2020
logZ = 1 / 2 * (size(G, 1) * log(2π) + logdet(G)) # it will be user's responsibility to make sure G is SPD and logdet(G) is defined
21-
2221
mul!(h.metric._temp, inv(G), r)
2322
# ldiv!(h.metric._temp, cholesky(G), r) # https://docs.julialang.org/en/v1/stdlib/LinearAlgebra/#LinearAlgebra.ldiv!
2423
return -logZ - dot(r, h.metric._temp) / 2
2524
end
2625

2726
function neg_energy(
28-
h::Hamiltonian{<:DenseRiemannianMetric, <:AbstractRelativisticKinetic},
27+
h::Hamiltonian{<:DenseRiemannianMetric,<:AbstractRelativisticKinetic},
2928
r::T,
30-
θ::T
29+
θ::T,
3130
) where {T<:AbstractVecOrMat}
3231
G = h.metric.map(h.metric.G(θ))
3332
# Need to consider the normalizing term as it is no longer same for different θs
@@ -39,12 +38,12 @@ function neg_energy(
3938

4039
mul!(h.metric._temp, inv(G), r)
4140
# ldiv!(h.metric._temp, cholesky(G), r) # https://docs.julialang.org/en/v1/stdlib/LinearAlgebra/#LinearAlgebra.ldiv!
42-
return -relativistic_energy(h.kinetic, r, h.metric._temp) - logZ_partial
41+
return -relativistic_energy(h.kinetic, r, h.metric._temp) - logZ_partial
4342
end
4443

4544
# QUES L31 of hamiltonian.jl now reads a bit weird (semantically)
4645
function ∂H∂θ(
47-
h::Hamiltonian{<:DenseRiemannianMetric{T,<:IdentityMap}, <:GaussianKinetic},
46+
h::Hamiltonian{<:DenseRiemannianMetric{T,<:IdentityMap},<:GaussianKinetic},
4847
θ::AbstractVecOrMat{T},
4948
r::AbstractVecOrMat{T},
5049
) where {T}
@@ -68,7 +67,7 @@ function ∂H∂θ(
6867
end
6968

7069
function ∂H∂θ(
71-
h::Hamiltonian{<:DenseRiemannianMetric{T,<:IdentityMap}, <:AbstractRelativisticKinetic},
70+
h::Hamiltonian{<:DenseRiemannianMetric{T,<:IdentityMap},<:AbstractRelativisticKinetic},
7271
θ::AbstractVecOrMat{T},
7372
r::AbstractVecOrMat{T},
7473
) where {T}
@@ -130,7 +129,8 @@ function ∂H∂θ_cache(
130129
term_2 = Q * D * J * D * Q'
131130

132131
isdiag = ∂H∂θ isa AbstractMatrix
133-
g = isdiag ?
132+
g =
133+
isdiag ?
134134
-(∂ℓπ∂θ - 1 / 2 * diag(term_1_cached * ∂H∂θ) + 1 / 2 * diag(term_2 * ∂H∂θ)) :
135135
-mapreduce(vcat, 1:d) do i
136136
∂H∂θᵢ = ∂H∂θ[:, :, i]
@@ -149,8 +149,8 @@ end
149149
r::AbstractVecOrMat{T},
150150
) where {T} = ∂H∂θ_cache(h, θ, r)
151151
function ∂H∂θ_cache(
152-
h::Hamiltonian{<:DenseRiemannianMetric{T,<:SoftAbsMap},<:RelativisticKinetic},
153-
θ::AbstractVecOrMat{T},
152+
h::Hamiltonian{<:DenseRiemannianMetric{T,<:SoftAbsMap},<:RelativisticKinetic},
153+
θ::AbstractVecOrMat{T},
154154
r::AbstractVecOrMat{T};
155155
return_cache = false,
156156
cache = nothing,
@@ -207,11 +207,16 @@ function ∂H∂θ_cache(
207207
# @assert false
208208

209209
isdiag = ∂H∂θ isa AbstractMatrix
210-
g = isdiag ?
211-
-(∂ℓπ∂θ - 1 / 2 * diag(term_1_cached * ∂H∂θ) + 1 / 2 * (1 / mass) * diag(term_2 * ∂H∂θ)) :
210+
g =
211+
isdiag ?
212+
-(
213+
∂ℓπ∂θ - 1 / 2 * diag(term_1_cached * ∂H∂θ) +
214+
1 / 2 * (1 / mass) * diag(term_2 * ∂H∂θ)
215+
) :
212216
-mapreduce(vcat, 1:d) do i
213-
∂H∂θᵢ = ∂H∂θ[:,:,i]
214-
∂ℓπ∂θ[i] - 1 / 2 * tr(term_1_cached * ∂H∂θᵢ) + 1 / 2 * (1 / mass) * tr(term_2 * ∂H∂θᵢ) # (v2) cache friendly
217+
∂H∂θᵢ = ∂H∂θ[:, :, i]
218+
∂ℓπ∂θ[i] - 1 / 2 * tr(term_1_cached * ∂H∂θᵢ) +
219+
1 / 2 * (1 / mass) * tr(term_2 * ∂H∂θᵢ) # (v2) cache friendly
215220
end
216221

217222
dv = DualValue(ℓπ, g)
@@ -220,8 +225,11 @@ end
220225

221226
# FIXME This implementation for dimensionwise is incorrect
222227
function ∂H∂θ(
223-
h::Hamiltonian{<:DenseRiemannianMetric{T,<:SoftAbsMap},<:DimensionwiseRelativisticKinetic},
224-
θ::AbstractVecOrMat{T},
228+
h::Hamiltonian{
229+
<:DenseRiemannianMetric{T,<:SoftAbsMap},
230+
<:DimensionwiseRelativisticKinetic,
231+
},
232+
θ::AbstractVecOrMat{T},
225233
r::AbstractVecOrMat{T},
226234
) where {T}
227235
ℓπ, ∂ℓπ∂θ = h.∂ℓπ∂θ(θ)
@@ -251,7 +259,7 @@ function ∂H∂θ(
251259

252260
term_2_cached = Q * D * J * D * Q'
253261
g = -mapreduce(vcat, 1:d) do i
254-
∂H∂θᵢ = ∂H∂θ[:,:,i]
262+
∂H∂θᵢ = ∂H∂θ[:, :, i]
255263
# ∂ℓπ∂θ[i] - 1 / 2 * tr(term_1_cached * ∂H∂θᵢ) + 1 / 2 * M' * (J .* (Q' * ∂H∂θᵢ * Q)) * M # (v1)
256264
# NOTE Some further optimization can be done here: cache the 1st product all together
257265
∂ℓπ∂θ[i] - 1 / 2 * term_1_cached[i] * -tr(term_2_cached * ∂H∂θᵢ) # (v2) cache friendly
@@ -262,7 +270,7 @@ end
262270

263271
#! Eq (14) of Girolami & Calderhead (2011)
264272
function ∂H∂r(
265-
h::Hamiltonian{<:DenseRiemannianMetric, <:GaussianKinetic},
273+
h::Hamiltonian{<:DenseRiemannianMetric,<:GaussianKinetic},
266274
θ::AbstractVecOrMat,
267275
r::AbstractVecOrMat,
268276
)
@@ -277,7 +285,11 @@ function ∂H∂r(
277285
return G \ r # NOTE it's actually pretty weird that ∂H∂θ returns DualValue but ∂H∂r doesn't
278286
end
279287

280-
function ∂H∂r(h::Hamiltonian{<:DenseRiemannianMetric, <:AbstractRelativisticKinetic}, θ::AbstractVecOrMat, r::AbstractVecOrMat)
288+
function ∂H∂r(
289+
h::Hamiltonian{<:DenseRiemannianMetric,<:AbstractRelativisticKinetic},
290+
θ::AbstractVecOrMat,
291+
r::AbstractVecOrMat,
292+
)
281293
M = h.metric.map(h.metric.G(θ))
282294
# M⁻¹ = inv(M)
283295
# cholM⁻¹ = cholesky(Symmetric(M⁻¹)).U

src/riemannian/metric.jl

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ end
1414
#! The definition of SoftAbs from Page 3 of Betancourt (2012)
1515
function softabs(X, α = 20.0)
1616
F = eigen(
17-
Symmetric(X) # NOTE ~Symmetric~ is needed to avid eigen returns complex numbers
17+
Symmetric(X), # NOTE ~Symmetric~ is needed to avid eigen returns complex numbers
1818
) # ReverseDiff cannot diff through `eigen`
1919
Q = hcat(F.vectors)
2020
λ = F.values
2121
softabsλ = λ .* coth.(α * λ)
2222
return Q * Diagonal(softabsλ) * Q', Q, λ, softabsλ
2323
end
2424

25-
function softabs(X::T, α = 20.0) where {T <: Diagonal}
25+
function softabs(X::T, α = 20.0) where {T<:Diagonal}
2626
Q = I
2727
λ = X.diag
2828
softabsλ = λ .* coth.(α * λ)
@@ -59,7 +59,7 @@ Base.show(io::IO, dem::DenseRiemannianMetric) = print(io, "DenseRiemannianMetric
5959
function _rand(
6060
rng::Union{AbstractRNG,AbstractVector{<:AbstractRNG}},
6161
metric::DenseRiemannianMetric{T},
62-
kinetic::Union{GaussianKinetic, <:AbstractRelativisticKinetic{T}},
62+
kinetic::Union{GaussianKinetic,<:AbstractRelativisticKinetic{T}},
6363
θ::AbstractVecOrMat,
6464
) where {T}
6565
r = _rand(rng, UnitEuclideanMetric(size(metric)), kinetic)
@@ -69,8 +69,12 @@ function _rand(
6969
return r
7070
end
7171

72-
Base.rand(rng::AbstractRNG, metric::AbstractRiemannianMetric, kinetic::AbstractKinetic, θ::AbstractVecOrMat) =
73-
_rand(rng, metric, kinetic, θ)
72+
Base.rand(
73+
rng::AbstractRNG,
74+
metric::AbstractRiemannianMetric,
75+
kinetic::AbstractKinetic,
76+
θ::AbstractVecOrMat,
77+
) = _rand(rng, metric, kinetic, θ)
7478
Base.rand(
7579
rng::AbstractVector{<:AbstractRNG},
7680
metric::AbstractRiemannianMetric,

0 commit comments

Comments
 (0)