Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

general relativistic HMC #372

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open

general relativistic HMC #372

wants to merge 10 commits into from

Conversation

xukai92
Copy link
Member

@xukai92 xukai92 commented Jul 25, 2024

No description provided.

xukai92 and others added 3 commits July 25, 2024 12:45
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@xukai92 xukai92 marked this pull request as ready for review October 26, 2024 16:07
@xukai92 xukai92 requested a review from yebai October 26, 2024 16:07
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remaining comments which cannot be posted as a review comment to avoid GitHub Rate Limit

JuliaFormatter

[JuliaFormatter] reported by reviewdog 🐶

z_lst = step(
proposal.τ.integrator,
hamiltonian,
z₀,
hps.L;
full_trajectory = Val(true),
)


[JuliaFormatter] reported by reviewdog 🐶

UnitEuclideanMetric(D),
DiagEuclideanMetric(D),
DiagEuclideanMetric([0.5, 4.0]),
DenseEuclideanMetric(D),
DenseEuclideanMetric([1.32 0.79; 0.79 0.48]),
]


[JuliaFormatter] reported by reviewdog 🐶

RelativisticKinetic(hps.m, hps.c),


[JuliaFormatter] reported by reviewdog 🐶

finite_difference_gradient(Hamifuncr, r),


[JuliaFormatter] reported by reviewdog 🐶

@testset "$(nameof(typeof(target)))" for target in [
HighDimGaussian(2),
Funnel(),
]


[JuliaFormatter] reported by reviewdog 🐶

@test δ(reshape_∂G∂θ(finite_difference_jacobian(Gfunc, x)), ∂G∂θfunc(x)) < TARGET_TOL


[JuliaFormatter] reported by reviewdog 🐶

@testset "$(nameof(typeof(hessmap)))" for hessmap in [
IdentityMap(),
SoftAbsMap(hps.α),
]


[JuliaFormatter] reported by reviewdog 🐶

GaussianKinetic(),
RelativisticKinetic(hps.m, hps.c),
DimensionwiseRelativisticKinetic(hps.m, hps.c),
]


[JuliaFormatter] reported by reviewdog 🐶

(hessmap isa SoftAbsMap || all(iszero.(x))) # that of IdentityMap can be non-PD for x==0 that I know it's PD


[JuliaFormatter] reported by reviewdog 🐶

@test neg_energy(hamiltonian, r, x) logpdf(MvNormal(zeros(D), Σ), r)


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

) < HAMILTONIAN_TOL broken=broken


[JuliaFormatter] reported by reviewdog 🐶

finite_difference_gradient(Hamifuncr, r),


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶


[JuliaFormatter] reported by reviewdog 🐶

) = _rand(rng, metric, kinetic, θ)

const axes_grid1 = pyimport("mpl_toolkits.axes_grid1")
plt.style.use("bmh")
function subplots(args...; kwargs...)
retval = plt.subplots(args...; tight_layout=true, kwargs...)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
retval = plt.subplots(args...; tight_layout=true, kwargs...)
retval = plt.subplots(args...; tight_layout = true, kwargs...)

return retval
end
function savefig(fig, fn; kwargs...)
fig.savefig(fn; bbox_inches="tight", kwargs...)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
fig.savefig(fn; bbox_inches="tight", kwargs...)
fig.savefig(fn; bbox_inches = "tight", kwargs...)

isdistributed() = isdefined(Main, :Distributed)

"pmap if Distribued is used"
maybepmap(args...; kwargs...) =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
maybepmap(args...; kwargs...) =
maybepmap(args...; kwargs...) =

for dir_type in ("artifacts", "results", "log")
function_name = Symbol(dir_type * "dir")
@eval begin
$function_name(args...; suffix="") = projectdir($dir_type, args...) * (isempty(suffix) ? "" : "-$suffix")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
$function_name(args...; suffix="") = projectdir($dir_type, args...) * (isempty(suffix) ? "" : "-$suffix")
$function_name(args...; suffix = "") =
projectdir($dir_type, args...) * (isempty(suffix) ? "" : "-$suffix")

return path
end

function make_Z(f, is=nothing, js=nothing; xlim=(-6, 2), ylim=(-2, 2))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
function make_Z(f, is=nothing, js=nothing; xlim=(-6, 2), ylim=(-2, 2))
function make_Z(f, is = nothing, js = nothing; xlim = (-6, 2), ylim = (-2, 2))

Comment on lines +216 to +217

kinetic = get(hps, :kinetic, :gaussian) == :gaussian ? GaussianKinetic() : # support missing kinetic in hps
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
kinetic = get(hps, :kinetic, :gaussian) == :gaussian ? GaussianKinetic() : # support missing kinetic in hps
kinetic =
get(hps, :kinetic, :gaussian) == :gaussian ? GaussianKinetic() : # support missing kinetic in hps


kinetic = get(hps, :kinetic, :gaussian) == :gaussian ? GaussianKinetic() : # support missing kinetic in hps
hps.kinetic == :relativistic ? RelativisticKinetic(hps.m, hps.c) :
hps.kinetic == :dimwise_relativistic ? DimensionwiseRelativisticKinetic(hps.m, hps.c) :
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
hps.kinetic == :dimwise_relativistic ? DimensionwiseRelativisticKinetic(hps.m, hps.c) :
hps.kinetic == :dimwise_relativistic ?
DimensionwiseRelativisticKinetic(hps.m, hps.c) :

return (; rng, target, hamiltonian, proposal, θ₀)
end

function sample_target(hps; rng = MersenneTwister(1110), output_only::Bool=false)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
function sample_target(hps; rng = MersenneTwister(1110), output_only::Bool=false)
function sample_target(hps; rng = MersenneTwister(1110), output_only::Bool = false)

Comment on lines +266 to +267

z₀ = initial_momentum isa AbstractVector ? phasepoint(hamiltonian, θ₀, initial_momentum) :
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
z₀ = initial_momentum isa AbstractVector ? phasepoint(hamiltonian, θ₀, initial_momentum) :
z₀ =
initial_momentum isa AbstractVector ?
phasepoint(hamiltonian, θ₀, initial_momentum) :

initial_momentum == :default ? phasepoint(rng, θ₀, hamiltonian) :
# NOTE The two options below ensures intiial momentum is identical
initial_momentum == :simple ? phasepoint(hamiltonian, θ₀, randn(rng, size(θ₀)...)) :
initial_momentum == :gaussian_kinetic ? phasepoint(hamiltonian, θ₀, rand(rng, hamiltonian.metric, GaussianKinetic(), θ₀)) :
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
initial_momentum == :gaussian_kinetic ? phasepoint(hamiltonian, θ₀, rand(rng, hamiltonian.metric, GaussianKinetic(), θ₀)) :
initial_momentum == :gaussian_kinetic ?
phasepoint(hamiltonian, θ₀, rand(rng, hamiltonian.metric, GaussianKinetic(), θ₀)) :

Copy link
Member

@yebai yebai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some comments above. Will continue later.

ArgCheck = "1, 2"
CUDA = "3, 4, 5"
DocStringExtensions = "0.8, 0.9"
InplaceOps = "0.3"
LinearAlgebra = "1.6"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate with L53.

Suggested change
LinearAlgebra = "1.6"

@@ -4,6 +4,7 @@ version = "0.6.2"

[deps]
AbstractMCMC = "80f14c24-f653-4e6a-9b94-39d6b0f70001"
AdaptiveRejectionSampling = "c75e803d-635f-53bd-ab7d-544e482d8c75"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A minor issue: Do we want to depend on ARS? Is it possible to turn this into a weak deps?

include("relativistic/hamiltonian.jl")
export RelativisticKinetic, DimensionwiseRelativisticKinetic

using AdaptiveRejectionSampling: RejectionSampler, run_sampler!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider turning ARS into an AHMCARSext extension so ARS is a weak dep. See also the above comment about ARS.

relativistic_energy(kinetic::RelativisticKinetic, r, r′ = r) =
sum(kinetic.c^2 * relativistic_mass(kinetic, r, r′))

struct DimensionwiseRelativisticKinetic{T} <: AbstractRelativisticKinetic{T}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a ref to:

Lu, X., Perrone, V., Hasenclever, L., Teh, Y., & Vollmer, S. (2016). Relativistic Monte Carlo. International Conference on Artificial Intelligence and Statistics, 54, 1236–1245.


relativistic_mass(kinetic::RelativisticKinetic, r, r′ = r) =
kinetic.m * sqrt(dot(r, r′) / (kinetic.m^2 * kinetic.c^2) + 1)
relativistic_energy(kinetic::RelativisticKinetic, r, r′ = r) =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
relativistic_energy(kinetic::RelativisticKinetic, r, r′ = r) =
# Negative kinetic energy
relativistic_energy(kinetic::RelativisticKinetic, r, r′ = r) =

Copy link
Member

@yebai yebai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xukai92 I added some further comments. Please take a look.

A high-level comment:

  • Perhaps we should add a folder general_relavistic (or riemannian_relativistic), and move all general relavistic code there: general_relavistic/hamiltonian.jl and general_relavistic/metric.jl.


relativistic_mass(kinetic::DimensionwiseRelativisticKinetic, r, r′ = r) =
kinetic.m .* sqrt.(r .* r′ ./ (kinetic.m .^ 2 .* kinetic.c .^ 2) .+ 1)
relativistic_energy(kinetic::DimensionwiseRelativisticKinetic, r, r′ = r) =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
relativistic_energy(kinetic::DimensionwiseRelativisticKinetic, r, r′ = r) =
# Negative kinetic energy
# Eq (5) of Lu et al. (2016)
relativistic_energy(kinetic::DimensionwiseRelativisticKinetic, r, r′ = r) =

return -relativistic_energy(h.kinetic, r, h.metric._temp) - logZ_partial
end

# QUES L31 of hamiltonian.jl now reads a bit weird (semantically)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't follow this comment. Consider removing or clarifying.

Comment on lines +61 to +64
# Gr = G \ r
# ∂ℓπ∂θ[i] - 1 / 2 * tr(G \ ∂G∂θᵢ) + 1 / 2 * Gr' * ∂G∂θᵢ * Gr
# 1 / 2 * tr(invG * ∂G∂θᵢ)
# 1 / 2 * r' * invG * ∂G∂θᵢ * invG * r
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Gr = G \ r
# ∂ℓπ∂θ[i] - 1 / 2 * tr(G \ ∂G∂θᵢ) + 1 / 2 * Gr' * ∂G∂θᵢ * Gr
# 1 / 2 * tr(invG * ∂G∂θᵢ)
# 1 / 2 * r' * invG * ∂G∂θᵢ * invG * r

#! (18) of Overleaf note
mass = relativistic_mass(h.kinetic, r, M \ r)

# TODO convert the code below to a test case
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's convert this to a test in this PR.

return return_cache ? (dv, (; ℓπ, ∂ℓπ∂θ, ∂H∂θ, Q, softabsλ, J, term_1_cached, M)) : dv
end

# FIXME This implementation for dimensionwise is incorrect
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@torfjelde is this fixed now?

return J
end

# TODO Add stricter types to block hamiltonian.jl#L37 from working on unknown metric/kinetic
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is likely fragile due to the concrete reference to line number.
Consider fixing it or use a better reference (e.g. refer to a function name)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants