Skip to content

Populations

Population realizations shared by the biology packages: populations and their growth and mortality.

ExponentialGrowthInteraction(label, *, target, r=1.0, state='n')

Bases: GrowthInteraction

Growth at a constant per capita rate, dn/dt = r n, the exponential form of a growth without harvest.

Parameters:

Name Type Description Default
label str

The label of the interaction.

required
target Annotated[str, RoleSpec()]

The path of the element or group whose population grows.

required
r Annotated[float, ParameterSpec()]

The per capita growth rate, negative for decay.

1.0
state str

The name of the state of the target that holds the population.

'n'

Examples:

>>> from skcomplex.core.elements import CompartmentElement
>>> from skcomplex.core.system import System
>>> from skcomplex.engine.runtime import Simulation
>>> from skcomplex.models.biology.common.populations import ExponentialGrowthInteraction
>>> system = System(
...     elements=[CompartmentElement('rabbits', n=1.0)],
...     interactions=[ExponentialGrowthInteraction('growth', target='rabbits', r=0.5)],
... )
>>> trajectory = Simulation(system, dt=0.01).check().prepare().run(until=2.0).trajectory_
>>> round(float(trajectory.values('rabbits.n')[-1]), 3)
2.718
Source code in src/skcomplex/models/biology/common/populations/_exponential_growth.py
45
46
47
48
49
50
51
52
53
def __init__(
    self,
    label: str,
    *,
    target: Annotated[str, RoleSpec()],
    r: Annotated[float, ParameterSpec()] = 1.0,
    state: str = 'n',
) -> None:
    super().__init__(label, target=target, r=r, form='exponential', state=state)

GompertzGrowthInteraction(label, *, target, r=0.0719, K=1964.0, tau=0.0, state='n')

Bases: GrowthInteraction

Gompertz growth towards a capacity, dn/dt = r n log(K / n(t - tau)), without harvest.

Parameters:

Name Type Description Default
label str

The label of the interaction.

required
target Annotated[str, RoleSpec()]

The path of the element or group whose population grows.

required
r Annotated[float, ParameterSpec(domain=open(0, oo))]

The growth rate.

0.0719
K Annotated[float, ParameterSpec(domain=open(0, oo))]

The capacity.

1964.0
tau Annotated[float, ParameterSpec(domain=closed_open(0, oo))]

The delay of the limiting factor, 0 for none.

0.0
state str

The name of the state of the target that holds the population.

'n'

Examples:

>>> from skcomplex.core.elements import CompartmentElement
>>> from skcomplex.core.system import System
>>> from skcomplex.engine.runtime import Simulation
>>> from skcomplex.models.biology.common.populations import GompertzGrowthInteraction
>>> system = System(
...     elements=[CompartmentElement('tumour', n=1.0)],
...     interactions=[GompertzGrowthInteraction('growth', target='tumour', r=1.0, K=20.0)],
... )
>>> trajectory = Simulation(system, dt=0.1).check().prepare().run(until=30.0).trajectory_
>>> round(float(trajectory.values('tumour.n')[-1]), 3)
20.0
Source code in src/skcomplex/models/biology/common/populations/_gompertz_growth.py
52
53
54
55
56
57
58
59
60
61
62
def __init__(
    self,
    label: str,
    *,
    target: Annotated[str, RoleSpec()],
    r: Annotated[float, ParameterSpec(domain=RealSet.open(0, oo))] = 0.0719,
    K: Annotated[float, ParameterSpec(domain=RealSet.open(0, oo))] = 1964.0,
    tau: Annotated[float, ParameterSpec(domain=RealSet.closed_open(0, oo))] = 0.0,
    state: str = 'n',
) -> None:
    super().__init__(label, target=target, r=r, K=K, tau=tau, form='gompertz', state=state)

GrowthInteraction(label, *, target, r=1.0, K=1.0, p=1.0, h=0.0, tau=0.0, form='exponential', state='n')

Bases: RateInteraction

Growth or decay of a population n of a target by a growth law, with a proportional harvest.

The rate of n is the growth of the form minus the harvest h n:

  • 'exponential': r n.
  • 'logistic': r n (1 - (n / K) ** p), the generalized logistic of Richards, with p = 1 for Verhulst's.
  • 'gompertz': r n log(K / n).
  • 'power': r n ** p.
  • 'bertalanffy': r n ** p (1 - (n / K) ** (1 - p)), von Bertalanffy's growth towards K, with p < 1.

With a delay tau above 0, the limiting factor of the logistic and the Gompertz forms reads the population n(t - tau), as in Hutchinson's delayed logistic equation. A negative rate r gives decay.

Parameters:

Name Type Description Default
label str

The label of the interaction, unique among the parts of its system.

required
target Annotated[str, RoleSpec()]

The path of the element or group whose population grows.

required
r Annotated[float, ParameterSpec()]

The growth rate.

1.0
K Annotated[float, ParameterSpec(domain=open(0, oo))]

The capacity of the logistic, Gompertz, and von Bertalanffy forms.

1.0
p Annotated[float, ParameterSpec()]

The exponent of the logistic, power, and von Bertalanffy forms.

1.0
h Annotated[float, ParameterSpec(domain=closed_open(0, oo))]

The harvest rate, the fraction of the population removed per unit time.

0.0
tau Annotated[float, ParameterSpec(domain=closed_open(0, oo))]

The delay of the limiting factor, 0 for none.

0.0
form str

The growth law, 'exponential', 'logistic', 'gompertz', 'power', or 'bertalanffy'.

'exponential'
state str

The name of the state of the target that holds the population.

'n'

Raises:

Type Description
ValidationError

The form is unknown, the state is not a name, a delay is given to a form without a limiting factor, or the von Bertalanffy exponent is 1.

Examples:

>>> from skcomplex.core.elements import CompartmentElement
>>> from skcomplex.models.biology.common.populations import GrowthInteraction
>>> from skcomplex.core.system import System
>>> from skcomplex.engine.runtime import Simulation
>>> system = System(
...     elements=[CompartmentElement('population', n=1.0)],
...     interactions=[GrowthInteraction('growth', target='population', r=1.0, K=100.0, form='logistic')],
... )
>>> trajectory = Simulation(system, dt=1.0).check().prepare().run(until=30).trajectory_
>>> round(float(trajectory.values('population.n')[-1]), 2)
100.0
Source code in src/skcomplex/models/biology/common/populations/_growth.py
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
def __init__(
    self,
    label: str,
    *,
    target: Annotated[str, RoleSpec()],
    r: Annotated[float, ParameterSpec()] = 1.0,
    K: Annotated[float, ParameterSpec(domain=RealSet.open(0, oo))] = 1.0,
    p: Annotated[float, ParameterSpec()] = 1.0,
    h: Annotated[float, ParameterSpec(domain=RealSet.closed_open(0, oo))] = 0.0,
    tau: Annotated[float, ParameterSpec(domain=RealSet.closed_open(0, oo))] = 0.0,
    form: str = 'exponential',
    state: str = 'n',
) -> None:
    super().__init__(label, target=target, state=state)
    self.r = r
    self.K = K
    self.p = p
    self.h = h
    self.tau = tau
    self.form = form

LogisticGrowthInteraction(label, *, target, r=1.0, K=100.0, tau=0.0, state='n')

Bases: GrowthInteraction

Verhulst's growth limited by a carrying capacity, dn/dt = r n (1 - n(t - tau) / K), without harvest.

A delay tau above 0 gives Hutchinson's delayed logistic equation. The generalized logistic of Richards, with an exponent on the crowding, is GrowthInteraction(form='logistic', p=...).

Parameters:

Name Type Description Default
label str

The label of the interaction.

required
target Annotated[str, RoleSpec()]

The path of the element or group whose population grows.

required
r Annotated[float, ParameterSpec(domain=closed_open(0, oo))]

The per capita growth rate at low density.

1.0
K Annotated[float, ParameterSpec(domain=open(0, oo))]

The carrying capacity.

100.0
tau Annotated[float, ParameterSpec(domain=closed_open(0, oo))]

The delay of the limiting factor, 0 for none.

0.0
state str

The name of the state of the target that holds the population.

'n'

Examples:

>>> from skcomplex.core.elements import CompartmentElement
>>> from skcomplex.core.system import System
>>> from skcomplex.engine.runtime import Simulation
>>> from skcomplex.models.biology.common.populations import LogisticGrowthInteraction
>>> system = System(
...     elements=[CompartmentElement('rabbits', n=1.0)],
...     interactions=[LogisticGrowthInteraction('growth', target='rabbits', r=1.0, K=50.0)],
... )
>>> trajectory = Simulation(system, dt=0.1).check().prepare().run(until=30.0).trajectory_
>>> round(float(trajectory.values('rabbits.n')[-1]), 3)
50.0
Source code in src/skcomplex/models/biology/common/populations/_logistic_growth.py
55
56
57
58
59
60
61
62
63
64
65
def __init__(
    self,
    label: str,
    *,
    target: Annotated[str, RoleSpec()],
    r: Annotated[float, ParameterSpec(domain=RealSet.closed_open(0, oo))] = 1.0,
    K: Annotated[float, ParameterSpec(domain=RealSet.open(0, oo))] = 100.0,
    tau: Annotated[float, ParameterSpec(domain=RealSet.closed_open(0, oo))] = 0.0,
    state: str = 'n',
) -> None:
    super().__init__(label, target=target, r=r, K=K, tau=tau, form='logistic', state=state)

MortalityInteraction(label, *, target, d=0.1, state='n')

Bases: RateInteraction

Death or loss at a constant per capita rate, dn/dt = -d n.

Parameters:

Name Type Description Default
label str

The label of the interaction.

required
target Annotated[str, RoleSpec()]

The path of the element or group whose population dies.

required
d Annotated[float, ParameterSpec(domain=closed_open(0, oo))]

The per capita death rate.

0.1
state str

The name of the state of the target that holds the population.

'n'

Examples:

>>> from skcomplex.core.elements import CompartmentElement
>>> from skcomplex.core.system import System
>>> from skcomplex.engine.runtime import Simulation
>>> from skcomplex.models.biology.common.populations import MortalityInteraction
>>> system = System(
...     elements=[CompartmentElement('foxes', n=8.0)],
...     interactions=[MortalityInteraction('death', target='foxes', d=0.5)],
... )
>>> trajectory = Simulation(system, dt=0.01).check().prepare().run(until=2.0).trajectory_
>>> round(float(trajectory.values('foxes.n')[-1]), 3)
2.943
Source code in src/skcomplex/models/biology/common/populations/_mortality.py
46
47
48
49
50
51
52
53
54
55
def __init__(
    self,
    label: str,
    *,
    target: Annotated[str, RoleSpec()],
    d: Annotated[float, ParameterSpec(domain=RealSet.closed_open(0, oo))] = 0.1,
    state: str = 'n',
) -> None:
    super().__init__(label, target=target, state=state)
    self.d = d

PopulationElement(label, visual=None, *, n=1.0)

Bases: CompartmentElement

Population of one species, a compartment whose state n holds its size.

Parameters:

Name Type Description Default
label str

The label of the population.

required
visual VisualSpec | None

How the element is drawn, or None for default_visual_.

None
n Annotated[float, StateSpec(domain=closed_open(0, oo))]

The initial size.

1.0

Examples:

>>> from skcomplex.models.biology.common.populations import PopulationElement
>>> PopulationElement('rabbits', n=40).n
40
Source code in src/skcomplex/models/biology/common/populations/_population.py
34
35
36
37
38
39
40
41
def __init__(
    self,
    label: str,
    visual: VisualSpec | None = None,
    *,
    n: Annotated[float, StateSpec(domain=RealSet.closed_open(0, oo))] = 1.0,
) -> None:
    super().__init__(label, visual=visual, n=n)

PowerLawGrowthInteraction(label, *, target, r=1.32, p=0.58, state='n')

Bases: GrowthInteraction

Growth that scales as a power of the size, dn/dt = r n ** p, without harvest.

Parameters:

Name Type Description Default
label str

The label of the interaction.

required
target Annotated[str, RoleSpec()]

The path of the element or group whose population grows.

required
r Annotated[float, ParameterSpec(domain=open(0, oo))]

The growth rate.

1.32
p Annotated[float, ParameterSpec(domain=open(0, oo))]

The exponent, 2/3 for a growing rim and 1 for exponential growth.

0.58
state str

The name of the state of the target that holds the population.

'n'

Examples:

>>> from skcomplex.core.elements import CompartmentElement
>>> from skcomplex.core.system import System
>>> from skcomplex.engine.runtime import Simulation
>>> from skcomplex.models.biology.common.populations import PowerLawGrowthInteraction
>>> system = System(
...     elements=[CompartmentElement('tumour', n=1.0)],
...     interactions=[PowerLawGrowthInteraction('growth', target='tumour', r=1.0, p=0.5)],
... )
>>> trajectory = Simulation(system, dt=0.01).check().prepare().run(until=2.0).trajectory_
>>> round(float(trajectory.values('tumour.n')[-1]), 3)
4.0
Source code in src/skcomplex/models/biology/common/populations/_power_law_growth.py
49
50
51
52
53
54
55
56
57
58
def __init__(
    self,
    label: str,
    *,
    target: Annotated[str, RoleSpec()],
    r: Annotated[float, ParameterSpec(domain=RealSet.open(0, oo))] = 1.32,
    p: Annotated[float, ParameterSpec(domain=RealSet.open(0, oo))] = 0.58,
    state: str = 'n',
) -> None:
    super().__init__(label, target=target, r=r, p=p, form='power', state=state)