diff --git a/src/DynamicPPL.jl b/src/DynamicPPL.jl index 774a8010f..9d870c9e8 100644 --- a/src/DynamicPPL.jl +++ b/src/DynamicPPL.jl @@ -116,7 +116,7 @@ export AbstractVarInfo, logprior, logjoint, pointwise_loglikelihoods, - varwise_logpriors, + pointwise_logdensities, condition, decondition, fix, @@ -182,8 +182,7 @@ include("varinfo.jl") include("simple_varinfo.jl") include("context_implementations.jl") include("compiler.jl") -include("loglikelihoods.jl") -include("logpriors_var.jl") +include("pointwise_logdensities.jl") include("submodel_macro.jl") include("test_utils.jl") include("transforming.jl") @@ -191,6 +190,7 @@ include("logdensityfunction.jl") include("model_utils.jl") include("extract_priors.jl") include("values_as_in_model.jl") +include("deprecated.jl") include("debug_utils.jl") using .DebugUtils diff --git a/src/deprecated.jl b/src/deprecated.jl new file mode 100644 index 000000000..09e1ac84d --- /dev/null +++ b/src/deprecated.jl @@ -0,0 +1,9 @@ +# https://invenia.github.io/blog/2022/06/17/deprecating-in-julia/ + +Base.@deprecate pointwise_loglikelihoods(model::Model, chain, keytype) pointwise_logdensities( + model::Model, LikelihoodContext(), chain, keytype) + +Base.@deprecate pointwise_loglikelihoods( + model::Model, varinfo::AbstractVarInfo) pointwise_logdensities( + model::Model, varinfo, LikelihoodContext()) + diff --git a/src/logpriors_var.jl b/src/logpriors_var.jl deleted file mode 100644 index 1860d8ccd..000000000 --- a/src/logpriors_var.jl +++ /dev/null @@ -1,143 +0,0 @@ -""" -Context that records logp after tilde_assume!! -for each VarName used by [`varwise_logpriors`](@ref). -""" -struct VarwisePriorContext{A,Ctx} <: AbstractContext - logpriors::A - context::Ctx -end - -function VarwisePriorContext( - logpriors=OrderedDict{Symbol,Float64}(), - context::AbstractContext=DynamicPPL.PriorContext(), - #OrderedDict{Symbol,Vector{Float64}}(),PriorContext()), -) - return VarwisePriorContext{typeof(logpriors),typeof(context)}( - logpriors, context - ) -end - -NodeTrait(::VarwisePriorContext) = IsParent() -childcontext(context::VarwisePriorContext) = context.context -function setchildcontext(context::VarwisePriorContext, child) - return VarwisePriorContext(context.logpriors, child) -end - -function tilde_assume(context::VarwisePriorContext, right, vn, vi) - #@info "VarwisePriorContext tilde_assume!! called for $vn" - value, logp, vi = tilde_assume(context.context, right, vn, vi) - #sym = DynamicPPL.getsym(vn) - new_context = acc_logp!(context, vn, logp) - return value, logp, vi -end - -function dot_tilde_assume(context::VarwisePriorContext, right, left, vn, vi) - #@info "VarwisePriorContext dot_tilde_assume!! called for $vn" - # @show vn, left, right, typeof(context).name - value, logp, vi = dot_tilde_assume(context.context, right, left, vn, vi) - new_context = acc_logp!(context, vn, logp) - return value, logp, vi -end - - -tilde_observe(context::VarwisePriorContext, right, left, vi) = 0, vi -dot_tilde_observe(::VarwisePriorContext, right, left, vi) = 0, vi - -function acc_logp!(context::VarwisePriorContext, vn::Union{VarName,AbstractVector{<:VarName}}, logp) - #sym = DynamicPPL.getsym(vn) # leads to duplicates - # if vn is a Vector leads to Symbol("VarName{:s, IndexLens{Tuple{Int64}}}[s[1], s[2]]") - sym = Symbol(vn) - context.logpriors[sym] = logp - return (context) -end - -""" - varwise_logpriors(model::Model, chain::Chains; context) - -Runs `model` on each sample in `chain` returning a tuple `(values, var_names)` -with var_names corresponding to symbols of the prior components, and values being -array of shape `(num_samples, num_components, num_chains)`. - -`context` specifies child context that handles computation of log-priors. - -# Example -```julia; setup = :(using Distributions) -using DynamicPPL, Turing - -@model function demo(x, ::Type{TV}=Vector{Float64}) where {TV} - s ~ InverseGamma(2, 3) - m = TV(undef, length(x)) - for i in eachindex(x) - m[i] ~ Normal(0, √s) - end - x ~ MvNormal(m, √s) - end - -model = demo(randn(3), randn()); - -chain = sample(model, MH(), 10); - -lp = varwise_logpriors(model, chain) -# Can be used to construct a new Chains object -#lpc = MCMCChains(varwise_logpriors(model, chain)...) - -# got a logdensity for each parameter prior -(but fewer if used `.~` assignments, see below) -lp[2] == names(chain, :parameters) - -# for each sample in the Chains object -size(lp[1])[[1,3]] == size(chain)[[1,3]] -``` - -# Broadcasting -Note that `m .~ Dist()` will treat `m` as a collection of -_independent_ prior rather than as a single prior, -but `varwise_logpriors` returns the single -sum of log-likelihood of components of `m` only. -If one needs the log-density of the components, one needs to rewrite -the model with an explicit loop. -""" -function varwise_logpriors( - model::Model, varinfo::AbstractVarInfo, - context::AbstractContext=PriorContext() -) -# top_context = VarwisePriorContext(OrderedDict{Symbol,Float64}(), context) - top_context = VarwisePriorContext(OrderedDict{Symbol,Float64}(), context) - model(varinfo, top_context) - return top_context.logpriors -end - -function varwise_logpriors(model::Model, chain::AbstractChains, - context::AbstractContext=PriorContext(); - top_context::VarwisePriorContext{T} = VarwisePriorContext(OrderedDict{Symbol,Float64}(), context) - ) where T - # pass top-context as keyword to allow adapt Number type of log-prior - get_values = (vi) -> begin - model(vi, top_context) - values(top_context.logpriors) - end - arr = map_model(get_values, model, chain) - par_names = collect(keys(top_context.logpriors)) - return(arr, par_names) -end - -function map_model(get_values, model::Model, chain::AbstractChains) - niters = size(chain, 1) - nchains = size(chain, 3) - vi = VarInfo(model) - iters = Iterators.product(1:size(chain, 1), 1:size(chain, 3)) - # initialize the array by the first result - (sample_idx, chain_idx), iters2 = Iterators.peel(iters) - setval!(vi, chain, sample_idx, chain_idx) - values1 = get_values(vi) - arr = Array{eltype(values1)}(undef, niters, length(values1), nchains) - arr[sample_idx, :, chain_idx] .= values1 - #(sample_idx, chain_idx), iters3 = Iterators.peel(iters2) - for (sample_idx, chain_idx) in iters2 - # Update the values - setval!(vi, chain, sample_idx, chain_idx) - values_i = get_values(vi) - arr[sample_idx, :, chain_idx] .= values_i - end - return(arr) -end diff --git a/src/loglikelihoods.jl b/src/pointwise_logdensities.jl similarity index 59% rename from src/loglikelihoods.jl rename to src/pointwise_logdensities.jl index 227a70889..73d3e5c0c 100644 --- a/src/loglikelihoods.jl +++ b/src/pointwise_logdensities.jl @@ -1,83 +1,83 @@ # Context version -struct PointwiseLikelihoodContext{A,Ctx} <: AbstractContext - loglikelihoods::A +struct PointwiseLogdensityContext{A,Ctx} <: AbstractContext + logdensities::A context::Ctx end -function PointwiseLikelihoodContext( +function PointwiseLogdensityContext( likelihoods=OrderedDict{VarName,Vector{Float64}}(), - context::AbstractContext=LikelihoodContext(), + context::AbstractContext=DefaultContext(), ) - return PointwiseLikelihoodContext{typeof(likelihoods),typeof(context)}( + return PointwiseLogdensityContext{typeof(likelihoods),typeof(context)}( likelihoods, context ) end -NodeTrait(::PointwiseLikelihoodContext) = IsParent() -childcontext(context::PointwiseLikelihoodContext) = context.context -function setchildcontext(context::PointwiseLikelihoodContext, child) - return PointwiseLikelihoodContext(context.loglikelihoods, child) +NodeTrait(::PointwiseLogdensityContext) = IsParent() +childcontext(context::PointwiseLogdensityContext) = context.context +function setchildcontext(context::PointwiseLogdensityContext, child) + return PointwiseLogdensityContext(context.logdensities, child) end function Base.push!( - context::PointwiseLikelihoodContext{<:AbstractDict{VarName,Vector{Float64}}}, + context::PointwiseLogdensityContext{<:AbstractDict{VarName,Vector{Float64}}}, vn::VarName, logp::Real, ) - lookup = context.loglikelihoods + lookup = context.logdensities ℓ = get!(lookup, vn, Float64[]) return push!(ℓ, logp) end function Base.push!( - context::PointwiseLikelihoodContext{<:AbstractDict{VarName,Float64}}, + context::PointwiseLogdensityContext{<:AbstractDict{VarName,Float64}}, vn::VarName, logp::Real, ) - return context.loglikelihoods[vn] = logp + return context.logdensities[vn] = logp end function Base.push!( - context::PointwiseLikelihoodContext{<:AbstractDict{String,Vector{Float64}}}, + context::PointwiseLogdensityContext{<:AbstractDict{String,Vector{Float64}}}, vn::VarName, logp::Real, ) - lookup = context.loglikelihoods + lookup = context.logdensities ℓ = get!(lookup, string(vn), Float64[]) return push!(ℓ, logp) end function Base.push!( - context::PointwiseLikelihoodContext{<:AbstractDict{String,Float64}}, + context::PointwiseLogdensityContext{<:AbstractDict{String,Float64}}, vn::VarName, logp::Real, ) - return context.loglikelihoods[string(vn)] = logp + return context.logdensities[string(vn)] = logp end function Base.push!( - context::PointwiseLikelihoodContext{<:AbstractDict{String,Vector{Float64}}}, + context::PointwiseLogdensityContext{<:AbstractDict{String,Vector{Float64}}}, vn::String, logp::Real, ) - lookup = context.loglikelihoods + lookup = context.logdensities ℓ = get!(lookup, vn, Float64[]) return push!(ℓ, logp) end function Base.push!( - context::PointwiseLikelihoodContext{<:AbstractDict{String,Float64}}, + context::PointwiseLogdensityContext{<:AbstractDict{String,Float64}}, vn::String, logp::Real, ) - return context.loglikelihoods[vn] = logp + return context.logdensities[vn] = logp end -function tilde_observe!!(context::PointwiseLikelihoodContext, right, left, vi) +function tilde_observe!!(context::PointwiseLogdensityContext, right, left, vi) # Defer literal `observe` to child-context. return tilde_observe!!(context.context, right, left, vi) end -function tilde_observe!!(context::PointwiseLikelihoodContext, right, left, vn, vi) +function tilde_observe!!(context::PointwiseLogdensityContext, right, left, vn, vi) # Need the `logp` value, so we cannot defer `acclogp!` to child-context, i.e. # we have to intercept the call to `tilde_observe!`. logp, vi = tilde_observe(context.context, right, left, vi) @@ -88,11 +88,11 @@ function tilde_observe!!(context::PointwiseLikelihoodContext, right, left, vn, v return left, acclogp!!(vi, logp) end -function dot_tilde_observe!!(context::PointwiseLikelihoodContext, right, left, vi) +function dot_tilde_observe!!(context::PointwiseLogdensityContext, right, left, vi) # Defer literal `observe` to child-context. return dot_tilde_observe!!(context.context, right, left, vi) end -function dot_tilde_observe!!(context::PointwiseLikelihoodContext, right, left, vn, vi) +function dot_tilde_observe!!(context::PointwiseLogdensityContext, right, left, vn, vi) # Need the `logp` value, so we cannot defer `acclogp!` to child-context, i.e. # we have to intercept the call to `dot_tilde_observe!`. @@ -129,8 +129,49 @@ function _pointwise_tilde_observe( end end +function tilde_assume(context::PointwiseLogdensityContext, right, vn, vi) + #@info "PointwiseLogdensityContext tilde_assume!! called for $vn" + value, logp, vi = tilde_assume(context.context, right, vn, vi) + #sym = DynamicPPL.getsym(vn) + new_context = acc_logp!(context, vn, logp) + return value, logp, vi +end + +function dot_tilde_assume(context::PointwiseLogdensityContext, right, left, vn, vi) + #@info "PointwiseLogdensityContext dot_tilde_assume!! called for $vn" + # @show vn, left, right, typeof(context).name + value, logp, vi = dot_tilde_assume(context.context, right, left, vn, vi) + new_context = acc_logp!(context, vn, logp) + return value, logp, vi +end + +function acc_logp!(context::PointwiseLogdensityContext, vn::VarName, logp) + push!(context, vn, logp) + return (context) +end + +function acc_logp!(context::PointwiseLogdensityContext, vns::AbstractVector{<:VarName}, logp) + # construct a new VarName from given sequence of VarName + # assume that all items in vns have an IndexLens optic + indices = tuplejoin(map(vn -> getoptic(vn).indices, vns)...) + vn = VarName(first(vns), Accessors.IndexLens(indices)) + push!(context, vn, logp) + return (context) +end + +#https://discourse.julialang.org/t/efficient-tuple-concatenation/5398/8 +@inline tuplejoin(x) = x +@inline tuplejoin(x, y) = (x..., y...) +@inline tuplejoin(x, y, z...) = (x..., tuplejoin(y, z...)...) + +() -> begin + # code that generates julia-repl in docstring below + # using DynamicPPL, Turing + # TODO when Turing version that is compatible with DynamicPPL 0.29 becomes available +end + """ - pointwise_loglikelihoods(model::Model, chain::Chains, keytype = String) + pointwise_logdensities(model::Model, chain::Chains, keytype = String) Runs `model` on each sample in `chain` returning a `OrderedDict{String, Matrix{Float64}}` with keys corresponding to symbols of the observations, and values being matrices @@ -184,21 +225,21 @@ julia> model = demo(randn(3), randn()); julia> chain = sample(model, MH(), 10); -julia> pointwise_loglikelihoods(model, chain) +julia> pointwise_logdensities(model, chain) OrderedDict{String,Array{Float64,2}} with 4 entries: "xs[1]" => [-1.42932; -2.68123; … ; -1.66333; -1.66333] "xs[2]" => [-1.6724; -0.861339; … ; -1.62359; -1.62359] "xs[3]" => [-1.42862; -2.67573; … ; -1.66251; -1.66251] "y" => [-1.51265; -0.914129; … ; -1.5499; -1.5499] -julia> pointwise_loglikelihoods(model, chain, String) +julia> pointwise_logdensities(model, chain, String) OrderedDict{String,Array{Float64,2}} with 4 entries: "xs[1]" => [-1.42932; -2.68123; … ; -1.66333; -1.66333] "xs[2]" => [-1.6724; -0.861339; … ; -1.62359; -1.62359] "xs[3]" => [-1.42862; -2.67573; … ; -1.66251; -1.66251] "y" => [-1.51265; -0.914129; … ; -1.5499; -1.5499] -julia> pointwise_loglikelihoods(model, chain, VarName) +julia> pointwise_logdensities(model, chain, VarName) OrderedDict{VarName,Array{Float64,2}} with 4 entries: xs[1] => [-1.42932; -2.68123; … ; -1.66333; -1.66333] xs[2] => [-1.6724; -0.861339; … ; -1.62359; -1.62359] @@ -217,20 +258,21 @@ julia> @model function demo(x) julia> m = demo([1.0, ]); -julia> ℓ = pointwise_loglikelihoods(m, VarInfo(m)); first(ℓ[@varname(x[1])]) +julia> ℓ = pointwise_logdensities(m, VarInfo(m)); first(ℓ[@varname(x[1])]) -1.4189385332046727 julia> m = demo([1.0; 1.0]); -julia> ℓ = pointwise_loglikelihoods(m, VarInfo(m)); first.((ℓ[@varname(x[1])], ℓ[@varname(x[2])])) +julia> ℓ = pointwise_logdensities(m, VarInfo(m)); first.((ℓ[@varname(x[1])], ℓ[@varname(x[2])])) (-1.4189385332046727, -1.4189385332046727) ``` """ -function pointwise_loglikelihoods(model::Model, chain, keytype::Type{T}=String) where {T} +function pointwise_logdensities(model::Model, chain, + context::AbstractContext=DefaultContext(), keytype::Type{T}=String) where {T} # Get the data by executing the model once vi = VarInfo(model) - context = PointwiseLikelihoodContext(OrderedDict{T,Vector{Float64}}()) + point_context = PointwiseLogdensityContext(OrderedDict{T,Vector{Float64}}(), context) iters = Iterators.product(1:size(chain, 1), 1:size(chain, 3)) for (sample_idx, chain_idx) in iters @@ -238,20 +280,24 @@ function pointwise_loglikelihoods(model::Model, chain, keytype::Type{T}=String) setval!(vi, chain, sample_idx, chain_idx) # Execute model - model(vi, context) + model(vi, point_context) end niters = size(chain, 1) nchains = size(chain, 3) - loglikelihoods = OrderedDict( + logdensities = OrderedDict( varname => reshape(logliks, niters, nchains) for - (varname, logliks) in context.loglikelihoods + (varname, logliks) in point_context.logdensities ) - return loglikelihoods + return logdensities end -function pointwise_loglikelihoods(model::Model, varinfo::AbstractVarInfo) - context = PointwiseLikelihoodContext(OrderedDict{VarName,Vector{Float64}}()) - model(varinfo, context) - return context.loglikelihoods +function pointwise_logdensities(model::Model, + varinfo::AbstractVarInfo, context::AbstractContext=DefaultContext()) + point_context = PointwiseLogdensityContext( + OrderedDict{VarName,Vector{Float64}}(), context) + model(varinfo, point_context) + return point_context.logdensities end + + diff --git a/src/test_utils.jl b/src/test_utils.jl index 9db8c37fd..85dfa71f4 100644 --- a/src/test_utils.jl +++ b/src/test_utils.jl @@ -1078,12 +1078,13 @@ function DynamicPPL.dot_tilde_assume(context::TestLogModifyingChildContext, righ return value, logp*context.mod, vi end function DynamicPPL.tilde_observe(context::TestLogModifyingChildContext, right, left, vi) - value, logp, vi = DynamicPPL.tilde_observe(context.context, right, left, vi) - return value, logp*context.mod, vi + # @info "called tilde_observe TestLogModifyingChildContext for left=$left, right=$right" + logp, vi = DynamicPPL.tilde_observe(context.context, right, left, vi) + return logp*context.mod, vi end function DynamicPPL.dot_tilde_observe(context::TestLogModifyingChildContext, right, left, vi) - return DynamicPPL.dot_tilde_observe(context.context, right, left, vi) - return value, logp*context.mod, vi + logp, vi = DynamicPPL.dot_tilde_observe(context.context, right, left, vi) + return logp*context.mod, vi end diff --git a/test/contexts.jl b/test/contexts.jl index 11e2c99b7..4ec9ff945 100644 --- a/test/contexts.jl +++ b/test/contexts.jl @@ -8,7 +8,7 @@ using DynamicPPL: NodeTrait, IsLeaf, IsParent, - PointwiseLikelihoodContext, + PointwiseLogdensityContext, contextual_isassumption, ConditionContext, hasconditioned, @@ -67,7 +67,7 @@ end SamplingContext(), MiniBatchContext(DefaultContext(), 0.0), PrefixContext{:x}(DefaultContext()), - PointwiseLikelihoodContext(), + PointwiseLogdensityContext(), ConditionContext((x=1.0,)), ConditionContext((x=1.0,), ParentContext(ConditionContext((y=2.0,)))), ConditionContext((x=1.0,), PrefixContext{:a}(ConditionContext((var"a.y"=2.0,)))), diff --git a/test/deprecated.jl b/test/deprecated.jl new file mode 100644 index 000000000..24fb3a55e --- /dev/null +++ b/test/deprecated.jl @@ -0,0 +1,29 @@ +@testset "loglikelihoods.jl" begin + @testset "$(m.f)" for m in DynamicPPL.TestUtils.DEMO_MODELS + example_values = DynamicPPL.TestUtils.rand_prior_true(m) + + # Instantiate a `VarInfo` with the example values. + vi = VarInfo(m) + for vn in DynamicPPL.TestUtils.varnames(m) + vi = DynamicPPL.setindex!!(vi, get(example_values, vn), vn) + end + + # Compute the pointwise loglikelihoods. + lls = pointwise_loglikelihoods(m, vi) + loglikelihood = sum(sum, values(lls)) + + #if isempty(lls) + if loglikelihood ≈ 0.0 #isempty(lls) + # One of the models with literal observations, so we just skip. + # TODO: Think of better way to detect this special case + continue + end + + loglikelihood_true = DynamicPPL.TestUtils.loglikelihood_true(m, example_values...) + + #priors = + + @test loglikelihood ≈ loglikelihood_true + end +end + diff --git a/test/loglikelihoods.jl b/test/pointwise_logdensitiesjl similarity index 65% rename from test/loglikelihoods.jl rename to test/pointwise_logdensitiesjl index 17185c4ad..5214bf5a1 100644 --- a/test/loglikelihoods.jl +++ b/test/pointwise_logdensitiesjl @@ -1,41 +1,16 @@ -@testset "loglikelihoods.jl" begin - @testset "$(m.f)" for m in DynamicPPL.TestUtils.DEMO_MODELS - example_values = DynamicPPL.TestUtils.rand_prior_true(m) - - # Instantiate a `VarInfo` with the example values. - vi = VarInfo(m) - for vn in DynamicPPL.TestUtils.varnames(m) - vi = DynamicPPL.setindex!!(vi, get(example_values, vn), vn) - end - - # Compute the pointwise loglikelihoods. - lls = pointwise_loglikelihoods(m, vi) - - if isempty(lls) - # One of the models with literal observations, so we just skip. - continue - end - - loglikelihood = sum(sum, values(lls)) - loglikelihood_true = DynamicPPL.TestUtils.loglikelihood_true(m, example_values...) - - @test loglikelihood ≈ loglikelihood_true - end -end - -@testset "logpriors_var.jl" begin - mod_ctx = DynamicPPL.TestUtils.TestLogModifyingChildContext(1.2, PriorContext()) +@testset "logdensities_likelihoods.jl" begin + likelihood_context = LikelihoodContext() + prior_context = PriorContext() + mod_ctx = DynamicPPL.TestUtils.TestLogModifyingChildContext(1.2) mod_ctx2 = DynamicPPL.TestUtils.TestLogModifyingChildContext(1.4, mod_ctx) #m = DynamicPPL.TestUtils.DEMO_MODELS[1] - # m = DynamicPPL.TestUtils.demo_assume_index_observe() # logp at i-level? - # m = DynamicPPL.TestUtils.demo_assume_dot_observe() # failing test? @testset "$(m.f)" for (i, m) in enumerate(DynamicPPL.TestUtils.DEMO_MODELS) #@show i example_values = DynamicPPL.TestUtils.rand_prior_true(m) # Instantiate a `VarInfo` with the example values. vi = VarInfo(m) - () -> begin + () -> begin # when interactively debugging, need the global keyword for vn in DynamicPPL.TestUtils.varnames(m) global vi = DynamicPPL.setindex!!(vi, get(example_values, vn), vn) end @@ -44,26 +19,45 @@ end vi = DynamicPPL.setindex!!(vi, get(example_values, vn), vn) end - #chains = sample(m, SampleFromPrior(), 2; progress=false) + loglikelihood_true = DynamicPPL.TestUtils.loglikelihood_true(m, example_values...) + logp_true = logprior(m, vi) # Compute the pointwise loglikelihoods. - logpriors = DynamicPPL.varwise_logpriors(m, vi) - logp1 = getlogp(vi) - logp = logprior(m, vi) - @test !isfinite(logp) || sum(x -> sum(x), values(logpriors)) ≈ logp - # - # test on modifying child-context - logpriors_mod = DynamicPPL.varwise_logpriors(m, vi, mod_ctx2) - logp1 = getlogp(vi) - #logp_mod = logprior(m, vi) # uses prior context but not mod_ctx2 - # Following line assumes no Likelihood contributions - # requires lowest Context to be PriorContext - @test !isfinite(logp1) || sum(x -> sum(x), values(logpriors_mod)) ≈ logp1 # - @test all(values(logpriors_mod) .≈ values(logpriors) .* 1.2 .* 1.4) + lls = pointwise_logdensities(m, vi, likelihood_context) + #lls2 = pointwise_loglikelihoods(m, vi) + loglikelihood = sum(sum, values(lls)) + if loglikelihood ≈ 0.0 #isempty(lls) + # One of the models with literal observations, so we just skip. + # TODO: Think of better way to detect this special case + loglikelihood_true = 0.0 + end + @test loglikelihood ≈ loglikelihood_true + + # Compute the pointwise logdensities of the priors. + lps_prior = pointwise_logdensities(m, vi, prior_context) + logp = sum(sum, values(lps_prior)) + if false # isempty(lps_prior) + # One of the models with only observations so we just skip. + else + logp1 = getlogp(vi) + @test !isfinite(logp_true) || logp ≈ logp_true + end + + # Compute both likelihood and logdensity of prior + # using the default DefaultContex + lps = pointwise_logdensities(m, vi) + logp = sum(sum, values(lps)) + @test logp ≈ (logp_true + loglikelihood_true) + + # Test that modifications of Setup are picked up + lps = pointwise_logdensities(m, vi, mod_ctx2) + logp = sum(sum, values(lps)) + @test logp ≈ (logp_true + loglikelihood_true) * 1.2 * 1.4 end -end; +end + -@testset "logpriors_var chain" begin +@testset "pointwise_logdensities chain" begin @model function demo(x, ::Type{TV}=Vector{Float64}) where {TV} s ~ InverseGamma(2, 3) m = TV(undef, length(x)) @@ -82,11 +76,13 @@ end; end arr0 = [5.590726417006858 -3.3407908212996493 -3.5126580698975687 -0.02830755634462317; 5.590726417006858 -3.3407908212996493 -3.5126580698975687 -0.02830755634462317; 0.9199555480151707 -0.1304320097505629 1.0669120062696917 -0.05253734412139093; 1.0982766276744311 0.9593277181079177 0.005558174156359029 -0.45842032209694183; 1.0982766276744311 0.9593277181079177 0.005558174156359029 -0.45842032209694183; 1.0982766276744311 0.9593277181079177 0.005558174156359029 -0.45842032209694183; 1.0982766276744311 0.9593277181079177 0.005558174156359029 -0.45842032209694183; 1.0982766276744311 0.9593277181079177 0.005558174156359029 -0.45842032209694183; 1.0982766276744311 0.9593277181079177 0.005558174156359029 -0.45842032209694183; 1.0982766276744311 0.9593277181079177 0.005558174156359029 -0.45842032209694183;;; 3.5612802961176797 -5.167692608117693 1.3768066487740864 -0.9154694769223497; 3.5612802961176797 -5.167692608117693 1.3768066487740864 -0.9154694769223497; 2.5409470583244933 1.7838744695696407 0.7013562890105632 -3.0843947804314658; 0.8296370582311665 1.5360702767879642 -1.5964695255693102 0.16928084806166913; 2.6246697053824954 0.8096845024785173 -1.2621822861663752 1.1414885535466166; 1.1304261861894538 0.7325784741344005 -1.1866016911837542 -0.1639319562090826; 2.5669872989791473 -0.43642462460747317 0.07057300935786101 0.5168578624259272; 2.5669872989791473 -0.43642462460747317 0.07057300935786101 0.5168578624259272; 2.5669872989791473 -0.43642462460747317 0.07057300935786101 0.5168578624259272; 0.9838526141898173 -0.20198797220982412 2.0569535882007006 -1.1560724118010939] chain = Chains(arr0, [:s, Symbol("m[1]"), Symbol("m[2]"), Symbol("m[3]")]); - tmp1 = varwise_logpriors(model, chain) - tmp = Chains(tmp1...); # can be used to create a Chains object + tmp1 = pointwise_logdensities(model, chain) vi = VarInfo(model) i_sample, i_chain = (1,2) DynamicPPL.setval!(vi, chain, i_sample, i_chain) - lp1 = DynamicPPL.varwise_logpriors(model, vi) - @test all(tmp1[1][i_sample,:,i_chain] .≈ values(lp1)) + lp1 = DynamicPPL.pointwise_logdensities(model, vi) + # k = first(keys(lp1)) + for k in keys(lp1) + @test tmp1[string(k)][i_sample,i_chain] .≈ lp1[k][1] + end end; \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index a321151ab..6de0cb7fe 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -57,9 +57,11 @@ include("test_util.jl") include("serialization.jl") - include("loglikelihoods.jl") + include("pointwise_logdensitiesjl") include("lkj.jl") + + include("deprecated.jl") end @testset "compat" begin