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_stockIndividual.fishing_effortIndividual.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 individualCell.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 uniqueCultureprocess taxon relevant for all individualsCulture.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_stockvia an ODEmy_exploit_fishing: computation of
Individual.catchgivenIndividual.fishing_effortand corresponding reduction ofCell.fish_stockvia an ODEmy_exploit_learning: for each
Individual, identify next time point for learning, then, at that time point, draw a neighbour fromCulture.acquaintance_network, compare own and neighbour’scatchand update ownfishing_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.pythat 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
implementationthat 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
Variableclass 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
Cellthat computes the RHS of the equation and stores it in the special variableself.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
Culturethat returns the next time point for learning, another inCulturethat selects the individuals that learn, and one inIndividualthat 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