Graph containers¶
pbcgraph.graph.PeriodicDiGraph ¶
Directed periodic graph on Z^d.
The quotient is stored as a NetworkX :class:networkx.MultiDiGraph, but
this container enforces an important invariant:
For any fixed triple (u, v, tvec), at most one edge exists.
This means that the translation vector is treated as part of the edge identity. Parallel edges between the same ordered node pair are still possible as long as their translation vectors differ.
Attributes:
| Name | Type | Description |
|---|---|---|
structural_version |
int
|
Incremented when the quotient structure changes (nodes/edges added or removed). |
data_version |
int
|
Incremented when user data changes without structural changes (node/edge attribute updates). |
Notes
- Quotient nodes are
NodeIdvalues. - Each directed edge stores a translation vector (
TVec) that describes how the cell shift changes when traversing that edge in the infinite periodic lift.
is_undirected
property
¶
is_undirected: bool
Whether this container should be treated as undirected by algorithms.
is_multigraph
property
¶
is_multigraph: bool
Whether this container allows multiple edges per (u, v, tvec).
number_of_edges ¶
number_of_edges() -> int
Return the number of directed quotient edges (counts parallel edges).
add_node ¶
add_node(u: NodeId, **attrs: Any) -> None
Add a quotient node.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
u
|
NodeId
|
Node id. |
required |
**attrs
|
Any
|
User attributes. |
{}
|
Notes
- Increments
structural_versionif the node is new. - If the node already exists and
attrsare provided, this updates attributes and incrementsdata_version. - If the node is new, attributes provided at creation do not
increment
data_version(pure structural change semantics).
remove_node ¶
remove_node(u: NodeId) -> None
Remove a quotient node and all incident edges.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
u
|
NodeId
|
Node id. |
required |
Raises:
| Type | Description |
|---|---|
KeyError
|
If |
nodes ¶
nodes(data: bool = False) -> Iterable
Iterate quotient nodes in deterministic order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
bool
|
If True, yield |
False
|
Returns:
| Type | Description |
|---|---|
Iterable
|
Iterable of node ids or |
get_node_data ¶
get_node_data(u: NodeId) -> MappingProxyType
Return a read-only live view of the node attribute mapping.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
u
|
NodeId
|
Node id. |
required |
Raises:
| Type | Description |
|---|---|
KeyError
|
If node is missing. |
set_node_attrs ¶
set_node_attrs(u: NodeId, **attrs: Any) -> None
Update node attributes and increment data_version.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
u
|
NodeId
|
Node id. |
required |
**attrs
|
Any
|
Attributes to set. |
{}
|
Raises:
| Type | Description |
|---|---|
KeyError
|
If node is missing. |
_alloc_key_directed ¶
_alloc_key_directed(u: NodeId, v: NodeId) -> EdgeKey
Allocate a new edge key for a directed edge (u -> v).
Mirrors NetworkX's new_edge_key behavior: start from
len(keys), then increment until unused.
_alloc_key_undirected ¶
_alloc_key_undirected(u: NodeId, v: NodeId) -> EdgeKey
Allocate a new edge key for an undirected edge between u and v.
Keys are allocated in public base-key space. Undirected containers
store directed realizations using private _UKey objects, so the
internal MultiDiGraph keys are not necessarily ints.
_key_for_tvec ¶
_key_for_tvec(
u: NodeId, v: NodeId, tvec: TVec
) -> Optional[EdgeKey]
Return an existing edge key for a given directed (u, v, tvec).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
u
|
NodeId
|
Source node. |
required |
v
|
NodeId
|
Target node. |
required |
tvec
|
TVec
|
Translation vector. |
required |
Returns:
| Type | Description |
|---|---|
Optional[EdgeKey]
|
The corresponding edge key if an edge with this translation exists, |
Optional[EdgeKey]
|
otherwise None. |
_add_edge_impl ¶
_add_edge_impl(
u: NodeId,
v: NodeId,
tvec: TVec,
*,
key: Optional[EdgeKey],
attrs: Dict[str, Any],
) -> EdgeKey
Implementation for adding a directed edge (no (u, v, tvec) checks).
add_edge ¶
add_edge(
u: NodeId,
v: NodeId,
tvec: TVec,
key: Optional[EdgeKey] = None,
**attrs: Any,
) -> EdgeKey
Add a directed periodic edge.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
u
|
NodeId
|
Source node id. |
required |
v
|
NodeId
|
Target node id. |
required |
tvec
|
TVec
|
Translation vector in Z^d. |
required |
key
|
Optional[EdgeKey]
|
Optional explicit edge key. If None, a fresh deterministic key is assigned. |
None
|
**attrs
|
Any
|
User attributes. |
{}
|
Returns:
| Type | Description |
|---|---|
EdgeKey
|
The edge key used. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
has_edge ¶
has_edge(
u: NodeId, v: NodeId, key: Optional[EdgeKey] = None
) -> bool
edge_tvec ¶
edge_tvec(u: NodeId, v: NodeId, key: EdgeKey) -> TVec
Return the structural translation vector for an edge.
get_edge_data ¶
get_edge_data(
u: NodeId, v: NodeId, key: EdgeKey, default: Any = None
) -> Any
Return a read-only live view of the user attribute mapping.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
u
|
NodeId
|
Source node id. |
required |
v
|
NodeId
|
Target node id. |
required |
key
|
EdgeKey
|
Edge key. |
required |
default
|
Any
|
Value to return if edge is missing. |
None
|
Returns:
| Type | Description |
|---|---|
Any
|
A read-only live view of the user attribute mapping, or |
Any
|
if missing. |
set_edge_attrs ¶
set_edge_attrs(
u: NodeId, v: NodeId, key: EdgeKey, **attrs: Any
) -> None
Update user attributes for an edge and increment data_version.
remove_edge ¶
remove_edge(u: NodeId, v: NodeId, key: EdgeKey) -> None
Remove a directed edge.
Raises:
| Type | Description |
|---|---|
KeyError
|
If the edge does not exist. |
edges ¶
edges(
keys: bool = False,
data: bool = False,
tvec: bool = False,
) -> Iterable
Iterate directed edges in deterministic order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
keys
|
bool
|
If True, include the multiedge key. |
False
|
data
|
bool
|
If True, include the read-only user attribute mapping. |
False
|
tvec
|
bool
|
If True, include the translation vector. |
False
|
Returns:
| Type | Description |
|---|---|
Iterable
|
An iterable of:
- |
undirected_edges_unique ¶
undirected_edges_unique(
keys: bool = False,
data: bool = False,
tvec: bool = False,
) -> Iterable
Iterate unique undirected edges in deterministic order.
This iterator is only defined for undirected containers
(PeriodicGraph / PeriodicMultiGraph). It returns each undirected
quotient edge exactly once, in a canonical orientation.
Canonicalization rules
- For
u != v, the returned endpoints satisfyu <= vunder the same ordering policy used elsewhere in pbcgraph. - For quotient self-loops with nonzero translation, the returned
translation vector is canonicalized to
min(tvec, -tvec).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
keys
|
bool
|
If True, include the public base edge key. |
False
|
data
|
bool
|
If True, include the read-only user attribute mapping. |
False
|
tvec
|
bool
|
If True, include the translation vector. |
False
|
Returns:
| Type | Description |
|---|---|
Iterable
|
An iterable of:
- |
Raises:
| Type | Description |
|---|---|
TypeError
|
If called on a directed container. |
neighbors ¶
neighbors(
u: NodeId, keys: bool = False, data: bool = False
) -> Iterable
Iterate outgoing periodic edges from quotient node u.
Yields:
| Type | Description |
|---|---|
Iterable
|
Depending on flags: |
Iterable
|
|
Iterable
|
|
Iterable
|
|
Iterable
|
|
in_neighbors ¶
in_neighbors(
u: NodeId, keys: bool = False, data: bool = False
) -> Iterable
Iterate incoming periodic edges into quotient node u.
The returned translation vector is the one stored on the directed edge
v -> u (i.e. not negated).
Yields:
| Type | Description |
|---|---|
Iterable
|
Depending on flags: |
Iterable
|
|
Iterable
|
|
Iterable
|
|
Iterable
|
|
neighbors_inst ¶
neighbors_inst(
node_inst: NodeInst,
keys: bool = False,
data: bool = False,
) -> Iterable
Iterate outgoing lifted neighbors from a node instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
node_inst
|
NodeInst
|
|
required |
Yields:
| Type | Description |
|---|---|
Iterable
|
Depending on flags: |
Iterable
|
|
Iterable
|
|
Iterable
|
|
Iterable
|
|
in_neighbors_inst ¶
in_neighbors_inst(
node_inst: NodeInst,
keys: bool = False,
data: bool = False,
) -> Iterable
Iterate incoming lifted neighbors into a node instance.
For an incoming edge v -> u with translation tvec, the lifted
neighbor instance for v is shift - tvec.
successors ¶
successors(u: NodeId) -> Iterable[NodeId]
Return successor nodes (quotient) in deterministic order.
predecessors ¶
predecessors(u: NodeId) -> Iterable[NodeId]
Return predecessor nodes (quotient) in deterministic order.
from_edges
classmethod
¶
from_edges(
dim: int,
nodes: Optional[Iterable[Any]] = None,
edges: Optional[Iterable[Any]] = None,
) -> "PeriodicDiGraph"
Construct a graph from nodes and edges.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dim
|
int
|
Lattice dimension. |
required |
nodes
|
Optional[Iterable[Any]]
|
Optional iterable of node ids or |
None
|
edges
|
Optional[Iterable[Any]]
|
Optional iterable of edges, each one of:
- |
None
|
Returns:
| Type | Description |
|---|---|
'PeriodicDiGraph'
|
A graph instance of type |
components ¶
components() -> List['PeriodicComponent']
Return connected components as PeriodicComponent objects.
lift_patch ¶
lift_patch(
seed: NodeInst,
*,
radius: Optional[int] = None,
box: Optional[Tuple[Tuple[int, int], ...]] = None,
box_rel: Optional[Tuple[Tuple[int, int], ...]] = None,
include_edges: bool = True,
max_nodes: Optional[int] = None,
node_order: Optional[Callable[[NodeInst], Any]] = None,
edge_order: Optional[
Callable[[Tuple[Any, ...]], Any]
] = None,
) -> "LiftPatch"
Extract a finite patch of the lifted graph.
This is a thin wrapper over :func:pbcgraph.alg.lift.lift_patch.
Notes
For directed containers this patch is directed by default (exported
as nx.DiGraph / nx.MultiDiGraph). Use
patch.to_networkx(as_undirected=True, ...) for undirected views.
pbcgraph.graph.PeriodicGraph ¶
Bases: PeriodicDiGraph
Undirected periodic graph.
Internally, an undirected periodic edge is represented by two directed realizations:
u -> vwith translationtvecv -> uwith translation-tvec
Both realizations share the same underlying user-attributes dict. The public API returns read-only live views of that mapping.
Important: a crystallographically common pattern is a quotient
self-loop with non-zero translation (u == v and tvec != 0),
representing a bond to a periodic image of the same motif.
NetworkX identifies multiedges by (u, v, key). For self-loops,
the two directed realizations would collide if they shared the same key.
To avoid this, PeriodicGraph stores directed realizations using a private
internal key type _UKey(base, dir), where base is the user-visible
integer key and dir is +1 / -1. The public API always exposes
the base key.
In addition to the undirected-invariant pairing, this container enforces
an invariant analogous to PeriodicDiGraph:
For any undirected triple {u, v, tvec} (up to reversal), at most one
edge exists.
To allow multiple contacts for the same motif pair and translation, use
PeriodicMultiGraph.
Notes
PeriodicGraph is a subclass of PeriodicDiGraph, but restricts some
operations (for example, directed connectivity modes in algorithms).
is_undirected
property
¶
is_undirected: bool
Whether this container should be treated as undirected by algorithms.
edges ¶
edges(
keys: bool = False,
data: bool = False,
tvec: bool = False,
) -> Iterable
Iterate directed realizations in deterministic order.
This iterator yields directed realizations of undirected edges.
Note
For self-loop periodic edges (u == v and tvec != 0), the
two directed realizations share the same (u, v, key) triple and
differ only by the translation vector. If keys=True but
tvec=False, this may yield duplicate (u, u, key) records. Use
tvec=True to disambiguate.
See PeriodicDiGraph.edges for the record formats.
_internal_keys_for_base ¶
_internal_keys_for_base(
u: NodeId, v: NodeId, key: EdgeKey
) -> List[object]
Return internal keys on (u -> v) whose public base key
equals key.
_choose_internal_key ¶
_choose_internal_key(
u: NodeId, v: NodeId, key: EdgeKey
) -> object
Choose a deterministic internal key for accessing shared attrs/tvec.
_has_undirected_base ¶
_has_undirected_base(
u: NodeId, v: NodeId, key: EdgeKey
) -> bool
Return True if an undirected edge with base key exists between u and v.
add_edge ¶
add_edge(
u: NodeId,
v: NodeId,
tvec: TVec,
key: Optional[EdgeKey] = None,
**attrs: Any,
) -> EdgeKey
_add_undirected_impl ¶
_add_undirected_impl(
u: NodeId,
v: NodeId,
tvec: TVec,
*,
key: Optional[EdgeKey],
attrs: Dict[str, Any],
) -> EdgeKey
Implementation for adding an undirected edge (no tvec checks).
check_invariants ¶
check_invariants(*, strict: bool = False) -> Dict[str, Any]
Check undirected pairing invariants.
Returns a structured report and optionally raises on errors.
Invariants checked
- For every directed realization there is a paired reverse one.
- Translation vectors satisfy t(v,u,rev) = -t(u,v,fwd).
- The user-attributes dict is the same object for paired realizations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
strict
|
bool
|
If True, raise ValueError on the first violation. |
False
|
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
A dict with keys: |
pbcgraph.graph.PeriodicMultiDiGraph ¶
Bases: PeriodicDiGraph
Directed periodic multigraph on Z^d.
Unlike PeriodicDiGraph, this container allows multiple edges for the same
directed triple (u, v, tvec). Such parallel edges are distinguished by
their edge keys.
pbcgraph.graph.PeriodicMultiGraph ¶
Bases: PeriodicGraph
Undirected periodic multigraph.
Unlike PeriodicGraph, this container allows multiple undirected edges for
the same motif pair and translation (i.e. multiple edges for the same
undirected {u, v, tvec} up to reversal). Parallel edges are
distinguished by their edge keys.