In the last few examples of epidemiological modeling, I focused on stochastic models. However, most published models are in the form of a set of differential equations. In R, I often use simecol. The ODE package in Julia offers some functionality for solving ordinary differential equations, which should be very familiar to users of Matlab/Octave.
Here's the old favourite, the susceptible-infected-recovered model again.
# Load libraries
using ODE
using DataFrames
using Gadfly
# Define the model
# Has to return a column vector
function SIR(t,x)
S=x[1]
I=x[2]
R=x[3]
beta=x[4]
gamma=x[5]
N=S+I
dS=-beta*S*I/N
dI=beta*S*I/N-gamma*I
dR=gamma*I
return([dS;dI;dR;0;0])
end
# Initialise model
t = linspace(0,500,101);
inits=[9999,1,0,0.1,0.05];
# Run model
result=ode23(SIR,t,inits);
# Collate results in DataFrame
df=DataFrame();
df["t"]=result[1];
df["S"]=result[2][:,1];
df["I"]=result[2][:,2];
df["R"]=result[2][:,3];
# Plot using Gadfly
p=Gadfly.plot(df,x="t",y="I",Geom.line)
There are a few things to note; firstly, the syntax of the ode23 command expects only the time and a state vector. For parameter values, one can hard-code them in the model description (not good) or pass them as additional variables (with gradient 0, so they don't change). I don't really like either option. Perhaps one can use macros to do much the same job, but I'm not that well acquainted with Julia yet.
Lexical scoping and anonymous functions are your friends here. If you are solving x' = f(t,x, p), with p being some additional parameter(s), and you have the function f, you can just do:
ReplyDeleteode23((t,x) -> f(t,x,p), trange, x0)
in order to pass some additional parameteter p to f.
Thanks Steven! Updated code as follows.
Deletefunction SIR(t,x,p)
S=x[1]
I=x[2]
R=x[3]
beta=p[1]
gamma=p[2]
N=S+I
dS=-beta*S*I/N
dI=beta*S*I/N-gamma*I
dR=gamma*I
return([dS;dI;dR])
end
# Initialise model
t = linspace(0,500,101);
inits=[9999,1,0];
p=[0.1,0.05];
# Run model
result=ode23((t,x)->SIR(t,x,p),t,inits);
Hello,
ReplyDeleteI begin with Julia, trying to do the same with a 3d (non-linear) system to simulate. I used your code and compiled to check if it worked for me and it did. I then modified your setting for mine, but compiling gives error.
HERE IS THE CODE :
# Load libraries
using ODE # ODE package for simulations of the system
using DataFrames # DataFrames package for managing matrices
using Gadfly # Gadfly package for graphics
# please load these packages if they are not in your library
# If using IJulia and Gadfly, executing generates these natural errors
# Warning: could not import Base.foldl into NumericExtensions
# Warning: could not import Base.foldr into NumericExtensions
# Warning: could not import Base.sum! into NumericExtensions
# Warning: could not import Base.maximum! into NumericExtensions
# Warning: could not import Base.minimum! into NumericExtensions
# Warning: could not import StatsBase.bandwidth into Stat
# Warning: could not import StatsBase.kde into Stat
# Define the direct parameters of the dynamical system
nu = 3 # capital-to-output ratio
alpha = 0.025 # productivity growth rate
beta = 0.02 # population growth rate
gamma = 0.07 # markup adjustement speed and worst deflation rate
delta = 0.01 # depreciation rate of capital
r = 0.04 # interest rate on deposit/debt
c_1 = 0.9 # propensity to consume out of wage
c_2 = 0.03 # propensity to consume out of wealth
eta_p = 0.7 # rigidity factor of inflation in wage progression
m = 1.15 # target markup factor, m-1 = target profit rate
par_phi_0 = (0.04^3)/(1-0.04^2)
par_phi_1 = 0.04/(1-0.04^2)
par_kappa_0 = -0.01
par_kappa_1 = 0.9
par_kappa_2 = 2.5
parameters = [
nu;
alpha;
beta;
gamma;
delta;
r;
c_1;
c_2;
eta_p;
m;
par_phi_0;
par_phi_1;
par_kappa_0;
par_kappa_1;
par_kappa_2;
]
# Define the model
# Has to return a column vector of dim 3
function D3(t,X,p)
#state space variables
om = X[1]
lam = X[2]
d = X[3]
#parameters
nu = p[1]
alpha = p[2]
beta = p[3]
gamma = p[4]
delta = p[5]
r = p[6]
c_1 = p[7]
c_2 = p[8]
eta_p = p[9]
m = p[10]
par_phi = p[11:12]
par_kappa = p[13:15]
# Define the Philips curve function and its parameters
function fun_Phi(x, p)
return p[1] + p[2]/(1-x)^2
end
# Define the investment function and its parameters
function fun_Kappa(x,p)
return p[1] + p[2]*x*exp(p[3]*x)
end
#additional values
pi = 1 - om - r*d
y_d = c_1 * om + c_2 * d + fun_Kappa(pi, par_kappa)
inflation_rate = gamma * (m * om - 1)
#dynamics
d_om = om * (fun_Phi(lam, par_phi) - alpha - (1-eta_p) * inflation_rate)
d_lam = lam * (fun_Kappa(pi, par_kappa)/nu - alpha - beta - delta)
d_deb = d * (r + delta -inflation_rate - fun_Kappa(pi, par_kappa)/nu) + fun_Kappa(pi, par_kappa) - (1-om)*y_d
return([d_om;d_lam;d_deb])
end
# Initialise model
t = linspace(0,500,101);
Omega_0 = 0.70
Lambda_0 = 0.85
Debt_0 = 0.1
inits=[Omega_0,Lambda_0,Debt_0];
# Run model
result=ode23((t,x)->D3(t,x,parameters),t,inits);
# Collate results in DataFrame
df=DataFrame();
df["time"]=result[1];
df["omega_e"]=result[2][:,1];
df["lambda"]=result[2][:,2];
df["d_e"]=result[2][:,3];
HERE IS THE ANSWER :
no method append!(DataArray{Float64,1},DataArray{Float64,1})
in cat_aes_var! at /home/adrien/.julia/v0.2/Gadfly/src/aesthetics.jl:238
in cat at /home/adrien/.julia/v0.2/Gadfly/src/aesthetics.jl:217
in render at /home/adrien/.julia/v0.2/Gadfly/src/Gadfly.jl:644
in writemime at /home/adrien/.julia/v0.2/Gadfly/src/Gadfly.jl:751
in sprint at io.jl:434
in display_dict at /home/adrien/.julia/v0.2/IJulia/src/execute_request.jl:35
Do you have any clue of what happened? I understand that with semantic scope, the way I defined parameters is ok. I hope the code is clear.
Thank You,
Hi,
ReplyDeleteSorry for confusion, I had to delete the last part of code generating graphs, which is what actually what generates the error. It is different :
plot(df, layer(x="time", y="omega_e", Geom.point),
layer(x="time", y="lambda", Geom.line),
layer(x="time", y="d_e", Geom.line))
I'll try to correct it myself from here : http://dcjones.github.io/Gadfly.jl/#layers
Hi, Very nice description about Video Ranking Formula. I like your web blog.
ReplyDeleteBecause whenever i come into your web blog then i always get the new interesting and important information in your web blog.
Thank You
Viral factor Formula