Species Interactions#
Species Interactions
Consumer-resource interactions
MacArthur’s theory/models
Predator-prey & competition (one prey two predators) - Rosenzweig-MacArthur (VJ)
Bacterial-substrate (1 batceria - 1 or many substrates , two bacteria and 1 or more resources) - MiCRM
The Lotka-Volterra equations
Every LV system is “effective” (derivation from MacArthur’s models / MiCRM)
Normal form?
Competition and Mutualism
Bifurcations (VJ)
Evolutionary dynamics?
Stochasticity?
Applications/Examples
Introduction#
Consumers “live to eat” and “eat to live.” They are heterotrophs that harvest energy from other organisms, such as tigers, or from organic sources, such as bacteria. As Ludwig Boltzmann noted in 1886:
“The struggle for existence of living beings is not for the fundamental constituents of food, but for the possession of the free energy obtained, chiefly by means of the green plant, from the transfer of radiant energy from the hot sun to the cold earth.”
Consumer-resource interactions play a crucial role in the flow of energy through ecosystems. The metabolic theory of ecology provides a foundation for understanding these interactions, linking individual metabolic processes to population and ecosystem dynamics.
Energy, Metabolism, and Consumption#
All living organisms must maintain an energy balance:
Different organisms allocate energy to maintenance, growth, and movement in varying proportions. To do more than just maintain themselves, organisms must consume energy at a rate faster than their metabolic rate. This requires investment in activities such as foraging, which links energy acquisition to body size. For instance, autotrophs utilize photosynthesis, while heterotrophs depend on consuming organic material.
Size and Metabolic Needs#
Resting metabolic rate (\(B\)) increases with body size (\(M\)) following a power-law relationship:
where \(B_0\) is a normalization constant and \(b\) is the scaling exponent, typically around \(3/4\). Larger organisms have higher absolute metabolic rates but lower mass-specific rates:
This relationship implies that larger organisms need to consume more energy overall but are more efficient per unit of body mass. This efficiency has significant implications for energy flow in ecosystems, as larger consumers typically occupy higher trophic levels and have lower population densities.
Biomechanical Implications of Size#
Size also affects biomechanics and interactions with the physical environment. As Haldane (1926) observed:
“You can drop a mouse down a thousand-yard mine shaft; and, on arriving at the bottom, it gets a slight shock and walks away, provided that the ground is fairly soft. A rat is killed, a man is broken, a horse splashes.”
Size influences how organisms move, forage, and interact with resources, ultimately affecting their consumption rates. Smaller organisms, for example, often forage faster but consume smaller amounts per event, while larger organisms are slower but consume larger quantities.
Dissecting Consumer-Resource Interactions#
Components of consumer-resource interactions determine consumption rate (\(c\)):
where \(a\) is the search rate, \(R\) is resource density, and \(h\) is handling time. This is known as the Type II functional response, where resource handling dominates at high resource densities, while searching dominates at low densities.
These interactions are further influenced by environmental factors, such as temperature and resource availability, which alter the rates of searching and handling.
Predicting Consumer-Resource Interactions#
Key components of consumer-resource interactions scale with size:
Velocity and detection distance increase with consumer size.
Handling time decreases with size.
Consumption rate scales positively with size and interaction dimensionality (e.g., 2D vs. 3D).
For example, in 3D environments like oceans, consumption rates scale more steeply with size compared to 2D environments. Studies have shown that aquatic predators exhibit 10x higher consumption rates at a given size compared to terrestrial predators due to the higher dimensionality of their interaction space.
#
Temperature and Consumer-Resource Interactions#
Temperature affects interaction components via the Boltzmann-Arrhenius equation:
where \(k\) is the reaction rate, \(A\) is a constant, \(E_a\) is activation energy, \(k_B\) is Boltzmann’s constant, and \(T\) is temperature. Higher temperatures generally increase foraging velocity and reduce handling time, leading to higher consumption rates. For example, ectothermic organisms show a strong temperature dependence in their foraging activities, while endotherms have a more stable consumption rate due to thermal regulation.
Consumer-Resource Dynamics & MacArthur’s theory#
The logistic model primarily focuses on the intrinsic dynamics of a species, which are influenced by a variety of factors. To enhance the accuracy and comprehensiveness of the model, we incorporate the effects of predators (consumers) on the population dynamics of the species:
As illustrated, we have modified the initial logistic model by introducing the term \( -aNC \), and we have incorporated a new equation, \( \frac{dC}{dt} \), to describe the dynamics of the predator population. In the new modeal, \(r_m\) is the resource’s maximum growth rate, \(K\) is carrying capacity, \(a\) is search rate, \(e\) is conversion efficiency (the ability to convert energy into growth), and \(z\) is mortality rate. This refined model is MacArthur Model.
P.S. These parameters may also depend on size and temperature, linking individual metabolism to population-level outcomes. Additionally, such models help explain phenomena like population cycles and the effects of environmental changes on consumer-resource interactions.
Summary#
Metabolic rate and biomechanics shape species’ consumer-resource interactions and consumption rates.
Size, temperature, and dimensionality influence these interactions.
Models incorporating metabolic constraints can predict population dynamics and ecological patterns.
Understanding these principles provides insights into energy flow and stability in ecosystems.
Discussion Questions#
What are the main advantages of a consumer (heterotrophic) lifestyle compared to an producer (autotrophic) one? What are the disadvantages?
Which is the most common and diverse organisms on planet earth ? Why? Think in terms of what type of consumer they are, and what their size is.
What is the largest consumer on Earth? What is the smallest? In what respects is their “struggle for existence” similar? In what respects is it different?
Which consumer(s) on earth operate(s) at the hottest temperatures? Which operate at the coldest? How is their “struggle for existence” similar or different?
Simulation Code#
Let simulate the model by Python! The parameters are given as below.
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
# Define model parameters
params = {
'r': 1.0, # Resource growth rate
'K': 100.0, # Environmental carrying capacity
'a': 0.02, # Predation rate
'w': 0.5, # Resource conversion efficiency
'm': 0.2 # Consumer death rate
}
def model(state, t, r, K, a, w, m):
"""
Differential equations for the consumer-resource model.
state[0]: R (resource quantity)
state[1]: C (consumer quantity)
"""
R, C = state
# Resource equation: dR/dt = rR(1-R/K) - aRC
dRdt = r * R * (1 - R/K) - a * R * C
# Consumer equation: dC/dt = C(waR - m)
dCdt = C * (w * a * R - m)
return [dRdt, dCdt]
# Time series
t = np.linspace(0, 100, 1000)
# Initial conditions
R0 = 50.0 # Initial resource quantity
C0 = 10.0 # Initial consumer quantity
state0 = [R0, C0]
# Solve the differential equations
solution = odeint(model, state0, t, args=(params['r'], params['K'],
params['a'], params['w'],
params['m']))
# Plotting
plt.figure(figsize=(12, 8))
# Time series plot
plt.plot(t, solution[:, 0], 'g-', linewidth=1.5, label='Resource (R)')
plt.plot(t, solution[:, 1], 'r--', linewidth=1.5, label='Consumer (C)') # Changed to dashed line
plt.legend()
plt.xlabel('Time', fontsize=14) # Adjusted font size
plt.ylabel('Population', fontsize=14) # Adjusted font size
plt.title('Consumer-Resource Population Dynamics', fontsize=14) # Adjusted font size
plt.tight_layout()
plt.show()
# Print steady state values (if they exist)
final_state = solution[-1]
print(f"\nFinal state (t={t[-1]}):")
print(f"Resource: {final_state[0]:.2f}")
print(f"Consumer: {final_state[1]:.2f}")
# Calculate equilibrium points of the system
# Non-trivial equilibrium satisfies:
# 1) 0 = rR(1-R/K) - aRC
# 2) 0 = C(waR - m)
# From the second equation, either C = 0 or R = m/(wa)
R_eq = params['m']/(params['w'] * params['a'])
if R_eq < params['K']:
C_eq = (params['r']/params['a']) * (1 - R_eq/params['K'])
print("\nTheoretical equilibrium point:")
print(f"R*: {R_eq:.2f}")
print(f"C*: {C_eq:.2f}")
else:
print("\nNo feasible non-trivial equilibrium exists")
Consumer-Resource Model:#
If we want to expand the explanation of MacArthur model, let’s treat prey as a resource and predators as consumers. So, we replace the \(N\) in the model with \(R\). Also, to avoid any misunderstanding about the parameters, we replaced some notations. Now the model is shown as below:
The MacArthur model is typically used to describe interactions between a single consumer population and a single resource population. How can we expand it to multiple resources and multiple consumers? There are following two points we need to consider:
Multiple Resources: Instead of considering just one resource \( R \), we now consider a set of resources \( R_\alpha \) (for \( \alpha = 1, 2, ..., n \)) that interact with the consumers. Thus, in \( \frac{dC}{dt} \), the resource term is updated to \(\sum_{\alpha}w_{\alpha}a_{\alpha}R_{\alpha}C\). Let’s add the index for Consumer \(i\): \(\frac{dC_i}{dt} = \sum_{\alpha}w_{i\alpha}a_{i\alpha}R_{\alpha}C_i - m_iC_i\).
Multiple Consumers: Each consumer species \( C_i \) may interact with all of the available resources, consuming them at different rates and with different efficiencies. Thus, in \( \frac{dR}{dt} \), the consumer term is updated to \(-\sum_{i}a_{i}RC_i\). Let’s add the index for Resource \(\alpha\): \(\frac{dR_{\alpha}}{dt}=r_{\alpha} R_{\alpha} \left( 1- \frac{R_{\alpha}}{K_{\alpha}}\right)- \sum_{i}a_{i\alpha}R_{\alpha}C_i\)
Let’s conbine it write it together:
where:
\( r_\alpha \): Maximum growth rate of resource \( \alpha \).
\( K_\alpha \): Carrying capacity of resource \( \alpha \), representing the maximum sustainable population size.
\( a_{i\alpha} \): Interaction coefficient representing the rate at which consumer \( i \) consumes resource \( \alpha \).
\( w_{i\alpha} \): Conversion efficiency, indicating how efficiently resource \( \alpha \) supports consumer \( i \)‘s growth.
\( m_i \): Mortality rate of consumer \( i \), representing natural death and other forms of population loss.
Detailed explanation:#
Resource Dynamics (\( \frac{dR_\alpha}{dt} \)):
The first term \( r_\alpha R_\alpha \left(1 - \frac{R_\alpha}{K_\alpha}\right) \) describes the logistic growth of resource \( \alpha \). It models the growth of resources up to a maximum carrying capacity \( K_\alpha \), where growth rate \( r_\alpha \) diminishes as \( R_\alpha \) approaches \( K_\alpha \).
The second term \( - \sum_i a_{i\alpha} R_\alpha C_i \) represents the consumption of resource \( \alpha \) by all consumers \( i \). It reflects the depletion of resources due to consumption by consumers.
Consumer Dynamics (\( \frac{dC_i}{dt} \)):
\( C_i \left[\sum_\alpha w_{i\alpha} a_{i\alpha} R_\alpha - m_i\right] \) governs the change in consumer \( i \)‘s population.
\( \sum_\alpha w_{i\alpha} a_{i\alpha} R_\alpha \) calculates the net growth rate of consumer \( i \) considering all resources \( \alpha \) it consumes, weighted by \( w_{i\alpha} \), which represents the efficiency of resource \( \alpha \) in supporting consumer \( i \)‘s growth.
\( m_i \) represents the mortality rate of consumer \( i \), affecting its population dynamics by reducing \( C_i \).
Model Insights:#
Metabolic Basis: The model integrates metabolic rates (through \( a_{i\alpha} \), \( w_{i\alpha} \), \( m_i \)) to predict consumer-resource interactions. These parameters link individual-level processes (metabolism, consumption) to population-level outcomes (population dynamics, ecological stability).
Environmental Effects: Changes in environmental factors (like temperature, resource availability) influence \( r_\alpha \), \( K_\alpha \), \( a_{i\alpha} \), and \( w_{i\alpha} \), thereby affecting the stability and dynamics of ecological systems.
Predictive Power: By simulating these interactions, the model can predict population cycles, community structure, and the impact of environmental changes on ecosystems.
A simple example#
Let’s assume that there are two resources and two consumers.
For Resource 1:
For Resource 2:
For Consumer 1:
For Consumer 2:
Simulation Code#
Let simulate the model by Python! The parameters are given as below.
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
# Define model parameters
params = {
# Resource growth rates
'r1': 1.0,
'r2': 1.2,
# Environmental carrying capacities
'K1': 100.0,
'K2': 120.0,
# Predation rate matrix a[i,j] represents the predation rate of consumer i on resource j
'a': np.array([
[0.02, 0.01], # Consumer 1's predation rate on Resource 1 and Resource 2
[0.01, 0.02] # Consumer 2's predation rate on Resource 1 and Resource 2
]),
# Resource conversion efficiency matrix w[i,j] represents the efficiency of consumer i converting resource j
'w': np.array([
[0.5, 0.3], # Consumer 1's conversion efficiency for Resource 1 and Resource 2
[0.3, 0.5] # Consumer 2's conversion efficiency for Resource 1 and Resource 2
]),
# Consumer mortality rates
'm1': 0.2,
'm2': 0.2
}
def model(state, t, params):
"""
Differential equations for a two-consumer, two-resource model.
state: [R1, R2, C1, C2]
"""
R1, R2, C1, C2 = state
# Equation for Resource 1
dR1dt = params['r1'] * R1 * (1 - R1/params['K1']) - \
(params['a'][0,0]*C1 + params['a'][1,0]*C2) * R1
# Equation for Resource 2
dR2dt = params['r2'] * R2 * (1 - R2/params['K2']) - \
(params['a'][0,1]*C1 + params['a'][1,1]*C2) * R2
# Equation for Consumer 1
dC1dt = C1 * (params['w'][0,0]*params['a'][0,0]*R1 + \
params['w'][0,1]*params['a'][0,1]*R2 - params['m1'])
# Equation for Consumer 2
dC2dt = C2 * (params['w'][1,0]*params['a'][1,0]*R1 + \
params['w'][1,1]*params['a'][1,1]*R2 - params['m2'])
return [dR1dt, dR2dt, dC1dt, dC2dt]
# Time series
t = np.linspace(0, 200, 2000)
# Initial conditions
R1_0 = 50.0 # Initial quantity of Resource 1
R2_0 = 60.0 # Initial quantity of Resource 2
C1_0 = 10.0 # Initial quantity of Consumer 1
C2_0 = 12.0 # Initial quantity of Consumer 2
state0 = [R1_0, R2_0, C1_0, C2_0]
# Solve the differential equations
solution = odeint(model, state0, t, args=(params,))
# Plotting
plt.figure(figsize=(15, 10))
# Time series plot
# plt.plot(t, solution[:, 0], 'g-', linewidth=1.5, label='Resource 1')
# plt.plot(t, solution[:, 1], 'r-', linewidth=1.5, label='Resource 2')
plt.plot(t, solution[:, 2], 'b--', linewidth=1.5, label='Consumer 1')
plt.plot(t, solution[:, 3], 'y--', linewidth=1.5, label='Consumer 2')
plt.legend()
plt.xlabel('Time', fontsize=14) # Adjust font size
plt.ylabel('Population', fontsize=14) # Adjust font size
# plt.title('Consumer-Resource Population Dynamics', fontsize=14) # Adjust font size
plt.title('Consumer Dynamics', fontsize=14) # Adjust font size
plt.tight_layout()
plt.show()
# Print final state
final_state = solution[-1]
print(f"\nFinal state (t={t[-1]}):")
print(f"Resource 1: {final_state[0]:.2f}")
print(f"Resource 2: {final_state[1]:.2f}")
print(f"Consumer 1: {final_state[2]:.2f}")
print(f"Consumer 2: {final_state[3]:.2f}")
Effective Lotka-Volterra (eLV) model#
Now, we can obtain the dynamic of multiple resources and multiple consumers, but how to determine the interactions between different consumers? It is not difficult to find that the consumer-resource model is actually very similar to the Lotka-Volterra (LV) model (which has been introduced in other chapters), and for the LV model, we can calculate it in the form of effective Lotka-Volterra (eLV) to analyze the interaction between \(x_i\) and \(x_j\). If you are interested in the proof, please refer to the references.
Lotka-Volterra (LV) model:
Effective Lotka-Volterra (eLV) model:
where, \(r_i\) is the growth rate coefficient and \(\alpha_{ij}\) is the effective interaction coefficient. Similarly, we can calculate the consumer-resource model in the form of eLV:
where, \(\alpha_{ij}=- \sum_{\alpha} \frac{w_{i\alpha} a_{i\alpha} K_\alpha a_{j\alpha}}{r_\alpha}\), \(r_i = \sum_\alpha w_{i\alpha} a_{i\alpha} K_\alpha - m_i\).
Reference#
Species packing and competitive equilibrium for many species
A minimal model for microbial biodiversity can reproduce experimentally observed ecological patterns
Simulation Code#
Let simulate the model by Python! The parameters are given as below.
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
# Define parameters
params = {
'r': np.array([1.0, 1.2]), # Resource growth rates
'K': np.array([100.0, 120.0]), # Carrying capacities
'a': np.array([
[0.02, 0.01],
[0.01, 0.02]
]),
'w': np.array([
[0.5, 0.3],
[0.3, 0.5]
]),
'm': np.array([0.2, 0.2]) # Consumer mortality rates
}
# Compute Effective Interaction Coefficients (alpha_ij) and Growth Rates (r_i)
r_i = np.array([
sum(params['w'][i, alpha] * params['a'][i, alpha] * params['K'][alpha] for alpha in range(2)) - params['m'][i]
for i in range(2)
])
alpha_ij = np.array([
[-sum(params['w'][i, alpha] * params['a'][i, alpha] * params['K'][alpha] * params['a'][j, alpha] / params['r'][alpha] for alpha in range(2))
for j in range(2)]
for i in range(2)
])
print("Growth Rates (r_i):", r_i)
print("Effective Interaction Coefficients (alpha_ij):\n", alpha_ij)
# Define ELV model
def elv_model(C, t, r, alpha):
C1, C2 = C
dC1dt = C1 * (r[0] + alpha[0,0] * C1 + alpha[0,1] * C2)
dC2dt = C2 * (r[1] + alpha[1,0] * C1 + alpha[1,1] * C2)
return [dC1dt, dC2dt]
# Initial conditions
C0 = [10.0, 12.0]
# Time range
t = np.linspace(0, 200, 2000)
# Solve ODEs
solution = odeint(elv_model, C0, t, args=(r_i, alpha_ij))
# Plot results
plt.figure(figsize=(10, 6))
plt.plot(t, solution[:, 0], 'b--', linewidth=1.5, label='Consumer 1')
plt.plot(t, solution[:, 1], 'y--', linewidth=1.5, label='Consumer 2')
plt.legend()
plt.xlabel('Time')
plt.ylabel('Population')
plt.title('Consumer Dynamics under ELV Model')
# plt.grid()
plt.show()
Further modification#
Leakage represents inefficiencies or resource recycling processes that occur in ecological systems. To incorporate leakage into the Consumer-Resource model, we need to account for the fraction of resources consumed by a consumer that is not fully converted into biomass for the consumer but instead “leaks” back into the resource pool or into another resource.
Including Leakage in Consumer Dynamics#
Leakage is incorporated by assuming that:
A portion of the consumed resource \(R_\alpha \) by consumer \( C_i \) is not converted into biomass but is instead “leaked” into other resource pools \( R_\beta \), where \( \alpha \neq \beta \).
The leakage is defined by a leakage matrix \( l^i_{\alpha \beta} \), where \( l^i_{\alpha \beta} \) represents the fraction of resource \( R_\alpha \) consumed by consumer \( C_i \) that leaks into resource \( R_\beta \).
Thus, the effective resource contribution to the growth of consumer \( C_i \) becomes:
where \( u_{i\alpha} \) replaces \( w_{i\alpha} a_{i\alpha} \) to represent the combined uptake and conversion efficiency of \( C_i \) for resource \( R_\alpha \). The term \( (1 - \sum_\beta l^i_{\alpha \beta}) \) ensures that only the fraction of the resource not leaked contributes to the consumer’s growth.
Updated Consumer Dynamics#
With leakage included, the consumer dynamics become:
\( \sum_\alpha u_{i\alpha} (1 - \sum_\beta l^i_{\alpha \beta}) R_\alpha \): The effective growth rate of consumer \( C_i \), considering the resource uptake \( u_{i\alpha} R_\alpha \) minus the leaked fraction \( \sum_\beta l^i_{\alpha \beta} \).
\( m_i \): Mortality rate of consumer \( C_i \).
Including Leakage in Resource Dynamics#
When leakage is included, we must account for two effects:
Depletion by Consumption: Resource \( R_\alpha \) is still depleted by consumer \( C_i \) at a rate \( C_i u_{i\alpha} R_\alpha \).
Return via Leakage: A fraction of other consumed resources \( R_\beta \) (where \( \beta \neq \alpha \)) leaks into \( R_\alpha \) at a rate proportional to \( l^i_{\beta \alpha} \). The total leakage into \( R_\alpha \) is given by:
where \( \beta \) runs over all other resources.
Combining these effects, the resource dynamics become:
\( \rho_\alpha (R) \): Growth rate of resource \( R_\alpha \).
\( - \sum_i C_i u_{i\alpha} R_\alpha \): Depletion of resource \( R_\alpha \) due to consumption by all consumers.
\( + \sum_i \sum_\beta C_i u_{i\beta} R_\beta l^i_{\beta \alpha} \): Gain in \( R_\alpha \) from leakage contributions of other resources \( R_\beta \).
Final Form#
By combining the updated consumer and resource dynamics, the final model with leakage becomes:
Key Features and Explanations:#
Leakage Matrix \( l^i_{\alpha \beta} \):
\( l^i_{\alpha \beta} \) determines how much of resource \( R_\alpha \) consumed by \( C_i \) is leaked into resource \( R_\beta \). It is critical for describing resource recycling and feedback loops in ecosystems.
Consumer Dynamics:
Consumer growth is reduced by leakage, as only a fraction of the consumed resources \( (1 - \sum_\beta l^i_{\alpha \beta}) \) contributes to the consumer’s biomass.
Resource Dynamics:
Resource pools are interconnected via leakage. Resources can gain from the leakage of other resources, creating complex interactions and potential stabilization mechanisms in ecosystems.
Ecological Implications:
The inclusion of leakage allows the model to simulate nutrient cycling, detritus feeding, or other real-world ecological processes where energy and matter are not perfectly transferred between trophic levels.
This extended model provides a more realistic representation of ecological systems by incorporating inefficiencies and feedbacks in resource consumption.
A simple example#
Let’s add leakage for above “2 consumers - 2 resources” model and simulate the model by Python! The parameters are given as below.
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
# Parameters
params = {
'r': np.array([1.0, 1.2]),
'K': np.array([100.0, 120.0]),
'a': np.array([
[0.02, 0.01],
[0.01, 0.02]
]),
'w': np.array([
[0.5, 0.3],
[0.3, 0.5]
]),
'm': np.array([0.2, 0.2])
}
# Leakage tensor l^i_{alpha beta}
l = np.array([
[[0.1, 0.05], [0.05, 0.1]], # Leakage for consumer 1
[[0.1, 0.05], [0.05, 0.1]] # Leakage for consumer 2
])
# Model equations
def dXdt(X, t, params, l):
C = X[:2] # Consumer populations
R = X[2:] # Resource populations
r = params['r']
K = params['K']
a = params['a']
w = params['w']
m = params['m']
u = w * a # Interaction strengths
# Consumer dynamics
dCdt = C * (np.sum(u * (1 - np.sum(l, axis=2)) * R, axis=1) - m)
# Resource dynamics
dRdt = r * (1 - R / K) * R - np.sum(C[:, np.newaxis] * u * R -
np.sum(C[:, np.newaxis] * u * R * l, axis=2), axis=0)
return np.concatenate([dCdt, dRdt])
# Initial conditions
X0 = np.array([10, 15, 50, 60])
# Time points
t = np.linspace(0, 100, 500)
# Solve ODEs
X = odeint(dXdt, X0, t, args=(params, l))
# Plot results
plt.figure(figsize=(10, 6))
plt.plot(t, X[:, 0], label='Consumer 1')
plt.plot(t, X[:, 1], label='Consumer 2')
plt.plot(t, X[:, 2], '--', label='Resource 1')
plt.plot(t, X[:, 3], '--', label='Resource 2')
plt.xlabel('Time')
plt.ylabel('Population/Resource Density')
plt.legend()
plt.title('Consumer-Resource Model Dynamics')
plt.show()