Skip to content
This repository has been archived by the owner on Jun 23, 2023. It is now read-only.

Quantitative descriptors #159

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
# EcologicalNetworks.jl

This `julia` package provides a common interface to analyze all types of data
on ecological networks. It is designed to be general, easy to expand, and work
on bipartite/unipartite as well as deterministic/quantitative/probabilistic
networks. The current version is compatible with `julia` version 1.0 and 0.7.
This `julia` package provides a common interface to analyze all types of data on
ecological networks. It is designed to be general, easy to expand, and work on
bipartite/unipartite as well as deterministic/quantitative/probabilistic
networks. The current version is compatible with `julia` version 1.0.

[![](https://img.shields.io/badge/docs-stable-blue.svg)](https://ecojulia.github.io/EcologicalNetworks.jl/stable)
[![](https://img.shields.io/badge/docs-dev-orange.svg)](https://ecojulia.github.io/EcologicalNetworks.jl/dev)

There is a short bibliography of the methods in the [package
documentation][pdocref], and in the documentations of each function.

[pdocref]: http://poisotlab.io/EcologicalNetworks.jl/latest/#references

## Getting started

Install (from the package mode):
Expand All @@ -25,6 +30,7 @@ add EcologicalNetworksPlots
That's it. Now head over to the
[documentation](http://EcoJulia.github.io/EcologicalNetworks.jl/stable/).


## How's the code doing?

### Released version
Expand Down
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ makedocs(
"Nestedness" => "properties/nestedness.md",
"Motifs" => "properties/motifs.md",
"Centrality and paths" => "properties/paths.md",
"Food webs" => "properties/foodwebs.md",
"Overlap and similarity" => "properties/overlap.md",
"Beta-diversity" => "properties/betadiversity.md",
"Resilience" => "properties/resilience.md",
Expand Down
16 changes: 16 additions & 0 deletions docs/src/properties/foodwebs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Food web measures

## Food chain length

```@docs
trophic_level
fractional_trophic_level
```

## Quantitative measures

```@docs
flow_diversity
equivalent_degree
positional_index
```
2 changes: 2 additions & 0 deletions docs/src/properties/links.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ sum
links
connectance
linkage_density
generality
vulnerability
```

## Degree
Expand Down
70 changes: 37 additions & 33 deletions src/EcologicalNetworks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -51,69 +51,69 @@ function __init__()
end

# General useful manipulations
include(joinpath(".", "types/utilities.jl"))
include(joinpath(".", "types/comparisons.jl"))
include(joinpath(".", "types/iteration.jl"))
include(joinpath(".", "types", "utilities.jl"))
include(joinpath(".", "types", "comparisons.jl"))
include(joinpath(".", "types", "iteration.jl"))
export species, interactions, has_interaction, richness, nodiagonal, nodiagonal!

# Degree
include(joinpath(".", "links/degree.jl"))
export degree, degree_var
include(joinpath(".", "links", "degree.jl"))
export degree, degree_var, generality, vulnerability

include(joinpath(".", "links/specificity.jl"))
include(joinpath(".", "links", "specificity.jl"))
export specificity

include(joinpath(".", "links/connectance.jl"))
include(joinpath(".", "links", "connectance.jl"))
export links, L, links_var, connectance, connectance_var,
linkage_density, link_number

include(joinpath(".", "links/degenerate.jl"))
include(joinpath(".", "links", "degenerate.jl"))
export isdegenerate, simplify, simplify!
#, species_has_no_successors, species_has_no_predecessors,
#species_is_free, free_species

# Random networks and permutations
include(joinpath(".", "rand/draws.jl"))
include(joinpath(".", "rand/sample.jl"))
include(joinpath(".", "rand", "draws.jl"))
include(joinpath(".", "rand", "sample.jl"))
export sample
include(joinpath(".", "rand/shuffle.jl"))
include(joinpath(".", "rand/null.jl"))
include(joinpath(".", "rand/linfilter.jl"))
include(joinpath(".", "rand", "shuffle.jl"))
include(joinpath(".", "rand", "null.jl"))
include(joinpath(".", "rand", "linfilter.jl"))
export linearfilter, linearfilterzoo
export null1, null2, null3, null4

# Random networks from structural models
include(joinpath(".", "structuralmodels/cascademodel.jl"))
include(joinpath(".", "structuralmodels", "cascademodel.jl"))
export cascademodel
include(joinpath(".", "structuralmodels/mpnmodel.jl"))
include(joinpath(".", "structuralmodels", "mpnmodel.jl"))
export mpnmodel
include(joinpath(".", "structuralmodels/nestedhierarchymodel.jl"))
include(joinpath(".", "structuralmodels", "nestedhierarchymodel.jl"))
export nestedhierarchymodel
include(joinpath(".", "structuralmodels/nichemodel.jl"))
include(joinpath(".", "structuralmodels", "nichemodel.jl"))
export nichemodel

# Nestedness
include(joinpath(".", "community/nestedness.jl"))
include(joinpath(".", "community", "nestedness.jl"))
export η, nodf

# Spectral radius
include(joinpath(".", "community/spectralradius.jl"))
export ρ

# Paths
include(joinpath(".", "community/paths.jl"))
include(joinpath(".", "community", "paths.jl"))
export number_of_paths, shortest_path, bellman_ford, dijkstra

# Centrality
include(joinpath(".", "community/centrality.jl"))
include(joinpath(".", "community", "centrality.jl"))
export centrality_katz, centrality_closeness, centrality_degree

# Motifs
include(joinpath(".", "community/motifs.jl"))
include(joinpath(".", "community", "motifs.jl"))
export find_motif, expected_motif_count, unipartitemotifs

# Overlap
include(joinpath(".", "community/overlap.jl"))
include(joinpath(".", "community", "overlap.jl"))
export overlap
export AJS, EAJS

Expand All @@ -125,39 +125,43 @@ export s
export σ_in, σ_out

# Modularity
include(joinpath(".", "modularity/utilities.jl"))
include(joinpath(".", "modularity", "utilities.jl"))
export Q, Qr

include(joinpath(".", "modularity/labelpropagation.jl"))
include(joinpath(".", "modularity", "labelpropagation.jl"))
export lp, salp

include(joinpath(".", "modularity/starters.jl"))
include(joinpath(".", "modularity", "starters.jl"))
export n_random_modules, each_species_its_module

include(joinpath(".", "modularity/brim.jl"))
include(joinpath(".", "modularity", "brim.jl"))
export brim

include(joinpath(".", "modularity/roles.jl"))
include(joinpath(".", "modularity", "roles.jl"))
export functional_cartography

# Beta-diversity
include(joinpath(".", "betadiversity/operations.jl"))
include(joinpath(".", "betadiversity/partitions.jl"))
include(joinpath(".", "betadiversity", "operations.jl"))
include(joinpath(".", "betadiversity", "partitions.jl"))
export βs, βos, βwn

include(joinpath(".", "betadiversity/measures.jl"))
include(joinpath(".", "betadiversity", "measures.jl"))
export KGL01, KGL02, KGL03, KGL04, KGL05, KGL06, KGL07, KGL08, KGL09, KGL10,
KGL11, KGL12, KGL13, KGL14, KGL15, KGL16, KGL17, KGL18, KGL19, KGL20, KGL21,
KGL22, KGL23, KGL24

# Food webs
include(joinpath(".", "foodwebs/trophiclevels.jl"))
include(joinpath(".", "foodwebs", "trophiclevels.jl"))
export fractional_trophic_level, trophic_level

include(joinpath(".", "foodwebs/omnivory.jl"))
include(joinpath(".", "foodwebs", "omnivory.jl"))
export omnivory

include(joinpath(".", "information/entropy.jl"))
include(joinpath(".", "quantitative", "bersier2002.jl"))
export flow_diversity, equivalent_degree, positional_index

# Information theory and entropy
include(joinpath(".", "information", "entropy.jl"))
export entropy, make_joint_distribution, mutual_information, conditional_entropy,
variation_information, diff_entropy_uniform, information_decomposition,
convert2effective, potential_information
Expand Down
77 changes: 77 additions & 0 deletions src/links/degree.jl
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,80 @@ function degree_var(N::ProbabilisticNetwork; dims::Union{Nothing,Integer}=nothin
end
throw(ArgumentError("dims can only be 1 (out-degre) or 2 (in-degree) or `nothing` (both), you used $(dims)"))
end

"""
basal_intermediate_top(N::T) where {T <: DeterministicNetwork}}

Counts the number of basal, intermediate, and top species in a unipartite
network.
"""
function basal_intermediate_top(N::T) where {T <: DeterministicNetwork}
@assert !isdegenerate(N)
b = 0
i = 0
t = 0
d_in = degree(N; dims=2)
d_out = degree(N; dims=1)
for s in species(N)
if d_in[s] == 0
t = t + 1
elseif d_out[s] == 0
b = b + 1
else
i = i + 1
end
end
return (b, i, t)
end

"""
generality(N::T) where {T <: DeterministicNetwork}

Average number of consumees per species. By default, this measures the
*unscaled* version of Schoener. Using the keyword `scaled` can alternatively
measure the *scaled* version of Williams & Martinez, in which the values are
between 0 and 1, thereby allowing comparison between networks of different
sizes.

#### References

Schoener, T.W., 1989. Food webs from the small to the large. Ecology 70,
1559–1589.

Williams, R., Martinez, N., 2000. Simple rules yield complex food webs. Nature
404, 180–183.
"""
function generality(N::T; scaled::Bool=false) where {T <: DeterministicNetwork}
if !scaled
b, i, t = basal_intermediate_top(N)
return links(N)/(t+i)
else
return 1.0/(links(N)/richness(N))*sum(collect(values(degree(N; dims=1))))
end
end

"""
vulnerability(N::T) where {T <: DeterministicNetwork}

Average number of consumers per species. By default, this measures the
*unscaled* version of Schoener. Using the keyword `scaled` can alternatively
measure the *scaled* version of Williams & Martinez, in which the values are
between 0 and 1, thereby allowing comparison between networks of different
sizes.

#### References

Schoener, T.W., 1989. Food webs from the small to the large. Ecology 70,
1559–1589.

Williams, R., Martinez, N., 2000. Simple rules yield complex food webs. Nature
404, 180–183.
"""
function vulnerability(N::T; scaled::Bool=false) where {T <: DeterministicNetwork}
if !scaled
b, i, t = basal_intermediate_top(N)
return links(N)/(b+t)
else
return 1.0/(links(N)/richness(N))*sum(collect(values(degree(N; dims=2))))
end
end
68 changes: 68 additions & 0 deletions src/quantitative/bersier2002.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""
flow_diversity(N::T; dims::Integer=1) where {T <: UnipartiteQuantitativeNetwork}

TODO

#### References

Bersier, L.F., Banašek-Richter, C., Cattin, M.-F., 2002. Quantitative
descriptors of food-web matrices. Ecology 83, 2394–2407.
"""
function flow_diversity(N::T; dims::Integer=1) where {T <: UnipartiteQuantitativeNetwork}
@assert dims ∈ [1,2]
odims = dims == 2 ? 1 : 2
@warn "UNTESTED"
b = N.A ./ sum(N; dims=odims)
for i in eachindex(b)
if isnan(b[i])
b[i] = zero(eltype(b))
end
end
info = b .* log.(2.0, b)
for i in eachindex(info)
if isnan(info[i])
info[i] = zero(eltype(info))
end
end
return Dict(zip(species(N), vec(abs.(sum(info; dims=odims)))))
end

"""
equivalent_degree(N::T; dims::Integer=1) where {T <: UnipartiteQuantitativeNetwork}

TODO

#### References

Bersier, L.F., Banašek-Richter, C., Cattin, M.-F., 2002. Quantitative
descriptors of food-web matrices. Ecology 83, 2394–2407.
"""
function equivalent_degree(N::T; dims::Integer=1) where {T <: UnipartiteQuantitativeNetwork}
@assert dims ∈ [1,2]
@warn "UNTESTED"
odims = dims == 2 ? 1 : 2
d = degree(N; dims=dims)
f = flow_diversity(N; dims=dims)
nxk = Dict([s => d[s] == 0 ? 0.0 : 2.0^f[s] for s in species(N)])
return nxk
end

"""
positional_index(N::T; weighted=false) where {T <: UnipartiteQuantitativeNetwork}

#### References

Bersier, L.F., Banašek-Richter, C., Cattin, M.-F., 2002. Quantitative
descriptors of food-web matrices. Ecology 83, 2394–2407.
"""
function positional_index(N::T; weighted=false) where {T <: UnipartiteQuantitativeNetwork}
nnk = equivalent_degree(N; dims=2)
npk = equivalent_degree(N; dims=1)
if !weighted
return Dict([s => nnk[s]/(nnk[s]+npk[s]) for s in species(N)])
else
s1 = sum(N; dims=1)
s2 = sum(N; dims=2)
return Dict([s => (s2[i]*nnk[s])/(s2[i]*nnk[s]+s1[i]*npk[s]) for (i,s) in enumerate(species(N))])
end
end
6 changes: 3 additions & 3 deletions src/rand/null.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Given a network `N`, `null1(N)` returns a network with the same dimensions, wher
every interaction happens with a probability equal to the connectance of `N`.

Note that this does not guarantee that the network is not degenerate, so the
output of this analysis *should* be filtered using `is_degenerate`, or passed to
output of this analysis *should* be filtered using `isdegenerate`, or passed to
`simplify`. The output of this approach is *always* a probabilistic network of
the same partiteness as the original network.

Expand All @@ -28,7 +28,7 @@ where every interaction happens with a probability equal to the out-degree
species, divided by the total number of possible predecessors/successors.

Note that this does not guarantee that the network is not degenerate, so the
output of this analysis *should* be filtered using `is_degenerate`, or passed to
output of this analysis *should* be filtered using `isdegenerate`, or passed to
`simplify`. The output of this approach is *always* a probabilistic network of
the same partiteness as the original network.

Expand All @@ -52,7 +52,7 @@ every interaction happens with a probability equal to the degree of each
species.

Note that this does not guarantee that the network is not degenerate, so the
output of this analysis *should* be filtered using `is_degenerate`, or passed to
output of this analysis *should* be filtered using `isdegenerate`, or passed to
`simplify`. The output of this approach is *always* a probabilistic network of
the same partiteness as the original network.

Expand Down
2 changes: 2 additions & 0 deletions test/data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@ module TestData

p = pajek()
@test typeof(p[:Chesapeake]) <: UnipartiteQuantitativeNetwork
@test richness(p[:ChesMiddle]) == 37
@test richness(p[:Florida]) == 128

end
Loading