Newer
Older

Peter Jentsch
committed
#remove Base.@propagate_inbounds during tests if you get segfaults or change anything,
# as that might mean there is an indexing bug that is not being caught,
#and therefore accessing the wrong memory is causing background errors

Peter Jentsch
committed
function contact_weight(p, contact_time)
return 1 - (1-p)^contact_time
end

Peter Jentsch
committed
function Φ(payoff,β)
return 1 / (exp(-1*β*payoff))
end

Peter Jentsch
committed
Base.@propagate_inbounds @views function update_alert_durations!(t,modelsol) # Base.@propagate_inbounds
@unpack notification_parameter,notification_threshold = modelsol.params
@unpack time_of_last_alert, app_user_index,inf_network,covid_alert_notifications,app_user = modelsol
for (i,node) in enumerate(modelsol.app_user_index)

Peter Jentsch
committed
for j in 2:14

Peter Jentsch
committed
covid_alert_notifications[j-1,i] = covid_alert_notifications[j,i] #shift them all back

Peter Jentsch
committed
end

Peter Jentsch
committed
total_weight_i = 0
for mixing_graph in inf_network.graph_list[t]
for j in neighbors(mixing_graph.g,node)
if app_user[j]
total_weight_i+= get_weight(mixing_graph,GraphEdge(node,j))
end

Peter Jentsch
committed
end
end

Peter Jentsch
committed
coin_flip = 1 - (1 - notification_parameter)^total_weight_i

Peter Jentsch
committed
r = rand(Random.default_rng(Threads.threadid()))

Peter Jentsch
committed
if r < coin_flip
covid_alert_notifications[end,i] = 1 #add the notifications for today
else
covid_alert_notifications[end,i] = 0
end
if sum(covid_alert_notifications[:,i])>=notification_threshold

Peter Jentsch
committed
time_of_last_alert[i] = t
end
end
end

Peter Jentsch
committed
Base.@propagate_inbounds @views function update_infection_state!(t,modelsol)
@unpack base_transmission_probability,immunization_loss_prob,recovery_rate,immunizing,immunization_begin_day = modelsol.params
@unpack u_inf,u_vac,u_next_inf,u_next_vac,demographics,inf_network,status_totals, immunization_countdown = modelsol

Peter Jentsch
committed
modelsol.daily_infected = 0
modelsol.daily_immunizations_by_age.= 0

Peter Jentsch
committed
function agent_transition!(node, from::AgentStatus,to::AgentStatus)
immunization_countdown[node] = -1

Peter Jentsch
committed
status_totals[Int(from)] -= 1
status_totals[Int(to)] += 1

Peter Jentsch
committed
u_next_inf[node] = to
end
u_next_inf .= u_inf

Peter Jentsch
committed
for i in 1:modelsol.nodes
agent_status = u_inf[i]
is_vaccinator = u_vac[i]
agent_demo = demographics[i]
if agent_status == Susceptible
if is_vaccinator && immunizing && immunization_countdown[i] == -1 && t> immunization_begin_day
immunization_countdown[i] = 14

Peter Jentsch
committed
else

Peter Jentsch
committed
for mixing_graph in inf_network.graph_list[t]

Peter Jentsch
committed
for j in neighbors(mixing_graph.g,i)

Peter Jentsch
committed
if u_inf[j] == Infected && u_next_inf[i] != Infected

Peter Jentsch
committed
if rand(Random.default_rng(Threads.threadid())) < contact_weight(base_transmission_probability,get_weight(mixing_graph,GraphEdge(i,j)))

Peter Jentsch
committed
agent_transition!(i, Susceptible,Infected)
end

Peter Jentsch
committed
end
end
end
end
elseif agent_status == Infected

Peter Jentsch
committed
if rand(Random.default_rng(Threads.threadid())) < recovery_rate

Peter Jentsch
committed
agent_transition!(i, Infected,Recovered)

Peter Jentsch
committed
end
elseif agent_status == Immunized

Peter Jentsch
committed
if rand(Random.default_rng(Threads.threadid())) < immunization_loss_prob

Peter Jentsch
committed
agent_transition!(i, Immunized,Susceptible)

Peter Jentsch
committed
end
end
if immunization_countdown[i] == 0
modelsol.daily_immunizations_by_age[Int(agent_demo)] += 1
agent_transition!(i, Susceptible,Immunized)
elseif immunization_countdown[i]>0
immunization_countdown[i] -= 1
end

Peter Jentsch
committed
end
end
Base.@propagate_inbounds @views function update_vaccination_opinion_state!(t,modelsol,total_infections)
@unpack π_base, η,γ, κ, ω, ρ_y,ρ_m,ρ_o, ω_en,ρ_en,γ,β = modelsol.params

Peter Jentsch
committed
@unpack demographics,time_of_last_alert, nodes, soc_network,u_vac,u_next_vac,app_user,app_user_list = modelsol

Peter Jentsch
committed
app_user_pointer = 0
for i in 1:nodes
vac_payoff = 0
soc_nbrs_vac = @MArray [0,0,0]

Peter Jentsch
committed
soc_nbrs_nonvac = 0
num_soc_nbrs = 0

Peter Jentsch
committed
for sc_g in soc_network.graph_list[t]
soc_nbrs = neighbors(sc_g.g,i)

Peter Jentsch
committed
num_soc_nbrs += length(soc_nbrs)
for nbr in soc_nbrs
if u_vac[nbr]
soc_nbrs_vac[Int(demographics[nbr])] += 1
else
soc_nbrs_nonvac += 1
end
end
end

Peter Jentsch
committed

Peter Jentsch
committed
vac_payoff += π_base + dot(ρ,soc_nbrs_vac) + total_infections*ω +
ifelse(num_soc_nbrs> 0, κ * ((sum(soc_nbrs_vac) - soc_nbrs_nonvac)/num_soc_nbrs),0)

Peter Jentsch
committed
if app_user[i] && time_of_last_alert[app_user_list[i]]>=0
vac_payoff += γ^(-1*(t - time_of_last_alert[app_user_list[i]]))* (η + dot(ρ_en,soc_nbrs_vac) + total_infections*ω_en)
end

Peter Jentsch
committed

Peter Jentsch
committed
if u_vac[i]

Peter Jentsch
committed
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
if rand(Random.default_rng(Threads.threadid())) < 1 - Φ(vac_payoff,β)
u_next_vac[i] = !u_vac[i]
else
u_next_vac[i] = u_vac[i]
end
else
if rand(Random.default_rng(Threads.threadid())) < Φ(vac_payoff,β)
u_next_vac[i] = !u_vac[i]
else
u_next_vac[i] = u_vac[i]
end
end
end
modelsol.daily_vaccinators = count(==(true),u_vac) #could maybe make this more efficient
end
Base.@propagate_inbounds @views function update_vaccination_opinion_state_2!(t,modelsol,total_infections)
@unpack π_base, η,γ, κ, ω, ρ_y,ρ_m,ρ_o, ω_en,ρ_en,γ,β = modelsol.params
@unpack demographics,time_of_last_alert, nodes, soc_network,u_vac,u_next_vac,app_user,app_user_list = modelsol
app_user_pointer = 0
for i in 1:nodes
vac_payoff = 0
soc_nbrs = @MArray [0,0,0]
num_soc_nbrs = 0
for sc_g in soc_network.graph_list[t]
soc_nbrs = neighbors(sc_g.g,i)
num_soc_nbrs += length(soc_nbrs)
for nbr in soc_nbrs
soc_nbrs[Int(demographics[nbr])] += 1
end
end
ρ = @SVector [ρ_y,ρ_m,ρ_o]
# random_neighbour =
vac_payoff += π_base + dot(ρ,soc_nbrs_vac) + total_infections*ω +
ifelse(num_soc_nbrs> 0, κ * ((sum(soc_nbrs_vac) - soc_nbrs_nonvac)/num_soc_nbrs),0)
if app_user[i] && time_of_last_alert[app_user_list[i]]>=0
vac_payoff += γ^(-1*(t - time_of_last_alert[app_user_list[i]]))* (η + dot(ρ_en,soc_nbrs_vac) + total_infections*ω_en)
end
if u_vac[i]
if rand(Random.default_rng(Threads.threadid())) < 1 - Φ(vac_payoff,β)

Peter Jentsch
committed
u_next_vac[i] = !u_vac[i]

Peter Jentsch
committed
else
u_next_vac[i] = u_vac[i]

Peter Jentsch
committed
end
else

Peter Jentsch
committed
if rand(Random.default_rng(Threads.threadid())) < Φ(vac_payoff,β)

Peter Jentsch
committed
u_next_vac[i] = !u_vac[i]

Peter Jentsch
committed
else
u_next_vac[i] = u_vac[i]

Peter Jentsch
committed
end
end
end
modelsol.daily_vaccinators = count(==(true),u_vac) #could maybe make this more efficient

Peter Jentsch
committed
end
function agents_step!(t,modelsol)

Peter Jentsch
committed
remake!(modelsol.inf_network,modelsol.index_vectors,modelsol.ws_matrix_tuple.daily)
remake!(modelsol.soc_network,modelsol.index_vectors,modelsol.rest_matrix_tuple.daily)

Peter Jentsch
committed
for network in modelsol.inf_network.graph_list[t]
sample_mixing_graph!(network) #get new contact weights

Peter Jentsch
committed
end
if t == modelsol.params.infection_introduction_day

Peter Jentsch
committed
init_indices = rand(Random.default_rng(Threads.threadid()), 1:modelsol.nodes, round(Int,modelsol.nodes*modelsol.params.I_0_fraction))
modelsol.u_inf[init_indices] .= Infected
modelsol.status_totals[Int(Infected)] += length(init_indices)
end
if t>modelsol.params.infection_introduction_day
update_alert_durations!(t,modelsol)
end

Peter Jentsch
committed
update_vaccination_opinion_state!(t,modelsol,modelsol.status_totals[Int(Infected)])

Peter Jentsch
committed
update_infection_state!(t,modelsol)

Peter Jentsch
committed

Peter Jentsch
committed
modelsol.u_vac .= modelsol.u_next_vac
modelsol.u_inf .= modelsol.u_next_inf
end

Peter Jentsch
committed
function solve!(modelsol,recordings...)

Peter Jentsch
committed
for t in 1:modelsol.sim_length

Peter Jentsch
committed
#advance agent states based on the new network

Peter Jentsch
committed
for recording in recordings
record!(t,modelsol,recording)
end