piegy.simulation

This section documents the core of the piegy package: model initialization and stochastic simulation.

To run a simulation, first use the model class to set up a model, then run simulation by run function. The simulations are computationally intensive. See brief discussion of runtime at runtime.

class simulation.model(N, M, maxtime, record_itv, sim_time, boundary, init_popu, matrices, patch_params, print_pct=50, seed=None)

A simulation.model object contains the parameters and data storage bins for a model. Initialize such an object to set up your model. See below for detailed explanation of init_popu, matrices, patch_params parameters.

Parameters:
  • N (int) – spatial dimension, number of rows.

  • M (int) – spatial dimension, number of columns.

  • maxtime (float or int) – how long you wish the simulation to run.

  • record_itv (float or int) – record interval. Stores data every record_itv of time. Smaller values give finer data but also take more space.

  • boundary (bool) – boundary condition. True for zero-flux (“with boundary”), False for periodical (“no boundary”).

  • init_popu (list or numpy.ndarray) – initial population. Expect shape N x M x 2, the last dimension refers to the initial population of the two species in a patch.

  • matrices (list or numpy.ndarray) – payoff matrices. Expect shape N x M x 4, the last dimension refers to flattened 2 x 2 payoff matrices in each patch.

  • patch_params (list or numpy.ndarray) – patch parameters. Expect shape N x M x 6. There are 6 parameters in a patch: \(\mu1\), \(\mu2\), \(w1\), \(w2\), \(\kappa1\), \(\kappa2\), stored in that order.

  • print_pct (int or None.) – current progress in percentage. Used to specify progress percentage being printed. Set to None to disable. Use multiples of 100 to print only every some rounds.

  • seed (int) – seed for random number generator. Used to initialize a numpy random generator.

We use the following instance variables for data saving.

max_record

Total number of records this object stores. Equals to int(maxtime / interval).

Type:

int

compress_ratio

Number of data points to take average over and then save. Intended to reduce data size. See details at Clarifications-compress_data

Type:

int

U

Hawk’s population. Has shape N x M x max_record.

Type:

numpy.ndarray

V

Dove’s population. Has shape N x M x max_record.

Type:

numpy.ndarray

Hpi

Hawk’s payoff. Has shape N x M x max_record.

Type:

numpy.ndarray

Dpi

Dove’s payoff. Has shape N x M x max_record.

Type:

numpy.ndarray

Below are the public methods of simulation class.

copy(copy_data=True)

Return a deep copy of self.

Parameters:

copy_data (bool) – whether to copy data as well. Set to False if you want an empty copy.

Returns:

a deep copy of self.

Return type:

piegy.simulation.model

clear_data()

Clear data (U, V, Hpi, Dpi): set all 4 objects to None.

change_maxtime(maxtime)

Change maxtime and re-initialize data (set to None).

Warning: this will result in loss of data.

Parameters:

maxtime (float or int) – the new maxtime

set_seed(seed)

Set a new seed.

Parameters:

seed (int) – the new seed, must be non-negative.

compress_data(compress_ratio=5)
Significantly reduces data size by taking average of every some number of data points and store these averages. See implementation details at Clarifications-compress_data.
The update is in-place, no return value.

Notice this results in loss of orginal data.
Parameters:

compress_ratio (int) – over how many data points to take average and re-save.

Note

Regarding considerations about conflict with interval param in figures module, see Clarifications, interval-compress_ratio


simulation.run(mod, predict_runtime=False, message='')

Run simulations on mod. All data will be stored in mod. Only runs with empty model objects and raises error if not empty.

Parameters:
  • mod (piegy.simulation.model object) – where all parameters of the model are stored.

  • predict_runtime (bool) – whether to predict how much runtime the simulation still needs.

  • message (str) – add a message in front of the print line. Only works if mod.print_pct is not None. Not intended for public usage.


simulation.demo_model()
Returns an demo-purpose piegy.simulation.model object. See its parameters at Demo_Params
Returns:

a demo model.

Return type:

piegy.simulation.model


init_popu, matrices, and patch_params

There are three parameters in our model not explained in detail in the piegy.simulation class above: I, X, P, i.e., Initial Population, Payoff Matrices, and Patch Variables.

We provide detailed explanation here.

  • init_popu has dimension \(N \times M \times 2\). init_popu[i][j][0] is hawk’s initial population at patch \((i,j)\), and init_popu[i][j][1] is dove’s initial population.

  • matrices has dimension \(N \times M \times 4\). matrices[i][j] is payoff matrix flattened from the classical \(2 \times 2\) format, with U at first row & col, V at second row & col.

  • patch_params has dimension \(N \times M \times 6\). patch_params[i][j][0], patch_params[i][j][1] characterize tendency of migration, which we denote by \(\mu1\), \(\mu2\), for hawks and doves, respectively.

    Non-negative numbers. Use smaller values for weaker migration behavior, larger values on the contrary. In particular, set \(\mu=0\) to disallow migration.

  • patch_params[i][j][2], patch_params[i][j][3] measure sensitivity to payoff, i.e., the extent to which the direction of migration is biased by payoff. We denote by \(w1\), \(w2\), for hawks and doves, respectively.

    \(w1\), \(w2\) can be any non-negative number. A typical range is \([0, 500]\), with smaller values for lower sensitivity to payoff, larger values on the contrary. In particular, set \(w=0\) for pure random walk. However, since w1 and w2 are used in the exponential function exp, large values might result in overflow or reduced accuracy.

  • patch_params[i][j][2], patch_params[i][j][3] measure carrying capacity, which we denote by \(\kappa1\), \(\kappa2\), respectively.

    \(\kappa1\), \(\kappa2\) can also be any non-negative number, while we recommend around \(0.001\). Too large \(\kappa\) values lead to very small equilibrium population.

Note by using \(N \times M \times x\) lists/arrays, our model allows each patch to have different initial populations, payoff matrices, and patch variables. So don’t restrict your model to uniform setups!


Examples

Here we give a detailed example for model setup.

First please import the piegy.simulation module:

import piegy.simulation as simulation

A simulation begins with defining a set of parameters and storing them in a piegy.simulation.model object. To get started right away, you can simply call piegy.simulation.demo_model and get a pre-made model:

mod = simulation.demo_model()

Or you can define your own set of parameters. Here is a full list of parameters with values same as mod above.

N = 10                  # Number of rows
M = 10                  # Number of cols
maxtime = 100           # how long you want the model to run
record_itv = 0.1        # how often to record data.
sim_time = 1            # repeat the simulation a few times
boundary = True         # boundary condition.

# initial population for the N x M patches.
init_popu = [[[200, 100] for _ in range(M)] for _ in range(N)]

# flattened payoff matrices, total resource is 0.4, cost of fighting is 0.1
matrices = [[[-1, 4, 0, 2] for _ in range(M)] for _ in range(N)]

# patch variables
patch_params = [[[1, 1, 10, 10, 0.001, 0.001] for _ in range(M)] for _ in range(N)]

print_pct = 50           # print progress
seed = 36               # seed for random number generation

# store in a piegy.simulation.model object
mod = simulation.model(N, M, maxtime, record_itv, sim_time, boundary, init_popu, matrices, patch_params, print_pct, seed)
Now we can run the simulation: simply call piegy.simulation.run. Runtime may vary based on what parameters you use.
simulation.run(mod)
It will print out current progress while running the simulation. To run silently, set print_pct = None in the above parameters and re-create sim and run the simulation.
Data generated during the simulation will be stored in the sim variable. You can either examine them directly or save for later use by piegy.data_tools

Here is a short script for saving:
from piegy.data_tools import save_data
save_data(mod, 'some_directory')

But there is one problem (and you may have noticed): the data size is too large!

For our demo simulation, we are saving \(12 \cdot 10^6\) numbers in total (see: Clarifications-compress_data). We can decrease reduce this size by 10 times using the compress_data method (see above for method details):

mod.compress_data(10)

This directly modifies sim variable and only stores average values over every 10 original data points.

Please note that the change is in-place: sim itself will be changed and you will lose the original data permanently. If you are not sure, please make a copy of sim first:

sim_copy = mod.copy()

And then call compress_data on sim_copy.