You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+4-1Lines changed: 4 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,7 +16,7 @@
16
16
17
17
**MultilayerGraphs.jl** implements the mathematical formulation of multilayer graphs proposed by [De Domenico et al. (2013)](https://doi.org/10.1103/PhysRevX.3.041022). It mainly revolves around two custom types, [`MultilayerGraph`](@ref) and [`MultilayerDiGraph`](@ref), encoding undirected and directed multilayer graphs respectively.
18
18
19
-
Roughly speaking, a multilayer graph is a collection of graphs, called *layers*, whose vertices are representations of the same set of nodes endowed with a relational structure provided by the *interlayer*: the [bipartite graph](https://en.wikipedia.org/wiki/Bipartite_graph) whose vertices are those of any two consecutive layers and whose edges are those between nodes of the two consecutive layers. See below for the distinction between *node* and *vertex*.
19
+
Roughly speaking, a multilayer graph is a collection of graphs, called *layers*, whose vertices are representations of the same set of nodes, and *interlayers*, i.e the [bipartite graphs](https://en.wikipedia.org/wiki/Bipartite_graph) whose vertices are those of any two layers and whose edges are those between vertices of the same two layers.
20
20
21
21
[`MultilayerGraph`](@ref) and [`MultilayerDiGraph`](@ref) are fully-fledged [Graphs.jl](https://github.com/JuliaGraphs/Graphs.jl) extensions. Both structs are designed so that their layers and interlayers can be of any type (as long as they are Graphs.jl extensions themselves) and they need not be all of the same type. It is anyway required that all layers and interlayers of [`MultilayerGraph`](@ref) and [`MultilayerDiGraph`](@ref) are respectively undirected and directed. Directedness is checked via the `IsDirected` trait defined in Graphs.jl adopting [SimpleTraits.jl](https://github.com/mauro3/SimpleTraits.jl). Since the layers' and interlayers' graph types don't need to be the same, multilayer graph types are considered weighted graphs by default, and thus are assigned the trait `IsWeighted`.
22
22
@@ -27,12 +27,15 @@ Press `]` in the Julia REPL and then
[Registration](https://github.com/JuliaRegistries/General/pull/66311) is under way.
30
31
31
32
## Tutorial
32
33
33
34
In the package documentation we have written a [tutorial](https://inphyt.github.io/MultilayerGraphs.jl/stable/#Tutorial) to illustrate how to define, handle and analyse a [`MultilayerGraph`](@ref) (the directed version is completely analogous).
34
35
35
36
## Future Developments
37
+
38
+
Here we highlight the major future developments we have currently identified:
36
39
-[] Better integration with [Graphs.jl](https://github.com/JuliaGraphs/Graphs.jl) (e.g. move the `AbstractVertex` to Graphs.jl, standardize graphs constructors, etc.);
37
40
-[] Better integration with [MetaGraphs.jl](https://github.com/JuliaGraphs/MetaGraphs.jl) and [SimpleValueGraphs.jl](https://github.com/simonschoelly/SimpleValueGraphs.jl). Although it is possible to specify a `MetaGraph` and `SimpleValueGraph` as layer and/or interlayer, they are not yet fully supported (i.e. API may be a little unfit for them). An example using MetaGraphs, SimpleValueGraphs can be found at our announcement post [here]();
**MultilayerGraphs.jl** implements the mathematical formulation of multilayer graphs proposed by [De Domenico et al. (2013)](https://doi.org/10.1103/PhysRevX.3.041022). It mainly revolves around two custom types, [`MultilayerGraph`](@ref) and [`MultilayerDiGraph`](@ref), encoding undirected and directed multilayer graphs respectively.
22
22
23
-
Roughly speaking, a multilayer graph is a collection of graphs, called *layers*, whose vertices are representations of the same set of nodes endowed with a relational structure provided by the *interlayer*: the [bipartite graph](https://en.wikipedia.org/wiki/Bipartite_graph) whose vertices are those of any two consecutive layers and whose edges are those between nodes of the two consecutive layers. See below for the distinction between *node* and *vertex*.
23
+
Roughly speaking, a multilayer graph is a collection of graphs, called *layers*, whose vertices are representations of the same set of nodes, and *interlayers*, i.e the [bipartite graphs](https://en.wikipedia.org/wiki/Bipartite_graph) whose vertices are those of any two layers and whose edges are those between vertices of the same two layers. See below for the distinction between *node* and *vertex*.
24
24
25
25
[`MultilayerGraph`](@ref) and [`MultilayerDiGraph`](@ref) are fully-fledged [Graphs.jl](https://github.com/JuliaGraphs/Graphs.jl) extensions. Both structs are designed so that their layers and interlayers can be of any type (as long as they are Graphs.jl extensions themselves) and they need not be all of the same type. It is anyway required that all layers and interlayers of [`MultilayerGraph`](@ref) and [`MultilayerDiGraph`](@ref) are respectively undirected and directed. Directedness is checked via the `IsDirected` trait defined in Graphs.jl adopting [SimpleTraits.jl](https://github.com/mauro3/SimpleTraits.jl). Since the layers' and interlayers' graph types don't need to be the same, multilayer graph types are considered weighted graphs by default, and thus are assigned the trait `IsWeighted`.
26
26
@@ -31,6 +31,7 @@ Press `]` in the Julia REPL and then
We proceed by constructing a layer (see [`Layer`](@ref))
71
+
As said before, to define a multilayer graph we need to specify its layers and interlayers. We proceed by constructing a layer (see [`Layer`](@ref))
71
72
72
73
```julia
73
74
# Construct a layer
74
75
layer =Layer(:layer_1, SimpleGraph(n_nodes, rand(min_edges:max_edges)); U = Float64)
75
76
```
76
77
77
-
A `Layer` has a name (here `:layer_1`), an underlying graph (`SimpleGraph(n_nodes, rand(min_edges:max_edges))`) and an adjacency matrix `eltype``U`. To correctly specify a multilayer graph all layers and interlayers must have the same `U`, otherwise the adjacency tensor would be poorly specified. Notice that `U` does not need to coincide with the `eltype` of the adjacency matrix of the underlying graph.
78
-
79
-
As far as we know, there is no way to set it explicitly for all Graphs.jl extensions, nor it is required for extensions to implement such feature, so our package converts to `U` the `eltype` of `Layer`s and `Interlayer`s adjacency matrices every time they are invoked
78
+
A `Layer` has a name (here `:layer_1`), an underlying graph (`SimpleGraph(n_nodes, rand(min_edges:max_edges))`) and a weight matrix `eltype``U` (it defaults to the adjacency matrix's `eltype` if the graph in unweighted). To correctly specify a multilayer graph all layers and interlayers must have the same `U`, otherwise the multilayers's adjacency tensor would be poorly specified. Notice that `U` does not need to coincide with the `eltype` of the adjacency matrix of the underlying graph: as far as we know, there is no way to set it explicitly for all Graphs.jl extensions, nor it is required for extensions to implement such feature, so our package converts to `U` the `eltype` of `Layer`s and `Interlayer`s weight (/adjacency) matrices every time they are invoked
80
79
81
80
```julia
82
81
adjacency_matrix(layers[1])
@@ -108,7 +107,7 @@ We similarly define an interlayer (see [`Interlayer`](@ref))
Here we used a constructor that returns a random `Interlayer`. Its arguments are the number of nodes `n_nodes`, the name of the `Interlayer``interlayer_layer_1_layer_2`, the name of the `Layers` that it connects (`:layer_1` and `:layer_2`), the underlying graph type `SimpleGraph{Int64}`, and the number of edges `rand(min_edges:max_edges)` and the adjacency matrix `eltype` again need to be specified (although it may be left blank and the constructor will default to `eltype(adjacency_matrix(SimpleGraph{Int64}))`).
110
+
Here we used a constructor that returns a random `Interlayer`. Its arguments are the number of nodes `n_nodes`, the name of the `Interlayer``interlayer_layer_1_layer_2`, the name of the `Layers` that it connects (`:layer_1` and `:layer_2`), the underlying graph type `SimpleGraph{Int64}`, and the number of edges `rand(min_edges:max_edges)` and the weight/adjacency matrix `eltype` again needs to be specified (although it may be left blank and the constructor will default to `eltype(adjacency_matrix(SimpleGraph{Int64}))`).
112
111
113
112
The adjacency matrix of an `Interlayer` is that of a bipartite graph
It is not important that the `interlayers` array does not contain all the interlayers needed to specify the multilayer graph: the unspecified interlayers are automatically generated according to the `default_interlayer` argument. Right now only the `"multiplex"` value is supported, and will generate interlayers that have edges between pair of vertices of the two layers that represent the same node.
157
+
It is not important that the `interlayers` array contains all the interlayers needed to specify the multilayer graph: the unspecified interlayers are automatically generated according to the `default_interlayer` argument. Right now only the `"multiplex"` value is supported, and will generate interlayers that have edges between pair of vertices of the two layers that represent the same node.
159
158
160
159
Notice that in the output the signature of `MultilayerGraph` has two parametric types, namely `MultilayerGraph{Int64, Float64}`. The first is referred to the node type, that just as in every `Graphs.jl` extension it is a subtype of `Integer`. The second parameter is instead the `eltype` of the equivalent of the adjacency matrix for multilayer graphs: the adjacency tensor (see below for more).
161
160
@@ -186,7 +185,7 @@ Let's explore some properties of the `MultilayerGraph` struct.
186
185
187
186
#### Layers
188
187
189
-
It is an `OrderedDict` where the keys are the layers' indexes within the multilayer graph and the values are the actual `Layer`s
188
+
It is an `OrderedDict` where the keys are the layers' indexes within the multilayer graph (the index is repeated twice in a tuple to be consistent with `multilayergraph.interlayers`' keys, see below) and the values are the actual `Layer`s.
Both `MultilayerGraph` and `MultilayerDiGraph` fully extend `Graphs.jl`, so they have access to Graphs.jl API as one would expect, just keeping in mind that vertices are `MultilayerVertex`s and not subtypes of `Integer` (`MultilayerVertex` is actually a subtype of `AbstractVertex` that this package defines, see [Future Developments](#Future-Developments)), and that edges are `MultilayerEdge`s, which actually subtypes`AbstractEdge`.
309
+
Both `MultilayerGraph` and `MultilayerDiGraph` fully extend `Graphs.jl`, so they have access to Graphs.jl API as one would expect, just keeping in mind that vertices are `MultilayerVertex`s and not subtypes of `Integer` (`MultilayerVertex` is actually a subtype of `AbstractVertex` that this package defines, see [Future Developments](#Future-Developments)), and that edges are `MultilayerEdge`s, which subtype`AbstractEdge`.
We may add an edge using the `add_edge!` function. Since the interlayer we are adding the edge has an unweighted underlying graph (we will say that the interlayer is unweighted), we have to add an unweighted edge, so we don't specify many weights after the vertices. The adjacency tensor will be updated with a `one(U)` in the correct position. `add_edge!` mimics the behaviour of the analogous function in Graphs.jl
400
+
We may add an edge using the `add_edge!` function. Since the interlayer we are adding the edge has an unweighted underlying graph (we will say that the interlayer is unweighted), we have to add an unweighted edge, so we don't specify the weight after the vertices. The adjacency tensor will be updated with a `one(U)` in the correct position. `add_edge!` mimics the behaviour of the analogous function in Graphs.jl
The first component of `w` is the weight associated to triplets that are contained in one layer, the second component to triplets whose vertices are spread across exactly two layers, the third to triplets whose vertices are spread across exactly three layers. Weights must sum to `1.0 . When they are all equal (like in this example), the weighted global clustering coefficient coincides with the global clustering coefficient.
477
+
The first component of `w` is the weight associated to triplets that are contained in one layer, the second component to triplets whose vertices are spread across exactly two layers, the third to triplets whose vertices are spread across exactly three layers. Weights must sum to 1.0 . When they are all equal (like in this example), the weighted global clustering coefficient coincides with the global clustering coefficient.
479
478
480
479
#### Eigenvector Centrality
481
480
@@ -504,7 +503,7 @@ modularity(multilayergraph,
504
503
505
504
#### Von Neumann Entropy
506
505
507
-
Compute the Von Neumann entropy as presented in [De Domenico et al. (2013)](https://doi.org/10.1103/PhysRevX.3.041022).
506
+
Compute the Von Neumann entropy as presented in [De Domenico et al. (2013)](https://doi.org/10.1103/PhysRevX.3.041022)
0 commit comments