Basic hypergraph functionality

This tutorial will give a brief introduction to using the XGI library to construct hypergraphs and perform basic operations on them.

[13]:
import random

import numpy as np

import xgi

Loading hypergraphs from different formats

We handle loading hypergraphs in many different formats, but the hypergraph constructor takes five main data formats: * A Hypergraph object * A hyperedge list * A hyperedge dictionary * A 2-column pandas dataframe specifying (node, edge) bipartite edges * An incidence matrix (A Numpy or Scipy matrix)

[14]:
n = 1000
m = 1000

min_edge_size = 2
max_edge_size = 25

# hyperedge list
hyperedge_list = [
    random.sample(range(n), random.choice(range(min_edge_size, max_edge_size + 1)))
    for i in range(m)
]

# hyperedge dict
hyperedge_dict = {
    i: random.sample(range(n), random.choice(range(min_edge_size, max_edge_size + 1)))
    for i in range(m)
}

# pandas dataframe
df = xgi.to_bipartite_pandas_dataframe(xgi.load_xgi_data("email-enron"))

# incidence matrix
incidence_matrix = np.random.randint(0, high=2, size=(n, m), dtype=int)

Loading a hyperedge list

When a user gives a hyperedge list, the system automatically creates system edge IDs.

[15]:
H = xgi.Hypergraph(hyperedge_list)
print(f"The hypergraph has {H.num_nodes} nodes and {H.num_edges} edges")
The hypergraph has 1000 nodes and 1000 edges

Loading a hyperedge dictionary

When a user gives a hyperedge dictionary, the system uses the edge IDs specified in the dictionary.

[16]:
H = xgi.Hypergraph(hyperedge_dict)
print(f"The hypergraph has {H.num_nodes} nodes and {H.num_edges} edges")
The hypergraph has 1000 nodes and 1000 edges

Loading an incidence matrix

When a user gives an incidence matrix, the system transforms the non-zero entries into lists of rows and columns specifying a bipartite edge list.

[17]:
H = xgi.Hypergraph(incidence_matrix)
print(f"The hypergraph has {H.num_nodes} nodes and {H.num_edges} edges")
The hypergraph has 1000 nodes and 1000 edges

Loading a Pandas dataframe

When a user gives a Pandas dataframe, the system automatically imports the first two columns as lists of node and edge indices specifying a bipartite edge list.

[18]:
H = xgi.Hypergraph(df)
print(f"The hypergraph has {H.num_nodes} nodes and {H.num_edges} edges")
The hypergraph has 143 nodes and 10885 edges

Simple functions

The Hypergraph class can do simple things like * output an incidence matrix * output the adjacency matrix for s-connectedness * output the dual of the hypergraph * find if the hypergraph is connected

Output relevant matrices

[19]:
# The incidence matrix
I = xgi.incidence_matrix(H, sparse=True)
# The adjacency matrix
A = xgi.adjacency_matrix(H)
# The clique motif matrix
W = xgi.clique_motif_matrix(H)

Forming the dual

[20]:
D = H.dual()

Testing whether the hypergraph is connected

[21]:
n = 1000
m = 100

min_edge_size = 2
max_edge_size = 10

# hyperedge list
hyperedge_list = [
    random.sample(range(n), random.choice(range(min_edge_size, max_edge_size + 1)))
    for i in range(m)
]
H = xgi.Hypergraph(hyperedge_list)
[22]:
is_connected = xgi.is_connected(H)
if is_connected:
    print(f"H is connected")
else:
    print(f"H is not connected")

print(f"The sizes of the connected components are:")
print([len(component) for component in xgi.connected_components(H)])

node = np.random.choice(H.nodes)
print(
    f"The size of the component containing node {node} is {len(xgi.node_connected_component(H, node))}"
)
H is not connected
The sizes of the connected components are:
[438, 4, 3, 3, 3, 3, 2, 4, 4, 4]
The size of the component containing node 713 is 438

Constructing subhypergraphs

A subhypergraph can be induced by a node subset, an edge subset, or an arbitrary combination of both. These examples are presented below.

[23]:
# A subhypergraph induced on nodes
node_subhypergraph = xgi.subhypergraph(H, nodes=list(range(100)))
# A subhypergraph induced on edges
edge_subhypergraph = xgi.subhypergraph(H, edges=list(range(100)))
# A subhypergraph induced on both nodes and edges
arbitrary_subhypergraph = xgi.subhypergraph(
    H, nodes=list(range(100)), edges=list(range(100))
)

Converting to other formats

Below are examples showing how to convert a hypergraph to a hyperedge list, a hyperedge dict, or an incidence matrix.

[24]:
# Convert to a hyperedge list
h_list = xgi.to_hyperedge_list(H)
# Convert to a hyperedge dict
h_dict = xgi.to_hyperedge_dict(H)
# Convert to an incidence matrix
h_I = xgi.to_incidence_matrix(H)
[ ]: