# Repeatedly calculating likelihood using Turing

**URL:** https://discourse.julialang.org/t/repeatedly-calculating-likelihood-using-turing/50608
**Category:** Probabilistic Programming
**Tags:** question, performance, turing
**Created:** [November 23, 2020, 3:56am UTC](https://discourse.julialang.org/t/repeatedly-calculating-likelihood-using-turing/50608 "2020-11-23T03:56:23Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![ArnoStrouwen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/arnostrouwen/32/8699_2.png) [@ArnoStrouwen](https://discourse.julialang.org/u/ArnoStrouwen)
#### Post date: [November 23, 2020, 3:56am UTC](https://discourse.julialang.org/t/repeatedly-calculating-likelihood-using-turing/50608/1 "2020-11-23T03:56:23Z")

</div>

I want to repeatedly calculate likelihoods of the same Turing model at different parameter values, and also with different possible observations. What is the best way to do this in Turing? A minimal example of the type of function I am trying to evaluate as fast as possible:

```nohighlight
using Turing
# θ unknown parameters
# X experimental design that has to be optimized, to estimate θ as precisely as possible
# y measurements
@model function lm(X,y) # 2 factors, main effects only and no intercept
    θ ~ MvNormal(ones(2),1.0)
    y ~ MvNormal(X*θ, 0.1) 
    return θ, y
end
function expected_KL_div(model_given_design ;n_in=100,n_out=100)
    val_out = 0.0
    for i = 1:n_out
        θ_outer, y_outer = model_given_design()
        val_out += logprob"y = y_outer | model = model_given_design, X = model_given_design.args.X, θ = θ_outer" 
        val_in = 0.0
        for j = 1:n_in
            θ_inner, ~ = model_given_design()
            val_in += logprob"y = y_outer | model = model_given_design, X = model_given_design.args.X, θ = θ_inner"
        end
        val_out -= val_in/n_in 
    end
    val_out/n_out
end
X_test = [1.0 1.0; 1.0 -1.0; -1.0 1.0; -1.0 -1.0]
model_given_design = lm(X_test,missing)
expected_KL_div(model_given_design )
# optimal_design = maximize(expected_KL_div)

```

I am mainly wondering if using `logprob"..."` inside a loop is a good idea.

---

<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: [November 23, 2020, 4:47am UTC](https://discourse.julialang.org/t/repeatedly-calculating-likelihood-using-turing/50608/2 "2020-11-23T04:47:31Z")

</div>

> [@ArnoStrouwen](#):
>
> I am mainly wondering if using `logprob"..."` inside a loop is a good idea.

Yes nothing wrong with that. One thing you can do to speed it up is to pre-allocate the internal data structure we use in `logprob` and pass it on the RHS to reuse it. For example:

```julia
varinfo = Turing.VarInfo(model_given_design)
logprob"... | varinfo = varinfo, ...."

```

---

<div class="post-metadata">

### Author: ![ArnoStrouwen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/arnostrouwen/32/8699_2.png) [@ArnoStrouwen](https://discourse.julialang.org/u/ArnoStrouwen)
#### Post date: [November 27, 2020, 8:56pm UTC](https://discourse.julialang.org/t/repeatedly-calculating-likelihood-using-turing/50608/3 "2020-11-27T20:56:36Z")

</div>

Thank you, this gave about a x5 speedup when evaluating the objective once. And about x10 when passed to an optimization routine.
