pub struct SiteIndexNetwork<NodeName, I>{ /* private fields */ }Expand description
Site Index Network (inspired by ITensorNetworks.jl’s IndsNetwork)
Represents the index structure of a tensor network:
- Topology: Graph structure via
NodeNameNetwork - Site space: Physical indices at each node via
HashMap
This structure enables:
- Comparing topologies and site spaces independently of tensor data
- Extracting index information without accessing tensor values
- Validating network structure consistency
§Type Parameters
NodeName: Node name type (must be Clone, Hash, Eq, Send, Sync, Debug)I: Index type (must implementIndexLike)
§Examples
use std::collections::HashSet;
use tensor4all_core::index::{DynId, Index, TagSet};
use tensor4all_treetn::SiteIndexNetwork;
let mut net = SiteIndexNetwork::<String, Index<DynId, TagSet>>::new();
let idx_a = Index::new_dyn(2);
let idx_b = Index::new_dyn(3);
net.add_node("A".to_string(), HashSet::from([idx_a])).unwrap();
net.add_node("B".to_string(), HashSet::from([idx_b])).unwrap();
net.add_edge(&"A".to_string(), &"B".to_string()).unwrap();
assert_eq!(net.node_count(), 2);
assert_eq!(net.edge_count(), 1);Implementations§
Source§impl<NodeName, I> SiteIndexNetwork<NodeName, I>
impl<NodeName, I> SiteIndexNetwork<NodeName, I>
Sourcepub fn with_capacity(nodes: usize, edges: usize) -> Self
pub fn with_capacity(nodes: usize, edges: usize) -> Self
Create a new SiteIndexNetwork with initial capacity.
Sourcepub fn add_node(
&mut self,
node_name: NodeName,
site_space: impl Into<HashSet<I>>,
) -> Result<NodeIndex, String>
pub fn add_node( &mut self, node_name: NodeName, site_space: impl Into<HashSet<I>>, ) -> Result<NodeIndex, String>
Add a node with site space (physical indices).
§Arguments
node_name- The name of the nodesite_space- The physical indices at this node (order doesn’t matter)
Returns an error if the node already exists.
Sourcepub fn rename_node(
&mut self,
old_name: &NodeName,
new_name: NodeName,
) -> Result<(), String>
pub fn rename_node( &mut self, old_name: &NodeName, new_name: NodeName, ) -> Result<(), String>
Rename an existing node and preserve its site-space metadata.
Sourcepub fn site_space(&self, node_name: &NodeName) -> Option<&HashSet<I>>
pub fn site_space(&self, node_name: &NodeName) -> Option<&HashSet<I>>
Get the site space (physical indices) for a node.
Sourcepub fn site_space_mut(
&mut self,
node_name: &NodeName,
) -> Option<&mut HashSet<I>>
pub fn site_space_mut( &mut self, node_name: &NodeName, ) -> Option<&mut HashSet<I>>
Get a mutable reference to the site space for a node.
Warning: Direct modification of site space via this method does NOT
update the reverse lookup (index_to_node). Use add_site_index(),
remove_site_index(), or replace_site_index() for modifications
that maintain consistency.
Sourcepub fn find_node_by_index(&self, index: &I) -> Option<&NodeName>
pub fn find_node_by_index(&self, index: &I) -> Option<&NodeName>
Sourcepub fn find_node_by_index_id(&self, id: &I::Id) -> Option<&NodeName>
pub fn find_node_by_index_id(&self, id: &I::Id) -> Option<&NodeName>
Find the node containing an index by ID.
Sourcepub fn contains_index(&self, index: &I) -> bool
pub fn contains_index(&self, index: &I) -> bool
Check if a site index is registered.
Sourcepub fn add_site_index(
&mut self,
node_name: &NodeName,
index: I,
) -> Result<(), String>
pub fn add_site_index( &mut self, node_name: &NodeName, index: I, ) -> Result<(), String>
Add a site index to a node’s site space.
Updates both the site space and the reverse lookup.
Sourcepub fn remove_site_index(
&mut self,
node_name: &NodeName,
index: &I,
) -> Result<bool, String>
pub fn remove_site_index( &mut self, node_name: &NodeName, index: &I, ) -> Result<bool, String>
Remove a site index from a node’s site space.
Updates both the site space and the reverse lookup.
Sourcepub fn replace_site_index(
&mut self,
node_name: &NodeName,
old_index: &I,
new_index: I,
) -> Result<(), String>
pub fn replace_site_index( &mut self, node_name: &NodeName, old_index: &I, new_index: I, ) -> Result<(), String>
Replace a site index in a node’s site space.
Updates both the site space and the reverse lookup.
Sourcepub fn set_site_space(
&mut self,
node_name: &NodeName,
new_indices: HashSet<I>,
) -> Result<(), String>
pub fn set_site_space( &mut self, node_name: &NodeName, new_indices: HashSet<I>, ) -> Result<(), String>
Replace all site indices for a node with a new set.
Updates both the site space and the reverse lookup. This is an atomic operation that removes all old indices and adds all new ones.
Sourcepub fn site_space_by_index(&self, node: NodeIndex) -> Option<&HashSet<I>>
pub fn site_space_by_index(&self, node: NodeIndex) -> Option<&HashSet<I>>
Get the site space by NodeIndex.
Sourcepub fn add_edge(
&mut self,
n1: &NodeName,
n2: &NodeName,
) -> Result<EdgeIndex, String>
pub fn add_edge( &mut self, n1: &NodeName, n2: &NodeName, ) -> Result<EdgeIndex, String>
Add an edge between two nodes.
Returns an error if either node doesn’t exist.
Sourcepub fn node_index(&self, node_name: &NodeName) -> Option<NodeIndex>
pub fn node_index(&self, node_name: &NodeName) -> Option<NodeIndex>
Get the NodeIndex for a node name.
Sourcepub fn node_name(&self, node: NodeIndex) -> Option<&NodeName>
pub fn node_name(&self, node: NodeIndex) -> Option<&NodeName>
Get the node name for a NodeIndex.
Sourcepub fn node_names(&self) -> Vec<&NodeName>
pub fn node_names(&self) -> Vec<&NodeName>
Get all node names.
Sourcepub fn node_count(&self) -> usize
pub fn node_count(&self) -> usize
Get the number of nodes.
Sourcepub fn edge_count(&self) -> usize
pub fn edge_count(&self) -> usize
Get the number of edges.
Sourcepub fn topology(&self) -> &NodeNameNetwork<NodeName>
pub fn topology(&self) -> &NodeNameNetwork<NodeName>
Get a reference to the underlying topology (NodeNameNetwork).
Sourcepub fn edges(&self) -> impl Iterator<Item = (NodeName, NodeName)> + '_
pub fn edges(&self) -> impl Iterator<Item = (NodeName, NodeName)> + '_
Get all edges as pairs of node names.
Returns an iterator of (NodeName, NodeName) pairs.
Sourcepub fn neighbors(
&self,
node_name: &NodeName,
) -> impl Iterator<Item = NodeName> + '_
pub fn neighbors( &self, node_name: &NodeName, ) -> impl Iterator<Item = NodeName> + '_
Get all neighbors of a node.
Returns an iterator of neighbor node names.
Sourcepub fn graph(&self) -> &StableGraph<(), (), Undirected>
pub fn graph(&self) -> &StableGraph<(), (), Undirected>
Get a reference to the internal graph.
Sourcepub fn graph_mut(&mut self) -> &mut StableGraph<(), (), Undirected>
pub fn graph_mut(&mut self) -> &mut StableGraph<(), (), Undirected>
Get a mutable reference to the internal graph.
Warning: Directly modifying the internal graph can break consistency.
Check if two SiteIndexNetworks share equivalent site index structure.
Two networks are equivalent if:
- Same topology (nodes and edges)
- Same site space for each node
This is used to verify that two TreeTNs can be added or contracted.
Sourcepub fn post_order_dfs(&self, root: &NodeName) -> Option<Vec<NodeName>>
pub fn post_order_dfs(&self, root: &NodeName) -> Option<Vec<NodeName>>
Perform a post-order DFS traversal starting from the given root node.
Sourcepub fn post_order_dfs_by_index(&self, root: NodeIndex) -> Vec<NodeIndex>
pub fn post_order_dfs_by_index(&self, root: NodeIndex) -> Vec<NodeIndex>
Perform a post-order DFS traversal starting from the given root NodeIndex.
Sourcepub fn path_between(
&self,
from: NodeIndex,
to: NodeIndex,
) -> Option<Vec<NodeIndex>>
pub fn path_between( &self, from: NodeIndex, to: NodeIndex, ) -> Option<Vec<NodeIndex>>
Find the shortest path between two nodes.
Sourcepub fn steiner_tree_nodes(
&self,
terminals: &HashSet<NodeIndex>,
) -> HashSet<NodeIndex>
pub fn steiner_tree_nodes( &self, terminals: &HashSet<NodeIndex>, ) -> HashSet<NodeIndex>
Compute the Steiner tree nodes spanning a set of terminal nodes.
Delegates to NodeNameNetwork::steiner_tree_nodes.
§Examples
use std::collections::HashSet;
use tensor4all_core::DynIndex;
use tensor4all_treetn::SiteIndexNetwork;
let mut net: SiteIndexNetwork<String, DynIndex> = SiteIndexNetwork::new();
let a = net.add_node("A".to_string(), HashSet::<DynIndex>::new()).unwrap();
let b = net.add_node("B".to_string(), HashSet::<DynIndex>::new()).unwrap();
let c = net.add_node("C".to_string(), HashSet::<DynIndex>::new()).unwrap();
net.add_edge(&"A".to_string(), &"B".to_string()).unwrap();
net.add_edge(&"B".to_string(), &"C".to_string()).unwrap();
let steiner = net.steiner_tree_nodes(&[a, c].into_iter().collect::<HashSet<_>>());
assert_eq!(steiner, [a, b, c].into_iter().collect());Sourcepub fn is_connected_subset(&self, nodes: &HashSet<NodeIndex>) -> bool
pub fn is_connected_subset(&self, nodes: &HashSet<NodeIndex>) -> bool
Check if a subset of nodes forms a connected subgraph.
Sourcepub fn edges_to_canonicalize(
&self,
current_region: Option<&HashSet<NodeIndex>>,
target: NodeIndex,
) -> CanonicalizeEdges
pub fn edges_to_canonicalize( &self, current_region: Option<&HashSet<NodeIndex>>, target: NodeIndex, ) -> CanonicalizeEdges
Compute edges to canonicalize from current state to target.
Sourcepub fn edges_to_canonicalize_by_names(
&self,
target: &NodeName,
) -> Option<Vec<(NodeName, NodeName)>>
pub fn edges_to_canonicalize_by_names( &self, target: &NodeName, ) -> Option<Vec<(NodeName, NodeName)>>
Compute edges to canonicalize from leaves to target, returning node names.
This is similar to edges_to_canonicalize(None, target) but returns
(from_name, to_name) pairs instead of (NodeIndex, NodeIndex).
See NodeNameNetwork::edges_to_canonicalize_by_names for details.
Sourcepub fn edges_to_canonicalize_to_region(
&self,
target_region: &HashSet<NodeIndex>,
) -> CanonicalizeEdges
pub fn edges_to_canonicalize_to_region( &self, target_region: &HashSet<NodeIndex>, ) -> CanonicalizeEdges
Compute edges to canonicalize from leaves towards a connected region (multiple centers).
See NodeNameNetwork::edges_to_canonicalize_to_region for details.
Sourcepub fn edges_to_canonicalize_to_region_by_names(
&self,
target_region: &HashSet<NodeName>,
) -> Option<Vec<(NodeName, NodeName)>>
pub fn edges_to_canonicalize_to_region_by_names( &self, target_region: &HashSet<NodeName>, ) -> Option<Vec<(NodeName, NodeName)>>
Compute edges to canonicalize towards a region, returning node names.
See NodeNameNetwork::edges_to_canonicalize_to_region_by_names for details.
Sourcepub fn apply_operator_topology(&self, operator: &Self) -> Result<Self, String>
pub fn apply_operator_topology(&self, operator: &Self) -> Result<Self, String>
Check if an operator can act on this state (as a ket).
Returns Ok(result_network) if the operator can act on self,
where result_network is the SiteIndexNetwork of the output state.
For an operator to act on a state:
- They must have the same topology (same nodes and edges)
- The operator must have indices that can contract with the state’s site indices
§Arguments
operator- The operator’s SiteIndexNetwork
§Returns
Ok(SiteIndexNetwork)- The resulting state’s site index network after the operator actsErr(String)- Error message if the operator cannot act on this state
§Note
This is a simplified version that assumes the operator’s output indices have the same structure as the input (i.e., the result has the same site index structure as the original state). For more complex operators with different input/output dimensions, a more sophisticated approach would be needed.
Sourcepub fn compatible_site_dimensions(&self, other: &Self) -> bool
pub fn compatible_site_dimensions(&self, other: &Self) -> bool
Check if this network has compatible site dimensions with another.
Two networks have compatible site dimensions if:
- Same topology (nodes and edges)
- Each node has the same number of site indices
- Site index dimensions match (after sorting, order doesn’t matter)
This is useful for checking if two states can be added or if a state matches the expected output of an operator.
Trait Implementations§
Source§impl<NodeName, I> Clone for SiteIndexNetwork<NodeName, I>
impl<NodeName, I> Clone for SiteIndexNetwork<NodeName, I>
Source§fn clone(&self) -> SiteIndexNetwork<NodeName, I>
fn clone(&self) -> SiteIndexNetwork<NodeName, I>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<NodeName, I> Debug for SiteIndexNetwork<NodeName, I>
impl<NodeName, I> Debug for SiteIndexNetwork<NodeName, I>
Source§impl<NodeName, I> Default for SiteIndexNetwork<NodeName, I>
impl<NodeName, I> Default for SiteIndexNetwork<NodeName, I>
Source§impl<NodeName, I> NetworkTopology<NodeName> for SiteIndexNetwork<NodeName, I>
Implement NetworkTopology for SiteIndexNetwork.
impl<NodeName, I> NetworkTopology<NodeName> for SiteIndexNetwork<NodeName, I>
Implement NetworkTopology for SiteIndexNetwork.
This enables direct use of SiteIndexNetwork for cache invalidation and environment computation without needing adapter types like StaticTopology.
Auto Trait Implementations§
impl<NodeName, I> Freeze for SiteIndexNetwork<NodeName, I>
impl<NodeName, I> RefUnwindSafe for SiteIndexNetwork<NodeName, I>
impl<NodeName, I> Send for SiteIndexNetwork<NodeName, I>
impl<NodeName, I> Sync for SiteIndexNetwork<NodeName, I>
impl<NodeName, I> Unpin for SiteIndexNetwork<NodeName, I>
impl<NodeName, I> UnsafeUnpin for SiteIndexNetwork<NodeName, I>
impl<NodeName, I> UnwindSafe for SiteIndexNetwork<NodeName, I>
Blanket Implementations§
§impl<U> As for U
impl<U> As for U
§fn as_<T>(self) -> Twhere
T: CastFrom<U>,
fn as_<T>(self) -> Twhere
T: CastFrom<U>,
self to type T. The semantics of numeric casting with the as operator are followed, so <T as As>::as_::<U> can be used in the same way as T as U for numeric conversions. Read moreSource§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
fn rand<T>(&self, rng: &mut (impl Rng + ?Sized)) -> Twhere
Self: Distribution<T>,
§impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
fn rand<T>(&self, rng: &mut (impl Rng + ?Sized)) -> Twhere
Self: Distribution<T>,
§impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
fn rand<T>(&self, rng: &mut (impl Rng + ?Sized)) -> Twhere
Self: Distribution<T>,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more