I am sure you guys ae eagerly awaiting the results.
I have decideds to perform a quick scan of the parameter space to get a quick feel of the Cost surface.
Here is the code
function Generate_Detect_Dead(param; enddayval=29)
S = Array{Float64}(undef,100)
I = Array{Float64}(undef,100)
R = Array{Float64}(undef,100)
β = param[1]
γ = param[2]
detect_rate = param[4]
death_rate = param[5]
endday=enddayval
S_zero = 1.4E9
I_zero = param[3]
R_zero = 0.0
N = S_zero + I_zero
ΔS = -β * (S_zero * I_zero / N)
ΔI = β * (S_zero * I_zero / N) - γ * I_zero
ΔR = γ * I_zero
S[1] = S_zero + ΔS
I[1] = I_zero + ΔI
R[1] = R_zero + ΔR
for t=2:endday
ΔS = -β * (S[t-1] * I[t-1] / N)
ΔI = β * (S[t-1] * I[t-1] / N) - γ * I[t-1]
ΔR = γ * I[t-1]
S[t] = S[t-1] + ΔS
I[t] = I[t-1] + ΔI
R[t] = R[t-1] + ΔR
end
daterange = 1:endday
DEAD = death_rate .* R[daterange]
DETECT = detect_rate .* I[daterange] + DEAD[daterange]
return (DETECT,DEAD)
end
function CostFunc(param,ActualCases,ActualDeaths)
(DETECT,DEAD)=Generate_Detect_Dead(param)
cost = 0.0
for k = 1:length(ActualCases)
(day,case) = ActualCases[k]
cost += (DETECT[day] - case)^2.0
end
for k = 1:length(ActualDeaths)
(day,death) = ActualDeaths[k]
cost += day^2.8 * (DEAD[day] - death)^2.0
end
return cost
end
function main()
# Actual Data
ActualCases = [ (16,45),(17,62),(18,121),(19,198),
(20,291),(21,440),(22,571),(23,830),(24,1287),(25,1975),
(26,2744),(27,4515),(28,5974),(29,7771) ];
ActualDeaths = [ (19,3),(20,6),(21,9),(22,17),
(23,25),(24,41),(25,56),(26,80),(27,106),
(28,132),(29,170) ];
lowest_cost = Inf
lowest_param = undef
for β = range(0.001,0.5,length=40)
for γ = range(0.001,0.5,length=40)
for detect_rate = range(0.01,0.99,length=40)
for death_rate = range(0.01,0.99,length=40)
for I_zero = range(1,100,length=40)
# Below is the parameter for the
parameter = (β, # β
γ, # γ
I_zero, # I_zero
detect_rate, # detect_rate
death_rate # death_rate
)
cost = CostFunc(parameter,ActualCases,ActualDeaths)
if cost < lowest_cost
lowest_cost = cost
lowest_param = parameter
end
end
end
end
end
end
println("lowest cost is ",lowest_cost)
println("lowest param is ",lowest_param)
println("β is ",lowest_param[1])
println("γ is ",lowest_param[2])
println("I_zero is ",lowest_param[3])
println("detect_rate is ",lowest_param[4])
println("death_rate is ",lowest_param[5])
(DETECT,DEAD)=Generate_Detect_Dead(lowest_param)
daterange = 1:29
for t in daterange
println("$t Jan 2020 DETECT=",round(DETECT[t])," DEAD=",round(DEAD[t]))
end
println("R0 is ",round(lowest_param[1]/lowest_param[2],sigdigits=3))
end
main()
Before I talk about the results, Here is what I have learned.
The Cost function must be constructed carefully. Because there are two sets of numbers coming out of China which are (1) num of cases and (2) num of Deaths
I must make sure that the cost of “num of cases” mismatch be roughly equal to the cost of “num of deaths” mismatch. Furthuremore, the mismatch later in the reporting timeline must have more weight than the mismatches earlier in the timeline
function CostFunc(param,ActualCases,ActualDeaths)
(DETECT,DEAD)=Generate_Detect_Dead(param)
cost = 0.0
for k = 1:length(ActualCases)
(day,case) = ActualCases[k]
cost += (DETECT[day] - case)^2.0
end
for k = 1:length(ActualDeaths)
(day,death) = ActualDeaths[k]
cost += day^2.8 * (DEAD[day] - death)^2.0
end
return cost
end
And now the results
β is 0.3976
γ is 0.05217
I_zero is 3.5
detect_rate is 0.38
death_rate is 0.060
We have
lowest cost is 3.986469644672301e6
lowest param is (0.39764102564102566, 0.05217948717948718, 3.5384615384615383, 0.3869230769230769, 0.06025641025641026)
β is 0.39764102564102566
γ is 0.05217948717948718
I_zero is 3.5384615384615383
detect_rate is 0.3869230769230769
death_rate is 0.06025641025641026
1 Jan 2020 DETECT=2.0 DEAD=0.0
2 Jan 2020 DETECT=3.0 DEAD=0.0
3 Jan 2020 DETECT=3.0 DEAD=0.0
4 Jan 2020 DETECT=5.0 DEAD=0.0
5 Jan 2020 DETECT=6.0 DEAD=0.0
6 Jan 2020 DETECT=8.0 DEAD=0.0
7 Jan 2020 DETECT=11.0 DEAD=0.0
8 Jan 2020 DETECT=15.0 DEAD=0.0
9 Jan 2020 DETECT=20.0 DEAD=0.0
10 Jan 2020 DETECT=27.0 DEAD=1.0
11 Jan 2020 DETECT=37.0 DEAD=1.0
12 Jan 2020 DETECT=49.0 DEAD=1.0
13 Jan 2020 DETECT=66.0 DEAD=1.0
14 Jan 2020 DETECT=89.0 DEAD=2.0
15 Jan 2020 DETECT=120.0 DEAD=3.0
16 Jan 2020 DETECT=162.0 DEAD=4.0
17 Jan 2020 DETECT=217.0 DEAD=5.0
18 Jan 2020 DETECT=293.0 DEAD=7.0
19 Jan 2020 DETECT=394.0 DEAD=9.0
20 Jan 2020 DETECT=530.0 DEAD=12.0
21 Jan 2020 DETECT=713.0 DEAD=16.0
22 Jan 2020 DETECT=959.0 DEAD=22.0
23 Jan 2020 DETECT=1290.0 DEAD=30.0
24 Jan 2020 DETECT=1736.0 DEAD=40.0
25 Jan 2020 DETECT=2335.0 DEAD=54.0
26 Jan 2020 DETECT=3142.0 DEAD=72.0
27 Jan 2020 DETECT=4227.0 DEAD=97.0
28 Jan 2020 DETECT=5688.0 DEAD=131.0
29 Jan 2020 DETECT=7652.0 DEAD=176.0
R0 is 7.62