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:
$\( k = A e^{-\frac{E_a}{k_B T}}, \)
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 metabolic basis of consumer-resource interactions can predict population dynamics using models like the Lotka-Volterra equations:
where \(r_m\) is the resource’s maximum growth rate, \(K\) is carrying capacity, \(a\) is search rate, \(e\) is conversion efficiency, and \(z\) is mortality rate. These parameters 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?
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:#
The MacArthur model is typically used to describe interactions between a single consumer population and a single resource population.
Expanding to Multiple Resources and Consumers
The natural extension of the MacArthur model involves adding multiple resources and multiple consumers. In a more complex ecological system, different consumer species interact with different resources, and each consumer might have distinct preferences or efficiencies in using different resources. This requires expanding the model to account for these new interactions:
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.
Multiple Consumers: Each consumer species \( C_i \) may interact with all of the available resources, consuming them at different rates and with different efficiencies. Each consumer species also has its own mortality rate and other parameters that govern its dynamics.
Introducing Conversion Efficiency
In the MacArthur model, the growth rate of the consumer population is simply tied to the amount of resources they consume. When transitioning to the Consumer-Resource model, we need to account for conversion efficiency, which represents the ability of each consumer species \( C_i \) to convert the resources it consumes into its own growth. This is captured by the conversion efficiency term \( w_{i\alpha} \), which modifies the impact of the resources on the growth of the consumer population.
The model describes the dynamics of \( R_\alpha \) (resources) and \( C_i \) (consumers) in a multi-species ecological system. The equations are:
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.
Explanation:#
Resource Dynamics (\( \frac{dR_\alpha}{dt} \)):
The first term \( r_\alpha \left(1 - \frac{R_\alpha}{K_\alpha}\right) R_\alpha \) 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.
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}")
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_a \) by consumer \( C_i \) is not converted into biomass but is instead “leaked” into other resource pools \( R_b \), where \( b \neq a \).
The leakage is defined by a leakage matrix \( l^i_{ab} \), where \( l^i_{ab} \) represents the fraction of resource \( R_a \) consumed by consumer \( C_i \) that leaks into resource \( R_b \).
Thus, the effective resource contribution to the growth of consumer \( C_i \) becomes:
where \( u_{ia} \) replaces \( w_{i\alpha} a_{i\alpha} \) to represent the combined uptake and conversion efficiency of \( C_i \) for resource \( R_a \). The term \( (1 - \sum_b l^i_{ab}) \) 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_a u_{ia} (1 - \sum_b l^i_{ab}) R_a \): The effective growth rate of consumer \( C_i \), considering the resource uptake \( u_{ia} R_a \) minus the leaked fraction \( \sum_b l^i_{ab} \).
\( 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_a \) is still depleted by consumer \( C_i \) at a rate \( C_i u_{ia} R_a \).
Return via Leakage: A fraction of other consumed resources \( R_b \) (where \( b \neq a \)) leaks into \( R_a \) at a rate proportional to \( l^i_{ba} \). The total leakage into \( R_a \) is given by:
where \( b \) runs over all other resources.
Combining these effects, the resource dynamics become:
\( \rho_a(R) \): Growth rate of resource \( R_a \).
\( - \sum_i C_i u_{ia} R_a \): Depletion of resource \( R_a \) due to consumption by all consumers.
\( + \sum_i \sum_b C_i u_{ib} R_b l^i_{ba} \): Gain in \( R_a \) from leakage contributions of other resources \( R_b \).
Final Form of the Model#
By combining the updated consumer and resource dynamics, the final model with leakage becomes:
Key Features and Explanations:#
Leakage Matrix \( l^i_{ab} \):
\( l^i_{ab} \) determines how much of resource \( R_a \) consumed by \( C_i \) is leaked into resource \( R_b \). 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_b l^i_{ab}) \) 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.
Effective Lotka-Volterra (ELV) model#
The effective pairwise species interactions are the coefficients of the effective LV (ELV) system of the Consumer-Resource Model, where the ELV is as follows:
The effective interaction \(\alpha_{ij}\) and growth rate \(r_i\) coefficients can be shown to be:
Reference#
Species packing and competitive equilibrium for many species
A minimal model for microbial biodiversity can reproduce experimentally observed ecological patterns
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
# Define model parameters
params = {
# Resource growth rate
'r1': 1.0,
'r2': 1.2,
# Environmental carrying capacity
'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], # Predation rate of consumer 1 on resource 1 and resource 2
[0.01, 0.02] # Predation rate of consumer 2 on resource 1 and resource 2
]),
# Resource conversion efficiency matrix w[i,j] represents the efficiency of consumer i converting resource j into its own biomass
'w': np.array([
[0.5, 0.3], # Conversion efficiency of consumer 1 on resource 1 and resource 2
[0.3, 0.5] # Conversion efficiency of consumer 2 on resource 1 and resource 2
]),
# Consumer mortality rate
'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 abundance of resource 1
R2_0 = 60.0 # Initial abundance of resource 2
C1_0 = 10.0 # Initial abundance of consumer 1
C2_0 = 12.0 # Initial abundance of consumer 2
state0 = [R1_0, R2_0, C1_0, C2_0]
# Solve the differential equations
solution = odeint(model, state0, t, args=(params,))
# Extract results
R1, R2, C1, C2 = solution.T
# Plot the dynamics of resources and consumer species
plt.figure(figsize=(12, 6))
# Consumer dynamics
plt.plot(t, C1, label='Consumer 1 (C1)')
plt.plot(t, C2, label='Consumer 2 (C2)')
plt.xlabel('Time')
plt.ylabel('Consumer Abundance')
plt.title('Consumer Dynamics')
plt.legend()
plt.tight_layout()
plt.show()
# Calculate effective interaction coefficients alpha_ij and maximum growth rates r_i
def calculate_effective_coefficients(params, R1_eq, R2_eq):
"""
Calculate effective interaction coefficients alpha_ij and maximum growth rates r_i
"""
# Compute partial derivatives of resources with respect to consumers
dR1_dC1 = -params['K1'] * params['a'][0,0] / params['r1']
dR1_dC2 = -params['K1'] * params['a'][1,0] / params['r1']
dR2_dC1 = -params['K2'] * params['a'][0,1] / params['r2']
dR2_dC2 = -params['K2'] * params['a'][1,1] / params['r2']
# Compute alpha_ij
alpha_11 = params['w'][0,0] * params['a'][0,0] * dR1_dC1 + params['w'][0,1] * params['a'][0,1] * dR2_dC1
alpha_12 = params['w'][0,0] * params['a'][0,0] * dR1_dC2 + params['w'][0,1] * params['a'][0,1] * dR2_dC2
alpha_21 = params['w'][1,0] * params['a'][1,0] * dR1_dC1 + params['w'][1,1] * params['a'][1,1] * dR2_dC1
alpha_22 = params['w'][1,0] * params['a'][1,0] * dR1_dC2 + params['w'][1,1] * params['a'][1,1] * dR2_dC2
# Compute r_i
r1 = params['w'][0,0] * params['a'][0,0] * R1_eq + params['w'][0,1] * params['a'][0,1] * R2_eq - params['m1']
r2 = params['w'][1,0] * params['a'][1,0] * R1_eq + params['w'][1,1] * params['a'][1,1] * R2_eq - params['m2']
return {
'alpha': np.array([[alpha_11, alpha_12], [alpha_21, alpha_22]]),
'r': np.array([r1, r2])
}
# Compute equilibrium resource abundance
R1_eq = params['K1'] * (1 - (params['a'][0,0] * C1[-1] + params['a'][1,0] * C2[-1]) / params['r1'])
R2_eq = params['K2'] * (1 - (params['a'][0,1] * C1[-1] + params['a'][1,1] * C2[-1]) / params['r2'])
# Compute effective interaction coefficients and maximum growth rates
effective_coefficients = calculate_effective_coefficients(params, R1_eq, R2_eq)
# Output results
print("Effective Interaction Coefficients (alpha_ij):")
print(effective_coefficients['alpha'])
print("\nMaximum Growth Rates (r_i):")
print(effective_coefficients['r'])