# Temporal Graphs

## TemporalSnapshotsGNNGraph

Documentation page for the graph type `TemporalSnapshotsGNNGraph`

and related methods, representing time varying graphs with time varying features.

`GNNGraphs.TemporalSnapshotsGNNGraph`

— Type`TemporalSnapshotsGNNGraph(snapshots::AbstractVector{<:GNNGraph})`

A type representing a temporal graph as a sequence of snapshots. In this case a snapshot is a `GNNGraph`

.

`TemporalSnapshotsGNNGraph`

can store the feature array associated to the graph itself as a `DataStore`

object, and it uses the `DataStore`

objects of each snapshot for the node and edge features. The features can be passed at construction time or added later.

**Constructor Arguments**

`snapshot`

: a vector of snapshots, where each snapshot must have the same number of nodes.

**Examples**

```
julia> using GraphNeuralNetworks
julia> snapshots = [rand_graph(10,20) for i in 1:5];
julia> tg = TemporalSnapshotsGNNGraph(snapshots)
TemporalSnapshotsGNNGraph:
num_nodes: [10, 10, 10, 10, 10]
num_edges: [20, 20, 20, 20, 20]
num_snapshots: 5
julia> tg.tgdata.x = rand(4); # add temporal graph feature
julia> tg # show temporal graph with new feature
TemporalSnapshotsGNNGraph:
num_nodes: [10, 10, 10, 10, 10]
num_edges: [20, 20, 20, 20, 20]
num_snapshots: 5
tgdata:
x = 4-element Vector{Float64}
```

`GNNGraphs.add_snapshot`

— Method`add_snapshot(tg::TemporalSnapshotsGNNGraph, t::Int, g::GNNGraph)`

Return a `TemporalSnapshotsGNNGraph`

created starting from `tg`

by adding the snapshot `g`

at time index `t`

.

**Examples**

```
julia> using GraphNeuralNetworks
julia> snapshots = [rand_graph(10, 20) for i in 1:5];
julia> tg = TemporalSnapshotsGNNGraph(snapshots)
TemporalSnapshotsGNNGraph:
num_nodes: [10, 10, 10, 10, 10]
num_edges: [20, 20, 20, 20, 20]
num_snapshots: 5
julia> new_tg = add_snapshot(tg, 3, rand_graph(10, 16)) # add a new snapshot at time 3
TemporalSnapshotsGNNGraph:
num_nodes: [10, 10, 10, 10, 10, 10]
num_edges: [20, 20, 16, 20, 20, 20]
num_snapshots: 6
```

`GNNGraphs.remove_snapshot`

— Method`remove_snapshot(tg::TemporalSnapshotsGNNGraph, t::Int)`

Return a `TemporalSnapshotsGNNGraph`

created starting from `tg`

by removing the snapshot at time index `t`

.

**Examples**

```
julia> using GraphNeuralNetworks
julia> snapshots = [rand_graph(10,20), rand_graph(10,14), rand_graph(10,22)];
julia> tg = TemporalSnapshotsGNNGraph(snapshots)
TemporalSnapshotsGNNGraph:
num_nodes: [10, 10, 10]
num_edges: [20, 14, 22]
num_snapshots: 3
julia> new_tg = remove_snapshot(tg, 2) # remove snapshot at time 2
TemporalSnapshotsGNNGraph:
num_nodes: [10, 10]
num_edges: [20, 22]
num_snapshots: 2
```

### TemporalSnapshotsGNNGraph random generators

`GNNGraphs.rand_temporal_radius_graph`

— Function```
rand_temporal_radius_graph(number_nodes::Int,
number_snapshots::Int,
speed::AbstractFloat,
r::AbstractFloat;
self_loops = false,
dir = :in,
kws...)
```

Create a random temporal graph given `number_nodes`

nodes and `number_snapshots`

snapshots. First, the positions of the nodes are randomly generated in the unit square. Two nodes are connected if their distance is less than a given radius `r`

. Each following snapshot is obtained by applying the same construction to new positions obtained as follows. For each snapshot, the new positions of the points are determined by applying random independent displacement vectors to the previous positions. The direction of the displacement is chosen uniformly at random and its length is chosen uniformly in `[0, speed]`

. Then the connections are recomputed. If a point happens to move outside the boundary, its position is updated as if it had bounced off the boundary.

**Arguments**

`number_nodes`

: The number of nodes of each snapshot.`number_snapshots`

: The number of snapshots.`speed`

: The speed to update the nodes.`r`

: The radius of connection.`self_loops`

: If`true`

, consider the node itself among its neighbors, in which case the graph will contain self-loops.`dir`

: The direction of the edges. If`dir=:in`

edges go from the neighbors to the central node. If`dir=:out`

we have the opposite direction.`kws`

: Further keyword arguments will be passed to the`GNNGraph`

constructor of each snapshot.

**Example**

```
julia> n, snaps, s, r = 10, 5, 0.1, 1.5;
julia> tg = rand_temporal_radius_graph(n,snaps,s,r) # complete graph at each snapshot
TemporalSnapshotsGNNGraph:
num_nodes: [10, 10, 10, 10, 10]
num_edges: [90, 90, 90, 90, 90]
num_snapshots: 5
```

`GNNGraphs.rand_temporal_hyperbolic_graph`

— Function```
rand_temporal_hyperbolic_graph(number_nodes::Int,
number_snapshots::Int;
α::Real,
R::Real,
speed::Real,
ζ::Real=1,
self_loop = false,
kws...)
```

Create a random temporal graph given `number_nodes`

nodes and `number_snapshots`

snapshots. First, the positions of the nodes are generated with a quasi-uniform distribution (depending on the parameter `α`

) in hyperbolic space within a disk of radius `R`

. Two nodes are connected if their hyperbolic distance is less than `R`

. Each following snapshot is created in order to keep the same initial distribution.

**Arguments**

`number_nodes`

: The number of nodes of each snapshot.`number_snapshots`

: The number of snapshots.`α`

: The parameter that controls the position of the points. If`α=ζ`

, the points are uniformly distributed on the disk of radius`R`

. If`α>ζ`

, the points are more concentrated in the center of the disk. If`α<ζ`

, the points are more concentrated at the boundary of the disk.`R`

: The radius of the disk and of connection.`speed`

: The speed to update the nodes.`ζ`

: The parameter that controls the curvature of the disk.`self_loops`

: If`true`

, consider the node itself among its neighbors, in which case the graph will contain self-loops.`kws`

: Further keyword arguments will be passed to the`GNNGraph`

constructor of each snapshot.

**Example**

```
julia> n, snaps, α, R, speed, ζ = 10, 5, 1.0, 4.0, 0.1, 1.0;
julia> thg = rand_temporal_hyperbolic_graph(n, snaps; α, R, speed, ζ)
TemporalSnapshotsGNNGraph:
num_nodes: [10, 10, 10, 10, 10]
num_edges: [44, 46, 48, 42, 38]
num_snapshots: 5
```

**References**

Section D of the paper Dynamic Hidden-Variable Network Models and the paper Hyperbolic Geometry of Complex Networks