OK – the tutorial on Turing seems to work ok (although I get different results each time I run the fitting).
NEXT project – try to use Turing
when I only measure a subset of the states (SIR model + data for I – the number of infected). In my initial attempt, I get an error message of inconsistent array dimensions…
Here is my attempt. First the experimental data
N = 763
tm = 3:14
Id = [25, 75, 227, 296, 258, 236, 192, 126, 71, 28, 11, 7]
The deterministic model:
# Function for deterministic SIR model
function sir_expanded!(dx,x,p,t,N)
S,I,R = x
tau_i,tau_r = p
#
dS = -I*S/tau_i/N
dI = I*S/tau_i/N - I/tau_r
dR = I/tau_r
dx .= [dS,dI,dR]
end
#
sir! = (dx,x,p,t) -> sir_expanded!(dx,x,p,t,N)
Next, initial values, parameters, etc. + problem solving:
I3 = Float64(Id[1])
S3 = N-I3
R3 = 0.
x3 = [S3,I3,R3]
#
tau_i = 0.553
tau_r = 2.15
RR0 = round(tau_r/tau_i,digits=1)
p = [tau_i, tau_r]
#
tspan=(3.,14.)
#
prob = ODEProblem(sir!,x3,tspan,p)
sol = solve(prob)
[I can plot the data + simulation results:
fg = plot(sol,lw=LW1,lc=[:blue :red :green],label=["\$S, \\mathsf{R}_0=$RR0\$" "\$I, \\mathsf{R}_0=$RR0\$" "\$R, \\mathsf{R}_0=$RR0\$"])
scatter!(fg,tm, Id, st=:scatter,ms=MS1,mc=:red,label=L"I^\mathrm{d}")
plot!(xlabel="time [day]",ylabel="# boys",title="Boarding school measles infection")
]
NOW, I try to use Turing
to solve the problem (the only new package I import is via using Turing
):
Turing.setadbackend(:forwarddiff)
#
@model function fit_sir(I_data)
V ~ InverseGamma(2,3)
tau_i ~ truncated(Normal(0.5,0.25),0.2,1)
tau_r ~ truncated(Normal(2,0.5),0.5,10)
#
p = [tau_i,tau_r]
prob = ODEProblem(sir!, x3, tspan, p)
I_pred = solve(prob, Tsit5(), saveat=1., save_idxs=[2])
#
for i in 1:length(I_pred)
I_data[:,i] ~ MvNormal(I_pred[i], V)
end
end
#
model = fit_sir(Id)
Finally, I run the sample
method to do the parameter estimation:
p_est = sample(model,NUTS(.65),10_000)
This leads to an error message:
DimensionMismatch("Inconsistent array dimensions.")
Stacktrace:
[1] logpdf(::MvNormal{Float64,PDMats.ScalMat{Float64},Array{Float64,1}}, ::Array{Int64,1}) at C:\Users\Bernt_Lie\.julia\packages\Distributions\jFoHB\src\multivariates.jl:193
[2] observe at C:\Users\...
As far as I can see, the only real difference compared to the tutorial Lotka Volterra model, are: (A) I attempt to specify that only a subset of states are available in the data array (save_idxs
), and (B) I have only imported the Turing
package, not all the other packages (DiffEqBayes
, etc.).
Question: what is it that I do incorrectly?