Examples
Skyrms (2010) Signals
evoke library examples from:
Skyrms, B. (2010). Signals: Evolution, Learning, and Information. Oxford University Press.
- class skyrms2010signals.Skyrms2010_1_1
Figure 1.1, page 11, of Skyrms (2010). The figure depicts the replicator dynamics of a population repeatedly playing a two-player cooperative game where each agent in the population either always plays sender or always plays receiver. Senders observe one of two randomly chosen states of the world and produce one of two signals. Receivers observe the signal and produce one of two acts. If the act matches the state, both players gain a payoff.
- run_simulation()
Technically this figure does not require a simulation. It describes how a population of two types would evolve if it were playing a cooperative game.
- Returns:
evo – The evolutionary scenario is represented by an object from the module evolve.
- Return type:
an instance of evolve.TwoPops.
- class skyrms2010signals.Skyrms2010_1_2
Figure 1.2, page 12, of Skyrms (2010). The figure depicts the replicator dynamics of a population repeatedly playing a two-player cooperative game where each agent in the population can switch between playing sender or receiver.
- run_simulation()
Technically this figure does not require a simulation. It describes how a population of one type would evolve if it were playing a cooperative game.
- Returns:
evo – The evolutionary scenario is represented by an object from the module evolve.
- Return type:
an instance of evolve.OnePop.
- class skyrms2010signals.Skyrms2010_3_3(iterations=100)
Figure 3.3, page 40, of Skyrms (2010). The figure depicts the mutual information between signal and state over successive trials of a two-player cooperative game in which agents learn via reinforcement. Typically the mutual information will increase over time as the agents learn to use specific signals as indicators of specific states. However, the stochastic nature of the simulation means that the figure will look different each time it is run.
- class skyrms2010signals.Skyrms2010_3_4(iterations=100)
Figure 3.4, page 46, of Skyrms (2010). The figure depicts the change over time of the average probability of success in a cooperative signalling chain game. In this game there is a sender, an intermediary, and a receiver. There are two signals, between the sender and intermediary and between the intermediary and receiver. It takes a lot longer for signalling to become established in this game. The original figure uses one million iterations (1e6); however, the probability of success often reaches 1 after just one hundred thousand iterations (1e5).
- class skyrms2010signals.Skyrms2010_4_1
Figure 4.1, page 59, of Skyrms (2010). The figure depicts cycles in the replicator dynamics of a rock-paper-scissors game.
- run_orbits()
Generate the cycles in the replicator dynamics.
The cycles are stored as class attribute self.xyzs. This is used by the superclass Ternary in the method self.show().
- Returns:
evo – The evolve object for a one-population game.
- Return type:
- class skyrms2010signals.Skyrms2010_5_2
Figure 5.2, page 72, of Skyrms (2010). The figure shows the value of assortment that is required to destabilise pooling in a 2x2x2 cooperative signalling game. Assortment is defined as the probability of meeting another player in the population who is the same type as you. Pooling is any strategy that produces the same signal for more than one state.
Skyrms describes this model on page 71:
“Here we consider a one-population model, in which nature assigns roles of sender or receiver on flip of a fair coin. We focus on four strategies, written as a vector whose components are: signal sent in state 1, signal sent in state 2, act done after signal 1, act done after signal 2.
s1 = <1, 2, 1, 2>
s2 = <2, 1, 2, 1>
s3 = <1, 1, 2, 2>
s4 = <2, 2, 2, 2>”
- show()
Show the figure.
We call the superclass method and tell it to show the line along with the datapoints.
- class skyrms2010signals.Skyrms2010_8_1(iterations=1000)
Figure 8.1, page 95, of Skyrms (2010). The figure depicts the change over time of the probability of success in a two-player cooperative game where the agents learn by reinforcement.
- show()
Show the figure.
We call the superclass method and tell it to show the line along with the datapoints.
- Return type:
None.
- class skyrms2010signals.Skyrms2010_8_2(trials=100, iterations=1000)
Figure 8.2, page 97, of Skyrms (2010). The figure depicts the probability of pooling in a signalling game with reinforcement learning for different initial weights. Initial weights determine how difficult it is to learn something new: large initial weights mean that learning is slower.
Skyrms does not explicitly state the number of trials or number of iterations used to generate his figure. We suspect the parameter values are something like trials=int(1e3) and iterations=int(1e5). However, attempting to generate this figure with those values will take an exceptionally long time.
Even with iterations=int(1e4), it’s looking like 12 minutes per weight, so about an hour overall.
This, combined with the difficulty of figuring out exactly how Skyrms is identifying pooling equilibria, leads to us overestimating the probability of pooling. You are warned!
- class skyrms2010signals.Skyrms2010_8_3(trials=100, iterations=300, learning_params=[0.01, 0.03, 0.05, 0.07, 0.1, 0.15, 0.2])
Figure 8.3, page 98, of Skyrms (2010). The figure depicts the probability of signalling for different values of the learning parameter in a Bush–Mosteller reinforcement scenario.
Our recreation of this figure is clearly undercounting signalling. That’s because we are defining signalling as “not pooling”, and we are overcounting pooling (see the docstring for class Skyrms2010_8_2).
In future, we need to try and count both pooling and signaling more accurately; this is difficult, since we don’t know exactly how Skyrms defines them for the purposes of his figures.
- initialize_simulation(learning_params) None
Sets the figure parameters as class attributes.
- Parameters:
learning_params (array-like, optional) – Learning parameters to run simulations for.
- class skyrms2010signals.Skyrms2010_10_5(trials=1000, iterations=10000)
Figure 10.5, page 130, of Skyrms (2010). The figure depicts the number of signals at the end of reinforcement for a cooperative game in which senders can invent new signals.
NB Skyrms uses trials=1000 and iterations=int(1e5) but this will take a very long time.
Godfrey-Smith & Martínez (2013)
evoke library examples from:
Godfrey-Smith, P., & Martínez, M. (2013). Communication and Common Interest. PLOS Computational Biology, 9(11), e1003282. https://doi.org/10.1371/journal.pcbi.1003282
The supporting information (including important definitions) can be found at https://doi.org/10.1371/journal.pcbi.1003282.s001
How to use this script
Quick run: Create figure objects with demo=True.
Figures 1 and 2, full run, minimal parameters:
Decide how many games per value of C you want to analyse, games_per_c. Godfrey-Smith and Martínez use 1500.
Run find_games_3x3(games_per_c). This will generate games_per_c games per value of C and store them in a local directory.
Run analyse_games_3x3(games_per_c). This will calculate values required to create figures 1 and 2. This can take a long time! 1500 games takes about 30 minutes.
Run GodfreySmith2013_1(games_per_c, demo=False) to create Figure 1.
Run GodfreySmith2013_2(games_per_c, demo=False) to create Figure 2.
Figure 3a (sender), full run, minimal parameters:
Decide how many games per value of C and K you want to analyse, games_per_c_and_k. Godfrey-Smith and Martínez use 1500.
Run find_games_3x3_c_and_k(games_per_c_and_k,sender=True). This will generate games_per_c_and_k games per pair of values C and K and store them locally.
Run analyse_games_3x3_c_and_k(games_per_c_and_k,sender=True). This will calculate values required to create figure 3. This can take a long time!
Run GodfreySmith2013_3_sender(games_per_c_and_k,demo=False) to create Figure 3a.
Figure 3b (receiver), full run, minimal parameters:
Decide how many games per value of C and K you want to analyse, games_per_c_and_k. Godfrey-Smith and Martínez use 1500.
Run find_games_3x3_c_and_k(games_per_c_and_k,sender=False). This will generate games_per_c_and_k games per pair of values C and K and store them locally.
Run analyse_games_3x3_c_and_k(games_per_c_and_k,sender=False). This will calculate values required to create figure 3. This can take a long time!
Run GodfreySmith2013_3_receiver(games_per_c_and_k,demo=False) to create Figure 3a.
- class godfreysmith2013communication.GodfreySmith2013_1(games_per_c=50, demo=True, dir_games='../data/')
Original figure: https://doi.org/10.1371/journal.pcbi.1003282.g001
How probable is an information-using equilibrium in a randomly-chosen game with a particular level of common interest?
Common interest here is defined as Godfrey-Smith and Martínez’s measure C.
How to use this class
You have two options to create this figure: demo mode and full mode.
Demo mode omits hard-to-find classes and places an upper limit on games_per_c. This allows it to run in a reasonable amount of time.
Full mode requires an existing set of game data stored in JSON files. These can be created via the functions find_games_3x3() and analyse_games_3x3().
The reason for demo mode is that the figure takes a VERY long time to create with the published parameter of games_per_c=1500. Realistically we need to prepare by finding games_per_c games for each value of C, storing them in a local JSON file, and calling them at runtime to count the equilibria. Demo mode omits games with c=0.000 and c=0.111 because they are especially hard to find.
- load_saved_games(dir_games, games_per_c) None
Get sender and receiver matrices and load them into game objects. Put them into dictionary self.games.
The games should already exist in dir_games with filenames of the form:
f”{dir_games}games_c{c_value:.3f}_n{games_per_c}.json”
- class godfreysmith2013communication.GodfreySmith2013_2(games_per_c=50, demo=True, dir_games='../data/')
Original figure: https://doi.org/10.1371/journal.pcbi.1003282.g002
What is the highest level of information transmission at equilibrium across a sample of games with a particular level of common interest?
Common interest here is defined as Godfrey-Smith and Martínez’s measure C.
How to use this class
You have two options to create this figure: demo mode and full mode.
Demo mode omits hard-to-find classes and places an upper limit on games_per_c. This allows it to run in a reasonable amount of time.
Full mode requires an existing set of game data stored in JSON files. These can be created via the functions find_games_3x3() and analyse_games_3x3().
The reason for demo mode is that the figure takes a VERY long time to create with the published parameter of games_per_c=1500. Realistically we need to prepare by finding games_per_c games for each value of C, storing them in a local JSON file, and calling them at runtime to count the equilibria. Demo mode omits games with c=0.000 and c=0.111 because they are especially hard to find.
- load_saved_games(dir_games, games_per_c) None
Get sender and receiver matrices and load them into game objects. Put them into dictionary self.games.
The games should already exist in dir_games with filenames of the form:
f”{dir_games}games_c{c_value:.3f}_n{games_per_c}.json”
- class godfreysmith2013communication.GodfreySmith2013_3(games_per_c_and_k=150, k_indicator=None, demo=False, dir_games='../data/')
See figure at https://doi.org/10.1371/journal.pcbi.1003282.g003
This object requires an existing set of game data stored in JSON files. These can be created with find_games_3x3_c_and_k() and analyse_games_3x3_c_and_k(). See the section How to use this script for more.
Demo mode is not yet available for this figure.
- load_saved_games(dir_games) None
Get sender and receiver matrices and load them into game objects. Put them into dictionary self.games.
The games should already exist in dir_games with filenames of the form:
f”{dir_games}games_c{c_value:.3f}_{ks or kr}{k_value:.3f}_n{games_per_c_and_k}.json”
- Parameters:
dir_games (str) – Directory containing JSON files with sender and receiver matrices.
- class godfreysmith2013communication.GodfreySmith2013_3_sender(**kwargs)
Wrapper for GodfreySmith2013_3(), calling with parameter self.k_indicator = “ks” to create figure 3a.
- class godfreysmith2013communication.GodfreySmith2013_3_receiver(**kwargs)
Wrapper for GodfreySmith2013_3(), calling with parameter self.k_indicator = “kr” to create figure 3b.
- godfreysmith2013communication.calculate_D(payoff_matrix, state, act_1, act_2) float
Calculate an agent’s relative preference of acts act_1 and act_2 in state state.
The measure is defined in the supplement of Godfrey-Smith and Martínez (2013), page 1.
- Parameters:
- Returns:
D – Godfrey-Smith and Martínez’s measure D.
0 if act 1 is preferred
0.5 if the payoffs are equal
1 if act 2 is preferred
- Return type:
- godfreysmith2013communication.calculate_C(state_chances, sender_payoff_matrix, receiver_payoff_matrix) float
Calculate C as per Godfrey-Smith and Martínez’s definition.
See page 2 of the supporting information at https://doi.org/10.1371/journal.pcbi.1003282.s001
- Returns:
c – PGS & MM’s measure C.
- Return type:
- godfreysmith2013communication.calculate_Ks_and_Kr(sender_payoff_matrix, receiver_payoff_matrix)
Calculate the extent to which an agent’s preference ordering over receiver actions varies with the state of the world.
Defined as K_S and K_R in the supplement of Godfrey-Smith and Martínez (2013), page 2.
- Parameters:
payoff_matrix (array-like) – The agent’s payoff matrix.
- Returns:
K
- Return type:
- godfreysmith2013communication.find_games_3x3(games_per_c=1500, c_values=array([0., 0.1111, 0.2222, 0.3333, 0.4444, 0.5556, 0.6667, 0.7778, 0.8889, 1.]), dir_games='../data/') None
Finds games_per_c 3x3 sender and receiver matrices and saves them as JSON files, storing them by C value in dir_games.
Since it’s hard to find games for certain values of C, we’ll save each JSON file individually once we’ve found it. Then if you have to terminate early, you can come back and just search for games with the values of C you need later on.
- godfreysmith2013communication.analyse_games_3x3(games_per_c=1500, c_values=array([0., 0.1111, 0.2222, 0.3333, 0.4444, 0.5556, 0.6667, 0.7778, 0.8889, 1.]), dir_games='../data/', sigfig=5) None
Find information-using equilibria of 3x3 games and the mutual information between states and acts at those equilibria.
The games should already exist in dir_games with filenames of the form:
f"{dir_games}games_c{c_value:.3f}_n{games_per_c}.json"
Each file should be a list of dicts. Each dict corresponds to a game:
{ "s": <sender payoff matrix> "r": <receiver payoff matrix> "e": <equilibrium with the highest information transmission> "i": <mutual information between states and acts at this equilibrium> }
s
andr
already exist; this function fills ine
andi
.- Parameters:
dir_games (str) – Directory to find and store JSON files
games_per_c (int, optional) – Number of games to find per value of c. The default is 1500.
c_values (array-like) – List of C values to find games for. The default is the global variable c_3x3_equiprobable.
sigfig (int, optional.) – The number of significant figures to report values in. Since gambit sometimes has problems rounding, it generates values like 0.9999999999996. We want to report these as 1.0000, especially if we’re dumping to a file. The default is 5.
- godfreysmith2013communication.find_games_3x3_c_and_k(games_per_c_and_k=1500, sender=True, c_values=array([0., 0.1111, 0.2222, 0.3333, 0.4444, 0.5556, 0.6667, 0.7778, 0.8889, 1.]), k_values=array([0., 0.3333, 0.6667, 1., 1.3333, 1.6667, 2.]), dir_games='../data/') None
Finds
games_per_c_and_k
3x3 sender and receiver matrices and saves them as JSON files, storing them by C and K values indir_games
.Note that it is EXTREMELY difficult to find games for some combinations of C and K, especially when C=0. Expect this to take a long time!
Since it’s hard to find games for certain combinations of C and K, we’ll save each JSON file individually once we’ve found it. Then if you have to terminate early, you can come back and just search for games with the combinations of C and K you need later on.
- Parameters:
games_per_c_and_k (int, optional) – Number of games to find per pair of c and k. The default is 1500.
sender (bool) – If True, the operative value of K is the sender’s K_S If False, the operative value of K is the receiver’s K_R
c_values (array-like) – List of C values to find games for. The default is the global variable c_3x3_equiprobable.
k_values (array-like) – List of K values to find games for. The default is the global variable k_3x3.
dir_games (str) – Directory to place JSON files
- godfreysmith2013communication.analyse_games_3x3_c_and_k(games_per_c_and_k=1500, sender=True, c_values=array([0., 0.1111, 0.2222, 0.3333, 0.4444, 0.5556, 0.6667, 0.7778, 0.8889, 1.]), k_values=array([0., 0.3333, 0.6667, 1., 1.3333, 1.6667, 2.]), dir_games='../data/', sigfig=5) None
Find information-using equilibria of 3x3 games and the mutual information between states and acts at those equilibria.
The games should already exist in dir_games with filenames of the form:
f"{dir_games}games_c{c_value:.3f}_{ks or kr}{k_value:.3f}_n{games_per_c}.json"
Each file should be a list of dicts. Each dict corresponds to a game:
{ "s": <sender payoff matrix> "r": <receiver payoff matrix> "e": <equilibrium with the highest information transmission> "i": <mutual information between states and acts at this equilibrium> }
s and r already exist; this function fills in e and i.
- Parameters:
games_per_c_and_k (int, optional) – Number of games to analyse per pair of c and k. The default is 1500.
sender (bool) – If True, the operative value of K is the sender’s K_S If False, the operative value of K is the receiver’s K_R
c_values (array-like) – List of C values to analyse games for. The default is the global variable c_3x3_equiprobable.
k_values (array-like) – List of K values to analyse games for. The default is the global variable k_3x3.
dir_games (str) – Directory to find and update JSON files
sigfig (int, optional.) – The number of significant figures to report values in. Since gambit sometimes has problems rounding, it generates values like 0.9999999999996. We want to report these as 1.0000, especially if we’re dumping to a file. The default is 5.
- godfreysmith2013communication.get_random_payoffs(states=3, acts=3, min_payoff=0, max_payoff=100)
Generate a random payoff matrix.
- Parameters:
- Returns:
payoffs – A random payoff matrix of shape (states,acts).
- Return type:
array-like