Opinion dynamics
Opinion dynamics: voting, coevolving networks, persuasion, bounded confidence, conventions, and diffusion.
AdopterElement(label, visual=VisualSpec('agents', {'color_by': 'adopted', 'color_range': (0.0, 1.0)}), *, adopted=0.0, threshold=50.0, reach=15.0)
Bases: Element
Agent of the threshold adoption system, who adopts an innovation for good.
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': 'adopted', 'color_range': (0.0, 1.0)})
|
adopted
|
Annotated[float, StateSpec(domain=FiniteEnumeratedSet([0, 1]))]
|
Whether the agent starts as an adopter. |
0.0
|
threshold
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The percentage of adopters in the agent's social circle above which it adopts in the influence mode. |
50.0
|
reach
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The distance within which other agents form an agent's social circle. |
15.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.social.opinion_dynamics import AdopterElement
>>> group = GroupElement('people', element=AdopterElement, size=10, values={'threshold': 50.0})
>>> group.label, group.element.__name__, group.size
('people', 'AdopterElement', 10)
Source code in src/skcomplex/systems/social/opinion_dynamics/_diffusion.py
127 128 129 130 131 132 133 134 135 136 137 138 139 | |
AdopterView(agent, stepper)
Bases: AgentView
View of an agent of the threshold adoption system, with its states and parameters as attributes.
Source code in src/skcomplex/core/engine/solvers/_mesa.py
559 560 561 | |
AdoptionInteraction(label, *, target, mode='infection')
Bases: TransitionInteraction
Synchronous adoption of the threshold system, where every agent adopts for good from its social circle.
In the infection mode an agent adopts once anyone in its social circle has adopted. In the influence mode it adopts once the percentage of adopters in its circle exceeds its threshold, or in society when its circle is empty. Every agent decides from the adoptions at the start of the step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of adopters. |
required |
mode
|
str
|
|
'infection'
|
Raises:
| Type | Description |
|---|---|
ValidationError
|
The mode is unknown. |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import AdoptionInteraction
>>> AdoptionInteraction('adoption', target='people', mode='influence').mode
'influence'
Source code in src/skcomplex/systems/social/opinion_dynamics/_diffusion.py
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | |
BelieverElement(label, visual=VisualSpec('agents', {'color_by': 'caring', 'color_range': (0.0, 3.0)}), *, belief=0.0, caring=0.0, influence=1.0, learning=1.0)
Bases: Element
Agent of the belief diffusion system, with the weights it gives to four levels of caring about an issue.
The levels are not caring at all, caring less, caring a bit, and caring passionately. An agent cares at the level
of its largest weight. In influentials, a MapInteraction of the vector of weights adds every step learning
times the influence of every neighbour to the weight of the level the neighbour cares at, a tie broken at random,
and a second one sets the level of caring.
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': 'caring', 'color_range': (0.0, 3.0)})
|
belief
|
Annotated[ArrayLike, StateSpec(vector=True)]
|
The initial weights of the four levels. |
0.0
|
caring
|
Annotated[float, StateSpec(domain=NN)]
|
The initial level of caring, the index of the largest weight. |
0.0
|
influence
|
Annotated[float, StateSpec(domain=open(0, oo))]
|
The weight of the agent's own level in the beliefs of its neighbours. |
1.0
|
learning
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The increment per neighbour and step. |
1.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.social.opinion_dynamics import BelieverElement
>>> group = GroupElement('people', element=BelieverElement, size=4, values={'belief': [1.0, 0.0, 0.0, 0.0]})
>>> group.label, group.element.__name__, group.size
('people', 'BelieverElement', 4)
Source code in src/skcomplex/systems/social/opinion_dynamics/_diffusion.py
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | |
BelieverView(agent, stepper)
Bases: AgentView
View of an agent of the influentials system, with its states and parameters as attributes.
Source code in src/skcomplex/core/engine/solvers/_mesa.py
559 560 561 | |
CitizenElement(label, visual=None, *, opinion=0.0)
Bases: Element
Agent of the Galam majority system, who holds a binary opinion.
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
|
opinion
|
Annotated[float, StateSpec(domain=NN)]
|
The initial opinion, 0 or 1. |
0.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.social.opinion_dynamics import CitizenElement
>>> group = GroupElement('citizens', element=CitizenElement, size=10, values={'opinion': 1.0})
>>> group.label, group.element.__name__, group.size
('citizens', 'CitizenElement', 10)
Source code in src/skcomplex/systems/social/opinion_dynamics/_persuasion.py
99 100 101 102 103 104 105 106 107 | |
CitizenView(agent, stepper)
Bases: AgentView
View of an agent of the Galam majority system, with its states and parameters as attributes.
Source code in src/skcomplex/core/engine/solvers/_mesa.py
559 560 561 | |
ClubMemberElement(label, visual=OPINION_VISUAL, *, opinion=0.0, degree=0.0, beta=1.0, appeal=0.0, deciding=0.1, activity=0.5, rewiring=0.5)
Bases: Element
Agent that is in a club (spin 1) or out of it (spin 0), aligned by a heat bath with the agents it knows.
Every step an agent reconsiders with probability deciding and then joins with probability
1 / (1 + exp(-2 β h)), where the field h counts the acquaintances in the club minus those out of it, plus the
appeal of the club. The interaction SeparationInteraction dissolves acquaintances between a member and an outsider
and reforms them towards an agent of the same side.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the agent is drawn, or |
OPINION_VISUAL
|
opinion
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
1 for a member of the club and 0 for an outsider. |
0.0
|
degree
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The number of acquaintances, read at the start of every step. |
0.0
|
beta
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The inverse temperature of the heat bath. |
1.0
|
appeal
|
Annotated[float, ParameterSpec()]
|
The field of the club on every agent, positive for an attractive club. |
0.0
|
deciding
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The probability that an agent reconsiders its choice in a step. |
0.1
|
activity
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The probability that an acquaintance is reconsidered in a step. |
0.5
|
rewiring
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The probability that a reconsidered acquaintance across the club boundary dissolves and reforms. |
0.5
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import ClubMemberElement
>>> ClubMemberElement('agents', beta=2.0).beta
2.0
Source code in src/skcomplex/systems/social/opinion_dynamics/_coevolution.py
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | |
CoevolvingVoterElement(label, visual=OPINION_VISUAL, *, opinion=0.0, degree=0.0, activity=0.5, rewiring=0.3)
Bases: Element
Voter of a coevolving network, with a binary opinion, its degree, and its number of discordant neighbours.
Every step a voter is active with probability activity and picks a random neighbour. When the neighbour
disagrees, the voter copies its opinion with probability 1 - rewiring, and otherwise the interaction
SeparationInteraction moves the edge to a random voter who agrees with it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the voter or the group. |
required |
visual
|
VisualSpec | None
|
How the agent is drawn, or |
OPINION_VISUAL
|
opinion
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The opinion, 0 or 1. |
0.0
|
degree
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The number of neighbours, read at the start of every step. |
0.0
|
activity
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The probability that a voter acts in a step. |
0.5
|
rewiring
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The probability that an active voter with a discordant neighbour rewires instead of copying. |
0.3
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import CoevolvingVoterElement
>>> CoevolvingVoterElement('voters', rewiring=0.3).rewiring
0.3
Source code in src/skcomplex/systems/social/opinion_dynamics/_coevolution.py
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | |
ComplexAgentElement(label, visual=None, *, configuration=2.0, spin=0.0)
Bases: Element
Agent with many internal configurations, of which two show a characteristic with the spin 1 or -1.
Configuration 0 has the spin S = 1, configuration 1 the spin S = -1, and the configurations from 2 to H + 1
the spin 0. In standardized_agents, a MapInteraction sets the spin after every change of configuration.
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
|
configuration
|
Annotated[float, StateSpec(domain=NN)]
|
The internal configuration, from 0 to |
2.0
|
spin
|
Annotated[float, StateSpec(domain=ZZ)]
|
The spin of the configuration. |
0.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.social.opinion_dynamics import ComplexAgentElement
>>> GroupElement(
... 'agents', element=ComplexAgentElement, size=10, values={'configuration': 5.0, 'spin': 0.0}
... ).size
10
Source code in src/skcomplex/systems/social/opinion_dynamics/_standardization.py
58 59 60 61 62 63 64 65 66 67 68 | |
ComplexAgentView(agent, stepper)
Bases: AgentView
View of an agent of the standardization system, with its states and parameters as attributes.
Source code in src/skcomplex/core/engine/solvers/_mesa.py
559 560 561 | |
ConfidenceCouplingInteraction(label, *, target, state='opinion')
Bases: CouplingInteraction
Hegselmann-Krause coupling, the move of every agent to the mean opinion of the neighbours within its confidence.
Every step every agent takes at once the mean opinion of its neighbours, itself included, whose opinions differ
from its own by less than its parameter confidence. It is the map form of coupling with the normalized mean over
the neighbours of the network weighted by the indicator of the confidence.
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 agents, on the nodes of a network. |
required |
state
|
str
|
The name of the state that holds the opinions. |
'opinion'
|
Examples:
>>> import networkx as nx
>>> import numpy as np
>>> from skcomplex.core.components.elements import LatticeElement
>>> from skcomplex.core.components.spaces import DiscreteTime, NetworkSpace
>>> from skcomplex.core.components.system import System
>>> from skcomplex.core.engine.runtime import Simulation
>>> from skcomplex.systems.social.opinion_dynamics import ConfidenceCouplingInteraction, ConfidentElement
>>> people = LatticeElement(
... 'people',
... element=ConfidentElement,
... space=NetworkSpace(nx.complete_graph(3)),
... values={'opinion': [0.1, 0.2, 0.9], 'confidence': 0.2},
... )
>>> coupling = ConfidenceCouplingInteraction('compromise', target='people')
>>> system = System(elements=[people], interactions=[coupling], time=DiscreteTime())
>>> opinions = Simulation(system).prepare().run(until=1).trajectory_.values('people.opinion')
>>> np.round(opinions[-1], 6).tolist()
[0.15, 0.15, 0.9]
Source code in src/skcomplex/systems/social/opinion_dynamics/_bounded_confidence.py
157 158 159 160 161 162 163 164 165 166 167 168 169 | |
ConfidentElement(label, visual=VisualSpec('histograms', {'color_range': (0.0, 1.0), 'histogram_first': True}), *, opinion=0.5, confidence=0.2)
Bases: Element
Agent of the Hegselmann-Krause system, with an opinion and the confidence within which it trusts neighbours.
ConfidenceCouplingInteraction moves every agent each step to the mean opinion of the neighbours, itself
included, whose opinions differ from its own by less than confidence.
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('histograms', {'color_range': (0.0, 1.0), 'histogram_first': True})
|
opinion
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The opinion, between 0 and 1. |
0.5
|
confidence
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The largest opinion difference of a neighbour an agent still listens to. |
0.2
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import ConfidentElement
>>> ConfidentElement('people', confidence=0.1).confidence
0.1
Source code in src/skcomplex/systems/social/opinion_dynamics/_bounded_confidence.py
51 52 53 54 55 56 57 58 59 60 61 | |
ConnectionElement(label, visual=None, *, A=0.0)
Bases: Element
Edge of a network with a connection A, the phase an agent transports along it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the edge or the group on the edges. |
required |
visual
|
VisualSpec | None
|
How the edge is drawn, or |
None
|
A
|
Annotated[float, ParameterSpec()]
|
The connection along the direction of the edge. |
0.0
|
Attributes:
| Name | Type | Description |
|---|---|---|
default_visual_ |
The visual of the edge when it sets none. |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import ConnectionElement
>>> ConnectionElement('edge', A=0.5).A
0.5
Source code in src/skcomplex/systems/social/opinion_dynamics/_gauge_agents.py
127 128 129 130 131 132 133 134 135 | |
ConversationsInteraction(label, *, target, phase=None)
Bases: GroupingInteraction
Conversations of the cognitive consistency system, one per agent and step, the agents speaking in random order.
A speaker talks to a random neighbour about F1 or F2. The hearer averages its valence of the topic with the speaker's and settles its belief network, and its attitude is its valence of X.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of thinkers. |
required |
phase
|
str | None
|
The phase of the step the conversations run in, or |
None
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import ConversationsInteraction
>>> ConversationsInteraction('talks', target='thinkers').groups
'neighborhood'
Source code in src/skcomplex/systems/social/opinion_dynamics/_cognition.py
152 153 154 155 156 157 158 159 | |
act_on(members, system)
Let the first member speak to a random neighbour, who averages the topic and settles its beliefs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
members
|
list[AgentViewProtocol]
|
The speaker, followed by its neighbours. |
required |
system
|
SystemViewProtocol
|
The system view of the rule. |
required |
Source code in src/skcomplex/systems/social/opinion_dynamics/_cognition.py
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | |
CulturalInfluenceInteraction(label, *, target, phase=None)
Bases: GroupingInteraction
Cultural influence of Axelrod's system, where every village in turn may copy a trait of a random neighbour.
Every step every village, in random order, picks a random neighbour and, with probability equal to the fraction of features they share, copies the trait of one feature on which they differ.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of villages. |
required |
phase
|
str | None
|
The phase of the step the influence runs in, or |
None
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import CulturalInfluenceInteraction
>>> CulturalInfluenceInteraction('influence', target='villages').groups
'neighborhood'
Source code in src/skcomplex/systems/social/opinion_dynamics/_axelrod.py
129 130 131 132 133 134 135 136 | |
act_on(members, system)
Copy one differing trait of a random neighbour with probability equal to the cultural overlap.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
members
|
list[AgentViewProtocol]
|
The village, followed by its neighbours. |
required |
system
|
SystemViewProtocol
|
The system view of the rule. |
required |
Source code in src/skcomplex/systems/social/opinion_dynamics/_axelrod.py
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | |
DiscussantElement(label, visual=VisualSpec('agents', {'color_by': 'opinion', 'color_range': (0.0, 1.0)}), *, opinion=0.5, confidence=0.2, convergence=0.5)
Bases: Element
Agent of the Deffuant system, with a continuous opinion and a confidence bound.
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': 'opinion', 'color_range': (0.0, 1.0)})
|
opinion
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The initial opinion, between 0 and 1. |
0.5
|
confidence
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The largest opinion difference at which two agents still compromise. |
0.2
|
convergence
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The fraction of the opinion difference by which each agent of a compromising pair moves. |
0.5
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.social.opinion_dynamics import DiscussantElement
>>> group = GroupElement('people', element=DiscussantElement, size=10, values={'opinion': 0.5})
>>> group.label, group.element.__name__, group.size
('people', 'DiscussantElement', 10)
Source code in src/skcomplex/systems/social/opinion_dynamics/_bounded_confidence.py
99 100 101 102 103 104 105 106 107 108 109 110 111 | |
DiscussantView(agent, stepper)
Bases: AgentView
View of an agent of the Deffuant bounded confidence system, with its states and parameters as attributes.
Source code in src/skcomplex/core/engine/solvers/_mesa.py
559 560 561 | |
DiscussionsInteraction(label, *, target, size=3)
Bases: GroupingInteraction
Discussions of the Galam system, which split the citizens into random groups that adopt their majority opinion.
It is a symbolic GroupingInteraction of random partitions, drawn again at every step. A tie in a group of even
size goes to opinion 0, the status quo.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of citizens. |
required |
size
|
int
|
The number of citizens in each discussion group, the last group holding the remainder. |
3
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import DiscussionsInteraction
>>> DiscussionsInteraction('talks', target='citizens', size=4).write
'opinion'
Source code in src/skcomplex/systems/social/opinion_dynamics/_persuasion.py
204 205 206 207 208 209 210 211 212 213 | |
EncountersInteraction(label, *, target, phase=None)
Bases: RandomPairsInteraction
Random binary encounters of the Deffuant system, as many per step as there are agents.
In every encounter two random agents whose opinions differ by less than the confidence bound move towards each other by the convergence fraction of their difference.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of discussants. |
required |
phase
|
str | None
|
The phase of the step the encounters run in, or |
None
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import EncountersInteraction
>>> EncountersInteraction('meetings', target='people').target
'people'
Source code in src/skcomplex/systems/social/opinion_dynamics/_random_pairs.py
38 39 40 41 42 43 44 45 | |
act_on(members, system)
Move the opinions of a pair towards each other when they differ by less than the confidence bound.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
members
|
list[AgentViewProtocol]
|
The two discussants of the encounter. |
required |
system
|
SystemViewProtocol
|
The system view of the rule. |
required |
Source code in src/skcomplex/systems/social/opinion_dynamics/_bounded_confidence.py
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | |
InfluenceeElement(label, visual=VisualSpec('agents', {'color_by': 'opinion', 'color_range': (-1.0, 1.0)}), *, opinion=1.0, persuasiveness=1.0, supportiveness=1.0, exponent=2.0, noise=0.0)
Bases: Element
Agent of the social impact system, with an opinion of -1 or 1, a persuasiveness, and a supportiveness.
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': 'opinion', 'color_range': (-1.0, 1.0)})
|
opinion
|
Annotated[float, StateSpec(domain=ZZ)]
|
The initial opinion, -1 or 1. |
1.0
|
persuasiveness
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The strength with which the agent persuades agents of the other opinion. |
1.0
|
supportiveness
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The strength with which the agent supports agents of its opinion. |
1.0
|
exponent
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The exponent of the distance by which impact decays. |
2.0
|
noise
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The half-width of the uniform random field added to the impact on every agent and step. |
0.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.social.opinion_dynamics import InfluenceeElement
>>> group = GroupElement('people', element=InfluenceeElement, size=4, values={'opinion': -1.0})
>>> group.label, group.element.__name__, group.size
('people', 'InfluenceeElement', 4)
Source code in src/skcomplex/systems/social/opinion_dynamics/_persuasion.py
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | |
InfluenceeView(agent, stepper)
Bases: AgentView
View of an agent of the social impact system, with its states and parameters as attributes.
Source code in src/skcomplex/core/engine/solvers/_mesa.py
559 560 561 | |
MajorityVoterElement(label, visual=None, *, opinion=0)
Bases: Element
Cell that takes the majority opinion of its Moore neighbourhood, itself included.
The majority rule is a LocalRuleInteraction of the lattice, which majority_rule adds.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the cell or the lattice group. |
required |
visual
|
VisualSpec | None
|
How the agent is drawn, or |
None
|
opinion
|
Annotated[float, StateSpec(domain=FiniteEnumeratedSet([0, 1]))]
|
The initial opinion, 0 or 1. |
0
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import MajorityVoterElement
>>> MajorityVoterElement('cell', opinion=1).opinion
1
Source code in src/skcomplex/systems/social/opinion_dynamics/_voters.py
47 48 49 50 51 52 53 54 55 | |
NamerElement(label, visual=None, *, words=0.0)
Bases: Element
Agent of the naming game, with an inventory of the words it knows for one object.
The inventory is an indicator vector over the lexicon, with one slot per agent for the word that agent invents when it first speaks with an empty inventory.
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
|
words
|
Annotated[ArrayLike, StateSpec(vector=True)]
|
The initial inventory, 1 for every known word and 0 otherwise. |
0.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> import numpy as np
>>> from skcomplex.systems.social.opinion_dynamics import NamerElement
>>> group = GroupElement('namers', element=NamerElement, size=5, values={'words': np.zeros((5, 5))})
>>> group.label, group.element.__name__, group.size
('namers', 'NamerElement', 5)
Source code in src/skcomplex/systems/social/opinion_dynamics/_conventions.py
52 53 54 55 56 57 58 59 60 | |
NamerView(agent, stepper)
Bases: AgentView
View of an agent of the naming game, with its states and parameters as attributes.
Source code in src/skcomplex/core/engine/solvers/_mesa.py
559 560 561 | |
NamingGamesInteraction(label, *, target, phase=None)
Bases: RandomPairsInteraction
Pairwise games of the minimal naming game, as many per step as there are agents.
A random speaker says a random word of its inventory to a random hearer. When the hearer knows it, both keep that word alone, and otherwise the hearer adds it. A speaker with an empty inventory first invents a word that no agent knows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of namers. |
required |
phase
|
str | None
|
The phase of the step the games run in, or |
None
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import NamingGamesInteraction
>>> NamingGamesInteraction('games', target='namers').target
'namers'
Source code in src/skcomplex/systems/social/opinion_dynamics/_random_pairs.py
38 39 40 41 42 43 44 45 | |
act_on(members, system)
Play one naming game between the first member, the speaker, and the second, the hearer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
members
|
list[AgentViewProtocol]
|
The speaker and the hearer. |
required |
system
|
SystemViewProtocol
|
The system view of the rule. |
required |
Source code in src/skcomplex/systems/social/opinion_dynamics/_conventions.py
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | |
OpinionElement(label, visual=None, *, x=0.0)
Bases: Element
Node of a consensus process with a continuous opinion.
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
|
x
|
Annotated[float, StateSpec()]
|
The initial opinion. |
0.0
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import OpinionElement
>>> OpinionElement('node', x=0.5).x
0.5
Source code in src/skcomplex/systems/social/opinion_dynamics/_hypergraph_consensus.py
45 46 47 48 49 50 51 52 53 | |
OpinionEncountersInteraction(label, *, candidate, field, levels=7, confidence=2, eta=1.0, persuasion=0.3, repulsion=0.1)
Bases: EncounterInteraction
Conservative encounters between opinion levels, which persuade close opinions and repel distant ones.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
candidate
|
Annotated[str, RoleSpec()]
|
The path of the distribution over opinion levels whose members move. |
required |
field
|
Annotated[str, RoleSpec()]
|
The path of the distribution over opinion levels they meet, usually the same distribution. |
required |
levels
|
Annotated[int, ParameterSpec(domain=open(0, oo))]
|
The number of opinion levels. |
7
|
confidence
|
Annotated[int, ParameterSpec(domain=closed_open(0, oo))]
|
The largest distance in levels at which encounters persuade. |
2
|
eta
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The encounter rate. |
1.0
|
persuasion
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The probability of moving toward a close opinion. |
0.3
|
repulsion
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The probability of moving away from a distant opinion. |
0.1
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import OpinionEncountersInteraction
>>> OpinionEncountersInteraction('encounters', candidate='opinions', field='opinions').confidence
2
Source code in src/skcomplex/systems/social/opinion_dynamics/_kinetic_opinion.py
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | |
PersuaderElement(label, visual=VisualSpec('agents', {'color_by': 'opinion', 'color_range': (0.0, 1.0)}), *, opinion=0.0)
Bases: Element
Agent of the Sznajd system, who convinces the neighbours of an agreeing pair.
A step of an agent picks a random neighbour, and when both share an opinion every neighbour of either adopts it. On a ring this is the original one-dimensional rule, where the pair convinces the two agents beside it.
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': 'opinion', 'color_range': (0.0, 1.0)})
|
opinion
|
Annotated[float, StateSpec(domain=NN)]
|
The initial opinion, 0 or 1. |
0.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.social.opinion_dynamics import PersuaderElement
>>> group = GroupElement('people', element=PersuaderElement, size=10, values={'opinion': 1.0})
>>> group.label, group.element.__name__, group.size
('people', 'PersuaderElement', 10)
Source code in src/skcomplex/systems/social/opinion_dynamics/_persuasion.py
56 57 58 59 60 61 62 63 64 | |
PersuaderView(agent, stepper)
Bases: AgentView
View of an agent of the Sznajd system, with its states and parameters as attributes.
Source code in src/skcomplex/core/engine/solvers/_mesa.py
559 560 561 | |
PersuasionInteraction(label, *, target, phase=None)
Bases: GroupingInteraction
Persuasion of the Sznajd system, where an agreeing pair of neighbours convinces the neighbours of both.
Every step every agent, in random order, picks a random neighbour, and when both share an opinion every neighbour of either adopts it. On a ring this is the original one-dimensional rule, where the pair convinces the two agents beside it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of persuaders. |
required |
phase
|
str | None
|
The phase of the step the persuasion runs in, or |
None
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import PersuasionInteraction
>>> PersuasionInteraction('persuasion', target='people').groups
'neighborhood'
Source code in src/skcomplex/systems/social/opinion_dynamics/_persuasion.py
295 296 297 298 299 300 301 302 | |
act_on(members, system)
Convince the neighbours of the first member and a random neighbour of it when the two agree.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
members
|
list[AgentViewProtocol]
|
The persuader, followed by its neighbours. |
required |
system
|
SystemViewProtocol
|
The system view of the rule. |
required |
Source code in src/skcomplex/systems/social/opinion_dynamics/_persuasion.py
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 | |
PhaseAgentElement(label, visual=None, *, theta=0.0)
Bases: Element
Agent with a phase theta.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or the group on the nodes. |
required |
visual
|
VisualSpec | None
|
How the agent is drawn, or |
None
|
theta
|
Annotated[float, StateSpec(period=2 * pi)]
|
The initial phase. |
0.0
|
Attributes:
| Name | Type | Description |
|---|---|---|
default_visual_ |
The visual of the agent when it sets none. |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import PhaseAgentElement
>>> PhaseAgentElement('agent', theta=0.5).theta
0.5
Source code in src/skcomplex/systems/social/opinion_dynamics/_gauge_agents.py
93 94 95 96 97 98 99 100 101 | |
RadicalElement(label, visual=VisualSpec('agents', {'color_by': 'opinion', 'color_range': (-3.0, 3.0)}), *, opinion=0.0, activity=0.1)
Bases: Element
Agent with an unbounded opinion, whose sign is its stance and whose size is its conviction, and an activity.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or the group. |
required |
visual
|
VisualSpec | None
|
How the agent is drawn, or |
VisualSpec('agents', {'color_by': 'opinion', 'color_range': (-3.0, 3.0)})
|
opinion
|
Annotated[float, StateSpec()]
|
The opinion |
0.0
|
activity
|
Annotated[float, StateSpec(domain=closed(0, 1))]
|
The probability |
0.1
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import RadicalElement
>>> RadicalElement('agent', activity=0.1).activity
0.1
Source code in src/skcomplex/systems/social/opinion_dynamics/_echo_chambers.py
55 56 57 58 59 60 61 62 63 64 65 | |
RadicalView(agent, stepper)
Bases: AgentView
View of an agent of the echo chamber system, with its states as attributes.
Source code in src/skcomplex/core/engine/solvers/_mesa.py
559 560 561 | |
RadicalizationInteraction(label, *, target, strength=3.0, controversy=3.0, homophily=3.0, contacts=10, reciprocity=0.5, dt=0.01, substeps=10)
Bases: Interaction
Opinion dynamics of Baumann and coauthors, dx_i/dt = -x_i + K sum_j A_ij(t) tanh(alpha x_j).
Every step of the system integrates the opinions with substeps Euler steps of length dt, and draws a new
temporal network for every one of them. In a draw, every agent is active with the probability of its activity and
contacts contacts distinct others, each chosen with the probability |x_i - x_j|^-beta normalized over the
others. A contacted agent receives the influence of the agent that contacts it, which receives the influence back
when the contact is reciprocated, with the probability reciprocity.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of agents. |
required |
strength
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The social interaction strength |
3.0
|
controversy
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The controversialness |
3.0
|
homophily
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The exponent |
3.0
|
contacts
|
Annotated[int, ParameterSpec(domain=NN)]
|
The number |
10
|
reciprocity
|
Annotated[float, ParameterSpec(domain=closed(0, 1))]
|
The probability |
0.5
|
dt
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The length of an Euler step. |
0.01
|
substeps
|
Annotated[int, ParameterSpec(domain=NN)]
|
The number of Euler steps per step of the system. |
10
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import RadicalizationInteraction
>>> RadicalizationInteraction('influence', target='agents').contacts
10
Source code in src/skcomplex/systems/social/opinion_dynamics/_echo_chambers.py
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | |
influence(system)
Integrate the opinions over the Euler steps of one step of the system.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system
|
SystemView
|
The system. |
required |
Source code in src/skcomplex/systems/social/opinion_dynamics/_echo_chambers.py
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | |
RandomPairsInteraction(label, *, target, phase=None)
Bases: GroupingInteraction
Grouping that draws as many random ordered pairs of distinct agents per step as there are agents.
The pairs are drawn independently, so an agent can meet several partners in one step, and every pair acts in random
order through act_on, which a subclass overrides. One unit of time holds one encounter per agent, as in the
random sequential encounters of mean-field opinion and convention systems.
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 whose agents meet in pairs. |
required |
phase
|
str | None
|
The phase of the step the encounters run in, or |
None
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import RandomPairsInteraction
>>> RandomPairsInteraction('meetings', target='people').groups
'pairs'
Source code in src/skcomplex/systems/social/opinion_dynamics/_random_pairs.py
38 39 40 41 42 43 44 45 | |
ScheduleElement(label, visual=None, *, phase=0.0)
Bases: Element
Triangle of a temporal hypergraph, active in every other half of a period from its own phase.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the triangle or the group. |
required |
visual
|
VisualSpec | None
|
How the triangle is drawn, or |
None
|
phase
|
Annotated[float, ParameterSpec()]
|
The phase of the schedule, in radians. |
0.0
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import ScheduleElement
>>> ScheduleElement('triangle', phase=1.0).phase
1.0
Source code in src/skcomplex/systems/social/opinion_dynamics/_hypergraph_consensus.py
75 76 77 78 79 80 81 82 83 | |
SeparationInteraction(label, *, voters, keep='source', opinion=1.0)
Bases: TopologyInteraction
Rewiring of discordant edges by one end, which keeps the edge and moves its other end to a like-minded node.
It is a TopologyInteraction that rewires the edges of the voters. The end keep acts on an edge with
probability activity / degree per step, and when it holds the opinion opinion and the other end does not, it
rewires the edge with probability rewiring, drawing a new end among the voters of the opinion opinion.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
voters
|
Annotated[str, RoleSpec()]
|
The path of the voters on the nodes. |
required |
keep
|
str
|
The end of an edge that acts and keeps the edge, |
'source'
|
opinion
|
float
|
The opinion of the end that acts, 0 or 1. |
1.0
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import SeparationInteraction
>>> SeparationInteraction('separation', voters='voters', keep='target', opinion=0).action
'rewire'
Source code in src/skcomplex/systems/social/opinion_dynamics/_coevolution.py
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | |
SocialImpactInteraction(label, *, target)
Bases: MapInteraction
Synchronous update of the social impact system, where every agent takes the opinion of the stronger impact.
The impact on agent i is I_i = sum_j t_j (1 - o_i o_j) / d_ij^a - sum_j s_j (1 + o_i o_j) / d_ij^a, with the
persuasiveness t, the supportiveness s, and the distance d on the grid, where an agent supports itself from
distance 1. The impact is the net pressure to change, whatever the opinion, so an agent flips its opinion when
I_i + h_i > 0, with a uniform random field h_i. Every agent decides from the opinions at the start of the step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of agents. |
required |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import SocialImpactInteraction
>>> SocialImpactInteraction('impact', target='people').form
'agent'
Source code in src/skcomplex/systems/social/opinion_dynamics/_persuasion.py
241 242 243 244 245 246 247 | |
StandardizationInteraction(label, *, target, K=10.0, J=1.0, H=50, intensity=2.0, activity=1.0, phase=None)
Bases: ChoiceInteraction
Changes of configuration of random agents, accepted with the logistic probability of their gain in utility.
The utility of agent i is u_i = K / N sum_j |S_i| |S_j| + J / N sum_j S_i S_j over the other agents. An agent
proposes a configuration drawn uniformly from the H + 2 configurations, its own included, and takes it with the
probability 1 / (1 + exp(-beta (u_i' - u_i))) of the rule 'fermi', so the agents sample P ~ exp(beta E). The
utilities read the counts of the configurations of the group, so every proposal sees the changes accepted before
it. In standardized_agents, a phase of visits draws N agents with replacement every unit of time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of agents. |
required |
K
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The coupling of the characteristics |
10.0
|
J
|
Annotated[float, ParameterSpec()]
|
The coupling of the spins |
1.0
|
H
|
int
|
The number of configurations without the characteristic. |
50
|
intensity
|
float
|
The intensity of choice |
2.0
|
activity
|
float
|
The probability that a visited agent proposes a configuration. |
1.0
|
phase
|
str | None
|
The phase of the step the choice runs in, or |
None
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import StandardizationInteraction
>>> StandardizationInteraction('standardization', target='agents', H=100).options[-1]
101.0
Source code in src/skcomplex/systems/social/opinion_dynamics/_standardization.py
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 | |
ThinkerElement(label, visual=VisualSpec('agents', {'color_by': 'attitude', 'color_range': (-1.0, 1.0)}), *, valences=0.0, attitude=0.0, decay=0.05)
Bases: Element
Agent of the cognitive consistency system, with the valences of the concepts of its belief network.
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': 'attitude', 'color_range': (-1.0, 1.0)})
|
valences
|
Annotated[ArrayLike, StateSpec(vector=True)]
|
The initial valences of the concepts F1, X, and F2, between -1 and 1. |
0.0
|
attitude
|
Annotated[float, StateSpec()]
|
The attitude of the agent, the valence of the concept X once the belief network settles. |
0.0
|
decay
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The fraction of every valence lost per update of the belief network. |
0.05
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.social.opinion_dynamics import ThinkerElement
>>> group = GroupElement('thinkers', element=ThinkerElement, size=5, values={'valences': [1.0, 1.0, -1.0]})
>>> group.label, group.element.__name__, group.size
('thinkers', 'ThinkerElement', 5)
Source code in src/skcomplex/systems/social/opinion_dynamics/_cognition.py
60 61 62 63 64 65 66 67 68 69 70 71 72 | |
ThinkerView(agent, stepper)
Bases: AgentView
View of an agent of the cognitive consistency system, with its states and parameters as attributes.
Source code in src/skcomplex/core/engine/solvers/_mesa.py
559 560 561 | |
ThreeBodyConsensusInteraction(label, *, target, triangles, reinforcement=0.0, period=1.0)
Bases: HyperedgeInteraction
Nonlinear three-body consensus of Neuhäuser, Mellor, and Lambiotte, on the triangles active at the time.
The focal node i of an active triangle ijk moves towards the two others at the rate s(|x_j - x_k|) (x_j + x_k -
2 x_i), with s(d) = exp(reinforcement * d), so a pair that agrees pulls harder for a negative reinforcement. A
triangle is active when sin(2 pi t / period + phase) > 0, with the phase of the triangle member of the group on
hyperedges.
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 |
triangles
|
Annotated[str, RoleSpec()]
|
The path of the group of the schedules of the triangles. |
required |
reinforcement
|
Annotated[float, ParameterSpec()]
|
The exponent of the modulating function |
0.0
|
period
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The period of the schedules. |
1.0
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import ThreeBodyConsensusInteraction
>>> ThreeBodyConsensusInteraction('consensus', target='nodes', triangles='triangles').size
3
Source code in src/skcomplex/systems/social/opinion_dynamics/_hypergraph_consensus.py
119 120 121 122 123 124 125 126 127 128 129 130 131 132 | |
TransportedCouplingInteraction(label, *, target, links, K=1.0)
Bases: CouplingInteraction
Relaxation of agent phases towards the phases of their neighbours, theta_i' += K sin(theta_j - theta_i - A_ij).
The connection A_ij lives on the edge of the network from i to j, and A_ji = -A_ij.
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 agents on the nodes. |
required |
links
|
Annotated[str, RoleSpec()]
|
The path of the group on the edges, whose parameter |
required |
K
|
Annotated[float, ParameterSpec()]
|
The coupling strength. |
1.0
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import TransportedCouplingInteraction
>>> TransportedCouplingInteraction('coupling', target='agents', links='links', K=0.5).K
0.5
Source code in src/skcomplex/systems/social/opinion_dynamics/_gauge_agents.py
51 52 53 54 55 56 57 58 59 60 61 | |
UndecidedElement(label, visual=VisualSpec('agents', {'color_by': 'opinion', 'color_range': (-1.0, 1.0)}), *, opinion=0.0, sensitivity=2.0)
Bases: Element
Voter who is against, undecided, or for, at -1, 0, or 1, and redraws its opinion from its neighbours.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the voter or the group. |
required |
visual
|
VisualSpec | None
|
How the agent is drawn, or |
VisualSpec('agents', {'color_by': 'opinion', 'color_range': (-1.0, 1.0)})
|
opinion
|
Annotated[float, StateSpec(domain=FiniteEnumeratedSet([-1, 0, 1]))]
|
The opinion, -1, 0, or 1. |
0.0
|
sensitivity
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The sensitivity |
2.0
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import UndecidedElement
>>> UndecidedElement('voter').sensitivity
2.0
Source code in src/skcomplex/systems/social/opinion_dynamics/_undecided.py
54 55 56 57 58 59 60 61 62 63 64 | |
UndecidedFlowsElement(label, visual=None, *, against=0.0, undecided=100.0, support=0.0, omega=1.0, gamma=0.05, eta=0.02, drive=1.0)
Bases: Element
Population split into the numbers A against, B for, and C undecided.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the element. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
against
|
Annotated[object, StateSpec(domain=closed_open(0, oo), quantity=agents)]
|
The number |
0.0
|
undecided
|
Annotated[object, StateSpec(domain=closed_open(0, oo), quantity=agents)]
|
The number |
100.0
|
support
|
Annotated[object, StateSpec(domain=closed_open(0, oo), quantity=agents)]
|
The number |
0.0
|
omega
|
Annotated[object, ParameterSpec(domain=closed_open(0, oo))]
|
The rate |
1.0
|
gamma
|
Annotated[object, ParameterSpec(domain=closed_open(0, oo))]
|
The rate |
0.05
|
eta
|
Annotated[object, ParameterSpec(domain=closed_open(0, oo))]
|
The rate |
0.02
|
drive
|
Annotated[object, ParameterSpec(domain=FiniteEnumeratedSet([0, 1]))]
|
The exponent of |
1.0
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import UndecidedFlowsElement
>>> UndecidedFlowsElement('population').omega
1.0
Source code in src/skcomplex/systems/social/opinion_dynamics/_undecided.py
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | |
UndecidedView(agent, stepper)
Bases: AgentView
View of a voter of the three-state opinion system, with its states and parameters as attributes.
Source code in src/skcomplex/core/engine/solvers/_mesa.py
559 560 561 | |
VariantVoterElement(label, visual=VisualSpec('agents', {'color_by': 'opinion', 'color_range': (0.0, 1.0)}), *, opinion=0.0, contrarian=0.0, threshold=0.0)
Bases: Element
Agent of the voter system variants: an imitator, a threshold voter, or a contrarian.
With a threshold of 0 the voting copies a random neighbour into the agent, as in the voter system. With a positive threshold it gives the agent the opinion opposite to its own when the share of neighbours that hold it exceeds the threshold, so a threshold of 0.5 gives the majority rule. A contrarian adopts the opposite of what it would otherwise adopt.
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': 'opinion', 'color_range': (0.0, 1.0)})
|
opinion
|
Annotated[float, StateSpec(domain=NN)]
|
The initial opinion, 0 or 1. |
0.0
|
contrarian
|
Annotated[float, StateSpec(domain=FiniteEnumeratedSet([0, 1]))]
|
Whether the agent is a contrarian, 1, or not, 0. |
0.0
|
threshold
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The share of disagreeing neighbours above which the agent changes its opinion, or 0 to copy a random neighbour. |
0.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.social.opinion_dynamics import VariantVoterElement
>>> group = GroupElement('voters', element=VariantVoterElement, size=10, values={'threshold': 0.5})
>>> group.label, group.element.__name__, group.size
('voters', 'VariantVoterElement', 10)
Source code in src/skcomplex/systems/social/opinion_dynamics/_voters.py
99 100 101 102 103 104 105 106 107 108 109 110 111 | |
VariantVoterView(agent, stepper)
Bases: AgentView
View of an agent of the voter system variants, with its states and parameters as attributes.
Source code in src/skcomplex/core/engine/solvers/_mesa.py
559 560 561 | |
VariantVotingInteraction(label, *, target)
Bases: MapInteraction
Voting of the voter system variants, where every voter in turn takes the opinion of its variant.
A voter of threshold 0 copies a random neighbour. A voter of positive threshold adopts the opinion opposite to its own when the share of neighbours that hold it exceeds the threshold. A contrarian adopts the opposite of what it would otherwise adopt. The voters update one after the other in a new random order every step, each reading the opinions the voters before it set, and a voter without a neighbouring voter keeps its opinion.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of voters. |
required |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import VariantVotingInteraction
>>> VariantVotingInteraction('voting', target='voters').schedule
'random-sequential'
Source code in src/skcomplex/systems/social/opinion_dynamics/_voters.py
183 184 185 186 187 188 189 190 191 | |
VillageElement(label, visual=VisualSpec('agents', {'color_by': 'culture'}), *, culture=0, features=5.0, traits=10.0)
Bases: Element
Village of Axelrod's system, with a culture of F features of q traits each, stored as one integer.
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': 'culture'})
|
culture
|
Annotated[float, StateSpec(domain=NN)]
|
The culture code, the traits of the features as the digits of a number in base |
0
|
features
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The number of features |
5.0
|
traits
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The number of traits |
10.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.social.opinion_dynamics import VillageElement
>>> GroupElement(
... 'villages', element=VillageElement, size=4, values={'culture': 0, 'features': 3, 'traits': 5}
... ).size
4
Source code in src/skcomplex/systems/social/opinion_dynamics/_axelrod.py
62 63 64 65 66 67 68 69 70 71 72 73 74 | |
VillageView(agent, stepper)
Bases: AgentView
View of a village of the Axelrod culture system, with its states and parameters as attributes.
Source code in src/skcomplex/core/engine/solvers/_mesa.py
559 560 561 | |
VoterElement(label, visual=VisualSpec('agents', {'color_by': 'opinion', 'color_range': (0.0, 1.0)}), *, opinion=0.0)
Bases: Element
Agent of the voter system, whose opinion the imitation sets to that of a random neighbour on a network.
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': 'opinion', 'color_range': (0.0, 1.0)})
|
opinion
|
Annotated[float, StateSpec(domain=NN)]
|
The initial opinion, 0 or 1. |
0.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.social.opinion_dynamics import VoterElement
>>> group = GroupElement('voters', element=VoterElement, size=20, values={'opinion': 1.0})
>>> group.label, group.element.__name__, group.size
('voters', 'VoterElement', 20)
Source code in src/skcomplex/systems/social/opinion_dynamics/_voters.py
146 147 148 149 150 151 152 153 154 | |
VoterImitationInteraction(label, *, target)
Bases: MapInteraction
Imitation of the voter system, where every voter in turn adopts the opinion of a random neighbour.
The voters update one after the other in a new random order every step, each reading the opinions the voters before it set. A voter without a neighbouring voter keeps its opinion.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of voters. |
required |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import VoterImitationInteraction
>>> VoterImitationInteraction('imitation', target='voters').schedule
'random-sequential'
Source code in src/skcomplex/systems/social/opinion_dynamics/_voters.py
233 234 235 236 237 238 239 240 241 | |
VoterView(agent, stepper)
Bases: AgentView
View of an agent of the voter system, with its states and parameters as attributes.
Source code in src/skcomplex/core/engine/solvers/_mesa.py
559 560 561 | |
WillingMajorityInteraction(label, *, target, group_size=3)
Bases: Interaction
Majority rule with willingness, where a random agent adopts the majority opinion of a random group.
Every step has one update per agent. An update chooses an agent uniformly, then an odd number group_size of
other agents uniformly, and the agent adopts the majority opinion of the group with the probability of its
willingness.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of voters. |
required |
group_size
|
Annotated[int, ParameterSpec(domain=NN)]
|
The odd number of other agents an agent consults. |
3
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import WillingMajorityInteraction
>>> WillingMajorityInteraction('majority', target='voters').group_size
3
Source code in src/skcomplex/systems/social/opinion_dynamics/_willing_majority.py
92 93 94 95 96 97 98 99 100 101 | |
follow(system)
Update as many random agents as there are agents, each by the majority of a random group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system
|
SystemView
|
The system. |
required |
Source code in src/skcomplex/systems/social/opinion_dynamics/_willing_majority.py
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | |
WillingVoterElement(label, visual=VisualSpec('agents', {'color_by': 'opinion', 'color_range': (0.0, 1.0)}), *, opinion=0.0, willingness=1.0)
Bases: Element
Voter with a binary opinion and a willingness to follow the majority, a zealot at willingness 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the voter or the group. |
required |
visual
|
VisualSpec | None
|
How the agent is drawn, or |
VisualSpec('agents', {'color_by': 'opinion', 'color_range': (0.0, 1.0)})
|
opinion
|
Annotated[float, StateSpec(domain=NN)]
|
The opinion, 0 for |
0.0
|
willingness
|
Annotated[float, StateSpec(domain=closed(0, 1))]
|
The probability that the voter adopts the majority opinion of the group it consults. |
1.0
|
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import WillingVoterElement
>>> WillingVoterElement('voter').willingness
1.0
Source code in src/skcomplex/systems/social/opinion_dynamics/_willing_majority.py
51 52 53 54 55 56 57 58 59 60 61 | |
WillingVoterView(agent, stepper)
Bases: AgentView
View of a voter of the majority rule with willingness, with its states as attributes.
Source code in src/skcomplex/core/engine/solvers/_mesa.py
559 560 561 | |
axelrod(width=20, height=20, *, features=5, traits=10, random_state=0)
Return Axelrod's culture dissemination system on a full grid with von Neumann neighbourhoods.
Every village starts with random traits. For few traits per feature the villages converge to one culture, and
for many traits they freeze into many small cultural regions, an order-disorder transition at a critical q.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
width
|
int
|
The number of columns. |
20
|
height
|
int
|
The number of rows. |
20
|
features
|
int
|
The number of cultural features |
5
|
traits
|
int
|
The number of traits |
10
|
random_state
|
int | Generator | None
|
The seed or generator of the initial cultures. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import axelrod
>>> axelrod(5, 4).elements[0].prepare().size_
20
Source code in src/skcomplex/systems/social/opinion_dynamics/_axelrod.py
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | |
coevolving_voter(n_voters=200, *, mean_degree=4.0, rewiring=0.3, activity=0.5, random_state=0)
Return the coevolving voter system, which fragments into consensual components when rewiring is fast.
Voters on an Erdős-Rényi graph copy discordant neighbours or rewire the discordant edges to like-minded voters. Below a critical rewiring probability, near 0.38 for mean degree 4, the network stays connected and discordant edges survive for long times, and above it the network splits into components of one opinion.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_voters
|
int
|
The number of voters. |
200
|
mean_degree
|
float
|
The mean degree of the initial random graph. |
4.0
|
rewiring
|
float
|
The probability that an active voter with a discordant neighbour rewires instead of copying. |
0.3
|
activity
|
float
|
The probability that a voter acts in a step. |
0.5
|
random_state
|
int | Generator | None
|
The seed or generator of the graph and of the uniform random opinions. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the groups |
Examples:
>>> from skcomplex.core.engine.runtime import Simulation
>>> from skcomplex.systems.social.opinion_dynamics import coevolving_voter
>>> trajectory = Simulation(coevolving_voter(30), random_state=0).prepare().run(until=5).trajectory_
>>> int(trajectory.network(-1).sources.size) == int(trajectory.network(0).sources.size)
True
Source code in src/skcomplex/systems/social/opinion_dynamics/_coevolution.py
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | |
cognitive_consistency(graph=None, *, positive=0.7, decay=0.05, random_state=0)
Return agents whose attitudes spread by conversation and settle in a belief network that seeks consistency.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
graph
|
object
|
The NetworkX graph, or |
None
|
positive
|
float
|
The share of agents that start in the positive state, F1 = X = 1 and F2 = -1, the others starting in the negative state. |
0.7
|
decay
|
float
|
The fraction of every valence lost per update of the belief network. |
0.05
|
random_state
|
int | Generator | None
|
The seed or generator of the initial states. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> import networkx as nx
>>> from skcomplex.systems.social.opinion_dynamics import cognitive_consistency
>>> cognitive_consistency(nx.complete_graph(6), random_state=0).elements[0].prepare().size_
6
Source code in src/skcomplex/systems/social/opinion_dynamics/_cognition.py
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | |
cultural_traits(culture, features, traits)
Return the traits of a culture vector stored as one integer, its digits in base q.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
culture
|
float
|
The integer code of the culture vector. |
required |
features
|
int
|
The number of features |
required |
traits
|
int
|
The number of traits |
required |
Returns:
| Name | Type | Description |
|---|---|---|
traits |
IntArray
|
The trait of every feature, the first feature first. |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import cultural_traits
>>> cultural_traits(7, 3, 2).tolist()
[1, 1, 1]
Source code in src/skcomplex/systems/social/opinion_dynamics/_axelrod.py
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | |
culture_observables(width, height)
Return the share of the largest cultural region and the number of cultures of a full grid of villages.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
width
|
int
|
The number of columns of the grid. |
required |
height
|
int
|
The number of rows of the grid. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
observables |
list[ObservableSpec]
|
The observables |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import culture_observables
>>> [item.label for item in culture_observables(5, 4)]
['largest_region', 'cultures']
Source code in src/skcomplex/systems/social/opinion_dynamics/_axelrod.py
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | |
deffuant(n_agents=200, *, confidence=0.2, convergence=0.5, random_state=0)
Return the Deffuant bounded confidence system, whose opinions settle into about 1 / (2 * confidence) clusters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_agents
|
int
|
The number of agents. |
200
|
confidence
|
float
|
The largest opinion difference at which two agents compromise. |
0.2
|
convergence
|
float
|
The fraction of the difference by which each agent of a compromising pair moves. |
0.5
|
random_state
|
int | Generator | None
|
The seed or generator of the uniform initial opinions. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import deffuant
>>> deffuant(20, random_state=0).elements[0].prepare().size_
20
Source code in src/skcomplex/systems/social/opinion_dynamics/_bounded_confidence.py
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | |
echo_chamber_radicalization(n_agents=200, *, strength=3.0, controversy=3.0, homophily=3.0, contacts=10, reciprocity=0.5, exponent=2.1, least_activity=0.01, random_state=0)
Return the radicalization model of echo chambers of Baumann and coauthors on an activity-driven network.
Opinions follow dx_i/dt = -x_i + K sum_j A_ij(t) tanh(alpha x_j), where the controversialness alpha shapes
the influence and A_ij(t) is an activity-driven temporal network redrawn at every integration step dt = 0.01:
agent i is active with the probability a_i, drawn from F(a) ~ a^-gamma on [epsilon, 1], and contacts m
others with the homophilic probability |x_i - x_j|^-beta / sum_j |x_i - x_j|^-beta, and a contact is
reciprocated with the probability r (arXiv 1906.12325 Eqs. 1 and 2). Opinions start uniformly spaced on
[-1, 1]. For small K alpha they reach the neutral consensus, above alpha_c = 1 / ((1 + r) K m <a>) they
radicalize, all to one side without homophily (beta = 0), and into two opposite echo chambers with it. The
defaults are the polarized case of Fig. 1(c), K = 3, alpha = 3, beta = 3, r = 0.5, m = 10, and
gamma = 2.1, with fewer agents than the 1000 of the paper so a step is fast. Every step of the system is ten
integration steps.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_agents
|
int
|
The number of agents. |
200
|
strength
|
float
|
The social interaction strength |
3.0
|
controversy
|
float
|
The controversialness |
3.0
|
homophily
|
float
|
The exponent |
3.0
|
contacts
|
int
|
The number |
10
|
reciprocity
|
float
|
The probability |
0.5
|
exponent
|
float
|
The exponent |
2.1
|
least_activity
|
float
|
The least activity |
0.01
|
random_state
|
int | Generator | None
|
The seed or generator of the activities. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import echo_chamber_radicalization
>>> echo_chamber_radicalization(50).elements[0].prepare().size_
50
Source code in src/skcomplex/systems/social/opinion_dynamics/_echo_chambers.py
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | |
galam_majority(n_agents=300, *, group_size=3, share=0.4, random_state=0)
Return the Galam majority system, where random groups adopt their majority until one opinion wins.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_agents
|
int
|
The number of agents. |
300
|
group_size
|
int
|
The number of agents in each discussion group. |
3
|
share
|
float
|
The share of agents with opinion 1. |
0.4
|
random_state
|
int | Generator | None
|
The seed or generator of the opinions. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import galam_majority
>>> galam_majority(30, random_state=0).elements[0].prepare().size_
30
Source code in src/skcomplex/systems/social/opinion_dynamics/_persuasion.py
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 | |
gauge_network_agents(n_agents=12, *, flux=0.0, K=1.0, spread=1.0, connections=None, graph=None, seed=0)
Return agent phases on the nodes of a network that relax towards the transported phases of their neighbours.
Agent i follows theta_i' = K sum_j sin(theta_j - theta_i - A_ij) over its neighbours. A connection whose
oriented sum around a loop is not a multiple of 2 pi frustrates the loop: the transported differences cannot all
vanish, so the agents keep a residual energy sum (1 - cos(theta_j - theta_i - A_ij)) and a twist around the loop.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_agents
|
int
|
The number of agents on a ring, when no graph is given. |
12
|
flux
|
float
|
The oriented sum of the connection around the first face of the minimum cycle basis, spread evenly over the edges of that face. |
0.0
|
K
|
float
|
The coupling strength. |
1.0
|
spread
|
float
|
The largest absolute initial phase. |
1.0
|
connections
|
Sequence[float] | None
|
The connection of every edge, in place of |
None
|
graph
|
Graph | None
|
The network, or |
None
|
seed
|
int
|
The seed of the initial phases. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system. |
Raises:
| Type | Description |
|---|---|
ValidationError
|
A flux is given on a network without faces. |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import gauge_network_agents
>>> [element.label for element in gauge_network_agents(4).elements]
['agents', 'links']
Source code in src/skcomplex/systems/social/opinion_dynamics/_gauge_agents.py
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | |
hegselmann_krause(n_agents=200, *, confidence=0.15, graph=None, random_state=0)
Return the Hegselmann-Krause system, whose opinions freeze within a few steps into clusters about 2 ε apart.
Every step every agent moves at once to the mean opinion of its neighbours, itself included, whose opinions lie
within the confidence ε of its own. On the complete graph the opinions settle into about 1 / (2 ε) clusters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_agents
|
int
|
The number of agents, the nodes of the complete graph when no graph is given. |
200
|
confidence
|
float
|
The confidence |
0.15
|
graph
|
Graph | None
|
The network of the agents, or |
None
|
random_state
|
int | Generator | None
|
The seed or generator of the uniform initial opinions. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> import numpy as np
>>> from skcomplex.core.engine.runtime import Simulation
>>> from skcomplex.systems.social.opinion_dynamics import hegselmann_krause
>>> trajectory = Simulation(
... hegselmann_krause(50, confidence=0.3), random_state=0,
... ).prepare().run(until=20).trajectory_
>>> len(np.unique(np.round(trajectory.values('people.opinion')[-1], 6))) <= 3
True
Source code in src/skcomplex/systems/social/opinion_dynamics/_bounded_confidence.py
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | |
hypergraph_consensus(n_nodes=30, *, triangles=0.05, reinforcement=-1.0, period=2.0, seed=0)
Return the nonlinear three-body consensus system on a random hypergraph of triangles that switch on and off.
Every triple of nodes is a triangle with probability triangles, and every triangle is active in alternate half
periods from a random phase. On an active triangle ijk, node i follows x_i' = s(|x_j - x_k|) (x_j + x_k - 2
x_i) with s(d) = exp(reinforcement * d). Without reinforcement the pulls of a triangle on its three members sum
to zero, so the mean opinion stays fixed whatever the schedules. With reinforcement the pull depends on the member
it acts on, and the mean opinion drifts towards the pairs that agree, for a negative reinforcement, while the
opinions still reach a consensus on a connected hypergraph.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_nodes
|
int
|
The number of nodes. |
30
|
triangles
|
float
|
The probability that a triple of nodes is a triangle. |
0.05
|
reinforcement
|
float
|
The exponent of the modulating function |
-1.0
|
period
|
float
|
The period of the schedules of the triangles. |
2.0
|
seed
|
int
|
The seed of the hypergraph, the phases, and the opinions. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the opinions |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import hypergraph_consensus
>>> system = hypergraph_consensus(8, triangles=0.5)
>>> system.elements[0].prepare().size_
8
Source code in src/skcomplex/systems/social/opinion_dynamics/_hypergraph_consensus.py
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | |
influentials(width=20, height=20, *, n_influentials=10, influence=3.0, news_report=False, random_state=0)
Return the belief diffusion system with influentials who care passionately and weigh more with their neighbours.
Every cell of a torus holds one agent whose weights start uniform on 0 to 4. Every agent in turn, in a random order, learns from its neighbours and then sets its level of caring.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
width
|
int
|
The number of columns. |
20
|
height
|
int
|
The number of rows. |
20
|
n_influentials
|
int
|
The number of influentials, chosen at random. |
10
|
influence
|
float
|
The influence of an influential, the others having influence 1. |
3.0
|
news_report
|
bool
|
Whether a news report adds one to every agent's weight of caring passionately at the start. |
False
|
random_state
|
int | Generator | None
|
The seed or generator of the initial beliefs and of the influentials. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import influentials
>>> influentials(5, 4, n_influentials=2, random_state=0).elements[0].prepare().size_
20
Source code in src/skcomplex/systems/social/opinion_dynamics/_diffusion.py
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | |
join_a_club(n_agents=200, *, mean_degree=6.0, beta=0.5, appeal=0.0, rewiring=0.5, random_state=0)
Return join-a-club spins, agents who join a club with their acquaintances while acquaintances follow the club.
Agents of an Erdős-Rényi graph are in or out of a club, a spin, and choose by a heat bath with the inverse
temperature beta in the field of their acquaintances and of the appeal of the club. Acquaintances across the
club boundary dissolve and reform among agents on the same side. Without coupling the choices stay random and
many acquaintances cross the boundary, and with strong coupling the members and the outsiders separate into
communities with few acquaintances between them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_agents
|
int
|
The number of agents. |
200
|
mean_degree
|
float
|
The mean number of acquaintances. |
6.0
|
beta
|
float
|
The inverse temperature of the heat bath. |
0.5
|
appeal
|
float
|
The field of the club on every agent. |
0.0
|
rewiring
|
float
|
The probability that a reconsidered acquaintance across the club boundary reforms on one side. |
0.5
|
random_state
|
int | Generator | None
|
The seed or generator of the graph and of the uniform random choices. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the groups |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import join_a_club
>>> join_a_club(30).elements[0].element.__name__
'ClubMemberElement'
Source code in src/skcomplex/systems/social/opinion_dynamics/_coevolution.py
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 | |
kinetic_opinion(levels=7, *, confidence=2, persuasion=0.3, repulsion=0.1, eta=1.0)
Return the kinetic system of opinion formation over a discrete grid of opinions.
The population is a distribution over opinion levels from -1 to 1, a site group on a lattice of the levels, which starts almost uniform with a slight lean toward positive opinions. Encounters between levels move an opinion one level toward a close opinion and one level away from a distant one, and keep the total density. With a wide confidence the opinions reach a consensus around the mean, and with a narrow confidence and repulsion they polarise into the two extremes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
levels
|
int
|
The number of opinion levels. |
7
|
confidence
|
int
|
The largest distance in levels at which encounters persuade. |
2
|
persuasion
|
float
|
The probability of moving toward a close opinion. |
0.3
|
repulsion
|
float
|
The probability of moving away from a distant opinion. |
0.1
|
eta
|
float
|
The encounter rate. |
1.0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the distribution |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import kinetic_opinion
>>> kinetic_opinion(levels=5).elements[0].size
5
Source code in src/skcomplex/systems/social/opinion_dynamics/_kinetic_opinion.py
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 | |
largest_region(locations, cultures, width, height)
Return the fraction of the cells in the largest connected region of one culture.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
locations
|
ArrayLike
|
The cell of every agent, one |
required |
cultures
|
ArrayLike
|
The culture code of every agent. |
required |
width
|
int
|
The number of columns of the grid. |
required |
height
|
int
|
The number of rows of the grid. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
fraction |
float
|
The size of the largest region of adjacent cells with the same culture over the number of cells. |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import largest_region
>>> largest_region([(0, 0), (1, 0), (0, 1), (1, 1)], [1, 1, 2, 3], 2, 2)
0.5
Source code in src/skcomplex/systems/social/opinion_dynamics/_axelrod.py
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | |
majority_rule(shape=(100, 100), *, density=0.5, random_state=0)
Return voters that take the majority opinion of their neighbourhood, which coarsens into domains.
Every step every voter takes the opinion of the majority of its eight Moore neighbours and keeps its own when they tie, the majority rule of Argun et al. (2021, section 4.3).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
shape
|
Sequence[int]
|
The number of rows and columns. |
(100, 100)
|
density
|
float
|
The probability that a voter starts with opinion 1. |
0.5
|
random_state
|
int | Generator | None
|
The seed or generator of the initial opinions. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the opinions |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import majority_rule
>>> majority_rule((10, 10)).elements[0].prepare().size_
100
Source code in src/skcomplex/systems/social/opinion_dynamics/_voters.py
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | |
mean_opinion(s, opinions)
Return the mean opinion of a distribution over opinion levels.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
s
|
SimpleNamespace
|
The namespace of one member of the distribution. |
required |
opinions
|
NDArray[float64]
|
The opinion of every level. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
mean |
Expression
|
The normalized first moment. |
Source code in src/skcomplex/systems/social/opinion_dynamics/_kinetic_opinion.py
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | |
naming_game(n_agents=50)
Return the minimal naming game, where agents with empty inventories agree on one word.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_agents
|
int
|
The number of agents. |
50
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import naming_game
>>> naming_game(10).elements[0].prepare().size_
10
Source code in src/skcomplex/systems/social/opinion_dynamics/_conventions.py
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 | |
opinion_grid(levels)
Return the opinion of every level, evenly spaced from -1 to 1.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
levels
|
int
|
The number of opinion levels. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
opinions |
NDArray[float64]
|
The opinion of every level. |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import opinion_grid
>>> opinion_grid(5).tolist()
[-1.0, -0.5, 0.0, 0.5, 1.0]
Source code in src/skcomplex/systems/social/opinion_dynamics/_kinetic_opinion.py
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | |
opinion_observables(levels)
Return the mean opinion and the variance of the opinions of a distribution opinions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
levels
|
int
|
The number of opinion levels. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
observables |
list[ObservableSpec]
|
The observables, each reading the moments of the distribution. |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import opinion_observables
>>> [item.label for item in opinion_observables(7)]
['mean_opinion', 'opinion_variance']
Source code in src/skcomplex/systems/social/opinion_dynamics/_kinetic_opinion.py
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | |
opinion_variance(s, opinions)
Return the variance of the opinions of a distribution, which grows as opinions polarise.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
s
|
SimpleNamespace
|
The namespace of one member of the distribution. |
required |
opinions
|
NDArray[float64]
|
The opinion of every level. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
variance |
Expression
|
The central second moment. |
Source code in src/skcomplex/systems/social/opinion_dynamics/_kinetic_opinion.py
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | |
persuasion_table(levels, confidence, persuasion, repulsion)
Return the transition table of encounters between opinion levels, A[h, k, i].
A candidate at level h that meets a field particle at level k within confidence levels moves one level
toward it with probability persuasion. One that meets a field particle further away moves one level away from it
with probability repulsion, unless it holds an extreme opinion already.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
levels
|
int
|
The number of opinion levels. |
required |
confidence
|
int
|
The largest distance in levels at which encounters persuade. |
required |
persuasion
|
object
|
The probability of moving toward a close opinion, a number or a parameter. |
required |
repulsion
|
object
|
The probability of moving away from a distant opinion, a number or a parameter. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
table |
NDArray[object_]
|
The transition probabilities, which sum to one over the outcomes. |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import persuasion_table
>>> persuasion_table(3, 1, 0.4, 0.1)[0, 1].astype(float).tolist()
[0.6, 0.4, 0.0]
Source code in src/skcomplex/systems/social/opinion_dynamics/_kinetic_opinion.py
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 | |
settle(valences, decay=0.05)
Return the valences of a belief network updated until no valence changes by more than 0.01.
The network links the first concept to the second with weight 0.05 and the second to the third with weight
-0.05. Every update decays a valence by decay and moves it towards 1 or -1 by its net input.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
valences
|
ArrayLike
|
The valences of the three concepts, between -1 and 1. |
required |
decay
|
float
|
The fraction of every valence lost per update. |
0.05
|
Returns:
| Name | Type | Description |
|---|---|---|
valences |
Array
|
The settled valences. |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import settle
>>> settle([1.0, 1.0, -1.0]).round(2).tolist()
[0.48, 0.57, -0.48]
Source code in src/skcomplex/systems/social/opinion_dynamics/_cognition.py
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 | |
social_impact(width=15, height=15, *, share=0.5, exponent=2.0, noise=0.0, random_state=0)
Return the social impact system on a full grid, with random persuasiveness and supportiveness.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
width
|
int
|
The number of columns. |
15
|
height
|
int
|
The number of rows. |
15
|
share
|
float
|
The share of agents with opinion 1, the others holding -1. |
0.5
|
exponent
|
float
|
The exponent of the distance by which impact decays. |
2.0
|
noise
|
float
|
The half-width of the uniform random field. |
0.0
|
random_state
|
int | Generator | None
|
The seed or generator of the opinions and strengths. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import social_impact
>>> social_impact(4, 5, random_state=0).elements[0].prepare().size_
20
Source code in src/skcomplex/systems/social/opinion_dynamics/_persuasion.py
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 | |
standardized_agents(agents=100, *, K=10.0, J=1.0, T=0.5, H=50, standardized=1.0, random_state=0)
Return complex agents whose interactions make them standardized, all showing one characteristic, and ordered.
Below the temperature T_S = K / (2 ln(H / 2)) the most probable share of agents with the characteristic jumps
from q ~ 0 to q ~ 1, a discontinuous transition, and below T_M = J the standardized agents order, with a
magnetization m of either sign. Both states are long-lived on either side of T_S in large groups, so the
initial share standardized selects the branch that the run follows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agents
|
int
|
The number of agents |
100
|
K
|
float
|
The coupling of the characteristics |
10.0
|
J
|
float
|
The coupling of the spins |
1.0
|
T
|
float
|
The temperature, the randomness of the choices. |
0.5
|
H
|
int
|
The number of configurations without the characteristic. |
50
|
standardized
|
float
|
The initial share of agents with the characteristic, each with a random spin. The others start in random configurations without it. |
1.0
|
random_state
|
int | Generator | None
|
The seed or generator of the initial configurations. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import standardized_agents
>>> standardized_agents(10, standardized=0.0).elements[0].values['spin'].tolist()
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
Source code in src/skcomplex/systems/social/opinion_dynamics/_standardization.py
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | |
sznajd(graph=None, *, share=0.5, random_state=0)
Return the Sznajd system, where agreeing pairs of agents convince their neighbours.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
graph
|
object
|
The NetworkX graph, or |
None
|
share
|
float
|
The share of agents with opinion 1. |
0.5
|
random_state
|
int | Generator | None
|
The seed or generator of the opinions. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> import networkx as nx
>>> from skcomplex.systems.social.opinion_dynamics import sznajd
>>> sznajd(nx.cycle_graph(8), random_state=0).elements[0].prepare().size_
8
Source code in src/skcomplex/systems/social/opinion_dynamics/_persuasion.py
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 | |
three_state_opinion(n_agents=200, *, degree=4, sensitivity=2.0, random_state=0)
Return the three-state opinion system of agents against, undecided, and for, on a random regular network.
Every step the agents redraw their opinions one after the other in random order, each from the sum x of the
opinions of its neighbours: against with the probability f(-beta x), for with f(beta x), and undecided
otherwise, where f(t) = 1 / (2 (1 + exp(-t))) (Jensen 2023 section 11.5, Project 1). Since
f(t) + f(-t) = 1 / 2, half of the draws are undecided. In mean field, with every agent seeing q <x>, the mean
opinion solves <x> = tanh(beta q <x> / 2) / 2, which has a non-zero solution only above beta_c = 4 / q. On the
sparse network, domains of both signs and the undecided half keep the order weaker than in mean field.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_agents
|
int
|
The number of agents. |
200
|
degree
|
int
|
The number |
4
|
sensitivity
|
float
|
The sensitivity |
2.0
|
random_state
|
int | Generator | None
|
The seed or generator of the network and of the initial opinions. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import three_state_opinion
>>> three_state_opinion(20).elements[0].prepare().size_
20
Source code in src/skcomplex/systems/social/opinion_dynamics/_undecided.py
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | |
threshold_adoption(n_agents=300, *, size=175.0, reach=15.0, mode='infection', thresholds='uniform', shifting=0.0, random_state=0)
Return the threshold adoption system in social circles, started by the 2.5% of agents with the lowest thresholds.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_agents
|
int
|
The number of agents, placed at random on a square torus. |
300
|
size
|
float
|
The side of the torus. |
175.0
|
reach
|
float
|
The distance within which other agents form an agent's social circle. |
15.0
|
mode
|
str
|
|
'infection'
|
thresholds
|
str
|
|
'uniform'
|
shifting
|
float
|
The share of agents that move one unit in a random direction every step. |
0.0
|
random_state
|
int | Generator | None
|
The seed or generator of the positions and thresholds. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import threshold_adoption
>>> threshold_adoption(40, size=60.0, random_state=0).elements[0].prepare().size_
40
Source code in src/skcomplex/systems/social/opinion_dynamics/_diffusion.py
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 | |
undecided_flows(n_agents=100.0, *, omega=1.0, gamma=0.05, eta=0.02, driven=True)
Return the mean-field flows between agents against, A, undecided, C, and for, B.
Undecided agents join either side at the rate omega, and agents against and for become undecided at the rates
gamma and eta, with no direct flow between the sides, so N = A + B + C is conserved (Jensen 2023 section
11.5, Project 1). With constant rates, driven=False, dA/dt = omega C - gamma A, and the population settles at
the attractive fixed point A : B : C = omega / gamma : omega / eta : 1. When the undecided drive the doubt,
driven=True, the flows into the undecided grow with their number, dA/dt = omega C - gamma A C, and the
dynamics change at N_c = omega (1 / gamma + 1 / eta): above it A = omega / gamma, B = omega / eta, and
N - N_c agents never make up their mind, and below it every agent ends on one side.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_agents
|
float
|
The number of agents, all undecided at the start. |
100.0
|
omega
|
float
|
The rate at which an undecided agent joins either side. |
1.0
|
gamma
|
float
|
The rate at which an agent against becomes undecided. |
0.05
|
eta
|
float
|
The rate at which an agent for becomes undecided. |
0.02
|
driven
|
bool
|
Whether the flows into the undecided are in proportion to their number. |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the numbers |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import undecided_flows
>>> undecided_flows(driven=False).elements[0].drive
0.0
Source code in src/skcomplex/systems/social/opinion_dynamics/_undecided.py
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | |
voter_system(graph=None, *, share=0.5, random_state=0)
Return a voter system with one voter per node of a network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
graph
|
object
|
The NetworkX graph, or |
None
|
share
|
float
|
The share of voters with opinion 1. |
0.5
|
random_state
|
int | Generator | None
|
The seed or generator of the opinions. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> import networkx as nx
>>> from skcomplex.systems.social.opinion_dynamics import voter_system
>>> voter_system(nx.cycle_graph(8), random_state=0).elements[0].prepare().size_
8
Source code in src/skcomplex/systems/social/opinion_dynamics/_voters.py
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 | |
voter_variants(graph=None, *, threshold=0.5, contrarians=0.1, share=0.5, random_state=0)
Return voter system variants on a network, with threshold voters and a share of contrarians.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
graph
|
object
|
The NetworkX graph, or |
None
|
threshold
|
float
|
The share of disagreeing neighbours above which a voter changes its opinion, 0.5 for the majority rule, or 0 to copy a random neighbour. |
0.5
|
contrarians
|
float
|
The share of voters that are contrarians. |
0.1
|
share
|
float
|
The share of voters with opinion 1. |
0.5
|
random_state
|
int | Generator | None
|
The seed or generator of the opinions and of the contrarians. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> import networkx as nx
>>> from skcomplex.systems.social.opinion_dynamics import voter_variants
>>> voter_variants(nx.cycle_graph(8), random_state=0).elements[0].prepare().size_
8
Source code in src/skcomplex/systems/social/opinion_dynamics/_voters.py
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 | |
willing_majority(n_agents=200, *, group_size=3, zealots=0.0, zealot_opinion=None, willingness=1.0, random_state=0)
Return the majority rule with willingness, where zealots of willingness 0 never change their opinion.
Every agent holds opinion A or B, drawn with probability 1/2, and a willingness w_i. An update chooses an
agent and an odd number n of other agents at random, and the agent adopts the majority opinion of the group with
the probability w_i (Jensen 2023 section 11.5, Exercise 4). Every agent has w_i = willingness, except a
fraction zealots of them with w_i = 0. With every agent willing, the population reaches consensus. Zealots of
both opinions prevent it, while a small group of zealots of one opinion, zealot_opinion, wins over everyone.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_agents
|
int
|
The number of agents. |
200
|
group_size
|
int
|
The odd number |
3
|
zealots
|
float
|
The fraction |
0.0
|
zealot_opinion
|
float | None
|
The opinion, 1 for |
None
|
willingness
|
float
|
The willingness of the other agents. |
1.0
|
random_state
|
int | Generator | None
|
The seed or generator of the opinions and of the zealots. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> from skcomplex.systems.social.opinion_dynamics import willing_majority
>>> willing_majority(30).elements[0].prepare().size_
30
Source code in src/skcomplex/systems/social/opinion_dynamics/_willing_majority.py
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 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | |