Skip to content

Commit b42f490

Browse files
committed
deploy: a14bc33
0 parents  commit b42f490

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+7881
-0
lines changed

.buildinfo

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Sphinx build info version 1
2+
# This file records the configuration used when building these files. When it is not found, a full rebuild will be done.
3+
config: fef82a2252b5bbd75425279a18f9ab63
4+
tags: 645f666f9bcd5a90fca523b33c5a78b7

.doctrees/author.doctree

3.91 KB
Binary file not shown.

.doctrees/environment.pickle

96.5 KB
Binary file not shown.

.doctrees/index.doctree

5.02 KB
Binary file not shown.

.doctrees/metapypulation.doctree

259 KB
Binary file not shown.

.doctrees/modules.doctree

2.76 KB
Binary file not shown.

.doctrees/overview.doctree

20.9 KB
Binary file not shown.

.nojekyll

Whitespace-only changes.

_sources/author.md.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# About the author
2+
3+
This repository is developed and maintained by Dr. Matteo Tomasini, research engineer at the Gothenburg Research Infrastructure in Digital Humanities and researcher within the project [Maritime Encounters](https://www.gu.se/en/research/maritime-encounters) at the University of Gothenburg. You can find more about him at his [personal webpage](https://mtomasini.github.io/).

_sources/index.rst.txt

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
.. MetaPypulation documentation master file, created by
2+
sphinx-quickstart on Tue Jul 9 12:12:46 2024.
3+
You can adapt this file completely to your liking, but it should at least
4+
contain the root `toctree` directive.
5+
6+
Welcome to MetaPypulation's documentation!
7+
==========================================
8+
9+
.. toctree::
10+
:maxdepth: 2
11+
:caption: Contents:
12+
13+
overview.md
14+
modules
15+
author.md
16+
17+
18+
Indices and tables
19+
==================
20+
21+
* :ref:`genindex`
22+
* :ref:`modindex`
23+
* :ref:`search`

_sources/metapypulation.rst.txt

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
metapypulation package
2+
======================
3+
4+
Submodules
5+
----------
6+
7+
metapypulation.individual module
8+
--------------------------------
9+
10+
.. automodule:: metapypulation.individual
11+
:members:
12+
:undoc-members:
13+
:show-inheritance:
14+
15+
metapypulation.metapopulation module
16+
------------------------------------
17+
18+
.. automodule:: metapypulation.metapopulation
19+
:members:
20+
:undoc-members:
21+
:show-inheritance:
22+
23+
metapypulation.subpopulation module
24+
-----------------------------------
25+
26+
.. automodule:: metapypulation.subpopulation
27+
:members:
28+
:undoc-members:
29+
:show-inheritance:
30+
31+
metapypulation.simulation module
32+
-----------------------------------
33+
34+
.. automodule:: metapypulation.simulation
35+
:members:
36+
:undoc-members:
37+
:show-inheritance:
38+
39+
Module contents
40+
---------------
41+
42+
.. automodule:: metapypulation
43+
:members:
44+
:undoc-members:
45+
:show-inheritance:

_sources/modules.rst.txt

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
metapypulation
2+
==============
3+
4+
.. toctree::
5+
:maxdepth: 4
6+
7+
metapypulation

_sources/overview.md.txt

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Metapypulation: an overview
2+
3+
Metapypulation is a package to simulate the spread of culture in a metapopulation. It supplies a set of tools partly inspired by other frameworks such as [Mesa](https://mesa.readthedocs.io/en/stable/overview.html) which are general-purpose methods to perform agent-based modelling with Python. The main reason to create my own package for this purpose is to change the focus of the tool - population-based simulations instead of individual-based.
4+
5+
## Structure
6+
7+
Metapypulation has three main classes:
8+
9+
- an [`Individual`](https://mtomasini.github.io/MetapopulationsPython/metapypulation.html#module-metapypulation.individual) class, which represents each individual in the metapopulation.
10+
- a [`Subpopulation`](https://mtomasini.github.io/MetapopulationsPython/metapypulation.html#module-metapypulation.subpopulation) class, representing the different discrete subpopulations that compose the metapopulation;
11+
- finally, a [`Metapopulation`](https://mtomasini.github.io/MetapopulationsPython/metapypulation.html#module-metapypulation.metapopulation) class, which puts `Individual` and `Subpopulation` together and have individuals interacting in this world.
12+
13+
In addition, I provide a [`Simulation`](https://mtomasini.github.io/MetapopulationsPython/metapypulation.html#module-metapypulation.simulation) class, which allows to run a simulation with several replicates, which outputs different measurements ([see below](#diversity-measures)). The class also provides some quick tools to plot the results of the simulation.
14+
15+
## The spread of cultural traits
16+
17+
Currently, each individual's culture is represented by a set of {math}`N` features. Each feature in turn can assume one of {math}`\nu` traits. These features represent different (assumed) independent facets of culture: one could be language, burial tradition, boat building features, *etc*. So each individual is currently represented by a vector of integers.
18+
19+
### Neutral model
20+
21+
The Neutral model follows loosely the set up selected by other authors working on the spread of cultural traits (_e.g._ *Patterns in space and time: simulating cultural transmission in archaeology*, Marko Porčić). We use the simplest model where one focal individual at random in each subpopulation and each time-step copies one trait at random from another individual in the same subpopulation. The model allows for copying errors with rate {math}`\mu`: if a copying error occurs, instead of copying a trait from another individual, the focal individual changes the trait at the feature in focus with a random trait between the available ones.
22+
23+
### Axelrod model
24+
25+
While we plan on adding several different ways for individuals to interact and change their traits, as of July 2024 the only such way to interact is shaped upon the **Axelrod model of culture dissemination** (*The Dissemination of Culture: A Model with Local Convergence and Global Polarization*, Robert Axelrod (1997), The Journal of Conflict Resolution, vol. 41, no. 2). In this model, at each generation an individual is chosen at random to copy a trait from a neighboring source on a lattice; the copy occurs with a probability proportional to the total similarity of the two random individuals. This mimicks homophily - the principle by which two individuals that resemble each other have a higher chance of having an exchange than two individuals that are completely different. In the metapopulation model that I developed, for each subpopulation we pick two random individuals that will act as target and source of the copy. Here too, copying errors occur with rate {math}`\mu`.
26+
27+
### Diversity measures
28+
29+
Currently, we have implemented a few diversity measures at the level of both the subpopulation and the whole metapopulation (to avoid repeating "subpopulation / metapopulation", we refer to either as the "reference population" for the measure.
30+
31+
#### Count of sets
32+
The first measure that we implemented is the number of unique sets of traits, {math}`K`. In code, this is done through the function `np.unique(..., return_counts = True)`.
33+
34+
#### Shannon diversity
35+
The second diversity index that we have implemented is the Shannon diversity index, which measures the entropy in the reference population. For {math}`K` sets of traits,
36+
37+
```{math}
38+
H^{\prime} = - \sum_{i = 1}^{K} p_i \ln p_i ,
39+
```
40+
41+
where {math}`p_i` is the frequency of a type of individual {math}`i` in the subpopulation / metapopulation. Shannon is a measure of how "easy" it is, given an individual of type `j`, to predict the set of traits of another individual in the same reference population.
42+
43+
#### Simpson index
44+
We also implemented the Simpson's diversity index, defined as
45+
46+
```{math}
47+
S = \sum_{i = 1}^{K} p^2_i .
48+
```
49+
50+
The Simpson index is bound between 0 and 1, and represents the probability that two individuals in the same reference population have the same set of traits.
51+
52+
#### Gini-Simpson index
53+
The Gini-Simpson index is simply the complement of the Simpson index, that is it measures the probability that two random indeividuals in the same reference population do not share a set of traits. This is calculated as
54+
55+
```{math}
56+
G = 1 - \sum_{i = 1}^{K} p^2_i = 1 - S.
57+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/* Compatability shim for jQuery and underscores.js.
2+
*
3+
* Copyright Sphinx contributors
4+
* Released under the two clause BSD licence
5+
*/
6+
7+
/**
8+
* small helper function to urldecode strings
9+
*
10+
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL
11+
*/
12+
jQuery.urldecode = function(x) {
13+
if (!x) {
14+
return x
15+
}
16+
return decodeURIComponent(x.replace(/\+/g, ' '));
17+
};
18+
19+
/**
20+
* small helper function to urlencode strings
21+
*/
22+
jQuery.urlencode = encodeURIComponent;
23+
24+
/**
25+
* This function returns the parsed url parameters of the
26+
* current request. Multiple values per key are supported,
27+
* it will always return arrays of strings for the value parts.
28+
*/
29+
jQuery.getQueryParameters = function(s) {
30+
if (typeof s === 'undefined')
31+
s = document.location.search;
32+
var parts = s.substr(s.indexOf('?') + 1).split('&');
33+
var result = {};
34+
for (var i = 0; i < parts.length; i++) {
35+
var tmp = parts[i].split('=', 2);
36+
var key = jQuery.urldecode(tmp[0]);
37+
var value = jQuery.urldecode(tmp[1]);
38+
if (key in result)
39+
result[key].push(value);
40+
else
41+
result[key] = [value];
42+
}
43+
return result;
44+
};
45+
46+
/**
47+
* highlight a given string on a jquery object by wrapping it in
48+
* span elements with the given class name.
49+
*/
50+
jQuery.fn.highlightText = function(text, className) {
51+
function highlight(node, addItems) {
52+
if (node.nodeType === 3) {
53+
var val = node.nodeValue;
54+
var pos = val.toLowerCase().indexOf(text);
55+
if (pos >= 0 &&
56+
!jQuery(node.parentNode).hasClass(className) &&
57+
!jQuery(node.parentNode).hasClass("nohighlight")) {
58+
var span;
59+
var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
60+
if (isInSVG) {
61+
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
62+
} else {
63+
span = document.createElement("span");
64+
span.className = className;
65+
}
66+
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
67+
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
68+
document.createTextNode(val.substr(pos + text.length)),
69+
node.nextSibling));
70+
node.nodeValue = val.substr(0, pos);
71+
if (isInSVG) {
72+
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
73+
var bbox = node.parentElement.getBBox();
74+
rect.x.baseVal.value = bbox.x;
75+
rect.y.baseVal.value = bbox.y;
76+
rect.width.baseVal.value = bbox.width;
77+
rect.height.baseVal.value = bbox.height;
78+
rect.setAttribute('class', className);
79+
addItems.push({
80+
"parent": node.parentNode,
81+
"target": rect});
82+
}
83+
}
84+
}
85+
else if (!jQuery(node).is("button, select, textarea")) {
86+
jQuery.each(node.childNodes, function() {
87+
highlight(this, addItems);
88+
});
89+
}
90+
}
91+
var addItems = [];
92+
var result = this.each(function() {
93+
highlight(this, addItems);
94+
});
95+
for (var i = 0; i < addItems.length; ++i) {
96+
jQuery(addItems[i].parent).before(addItems[i].target);
97+
}
98+
return result;
99+
};
100+
101+
/*
102+
* backward compatibility for jQuery.browser
103+
* This will be supported until firefox bug is fixed.
104+
*/
105+
if (!jQuery.browser) {
106+
jQuery.uaMatch = function(ua) {
107+
ua = ua.toLowerCase();
108+
109+
var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
110+
/(webkit)[ \/]([\w.]+)/.exec(ua) ||
111+
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
112+
/(msie) ([\w.]+)/.exec(ua) ||
113+
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
114+
[];
115+
116+
return {
117+
browser: match[ 1 ] || "",
118+
version: match[ 2 ] || "0"
119+
};
120+
};
121+
jQuery.browser = {};
122+
jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
123+
}

0 commit comments

Comments
 (0)