Go back to Flu Mortality
library(bbmle)
library(deSolve)
dyn.load(“mymod.so”)
data3 = c(118, 124, 126, 118, 124, 136, 145, 140, 172, 172, 206, 236, 239, 197, 189, 161, 162, 160, 158, 158, 142, 142, 142)
t3 = c(0:22)
base3 = c(102.1140, 103.1020, 104.1703, 105.3040, 106.4870, 107.7026, 108.9336, 110.1626, 111.3722, 112.5454, 113.6654, 114.7167, 115.6842, 116.5545, 117.3154, 117.9562, 118.4681, 118.8440, 119.0791, 119.1702, 119.1165, 118.9192, 118.5815)
model_SIR = function(t, theta) {
with(as.list(theta), { state1 = c(S = N - I1, I = I1) pars1 = c(beta = beta1, alpha = alpha1, N = N) state2 = c(S = N - I2, I = I2) pars2 = c(beta = beta2, alpha = alpha1, N = N) state3 = c(S = N - I3, I = I3) pars3 = c(beta = beta3, alpha = alpha1, N = N) out1 = ode(y = state1, times = t, func = "derivs", parms = pars1, jacfunc = "jac", dllname = "mymod", initfunc = "initmod", nout = 1, outnames = "S") out2 = ode(y = state2, times = t, func = "derivs", parms = pars2, jacfunc = "jac", dllname = "mymod", initfunc = "initmod", nout = 1, outnames = "S") out3 = ode(y = state3, times = t, func = "derivs", parms = pars3, jacfunc = "jac", dllname = "mymod", initfunc = "initmod", nout = 1, outnames = "S") return(cbind(-diff(out1[,"S"]), -diff(out2[,"S"]), -diff(out3[,"S"]))) })
}
loglik_negbin = function(theta, data, mean) {
# for negative bimonial, mean = r p /(1-p) r = theta[["r"]]; # if r < 0, return a tiny likelihood if (r < 0) { return(-1e10) } sum(dnbinom(x=data, size=r, mu=mean, log=TRUE))
}
SIR_fit_given_logL = function(times, data, base, theta0, model, logL) { # construct a general negative log-likelyhood function
L <- function() { # reconstruct the vector of named pairs of # parameters from the list of arguments l=length(theta0) theta=c() vars=names(theta0) for (i in 1:l) { item=c(x=get(vars[i])) names(item) <- vars[i] theta <-c(theta, item) } N = theta[["N"]] if(N < sum(data)) { return(1e10) } for(i in 1:length(theta)) { if(theta[[i]] < 0) { return(1e10) } } l = model(times, theta) #"base" is the vector of baseline values mean = l[,1] + l[,2] + l[,3] + base # compute the negative log-likelihood L = -logL(theta, data, mean) # if not a number, return a very small likelihood if (is.na(L)) { return(1e10) } return(L) }
# replace the input arguments of L by the list of parameters formals(L)←as.list(theta0) # mle2 # sometimes confint may find a better solution. # In this case we need to refit the model with the better # solution as a starting paoint, because the parameter # names in the returned better fit can be wrong fit = mle2(L, method = “BFGS”, start = as.list(theta0), control = list(maxit = 1e6*length(theta0))) # fit = mle2(L, method = “Nelder-Mead”, start = as.list(theta0), control = list(maxit = 1e6*length(theta0), ndeps = 1e-4, reltol = 1e-10)) # if there is only one parameter to be fitted # the returned confidence interval is a vector # change it to a matrix return(fit) }
SIR_fit = function(times, data, base, theta0, model) {
# we start with negative binomial if (is.na(theta0['r'])) { theta0 = c(theta0, r = 17997748) } while (TRUE) { p = SIR_fit_given_logL(times, data, base, theta0, model, loglik_negbin) conf = confint(p) if(is.vector(conf)) { conf = matrix(conf, nrow = 1) } if(is.matrix(conf)) { break } theta0 = coef(conf) names(theta0) = names(coef(p)) } return(list(fit=p, conf = conf, r=coef(p)["r"]))
}
c = SIR_fit(c(0:23), data3, base3, c(beta1 = 2.3, alpha1 = 2.2, N = (sum(data3)*1.166), I1 = 1, beta2 = 2.3, I2 = 1, beta3 = 2.3, I3 = 1), model_SIR)
print©
aicc = AICc(c"fit", nobs = length(data3))
print(aicc)