springer-math / Mathematics-of-Epidemics-on-Networks

Source code accompanying 'Mathematics of Epidemics on Networks' by Kiss, Miller, and Simon http://www.springer.com/us/book/9783319508047 . Documentation for the software package is at https://epidemicsonnetworks.readthedocs.io/en/latest/
MIT License
151 stars 61 forks source link

Transmissions in full_data code #36

Closed debmalya191 closed 5 years ago

debmalya191 commented 5 years ago

@joelmiller I was browsing through this code in discrete_SIR-

[if rho is not None and initial_infecteds is not None: raise EoN.EoNError("cannot define both initial_infecteds and rho")

if initial_infecteds is None:  #create initial infecteds list if not given
    if rho is None:
        initial_number = 1
    else:
        initial_number = int(round(G.order()*rho))
    initial_infecteds=random.sample(G.nodes(), initial_number)
elif G.has_node(initial_infecteds):
    initial_infecteds=[initial_infecteds]
#else it is assumed to be a list of nodes.

if return_full_data:
    node_history = defaultdict(lambda : ([tmin], ['S']))
    transmissions = []
    for node in initial_infecteds:
        node_history[node] = ([tmin], ['I'])
        transmissions.append((tmin-1, None, node))
    if initial_recovereds is not None:
        for node in initial_recovereds:
            node_history[node] = ([tmin], ['R'])

N=G.order()
t = [tmin]
S = [N-len(initial_infecteds)]
I = [len(initial_infecteds)]
R = [0]

susceptible = defaultdict(lambda: True)  
#above line is equivalent to u.susceptible=True for all nodes.

for u in initial_infecteds:
    susceptible[u] = False
if initial_recovereds is not None:
    for u in initial_recovereds:
        susceptible[u] = False

infecteds = set(initial_infecteds)

while infecteds and t[-1]<tmax:
    new_infecteds = set()
    infector = {}  #used for returning full data.  a waste of time otherwise
    for u in infecteds:
        for v in G.neighbors(u):
            if susceptible[v] and test_transmission(u, v, *args): 
                new_infecteds.add(v)
                susceptible[v] = False
                infector[v] = [u]
            elif return_full_data and v in new_infecteds and test_transmission(u, v, *args):
                infector[v].append(u)

    if return_full_data:
        for v in infector.keys():
            transmissions.append((t[-1], random.choice(infector[v]), v))
        next_time = t[-1]+1
        if next_time <= tmax:
            for u in infecteds:
                node_history[u][0].append(next_time)
                node_history[u][1].append('R')
            for v in new_infecteds:
                node_history[v][0].append(next_time)
                node_history[v][1].append('I')

    infecteds = new_infecteds

    R.append(R[-1]+I[-1])
    I.append(len(infecteds))
    S.append(S[-1]-I[-1])
    t.append(t[-1]+1)
if not return_full_data:
    return scipy.array(t), scipy.array(S), scipy.array(I), \
           scipy.array(R)
else:
    return EoN.Simulation_Investigation(G, node_history, transmissions)](url)

and I was wondering what does this line do- " transmissions.append((t[-1], random.choice(infector[v]), v))" in the full_data part of the code

joelmiller commented 5 years ago

in the discrete time model, a node v might have multiple infected neighbors. Of these neighbors, perhaps more than one would transmit to v in the given time step. Only the first of these is successful. So if we want to assign the infection to a particular source, we will choose at random from all of the potential infectors of v in that time step.

So this line adds a transmission to our collection of transmissions. The transmission occurs at time t[-1], it is credited to a randomly selected infector of v, and it is to v.

debmalya191 commented 5 years ago

thanks a lot!