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

fast_SIS broken with initial_infecteds=None, rho=None #97

Closed j-bowhay closed 11 months ago

j-bowhay commented 11 months ago

Docs suggest this should chose a random node but instead

import networkx as nx
import EoN
import matplotlib.pyplot as plt

G = nx.configuration_model([1,5,10]*100)
gamma = 1.
tau = 0.2
t, S, I = EoN.fast_SIS(G, tau, gamma, tmax = 10)

plt.plot(t, I)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[38], line 9
      7 gamma = 1.
      8 tau = 0.2
----> 9 t, S, I = EoN.fast_SIS(G, tau, gamma, tmax = 10)
     11 plt.plot(t, I)

File ~/development/mathmod/venv/lib/python3.11/site-packages/EoN/simulation.py:2711, in fast_SIS(G, tau, gamma, initial_infecteds, rho, tmin, tmax, transmission_weight, recovery_weight, return_full_data, sim_kwargs)
   2709     else:
   2710         initial_number = int(round(G.order()*rho))
-> 2711     initial_infecteds=random.sample(G.nodes(), initial_number)
   2712 elif G.has_node(initial_infecteds):
   2713     initial_infecteds=[initial_infecteds]

File /usr/lib/python3.11/random.py:439, in Random.sample(self, population, k, counts)
    415 # Sampling without replacement entails tracking either potential
    416 # selections (the pool) in a list or previous selections in a set.
    417 
   (...)
    435 # too many calls to _randbelow(), making them slower and
    436 # causing them to eat more entropy than necessary.
    438 if not isinstance(population, _Sequence):
--> 439     raise TypeError("Population must be a sequence.  "
    440                     "For dicts or sets, use sorted(d).")
    441 n = len(population)
    442 if counts is not None:

TypeError: Population must be a sequence.  For dicts or sets, use sorted(d).
joelmiller commented 11 months ago

I have corrected this on the github repository. If you use pip, it will still be broken. You will need to replace simulation.py in your repository with the version currently on github. This error in your post shows where that file is: ~/development/mathmod/venv/lib/python3.11/site-packages/EoN/simulation.py

There's a sequence of tests that I run before I update anything for pip, but I now on a windows machine instead of a mac so it will take time to make sure everything is in place. On top of that, I'm travelling for a conference. It will take time for me to run those. I'll leave this issue open until it's updated on pip.

I'm not quite sure if it's a networkx or python update that broke this, but it looks like it's been broken for a while now. So thank you for the report.

joelmiller commented 11 months ago

Alternatively, for now you can select a random node from G and give it as initial_infecteds:

initial_infecteds = [random.choice(list(G))]
t, S, I = EoN.fast_SIS(G, tau, gamma, tmax = 10, initial_infecteds=initial_infecteds)
j-bowhay commented 11 months ago

Thanks for the quick response!