# Use of intermediate variables to condition likelihood

I’d like to model prices as following a kind of stochastic difference equation, where jumps from one time step to the next follow
p_{t} = p_{t - 1} + c \exp(- b t_0) \Delta t + X(t)
X ~ \text{student_t}(3, 0, \sqrt{\Delta t} \times (\sigma_0 + \sigma \exp(- \gamma t))
Here is the model

d_price_mean(c::Real, b::Real, t0::Real, dt::Real)::Real = begin
c * exp(- b * t0) * dt
end

perturbation_volatility(
sigma1::Real,
sigma::Real,
gamma::Real,
t0::Real, dt::Real)::Real = begin
sigma1 + sigma * exp(- gamma * t0) * sqrt(dt)
end

@model price_model(
d_price,
selldown_time,
d_selldown_time,
n
) = begin
c ~ LogNormal(2, 1)
b ~ LogNormal(2, 1)
sigma1 ~ LogNormal(-1.3862943611198906, 1)
sigma ~ LogNormal(-0.6931471805599453, 1)
gamma ~ LogNormal(2, 1)
price_diff = d_price .- d_price_mean.(Ref(c), Ref(b), selldown_time, d_selldown_time)
vol = perturbation_volatility.(
Ref(sigma1),
Ref(sigma),
Ref(gamma),
selldown_time,
d_selldown_time)
std_price_diff = price_diff ./ vol
for i = 1:n
std_price_diff[i] ~ TDist(3)
end
end


When I try sampling from this model, it never finishes even with a trivial amount of data, and when I try running the MAP to test, each of the individual parameters (c, b, \sigma, \sigma_{1}, \gamma) all converge to exactly their prior modes. This indicates to me that I must be defining the likelihood in a way such that its gradient is exactly the zero vector.

My guess is that for Turing to pick up on a likelihood, it must have an argument to the left of the sampling statement, or else it just defines a new parameter, even if its been defined in the model scope. What would be the right way to write these kinds of reparameterizations?

In Turing, it is not possible for the left-hand side of a tilde expression to be a function of sampled parameters. In general, I think this would violate conditional probability. Since your transformation is affine, you can instead transform TDist. i.e. a + bx ~ TDist(ν) is equivalent to x ~ (TDist(ν) - a) / b with Distributions’s syntax/

So I think something like this would be equivalent to what you have:

d_price .~ (TDist(3) .+ (d_price .- price_diff)) .* vol