xgi.core.simplicialcomplex.SimplicialComplex#
- class SimplicialComplex(incoming_data=None, **attr)[source]#
Bases:
HypergraphA class to represent undirected simplicial complexes.
A simplicial complex is a collection of subsets of a set of nodes or vertices. It is a pair \((V, E)\), where \(V\) is a set of elements called nodes or vertices, and \(E\) is a set whose elements are subsets of \(V\), that is, each \(e \in E\) satisfies \(e \subset V\). The elements of \(E\) are called simplices. Additionally, if a simplex is part of a simplicial complex, all its faces must be too. This makes simplicial complexes a special case of hypergraphs.
The SimplicialComplex class allows any hashable object as a node and can associate attributes to each node, simplex, or the simplicial complex itself, in the form of key/value pairs.
- Parameters:
incoming_data (input simplicial complex data, optional) –
Data to initialize the simplicial complex. If None (default), an empty simplicial complex is created, i.e. one with no nodes or simplices. The data can be in the following formats:
simplex list
simplex dictionary
2-column Pandas dataframe (bipartite edges)
Incidence matrix: numpy ndarray or scipy.sparse array
SimplicialComplex object
Hypergraph object
**attr (dict, optional) – Attributes to add to the simplicial complex as key, value pairs. By default, None.
See also
Notes
Unique IDs are assigned to each node and simplex internally and are used to refer to them throughout.
The attr keyword arguments are added as simplicial complex attributes. To add node or simplex attributes see
add_node()andadd_simplex(). Methods such asadd_simplex()replaceHypergraphmethods such asadd_edge()which here raise an error.Per-node and per-edge statistics are available through the
statsframework, just like forHypergraph. Access them viaS.nodes.<stat>andS.edges.<stat>.Algorithms in
xgi.algorithmswork on simplicial complexes too, e.g.,xgi.connected_components(S),xgi.clustering_coefficient(S). Simpliciality measures (edit_simpliciality(),simplicial_fraction(), etc.) are particularly relevant for this class.Examples
>>> import xgi >>> S = xgi.SimplicialComplex([[1, 2, 3], [4], [5, 6], [6, 7, 8]]) >>> S.nodes NodeView((1, 2, 3, 4, 5, 6, 7, 8)) >>> S.edges EdgeView((0, 1, 2, 3, 4, 5, 6, 7, 8, 9))
Attributes
edgesAn
EdgeViewof this network.nodesA
NodeViewof this network.num_edgesThe number of edges in the hypergraph.
num_nodesThe number of nodes in the hypergraph.
Checks whether a simplicial complex is frozen
Methods
add_nodeAdd one node with optional attributes.
add_nodes_fromAdd multiple nodes with optional attributes.
Add a simplex to the simplicial complex, and all its subfaces that do not exist yet.
Add multiple edges with optional attributes.
Add weighted simplices in ebunch_to_add with specified weight attr
Remove a simplex with a given id.
Remove all simplicies specified in ebunch.
Remove a single node.
Remove multiple nodes.
Adds all missing subfaces to the complex.
Whether a simplex appears in the simplicial complex.
Removes potentially undesirable artifacts from the hypergraph.
Method for freezing a simplicial complex which prevents it from being modified
Inherited methods that cannot be used
Add one edge with optional attributes.
Add multiple edges with optional attributes.
Add multiple weighted edges with optional attributes.
Remove one edge.
Remove multiple edges.
- add_edge(*args, **kwargs)[source]#
Add one edge with optional attributes.
- Parameters:
members (Iterable) – An iterable of the ids of the nodes contained in the new edge.
idx (hashable, optional) – Id of the new edge. If None (default), a unique numeric ID will be created.
**attr (dict, optional) – Attributes of the new edge.
- Raises:
XGIError – If members is empty.
Examples
Add edges with or without specifying an edge id.
>>> import xgi >>> H = xgi.Hypergraph() >>> H.add_edge([1, 2, 3]) >>> H.add_edge([3, 4], idx='myedge') >>> H.edges EdgeView((0, 'myedge'))
Access attributes using square brackets. By default no attributes are created.
>>> H.edges[0] {} >>> H.add_edge([1, 4], color='red', place='peru') >>> H.edges EdgeView((0, 'myedge', 1)) >>> H.edges[1] {'color': 'red', 'place': 'peru'}
- add_edges_from(*args, **kwargs)[source]#
Add multiple edges with optional attributes.
- Parameters:
ebunch_to_add (Iterable) –
An iterable of edges. This may be an iterable of iterables (Format 1), where each element contains the members of the edge specified as valid node IDs. Alternatively, each element could also be a tuple in any of the following formats:
Format 2: 2-tuple (members, edge_id), or
Format 3: 2-tuple (members, attr), or
Format 4: 3-tuple (members, edge_id, attr),
where members is an iterable of node IDs, edge_id is a hashable to use as edge ID, and attr is a dict of attributes. Finally, ebunch_to_add may be a dict of the form {edge_id: edge_members} (Format 5).
Formats 2 and 3 are unambiguous because attr dicts are not hashable, while id`s must be. In Formats 2-4, each element of `ebunch_to_add must have the same length, i.e. you cannot mix different formats. The iterables containing edge members cannot be strings.
**attr (kwargs, optional) – Additional attributes to be assigned to all edges. Attribues specified via ebunch_to_add take precedence over attr.
See also
add_edgeAdd a single edge.
add_weighted_edges_fromConvenient way to add weighted edges.
set_edge_attributesNotes
Adding the same edge twice will create a multi-edge. Currently cannot add empty edges; the method skips over them.
Examples
>>> import xgi >>> H = xgi.Hypergraph()
When specifying edges by their members only, numeric edge IDs will be assigned automatically.
>>> H.add_edges_from([[0, 1], [1, 2], [2, 3, 4]]) >>> H.edges.members(dtype=dict) {0: {0, 1}, 1: {1, 2}, 2: {2, 3, 4}}
Custom edge ids can be specified using a dict.
>>> H = xgi.Hypergraph() >>> H.add_edges_from({'one': [0, 1], 'two': [1, 2], 'three': [2, 3, 4]}) >>> H.edges.members(dtype=dict) {'one': {0, 1}, 'two': {1, 2}, 'three': {2, 3, 4}}
You can use the dict format to easily add edges from another hypergraph.
>>> H2 = xgi.Hypergraph() >>> H2.add_edges_from(H.edges.members(dtype=dict)) >>> H.edges == H2.edges True
Alternatively, edge ids can be specified using an iterable of 2-tuples.
>>> H = xgi.Hypergraph() >>> H.add_edges_from([([0, 1], 'one'), ([1, 2], 'two'), ([2, 3, 4], 'three')]) >>> H.edges.members(dtype=dict) {'one': {0, 1}, 'two': {1, 2}, 'three': {2, 3, 4}}
Attributes for each edge may be specified using a 2-tuple for each edge. Numeric IDs will be assigned automatically.
>>> H = xgi.Hypergraph() >>> edges = [ ... ([0, 1], {'color': 'red'}), ... ([1, 2], {'age': 30}), ... ([2, 3, 4], {'color': 'blue', 'age': 40}), ... ] >>> H.add_edges_from(edges) >>> {e: H.edges[e] for e in H.edges} {0: {'color': 'red'}, 1: {'age': 30}, 2: {'color': 'blue', 'age': 40}}
Attributes and custom IDs may be specified using a 3-tuple for each edge.
>>> H = xgi.Hypergraph() >>> edges = [ ... ([0, 1], 'one', {'color': 'red'}), ... ([1, 2], 'two', {'age': 30}), ... ([2, 3, 4], 'three', {'color': 'blue', 'age': 40}), ... ] >>> H.add_edges_from(edges) >>> {e: H.edges[e] for e in H.edges} {'one': {'color': 'red'}, 'two': {'age': 30}, 'three': {'color': 'blue', 'age': 40}}
- add_simplex(members, idx=None, **attr)[source]#
Add a simplex to the simplicial complex, and all its subfaces that do not exist yet.
Simplex attributes can be specified with keywords or by directly accessing the simplex’s attribute dictionary. The attributes do not propagate to the subfaces.
- Parameters:
members (Iterable) – An iterable of the ids of the nodes contained in the new simplex.
idx (hashable, optional) – Id of the new simplex. If None (default), a unique numeric ID will be created.
**attr (dict, optional) – Attributes of the new simplex.
See also
add_simplices_fromAdd a collection of simplices.
Notes
Currently cannot add empty simplices.
Examples
Add simplices with or without specifying an simplex idx.
>>> import xgi >>> S = xgi.SimplicialComplex() >>> S.add_simplex([1, 2, 3]) >>> S.edges.members() [frozenset({1, 2, 3}), frozenset({2, 3}), frozenset({1, 2}), frozenset({1, 3})] >>> S.add_simplex([3, 4], idx='myedge') >>> S.edges EdgeView((0, 1, 2, 3, 'myedge'))
Access attributes using square brackets. By default no attributes are created.
>>> S.edges[0] {} >>> S.add_simplex([1, 4], color='red', place='peru') >>> S.edges EdgeView((0, 1, 2, 3, 'myedge', 4)) >>> S.edges[4] {'color': 'red', 'place': 'peru'}
- add_simplices_from(ebunch_to_add, max_order=None, **attr)[source]#
Add multiple edges with optional attributes.
- Parameters:
ebunch_to_add (Iterable) –
An iterable of simplices. This may be an iterable of iterables (Format 1), where each element contains the members of the simplex specified as valid node IDs. Alternatively, each element could also be a tuple in any of the following formats:
Format 2: 2-tuple (members, simplex_id), or
Format 3: 2-tuple (members, attr), or
Format 4: 3-tuple (members, simplex_id, attr),
where members is an iterable of node IDs, simplex_id is a hashable to use as simplex ID, and attr is a dict of attributes. Finally, ebunch_to_add may be a dict of the form {simplex_id: simplex_members} (Format 5).
Formats 2 and 3 are unambiguous because attr dicts are not hashable, while id`s must be. In Formats 2-4, each element of `ebunch_to_add must have the same length, i.e. you cannot mix different formats. The iterables containing simplex members cannot be strings.
max_order (int, optional) – Maximal dimension of simplices to add. If None (default), adds all simplices. If int, and ebunch_to_add contains simplices of order > max_order, creates and adds all its subfaces up to max_order.
**attr (kwargs, optional) – Additional attributes to be assigned to all simplices. Attribues specified via ebunch_to_add take precedence over attr.
See also
add_simplexadd a single simplex
add_weighted_simplices_fromconvenient way to add weighted simplices
Notes
Adding the same simplex twice will add it only once. Currently cannot add empty simplices; the method skips over them.
Examples
>>> import xgi >>> S = xgi.SimplicialComplex()
When specifying simplices by their members only, numeric simplex IDs will be assigned automatically.
>>> S.add_simplices_from([[0, 1], [1, 2], [2, 3, 4]]) >>> S.edges.members(dtype=dict) {0: frozenset({0, 1}), 1: frozenset({1, 2}), 2: frozenset({2, 3, 4}), 3: frozenset({2, 3}), 4: frozenset({2, 4}), 5: frozenset({3, 4})}
Custom simplex ids can be specified using a dict.
>>> S = xgi.SimplicialComplex() >>> S.add_simplices_from({'one': [0, 1], 'two': [1, 2], 'three': [2, 3, 4]}) >>> S.edges.members(dtype=dict) {'one': frozenset({0, 1}), 'two': frozenset({1, 2}), 'three': frozenset({2, 3, 4}), 0: frozenset({2, 3}), 1: frozenset({2, 4}), 2: frozenset({3, 4})}
You can use the dict format to easily add simplices from another simplicial complex.
>>> S2 = xgi.SimplicialComplex() >>> S2.add_simplices_from(S.edges.members(dtype=dict)) >>> list(S.edges) == list(S2.edges) True
Alternatively, simplex ids can be specified using an iterable of 2-tuples.
>>> S = xgi.SimplicialComplex() >>> S.add_simplices_from([([0, 1], 'one'), ([1, 2], 'two'), ([2, 3, 4], 'three')]) >>> S.edges.members(dtype=dict) {'one': frozenset({0, 1}), 'two': frozenset({1, 2}), 'three': frozenset({2, 3, 4}), 0: frozenset({2, 3}), 1: frozenset({2, 4}), 2: frozenset({3, 4})}
Attributes for each simplex may be specified using a 2-tuple for each simplex. Numeric IDs will be assigned automatically.
>>> S = xgi.SimplicialComplex() >>> simplices = [ ... ([0, 1], {'color': 'red'}), ... ([1, 2], {'age': 30}), ... ([2, 3, 4], {'color': 'blue', 'age': 40}), ... ] >>> S.add_simplices_from(simplices) >>> {e: S.edges[e] for e in S.edges} {0: {'color': 'red'}, 1: {'age': 30}, 2: {'color': 'blue', 'age': 40}, 3: {}, 4: {}, 5: {}}
Attributes and custom IDs may be specified using a 3-tuple for each simplex.
>>> S = xgi.SimplicialComplex() >>> simplices = [ ... ([0, 1], 'one', {'color': 'red'}), ... ([1, 2], 'two', {'age': 30}), ... ([2, 3, 4], 'three', {'color': 'blue', 'age': 40}), ... ] >>> S.add_simplices_from(simplices) >>> {e: S.edges[e] for e in S.edges} {'one': {'color': 'red'}, 'two': {'age': 30}, 'three': {'color': 'blue', 'age': 40}, 0: {}, 1: {}, 2: {}}
- add_weighted_edges_from(*args, **kwargs)[source]#
Add multiple weighted edges with optional attributes.
- Parameters:
ebunch_to_add (iterable of edges) – Each edge given in the list or container will be added to the graph. The edges must be given as tuples of the form (node1, node2, …, noden, weight).
weight (string, optional) – The attribute name for the edge weights to be added, by default “weight”.
attr (keyword arguments, optional) – Edge attributes to add/update for all edges.
See also
add_edgeAdd a single edge.
add_edges_fromAdd multiple edges.
set_edge_attributes,get_edge_attributesNotes
Adding the same edge twice creates a multiedge.
Examples
>>> import xgi >>> H = xgi.Hypergraph() >>> edges = [(0, 1, 0.3), (0, 2, 0.8)] >>> H.add_weighted_edges_from(edges) >>> H.edges[0] {'weight': 0.3}
- add_weighted_simplices_from(ebunch_to_add, max_order=None, weight='weight', **attr)[source]#
Add weighted simplices in ebunch_to_add with specified weight attr
- Parameters:
ebunch_to_add (iterable of simplices) – Each simplex given in the list or container will be added to the graph. The simplices must be given as tuples of the form (node1, node2, …, noden, weight).
max_order (int, optional) – The maximum order simplex to add, by default None.
weight (string, optional) – The attribute name for the simplex weights to be added. By default, “weight”.
attr (keyword arguments, optional (default= no attributes)) – simplex attributes to add/update for all simplices.
See also
add_simplexadd a single simplex
add_simplices_fromadd multiple simplices
Notes
Adding the same simplex twice will add it only once.
Example
>>> import xgi >>> S = xgi.SimplicialComplex() >>> simplices = [(0, 1, 0.3), (0, 2, 0.8)] >>> S.add_weighted_simplices_from(simplices) >>> S.edges[0] {'weight': 0.3}
- cleanup(isolates=False, empties=False, connected=True, relabel=True, in_place=True)[source]#
Removes potentially undesirable artifacts from the hypergraph.
- Parameters:
isolates (bool, optional) – Whether isolated nodes are allowed, by default False.
singletons (bool, optional) – Whether singleton edges are allowed, by default False.
empties (bool, optional) – Whether empty edges (edges with no nodes) are allowed, by default False.
multiedges (bool, optional) – Whether multiedges are allowed, by default False.
connected (bool, optional) – Whether the returned hypergraph should be connected. If true, returns the hypergraph induced on the largest connected component. By default, False.
relabel (bool, optional) – Whether to convert all node and edge labels to sequential integers, by default True.
in_place (bool, optional) – Whether to modify the current hypergraph or output a new one, by default True.
- close()[source]#
Adds all missing subfaces to the complex.
See also
add_simplexadd a single simplex
add_weighted_simplices_fromconvenient way to add weighted simplices
Notes
Adding the same simplex twice will add it only once. Currently cannot add empty simplices; the method skips over them.
- copy()[source]#
A deep copy of the simplicial complex.
A deep copy of the simplicial complex, including node, edge, and network attributes.
- Returns:
S – A copy of the simplicial complex.
- Return type:
- freeze()[source]#
Method for freezing a simplicial complex which prevents it from being modified
See also
frozenMethod that raises an error when a
useris_frozenCheck whether a simplicial complex is frozen
Examples
>>> import xgi >>> edges = [[1, 2], [2, 3, 4]] >>> S = xgi.SimplicialComplex(edges) >>> S.freeze() >>> S.add_node(5) Traceback (most recent call last): xgi.exception.XGIError: Frozen higher-order network can't be modified
- has_simplex(simplex)[source]#
Whether a simplex appears in the simplicial complex.
- Parameters:
simplex (list or set) – An iterable of hashables that specifies an simplex
- Returns:
Whether or not simplex is as a simplex in the simplicial complex.
- Return type:
bool
Examples
>>> import xgi >>> S = xgi.SimplicialComplex([[1, 2], [2, 3, 4]]) >>> S.has_simplex([1, 2]) True >>> S.has_simplex({1, 3}) False
- property is_frozen#
Checks whether a simplicial complex is frozen
- Returns:
True if simplicial complex is frozen, false if not.
- Return type:
bool
See also
freezeA method to prevent a simplicial complex from being modified.
Examples
>>> import xgi >>> edges = [[1, 2], [2, 3, 4]] >>> S = xgi.SimplicialComplex(edges) >>> S.freeze() >>> S.is_frozen True
- remove_edge(*args, **kwargs)[source]#
Remove one edge.
- Parameters:
idx (Hashable) – edge ID to remove
- Raises:
XGIError – If no edge has that ID.
See also
remove_edges_fromRemove multiple edges.
- remove_edges_from(*args, **kwargs)[source]#
Remove multiple edges.
- Parameters:
ebunch (Iterable) – Edges to remove.
- Raises:
xgi.exception.IDNotFound – If an id in ebunch is not part of the network.
See also
remove_edgeremove a single edge.
- remove_node(n)[source]#
Remove a single node.
The removal is strong meaning that all edges containing the node are removed.
- Parameters:
n (node) – A node in the simplicial complex
- Raises:
XGIError – If n is not in the simplicial complex.
See also
- remove_nodes_from(nodes)[source]#
Remove multiple nodes.
- Parameters:
nodes (iterable) – An iterable of nodes.
See also
- remove_simplex_id(idx)[source]#
Remove a simplex with a given id.
This also removes all simplices of which this simplex is face, to preserve the simplicial complex structure.
- Parameters:
idx (Hashable) – edge ID to remove
- Raises:
XGIError – If no edge has that ID.
See also
remove_edges_fromremove a collection of edges
- remove_simplex_ids_from(ebunch)[source]#
Remove all simplicies specified in ebunch.
- Parameters:
ebunch (list or iterable of hashables) – Each edge id given in the list or iterable will be removed from the Simplicialcomplex.
- Raises:
xgi.exception.IDNotFound – If an id in ebunch is not part of the network.
See also
remove_simplex_idremove a single simplex by ID.