Generate Food Webs
Food webs are at the core of this package, and thus can be generated in various ways depending on your needs. In the following sections, we will go over the different methods of network generation. But, first things first, let us see what is inside a Foodweb.
A Foodweb object contains the trophic adjacency matrix A filled with 0s and 1s indicating respectively the absence and presence of trophic interactions. Rows are consumers and columns resources, thus A[i,j] = 1 reads "species i eats species j"
From an Adjacency Matrix
The most straightforward way to generate a Foodweb is to define your own adjacency matrix (A) by hand and give it to the Foodweb method that will return the corresponding Foodweb object.
A = [0 0 0; 1 0 0; 0 1 0] # 1 <- 2 <- 3.
foodweb = Foodweb(A)blueprint for <Foodweb>: Matrix {
A: 3×3 sparse matrix with 2 values (true),
species: <implied blueprint for <Species>>,
}From an Adjacency List
Sometimes it is more convenient to define the food web using an adjacency list, because adjacency lists are often more readable than adjacency matrices. Adjacency lists are a list of pairs, where each pair is a consumer-resource interaction.
For instance, the food web presented in the previous example can be defined as:
list = [2 => 1, 3 => 2]
foodweb = Foodweb(list)blueprint for <Foodweb>: Adjacency {
A: {2: {1}, 3: {2}},
species: <implied blueprint for <Species>>,
}Species can also be named with strings or symbols:
list = [:eagle => :rabbit, :rabbit => :grass]
foodweb = Foodweb(list)blueprint for <Foodweb>: Adjacency {
A: {eagle: {rabbit}, rabbit: {grass}},
species: <implied blueprint for <Species>>,
}Creating a Foodweb from your own adjacency matrix or list is straightforward, but this is mostly useful for simple and small 'toy systems'. If you want to work with Foodwebs with a large size and a realistic structure, it is more suitable to create the Foodweb using structural models.
Structural Models
You can generate a Foodweb using either the niche model or the cascade model.
Niche Model
The niche model requires:
S: Number of species.- Either
C(connectance) orL(number of links).
fw1 = Foodweb(:niche; S = 5, C = 0.2)
fw2 = Foodweb(:niche; S = 5, L = 5)blueprint for <Foodweb>: Matrix {
A: 5×5 sparse matrix with 5 values (true),
species: <implied blueprint for <Species>>,
}Cascade Model
The cascade model requires:
S: Number of species.C: Connectance.
fw3 = Foodweb(:cascade; S = 5, C = 0.2)blueprint for <Foodweb>: Matrix {
A: 5×5 sparse matrix with 5 values (true),
species: <implied blueprint for <Species>>,
}Tolerance and Constraints
By default, the generated Foodweb ensures the number of links (L) or connectance (C) falls within a 10% tolerance of the specified value:
- If
L = 20, the output will have 18–22 links. - If
Cis given, the tolerance is similarly applied to the connectance.
Example: Default Tolerance
fw4 = Foodweb(:niche; S = 15, L = 15)
13 <= sum(fw4.A) <= 18 # 15 links ±10% (rounded)trueCustom Tolerance
Override defaults with tol_L (for L) or tol_C (for C):
fw5 = Foodweb(:niche; S = 15, L = 15, tol_L = 0) # Strictly 15 links
sum(fw5.A) == 15trueAdvanced Control
Trophic Structure Validation
By default, the model:
- Rejects disconnected species (
reject_if_disconnected = true). - Allows cycles (
reject_cycles = false; e.g., cannibalism).
Options:
fw6 = Foodweb(:niche; S = 15, L = 15, reject_cycles = false) # Allow cycles
fw7 = Foodweb(:niche; S = 15, L = 15, reject_if_disconnected = false) # Allow disconnected speciesblueprint for <Foodweb>: Matrix {
A: 15×15 sparse matrix with 17 values (true),
species: <implied blueprint for <Species>>,
}Algorithm Iterations
The default maximum iterations (10^5) can be increased for challenging parameter combinations (e.g., near boundary conditions or strict tolerances):
fw8 = Foodweb(:niche; S = 15, L = 15, max_iterations = 10^6)blueprint for <Foodweb>: Matrix {
A: 15×15 sparse matrix with 17 values (true),
species: <implied blueprint for <Species>>,
}