Skip to content

Commit

Permalink
Switch names from logdensity to logdensityof and update stuff acc…
Browse files Browse the repository at this point in the history
…ordingly
  • Loading branch information
phipsgabler committed Nov 8, 2021
1 parent a7902a3 commit 3498431
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 15 deletions.
2 changes: 2 additions & 0 deletions Project.toml
Expand Up @@ -7,9 +7,11 @@ version = "0.3.1"

[deps]
AbstractMCMC = "80f14c24-f653-4e6a-9b94-39d6b0f70001"
DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d"
Setfield = "efcf1570-3423-57d1-acb7-fd33fddbac46"

[compat]
AbstractMCMC = "2, 3"
DensityInterface = "0.3"
Setfield = "0.7.1, 0.8"
julia = "1"
22 changes: 12 additions & 10 deletions interface.md
Expand Up @@ -29,7 +29,7 @@ Therefore, the interface consists of:
- `condition(::Model, ::Trace) -> ConditionedModel`
- `decondition(::ConditionedModel) -> GenerativeModel`
- `sample(::Model, ::Sampler = Exact(), [Int])` (from `AbstractMCMC.sample`)
- `logdensity(::Model, ::Trace)`
- `DensityInterface.logdensityof(::Model, ::Trace)`


### Traces & probability expressions
Expand Down Expand Up @@ -198,32 +198,34 @@ Not all variants need to be supported – for example, a posterior model might n
model.


### Density Calculation
### Density Evaluation

Since the different “versions” of how a model is to be understood as generative or conditioned are
to be expressed in the type or dispatch they support, there should be no need for separate functions
`logjoint`, `loglikelihood`, etc., which force these semantic distinctions on the implementor; one
`logdensity` should suffice for all, with the distinction being made by the capabilities of the
concrete model instance.
`logjoint`, `loglikelihood`, etc., which force these semantic distinctions on the implementor; we
therefore adapt the interface of
[DensityInterface.jl](https://github.com/JuliaMath/DensityInterface.jl). Its one function
`logdensityof` should suffice for variants, with the distinction being made by the capabilities of
the concrete model instance.

Note that this generalizes `logpdf`, too, since the posterior density will of course in general be
unnormalized and hence not a probability density.

The evaluation will usually work with the internal, concrete trace type, like `VarInfo` in Turing.jl:

```julia
logdensity(m, vi)
logdensityof(m, vi)
```

But the user will more likely work on the interface using probability expressions:

```julia
logdensity(m, @T(X = ...))
logdensityof(m, @T(X = ...))
```

(Note that this would replace the current `prob` string macro in Turing.jl.)

Densities need not be normalized.
Densities need (and usually, will) not be normalized.


#### Implementation notes
Expand All @@ -232,15 +234,15 @@ It should be able to make this fall back on the internal method with the right d
implementation of `maketrace`:

```julia
logdensity(m, t::ProbabilityExpression) = logdensity(m, maketrace(m, t))
logdensityof(m, t::ProbabilityExpression) = logdensityof(m, maketrace(m, t))
```

There is one open question – should normalized and unnormalized densities be able to be
distinguished? This could be done by dispatch as well, e.g., if the caller wants to make sure
normalization:

```
logdensity(g, @T(X = ..., Y = ..., Z = ...); normalized=Val{true})
logdensityof(g, @T(X = ..., Y = ..., Z = ...); normalized=Val{true})
```

Although there is proably a better way through traits; maybe like for arrays, with
Expand Down
2 changes: 1 addition & 1 deletion src/AbstractPPL.jl
Expand Up @@ -5,7 +5,7 @@ export VarName, getsym, getindexing, getlens, inspace, subsumes, varname, vsym,


# Abstract model functions
export AbstractProbabilisticProgram, condition, decondition, logdensity
export AbstractProbabilisticProgram, condition, decondition, logdensityof


# Abstract traces
Expand Down
11 changes: 7 additions & 4 deletions src/abstractprobprog.jl
@@ -1,4 +1,5 @@
using AbstractMCMC
using DensityInterface


"""
Expand All @@ -8,19 +9,21 @@ Common base type for models expressed as probabilistic programs.
"""
abstract type AbstractProbabilisticProgram <: AbstractMCMC.AbstractModel end

DensityInterface.hasdensity(::AbstractProbabilisticProgram) = true


"""
logdensity(model, trace)
logdensityof(model, trace)
Evaluate the (possibly unnormalized) density of the model specified by the probabilistic program
in `model`, at specific values for the random variables given through `trace`.
`trace` can be of any supported internal trace type, or a fixed probability expression.
`logdensity` should interact with conditioning and deconditioning in the way required by probability
theory.
`logdensityof` should interact with conditioning and deconditioning in the way required by
probability theory.
"""
function logdensity end
DensityInterface.logdensityof


"""
Expand Down

0 comments on commit 3498431

Please sign in to comment.