Part 1. Overview and modularisation

Before actually starting the work, let us shortly get an overview of what needs to be done and understand the main structure of a model developed with copan:CORE.

Our model will have three processes (“things that happen”):

  • growth: in each cell, a local resource stock grows, following the continuous-time logistic growth model given by a certain ODE.

  • fishing: each individual employs a certain effort to harvest the resource growing in its cell, leading to individual catchs and an additional fishing terms in the stock’s ODE.

  • learning: at random points in time given by a Poisson process, each i in a random sample of individuals compares her catch with that of randomly chosen acquaintance j, and copies j’s effort level with a probability depending on the difference in catchs.

In pycopancore, the entities (“things that are”) of a model are distinguished by their entity-type. Of its four built-in entity-types, we only use two:

  • Cell, representing the place where a local resource stock is located (corresponding to a fish pond in the Wiedermann paper),

  • Individual, representing a person fishing some local resource (corresponding to a fishing village in the Wiedermann paper).

(Later on, we may also want to add some processes acting on the level of the entity-types SocialSystem and World, but we keep it simple for now.)

The main dynamic variables of the model will thus be

  • Cell.fish_stock

  • Individual.fishing_effort

  • Individual.catch: the catch

plus some fixed parameters which will also be treated as variables formally and introduced later.

To describe the relationships between cells and individuals, we make use of the following entity attributes shipped with copan:CORE’s base model component:

  • Individual.cell: the home cell of the individual

  • Cell.individuals: list of all individuals living in the cell (in the Wiedermann paper, only one fishing village has access to each fish pond, but here we also allow several individuals to harvest in the same cell)

  • Individual.culture: the unique Culture process taxon relevant for all individuals

  • Culture.acquaintance_network: the social network connecting the individuals

In pycopancore, each variable and each process is owned by some object, most often an entity of a type such as Cell, but sometimes by a so-called process taxon such as Culture. E.g., the inbuild acquaintance_network is owned not by any particular individual but by Culture itself, and individuals can access it via the reference variable named culture that is owned by Individual.

Since the three processes are only connected via the three variables and are otherwise independent, and since we may want to replace one of them by a different version later on (e.g., replace logistic growth by some other growth model or replace the particular form of social learning by some other form of learning), we will implement each process in its own model component and then plug them together to form the actual model.

So our model components will be

  • my_exploit_growth: growth of Cell.fish_stock via an ODE

  • my_exploit_fishing: computation of Individual.catch given Individual.fishing_effort and corresponding reduction of Cell.fish_stock via an ODE

  • my_exploit_learning: for each Individual, identify next time point for learning, then, at that time point, draw a neighbour from Culture.acquaintance_network, compare own and neighbour’s catch and update own fishing_effort.

Each model component will become a python subpackage of pycopancore.model_components, represented by a folder of the same name, which mainly contains …

  • a file model.py that defines which entity-types and process taxa the component uses.

  • a further subpackage called ``interface``that contains the interface classes for all these entity-types and process taxa, describing what variables the component reads and writes;

  • another subpackage called implementation that contains the implementation classes for all these entity-types and process taxa, implementing the processes of the component.

While the interface subpackage is typically represented by a single file interface.py containing several short class definitions, the implementation subpackage is typically represented by a subfolder implementation that contains a separate file for each entity-type or process taxon with a single, longer class definition.

(Later on, when composing the actual model from the three model components, all classes contributing to the same entity-type will be mixed together via multiple inheritance, hence they will also be called mixin classes.)

In the interface classes, each variable is listed in one of three possible ways, each of which we will use for some variables:

  • by reference to an existing variable definition from the master data model;

  • by reference to an existing variable definition in another model component;

  • by giving a new variable definition via instantiating the Variable class and specifying all relevant meta-data for the variable.

In the implementation classes, we will implement the process logics using a number of different techniques suitable for different types of processes (ODEs, algebraic equations, and rules for agent behaviour):

  • the logistic growth ODE will be implemented in imperative-programming style via a method of Cell that computes the RHS of the equation and stores it in the special variable self.d_fish_stock.

  • the formula for the catch of all individuals in a cell will instead be given in declarative-programming style by a simple symbolic expression in the class Cell, and the ODE for fishing will use the same expression.

  • learning will be implemented via three methods, one in Culture that returns the next time point for learning, another in Culture that selects the individuals that learn, and one in Individual that performs the actual learning.

We will see that there are often several alternative ways for implementing a certain process and several alternative classes that could ‘own’ the process.

(Although we need to implement the individual processes, we do not need to take care of how these equations get solved or when the different methods must be called, since that is the job of copan:CORE’s inbuilt runner.)

After having implemented the three model components, we will compose from it the actual model. Just like model components are subpackages of pycopancore.model_components, a model is a subpackage of pycopancore.models and is typically defined in a single python file inside the folder pycopancore/models. The model definition will mainly import the necessary model components and will compose the final implementation classes of all entity-types and process taxa from the mixin classes provided by the components.

Finally, we will write a python script run_my_exploit.py that performs a simple study by running the model with some particular initial condition and parameter values and plotting some results. Such study scripts can be stored in the studies folder outside the pycopancore package.

Summarizing, we will first act as model component developer, then as model composer, and finally as model end user, and will eventually have written the following files (omitting certain secondary files we will learn about later):

pycopancore (repository folder)

  pycopancore (main package folder)
  | model_components
  | | my_exploit_growth
  | | | implementation
  | | | | cell.py
  | | | | environment.py
  | | | interface.py
  | | | model.py
  | | my_exploit_fishing
  | | | implementation
  | | | | cell.py
  | | | | individual.py
  | | | | metabolism.py
  | | | interface.py
  | | | model.py
  | | my_exploit_learning
  | | | implementation
  | | | | culture.py
  | | | | individual.py
  | | | interface.py
  | | | model.py
  | models
  | | my_exploit.py

  studies (folder for studies)
  | run_my_exploit.py

Nicely, we can make use of some templates provided in the templates folder:

templates (folder containing stuff to be copied and adjusted)
| model_components
| | SOME_COMPONENT (template for a model component folder)
| | | ...
| models
| | SOME_MODEL.py (template for a model)
| studies
| | SOME_STUDY.py (template for a study)

So, let’s go: Part 2. Implementing the growth component