From 7956b10e546fe49147191a95df6c6f08dbe939a4 Mon Sep 17 00:00:00 2001 From: michielstock Date: Fri, 5 Apr 2019 17:53:23 +0200 Subject: [PATCH 1/7] :tada: basics methods for network resilience --- src/community/resilience.jl | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/community/resilience.jl diff --git a/src/community/resilience.jl b/src/community/resilience.jl new file mode 100644 index 000000000..24dd98c99 --- /dev/null +++ b/src/community/resilience.jl @@ -0,0 +1,21 @@ +#= +Some functions from *Universal resilience patterns in complex networks* +by Gao et al. (2016) +=# + +using Statistics: mean, std + +# TODO : AbstractUnipartiteNetwork as type + +s_in(N::UnipartiteNetwork) = mean(N.A, dims=2) +s_out(N::UnipartiteNetwork) = mean(N.A, dims=1)' +s_mean(N::UnipartiteNetwork) = mean(N.A) + +σ_in(N::UnipartiteNetwork) = std(s_in(N)) +σ_out(N::UnipartiteNetwork) = std(s_out(N)) + +symmetry(N::UnipartiteNetwork) = (mean(s_in(N) .* s_in(N)) - mean(s_in(N)) * mean(s_out(N))) / (σ_in(N)*σ_out(N)) +heterogenity(N::UnipartiteNetwork) = σ_in(N) * σ_out(N) / s_mean(N) + +βeff(N::UnipartiteNetwork) = mean(s_in(N) .* s_out(N)) / s_mean(N) +resilience(N) = βeff(N) From f296e9414f0bf851afb53dc49cdf3ce526ab4ea0 Mon Sep 17 00:00:00 2001 From: michielstock Date: Wed, 10 Apr 2019 14:16:56 +0200 Subject: [PATCH 2/7] :construction: development of resilience indices. --- src/community/resilience.jl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/community/resilience.jl b/src/community/resilience.jl index 24dd98c99..ebff12c72 100644 --- a/src/community/resilience.jl +++ b/src/community/resilience.jl @@ -14,8 +14,12 @@ s_mean(N::UnipartiteNetwork) = mean(N.A) σ_in(N::UnipartiteNetwork) = std(s_in(N)) σ_out(N::UnipartiteNetwork) = std(s_out(N)) -symmetry(N::UnipartiteNetwork) = (mean(s_in(N) .* s_in(N)) - mean(s_in(N)) * mean(s_out(N))) / (σ_in(N)*σ_out(N)) -heterogenity(N::UnipartiteNetwork) = σ_in(N) * σ_out(N) / s_mean(N) +# symmetry computed wrongly in paper? +symmetry(N::UnipartiteNetwork) = -(mean(s_in(N) .* s_in(N)) - mean(s_in(N)) * mean(s_out(N))) / (σ_in(N) * σ_out(N)) +heterogenity(N::UnipartiteNetwork) = (σ_in(N) * σ_out(N)) / s_mean(N) βeff(N::UnipartiteNetwork) = mean(s_in(N) .* s_out(N)) / s_mean(N) resilience(N) = βeff(N) + +# check if βeff = sum(A *s_in) / sum(A) +# and βeff = + HS From 93800649d25e3a04827a096a4ce632173d28ebcf Mon Sep 17 00:00:00 2001 From: michielstock Date: Wed, 1 May 2019 18:41:58 +0200 Subject: [PATCH 3/7] :wrench: finishing resilience code + UT --- Manifest.toml | 14 +++++++------- Project.toml | 1 + src/EcologicalNetworks.jl | 7 +++++++ src/community/resilience.jl | 22 ++++++++++------------ test/runtests.jl | 1 + 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 98ba49a7a..380b90763 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -16,10 +16,10 @@ uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" version = "0.8.10" [[BinaryProvider]] -deps = ["Libdl", "Pkg", "SHA", "Test"] -git-tree-sha1 = "055eb2690182ebc31087859c3dd8598371d3ef9e" +deps = ["Libdl", "SHA"] +git-tree-sha1 = "c7361ce8a2129f20b0e05a89f7070820cfed6648" uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" -version = "0.5.3" +version = "0.5.4" [[Combinatorics]] deps = ["LinearAlgebra", "Polynomials", "Test"] @@ -89,15 +89,15 @@ uuid = "a63ad114-7e13-5084-954f-fe012c677804" [[OrderedCollections]] deps = ["Random", "Serialization", "Test"] -git-tree-sha1 = "85619a3f3e17bb4761fe1b1fd47f0e979f964d5b" +git-tree-sha1 = "c4c13474d23c60d20a67b217f1d7f22a40edf8f1" uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.0.2" +version = "1.1.0" [[PDMats]] deps = ["Arpack", "LinearAlgebra", "SparseArrays", "SuiteSparse", "Test"] -git-tree-sha1 = "b6c91fc0ab970c0563cbbe69af18d741a49ce551" +git-tree-sha1 = "8b68513175b2dc4023a564cb0e917ce90e74fd69" uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.9.6" +version = "0.9.7" [[Pkg]] deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] diff --git a/Project.toml b/Project.toml index 2f4a480af..cfe4c6eb6 100644 --- a/Project.toml +++ b/Project.toml @@ -11,6 +11,7 @@ Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/src/EcologicalNetworks.jl b/src/EcologicalNetworks.jl index 3442b5a54..6683a9751 100644 --- a/src/EcologicalNetworks.jl +++ b/src/EcologicalNetworks.jl @@ -102,6 +102,13 @@ include(joinpath(".", "community/overlap.jl")) export overlap export AJS, EAJS +# Overlap +include(joinpath(".", "community/resilience.jl")) +export βeff, resilience +export symmetry, heterogenity +export s_in, s_out, s_mean +export σ_in, σ_out + # Modularity include(joinpath(".", "modularity/utilities.jl")) export Q, Qr diff --git a/src/community/resilience.jl b/src/community/resilience.jl index ebff12c72..63034aeaa 100644 --- a/src/community/resilience.jl +++ b/src/community/resilience.jl @@ -3,23 +3,21 @@ Some functions from *Universal resilience patterns in complex networks* by Gao et al. (2016) =# -using Statistics: mean, std +using StatsBase: mean, std -# TODO : AbstractUnipartiteNetwork as type +s_in(N::AbstractUnipartiteNetwork) = sum(N.A, dims=2) +s_out(N::AbstractUnipartiteNetwork) = sum(N.A, dims=1)' +s_mean(N::AbstractUnipartiteNetwork) = sum(N.A) / size(N.A, 1) -s_in(N::UnipartiteNetwork) = mean(N.A, dims=2) -s_out(N::UnipartiteNetwork) = mean(N.A, dims=1)' -s_mean(N::UnipartiteNetwork) = mean(N.A) - -σ_in(N::UnipartiteNetwork) = std(s_in(N)) -σ_out(N::UnipartiteNetwork) = std(s_out(N)) +σ_in(N::AbstractUnipartiteNetwork) = std(s_in(N), corrected=false) +σ_out(N::AbstractUnipartiteNetwork) = std(s_out(N), corrected=false) # symmetry computed wrongly in paper? -symmetry(N::UnipartiteNetwork) = -(mean(s_in(N) .* s_in(N)) - mean(s_in(N)) * mean(s_out(N))) / (σ_in(N) * σ_out(N)) -heterogenity(N::UnipartiteNetwork) = (σ_in(N) * σ_out(N)) / s_mean(N) +symmetry(N::AbstractUnipartiteNetwork) = (mean(s_in(N) .* s_out(N)) - mean(s_in(N)) * mean(s_out(N))) / (σ_in(N) * σ_out(N)) +heterogenity(N::AbstractUnipartiteNetwork) = (σ_in(N) * σ_out(N)) / s_mean(N) -βeff(N::UnipartiteNetwork) = mean(s_in(N) .* s_out(N)) / s_mean(N) -resilience(N) = βeff(N) +βeff(N::AbstractUnipartiteNetwork) = dot(s_in(N), s_out(N)) / sum(N.A) +resilience(N::AbstractUnipartiteNetwork) = βeff(N) # check if βeff = sum(A *s_in) / sum(A) # and βeff = + HS diff --git a/test/runtests.jl b/test/runtests.jl index f40afcfd2..55922882d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -25,6 +25,7 @@ my_tests = [ "community/centrality.jl", "community/motifs.jl", "community/foodwebs.jl", + "community/resilience.jl", "betadiversity/operations.jl", "betadiversity/partitions.jl", "modularity/utilities.jl", From 9fabffaa1fe17e3a75d9f4394d4ffff25b0bdf5d Mon Sep 17 00:00:00 2001 From: michielstock Date: Mon, 6 May 2019 18:19:08 +0200 Subject: [PATCH 4/7] :pencil2: documentation --- docs/make.jl | 3 +- docs/src/properties/resilience.md | 53 ++++++++++++++++++++ src/community/resilience.jl | 80 +++++++++++++++++++++++++++++-- test/community/resilience.jl | 42 ++++++++++++++++ 4 files changed, 173 insertions(+), 5 deletions(-) create mode 100644 docs/src/properties/resilience.md create mode 100644 test/community/resilience.jl diff --git a/docs/make.jl b/docs/make.jl index e9002ddf8..4c12ed509 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -26,7 +26,8 @@ makedocs( "Centrality and paths" => "properties/paths.md", "Overlap and similarity" => "properties/overlap.md", "Null models" => "properties/nullmodels.md", - "Beta-diversity" => "properties/betadiversity.md" + "Beta-diversity" => "properties/betadiversity.md", + "Resilience" => "properties/resilience.md" ] ] ) diff --git a/docs/src/properties/resilience.md b/docs/src/properties/resilience.md new file mode 100644 index 000000000..3e032839c --- /dev/null +++ b/docs/src/properties/resilience.md @@ -0,0 +1,53 @@ +# Resilience + +Species interaction networks provide the interactions of the individual species. +We provide the metrics proposed by Gao et al (2016) that summarize the global +behaviour of complex unipartite networks. The dynamics of a system of N components +(nodes/species) can follow the coupled nonlinear differential equation + +$$ +\frac{\text{d}x_i}{\text{d}t} = F(x_i) + \sum_{j=1}^N A_{ij}G(x_i, x_j) +$$ + +where the adjacency matrix $$A$$ captures the interaction between the components. + +This system can be descibed in 1-D using an effective term + +$$ +\frac{\text{d}x_\text{eff}}{\text{d}t} = F(x_\text{eff}) + \beta_\text{eff}G(x_\text{eff}, x_\text{eff}) +$$ + +with $$\beta_\text{eff}$$ a single resilience parameter which can capture +the effect of perturbating the system (node/link removal, weight change...). +This resience parameter can be computed from an `AbstractUnipartiteNetwork` +using the functions `βeff` or `resilience`. + +It can be shown that + +$$ +\beta_\text{eff} = \langle s \rangle + \mathcal{S} \mathcal{H}\,, +$$ + +with + +- $$\langle s \rangle$$ the average weighted degree (computed using `s_mean`), +- $$\mathcal{S}$$ the symmetry(computed using `symmetry`), +- $$\mathcal{H}$$ the heterogenity (computed using `heterogenity`). + + +> Goa, J., Barzael, B. and Barabási 2016. Universal resilience patterns in complex networks. +> Nature 530(7590), 307-312. doi:10.1038/nature16948 + +## Available functions + +```@docs +s_in +s_out +s_mean +σ_in +σ_out +symmetry +heterogenity +βeff +resilience +``` diff --git a/src/community/resilience.jl b/src/community/resilience.jl index 63034aeaa..ba30a6b6c 100644 --- a/src/community/resilience.jl +++ b/src/community/resilience.jl @@ -5,19 +5,91 @@ by Gao et al. (2016) using StatsBase: mean, std +""" + s_in(N::AbstractUnipartiteNetwork) + +Computes the vector of incoming weighted degrees of an unipartite network. +""" s_in(N::AbstractUnipartiteNetwork) = sum(N.A, dims=2) + +""" + s_out(N::AbstractUnipartiteNetwork) + +Computes the vector of outgoing weighted degrees of an unipartite network. +""" s_out(N::AbstractUnipartiteNetwork) = sum(N.A, dims=1)' + +""" + s_mean(N::AbstractUnipartiteNetwork) + +Computes the average weighted degree. This is proportional to the (weighted) +density of interactions. +""" s_mean(N::AbstractUnipartiteNetwork) = sum(N.A) / size(N.A, 1) +""" + σ_in(N::AbstractUnipartiteNetwork) + +Computes the standard deviation of the ingoing weighted degree of an unipartite +network. +""" σ_in(N::AbstractUnipartiteNetwork) = std(s_in(N), corrected=false) + +""" + σ_out(N::AbstractUnipartiteNetwork) + +Computes the standard deviation of the outgoing weighted degree of an unipartite +network. +""" σ_out(N::AbstractUnipartiteNetwork) = std(s_out(N), corrected=false) -# symmetry computed wrongly in paper? +""" + symmetry(N::AbstractUnipartiteNetwork) + +Computes the symmetry between s^in and s^out (the in- and outgoing weighted +degree of an unipartite network). This is computed as the Pearson correlation +between the s^in and s^out. It is hence a value between -1 and 1, where high +positive values indicate that species with many outgoing degrees also tend to have +many ingoing degrees and negative values mean the opposite. An undirected network +is perfectly symmetric but, for example, a food web where predators are less likely +to be prey would have a negative symmetry. + +> Goa, J., Barzael, B. and Barabási 2016. Universal resilience patterns in complex networks. +> Nature 530(7590), 307-312. doi:10.1038/nature16948 + +""" symmetry(N::AbstractUnipartiteNetwork) = (mean(s_in(N) .* s_out(N)) - mean(s_in(N)) * mean(s_out(N))) / (σ_in(N) * σ_out(N)) + +""" + heterogenity(N::AbstractUnipartiteNetwork) + +Computes the heterogenity for an unipartite network, a topological characteristic +which quantifies the difference in in- and outgoing degrees between species. It +is computed as σ_in * σ_out / s_mean. A value of 0 indicates that all species +have the same (weighted) in- and outdegrees. + +> Goa, J., Barzael, B. and Barabási 2016. Universal resilience patterns in complex networks. +> Nature 530(7590), 307-312. doi:10.1038/nature16948 + +""" heterogenity(N::AbstractUnipartiteNetwork) = (σ_in(N) * σ_out(N)) / s_mean(N) +""" + βeff(N::AbstractUnipartiteNetwork) + +A resilience parameters described by Gao et al. (2016). It is a global parameters +describing the dynamics of an unipartite network as an effective 1D equation of +the form + +f(xeff) = F(xeff) + βeff G(xeff, xeff) + +i.e. describing a second-order term representing the effect of the network on the +dynamics of the 'effective state' xeff of the system. + +> Goa, J., Barzael, B. and Barabási 2016. Universal resilience patterns in complex networks. +> Nature 530(7590), 307-312. doi:10.1038/nature16948 + +""" βeff(N::AbstractUnipartiteNetwork) = dot(s_in(N), s_out(N)) / sum(N.A) -resilience(N::AbstractUnipartiteNetwork) = βeff(N) -# check if βeff = sum(A *s_in) / sum(A) -# and βeff = + HS +resilience(N::AbstractUnipartiteNetwork) = βeff(N) diff --git a/test/community/resilience.jl b/test/community/resilience.jl new file mode 100644 index 000000000..b69fc6ad5 --- /dev/null +++ b/test/community/resilience.jl @@ -0,0 +1,42 @@ +module TestResilience + using Test, EcologicalNetworks + + A = rand([0, 1, 0.5], 10, 10) + N = UnipartiteQuantitativeNetwork(A) + + @assert s_mean(N) ≈ sum(A) / 10 + @assert s_in(N) ≈ sum(A, dims=2) + @assert s_out(N) ≈ sum(A, dims=1)' + + @assert βeff(N) ≈ s_mean(N) + symmetry(N) * heterogenity(N) + + # species only interact with themselves + Nid = UnipartiteNetwork([true false false false; + false true false false; + false false true false; + false false false true]) + + @assert heterogenity(Nid) ≈ 0.0 + # @assert symmetry(Nid) NAN + + # symetric network + Nsym = UnipartiteNetwork([false true true true; + true false false false; + true false false false; + true false false false]) + @assert symmetry(Nsym) ≈ 1.0 # in- and out degree is same + @assert heterogenity(Nsym) ≈ 0.5 + + + # asymetric network + Nasym = UnipartiteNetwork([false true true true; + false false false false; + false false false false; + false false false false]) + @assert symmetry(Nasym) ≈ -1.0 # in- and out degree is same + @assert heterogenity(Nasym) ≈ 0.75 + + v = ones(10) / 10 + Nhomo = UnipartiteProbabilisticNetwork(v * v') + @assert isapprox(heterogenity(Nhomo), 0.0, atol=1e-10) +end From c9d1076061f4a9e784ea9cdb2c48618f4b4caa39 Mon Sep 17 00:00:00 2001 From: michielstock Date: Mon, 6 May 2019 18:26:08 +0200 Subject: [PATCH 5/7] :pencil2: typo in docstring --- docs/src/properties/resilience.md | 3 +-- src/community/resilience.jl | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/docs/src/properties/resilience.md b/docs/src/properties/resilience.md index 3e032839c..1ae1698de 100644 --- a/docs/src/properties/resilience.md +++ b/docs/src/properties/resilience.md @@ -1,7 +1,6 @@ # Resilience -Species interaction networks provide the interactions of the individual species. -We provide the metrics proposed by Gao et al (2016) that summarize the global +We provide the metrics proposed by Gao et al (2016) which summarize the global behaviour of complex unipartite networks. The dynamics of a system of N components (nodes/species) can follow the coupled nonlinear differential equation diff --git a/src/community/resilience.jl b/src/community/resilience.jl index ba30a6b6c..1ca513f42 100644 --- a/src/community/resilience.jl +++ b/src/community/resilience.jl @@ -49,7 +49,7 @@ network. Computes the symmetry between s^in and s^out (the in- and outgoing weighted degree of an unipartite network). This is computed as the Pearson correlation between the s^in and s^out. It is hence a value between -1 and 1, where high -positive values indicate that species with many outgoing degrees also tend to have +positive values indicate that species with many outgoing degrees tend to have many ingoing degrees and negative values mean the opposite. An undirected network is perfectly symmetric but, for example, a food web where predators are less likely to be prey would have a negative symmetry. @@ -92,4 +92,20 @@ dynamics of the 'effective state' xeff of the system. """ βeff(N::AbstractUnipartiteNetwork) = dot(s_in(N), s_out(N)) / sum(N.A) +""" + resilience(N::AbstractUnipartiteNetwork) + +A resilience parameters described by Gao et al. (2016). It is a global parameters +describing the dynamics of an unipartite network as an effective 1D equation of +the form + +f(xeff) = F(xeff) + βeff G(xeff, xeff) + +i.e. describing a second-order term representing the effect of the network on the +dynamics of the 'effective state' xeff of the system. + +> Goa, J., Barzael, B. and Barabási 2016. Universal resilience patterns in complex networks. +> Nature 530(7590), 307-312. doi:10.1038/nature16948 + +""" resilience(N::AbstractUnipartiteNetwork) = βeff(N) From 4a121ee609104d83596d0c93354e3365bb9f5b36 Mon Sep 17 00:00:00 2001 From: michielstock Date: Sun, 12 May 2019 16:47:15 +0200 Subject: [PATCH 6/7] :pencil2: typo function + general `s` --- docs/src/properties/resilience.md | 4 ++-- src/EcologicalNetworks.jl | 4 ++-- src/community/resilience.jl | 34 ++++++++++++++++++++----------- test/community/resilience.jl | 10 ++++----- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/docs/src/properties/resilience.md b/docs/src/properties/resilience.md index 1ae1698de..564726cb2 100644 --- a/docs/src/properties/resilience.md +++ b/docs/src/properties/resilience.md @@ -31,7 +31,7 @@ with - $$\langle s \rangle$$ the average weighted degree (computed using `s_mean`), - $$\mathcal{S}$$ the symmetry(computed using `symmetry`), -- $$\mathcal{H}$$ the heterogenity (computed using `heterogenity`). +- $$\mathcal{H}$$ the heterogeneity (computed using `heterogeneity`). > Goa, J., Barzael, B. and Barabási 2016. Universal resilience patterns in complex networks. @@ -46,7 +46,7 @@ s_mean σ_in σ_out symmetry -heterogenity +heterogeneity βeff resilience ``` diff --git a/src/EcologicalNetworks.jl b/src/EcologicalNetworks.jl index 5a563c4e3..a530ecf5b 100644 --- a/src/EcologicalNetworks.jl +++ b/src/EcologicalNetworks.jl @@ -111,8 +111,8 @@ export AJS, EAJS # Overlap include(joinpath(".", "community/resilience.jl")) export βeff, resilience -export symmetry, heterogenity -export s_in, s_out, s_mean +export symmetry, heterogeneity +export s export σ_in, σ_out # Modularity diff --git a/src/community/resilience.jl b/src/community/resilience.jl index 1ca513f42..b572424fa 100644 --- a/src/community/resilience.jl +++ b/src/community/resilience.jl @@ -3,10 +3,26 @@ Some functions from *Universal resilience patterns in complex networks* by Gao et al. (2016) =# -using StatsBase: mean, std +using Statistics: mean, std """ - s_in(N::AbstractUnipartiteNetwork) + s(N::AbstractUnipartiteNetwork; dims::Union{Nothing,Integer}=nothing) + +Computes the average weighted degree. This is proportional to the (weighted) +density of interactions. + +If dims is provided, the incoming (`dims=1`) or outgoing (`dims=2`) is computed. +""" +function s(N::AbstractUnipartiteNetwork; dims::Union{Nothing,Integer}=nothing) + dims == 1 && return sum(N, dims=2) + dims == 2 && return sum(N, dims=1)' + if dims == nothing + return sum(N) / size(N)[1] + end +end +#= +""" + s(N::AbstractUnipartiteNetwork; dims) Computes the vector of incoming weighted degrees of an unipartite network. """ @@ -19,13 +35,7 @@ Computes the vector of outgoing weighted degrees of an unipartite network. """ s_out(N::AbstractUnipartiteNetwork) = sum(N.A, dims=1)' -""" - s_mean(N::AbstractUnipartiteNetwork) - -Computes the average weighted degree. This is proportional to the (weighted) -density of interactions. -""" -s_mean(N::AbstractUnipartiteNetwork) = sum(N.A) / size(N.A, 1) +=# """ σ_in(N::AbstractUnipartiteNetwork) @@ -61,9 +71,9 @@ to be prey would have a negative symmetry. symmetry(N::AbstractUnipartiteNetwork) = (mean(s_in(N) .* s_out(N)) - mean(s_in(N)) * mean(s_out(N))) / (σ_in(N) * σ_out(N)) """ - heterogenity(N::AbstractUnipartiteNetwork) + heterogeneity(N::AbstractUnipartiteNetwork) -Computes the heterogenity for an unipartite network, a topological characteristic +Computes the heterogeneity for an unipartite network, a topological characteristic which quantifies the difference in in- and outgoing degrees between species. It is computed as σ_in * σ_out / s_mean. A value of 0 indicates that all species have the same (weighted) in- and outdegrees. @@ -72,7 +82,7 @@ have the same (weighted) in- and outdegrees. > Nature 530(7590), 307-312. doi:10.1038/nature16948 """ -heterogenity(N::AbstractUnipartiteNetwork) = (σ_in(N) * σ_out(N)) / s_mean(N) +heterogeneity(N::AbstractUnipartiteNetwork) = (σ_in(N) * σ_out(N)) / s_mean(N) """ βeff(N::AbstractUnipartiteNetwork) diff --git a/test/community/resilience.jl b/test/community/resilience.jl index b69fc6ad5..4018b40b9 100644 --- a/test/community/resilience.jl +++ b/test/community/resilience.jl @@ -8,7 +8,7 @@ module TestResilience @assert s_in(N) ≈ sum(A, dims=2) @assert s_out(N) ≈ sum(A, dims=1)' - @assert βeff(N) ≈ s_mean(N) + symmetry(N) * heterogenity(N) + @assert βeff(N) ≈ s_mean(N) + symmetry(N) * heterogeneity(N) # species only interact with themselves Nid = UnipartiteNetwork([true false false false; @@ -16,7 +16,7 @@ module TestResilience false false true false; false false false true]) - @assert heterogenity(Nid) ≈ 0.0 + @assert heterogeneity(Nid) ≈ 0.0 # @assert symmetry(Nid) NAN # symetric network @@ -25,7 +25,7 @@ module TestResilience true false false false; true false false false]) @assert symmetry(Nsym) ≈ 1.0 # in- and out degree is same - @assert heterogenity(Nsym) ≈ 0.5 + @assert heterogeneity(Nsym) ≈ 0.5 # asymetric network @@ -34,9 +34,9 @@ module TestResilience false false false false; false false false false]) @assert symmetry(Nasym) ≈ -1.0 # in- and out degree is same - @assert heterogenity(Nasym) ≈ 0.75 + @assert heterogeneity(Nasym) ≈ 0.75 v = ones(10) / 10 Nhomo = UnipartiteProbabilisticNetwork(v * v') - @assert isapprox(heterogenity(Nhomo), 0.0, atol=1e-10) + @assert isapprox(heterogeneity(Nhomo), 0.0, atol=1e-10) end From f7cf182dedff5f9d854d7915ba48f33e5976d275 Mon Sep 17 00:00:00 2001 From: michielstock Date: Sun, 12 May 2019 17:09:38 +0200 Subject: [PATCH 7/7] :wrench: dependency to `Statistics` + update tests --- Manifest.toml | 6 +++--- Project.toml | 1 + docs/src/properties/resilience.md | 5 +---- src/EcologicalNetworks.jl | 2 +- src/community/resilience.jl | 34 ++++++++----------------------- test/community/resilience.jl | 8 ++++---- 6 files changed, 18 insertions(+), 38 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index e43be206d..e48015ca6 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -79,10 +79,10 @@ deps = ["Base64"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" [[Missings]] -deps = ["Dates", "InteractiveUtils", "SparseArrays", "Test"] -git-tree-sha1 = "d1d2585677f2bd93a97cfeb8faa7a0de0f982042" +deps = ["SparseArrays", "Test"] +git-tree-sha1 = "f0719736664b4358aa9ec173077d4285775f8007" uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" -version = "0.4.0" +version = "0.4.1" [[Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" diff --git a/Project.toml b/Project.toml index dea7a45d0..644ec5d63 100644 --- a/Project.toml +++ b/Project.toml @@ -11,6 +11,7 @@ Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Requires = "ae029012-a4dd-5104-9daa-d747884805df" +Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/docs/src/properties/resilience.md b/docs/src/properties/resilience.md index 564726cb2..9e69e3199 100644 --- a/docs/src/properties/resilience.md +++ b/docs/src/properties/resilience.md @@ -40,13 +40,10 @@ with ## Available functions ```@docs -s_in -s_out -s_mean +s σ_in σ_out symmetry heterogeneity -βeff resilience ``` diff --git a/src/EcologicalNetworks.jl b/src/EcologicalNetworks.jl index a530ecf5b..4d7263425 100644 --- a/src/EcologicalNetworks.jl +++ b/src/EcologicalNetworks.jl @@ -110,7 +110,7 @@ export AJS, EAJS # Overlap include(joinpath(".", "community/resilience.jl")) -export βeff, resilience +export resilience export symmetry, heterogeneity export s export σ_in, σ_out diff --git a/src/community/resilience.jl b/src/community/resilience.jl index b572424fa..627b5e1e7 100644 --- a/src/community/resilience.jl +++ b/src/community/resilience.jl @@ -14,10 +14,10 @@ density of interactions. If dims is provided, the incoming (`dims=1`) or outgoing (`dims=2`) is computed. """ function s(N::AbstractUnipartiteNetwork; dims::Union{Nothing,Integer}=nothing) - dims == 1 && return sum(N, dims=2) - dims == 2 && return sum(N, dims=1)' + dims == 1 && return sum(N.A, dims=2) + dims == 2 && return sum(N.A, dims=1)' if dims == nothing - return sum(N) / size(N)[1] + return sum(N.A) / size(N)[1] end end #= @@ -43,7 +43,7 @@ s_out(N::AbstractUnipartiteNetwork) = sum(N.A, dims=1)' Computes the standard deviation of the ingoing weighted degree of an unipartite network. """ -σ_in(N::AbstractUnipartiteNetwork) = std(s_in(N), corrected=false) +σ_in(N::AbstractUnipartiteNetwork) = std(s(N, dims=1), corrected=false) """ σ_out(N::AbstractUnipartiteNetwork) @@ -51,7 +51,7 @@ network. Computes the standard deviation of the outgoing weighted degree of an unipartite network. """ -σ_out(N::AbstractUnipartiteNetwork) = std(s_out(N), corrected=false) +σ_out(N::AbstractUnipartiteNetwork) = std(s(N, dims=2), corrected=false) """ symmetry(N::AbstractUnipartiteNetwork) @@ -68,7 +68,7 @@ to be prey would have a negative symmetry. > Nature 530(7590), 307-312. doi:10.1038/nature16948 """ -symmetry(N::AbstractUnipartiteNetwork) = (mean(s_in(N) .* s_out(N)) - mean(s_in(N)) * mean(s_out(N))) / (σ_in(N) * σ_out(N)) +symmetry(N::AbstractUnipartiteNetwork) = (mean(s(N, dims=1) .* s(N, dims=2)) - mean(s(N, dims=1)) * mean(s(N, dims=2))) / (σ_in(N) * σ_out(N)) """ heterogeneity(N::AbstractUnipartiteNetwork) @@ -82,25 +82,7 @@ have the same (weighted) in- and outdegrees. > Nature 530(7590), 307-312. doi:10.1038/nature16948 """ -heterogeneity(N::AbstractUnipartiteNetwork) = (σ_in(N) * σ_out(N)) / s_mean(N) - -""" - βeff(N::AbstractUnipartiteNetwork) - -A resilience parameters described by Gao et al. (2016). It is a global parameters -describing the dynamics of an unipartite network as an effective 1D equation of -the form - -f(xeff) = F(xeff) + βeff G(xeff, xeff) - -i.e. describing a second-order term representing the effect of the network on the -dynamics of the 'effective state' xeff of the system. - -> Goa, J., Barzael, B. and Barabási 2016. Universal resilience patterns in complex networks. -> Nature 530(7590), 307-312. doi:10.1038/nature16948 - -""" -βeff(N::AbstractUnipartiteNetwork) = dot(s_in(N), s_out(N)) / sum(N.A) +heterogeneity(N::AbstractUnipartiteNetwork) = (σ_in(N) * σ_out(N)) / s(N) """ resilience(N::AbstractUnipartiteNetwork) @@ -118,4 +100,4 @@ dynamics of the 'effective state' xeff of the system. > Nature 530(7590), 307-312. doi:10.1038/nature16948 """ -resilience(N::AbstractUnipartiteNetwork) = βeff(N) +resilience(N::AbstractUnipartiteNetwork) = dot(s(N, dims=1), s(N, dims=2)) / sum(N) diff --git a/test/community/resilience.jl b/test/community/resilience.jl index 4018b40b9..861c746d9 100644 --- a/test/community/resilience.jl +++ b/test/community/resilience.jl @@ -4,11 +4,11 @@ module TestResilience A = rand([0, 1, 0.5], 10, 10) N = UnipartiteQuantitativeNetwork(A) - @assert s_mean(N) ≈ sum(A) / 10 - @assert s_in(N) ≈ sum(A, dims=2) - @assert s_out(N) ≈ sum(A, dims=1)' + @assert s(N) ≈ sum(A) / 10 + @assert s(N, dims=1) ≈ sum(A, dims=2) + @assert s(N, dims=2) ≈ sum(A, dims=1)' - @assert βeff(N) ≈ s_mean(N) + symmetry(N) * heterogeneity(N) + @assert resilience(N) ≈ s(N) + symmetry(N) * heterogeneity(N) # species only interact with themselves Nid = UnipartiteNetwork([true false false false;