# Multivariate Distributions & Parameter Inference

Hi all,

I was trying to adapt the example from this tutorial on parameter inference
to a generalized Lotka-Volterra model with n equations when I ran into some issues. In order to write multivariate distributions into the Turing model (and avoid the much discussed (Turing type error: expected Float64, got ForwardDiff.Dual)) I followed the instructions outlined at the performance tips note, however, in this workflow this pushed the error to the subsequent “predicted = …” line when evaluating with the sampled values because my ODE function is not fit to handle the ForwardDiff.Dual{…} type.

How should I restructure this to get around the type errors?

Here is the code:

``````##
using DifferentialEquations
using Plots
using Random
using Turing
# Turing.turnprogress(false)
## Generate Model and Synthetic Data
# Random.seed!(14);

function gLV!(dx,x,p,t)
x[x .< 1e-8] .= 0
mu, A, np = p
dx .= x.*(mu + A*x)

# no cc catch
if any(x .> 100.0)
dx .= 0
end
end

function mult_noise!(dx,x,p,t)
mu, A, np = p
dx .= x.*np
end

mu = [0.4; 0.8; 0.2].*0.1
A = [-1.5 0.5 -0.2; -0.7 -1.3 0.1; 0.8 -0.2 -0.9]
np = [0.01; 0.01; 0.01] # species noise percentages

x0 = [0.1; 0.1; 0.1].*0.1
tspan = (0.0, 144.0)

# Definite Model with Read-Out Noise
np.=0

prob1 = ODEProblem(gLV!, x0, tspan, (mu, A, np))
sol = solve(prob1, Tsit5(), saveat = 24)
syndata = Array(sol) + 0.003*randn(size(Array(sol)))
plot(sol, alpha=0.3)
scatter!(sol.t, syndata')
title!("Definite")

## MCMC Fittin

@model function fitglv(data, prob1, ::Type{T} = Float64) where {T}
σ ~ InverseGamma(2, 3)

n = size(prob1.u0,1)
mu = Vector{T}(undef, n)
A = Matrix{T}(undef, n, n)

for i = 1:n
mu[i] ~ truncated(Normal(0.4, 0.2), 0, 1.5)
end

for i = 1:n
for j = 1:n
if i == j
A[i,j] ~ truncated(Normal(-0.8,1),-3,0)
else
A[i,j] ~ truncated(Normal(-0.3,1),-3,3)
end
end
end

np .= 0
p = (mu, A, np)
prob = remake(prob1, p=p)
predicted = solve(prob, Tsit5(), saveat=24)

for i = 1:length(predicted)
data[:,i] ~ MvNormal(predicted[i], σ)
end
end

model = fitglv(syndata, prob1)
chain = mapreduce(c -> sample(model, NUTS(.65), 1000), chainscat, 1:3)
``````

and the full error I am gettting:

``````TypeError: in typeassert, expected Float64, got a value of type ForwardDiff.Dual{Nothing,Float64,7}
macro expansion at simdloop.jl:77 [inlined]
Note, I tried using `filldist()` to see if it would work instead of the `{T}` fix, but my problem with this is that I need a different distribution for the diagonal of the matrix. My overwriting with CartesianIndex is not working:
`MethodError: no method matching axes(::DistributionsAD.MatrixOfUnivariate{Continuous,Truncated{Normal{Float64},Continuous,Float64},FillArrays.Fill{Truncated{Normal{Float64},Continuous,Float64},2,Tuple{Base.OneTo{Int64},Base.OneTo{Int64}}}}, ::Int64)`