From 0cb77f68b73ecd0de9da5c99e0ba2cec0c697160 Mon Sep 17 00:00:00 2001 From: David Widmann Date: Mon, 7 Mar 2022 04:29:28 +0100 Subject: [PATCH 1/6] Extend docstring of `@addlogprob!` --- src/utils.jl | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/utils.jl b/src/utils.jl index ffdc21070..261461094 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -6,6 +6,67 @@ const NO_DEFAULT = NoDefault() @addlogprob!(ex) Add the result of the evaluation of `ex` to the joint log probability. + +# Examples + +This macro allows you to [include arbitrary terms in the likelihood](https://github.com/TuringLang/Turing.jl/issues/1332) + +```jldoctest; setup = :(using Distributions) +julia> myloglikelihood(x, μ) = loglikelihood(Normal(μ, 1), x); + +julia> @model function demo(x) + μ ~ Normal() + @addlogprob! myloglikelihood(x, μ) + end; + +julia> x = [1.3, -2.1]; + +julia> loglikelihood(demo(x), (μ=0.2,)) ≈ my_loglikelihood(x, 0.2) +true +``` + +and to [reject samples](https://github.com/TuringLang/Turing.jl/issues/1328): + +```jldoctest; setup = :(using Distributions, LinearAlgebra) +julia> @model function demo(x) + m ~ MvNormal(zero(x), I) + if dot(m, x) < 0 + @addlogprob! -Inf + # Exit the model evaluation early + return + end + + x ~ MvNormal(m, I) + return + end; + +julia> logjoint(demo([-2.1]), (μ=[0.2],)) == -Inf +true +``` + +!!! note + The `@addlogprob!` macro increases the accumulated log probability, regardless of the sampling context, + i.e., regardless of whether you evaluate the log prior, the log likelihood or the log joint density. + If you would like to avoid this behaviour you should add check the sampling context + It can be accessed with the internal variable `__context__`. + For instance, in the following example the log density is not accumulated with `@addlogprob!` when the log prior is computed: + ```jldoctest; setup = :(using Distributions) + julia> myloglikelihood(x, μ) = loglikelihood(Normal(μ, 1), x); + + julia> @model function demo(x) + μ ~ Normal() + if DynamicPPL.leafcontext(__context__) !== PriorContext() + @addlogprob! myloglikelihood(x, μ) + end; + + julia> x = [1.3, -2.1]; + + julia> logprior(demo(x), (μ=0.2,)) ≈ logpdf(Normal(), 0.2) + true + + julia> loglikelihood(demo(x), (μ=0.2,)) ≈ my_loglikelihood(x, 0.2) + true + ``` """ macro addlogprob!(ex) return quote From 80f41b0c18492ce01dc4fa2eb021d7d6870ad9a7 Mon Sep 17 00:00:00 2001 From: David Widmann Date: Mon, 7 Mar 2022 04:42:12 +0100 Subject: [PATCH 2/6] Some fixes --- src/utils.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils.jl b/src/utils.jl index 261461094..472943187 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -21,7 +21,7 @@ julia> @model function demo(x) julia> x = [1.3, -2.1]; -julia> loglikelihood(demo(x), (μ=0.2,)) ≈ my_loglikelihood(x, 0.2) +julia> loglikelihood(demo(x), (μ=0.2,)) ≈ myloglikelihood(x, 0.2) true ``` @@ -57,6 +57,7 @@ true μ ~ Normal() if DynamicPPL.leafcontext(__context__) !== PriorContext() @addlogprob! myloglikelihood(x, μ) + end end; julia> x = [1.3, -2.1]; From 3ef410b67c3f98a7911d35afa5f072444d314f2e Mon Sep 17 00:00:00 2001 From: David Widmann Date: Mon, 7 Mar 2022 10:41:03 +0100 Subject: [PATCH 3/6] Apply suggestions from code review Co-authored-by: Hong Ge <3279477+yebai@users.noreply.github.com> --- src/utils.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils.jl b/src/utils.jl index 472943187..94e1bae34 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -45,9 +45,9 @@ true ``` !!! note - The `@addlogprob!` macro increases the accumulated log probability, regardless of the sampling context, + The `@addlogprob!` macro increases the accumulated log probability, regardless of the evaluation context, i.e., regardless of whether you evaluate the log prior, the log likelihood or the log joint density. - If you would like to avoid this behaviour you should add check the sampling context + If you would like to avoid this behaviour you should add check the evaluation context It can be accessed with the internal variable `__context__`. For instance, in the following example the log density is not accumulated with `@addlogprob!` when the log prior is computed: ```jldoctest; setup = :(using Distributions) From d3341035885872bba401e769c813341b53d8adf3 Mon Sep 17 00:00:00 2001 From: David Widmann Date: Mon, 7 Mar 2022 10:50:27 +0100 Subject: [PATCH 4/6] More fixes --- src/utils.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/utils.jl b/src/utils.jl index 94e1bae34..5397cd1d6 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -35,7 +35,6 @@ julia> @model function demo(x) # Exit the model evaluation early return end - x ~ MvNormal(m, I) return end; @@ -65,7 +64,7 @@ true julia> logprior(demo(x), (μ=0.2,)) ≈ logpdf(Normal(), 0.2) true - julia> loglikelihood(demo(x), (μ=0.2,)) ≈ my_loglikelihood(x, 0.2) + julia> loglikelihood(demo(x), (μ=0.2,)) ≈ myloglikelihood(x, 0.2) true ``` """ From 73919fd81240aea6475fb9da4b875da091efa4c9 Mon Sep 17 00:00:00 2001 From: David Widmann Date: Mon, 7 Mar 2022 10:55:51 +0100 Subject: [PATCH 5/6] Another typo --- src/utils.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.jl b/src/utils.jl index 5397cd1d6..42949edc0 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -39,7 +39,7 @@ julia> @model function demo(x) return end; -julia> logjoint(demo([-2.1]), (μ=[0.2],)) == -Inf +julia> logjoint(demo([-2.1]), (m=[0.2],)) == -Inf true ``` From 0925480e0520e3c02b110d5ae97d2b60d24b26c1 Mon Sep 17 00:00:00 2001 From: David Widmann Date: Mon, 7 Mar 2022 11:21:29 +0100 Subject: [PATCH 6/6] Improve note --- src/utils.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils.jl b/src/utils.jl index 42949edc0..d8f9090d1 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -44,11 +44,11 @@ true ``` !!! note - The `@addlogprob!` macro increases the accumulated log probability, regardless of the evaluation context, + The `@addlogprob!` macro increases the accumulated log probability regardless of the evaluation context, i.e., regardless of whether you evaluate the log prior, the log likelihood or the log joint density. - If you would like to avoid this behaviour you should add check the evaluation context + If you would like to avoid this behaviour you should check the evaluation context. It can be accessed with the internal variable `__context__`. - For instance, in the following example the log density is not accumulated with `@addlogprob!` when the log prior is computed: + For instance, in the following example the log density is not accumulated when only the log prior is computed: ```jldoctest; setup = :(using Distributions) julia> myloglikelihood(x, μ) = loglikelihood(Normal(μ, 1), x);