{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Julia Implementation of Host SEIR + Vector SEI\n", "\n", "*Author*: Carl A. B. Pearson @pearsonca\n", "\n", "*Date*: 2018-10-02\n", "\n", "This version considers multiple hosts, which introduces some indexing complications. This approach adopts the indexing scheme of:\n", "\n", " - all of host $i$ compartments ($S_H$, $E_H$, etc), for $i \\in 1\\ldots N$\n", " - vector compartments last\n", "\n", "With this approach, we can re-use the solution for one host, with slight modifications:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "F (generic function with 1 method)" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "H_comps = 4\n", "V_comps = 3\n", "\n", "# in sub functions, du / u are the particular relevant slices only\n", "function F1H(du,u,p,t,I_V,N_H)\n", " S_H, E_H, I_H, R_H = u\n", " \n", " # host dynamics\n", " host_infection = (p.β*S_H*I_V)/N_H\n", " host_mortality = p.μ_H .* u # include S_H, so easier to remove mortality\n", " host_births = sum(host_mortality)\n", " host_progression = p.σ_H*E_H\n", " recovery = p.λ*I_H\n", " \n", " du[1] = -host_infection + host_births\n", " du[2] = host_infection - host_progression\n", " du[3] = host_progression - recovery\n", " du[4] = recovery\n", " du[1:end] -= host_mortality \n", "end\n", "\n", "# in sub functions, du / u are the particular relevant slices only\n", "function FV(du,u,p,t,sum_β_I_H)\n", " S_V, E_V, I_V = u\n", " vec_infection = sum_β_I_H*S_V/p.N_H\n", " vec_mortality = p.μ_V .* u # include S_V, so easier to remove mortality\n", " vec_births = sum(vec_mortality)\n", " vec_progression = p.σ_V*E_V\n", " \n", " du[1] = -vec_infection + vec_births\n", " du[2] = vec_infection - vec_progression\n", " du[3] = vec_progression\n", " du[1:end] -= vec_mortality\n", "end\n", "\n", "function F(du,u,p,t)\n", " uvec = @view(u[(p.nHosts*H_comps+1):end]) # grab the vector compartments\n", " S_V, E_V, I_V = uvec\n", " sum_β_I_H = 0.0\n", " for host in 0:(p.nHosts-1)\n", " slice = (1:H_comps).+(H_comps*host)\n", " F1H(@view(du[slice]), @view(u[slice]), p.host[host+1], t, I_V, p.vec.N_H)\n", " # must use @view here, so that these arrays can be modified in F1H\n", " sum_β_I_H += p.host[host+1].β * u[slice[3]] # this host's I compartment\n", " end\n", " FV(@view(du[(p.nHosts*4+1):end]), uvec, p.vec,t,sum_β_I_H)\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, state initial conditions. This code generates them randomly for convenience, though they could be assigned based on data, desired parameter space, or algorithmically as part of a fitting process:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "23×1 Array{Float64,2}:\n", " 100.0\n", " 0.0\n", " 1.0\n", " 0.0\n", " 100.0\n", " 0.0\n", " 0.0\n", " 0.0\n", " 100.0\n", " 0.0\n", " 0.0\n", " 0.0\n", " 100.0\n", " 0.0\n", " 0.0\n", " 0.0\n", " 100.0\n", " 0.0\n", " 0.0\n", " 0.0\n", " 10000.0\n", " 0.0\n", " 0.0" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "nH = 5\n", "srand(0)\n", "\n", "S_Hs = ones(nH) .* 100.0\n", "E_Hs = zeros(nH)\n", "I_Hs = shuffle(vcat(zeros(nH-1),[1.0]))\n", "R_Hs = zeros(nH)\n", "host0 = reshape(hcat(S_Hs,E_Hs,I_Hs,R_Hs)', nH*4, 1)\n", "vec0 = [10000.0, 0.0, 0.0]\n", "u0 = vcat(host0, vec0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, generate dynamic parameters. Again: this code generates them randomly for convenience, though they could be assigned based on data, desired parameter space, or algorithmically as part of a fitting process:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(nHosts = 5, vec = (μ_V = 0.03333333333333333, σ_V = 0.14285714285714285, N_H = 501.0), host = NamedTuples._NT_μ__H_σ__H_λ_β{Float64,Float64,Float64,Float64}[(μ_H = 0.0117686, σ_H = 0.790008, λ = 0.0642631, β = 0.0209472), (μ_H = 0.00801628, σ_H = 0.175085, λ = 0.0817059, β = 0.0251379), (μ_H = 0.00888301, σ_H = 0.166683, λ = 0.0840894, β = 0.00203749), (μ_H = 0.351205, σ_H = 0.662263, λ = 0.0461889, β = 0.0287702), (μ_H = 0.00568503, σ_H = 0.168919, λ = 0.127011, β = 0.0859512)])" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "srand(1)\n", "\n", "μs = 1 ./ (rand(nH) .* 360)\n", "σs = 1 ./ (rand(nH) .* 6)\n", "λs = 1 ./ (rand(nH) .* 28)\n", "βs = rand(nH) ./ 10.0\n", "\n", "using NamedTuples\n", "# nb: in >= Julia v0.7, can eliminate this import\n", "# and the @NT syntax\n", "p = @NT(\n", " nHosts = nH,\n", " vec = @NT(μ_V=1/30, σ_V=1/7, N_H = sum(host0)),\n", " host = [@NT(μ_H=μs[i], σ_H=σs[i], λ=λs[i], β=βs[i]) for i in 1:nH]\n", " # just building up a random collection of params for demonstration\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now these values can be used with the ODE solver:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "retcode: Success\n", "Interpolation: 1st order linear\n", "t: 3651-element Array{Float64,1}:\n", " 0.0\n", " 0.1\n", " 0.2\n", " 0.3\n", " 0.4\n", " 0.5\n", " 0.6\n", " 0.7\n", " 0.8\n", " 0.9\n", " 1.0\n", " 1.1\n", " 1.2\n", " ⋮ \n", " 363.9\n", " 364.0\n", " 364.1\n", " 364.2\n", " 364.3\n", " 364.4\n", " 364.5\n", " 364.6\n", " 364.7\n", " 364.8\n", " 364.9\n", " 365.0\n", "u: 3651-element Array{Array{Float64,2},1}:\n", " [100.0; 0.0; … ; 0.0; 0.0] \n", " [100.001; 4.05106e-8; … ; 0.041287; 0.000295821]\n", " [100.002; 3.15487e-7; … ; 0.08154; 0.00117209] \n", " [100.004; 1.03672e-6; … ; 0.120779; 0.00261227] \n", " [100.005; 2.39309e-6; … ; 0.159026; 0.00460017] \n", " [100.006; 4.55256e-6; … ; 0.196298; 0.00711996] \n", " [100.007; 7.66377e-6; … ; 0.232616; 0.0101561] \n", " [100.008; 1.18579e-5; … ; 0.267998; 0.0136934] \n", " [100.009; 1.72497e-5; … ; 0.302464; 0.017717] \n", " [100.011; 2.39395e-5; … ; 0.336032; 0.0222123] \n", " [100.012; 3.20139e-5; … ; 0.36872; 0.0271651] \n", " [100.013; 4.15473e-5; … ; 0.400545; 0.0325615] \n", " [100.014; 5.26028e-5; … ; 0.431526; 0.0383877] \n", " ⋮ \n", " [45.2552; 0.790354; … ; 78.2356; 335.113] \n", " [45.2574; 0.790394; … ; 78.2385; 335.114] \n", " [45.2595; 0.790434; … ; 78.2413; 335.114] \n", " [45.2617; 0.790474; … ; 78.2442; 335.115] \n", " [45.2639; 0.790514; … ; 78.2471; 335.116] \n", " [45.2661; 0.790553; … ; 78.25; 335.117] \n", " [45.2682; 0.790593; … ; 78.2528; 335.117] \n", " [45.2704; 0.790633; … ; 78.2557; 335.118] \n", " [45.2725; 0.790673; … ; 78.2586; 335.119] \n", " [45.2747; 0.790713; … ; 78.2615; 335.12] \n", " [45.2768; 0.790753; … ; 78.2643; 335.121] \n", " [45.279; 0.790792; … ; 78.2672; 335.122] " ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "using DifferentialEquations\n", "using IterableTables, DataFrames\n", "\n", "tspan = (0.0, 365.0)\n", "prob = ODEProblem(F, u0, tspan, p)\n", "sol = solve(prob,Tsit5(),reltol=1e-8,abstol=1e-8,saveat=linspace(0,365,365*10+1))" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
variable | value | timestamp | index | name | facet | compartment | |
---|---|---|---|---|---|---|---|
1 | value1 | 100.0 | 0.0 | 1 | S_H1 | H1 | S |
2 | value1 | 100.0011761246569 | 0.1 | 1 | S_H1 | H1 | S |
3 | value1 | 100.00235062049974 | 0.2 | 1 | S_H1 | H1 | S |
4 | value1 | 100.00352325035139 | 0.3 | 1 | S_H1 | H1 | S |
5 | value1 | 100.00469378414253 | 0.4 | 1 | S_H1 | H1 | S |
6 | value1 | 100.00586199875751 | 0.5 | 1 | S_H1 | H1 | S |
7 | value1 | 100.00702767789407 | 0.6 | 1 | S_H1 | H1 | S |
8 | value1 | 100.00819061190617 | 0.7 | 1 | S_H1 | H1 | S |
9 | value1 | 100.00935059768018 | 0.8 | 1 | S_H1 | H1 | S |
10 | value1 | 100.01050743847112 | 0.9 | 1 | S_H1 | H1 | S |
11 | value1 | 100.01166094378736 | 1.0 | 1 | S_H1 | H1 | S |
12 | value1 | 100.01281092925007 | 1.1 | 1 | S_H1 | H1 | S |
13 | value1 | 100.01395721643992 | 1.2 | 1 | S_H1 | H1 | S |
14 | value1 | 100.01509963280547 | 1.3 | 1 | S_H1 | H1 | S |
15 | value1 | 100.01623801150974 | 1.4 | 1 | S_H1 | H1 | S |
16 | value1 | 100.01737219128947 | 1.5 | 1 | S_H1 | H1 | S |
17 | value1 | 100.01850201637215 | 1.6 | 1 | S_H1 | H1 | S |
18 | value1 | 100.01962733634535 | 1.7 | 1 | S_H1 | H1 | S |
19 | value1 | 100.02074800598677 | 1.8 | 1 | S_H1 | H1 | S |
20 | value1 | 100.02186388520346 | 1.9 | 1 | S_H1 | H1 | S |
21 | value1 | 100.02297483892835 | 2.0 | 1 | S_H1 | H1 | S |
22 | value1 | 100.0240807369486 | 2.1 | 1 | S_H1 | H1 | S |
23 | value1 | 100.02518145380708 | 2.2 | 1 | S_H1 | H1 | S |
24 | value1 | 100.02627686872802 | 2.3 | 1 | S_H1 | H1 | S |
25 | value1 | 100.02736686552852 | 2.4 | 1 | S_H1 | H1 | S |
26 | value1 | 100.0284513324241 | 2.5 | 1 | S_H1 | H1 | S |
27 | value1 | 100.02953016196817 | 2.6 | 1 | S_H1 | H1 | S |
28 | value1 | 100.03060325097552 | 2.7 | 1 | S_H1 | H1 | S |
29 | value1 | 100.03167050044642 | 2.8 | 1 | S_H1 | H1 | S |
30 | value1 | 100.03273181537787 | 2.9 | 1 | S_H1 | H1 | S |
⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ |