solve.jl 4.94 KB
Newer Older
1
# using LoopVectorization
2
3
4
function contact_weight(p, contact_time) 
    return 1 - (1-p)^contact_time
end
5
function update_alert_durations!(t,modelsol)  
6
    @unpack notification_parameter = modelsol.params
7
    @unpack time_of_last_alert, app_user_index,inf_network,covid_alert_times,app_user = modelsol
8
9


10
    for (i,node) in enumerate(modelsol.app_user_index), mixing_graph in modelsol.inf_network.graph_list[t]
11
12
13
14
15
        for j in 2:14
            covid_alert_times[i,j-1] = covid_alert_times[i,j] #shift them all back  
        end
        for j in neighbors(mixing_graph.g,node)
            if app_user[j] 
16
                covid_alert_times[i,end] += mixing_graph.weights_dict[(node,j)] #add the contact times for today to the back
17
18
19
20
21
22
23
24
25
            end
        end
        if rand(RNG) < 1 - (1- notification_parameter)^sum(covid_alert_times[i,:])
            time_of_last_alert[i] = t
        end
    end
end
function update_infection_state!(t,modelsol)
    @unpack base_transmission_probability,immunization_loss_prob,recovery_rate = modelsol.params
26
    @unpack u_inf,u_vac,u_next_inf,u_next_vac,demographics,inf_network,status_totals = modelsol
27
28
    
    function agent_transition!(node, from::AgentStatus,to::AgentStatus) 
29
30
        status_totals[Int(from)] -= 1
        status_totals[Int(to)] += 1
31
32
        u_next_inf[node] = to
    end
33

34
    u_next_inf .= u_inf
35
36
37
38
39
40
    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
41
                agent_transition!(i, Susceptible,Immunized)
42
            else
43
                for mixing_graph in inf_network.graph_list[t]
44
                    for j in neighbors(mixing_graph.g,i)    
45
46
47
48
                        if u_inf[j] == Infected && u_next_inf[i] != Infected 
                            if rand(RNG) < contact_weight(base_transmission_probability,mixing_graph.weights_dict[(i,j)])
                                agent_transition!(i, Susceptible,Infected)
                            end
49
50
51
52
53
54
                        end
                    end
                end
            end
        elseif agent_status == Infected
            if rand(RNG) < recovery_rate
55
               agent_transition!(i, Infected,Recovered)
56
57
58
            end
        elseif agent_status == Immunized
            if rand(RNG) < immunization_loss_prob
59
               agent_transition!(i, Immunized,Susceptible)
60
61
62
63
64
65
66
            end
        end
    end
end
function update_vaccination_opinion_state!(t,modelsol,total_infections)
    
    @unpack π_base, η,γ, κ, ω, ρ, ω_en,ρ_en,γ,β = modelsol.params
67
    @unpack demographics,time_of_last_alert, nodes, soc_network,u_vac,u_next_vac,app_user,app_user_list = modelsol
68
    app_user_pointer = 0
69
70


71
72
    for i in 1:nodes
        vac_payoff = 0
73
        soc_nbrs_vac = @MArray [0,0,0]
74
75
        soc_nbrs_nonvac = 0
        num_soc_nbrs = 0
76
77
        for sc_g in soc_network.graph_list[t]
            soc_nbrs = neighbors(sc_g.g,i)
78
79
80
81
82
83
84
85
86
            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
87
88
        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)
89
90
91
92
        
        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
93
        
94
        if u_vac[i]
95
            if rand(RNG) < 1 - Φ(vac_payoff,β)
96
                u_next_vac[i] = !u_vac[i]
97
98
            else
                u_next_vac[i] = u_vac[i]
99
100
            end
        else
101
            if rand(RNG) < Φ(vac_payoff,β)
102
                u_next_vac[i] = !u_vac[i]
103
104
            else
                u_next_vac[i] = u_vac[i]
105
106
107
108
109
110
111
            end
        end
    end
end


function agents_step!(t,modelsol)
112
113

    remake!(modelsol.inf_network,modelsol.index_vectors,modelsol.ws_matrix_tuple.daily)
114
    remake!(modelsol.soc_network,modelsol.index_vectors,modelsol.rest_matrix_tuple.daily)
115
    for network in modelsol.inf_network.graph_list[t]
116
        sample_mixing_graph!(network,modelsol.demographics) #get new contact weights
117
    end
118

119
    update_alert_durations!(t,modelsol)
120
    update_vaccination_opinion_state!(t,modelsol,modelsol.status_totals[Int(Infected)])
121
    update_infection_state!(t,modelsol)
122

123
124
    modelsol.u_vac .= modelsol.u_next_vac
    modelsol.u_inf .= modelsol.u_next_inf
125
    # modelsol.status_totals .= modelsol.status_totals_next
126
127
128
129
end



130
function solve!(modelsol,recording)
131
132
    for t in 1:modelsol.sim_length
        #advance agent states based on the new network
133
        record!(t,modelsol,recording)
134
        agents_step!(t,modelsol) 
135
    end
136
    return recording
137
138
139
140
141
142
143
end


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