Skip to content

Commit f718bd1

Browse files
authored
Merge pull request #64 from JuliaGraphs/minor_fixes
Update API, README and docs with minor fixes
2 parents 458deea + f15f1a3 commit f718bd1

13 files changed

+493
-239
lines changed

.vscode/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
{
22
"cSpell.words": [
3+
"abstractmatrixrrepresentation",
34
"abstractmultilayerdigraph",
45
"abstractmultilayergraph",
56
"abstractmultilayerugraph",
67
"abstractmultiplexdigraph",
78
"abstractmultiplexugraph",
89
"abstractsubgraph",
10+
"abstracttensorrepresentation",
11+
"abstractvertex",
912
"add_vertex",
1013
"adjm",
1114
"agrs",
@@ -107,6 +110,7 @@
107110
"supraweightmatrix",
108111
"swdg",
109112
"tensoreig",
113+
"tensorfacoriazations",
110114
"tensorsfactorizations",
111115
"testset",
112116
"traitdef",

README.md

Lines changed: 193 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,25 +39,211 @@ Finally, MultilayerGraphs.jl has been integrated within the [JuliaDynamics](http
3939

4040
## Installation
4141

42-
Press `]` in the Julia REPL and then
42+
To install MultilayerGraphs.jl it is sufficient to activate the `pkg` mode by pressing `]` in the Julia REPL and then run the following command:
4343

4444
```nothing
4545
pkg> add MultilayerGraphs
4646
```
4747

4848
## Usage
4949

50-
In the package documentation you can find a [tutorial](https://juliagraphs.org/MultilayerGraphs.jl/stable/#Tutorial) that illustrates all its main features and functionalities.
50+
Here we are going to synthetically illustrate some of the main features of MultilayerGraphs.jl. For a more comprehensive exploration of the package functionalities we strongly recommend consulting the [documentation](https://juliagraphs.org/MultilayerGraphs.jl).
51+
52+
Let's begin by importing the necessary dependencies and setting the relevant constants.
53+
54+
```julia
55+
using Distributions, Graphs, SimpleValueGraphs
56+
using MultilayerGraphs
57+
58+
# Set the number of nodes: objects represented by multilayer vertices
59+
const n_nodes = 100
60+
# Create a list of nodes
61+
const node_list = [Node("node_$i") for i in 1:n_nodes]
62+
```
63+
64+
### Layers and Interlayers
65+
66+
We will instantiate layers and interlayers with randomly-selected edges and vertices adopting a variety of techniques. Layers and Interlayers are not immutable, and mostly behave like normal graphs. The user is invited to consult the [API](https://juliagraphs.org/MultilayerGraphs.jl/stable/API/) for further details.
67+
68+
Here we define a layer with an underlying simple directed graph using a graph generator-like (or "configuration model"-like) constructor which allows us to specify both the **indegree** and the **outdegree sequences**. Before instantiating each layer we sample the number of its vertices and, optionally, of its edges.
69+
70+
```julia
71+
n_vertices = rand(1:100) # Number of vertices
72+
layer_simple_directed = layer_simpledigraph( # Layer constructor
73+
:layer_simple_directed, # Layer name
74+
sample(node_list, n_vertices; replace=false), # Nodes represented in the layer
75+
Truncated(Normal(5, 5), 0, 20), # Indegree sequence distribution
76+
Truncated(Normal(5, 5), 0, 20) # Outdegree sequence distribution
77+
)
78+
```
79+
80+
Then we define a layer with an underlying simple weighted directed graph. This is another kind of constructor that allows the user to specify the number of edges to be randomly distributed among vertices.
81+
82+
```julia
83+
n_vertices = rand(1:n_nodes) # Number of vertices
84+
n_edges = rand(n_vertices:(n_vertices * (n_vertices - 1) - 1)) # Number of edges
85+
layer_simple_directed_weighted = layer_simpleweighteddigraph( # Layer constructor
86+
:layer_simple_directed_weighted, # Layer name
87+
sample(node_list, n_vertices; replace=false), # Nodes represented in the layer
88+
n_edges; # Number of randomly distributed edges
89+
default_edge_weight=(src, dst) -> rand() # Function assigning weights to edges
90+
)
91+
```
92+
93+
Similar constructors, more flexible at the cost of ease of use, enable a finer tuning. The constructor we use below should be necessary only in rare circumstances, e.g. if the equivalent simplified constructor `layer_simplevaldigraph` is not able to infer the correct return types of `default_vertex_metadata` or `default_edge_metadata`, or to use and underlying graph structure that isn't currently supported.
94+
95+
```julia
96+
n_vertices = rand(1:n_nodes) # Number of vertices
97+
n_edges = rand(n_vertices:(n_vertices * (n_vertices - 1) - 1)) # Number of edges
98+
default_vertex_metadata = v -> ("vertex_$(v)_metadata") # Vertex metadata
99+
default_edge_metadata = (s, d) -> (rand(),) # Edge metadata
100+
layer_simple_directed_value = Layer( # Layer constructor
101+
:layer_simple_directed_value, # Layer name
102+
sample(node_list, n_vertices; replace=false), # Nodes represented in the layer
103+
n_edges, # Number of randomly distributed edges
104+
ValDiGraph(
105+
SimpleDiGraph{Int64}();
106+
vertexval_types=(String,),
107+
vertexval_init=default_vertex_metadata,
108+
edgeval_types=(Float64,),
109+
edgeval_init=default_edge_metadata,
110+
),
111+
Float64;
112+
default_vertex_metadata=default_vertex_metadata, # Vertex metadata
113+
default_edge_metadata=default_edge_metadata # Edge metadata
114+
)
115+
116+
# Create a list of layers
117+
layers = [layer_simple_directed, layer_simple_directed_weighted, layer_simple_directed_value]
118+
```
119+
120+
There are many more constructors the user is encouraged to explore in the package [documentation](https://juliagraphs.org/MultilayerGraphs.jl).
121+
122+
The interface of interlayers is very similar to that of layers. It is very important to notice that, in order to define a `Multilayer(Di)Graph`, interlayers don't need to be explicitly constructed by the user since they are automatically identified by the `Multilayer(Di)Graph` constructor, but for more complex interlayers the manual instantiation is required.
123+
124+
Here we define an interlayer with an underlying simple directed graph.
125+
126+
```julia
127+
n_vertices_1 = nv(layer_simple_directed) # Number of vertices of layer 1
128+
n_vertices_2 = nv(layer_simple_directed_weighted) # Number of vertices of layer 2
129+
n_edges = rand(1:(n_vertices_1 * n_vertices_2 - 1)) # Number of interlayer edges
130+
interlayer_simple_directed = interlayer_simpledigraph( # Interlayer constructor
131+
layer_simple_directed, # Layer 1
132+
layer_simple_directed_weighted, # Layer 2
133+
n_edges # Number of edges
134+
)
135+
```
136+
137+
The interlayer exports a more flexible constructor too.
138+
139+
```julia
140+
n_vertices_1 = nv(layer_simple_directed_weighted) # Number of vertices of layer 1
141+
n_vertices_2 = nv(layer_simple_directed_value) # Number of vertices of layer 2
142+
n_edges = rand(1:(n_vertices_1 * n_vertices_2 - 1)) # Number of interlayer edges
143+
interlayer_simple_directed_meta = interlayer_metadigraph( # Interlayer constructor
144+
layer_simple_directed_weighted, # Layer 1
145+
layer_simple_directed_value, # Layer 2
146+
n_edges; # Number of edges
147+
default_edge_metadata=(src, dst) -> # Edge metadata
148+
(edge_metadata="metadata_of_edge_from_$(src)_to_$(dst)"),
149+
transfer_vertex_metadata=true # Boolean deciding layer vertex metadata inheritance
150+
)
151+
152+
# Create a list of interlayers
153+
interlayers = [interlayer_simple_directed, interlayer_simple_directed_meta]
154+
```
155+
156+
### Multilayer Graphs
157+
158+
Let's construct a directed multilayer graph (`MultilayerDiGraph`).
159+
160+
```julia
161+
multilayerdigraph = MultilayerDiGraph( # Constructor
162+
layers, # The (ordered) collection of layers
163+
interlayers; # The manually specified interlayers
164+
# The interlayers that are left unspecified
165+
# will be automatically inserted according
166+
# to the keyword argument below
167+
default_interlayers_structure="multiplex"
168+
# The automatically specified interlayers will have only diagonal couplings
169+
)
170+
171+
# Layers and interlayer can be accessed as properties using their names
172+
multilayerdigraph.layer_simplevaldigraph
173+
```
174+
175+
Then we proceed by showing how to add nodes, vertices and edges to a directed multilayer graph. The user may add vertices that do or do not represent nodes which are already present in the multilayergraph. In the latter case, we have to create a node first and then add the vertex representing such node to the multilayer graph. The vertex-level metadata are effectively considered only if the graph underlying the relevant layer or interlayer supports them, otherwise they are discarded. The same holds for edge-level metadata and/or weight.
176+
177+
```julia
178+
# Create a node
179+
new_node_1 = Node("new_node_1")
180+
# Add the node to the multilayer graph
181+
add_node!(multilayerdigraph, new_node_1)
182+
# Create a vertex representing the node
183+
new_vertex_1 = MV( # Constructor (alias for "MultilayerVertex")
184+
new_node_1, # Node represented by the vertex
185+
:layer_simplevaldigraph, # Layer containing the vertex
186+
("new_metadata") # Vertex metadata
187+
)
188+
# Add the vertex
189+
add_vertex!(
190+
multilayerdigraph, # MultilayerDiGraph the vertex will be added to
191+
new_vertex_1 # MultilayerVertex to add
192+
)
193+
194+
# Create another node in another layer
195+
new_node_2 = Node("new_node_2")
196+
# Create another vertex representing the new node
197+
new_vertex_2 = MV(new_node_2, :layer_simpledigraph)
198+
# Add the new vertex
199+
add_vertex!(
200+
multilayerdigraph,
201+
new_vertex_2;
202+
add_node=true # Add the associated node before adding the vertex
203+
)
204+
# Create an edge
205+
new_edge = MultilayerEdge( # Constructor
206+
new_vertex_1, # Source vertex
207+
new_vertex_2, # Destination vertex
208+
("some_edge_metadata") # Edge metadata
209+
)
210+
# Add the edge
211+
add_edge!(
212+
multilayerdigraph, # MultilayerDiGraph the edge will be added to
213+
new_edge # MultilayerVertex to add
214+
)
215+
```
216+
217+
Finally we illustrate how to compute a few multilayer metrics such as the global clustering coefficient, the overlay clustering coefficient, the multilayer eigenvector centrality, and the multilayer modularity as defined in [De Domenico et al. (2013)](https://doi.org/10.1103/physrevx.3.041022).
218+
219+
```julia
220+
# Compute the global clustering coefficient
221+
multilayer_global_clustering_coefficient(multilayerdigraph)
222+
# Compute the overlay clustering coefficient
223+
overlay_clustering_coefficient(multilayerdigraph)
224+
# Compute the multilayer eigenvector centrality
225+
eigenvector_centrality(multilayerdigraph)
226+
# Compute the multilayer modularity
227+
modularity(
228+
multilayerdigraph,
229+
rand([1, 2, 3, 4], length(nodes(multilayerdigraph)), length(multilayerdigraph.layers))
230+
)
231+
```
51232

52233
## Future Developments
53234

54-
- [ ] [Implement more general configuration models / graph generators](https://github.com/JuliaGraphs/MultilayerGraphs.jl/issues/33);
55235
- [ ] [Implement graph of layers](https://github.com/JuliaGraphs/MultilayerGraphs.jl/issues/34);
56236
- [ ] [Implement projected monoplex and overlay graphs](https://github.com/JuliaGraphs/MultilayerGraphs.jl/issues/35);
57237
- [ ] [Implement more default multilayer graphs](https://github.com/JuliaGraphs/MultilayerGraphs.jl/issues/36) (e.g. multiplex graphs);
58238
- [ ] [Implement configuration models / graph generators for interlayers](https://github.com/JuliaGraphs/MultilayerGraphs.jl/issues/46);
239+
- [ ] [Implement a fully-fledged multilayer configuration model / graph generator](https://github.com/JuliaGraphs/MultilayerGraphs.jl/issues/48);
59240
- [ ] [Relax the requirement of same `T` and `U` for all `Layer`s and `Interlayer`s that are meant to constitute a `Multilayer(Di)Graph`](https://github.com/JuliaGraphs/MultilayerGraphs.jl/issues/53);
60-
- [ ] [Implement multilayer graph data visualisation functionalities (or a new package)](https://github.com/JuliaGraphs/MultilayerGraphs.jl/issues/54).
241+
- [ ] [Implement multilayer graph data visualisation functionalities](https://github.com/JuliaGraphs/MultilayerGraphs.jl/issues/54);
242+
- [ ] [Infer `weighttype` from `default_edge_weight`](https://github.com/JuliaGraphs/MultilayerGraphs.jl/issues/58);
243+
- [ ] [Improve error explanations](https://github.com/JuliaGraphs/MultilayerGraphs.jl/issues/59);
244+
- [ ] [Improve integration with Agents.jl](https://github.com/JuliaGraphs/MultilayerGraphs.jl/issues/61);
245+
- [ ] [Allow configuration models to specify a minimum discrepancy between the sampled (di)graphical sequence(s) and the provided distribution](https://github.com/JuliaGraphs/MultilayerGraphs.jl/issues/62);
246+
- [ ] [Add to `add_layer!` a kwarg that allows the user to specify some new interlayers, skipping the instantiation of the default ones.](https://github.com/JuliaGraphs/MultilayerGraphs.jl/issues/63).
61247

62248
## How to Contribute
63249

@@ -67,7 +253,9 @@ We therefore encourage you to participate in [discussions](https://github.com/Ju
67253

68254
## How to Cite
69255

70-
If you utilize this package in your project, please consider citing this repository using the citation information provided in [`CITATION.bib`](https://github.com/JuliaGraphs/MultilayerGraphs.jl/blob/main/CITATION.bib). This will help to give appropriate credit to the [contributors](https://github.com/JuliaGraphs/MultilayerGraphs.jl/graphs/contributors) and support the continued development of the package.
256+
If you utilize this package in your project, please consider citing this repository using the citation information provided in [`CITATION.bib`](https://github.com/JuliaGraphs/MultilayerGraphs.jl/blob/main/CITATION.bib).
257+
258+
This will help to give appropriate credit to the [contributors](https://github.com/JuliaGraphs/MultilayerGraphs.jl/graphs/contributors) and support the continued development of the package.
71259

72260
## Announcements
73261

docs/make.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using Revise
21
using Distributions
32
using Graphs
43
using MultilayerGraphs

docs/src/API.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,7 @@ mv_vertices(mg::AbstractMultilayerGraph)
235235
mv_inneighbors(mg::AbstractMultilayerGraph, mv::MultilayerVertex)
236236
mv_outneighbors(mg::AbstractMultilayerGraph, mv::MultilayerVertex)
237237
mv_neighbors( mg::AbstractMultilayerGraph, mv::MultilayerVertex)
238-
add_vertex!(mg::M, V::MultilayerVertex) where {T, U, M <: AbstractMultilayerUGraph{T,U}}
239-
add_vertex!(mg::M, V::MultilayerVertex) where {T, U, M <: AbstractMultilayerDiGraph{T,U}}
238+
add_vertex!(mg::AbstractMultilayerGraph, mv::MultilayerVertex; add_node::Bool)
240239
rem_vertex!(mg::AbstractMultilayerUGraph, V::MultilayerVertex)
241240
rem_vertex!(mg::AbstractMultilayerDiGraph, V::MultilayerVertex)
242241
has_edge(mg::AbstractMultilayerGraph, edge::MultilayerEdge)

0 commit comments

Comments
 (0)