toponetx.PathComplex#
- class toponetx.PathComplex(paths: Graph | Iterable[Sequence[Hashable] | Path] | None = None, reserve_sequence_order: bool = False, allowed_paths: Iterable[tuple[Hashable]] | None = None, max_rank: int = 3, **kwargs)[source]#
Bases:
Complex
A class representing a path complex based on simple paths as proposed in [1].
The original path complex is defined in [2].
A path complex contains elementary p-paths that span the space of simple paths. Path complexes are a topological structure whose building blocks are paths, which are essentially different from simplicial complexes and cell complexes. If certain conditions are met, path complexes can generalize simplicial complexes.
For example, a triangle with three vertices 1, 2, and 3 can be represented as a simplicial complex (1, 2, 3). Similarly, it can be represented as a path complex (1, 2, 3) whose boundary 1-paths are (1, 2), (2, 3), and (1, 3). Another example is a simple path (1, 2, 3). In this case, we cannot lift the simple path to a 2-dimensional simplicial complex, as triangle does not exist. However, we can still represent the simple path as a path complex (1, 2, 3) whose boundary 1-paths are (1, 2) and (2, 3) (1-path (1,3) does not exist).
- Parameters:
- pathsnx.Graph or Iterable[Sequence[Hashable]]
The paths in the path complex. If a graph is provided, the path complex will be constructed from the graph, and allowed paths are automatically computed.
- reserve_sequence_orderbool, default=False
If True, reserve the order of the sub-sequence of nodes in the elementary p-path. Else, the sub-sequence of nodes in the elementary p-path will be reversed if the first index is larger than the last index.
- allowed_pathsIterable[tuple[Hashable]], optional
An iterable of allowed boundaries. If None and the input is a Graph, allowed paths are automatically computed by enumerating all simple paths in the graph whose length is less than or equal to max_rank. If None and the input is not a Graph, allowed paths contain the input paths, their truncated subsequences (sub-sequences where the first or the last index is omitted), and any sub-sequences of the truncated subsequences in a recursive manner.
- max_rankint, default=3
The maximal length of a path in the path complex.
- **kwargskeyword arguments, optional
Additional attributes to be associated with the path complex.
- Attributes:
Methods
add_node
(node, **attr)Add node to the path complex.
add_path
(path, **attr)Add an elementary path to the path complex.
add_paths_from
(paths)Add elementary paths from an iterable of elementary paths.
adjacency_matrix
(rank[, signed, weight, index])Compute adjacency matrix of the path complex.
clone
()Return a copy of the path complex.
coadjacency_matrix
(rank[, signed, weight, index])Compute coadjacency matrix of the path complex.
compute_allowed_paths
(graph[, ...])Compute allowed paths from a graph.
down_laplacian_matrix
(rank[, signed, ...])Compute down laplacian matrix of the path complex.
get_edge_attributes
(name)Get edge attributes from a path complex.
get_node_attributes
(name)Get node attributes from a path complex.
get_path_attributes
(name)Get path attributes from a path complex.
hodge_laplacian_matrix
(rank[, signed, ...])Compute Hodge Laplacian matrix of the path complex.
incidence_matrix
(rank[, signed, weight, index])Compute incidence matrix of the path complex.
remove_nodes
(node_set)Remove nodes from the path complex.
restrict_to_nodes
(node_set)Return a new path complex restricted to a subset of nodes.
restrict_to_paths
(path_set)Return a new path complex restricted to a subset of paths.
set_edge_attributes
(values[, name])Set edge attributes for a path complex.
set_node_attributes
(values[, name])Set node attributes for a path complex.
set_path_attributes
(values[, name])Set path attributes for a path complex.
skeleton
(rank)Compute skeleton.
up_laplacian_matrix
(rank[, signed, weight, ...])Compute up laplacian matrix of the path complex.
Notes
By the definition established by [2], a path complex P is a non-empty collection of elementary p-paths such that for any sequence of vertices in a finite non-empty set V that belong to P, the truncated sequence of vertices (which is sometimes referred to as obvious boundaries) also belongs to P. The truncated sequences are sub-sequences of the original elementary p-path where the first or the last index is omitted. For instance, if we have an elementary p-path (1, 2, 3), the truncated sequences are (1,2) and (2,3).
Path complex in [1] is different from the path complex defined in [2] in the sense that elementary p-paths span the space of simple paths. The path complex originally proposed has elementary p-paths that span the space of boundary-invariant paths.
Unlike hypergraphs, combinatorial, simplicial, and cell complexes, path complexes take into account the order of sequences.
References
[1] (1,2)Truong and Chin. Generalizing Topological Graph Neural Networks with Paths. https://arxiv.org/abs/2308.06838.pdf
[2] (1,2,3)Grigor’yan, Lin, Muranov, and Yau. Homologies of path complexes and digraphs. https://arxiv.org/pdf/1207.2834.pdf
Examples
>>> PC = tnx.PathComplex([(1, 2, 3)]) >>> PC.paths PathView([(1,), (2,), (3,), (1, 2), (2, 3), (1, 2, 3)]) >>> PC.add_paths_from([(1, 2, 4), (1, 2, 5), (4, 5)]) >>> PC.paths PathView([(1,), (2,), (3,), (4,), (5,), (1, 2), (2, 3), (2, 4), (2, 5), (4, 5), (1, 2, 3), (1, 2, 4), (1, 2, 5)]) >>> G = nx.Graph() >>> G.add_edges_from([(1, 2), (2, 3), (1, 3)]) >>> PC = tnx.PathComplex(G) >>> PC.paths PathView([(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 3, 2), (1, 2, 3), (2, 1, 3)])
- __init__(paths: Graph | Iterable[Sequence[Hashable] | Path] | None = None, reserve_sequence_order: bool = False, allowed_paths: Iterable[tuple[Hashable]] | None = None, max_rank: int = 3, **kwargs) None [source]#
Initialize a new instance of the Complex class.
- Parameters:
- **kwargskeyword arguments, optional
Attributes to add to the complex as key=value pairs.
Methods
__init__
([paths, reserve_sequence_order, ...])Initialize a new instance of the Complex class.
add_node
(node, **attr)Add node to the path complex.
add_path
(path, **attr)Add an elementary path to the path complex.
add_paths_from
(paths)Add elementary paths from an iterable of elementary paths.
adjacency_matrix
(rank[, signed, weight, index])Compute adjacency matrix of the path complex.
clone
()Return a copy of the path complex.
coadjacency_matrix
(rank[, signed, weight, index])Compute coadjacency matrix of the path complex.
compute_allowed_paths
(graph[, ...])Compute allowed paths from a graph.
down_laplacian_matrix
(rank[, signed, ...])Compute down laplacian matrix of the path complex.
get_edge_attributes
(name)Get edge attributes from a path complex.
get_node_attributes
(name)Get node attributes from a path complex.
get_path_attributes
(name)Get path attributes from a path complex.
hodge_laplacian_matrix
(rank[, signed, ...])Compute Hodge Laplacian matrix of the path complex.
incidence_matrix
(rank[, signed, weight, index])Compute incidence matrix of the path complex.
remove_nodes
(node_set)Remove nodes from the path complex.
restrict_to_nodes
(node_set)Return a new path complex restricted to a subset of nodes.
restrict_to_paths
(path_set)Return a new path complex restricted to a subset of paths.
set_edge_attributes
(values[, name])Set edge attributes for a path complex.
set_node_attributes
(values[, name])Set node attributes for a path complex.
set_path_attributes
(values[, name])Set path attributes for a path complex.
skeleton
(rank)Compute skeleton.
up_laplacian_matrix
(rank[, signed, weight, ...])Compute up laplacian matrix of the path complex.
Attributes
Dimension.
Edges.
Nodes.
Set of all elementary p-paths.
Shape of path complex.
complex
- add_node(node: Hashable | Path, **attr) None [source]#
Add node to the path complex.
- Parameters:
- nodeHashable or Path
A Hashable or singleton Path representing a node in a path complex.
- **attrkeyword arguments
Additional attributes to be provided as keyword arguments.
- add_path(path: Hashable | Sequence[Hashable] | Path, **attr) None [source]#
Add an elementary path to the path complex.
An elementary p-path is a sequence of nodes $(n_1, …, n_p)$ where p is the length of the sequence. In a path complex, for every elementary p-path in the path complex, their truncated sequences $(n_2, …, n_p)$ and $(n_1, …, n_{p-1})$ are also in the path complex.
This method automatically initializes any obvious sub-paths (sub-paths where the first or last index is omitted) of the elementary path if not available. In order to add non-obvious sub-paths, manually add the sub-paths.
- Parameters:
- pathHashable or Sequence[Hashable] or Path
A Hashable or Sequence[Hashable] or Path representing a path in a path complex.
- **attrkeyword arguments, optional
Additional keyword arguments to be passed to the method.
Examples
>>> PC = tnx.PathComplex([(1, 2, 3)]) >>> PC.paths PathView([(1,), (2,), (3,), (1, 2), (2, 3), (1, 2, 3)]) >>> PC.add_path((1, 2, 4)) >>> PC.paths PathView([(1,), (2,), (3,), (4,), (1, 2), (2, 3), (2, 4), (1, 2, 3), (1, 2, 4)])
- add_paths_from(paths: Iterable[Sequence[Hashable] | Path]) None [source]#
Add elementary paths from an iterable of elementary paths.
An elementary p-path is a sequence of nodes $(n_1, …, n_p)$ where $p$ is the length of the sequence. In a path complex, for every elementary p-path in the path complex, their truncated sequences $(n_2, …, n_p)$ and $(n1, …, n_{p-1})$ are also in the path complex.
- Parameters:
- pathsIterable[Sequence[Hashable] or Path]
An iterable of paths as lists, tuples, or Path objects.
Examples
>>> PC = tnx.PathComplex([(1, 2, 3)]) >>> PC.paths PathView([(1,), (2,), (3,), (1, 2), (2, 3), (1, 2, 3)]) >>> PC.add_paths_from([(1, 2, 4), (1, 2, 5), (4, 5)]) >>> PC.paths PathView([(1,), (2,), (3,), (4,), (5,), (1, 2), (2, 3), (2, 4), (2, 5), (4, 5), (1, 2, 3), (1, 2, 4), (1, 2, 5)])
- adjacency_matrix(rank: int, signed: bool = False, weight: str | None = None, index: bool = False) tuple[dict, lil_matrix] | lil_matrix [source]#
Compute adjacency matrix of the path complex.
- Parameters:
- rankint
The dimension of the adjacency matrix.
- signedbool, default=False
If True, return signed adjacency matrix. Else, return absolute adjacency matrix.
- weightstr, default=None, optional
The weight to be used for the adjacency matrix.
- indexbool, default=False
If True, return adjacency matrix with indices. Else, return adjacency matrix without indices.
- Returns:
- tuple[dict, sp.sparse.lil_matrix] | sp.sparse.lil_matrix
If index is True, return a tuple of (idx_p, adjacency_matrix) else return adjacency_matrix.
- clone() Self [source]#
Return a copy of the path complex.
The clone method by default returns an independent shallow copy of the path complex. Use Python’s copy.deepcopy for new containers.
- Returns:
- PathComplex
Returns a copy of the PathComplex.
- coadjacency_matrix(rank: int, signed: bool = False, weight: str | None = None, index: bool = False) tuple[dict, lil_matrix] | lil_matrix [source]#
Compute coadjacency matrix of the path complex.
- Parameters:
- rankint
The dimension of the coadjacency matrix.
- signedbool, default=False
If True, return signed coadjacency matrix. Else, return absolute coadjacency matrix.
- weightstr, default=None, optional
The weight to be used for the adjacency matrix.
- indexbool, default=False
If True, return coadjacency matrix with indices. Else, return coadjacency matrix without indices.
- Returns:
- tuple[dict, sp.sparse.lil_matrix] | sp.sparse.lil_matrix
If index is True, return a tuple of (idx_p, coadjacency_matrix) else return coadjacency_matrix.
- static compute_allowed_paths(graph: Graph, reserve_sequence_order: bool = False, max_rank: int = 3) set[list | tuple] [source]#
Compute allowed paths from a graph.
Allowed paths are automatically computed by enumerating all simple paths in the graph whose length is less than or equal to max_rank. Allowed paths allow us to restrict the boundary of an elementary p-path to only sequences that exist in the graph.
- Parameters:
- graphnx.Graph
A graph.
- reserve_sequence_orderbool, default=False
If True, reserve the order of the sub-sequence of nodes in the elmentary p-path. Else, the sub-sequence of nodes in the elementary p-path will be reversed if the first index is larger than the last index.
- max_rankint, default=3
The maximal length of a path in the path complex.
- Returns:
- set[list | tuple]
A set of allowed paths.
Examples
>>> G = nx.Graph() >>> G.add_edges_from([(1, 2), (2, 3), (1, 3), (0, 1)]) >>> allowed_paths = tnx.PathComplex.compute_allowed_paths(G, max_rank=2) >>> allowed_paths {(0, 1), (1, 3), (1, 2), (2,), (1, 3, 2), (0, 1, 2), (0, 1, 3), (1, 2, 3), (2, 1, 3), (2, 3), (1,), (0,), (3,)}
- property dim: int#
Dimension.
- Returns:
- int
This is the highest dimension of any elementary p-path in the complex.
- down_laplacian_matrix(rank: int, signed: bool = True, weight: str | None = None, index: bool = False) tuple[dict, lil_matrix] | lil_matrix [source]#
Compute down laplacian matrix of the path complex.
- Parameters:
- rankint
The dimension of the down laplacian matrix.
- signedbool, default=True
If True, return signed down laplacian matrix. Else, return absolute down laplacian matrix.
- weightstr, optional
If not given, all nonzero entries are 1.
- indexbool, default=False
If True, return down laplacian matrix with indices. Else, return down laplacian matrix without indices.
- Returns:
- tuple[dict, sp.sparse.lil_matrix] | sp.sparse.lil_matrix
If index is True, return a tuple of (idx_p, down_laplacian_matrix) otherwise if index is False, return down_laplacian_matrix.
- property edges: EdgeView#
Edges.
- Returns:
- EdgeView
A view of all edges in the path complex.
- get_edge_attributes(name: str) dict[tuple[Hashable], Any] [source]#
Get edge attributes from a path complex.
- Parameters:
- namestr
The name of the edge attribute.
- Returns:
- dict[tuple[Hashable], Any]
A dictionary of edge and its associated value for the given attribute name.
Examples
>>> PC = tnx.PathComplex() >>> PC.add_paths_from([[0, 1], [1, 2, 3], [1, 3, 2], [2, 1, 3]]) >>> PC.add_path([0, 1], weight=32) >>> PC.add_path([1, 2], weight=98) >>> PC.add_path([1, 3], color="red") >>> PC.add_path([2, 3], color="blue") >>> PC.get_edge_attributes("weight") {(0, 1): 32, (1, 2): 98} >>> PC.get_edge_attributes("color") {(1, 3): 'red', (2, 3): 'blue'}
- get_node_attributes(name: str) dict[tuple[Hashable], Any] [source]#
Get node attributes from a path complex.
- Parameters:
- namestr
The name of the node attribute.
- Returns:
- dict[tuple[Hashable], Any]
A dictionary of node and its associated value for the given attribute name.
Examples
>>> PC = tnx.PathComplex() >>> PC.add_node(0) >>> PC.add_node(1, heat=55) >>> PC.add_node(2, heat=66) >>> PC.add_node(3, color="red") >>> PC.add_node(2, color="blue") >>> PC.add_paths_from([[0, 1], [1, 2, 3], [1, 3, 2], [2, 1, 3]]) >>> PC.get_node_attributes("heat") {(1,): 55, (2,): 66} >>> PC.get_node_attributes("color") {(2,): 'blue', (3,): 'red'}
- get_path_attributes(name: str) dict[tuple[Hashable], Any] [source]#
Get path attributes from a path complex.
- Parameters:
- namestr
The name of the path attribute.
- Returns:
- dict[tuple[Hashable], Any]
A dictionary of path and its associated value for the given attribute name.
Examples
>>> PC = tnx.PathComplex() >>> PC.add_paths_from([[0, 1]]) >>> PC.add_path([0, 1, 2], weight=43) >>> PC.add_path([0, 1, 3], weight=98) >>> PC.add_path([1, 2, 3], color="red") >>> PC.add_path([1, 3, 2], color="blue") >>> PC.add_path([2, 1, 3], color="green") >>> PC.get_path_attributes("weight") {(0, 1, 2): 43, (0, 1, 3): 98} >>> PC.get_path_attributes("color") {(1, 2, 3): 'red', (1, 3, 2): 'blue', (2, 1, 3): 'green'}
- hodge_laplacian_matrix(rank: int, signed: bool = True, weight: str | None = None, index: bool = False) tuple[dict, lil_matrix] | lil_matrix [source]#
Compute Hodge Laplacian matrix of the path complex.
- Parameters:
- rankint
The dimension of the Hodge Laplacian matrix.
- signedbool, default=False
If True, return signed Hodge Laplacian matrix. Else, return absolute Hodge Laplacian matrix.
- weightstr, optional
If not given, all nonzero entries are 1.
- indexbool, default=False
If True, return Hodge Laplacian matrix with indices. Else, return Hodge Laplacian matrix without indices.
- Returns:
- tuple[dict, sp.sparse.lil_matrix] | sp.sparse.lil_matrix
When index is True, return a tuple of (idx_p, Laplacian) else return Laplacian.
- incidence_matrix(rank: int, signed: bool = True, weight: str | None = None, index: bool = False) tuple[dict, dict, lil_matrix] | lil_matrix [source]#
Compute incidence matrix of the path complex.
- Parameters:
- rankint
The dimension of the incidence matrix.
- signedbool, default=True
If True, return signed incidence matrix. Else, return absolute incidence matrix.
- weightstr, optional
If not given, all nonzero entries are 1.
- indexbool, default=False
If True, return incidence matrix with indices. Else, return incidence matrix without indices.
- Returns:
- tuple[dict, dict, sp.sparse.lil_matrix] | sp.sparse.lil_matrix
If index is True, return a tuple of (idx_p_minus_1, idx_p, incidence_matrix) otherwise if index is False, return incidence_matrix.
- property nodes: NodeView#
Nodes.
- Returns:
- NodeView
A view of all nodes in the path complex.
- property paths: PathView#
Set of all elementary p-paths.
- Returns:
- PathView
A view of all elementary p-paths in the path complex.
- remove_nodes(node_set: Iterable[Hashable]) None [source]#
Remove nodes from the path complex.
- Parameters:
- node_setIterable[Hashable]
An iterable of nodes to be removed.
- restrict_to_nodes(node_set: Iterable[Hashable])[source]#
Return a new path complex restricted to a subset of nodes.
- Parameters:
- node_setIterable[Hashable]
The nodes to be used for the new restricted path complex.
- Returns:
- PathComplex
The new path complex restricted to the provided subset of nodes.
Examples
>>> PC = tnx.PathComplex( ... [[0, 1], [1, 2, 3], [1, 3, 2], [2, 1, 3], [0, 1, 2], [0, 1, 3]] ... ) >>> PC = PC.restrict_to_nodes([0, 1, 3]) >>> PC.paths PathView([(0,), (1,), (3,), (0, 1), (1, 3), (0, 1, 3)])
- restrict_to_paths(path_set: Iterable[Sequence[Hashable]])[source]#
Return a new path complex restricted to a subset of paths.
- Parameters:
- path_setIterable[Sequence[Hashable]]
The paths to be used for the new restricted path complex.
- Returns:
- PathComplex
The new path complex restricted to the provided subset of paths.
Examples
>>> PC = tnx.PathComplex( ... [[0, 1], [1, 2, 3], [1, 3, 2], [2, 1, 3], [0, 1, 2], [0, 1, 3]] ... ) >>> PC = PC.restrict_to_paths([[1, 2, 3]]) >>> PC.paths PathView([(1,), (2,), (3,), (1, 2), (2, 3), (1, 2, 3)])
- set_edge_attributes(values: dict[Sequence[Hashable], Hashable | dict[Hashable, Any]], name: str | None = None) None [source]#
Set edge attributes for a path complex.
- Parameters:
- valuesdict[Sequence[Hashable], Hashable | dict[Hashable, Any]]
A dictionary of edge and its associated attribute values.
- namestr
The name of the edge attribute.
Examples
>>> PC = tnx.PathComplex() >>> PC.add_paths_from([[0, 1], [1, 2, 3], [1, 3, 2], [2, 1, 3]]) >>> PC.add_path([0, 1], weight=32) >>> PC.add_path([1, 2], weight=98) >>> PC.add_path([1, 3], color="red") >>> PC.add_path([2, 3], color="blue") >>> PC.get_edge_attributes("weight") {(0, 1): 32, (1, 2): 98} >>> PC.set_edge_attributes({(0, 1): 33}, name="weight") >>> PC.get_edge_attributes("weight") {(0, 1): 33, (1, 2): 98} >>> PC.set_edge_attributes( ... { ... (1, 3): {"weight": 55, "color": "yellow"}, ... (2, 3): {"weight": 66, "color": "blue"}, ... } ... ) >>> PC[1, 3] {'color': 'yellow', 'weight': 55} >>> PC[2, 3] {'color': 'blue', 'weight': 66}
- set_node_attributes(values: dict[Sequence[Hashable], Hashable | dict[Hashable, Any]], name: str | None = None) None [source]#
Set node attributes for a path complex.
- Parameters:
- valuesdict[Sequence[Hashable], Hashable | dict[Hashable, Any]]
A dictionary of node and its associated attribute values.
- namestr
The name of the node attribute.
Examples
>>> PC = tnx.PathComplex() >>> PC.add_paths_from([[0, 1], [1, 2, 3], [1, 3, 2], [2, 1, 3]]) >>> PC.set_node_attributes( ... { ... (1,): {"heat": 55, "color": "red"}, ... (2,): {"heat": 66, "color": "blue"}, ... } ... ) >>> PC[1] {'heat': 55, 'color': 'red'} >>> PC[2] {'heat': 66, 'color': 'blue'} >>> PC.set_node_attributes({(1,): 58, (2,): 60}, name="heat") >>> PC[1] {'heat': 58, 'color': 'red'} >>> PC[2] {'heat': 60, 'color': 'blue'}
- set_path_attributes(values: dict[Sequence[Hashable], Hashable | dict[Hashable, Any]], name: str | None = None) None [source]#
Set path attributes for a path complex.
- Parameters:
- valuesdict[Sequence[Hashable], Hashable | dict[Hashable, Any]]
A dictionary of path and its associated attribute values.
- namestr
The name of the path attribute.
Examples
>>> PC = tnx.PathComplex( ... [[0, 1], [0, 1, 2], [0, 1, 3], [1, 2, 3], [1, 3, 2], [2, 1, 3]] ... ) >>> PC.set_path_attributes( ... { ... (0, 1, 2): {"weight": 43, "color": "red"}, ... (0, 1, 3): {"weight": 98, "color": "blue"}, ... } ... ) >>> PC.get_path_attributes("weight") {(0, 1, 2): 43, (0, 1, 3): 98} >>> PC.get_path_attributes("color") {(0, 1, 2): 'red', (0, 1, 3): 'blue'} >>> PC.set_path_attributes({0: 55}, "weight") >>> PC.get_path_attributes("weight") {(0,): 55, (0, 1, 2): 43, (0, 1, 3): 98} >>> PC.set_path_attributes({(0, 1): "red"}, "color") >>> PC.get_path_attributes("color") {(0, 1): 'red', (0, 1, 2): 'red', (0, 1, 3): 'blue'}
- property shape: tuple[int, ...]#
Shape of path complex.
(number of elementary p-paths for each dimension d, for d in range(0,dim(Pc)))
- Returns:
- tuple[int, …]
Returns a tuple representing the shape of the path complex.
- skeleton(rank: int) list[tuple[Hashable]] [source]#
Compute skeleton.
- Parameters:
- rankint
The rank to be used to generate the skeleton of elementary p-paths.
- Returns:
- set[tuple[Hashable]]
Set of elementary p-paths of dimension specified by rank.
- up_laplacian_matrix(rank: int, signed: bool = True, weight: str | None = None, index: bool = False) tuple[dict, lil_matrix] | lil_matrix [source]#
Compute up laplacian matrix of the path complex.
- Parameters:
- rankint
The dimension of the up laplacian matrix.
- signedbool, default=True
If True, return signed up laplacian matrix. Else, return absolute up laplacian matrix.
- weightstr, optional
If not given, all nonzero entries are 1.
- indexbool, default=False
If True, return up laplacian matrix with indices. Else, return up laplacian matrix without indices.
- Returns:
- tuple[dict, sp.sparse.lil_matrix] | sp.sparse.lil_matrix
If index is True, return a tuple of (idx_p, up_laplacian_matrix) otherwise if index is False, return up_laplacian_matrix.