@@ -24,12 +24,14 @@ There are three interrelating aspects that this interface intends to standardize
24
24
- Sampling
25
25
- “Conversions” between different conditionings of models
26
26
27
- Therefore, the interface consists of:
27
+ Therefore, the interface consists of an ` AbstractProbabilisticProgram ` supertype, together with
28
+ functions
28
29
29
30
- ` condition(::Model, ::Trace) -> ConditionedModel `
30
31
- ` decondition(::ConditionedModel) -> GenerativeModel `
31
32
- ` sample(::Model, ::Sampler = Exact(), [Int]) ` (from ` AbstractMCMC.sample ` )
32
- - ` logdensity(::Model, ::Trace) `
33
+ - ` logdensityof(::Model, ::Trace) ` and ` densityof(::Model, ::Trace) ` (from
34
+ [ DensityInterface.jl] ( https://github.com/JuliaMath/DensityInterface.jl ) )
33
35
34
36
35
37
### Traces & probability expressions
@@ -198,32 +200,46 @@ Not all variants need to be supported – for example, a posterior model might n
198
200
model.
199
201
200
202
201
- ### Density Calculation
203
+ ### Density Evaluation
202
204
203
205
Since the different “versions” of how a model is to be understood as generative or conditioned are
204
206
to be expressed in the type or dispatch they support, there should be no need for separate functions
205
- ` logjoint ` , ` loglikelihood ` , etc., which force these semantic distinctions on the implementor; one
206
- ` logdensity ` should suffice for all, with the distinction being made by the capabilities of the
207
- concrete model instance.
207
+ ` logjoint ` , ` loglikelihood ` , etc., which force these semantic distinctions on the implementor; we
208
+ therefore adapt the interface of
209
+ [ DensityInterface.jl] ( https://github.com/JuliaMath/DensityInterface.jl ) . Its main function
210
+ ` logdensityof ` should suffice for variants, with the distinction being made by the capabilities of
211
+ the concrete model instance.
208
212
209
- Note that this generalizes ` logpdf ` , too, since the posterior density will of course in general be
210
- unnormalized and hence not a probability density.
213
+ DensityInterface.jl also requires the trait function ` DensityKind ` , which is set to ` HasDensity() `
214
+ for the ` AbstractProbabilisticProgram ` type. Additional functions
211
215
212
- The evaluation will usually work with the internal, concrete trace type, like ` VarInfo ` in Turing.jl:
216
+ ```
217
+ DensityInterface.densityof(d, x) = exp(logdensityof(d, x))
218
+ DensityInterface.logdensityof(d) = Base.Fix1(logdensityof, d)
219
+ DensityInterface.densityof(d) = Base.Fix1(densityof, d)
220
+ ```
221
+
222
+ are provided automatically (repeated here for clarity).
223
+
224
+ Note that ` logdensityof ` strictly generalizes ` logpdf ` , since the posterior density will of course
225
+ in general be unnormalized and hence not a probability density.
226
+
227
+ The evaluation will usually work with the internal, concrete trace type, like ` VarInfo ` in
228
+ Turing.jl:
213
229
214
230
``` julia
215
- logdensity (m, vi)
231
+ logdensityof (m, vi)
216
232
```
217
233
218
234
But the user will more likely work on the interface using probability expressions:
219
235
220
236
``` julia
221
- logdensity (m, @T (X = ... ))
237
+ logdensityof (m, @T (X = … ))
222
238
```
223
239
224
240
(Note that this would replace the current ` prob ` string macro in Turing.jl.)
225
241
226
- Densities need not be normalized.
242
+ Densities need (and usually, will) not be normalized.
227
243
228
244
229
245
#### Implementation notes
@@ -232,15 +248,15 @@ It should be able to make this fall back on the internal method with the right d
232
248
implementation of ` maketrace ` :
233
249
234
250
``` julia
235
- logdensity (m, t:: ProbabilityExpression ) = logdensity (m, maketrace (m, t))
251
+ logdensityof (m, t:: ProbabilityExpression ) = logdensityof (m, maketrace (m, t))
236
252
```
237
253
238
254
There is one open question – should normalized and unnormalized densities be able to be
239
255
distinguished? This could be done by dispatch as well, e.g., if the caller wants to make sure
240
256
normalization:
241
257
242
258
```
243
- logdensity (g, @T(X = ... , Y = ... , Z = ... ); normalized=Val{true})
259
+ logdensityof (g, @T(X = … , Y = … , Z = … ); normalized=Val{true})
244
260
```
245
261
246
262
Although there is proably a better way through traits; maybe like for arrays, with
0 commit comments