# Calculate joint probability from Turing model

**URL:** https://discourse.julialang.org/t/calculate-joint-probability-from-turing-model/43545
**Category:** Probabilistic Programming
**Tags:** turing
**Created:** [July 23, 2020, 8:30am UTC](https://discourse.julialang.org/t/calculate-joint-probability-from-turing-model/43545 "2020-07-23T08:30:50Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![treichelt](https://avatars.discourse-cdn.com/v4/letter/t/7cd45c/32.png) [@treichelt](https://discourse.julialang.org/u/treichelt)
#### Post date: [July 23, 2020, 8:30am UTC](https://discourse.julialang.org/t/calculate-joint-probability-from-turing-model/43545/1 "2020-07-23T08:30:51Z")

</div>

Given a model defined in Turing I would like to calculate the joint probability function over all the variables. Say I have the model

```julia
@model function model(y)
    mu ~ Normal(0, 1)
    y ~ Normal(mu, 1)
end

y_obs = 1
mu = 1

```

With the prob macro I can do

```julia
prob"mu = mu, y = y_obs | model = model"

```

and it gives me exactly what I want. However, now I would like to be able to not have to explicitly pass in the value of `y_obs` and instead do

```julia
m = model(y_obs)
prob"mu = mu | model = m"

```

Is that somehow possible?

My end goal is to create a function which only takes as input an instantiated model and returns the joint probability function. So I want to have a function `get_joint_prob` such that:

```julia
m = model(y_obs)
joint_prob = get_joint_prob(m)
joint_prob((mu=mu,)) == prob"mu = mu, y = y_obs | model = model"

```

(`joint_prob` takes in a named tuple so that it can deal with multiple variables if necessary).

I have already read through the documentation on the Turing side and looked a bit at the implementation of the prob macro and the VarInfo stuff but I didn’t quite understand all of it well enough to get something to work. Any pointers would be really helpful!

---

<div class="post-metadata">

### Author: ![treichelt](https://avatars.discourse-cdn.com/v4/letter/t/7cd45c/32.png) [@treichelt](https://discourse.julialang.org/u/treichelt)
#### Post date: [July 23, 2020, 9:06am UTC](https://discourse.julialang.org/t/calculate-joint-probability-from-turing-model/43545/2 "2020-07-23T09:06:42Z")

</div>

After having a look at the [MH sampler implementation](https://github.com/TuringLang/Turing.jl/blob/master/src/inference/mh.jl). I came up with the following solution:

```julia
function make_log_joint_density(model)
    return function joint_density(xval)
        vi = Turing.VarInfo(model)
        vi[@varname(x)] = [xval]
        model(vi)
        return Turing.getlogp(vi)
    end
end

```

This works for my small toy model above. Using the `set_namedtuple!(vi::VarInfo, nt::NamedTuple)` [function](https://github.com/TuringLang/Turing.jl/blob/5f2c934a9828ce5b1ba9e327ad85f312ae2c93e7/src/inference/mh.jl#L76) I can generalise this to:

```julia
function make_log_joint_density(model)
    return function joint_density(named_tuple)
        vi = Turing.VarInfo(model)
        set_namedtuple!(vi, named_tuple)
        model(vi)
        return Turing.getlogp(vi)
    end
end

```

Does this sound like a reasonable approach or is there a better way to do this? Is there somewhere some documentation about the `VarInfo` type and how to interact with it?

---

<div class="post-metadata">

### Author: ![treichelt](https://avatars.discourse-cdn.com/v4/letter/t/7cd45c/32.png) [@treichelt](https://discourse.julialang.org/u/treichelt)
#### Post date: [July 24, 2020, 1:20pm UTC](https://discourse.julialang.org/t/calculate-joint-probability-from-turing-model/43545/3 "2020-07-24T13:20:34Z")

</div>

I found the docs about the [Turing compiler design](https://turing.ml/dev/docs/for-developers/compiler) and they answered most of my questions.

---

<div class="post-metadata">

### Author: ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)
#### Post date: [July 24, 2020, 2:35pm UTC](https://discourse.julialang.org/t/calculate-joint-probability-from-turing-model/43545/4 "2020-07-24T14:35:30Z")

</div>

I would look at the implementation of the macro. These functions get called in your case and can be customized for your use case  
[https://github.com/TuringLang/DynamicPPL.jl/blob/master/src/prob\_macro.jl#L24](https://github.com/TuringLang/DynamicPPL.jl/blob/master/src/prob_macro.jl#L24) [https://github.com/TuringLang/DynamicPPL.jl/blob/master/src/prob\_macro.jl#L118](https://github.com/TuringLang/DynamicPPL.jl/blob/master/src/prob_macro.jl#L118).
