quimb.tensor.belief_propagation.d1bp ==================================== .. py:module:: quimb.tensor.belief_propagation.d1bp .. autoapi-nested-parse:: Belief propagation for standard tensor networks. This: - assumes no hyper indices, only standard bonds. - assumes a single ('dense') tensor per site - works directly on the '1-norm' i.e. scalar tensor network - supports sparse COO-format tensors, which have specialized numba kernels This is the simplest version of belief propagation, and is useful for simple investigations. Classes ------- .. autoapisummary:: quimb.tensor.belief_propagation.d1bp.D1BP Functions --------- .. autoapisummary:: quimb.tensor.belief_propagation.d1bp.initialize_messages quimb.tensor.belief_propagation.d1bp.contract_d1bp Module Contents --------------- .. py:function:: initialize_messages(tn, fill_fn=None) .. py:class:: D1BP(tn: quimb.tensor.TensorNetwork, *, messages=None, damping=0.0, diis=False, update='sequential', normalize=None, distance=None, local_convergence=True, message_init_function=None, contract_every=None, inplace=False) Bases: :py:obj:`quimb.tensor.belief_propagation.bp_common.BeliefPropagationCommon` Dense (as in one tensor per site) 1-norm (as in for 'classical' systems) belief propagation algorithm. Allows message reuse. This version assumes no hyper indices (i.e. a standard tensor network). This is the simplest version of belief propagation. The tensors can be sparse COO-format tensors, either from pydata-sparse or scipy-sparse. :param tn: The tensor network to run BP on. :type tn: TensorNetwork :param messages: The initial messages to use, effectively defaults to all ones if not specified. :type messages: dict[(str, int), array_like], optional :param damping: The damping factor to apply to messages. This simply mixes some part of the old message into the new one, with the final message being ``damping * old + (1 - damping) * new``. This makes convergence more reliable but slower. :type damping: float or callable, optional :param diis: Whether to use direct inversion in the iterative subspace to help converge the messages by extrapolating to low error guesses. If a dict, should contain options for the DIIS algorithm. The relevant options are {`max_history`, `beta`, `rcond`}. :type diis: bool or dict, optional :param update: Whether to update messages sequentially (newly computed messages are immediately used for other updates in the same iteration round) or in parallel (all messages are comptued using messages from the previous round only). Sequential generally helps convergence but parallel can possibly converge to differnt solutions. :type update: {'sequential', 'parallel'}, optional :param normalize: How to normalize messages after each update. If None choose automatically. If a callable, it should take a message and return the normalized message. If a string, it should be one of 'L1', 'L2', 'L2phased', 'Linf' for the corresponding norms. 'L2phased' is like 'L2' but also normalizes the phase of the message, by default used for complex dtypes. :type normalize: {'L1', 'L2', 'L2phased', 'Linf', callable}, optional :param distance: How to compute the distance between messages to check for convergence. If None choose automatically. If a callable, it should take two messages and return the distance. If a string, it should be one of 'L1', 'L2', 'L2phased', 'Linf', or 'cosine' for the corresponding norms. 'L2phased' is like 'L2' but also normalizes the phases of the messages, by default used for complex dtypes if phased normalization is not already being used. :type distance: {'L1', 'L2', 'L2phased', 'Linf', 'cosine', callable}, optional :param local_convergence: Whether to allow messages to locally converge - i.e. if all their input messages have converged then stop updating them. :type local_convergence: bool, optional :param contract_every: If not None, 'contract' (via BP) the tensor network every ``contract_every`` iterations. The resulting values are stored in ``zvals`` at corresponding points ``zval_its``. :type contract_every: int, optional :param inplace: Whether to perform any operations inplace on the input tensor network. :type inplace: bool, optional .. attribute:: tn The target tensor network. :type: TensorNetwork .. attribute:: messages The current messages. The key is a tuple of the index and tensor id that the message is being sent to. :type: dict[(str, int), array_like] .. attribute:: key_pairs A dictionary mapping the key of a message to the key of the message propagating in the opposite direction. :type: dict[(str, int), (str, int)] .. py:attribute:: sparse .. py:attribute:: local_convergence :value: True .. py:attribute:: touched .. py:attribute:: key_pairs .. py:method:: iterate(tol=5e-06) Perform a single iteration of belief propagation. Subclasses should implement this method, returning either `max_mdiff` or a dictionary containing `max_mdiff` and any other relevant information: { "nconv": nconv, "ncheck": ncheck, "max_mdiff": max_mdiff, } .. py:method:: normalize_message_pairs() Normalize all messages such that for each bond ` = 1` and ` = ` (but in general != 1). .. py:method:: normalize_tensors(strip_exponent=True) Normalize every local tensor contraction so that it equals 1. Gather the overall normalization factor into ``self.exponent`` and the sign into ``self.sign`` by default. :param strip_exponent: Whether to collect the sign and exponent. If ``False`` then the value of the BP contraction is set to 1. :type strip_exponent: bool, optional .. py:method:: get_normalized_tn() Get a normalized copy of the target tensor network. This method rescales each tensor so its local BP contraction is one. It uses the current messages. It returns the normalization scale separately. It does not modify the target network, the messages, or the scale in this instance. :returns: * **tn** (*TensorNetwork*) -- The normalized copy of the target tensor network. * **sign** (*scalar*) -- The phase or sign of the normalization scale. * **exponent** (*float*) -- The base-10 exponent of the normalization scale. .. py:method:: get_gauged_tn() Gauge the original TN by inserting the BP-approximated transfer matrix eigenvectors, which may be complex. The BP-contraction of this gauged network is then simply the product of zeroth entries of each tensor. .. py:method:: get_cluster(tids, tn=None) Get the region of tensors given by `tids`, with the messages on the border contracted in, removing those dangling indices. :param tids: The tensor ids forming a region. :type tids: sequence of int :param tn: The tensor network from which to select the region. The boundary messages always come from this D1BP instance. :type tn: TensorNetwork, optional :rtype: TensorNetwork .. py:method:: get_cluster_excited(gloop) Build the local loop excitation tensor network for ``gloop``. Insert BP messages on boundary bonds and excitation projectors on all or selected inner bonds. See https://arxiv.org/abs/2409.03108. :param gloop: The region ``tids``. A :class:`~quimb.tensor.networking.NetworkPatch` also selects the subset of inner excited bonds. Non-excited inner bonds are treated like boundary bonds. See :func:`~quimb.tensor.networking.gen_gloops_edge_induced`. :type gloop: sequence[int] or NetworkPatch :rtype: TensorNetwork .. py:method:: contract_loop_series_expansion(gloops=None, multi_excitation_correct=True, tol_correction=1e-12, maxiter_correction=100, strip_exponent=False, optimize='auto-hq', **contract_opts) Contract the tensor network using the same procedure as in https://arxiv.org/abs/2409.03108 - "Loop Series Expansions for Tensor Networks". :param gloops: Loops or regions to use. An integer generates all loops up to that size. ``None`` and ``"min"`` use an automatic size. An iterable can contain explicit regions of ``tids`` or ``NetworkPatch`` objects. :type gloops: None, int, "min" or iterable, optional :param multi_excitation_correct: Whether to use the multi-excitation correction. If ``True``, then the free energy is refined iteratively until self consistent. :type multi_excitation_correct: bool, optional :param tol_correction: The tolerance for the multi-excitation correction. :type tol_correction: float, optional :param maxiter_correction: The maximum number of iterations for the multi-excitation correction. :type maxiter_correction: int, optional :param strip_exponent: Whether to strip the exponent from the final result. If ``True`` then the returned result is ``(mantissa, exponent)``. :type strip_exponent: bool, optional :param optimize: The path optimizer to use when contracting the messages. :type optimize: str or PathOptimizer, optional :param contract_opts: Other options supplied to ``TensorNetwork.contract``. .. py:method:: local_tensor_contract(tid) Contract the messages around tensor ``tid``. .. py:method:: local_message_contract(ix) Contract the messages at index ``ix``. .. py:method:: contract(strip_exponent=False, check_zero=True, **kwargs) Contract the target tensor network via BP using the current messages. .. py:method:: contract_with_loops(max_loop_length=None, min_loop_length=1, optimize='auto-hq', strip_exponent=False, check_zero=True, **contract_opts) Estimate the contraction of the tensor network, including loop corrections. .. py:method:: contract_gloop_expand(gloops=None, autocomplete=True, autoreduce=True, strip_exponent=False, check_zero=True, optimize='auto-hq', combine='prod', info=None, progbar=False, **contract_opts) Contract the tensor network using generalized loop cluster expansion. :param gloops: The generalized loops to use, an integer to generate all loops up to that size, or ``None``/``"min"`` for the automatic size, see :func:`~quimb.tensor.networking.gen_gloops`. :type gloops: None, int, "min" or iterable of tuples, optional :param autocomplete: Whether to add intersecting regions required to complete the region graph. :type autocomplete: bool, optional :param autoreduce: Whether to remove dangling tensors from each region. Use this option only at a BP fixed point. :type autoreduce: bool, optional :param strip_exponent: Whether to return the mantissa and base-10 exponent separately. :type strip_exponent: bool, optional :param check_zero: Whether to return zero early when combining a product containing a zero contraction. :type check_zero: bool, optional :param optimize: The contraction path optimizer to use. :type optimize: str or PathOptimizer, optional :param combine: Whether to combine region contractions as a product or sum. :type combine: {'prod', 'sum'}, optional :param info: A cache for normalized scalar contractions and the tensor-neighbor map. Reuse it only while the tensor network and BP messages remain unchanged. :type info: dict, optional :param progbar: Whether to show a progress bar. :type progbar: bool, optional :param contract_opts: These options configure :meth:`TensorNetwork.contract`. :returns: The generalized loop expansion estimate. The method can return the base-10 exponent separately. :rtype: scalar or (scalar, float) .. py:function:: contract_d1bp(tn, *, max_iterations=1000, tol=5e-06, damping=0.0, diis=False, update='sequential', normalize=None, distance=None, tol_abs=None, tol_rolling_diff=None, local_convergence=True, strip_exponent=False, check_zero=True, info=None, progbar=False, **contract_opts) Estimate the contraction of standard tensor network ``tn`` using dense 1-norm belief propagation. :param tn: The tensor network to contract, it should have no dangling or hyper indices. :type tn: TensorNetwork :param max_iterations: The maximum number of iterations to perform. :type max_iterations: int, optional :param tol: The convergence tolerance for messages. :type tol: float, optional :param damping: The damping parameter to use, defaults to no damping. :type damping: float, optional :param diis: Whether to use direct inversion in the iterative subspace to help converge the messages by extrapolating to low error guesses. If a dict, should contain options for the DIIS algorithm. The relevant options are {`max_history`, `beta`, `rcond`}. :type diis: bool or dict, optional :param update: Whether to update messages sequentially or in parallel. :type update: {'sequential', 'parallel'}, optional :param normalize: How to normalize messages after each update. If None choose automatically. If a callable, it should take a message and return the normalized message. If a string, it should be one of 'L1', 'L2', 'L2phased', 'Linf' for the corresponding norms. 'L2phased' is like 'L2' but also normalizes the phase of the message, by default used for complex dtypes. :type normalize: {'L1', 'L2', 'L2phased', 'Linf', callable}, optional :param distance: How to compute the distance between messages to check for convergence. If None choose automatically. If a callable, it should take two messages and return the distance. If a string, it should be one of 'L1', 'L2', 'L2phased', 'Linf', or 'cosine' for the corresponding norms. 'L2phased' is like 'L2' but also normalizes the phases of the messages, by default used for complex dtypes if phased normalization is not already being used. :type distance: {'L1', 'L2', 'L2phased', 'Linf', 'cosine', callable}, optional :param tol_abs: The absolute convergence tolerance for maximum message update distance, if not given then taken as ``tol``. :type tol_abs: float, optional :param tol_rolling_diff: The rolling mean convergence tolerance for maximum message update distance, if not given then taken as ``tol``. This is used to stop running when the messages are just bouncing around the same level, without any overall upward or downward trends, roughly speaking. :type tol_rolling_diff: float, optional :param local_convergence: Whether to allow messages to locally converge - i.e. if all their input messages have converged then stop updating them. :type local_convergence: bool, optional :param strip_exponent: Whether to return the mantissa and exponent separately. :type strip_exponent: bool, optional :param check_zero: Whether to check for zero values and return zero early. :type check_zero: bool, optional :param info: If supplied, the following information will be added to it: ``converged`` (bool), ``iterations`` (int), ``max_mdiff`` (float), ``rolling_abs_mean_diff`` (float). :type info: dict, optional :param progbar: Whether to show a progress bar. :type progbar: bool, optional