# Heterogeneous Graphs

Heterographs support is still experimental. The interface could be subject to change in the future.

Heterogeneus graphs (also called heterographs), are graphs where each node has a type, that we denote with symbols such as `:user`

and `:movie`

, and edges also represent different relations identified by a triple of symbols, `(source_nodes, edge_type, target_nodes)`

, as in `(:user, :rate, :movie)`

.

Different node/edge types can store different group of features and this makes heterographs a very flexible modeling tools and data containers.

In GraphNeuralNetworks.jl heterographs are implemented in the type `GNNHeteroGraph`

.

`GraphNeuralNetworks.GNNGraphs.GNNHeteroGraph`

— Type`GNNHeteroGraph(data; ndata, edata, gdata, num_nodes, graph_indicator, dir])`

A type representing a heterogeneous graph structure. it is similar `GNNGraph`

but node and edges are of different types.

**Arguments**

`data`

: A dictionary or an iterable object that maps (source*type, edge*type, target_type) triples to (source, target) index vectors.`num_nodes`

: The number of nodes for each type. If not specified, inferred from`g`

. Default`nothing`

.`graph_indicator`

: For batched graphs, a dictionary of vectors containing the graph assignment of each node. Default`nothing`

.`ndata`

: Node features. A dictionary of arrays or named tuple of arrays. The size of the last dimension of each array must be given by`g.num_nodes`

.`edata`

: Edge features. A dictionary of arrays or named tuple of arrays. The size of the last dimension of each array must be given by`g.num_edges`

.`gdata`

: Graph features. An array or named tuple of arrays whose last dimension has size`num_graphs`

.

`GNNHeteroGraph`

is still experimental and not fully supported. The interface could be subject to change in the future.

**Examples**

```
julia> using Flux, GraphNeuralNetworks
julia> num_nodes = Dict(:A => 10, :B => 20);
julia> edges1 = rand(1:num_nodes[:A], 20), rand(1:num_nodes[:B], 20)
([4, 8, 6, 3, 4, 7, 2, 7, 3, 2, 3, 4, 9, 4, 2, 9, 10, 1, 3, 9], [6, 4, 20, 8, 16, 7, 12, 16, 5, 4, 6, 20, 11, 19, 17, 9, 12, 2, 18, 12])
julia> edges2 = rand(1:num_nodes[:B], 30), rand(1:num_nodes[:A], 30)
([17, 5, 2, 4, 5, 3, 8, 7, 9, 7 … 19, 8, 20, 7, 16, 2, 9, 15, 8, 13], [1, 1, 3, 1, 1, 3, 2, 7, 4, 4 … 7, 10, 6, 3, 4, 9, 1, 5, 8, 5])
julia> eindex = ((:A, :rel1, :B) => edges1, (:B, :rel2, :A) => edges2);
julia> hg = GNNHeteroGraph(eindex; num_nodes)
GNNHeteroGraph:
num_nodes: (:A => 10, :B => 20)
num_edges: ((:A, :rel1, :B) => 20, (:B, :rel2, :A) => 30)
julia> hg.num_edges
Dict{Tuple{Symbol, Symbol, Symbol}, Int64} with 2 entries:
(:A, :rel1, :B) => 20
(:B, :rel2, :A) => 30
# Let's add some node features
julia> ndata = Dict(:A => (x = rand(2, num_nodes[:A]), y = rand(3, num_nodes[:A])),
:B => rand(10, num_nodes[:B]));
julia> hg = GNNHeteroGraph(eindex; num_nodes, ndata)
GNNHeteroGraph:
num_nodes: (:A => 10, :B => 20)
num_edges: ((:A, :rel1, :B) => 20, (:B, :rel2, :A) => 30)
ndata:
:A => (x = 2×10 Matrix{Float64}, y = 3×10 Matrix{Float64})
:B => x = 10×20 Matrix{Float64}
# Access features of nodes of type :A
julia> hg.ndata[:A].x
2×10 Matrix{Float64}:
0.825882 0.0797502 0.245813 0.142281 0.231253 0.685025 0.821457 0.888838 0.571347 0.53165
0.631286 0.316292 0.705325 0.239211 0.533007 0.249233 0.473736 0.595475 0.0623298 0.159307
```

See also `GNNGraph`

for a homogeneous graph type. and `rand_heterograph`

for a function to generate random heterographs.

Missing docstring for `rand_heterograph`

. Check Documenter's build log for details.