quimb.tensor.networking ======================= .. py:module:: quimb.tensor.networking .. autoapi-nested-parse:: Functionality for analyzing the structure of tensor networks, including finding paths, loops, connected components, hierarchical groupings and more. Classes ------- .. autoapisummary:: quimb.tensor.networking.NetworkPatch quimb.tensor.networking.NetworkPath Functions --------- .. autoapisummary:: quimb.tensor.networking.istree quimb.tensor.networking.isconnected quimb.tensor.networking.subgraphs quimb.tensor.networking.get_tree_span quimb.tensor.networking.get_local_patch quimb.tensor.networking.get_path_between_tids quimb.tensor.networking.gen_all_paths_between_tids quimb.tensor.networking.gen_paths_loops quimb.tensor.networking.gen_sloops quimb.tensor.networking.gen_patches quimb.tensor.networking.connected_bipartitions quimb.tensor.networking._get_two_core_tids quimb.tensor.networking._gen_gloops_single quimb.tensor.networking.gen_gloops quimb.tensor.networking._gen_gloops_edge_induced_single quimb.tensor.networking.gen_gloops_edge_induced quimb.tensor.networking.gen_loops quimb.tensor.networking.get_loop_union quimb.tensor.networking.gen_inds_connected quimb.tensor.networking.tids_are_connected quimb.tensor.networking.compute_shortest_distances quimb.tensor.networking.compute_hierarchical_linkage quimb.tensor.networking.compute_hierarchical_ssa_path quimb.tensor.networking.compute_hierarchical_ordering quimb.tensor.networking.compute_hierarchical_grouping quimb.tensor.networking.compute_centralities quimb.tensor.networking.most_central_tid quimb.tensor.networking.least_central_tid Module Contents --------------- .. py:class:: NetworkPatch(tids, inds) A simple class to represent a patch of tensors and indices, storing both the tensor identifies (`tids`) and indices (`inds`) it contains. .. py:attribute:: __slots__ :value: ('_inds', '_key', '_tids') .. py:attribute:: _tids .. py:attribute:: _inds .. py:attribute:: _key :value: None .. py:method:: from_sequence(it) :classmethod: .. py:property:: tids .. py:property:: num_tensors .. py:property:: inds .. py:property:: num_indices .. py:method:: __iter__() .. py:property:: key .. py:method:: merge(other) .. py:method:: __contains__(x) .. py:method:: __hash__() .. py:method:: __eq__(other) .. py:method:: __repr__() .. py:class:: NetworkPath(tids, inds=()) Bases: :py:obj:`NetworkPatch` A simple class to represent a path through a tensor network, storing both the tensor identifies (`tids`) and indices (`inds`) it passes through. .. py:attribute:: __slots__ :value: ('_inds', '_key', '_tids') .. py:attribute:: _tids .. py:attribute:: _inds :value: () .. py:attribute:: _key :value: None .. py:method:: __len__() .. py:method:: __iter__() .. py:method:: extend(ind, tid) Get a new path by extending this one with a new index and tensor id. .. py:function:: istree(tn) Check if this tensor network has a tree structure, (treating multibonds as a single edge). .. rubric:: Examples >>> MPS_rand_state(10, 7).istree() True >>> MPS_rand_state(10, 7, cyclic=True).istree() False .. py:function:: isconnected(tn) Check whether this tensor network is connected, i.e. whether there is a path between any two tensors, (including size 1 indices). .. py:function:: subgraphs(tn, virtual=False) Split this tensor network into disconneceted subgraphs. :param virtual: Whether the tensor networks should view the original tensors or not - by default take copies. :type virtual: bool, optional :rtype: list[TensorNetwork] .. py:function:: get_tree_span(tn, tids, min_distance=0, max_distance=None, include=None, exclude=None, ndim_sort='max', distance_sort='min', sorter=None, weight_bonds=True, inwards=True) Generate a tree on the tensor network graph, fanning out from the tensors identified by ``tids``, up to a maximum of ``max_distance`` away. The tree can be visualized with :meth:`~quimb.tensor.tensor_core.TensorNetwork.draw_tree_span`. :param tids: The nodes that define the region to span out of. :type tids: sequence of str :param min_distance: Don't add edges to the tree until this far from the region. For example, ``1`` will not include the last merges from neighboring tensors in the region defined by ``tids``. :type min_distance: int, optional :param max_distance: Terminate branches once they reach this far away. If ``None`` there is no limit, :type max_distance: None or int, optional :param include: If specified, only ``tids`` specified here can be part of the tree. :type include: sequence of str, optional :param exclude: If specified, ``tids`` specified here cannot be part of the tree. :type exclude: sequence of str, optional :param ndim_sort: When expanding the tree, how to choose what nodes to expand to next, once connectivity to the current surface has been taken into account. :type ndim_sort: {'min', 'max', 'none'}, optional :param distance_sort: When expanding the tree, how to choose what nodes to expand to next, once connectivity to the current surface has been taken into account. :type distance_sort: {'min', 'max', 'none'}, optional :param weight_bonds: Whether to weight the 'connection' of a candidate tensor to expand out to using bond size as well as number of bonds. :type weight_bonds: bool, optional :returns: The ordered list of merges, each given as tuple ``(tid1, tid2, d)`` indicating merge ``tid1 -> tid2`` at distance ``d``. :rtype: list[(str, str, int)] .. seealso:: :py:obj:`draw_tree_span` .. py:function:: get_local_patch(tn, tids, max_distance, include=None, exclude=None) Get the local patch of tids that is within ``max_distance`` of the given ``tids``. This is like an unordered version of ``get_tree_span``. :param tn: The tensor network to get the local patch from. :type tn: TensorNetwork :param tids: The tensor ids to start from. :type tids: sequence of int :param max_distance: The maximum distance from ``tids`` to include, in terms of graph distance. 0 corresponds to the original ``tids``, 1 to nearest neighbors and so on. :type max_distance: int :param include: If specified, only tids from this set can be included in the patch. :type include: sequence of int, optional :param exclude: If specified, tids from this set cannot be included in the patch. :type exclude: sequence of int, optional :rtype: tuple[int] .. py:function:: get_path_between_tids(tn, tida, tidb) Find a shortest path between ``tida`` and ``tidb`` in this tensor network. Returns a ``NetworkPath`` if a path is found, otherwise ``None``. Currently ignores dangling and hyper indices. :param tn: The tensor network to find a path in. :type tn: TensorNetwork :param tida: The tensor id to start from. :type tida: int :param tidb: The tensor id to end at. :type tidb: int :rtype: NetworkPath or None .. py:function:: gen_all_paths_between_tids(tn, tida, tidb) Generate all shortest paths between ``tida`` and ``tidb`` in this tensor network. Returns a generator of ``NetworkPath`` objects, ignores dangling and hyper indices currently. :param tn: The tensor network to find paths in. :type tn: TensorNetwork :param tida: The tensor id to start from. :type tida: int :param tidb: The tensor id to end at. :type tidb: int :Yields: *NetworkPath* .. py:function:: gen_paths_loops(tn, max_loop_length=None, intersect=False, tids=None, inds=None, paths=None) Generate all paths, up to a specified length, that represent loops in this tensor network. Unlike ``gen_loops`` this function will yield a `NetworkPath` objects, allowing one to differentiate between e.g. a double loop and a 'figure of eight' loop. Dangling and hyper indices are ignored. :param tn: The tensor network to find loops in. :type tn: TensorNetwork :param max_loop_length: Set the maximum number of indices that can appear in a loop. If ``None``, wait until any loop is found and set that as the maximum length. :type max_loop_length: None or int :param intersect: Whether to allow self-intersecting loops. :type intersect: bool, optional :param tids: If supplied, only consider loops containing one of these tensor ids. :type tids: None or sequence of int, optional :param inds: If supplied, only consider loops containing one of these indices. :type inds: None or sequence of str, optional :param paths: If supplied, only consider loops starting from these paths. :type paths: None or sequence of NetworkPath, optional :Yields: *NetworkPath* .. seealso:: :py:obj:`gen_loops`, :py:obj:`gen_inds_connected` .. py:function:: gen_sloops(tn, max_loop_length=None, num_joins=1, intersect=False, tids=None, inds=None, paths=None) .. py:function:: gen_patches(tn, max_size, tids=None, grow_from='all') Generate groups of tids that represent 'patches' of the tensor network, where each patch is a connected subgraph of the tensor network. Unlike generalized loops, patches can contain dangling nodes. :param tn: The tensor network to find patches in. :type tn: TensorNetwork :param max_size: Set the maximum number of tensors that can appear in a region. :type max_size: int :param tids: If supplied, only yield patches containing these tids, see ``grow_from``. :type tids: None or sequence of int, optional :param grow_from: Whether to grow patches from all tids at once ("all") or from any individual tid ("any"). The subsequent patches yielded will either contain all, or at least one of, `tids` specified respectively. :type grow_from: {"all", "any"}, optional :Yields: *tuple[int, ...]* .. py:function:: connected_bipartitions(tn) Generate all connected bipartitions of this tensor network, i.e. pairs of sets of tids (A, B) such that A U B is the full set of tids, A ∩ B = ∅, and both A and B are connected subgraphs. :param tn: The tensor network to find bipartitions in. :type tn: TensorNetwork :returns: The connected bipartitions found, each given as a tuple of frozensets of tids. :rtype: tuple[(frozenset[int, ...], frozenset[int, ...]), ...] .. py:function:: _get_two_core_tids(tn) Get the tids of the 2-core of ``tn``: the largest sub network in which every tensor has at least two bonds. I.e. all dangling tensors are removed. A tid outside the 2-core can never appear in a generalized loop. .. py:function:: _gen_gloops_single(tn, max_size=None, tids=None, grow_from='all') .. py:function:: gen_gloops(tn, max_size=None, tids=None, grow_from='all', num_joins=1, join_overlap=2) Generate sets of tids that represent 'generalized loops' where every node is connected to at least two bonds, i.e. 2-degree connected subgraphs. :param tn: The tensor network to find loops in. :type tn: TensorNetwork :param max_size: The maximum number of tensors that can appear in a region. If ``None``, grow the regions until every target tid, i.e. ``tids`` or every tid, appears in at least one loop, then use that size. Targets outside the 2-core never appear in a loop and are ignored, with a warning if ``tids`` was given or the network is tree like. If ``"min"``, instead use the size of the first valid region found. :type max_size: None, int or "min" :param tids: If supplied, only yield loops containing these tids, see ``grow_from``. :type tids: None or sequence of int, optional :param grow_from: Only if ``tids`` is specified, this determines how to filter loops. If 'all', only yield loops containing *all* of the tids in ``tids``, if 'any', yield loops containing *any* of the tids in ``tids``. If 'alldangle' or 'anydangle', the tids are allowed to be dangling, i.e. 1-degree connected. This is useful for computing local expectations where the operator insertion breaks the loop assumption locally. Any region covers a dangling target, so with these ``max_size=None`` acts like ``"min"``. :type grow_from: {'all', 'any', 'alldangle', 'anydangle'}, optional :param num_joins: If larger than 1, repeatedly generate larger loops by joining together the initial set (individually with size up to ``max_size``) of generalized loops. Each join combines loops that overlap on at least ``join_overlap`` tids. If ``tids`` are supplied, the base loops for each join are generated only around the current patches. An automatic ``max_size`` is resolved from the initial targeted loops and then held fixed. :type num_joins: int, optional :param join_overlap: When joining loops together, the minimum number of overlapping tids they much share. 1 allows merging on a single node, 2 requires sharing a bond, which leads to fewer but 'denser' loops. :type join_overlap: {1, 2}, optional :Yields: *tuple[int]* .. py:function:: _gen_gloops_edge_induced_single(tn, region) Generate all edge-induced loops that span exactly ``region``. Each :class:`NetworkPatch` stores the tensors and retained bonds. .. py:function:: gen_gloops_edge_induced(tn, max_size=None, tids=None, grow_from='all', num_joins=1, join_overlap=2) Generate edge-induced loops as :class:`NetworkPatch` objects. Unlike `gen_gloops`, the same tensor regions can yield multiple patches, differing by whether certain internal bonds are included or not (for example removing the centeral span of an figure of eight). Each patch stores the loop tensors in ``patch.tids`` and its bonds in ``patch.inds``. :func:`gen_gloops` includes every bond between a set of tensors. This function also yields loops that omit bonds while remaining connected and keeping at least two bonds per tensor. :param tn: Tensor network to search. :type tn: TensorNetwork :param max_size: Maximum tensors per region. See :func:`gen_gloops`. :type max_size: None, int or "min" :param tids: Only yield loops that contain these ``tids``. See ``grow_from``. :type tids: None or sequence of int, optional :param grow_from: How to filter loops when ``tids`` is set. See :func:`gen_gloops`. :type grow_from: {'all', 'any', 'alldangle', 'anydangle'}, optional :param num_joins: Number of loops to join per result. See :func:`gen_gloops`. :type num_joins: int, optional :param join_overlap: Minimum number of ``tids`` that joined loops must share. :type join_overlap: {1, 2}, optional :Yields: *NetworkPatch* .. seealso:: :py:obj:`gen_gloops` .. py:function:: gen_loops(tn, max_loop_length=None) Generate sequences of tids that represent loops in the TN. :param max_loop_length: Set the maximum number of tensors that can appear in a loop. If ``None``, wait until any loop is found and set that as the maximum length. :type max_loop_length: None or int :Yields: *tuple[int]* .. seealso:: :py:obj:`gen_paths_loops` .. py:function:: get_loop_union(tn, tids, max_size=None, grow_from='all') Find the union, in terms of tids, of all generliazed loops that pass through either all or at least one of the given tids, depending on `grow_from`. :param tn: The tensor network to find the loop union region in. :type tn: TensorNetwork :param tids: The tensor ids to consider. :type tids: sequence of int :param max_size: The maximum number of tensors that can appear in the region. If ``None``, grow the regions until every tid in ``tids`` appears in at least one loop, then use that size. If ``"min"``, instead use the size of the first valid region found. See :func:`gen_gloops`. :type max_size: None, int or "min", optional :param grow_from: Only if ``tids`` is specified, this determines how to filter loops. If 'all', only take loops containing *all* of the tids in ``tids``, if 'any', yield loops containing *any* of the tids in ``tids``. If 'alldangle' or 'anydangle', the base tids are allowed to be dangling, i.e. 1-degree connected. :type grow_from: {'all', 'any', 'alldangle', 'anydangle'}, optional :rtype: tuple[int] .. py:function:: gen_inds_connected(tn, max_length) Generate all index 'patches' of size up to ``max_length``. :param max_length: The maximum number of indices in the patch. :type max_length: int :Yields: *tuple[str]* .. seealso:: :py:obj:`gen_paths_loops` .. py:function:: tids_are_connected(tn, tids) Check whether nodes ``tids`` are connected. :param tn: The tensor network to check. :type tn: TensorNetwork :param tids: Nodes to check. :type tids: sequence of int :rtype: bool .. py:function:: compute_shortest_distances(tn, tids=None, exclude_inds=()) Compute the minimum graph distances between all or some nodes ``tids``. :param tn: The tensor network to compute distances in. :type tn: TensorNetwork :param tids: If supplied, only compute distances between these nodes. :type tids: None or sequence of int, optional :param exclude_inds: Exclude these indices when computing distances. :type exclude_inds: sequence of str, optional :rtype: dict[tuple[int, int], int] .. py:function:: compute_hierarchical_linkage(tn, tids=None, method='weighted', optimal_ordering=True, exclude_inds=()) .. py:function:: compute_hierarchical_ssa_path(tn, tids=None, method='weighted', optimal_ordering=True, exclude_inds=(), are_sorted=False, linkage=None) Compute a hierarchical grouping of ``tids``, as a ``ssa_path``. .. py:function:: compute_hierarchical_ordering(tn, tids=None, method='weighted', optimal_ordering=True, exclude_inds=(), linkage=None) Compute a hierarchical ordering of ``tids``. .. py:function:: compute_hierarchical_grouping(tn, max_group_size, tids=None, method='weighted', optimal_ordering=True, exclude_inds=(), linkage=None) Group ``tids`` (by default, all tensors) into groups of size ``max_group_size`` or less, using a hierarchical clustering. .. py:function:: compute_centralities(tn) Compute a simple centrality measure for each tensor in the network. The values go from 0 to 1, with 1 being the most central tensor. :param tn: The tensor network to compute centralities for. :type tn: TensorNetwork :rtype: dict[int, float] .. py:function:: most_central_tid(tn) Find the most central tensor in the network. .. py:function:: least_central_tid(tn) Find the least central tensor in the network.