Source code for seemps.operators.simplify_mpo

from __future__ import annotations
from math import isqrt
from . import MPO, MPOList, MPOSum
from ..state import (
    DEFAULT_STRATEGY,
    MPS,
    Strategy,
    Simplification,
    SIMPLIFICATION_STRATEGY,
    NO_TRUNCATION,
    simplify,
)

#: MPO simplification strategy based on canonical forms without truncation.
CANONICALIZE_MPO = NO_TRUNCATION.replace(simplify=Simplification.DO_NOT_SIMPLIFY)

# MPO simplification should not normalize by default
MPO_SIMPLIFICATION_STRATEGY = SIMPLIFICATION_STRATEGY.replace(normalize=False)


[docs] def mpo_as_mps(mpo: MPO) -> MPS: """Recast MPO as MPS.""" data = [] for site in mpo._data: bl, i, j, br = site.shape data.append(site.reshape(bl, i * j, br)) return MPS(data)
[docs] def mps_as_mpo( mps: MPS, mpo_strategy: Strategy = DEFAULT_STRATEGY, ) -> MPO: """Recast MPS as MPO.""" data = [] for site in mps._data: bl, p, br = site.shape s = isqrt(p) if s**2 != p: raise ValueError( "The physical dimensions of the MPS must be a perfect square" ) data.append(site.reshape(bl, s, s, br)) return MPO(data, strategy=mpo_strategy)
[docs] def simplify_mpo( operator: MPO | MPOList | MPOSum, strategy: Strategy = MPO_SIMPLIFICATION_STRATEGY, direction: int = +1, guess: MPO | None = None, mpo_strategy: Strategy | None = None, ) -> MPO: """Simplify an MPO state transforming it into another one with a smaller bond dimension, sweeping until convergence is achieved. Parameters ----------x operator : MPO | MPOList | MPOSum MPO to simplify. If given as `MPOList` or `MPOSum`, it is joined to `MPO` before the simplification. strategy : Strategy, default=SIMPLIFICATION_STRATEGY Truncation strategy to use in the simplification routine. direction : int, default=1 Initial direction for the sweeping algorithm. guess : MPS, optional Guess for the new state, to ease the optimization. mpo_strategy : Strategy | None Strategy of the resulting MPO (defaults to the one from `operator`) Returns ------- MPO Approximation O to the operator. """ if isinstance(operator, MPOList) or isinstance(operator, MPOSum): operator = operator.join() if mpo_strategy is None: mpo_strategy = operator.strategy mps = mpo_as_mps(operator) if guess is None: guess_mps = mps else: guess_mps = mpo_as_mps(guess) mps = simplify(mps, strategy, direction, guess_mps) return mps_as_mpo(mps, mpo_strategy=mpo_strategy)