Sometimes a model’s likelihood is not expressed directly as a distribution over observed data, but is instead computed by an external algorithm. A common example is state-space models , where a filtering algorithm (e.g. a Kalman filter or a particle filter) marginalises out the latent states and returns the marginal log-likelihood of the observations given the model parameters.
In this setting Turing only needs to sample the model parameters; the likelihood contribution is injected into the model with the @addlogprob! macro.
Minimal example
The function below stands in for an external filtering algorithm — for instance one provided by SSMProblems.jl or GeneralisedFilters.jl . Here we simply compute the log-likelihood of a Gaussian with unit variance, which is sufficient to demonstrate the integration pattern.
using Turing
# Mock filter — computes the Gaussian log-likelihood (constant terms
# omitted as they do not affect MCMC).
function run_external_filter (data, θ)
return - 0.5 * sum ((data .- θ) .^ 2 )
end
@model function external_likelihood_demo (data)
θ ~ Normal (0 , 1 )
@addlogprob ! run_external_filter (data, θ)
end
external_likelihood_demo (generic function with 2 methods)
We can now sample from this model in the usual way:
data = randn (100 )
model = external_likelihood_demo (data)
chain = sample (model, NUTS (), 100 )
Sampling 0%| | ETA: N/A
┌ Info: Found initial step size
└ ϵ = 0.2
Sampling 1%|▎ | ETA: 0:09:05
Sampling 1%|▌ | ETA: 0:05:23
Sampling 2%|▉ | ETA: 0:03:34
Sampling 3%|█▏ | ETA: 0:02:39
Sampling 3%|█▍ | ETA: 0:02:06
Sampling 4%|█▋ | ETA: 0:01:45
Sampling 5%|██ | ETA: 0:01:29
Sampling 5%|██▎ | ETA: 0:01:17
Sampling 6%|██▌ | ETA: 0:01:08
Sampling 7%|██▊ | ETA: 0:01:01
Sampling 7%|███▏ | ETA: 0:00:55
Sampling 8%|███▍ | ETA: 0:00:50
Sampling 9%|███▋ | ETA: 0:00:46
Sampling 9%|███▉ | ETA: 0:00:42
Sampling 10%|████▎ | ETA: 0:00:39
Sampling 11%|████▌ | ETA: 0:00:37
Sampling 11%|████▊ | ETA: 0:00:34
Sampling 12%|█████ | ETA: 0:00:32
Sampling 13%|█████▍ | ETA: 0:00:30
Sampling 13%|█████▋ | ETA: 0:00:28
Sampling 14%|█████▉ | ETA: 0:00:27
Sampling 15%|██████▏ | ETA: 0:00:25
Sampling 15%|██████▌ | ETA: 0:00:24
Sampling 16%|██████▊ | ETA: 0:00:23
Sampling 17%|███████ | ETA: 0:00:22
Sampling 17%|███████▎ | ETA: 0:00:21
Sampling 18%|███████▌ | ETA: 0:00:20
Sampling 19%|███████▉ | ETA: 0:00:19
Sampling 19%|████████▏ | ETA: 0:00:18
Sampling 20%|████████▍ | ETA: 0:00:17
Sampling 21%|████████▋ | ETA: 0:00:17
Sampling 21%|█████████ | ETA: 0:00:16
Sampling 22%|█████████▎ | ETA: 0:00:15
Sampling 23%|█████████▌ | ETA: 0:00:15
Sampling 23%|█████████▊ | ETA: 0:00:14
Sampling 24%|██████████▏ | ETA: 0:00:14
Sampling 25%|██████████▍ | ETA: 0:00:13
Sampling 25%|██████████▋ | ETA: 0:00:13
Sampling 26%|██████████▉ | ETA: 0:00:12
Sampling 27%|███████████▎ | ETA: 0:00:12
Sampling 27%|███████████▌ | ETA: 0:00:12
Sampling 28%|███████████▊ | ETA: 0:00:11
Sampling 29%|████████████ | ETA: 0:00:11
Sampling 29%|████████████▍ | ETA: 0:00:11
Sampling 30%|████████████▋ | ETA: 0:00:10
Sampling 31%|████████████▉ | ETA: 0:00:10
Sampling 31%|█████████████▏ | ETA: 0:00:10
Sampling 32%|█████████████▌ | ETA: 0:00:09
Sampling 33%|█████████████▊ | ETA: 0:00:09
Sampling 33%|██████████████ | ETA: 0:00:09
Sampling 34%|██████████████▎ | ETA: 0:00:08
Sampling 35%|██████████████▌ | ETA: 0:00:08
Sampling 35%|██████████████▉ | ETA: 0:00:08
Sampling 36%|███████████████▏ | ETA: 0:00:08
Sampling 37%|███████████████▍ | ETA: 0:00:08
Sampling 37%|███████████████▋ | ETA: 0:00:07
Sampling 38%|████████████████ | ETA: 0:00:07
Sampling 39%|████████████████▎ | ETA: 0:00:07
Sampling 39%|████████████████▌ | ETA: 0:00:07
Sampling 40%|████████████████▊ | ETA: 0:00:07
Sampling 41%|█████████████████▏ | ETA: 0:00:07
Sampling 41%|█████████████████▍ | ETA: 0:00:06
Sampling 42%|█████████████████▋ | ETA: 0:00:06
Sampling 43%|█████████████████▉ | ETA: 0:00:06
Sampling 43%|██████████████████▎ | ETA: 0:00:06
Sampling 44%|██████████████████▌ | ETA: 0:00:06
Sampling 45%|██████████████████▊ | ETA: 0:00:06
Sampling 45%|███████████████████ | ETA: 0:00:05
Sampling 46%|███████████████████▍ | ETA: 0:00:05
Sampling 47%|███████████████████▋ | ETA: 0:00:05
Sampling 47%|███████████████████▉ | ETA: 0:00:05
Sampling 48%|████████████████████▏ | ETA: 0:00:05
Sampling 49%|████████████████████▌ | ETA: 0:00:05
Sampling 49%|████████████████████▊ | ETA: 0:00:05
Sampling 50%|█████████████████████ | ETA: 0:00:04
Sampling 51%|█████████████████████▎ | ETA: 0:00:04
Sampling 51%|█████████████████████▌ | ETA: 0:00:04
Sampling 52%|█████████████████████▉ | ETA: 0:00:04
Sampling 53%|██████████████████████▏ | ETA: 0:00:04
Sampling 53%|██████████████████████▍ | ETA: 0:00:04
Sampling 54%|██████████████████████▋ | ETA: 0:00:04
Sampling 55%|███████████████████████ | ETA: 0:00:04
Sampling 55%|███████████████████████▎ | ETA: 0:00:04
Sampling 56%|███████████████████████▌ | ETA: 0:00:04
Sampling 57%|███████████████████████▊ | ETA: 0:00:03
Sampling 57%|████████████████████████▏ | ETA: 0:00:03
Sampling 58%|████████████████████████▍ | ETA: 0:00:03
Sampling 59%|████████████████████████▋ | ETA: 0:00:03
Sampling 59%|████████████████████████▉ | ETA: 0:00:03
Sampling 60%|█████████████████████████▎ | ETA: 0:00:03
Sampling 61%|█████████████████████████▌ | ETA: 0:00:03
Sampling 61%|█████████████████████████▊ | ETA: 0:00:03
Sampling 62%|██████████████████████████ | ETA: 0:00:03
Sampling 63%|██████████████████████████▍ | ETA: 0:00:03
Sampling 63%|██████████████████████████▋ | ETA: 0:00:03
Sampling 64%|██████████████████████████▉ | ETA: 0:00:03
Sampling 65%|███████████████████████████▏ | ETA: 0:00:02
Sampling 65%|███████████████████████████▌ | ETA: 0:00:02
Sampling 66%|███████████████████████████▊ | ETA: 0:00:02
Sampling 67%|████████████████████████████ | ETA: 0:00:02
Sampling 67%|████████████████████████████▎ | ETA: 0:00:02
Sampling 68%|████████████████████████████▌ | ETA: 0:00:02
Sampling 69%|████████████████████████████▉ | ETA: 0:00:02
Sampling 69%|█████████████████████████████▏ | ETA: 0:00:02
Sampling 70%|█████████████████████████████▍ | ETA: 0:00:02
Sampling 71%|█████████████████████████████▋ | ETA: 0:00:02
Sampling 71%|██████████████████████████████ | ETA: 0:00:02
Sampling 72%|██████████████████████████████▎ | ETA: 0:00:02
Sampling 73%|██████████████████████████████▌ | ETA: 0:00:02
Sampling 73%|██████████████████████████████▊ | ETA: 0:00:02
Sampling 74%|███████████████████████████████▏ | ETA: 0:00:02
Sampling 75%|███████████████████████████████▍ | ETA: 0:00:02
Sampling 75%|███████████████████████████████▋ | ETA: 0:00:01
Sampling 76%|███████████████████████████████▉ | ETA: 0:00:01
Sampling 77%|████████████████████████████████▎ | ETA: 0:00:01
Sampling 77%|████████████████████████████████▌ | ETA: 0:00:01
Sampling 78%|████████████████████████████████▊ | ETA: 0:00:01
Sampling 79%|█████████████████████████████████ | ETA: 0:00:01
Sampling 79%|█████████████████████████████████▍ | ETA: 0:00:01
Sampling 80%|█████████████████████████████████▋ | ETA: 0:00:01
Sampling 81%|█████████████████████████████████▉ | ETA: 0:00:01
Sampling 81%|██████████████████████████████████▏ | ETA: 0:00:01
Sampling 82%|██████████████████████████████████▌ | ETA: 0:00:01
Sampling 83%|██████████████████████████████████▊ | ETA: 0:00:01
Sampling 83%|███████████████████████████████████ | ETA: 0:00:01
Sampling 84%|███████████████████████████████████▎ | ETA: 0:00:01
Sampling 85%|███████████████████████████████████▌ | ETA: 0:00:01
Sampling 85%|███████████████████████████████████▉ | ETA: 0:00:01
Sampling 86%|████████████████████████████████████▏ | ETA: 0:00:01
Sampling 87%|████████████████████████████████████▍ | ETA: 0:00:01
Sampling 87%|████████████████████████████████████▋ | ETA: 0:00:01
Sampling 88%|█████████████████████████████████████ | ETA: 0:00:01
Sampling 89%|█████████████████████████████████████▎ | ETA: 0:00:01
Sampling 89%|█████████████████████████████████████▌ | ETA: 0:00:01
Sampling 90%|█████████████████████████████████████▊ | ETA: 0:00:00
Sampling 91%|██████████████████████████████████████▏ | ETA: 0:00:00
Sampling 91%|██████████████████████████████████████▍ | ETA: 0:00:00
Sampling 92%|██████████████████████████████████████▋ | ETA: 0:00:00
Sampling 93%|██████████████████████████████████████▉ | ETA: 0:00:00
Sampling 93%|███████████████████████████████████████▎ | ETA: 0:00:00
Sampling 94%|███████████████████████████████████████▌ | ETA: 0:00:00
Sampling 95%|███████████████████████████████████████▊ | ETA: 0:00:00
Sampling 95%|████████████████████████████████████████ | ETA: 0:00:00
Sampling 96%|████████████████████████████████████████▍ | ETA: 0:00:00
Sampling 97%|████████████████████████████████████████▋ | ETA: 0:00:00
Sampling 97%|████████████████████████████████████████▉ | ETA: 0:00:00
Sampling 98%|█████████████████████████████████████████▏| ETA: 0:00:00
Sampling 99%|█████████████████████████████████████████▌| ETA: 0:00:00
Sampling 99%|█████████████████████████████████████████▊| ETA: 0:00:00
Sampling 100%|██████████████████████████████████████████| Time: 0:00:04
Sampling 100%|██████████████████████████████████████████| Time: 0:00:05
╭─ FlexiChain (100 iterations, 1 chain) ──────────────────────────────────────── ╮
│ ↓ iter = 51:150 │
│ → chain = 1:1 │
│ │
│ Parameters (1) ── AbstractPPL.VarName │
│ Float64 θ │
│ │
│ Extras (14) │
│ Int64 n_steps, tree_depth │
│ Bool is_accept, numerical_error │
│ Float64 acceptance_rate, log_density, hamiltonian_energy, │
│ hamiltonian_energy_error, max_hamiltonian_energy_error, step_size, │
│ nom_step_size, logprior, loglikelihood, logjoint │
╰──────────────────────────────────────────────────────────────────────────────╯
Because the mock filter computes a Gaussian log-likelihood with unit variance, the posterior for θ should concentrate around the sample mean of data.
When to use this pattern
Use @addlogprob! whenever the likelihood of your observations is computed by code that lives outside Turing’s ~ syntax. Typical cases include:
State-space filtering — packages such as SSMProblems.jl and GeneralisedFilters.jl evaluate the marginal likelihood via Kalman or particle filters.
Hidden Markov Models — the HMM tutorial shows the same pattern using HiddenMarkovModels.jl and logdensityof.
Any domain-specific likelihood — whenever you have a function that returns a log-probability, you can plug it in with @addlogprob!.
For more details on the macro itself, see Modifying the Log Probability .
Back to top