Turing.jl - update variables within the model

I’m using Turing to fit a model, where every data point is a pair (S,L), as we describe in the following paper: Revisiting the links-species scaling relationship in food webs | bioRxiv

In practice, we do not use L to fit the model, but L-(S-1), and I have not been able to use this directly from within Turing - what I had to do was create a variable (equal to L.-(S.-1)) and then call the model on this.

The model is as follows:

@model flexible_links(s,f) = begin
    N = length(s)
    # Transformed data
    F = (s.*s) .- (s .- 1.0)
    # Parameters
    ϕ ~ Normal(3.0, 0.5)
    μ ~ Beta(3.0, 7.0)
    for i in 1:N
        f[i] ~ BetaBinomial(F[i], μ*exp(ϕ), (1-μ)*exp(ϕ))
    end
    return μ, ϕ
end

What I would like to write instead would look something like this:

@model flexible_links(s,l) = begin
    N = length(s)
    # Transformed data
    f = [l[i]-(s[i]-1) for i in 1:N]
    F = (s.*s) .- (s .- 1.0)
    # Parameters
    ϕ ~ Normal(3.0, 0.5)
    μ ~ Beta(3.0, 7.0)
    for i in 1:N
        f[i] ~ BetaBinomial(F[i], μ*exp(ϕ), (1-μ)*exp(ϕ))
    end
    return μ, ϕ
end

But it does not work, because f is of the wrong type - I’d appreciate any points as to where I should be looking to solve the problem.

Turing assumes that arguments to the model are observations and that all other model parameters should be treated as parameters. If f should be considered an observation you need to pass it to the model definition. Your model will also train faster if you construct f outside.

As an alternative you could use the @logpdf macro. But I would refrain from using it if not necessary.

1 Like

Gotcha - so there is no way in Turing to emulate what stan does with transformed variables, as in ms_straight_lines/betabin_connectance.stan at master · PoisotLab/ms_straight_lines · GitHub ?

At the moment we don’t have a way to do this, mainly because we assume that observations are passed as arguments. Transformations itself should not be an issue if we would be able to track that f depends on l and s. At the moment we don’t have a handle on this but it could be added to the compiler.

Could you open an issue if you feel that this would be an useful feature?

– EDIT –

Thanks for trying to implement your model in Turing! :slightly_smiling_face: