Spreading
Spreading: rumours, cascades, contagions on hypergraphs, and the growth of texts.
ExposureInteraction(label, *, target, rate=0.06, exponent=2.0)
Bases: CouplingInteraction
Infection of susceptible participants by the doses of their environments, and recovery, in discrete time.
It is a CouplingInteraction over the hyperedges of a network in the map form. An environment, a hyperedge, gives
each susceptible member the dose rate * rho ** exponent, where rho is the share of the other members that are
infected, and the doses of the environments of a participant add up to D. In every step a susceptible
participant is infected with probability 1 - exp(-D), and an infected one recovers with probability recovery,
a parameter of the participants.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the participants on the network. |
required |
rate
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The dose of an environment whose other members are all infected. |
0.06
|
exponent
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The exponent of the infection kernel, sublinear below 1 and supralinear above. |
2.0
|
Examples:
>>> from skcomplex.models.social.spreading import ExposureInteraction
>>> ExposureInteraction('exposure', target='participants', exponent=1.5).check().exponent
1.5
Source code in src/skcomplex/models/social/spreading/_exposure.py
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | |
GrowingWordElement(label, visual=None, *, count=1.0, innovation=0.1)
Bases: Element
Distinct word of the Simon model, with the number of times it occurs in the text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the agent is drawn, or |
None
|
count
|
Annotated[float, StateSpec(domain=NN)]
|
The number of occurrences. |
1.0
|
innovation
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The probability that the next word of the text is new. |
0.1
|
Examples:
>>> from skcomplex.core.elements import GroupElement
>>> from skcomplex.models.social.spreading import GrowingWordElement
>>> group = GroupElement('words', element=GrowingWordElement, size=1, values={'count': 1.0})
>>> group.label, group.element.__name__, group.size
('words', 'GrowingWordElement', 1)
Source code in src/skcomplex/models/social/spreading/_growing_word.py
40 41 42 43 44 45 46 47 48 49 50 | |
GrowingWordView(agent, stepper)
Bases: AgentView
View of a word of the Simon model, with its states and parameters as attributes.
Source code in src/skcomplex/engine/solvers/_mesa.py
513 514 515 | |
InfectiveElement(label, visual=None, *, infected=0.0, recovery=1.0)
Bases: Element
Node of a contagion, susceptible at 0 and infected at 1, that recovers at a rate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the node or the group. |
required |
visual
|
VisualSpec | None
|
How the node is drawn, or |
None
|
infected
|
Annotated[float, StateSpec(domain=FiniteEnumeratedSet([0, 1]))]
|
The initial state, 0 or 1. |
0.0
|
recovery
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The rate at which an infected node recovers. |
1.0
|
Examples:
>>> from skcomplex.models.social.spreading import InfectiveElement
>>> InfectiveElement('node').recovery
1.0
Source code in src/skcomplex/models/social/spreading/_infective.py
41 42 43 44 45 46 47 48 49 50 51 | |
ListenersElement(label, visual=None, *, n=0)
Bases: Element
Number of people in one state of a rumour: ignorant, spreading, or stifling.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the element. |
required |
visual
|
VisualSpec | None
|
How the agent is drawn, or |
None
|
n
|
Annotated[float, StateSpec(domain=NN)]
|
The initial number of people. |
0
|
Examples:
>>> from skcomplex.models.social.spreading import ListenersElement
>>> ListenersElement('spreaders', n=1).n
1
Source code in src/skcomplex/models/social/spreading/_listeners.py
33 34 35 36 37 38 39 40 41 | |
ParticipantElement(label, visual=None, *, infected=0.0, recovery=0.05)
Bases: Element
Participant in the environments of a contagion, susceptible at 0 and infected at 1.
The infection and the recovery are an ExposureInteraction of the hypergraph, which hypergraph_exposure_sis
adds.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the participant or the group. |
required |
visual
|
VisualSpec | None
|
How the participant is drawn, or |
None
|
infected
|
Annotated[float, StateSpec(domain=FiniteEnumeratedSet([0, 1]))]
|
The initial state, 0 or 1. |
0.0
|
recovery
|
Annotated[float, ParameterSpec(domain=closed(0, 1))]
|
The probability that an infected participant recovers in a step. |
0.05
|
Examples:
>>> from skcomplex.models.social.spreading import ParticipantElement
>>> ParticipantElement('participant').recovery
0.05
Source code in src/skcomplex/models/social/spreading/_participant.py
40 41 42 43 44 45 46 47 48 49 50 | |
RumourContactsInteraction(label, *, ignorants, spreaders, stiflers, spread=1.0, stifle=1.0)
Bases: Interaction
Contacts of the Maki-Thompson rumour model in a well-mixed population of size N.
A spreader who meets an ignorant tells the rumour at rate spread * X * Y / N, and a spreader who meets another
spreader or a stifler stops spreading at rate stifle * Y * (Y - 1 + Z) / N.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
ignorants
|
Annotated[str, RoleSpec()]
|
The path of the ignorants |
required |
spreaders
|
Annotated[str, RoleSpec()]
|
The path of the spreaders |
required |
stiflers
|
Annotated[str, RoleSpec()]
|
The path of the stiflers |
required |
spread
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The contact rate that spreads the rumour. |
1.0
|
stifle
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The contact rate that stifles a spreader. |
1.0
|
Examples:
>>> from skcomplex.models.social.spreading import RumourContactsInteraction
>>> RumourContactsInteraction('contacts', ignorants='X', spreaders='Y', stiflers='Z').spread
1.0
Source code in src/skcomplex/models/social/spreading/_rumour_contacts.py
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | |
SimplicialInfectionInteraction(label, *, target, beta=0.1, beta_triangle=0.1)
Bases: HyperedgeInteraction
Infection of a susceptible node by the other members of a link or a filled triangle, when all are infected.
A susceptible node of a link is infected at rate beta when its neighbour is infected, and a susceptible node of a
triangle at rate beta_triangle when both other members are infected.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction, unique among the parts of its system. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of nodes. |
required |
beta
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The rate of infection through a link. |
0.1
|
beta_triangle
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The rate of infection through a triangle. |
0.1
|
Examples:
>>> from skcomplex.models.social.spreading import SimplicialInfectionInteraction
>>> SimplicialInfectionInteraction('infection', target='nodes', beta_triangle=0.5).beta_triangle
0.5
Source code in src/skcomplex/models/social/spreading/_simplicial_infection.py
46 47 48 49 50 51 52 53 54 55 56 57 | |
ThresholdActivationInteraction(label, *, target)
Bases: MapInteraction
Activation of the Watts cascade model, where a node becomes active once enough of its neighbours are active.
A node becomes active for good once the share of active nodes among its neighbouring nodes reaches its threshold. The nodes update one after the other in a new random order every step, each reading the activations the nodes before it set, so a cascade can cross several nodes in one step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of nodes. |
required |
Examples:
>>> from skcomplex.models.social.spreading import ThresholdActivationInteraction
>>> ThresholdActivationInteraction('activation', target='nodes').check().state
'active'
Source code in src/skcomplex/models/social/spreading/_threshold_activation.py
34 35 36 37 38 39 40 41 42 | |
ThresholdNodeElement(label, visual=VisualSpec('agents', {'color_by': 'active', 'color_range': (0.0, 1.0)}), *, active=0.0, threshold=0.18)
Bases: Element
Node of the Watts cascade model, which the activation turns active once enough of its neighbours are active.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the agent is drawn, or |
VisualSpec('agents', {'color_by': 'active', 'color_range': (0.0, 1.0)})
|
active
|
Annotated[float, StateSpec(domain=FiniteEnumeratedSet([0, 1]))]
|
Whether the node starts active. |
0.0
|
threshold
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The share of active neighbours at which the node becomes active. |
0.18
|
Examples:
>>> from skcomplex.models.social.spreading import ThresholdNodeElement
>>> group = GroupElement('nodes', element=ThresholdNodeElement, size=10, values={'threshold': 0.18})
>>> group.label, group.element.__name__, group.size
('nodes', 'ThresholdNodeElement', 10)
Source code in src/skcomplex/models/social/spreading/_cascades.py
47 48 49 50 51 52 53 54 55 56 57 | |
ThresholdNodeView(agent, stepper)
Bases: AgentView
View of a node of the Watts cascade model, with its states and parameters as attributes.
Source code in src/skcomplex/engine/solvers/_mesa.py
513 514 515 | |
WritingInteraction(label, *, target, words_per_step=100)
Bases: Interaction
Writing of the Simon model, a number of words per step.
Every next word is new with probability innovation, and otherwise repeats a random earlier occurrence, so a word
is repeated with probability proportional to its count.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of words. |
required |
words_per_step
|
int
|
The number of words written per step. |
100
|
Examples:
>>> from skcomplex.models.social.spreading import WritingInteraction
>>> WritingInteraction('writing', target='words').words_per_step
100
Source code in src/skcomplex/models/social/spreading/_writing.py
40 41 42 43 44 45 46 47 48 49 | |
write(model)
Write the words of one step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
ModelView
|
The model. |
required |
Source code in src/skcomplex/models/social/spreading/_writing.py
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | |
hypergraph_exposure_sis(n_nodes=1000, *, sizes=(10, 20, 30), hyperdegree=5.0, rate=0.06, exponent=2.0, recovery=0.05, share=0.3, seed=0)
Return the SIS contagion of St-Onge et al. in the environments of a hypergraph, with a nonlinear kernel.
Participants meet in environments, the hyperedges of a random hypergraph. In every step an environment gives a
susceptible member the dose rate * rho ** exponent from the share rho of its other members that are infected,
the member is infected with probability 1 - exp(-D) of the sum D of its doses, and an infected participant
recovers with probability recovery. Heterogeneous exposure times give the power law rho ** exponent to the
infection kernel. With a sublinear or linear kernel the epidemic sets in continuously, and with a supralinear
kernel, exponent > 1, the healthy state stays stable: an endemic state coexists with it above a critical rate,
so a small seed dies out and a large one persists. In mean field the prevalence I is endemic where k rate
I ** (exponent - 1) (1 - I) = recovery for k environments per participant.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_nodes
|
int
|
The number of participants. |
1000
|
sizes
|
Sequence[int]
|
The sizes of the environments. |
(10, 20, 30)
|
hyperdegree
|
float
|
The mean number of environments of a participant, split evenly over the sizes, whose members are drawn at random. |
5.0
|
rate
|
float
|
The dose of an environment whose other members are all infected. |
0.06
|
exponent
|
float
|
The exponent of the infection kernel. |
2.0
|
recovery
|
float
|
The probability of recovery in a step. |
0.05
|
share
|
float
|
The share of infected participants at the start. |
0.3
|
seed
|
int
|
The seed of the hypergraph and the infected participants. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The model, with the states |
Examples:
>>> from skcomplex.models.social.spreading import hypergraph_exposure_sis
>>> hypergraph_exposure_sis(40).elements[0].check().prepare().size_
40
Source code in src/skcomplex/models/social/spreading/_exposure.py
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 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 | |
maki_thompson(n_people=1000, *, spread=1.0, stifle=1.0)
Return the Maki-Thompson rumour model started by one spreader, which leaves about 20% of people ignorant.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_people
|
int
|
The size of the population. |
1000
|
spread
|
float
|
The contact rate that spreads the rumour. |
1.0
|
stifle
|
float
|
The contact rate that stifles a spreader. |
1.0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The model, with the counts |
Examples:
>>> from skcomplex.models.social.spreading import maki_thompson
>>> [element.n for element in maki_thompson(100).elements]
[99, 1, 0]
Source code in src/skcomplex/models/social/spreading/_rumours.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | |
simon_yule(*, innovation=0.1, words_per_step=100)
Return the Simon model of a text that grows from one word, whose word counts follow a power law.
The rank-frequency exponent is 1 / (1 - innovation), and the number of distinct words grows as innovation
times the length of the text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
innovation
|
float
|
The probability that the next word is new. |
0.1
|
words_per_step
|
int
|
The number of words written per step. |
100
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The model, with the group |
Examples:
>>> from skcomplex.models.social.spreading import simon_yule
>>> simon_yule().elements[0].check().prepare().size_
1
Source code in src/skcomplex/models/social/spreading/_growth.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | |
simplicial_contagion(n_nodes=200, *, infectivity=0.75, triangle_infectivity=3.0, mean_degree=20.0, mean_triangles=6.0, recovery=1.0, share=0.4, seed=0)
Return the simplicial contagion of Iacopini et al., an SIS process on the links and triangles of a complex.
A random simplicial complex joins every pair of nodes with probability p1 and fills every triple with probability
p2, chosen so that a node has mean_degree links and mean_triangles triangles on average. A susceptible node is
infected at rate beta = infectivity * recovery / <k> by every infected neighbour, and at rate beta_triangle =
triangle_infectivity * recovery / <k_triangle> by every triangle whose two other members are infected, and an
infected node recovers at rate recovery. The mean-field prevalence follows rho' = -rho + infectivity rho (1 -
rho) + triangle_infectivity rho^2 (1 - rho) in units of the recovery time. For triangle_infectivity > 1 and
infectivities below the epidemic threshold 1, an endemic state coexists with the healthy one, so the epidemic
dies out from a small seed and persists from a large one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_nodes
|
int
|
The number of nodes. |
200
|
infectivity
|
float
|
The rescaled rate of infection through links. |
0.75
|
triangle_infectivity
|
float
|
The rescaled rate of infection through triangles. |
3.0
|
mean_degree
|
float
|
The mean number of links of a node, which sets |
20.0
|
mean_triangles
|
float
|
The mean number of triangles of a node, which sets |
6.0
|
recovery
|
float
|
The rate of recovery. |
1.0
|
share
|
float
|
The share of infected nodes at the start. |
0.4
|
seed
|
int
|
The seed of the complex and the infected nodes. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The model, with the states |
Examples:
>>> from skcomplex.models.social.spreading import simplicial_contagion
>>> system = simplicial_contagion(30, mean_degree=6.0, mean_triangles=2.0)
>>> system.elements[0].check().prepare().size_
30
Source code in src/skcomplex/models/social/spreading/_simplicial.py
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | |
watts_cascades(graph=None, *, threshold=0.18, seeds=1, random_state=0)
Return the Watts threshold model of global cascades started by a few random seeds.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
graph
|
object
|
The NetworkX graph, or |
None
|
threshold
|
float
|
The share of active neighbours at which a node becomes active. |
0.18
|
seeds
|
int
|
The number of nodes active at the start. |
1
|
random_state
|
int | Generator | None
|
The seed or generator of the default graph and of the seeds. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The model, with the group |
Examples:
>>> import networkx as nx
>>> from skcomplex.models.social.spreading import watts_cascades
>>> watts_cascades(nx.cycle_graph(10), random_state=0).elements[0].check().prepare().size_
10
Source code in src/skcomplex/models/social/spreading/_cascades.py
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | |