Skip to content

Commit 2043875

Browse files
InterdisciplinaryPhysicsTeamClaudMorpitmonticone
committed
Update docs, CITATION and Project.toml
Co-Authored-By: Claudio Moroni <43729990+ClaudMor@users.noreply.github.com> Co-Authored-By: Pietro Monticone <38562595+pitmonticone@users.noreply.github.com>
1 parent c94b3ff commit 2043875

File tree

5 files changed

+34
-56
lines changed

5 files changed

+34
-56
lines changed

CITATION.bib

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
@software{Monticone_Moroni_MultilayerGraphs_2022,
1+
@software{Moroni_Monticone_MultilayerGraphs_2022,
22
abstract = {A Julia package for the construction, manipulation and analysis of multilayer graphs.},
3-
author = {Monticone, Pietro and Moroni, Claudio},
3+
author = {Moroni, Claudio and Monticone, Pietro},
44
doi = {XX.XXXX/zenodo.XXXXXXX},
55
institution = {University of Turin (UniTO)},
66
keywords = {Julia Language, Julia Package, Graph Theory, Applied Graph Theory, Network Theory, Network Science, Graphs, Multilayer Graphs, Multilevel Graphs, Hierarchical Graphs, Networks, Multilayer Networks, Multilevel Networks, Hierarchical Networks, Complexity, Complex Systems},

JULIA_CITATION.bib

Lines changed: 0 additions & 38 deletions
This file was deleted.

Project.toml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "MultilayerGraphs"
22
uuid = "af984530-d72f-4904-8b81-b992bbbeaf3f"
3-
authors = ["Pietro Monticone <38562595+pitmonticone@users.noreply.github.com>", "Claudio Moroni <43729990+ClaudMor@users.noreply.github.com>"]
3+
authors = ["Claudio Moroni <43729990+ClaudMor@users.noreply.github.com>", "Pietro Monticone <38562595+pitmonticone@users.noreply.github.com>"]
44
version = "0.1.1"
55

66
[deps]
@@ -20,4 +20,14 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
2020
TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2"
2121

2222
[compat]
23+
DataStructures = "0.18"
24+
Graphs = "1.7"
25+
IterTools = "1.4"
26+
MetaGraphs = "0.7"
27+
OMEinsum = "0.7"
28+
PkgCite = "0.1"
29+
SimpleTraits = "0.9"
30+
SimpleValueGraphs = "0.4"
31+
SimpleWeightedGraphs = "1.2"
32+
TensorOperations = "3.2"
2333
julia = "1.7"

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
**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.
1818

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 ***layers***, i.e. graphs 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.
2020

2121
[`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`.
2222

@@ -28,11 +28,16 @@ Press `]` in the Julia REPL and then
2828
pkg> add https://github.com/InPhyT/MultilayerGraphs.jl
2929
```
3030

31+
[Registration](https://github.com/JuliaRegistries/General/pull/66311) is in progress.
32+
3133
## Tutorial
3234

3335
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).
3436

3537
## Future Developments
38+
39+
Here we highlight the major future developments we have currently identified:
40+
3641
- [ ] Better integration with [Graphs.jl](https://github.com/JuliaGraphs/Graphs.jl) (e.g. move the `AbstractVertex` to Graphs.jl, standardize graphs constructors, etc.);
3742
- [ ] 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]();
3843
- [ ] Optimise the adjacency tensor;

docs/src/index.md

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ CurrentModule = MultilayerGraphs
2020

2121
**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.
2222

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 ***layers***, i.e. graphs 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 ***nodes*** and ***vertices***.
2424

2525
[`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`.
2626

@@ -31,6 +31,7 @@ Press `]` in the Julia REPL and then
3131
```julia
3232
pkg> add https://github.com/InPhyT/MultilayerGraphs.jl
3333
```
34+
[Registration](https://github.com/JuliaRegistries/General/pull/66311) is in progress.
3435

3536
## Tutorial
3637

@@ -45,7 +46,7 @@ Let's import some necessary packages
4546
using Graphs, SimpleWeightedGraphs, MultilayerGraphs
4647
```
4748

48-
We define some methods and constants that will prove useful later in the tutorial (you may come back to these later when they get used)
49+
We define some methods and constants that will prove useful later in the tutorial
4950

5051
```julia
5152
# Set the number of nodes, minimum and maximum number of edges for random graphs
@@ -67,16 +68,16 @@ get_SimpleWeightedGraph() = SimpleWeightedGraph(simpleweightedgraph_sources, r
6768
get_SimpleWeightedDiGraph() = SimpleWeightedDiGraph(simpleweightedgraph_sources, rand(1:n_nodes, n_nodes), rand(n_nodes)) # Directed graph
6869
```
6970

70-
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))
7172

7273
```julia
7374
# Construct a layer
7475
layer = Layer(:layer_1, SimpleGraph(n_nodes, rand(min_edges:max_edges)); U = Float64)
7576
```
7677

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+
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 is 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.
7879

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
80+
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
8081

8182
```julia
8283
adjacency_matrix(layers[1])
@@ -108,7 +109,7 @@ We similarly define an interlayer (see [`Interlayer`](@ref))
108109
interlayer = Interlayer(n_nodes, :interlayer_layer_1_layer_2 , :layer_1, :layer_2, SimpleGraph{Int64}, rand(min_edges:max_edges); U = Float64)
109110
```
110111

111-
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}))`).
112+
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}))`).
112113

113114
The adjacency matrix of an `Interlayer` is that of a bipartite graph
114115

@@ -155,7 +156,7 @@ multilayergraph = MultilayerGraph(layers, interlayers; default_interlayer = "mul
155156
MultilayerGraph{Int64, Float64}([0.0 1.0 … 1.0 1.0; 1.0 0.0 … 0.0 1.0; … ; 1.0 0.0 … 0.0 0.0; 1.0 1.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 1.0 …],...)
156157
```
157158

158-
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.
159+
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.
159160

160161
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).
161162

@@ -186,7 +187,7 @@ Let's explore some properties of the `MultilayerGraph` struct.
186187

187188
#### Layers
188189

189-
It is an `OrderedDict` where the keys are the layers' indexes within the multilayer graph and the values are the actual `Layer`s
190+
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.
190191

191192
```julia
192193
multilayergraph.layers
@@ -246,7 +247,7 @@ multilayergraph.adjacency_tensor
246247
...
247248
```
248249

249-
The adjacency tensor is a 4-dimensional array. To understand its indexing, consider the following example
250+
To understand its indexing, consider the following example
250251

251252
```julia
252253
multilayergraph.adjacency_tensor[1,5,2,3]
@@ -264,7 +265,7 @@ struct MultilayerVertex{T <: Integer} <: AbstractMultilayerVertex{T}
264265
end
265266
```
266267

267-
To get the vertices of a `Layer` or an `Interlayer`, one may use Graphs.jl APIs
268+
To get the vertices of a `Layer` or an `Interlayer`, one may use the Graphs.jl APIs
268269

269270
```julia
270271
vertices(multilayergraph.layers[(1,1)])
@@ -307,7 +308,7 @@ Same for interlayers
307308
interlayer_2_1 = get_layer(multilayergraph, :interlayer_layer_2_layer_1)
308309
```
309310

310-
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`.
311+
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`.
311312

312313
Some notable examples are
313314

@@ -398,7 +399,7 @@ multilayergraph.adjacency_tensor[1,2,1,2]
398399

399400
##### Add an edge
400401

401-
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
402+
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
402403

403404
```julia
404405
add_edge!(multilayergraph, MultilayerVertex(1, :layer_1), MultilayerVertex(2, :layer_2))
@@ -475,7 +476,7 @@ multilayer_weighted_global_clustering_coefficient(multilayergraph,w)
475476
0.12667622867320916
476477
```
477478

478-
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+
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.
479480

480481
#### Eigenvector Centrality
481482

@@ -504,7 +505,7 @@ modularity(multilayergraph,
504505

505506
#### Von Neumann Entropy
506507

507-
Compute the Von Neumann entropy as presented in [De Domenico et al. (2013)](https://doi.org/10.1103/PhysRevX.3.041022).
508+
Compute the Von Neumann entropy as presented in [De Domenico et al. (2013)](https://doi.org/10.1103/PhysRevX.3.041022)
508509

509510
```julia
510511
von_neumann_entropy(multilayergraph)

0 commit comments

Comments
 (0)