Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Graphs.jl API support #8

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Mangal = "b8b640a6-63d9-51e6-b784-5033db27bef2"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Expand Down
2 changes: 2 additions & 0 deletions src/SpeciesInteractionNetworks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ using StatsBase
using TestItems
import Tables
import Mangal
import Graphs

# Various utilities for probabilities
# include(joinpath(".", "misc", "probabilities.jl"))
Expand Down Expand Up @@ -45,6 +46,7 @@ include("interfaces/iteration.jl")
include("interfaces/table.jl")
include("interfaces/broadcast.jl")
include("interfaces/linearalgebra.jl")
include("interfaces/graphs.jl")

export svd, rank, diag
export complexity, tsvd, rdpg
Expand Down
70 changes: 70 additions & 0 deletions src/interfaces/graphs.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""
Base.reverse(N::SpeciesInteractionNetwork{<:Partiteness, <:Interactions})

Returns a copy of the network, in which the interactions have been flipped. In
other words, an interaction A → B is now B → A. This maintains the nature of the
interaction, and works for loops, self-edges etc.
"""
function Base.reverse(N::SpeciesInteractionNetwork{<:Partiteness, <:Interactions})
M = copy(N)
reverse!(M)
end

"""
Base.reverse!(N::SpeciesInteractionNetwork{<:Partiteness, <:Interactions})

Modifies the network given as its argument so that the interactions are flipped.
See [`reverse`](@ref) for more information.
"""
function Base.reverse!(N::SpeciesInteractionNetwork{<:Partiteness, <:Interactions})
for interaction in interactions(N)
N[interaction[2], interaction[1]], N[interaction[1], interaction[2]] = N[interaction[1], interaction[2]], N[interaction[2], interaction[1]]
end
return N
end

@testitem "We can reverse a network" begin
edges = Binary(Bool[0 1 0 0; 0 0 1 0; 1 0 0 0; 0 1 1 1])
nodes = Unipartite(edges)
N = SpeciesInteractionNetwork(nodes, edges)
R = reverse(N)
for interaction in interactions(R)
@test N[interaction[2], interaction[1]] == interaction[3]
end
end

Graphs.has_vertex(N::T, v) where {T <: SpeciesInteractionNetwork} = v in species(N)

@testitem "We can check the existence of a vertex" begin
import SpeciesInteractionNetworks.Graphs
edges = Binary(Bool[0 1 0 0; 0 0 1 0; 1 0 0 0; 0 1 1 1])
nodes = Unipartite(edges)
N = SpeciesInteractionNetwork(nodes, edges)
@test Graphs.has_vertex(N, :node_1)
@test !Graphs.has_vertex(N, :node_1000)
end

function Graphs.has_edge(N::T, s, d) where {T <: SpeciesInteractionNetwork}
if !(Graphs.has_vertex(N, s) && Graphs.has_vertex(N, d))
return false
else
return !iszero(N[s,d])
end
end

@testitem "We can check the existence of an edge" begin
import SpeciesInteractionNetworks.Graphs
edges = Binary(Bool[0 1 0 0; 0 0 1 0; 1 0 0 0; 0 1 1 1])
nodes = Unipartite(edges)
N = SpeciesInteractionNetwork(nodes, edges)
@test Graphs.has_edge(N, :node_1, :node_2)
@test !Graphs.has_edge(N, :node_2, :node_1)
@test !Graphs.has_edge(N, :node_2000, :node_1)
@test !Graphs.has_edge(N, :node_2, :node_1000)
@test !Graphs.has_edge(N, :node_20000, :node_1000)
end

Graphs.inneighbors(N::T, v) where {T <: SpeciesInteractionNetwork} = predecessors(N, v)
Graphs.outneighbors(N::T, v) where {T <: SpeciesInteractionNetwork} = successors(N, v)

Graphs.edgetype(N::T) where {T <: SpeciesInteractionNetwork} = eltype(N)