Environment CTM#
Corner transfer matrix renormalization group (CTMRG) associates a local CTM environment with each lattice site and the corresponding rank-4 PEPS tensors a (potentially, coming from a double-layer contraction of bra and ket PEPSs). We show it below with the convention for ordering the indices in the CTMRG environment tensors:
┌──────┐ ┌─────┐ ┌──────┐
| C_tl ├── 1 0 ──┤ T_t ├── 2 0 ──┤ C_tr |
└──┬───┘ └──┬──┘ └───┬──┘
| | |
0 1 1
2 0 0
│ | |
┌──┴──┐ ┌──┴──┐ ┌──┴──┐
| T_l ├── 1 1 ──┤ a ├── 3 1 ──┤ T_r |
└──┬──┘ └──┬──┘ └──┬──┘
| | |
0 2 2
1 1 0
| | |
┌──┴───┐ ┌──┴──┐ ┌───┴──┐
| C_bl ├── 0 2 ──┤ T_b ├── 0 1 ──┤ C_br |
└──────┘ └─────┘ └──────┘
Operations on the CTM environment are supported by yastn.tn.fpeps.EnvCTM,
where each local CTM environment yastn.tn.fpeps.EnvCTM_local can be accessed specifying site coordinates in []
and PEPS network of rank-4 tensors is available via attribute psi.
The CTM environment class supports CTMRG updates for converging the environment, expectation value calculations,
bond metric, sampling, etc.
A single iteration of the CTMRG update, consisting of horizontal and vertical moves,
is performed with yastn.tn.fpeps.EnvCTM.update_().
Performing multiple updates is automatized in yastn.tn.fpeps.EnvCTM.iterate_() (or equivalently yastn.tn.fpeps.EnvCTM.ctmrg_()).
One can stop the CTM after a fixed number of iterations or, e.g., convergence of corner singular values.
Stopping criteria can also be set based on the convergence of one or more observables, e.g., total energy.
Once the CTMRG converges, it is straightforward to obtain one-site yastn.tn.fpeps.EnvCTM.measure_1site() and
two-site nearest-neighbor observables yastn.tn.fpeps.EnvCTM.measure_nn(), or other expectation values of interests.
Products of operators on a rectangular window of sites are contracted exactly by yastn.tn.fpeps.EnvCTM.measure_nsite_exact()
and, with contraction-path optimization, bond unrolling and MPO-valued operators, by
yastn.tn.fpeps.EnvCTM.measure_nsite_exact_oe(); see Exact n-site measurement with opt_einsum.
The CTMRG iteration#
One yastn.tn.fpeps.EnvCTM.update_() performs a single CTMRG iteration. Each move in it
builds projectors from enlarged corners and then absorbs a row or column of the network into the
environment tensors:
movesis the sequence of moves making up one iteration.'hv'(the default) updates all sites simultaneously in a horizontal and then a vertical move;'lrtb'executes left, right, top and bottom causally, row after row or column after column.methodselects how projectors are built.'2x2'uses enlarged 2x2 corners forming a 4x4 patch and can grow the environment bond dimension;'1x2'uses smaller 1x2 corners, which is considerably faster but less stable and cannot grow the bond dimension.opts_svdfixes the environment bond dimension, and is passed on toyastn.linalg.svd_with_truncation().
yastn.tn.fpeps.EnvCTM.iterate_() (equivalently yastn.tn.fpeps.EnvCTM.ctmrg_()) repeats
the iteration up to max_sweeps times, stopping early when corner_tol is met by the change of
corner singular values, or when a custom conv_check says so. With iterator=True it returns a
generator yielding after each sweep, so observables can be inspected as the environment converges.
Every option above, and the rest, is described in CTM options.
Subspace-iteration mode#
By default each projector pair comes from a truncated SVD of the enlarged corners, computed from scratch on every sweep. In subspace-iteration (SI) mode (arXiv:2607.15158) the pair is instead obtained from a pair of recycled range-finder bases \(X, Y\), refreshed by a few power iterations and carried over to the next sweep. Successive CTMRG environments differ little once the iteration settles, so the bases from the previous sweep are already a good starting guess, and the full decomposition can be replaced by a much smaller one.
The mode is switched on per call:
env.ctmrg_(opts_svd={'D_total': chi}, max_sweeps=100, corner_tol=1e-8,
opts_si={'enabled': True, 'oversampling': 4, 'niter': 2})
Alongside the options, each projector pair accumulates its own state – how many times it has been
updated (age), the subspace error its bases last reported, and where those bases came from.
That is yastn.tn.fpeps.envs.SI_state, and it is what makes the schedule below depend on the
history of the run rather than on the options alone.
The chart below traces a single projector-pair update, naming the yastn.tn.fpeps.envs.SIOpts
field that governs each branch.
How SI options enter one projector-pair update. Diamonds are decisions; the italicised names are the options that control them.#
Two points the chart makes concrete. skip_SI_update does not skip the projector – it skips only
the power iterations, reusing the incoming bases, and it is deliberately disabled while the
redistribution window is open so a pair is never frozen before its sectors have settled. And
rebase matters whenever the environment bond dimension is still growing: without it, every
change of the corner legs throws the accumulated bases away and redraws them from noise.
Note that the SI path truncates on a narrower set of opts_svd keys than the default path; the
set is named once, as SI_TRUNCATION_KEYS in yastn.tn.fpeps.envs.
API#
- class yastn.tn.fpeps.EnvCTM(psi, init='rand', leg=None, bra=None)[source]#
Environment used in Corner Transfer Matrix Renormalization Group algorithm.
- Note:
Index convention for environment tensors:
C---1 0---T---2 0---C | | | 0 1 1 2 0 | | T---1 1---T | | 0 2 1 1 0 | | | C---0 2---T---0 1---C
enlarged corners: anti-clockwise
- Parameters:
psi (yastn.tn.Peps) – PEPS lattice to be contracted using CTM. If
psihas physical legs, a double-layer PEPS with no physical legs is formed.init (str | None) – None, ‘eye’, ‘rand’, or ‘dl’. Initialization scheme, see
yastn.tn.fpeps.EnvCTM.reset_().leg (Optional[yastn.Leg]) – Passed to
yastn.tn.fpeps.EnvCTM.reset_()to further customize initialization.bra (Optional[yastn.tn.Peps]) – If provided, and
psihas physical legs, forms a double-layer PEPS <bra | ket>.
- bond_metric(Q0, Q1, s0, s1, dirn) Tensor[source]#
Calculates Full-Update metric tensor.
If dirn == 'h': tl═══t═══════t═══tr ║ ║ ║ ║ l════Q0══ ══Q1═══r ║ ║ ║ ║ bl═══b═══════b═══br If dirn == 'v': tl═══t═══tr ║ ║ ║ l═══0Q0═══r ║ ╳ ║ l═══1Q1═══r ║ ║ ║ bl═══b═══br
- ctmrg_(opts_svd=None, moves=None, method=None, max_sweeps=None, iterator=None, corner_tol=None, *, opts=None, **kwargs)#
Perform CTMRG updates
yastn.tn.fpeps.EnvCTM.update_()until convergence. Convergence can be measured based on singular values of CTM environment corner tensors.Outputs iterator if
iteratoris given, which allows inspectingenv, e.g., calculating expectation values, outside ofctmrg_function after every sweeps.- Parameters:
opts_svd (dict) – A dictionary of options to pass to SVD truncation algorithm. This sets EnvCTM bond dimension.
moves (str) – Specify a sequence of moves forming a single sweep. Individual moves are ‘l’, ‘r’, ‘t’, ‘b’, ‘h’, or ‘v’. Horizontal ‘h’ and vertical ‘v’ moves have all sites updated simultaneously. Left ‘l’, right ‘r’, top ‘t’, and bottom ‘b’ are executed causally, row after row or column after column. Argument specifies a sequence of individual moves, where sensible options are ‘hv’ and ‘lrtb’. The default is ‘hv’.
method (str) –
‘2x2’ or ‘1x2’ contained in method. The default is ‘2x2’.
‘2x2’ uses the standard 2x2 enlarged corners (forming 4x4 patch), enabling enlargement of EnvCTM bond dimensions. When some PEPS bonds are rank-1, it recognizes it to use 3x2 corners to prevent artificial collapse of EnvCTM bond dimensions to 1, which is important for hexagonal lattice.
‘1x2’ uses smaller 1x2 corners (forming 2x4 patch). It is significantly faster, but is less stable and does not allow for EnvCTM bond dimension growth.
max_sweeps (int) – The maximal number of sweeps.
iterator (bool) – If True,
ctmrg_returns a generator that would yield output after every sweep. The default is False, in which casectmrg_sweeps are performed immediately.corner_tol (float) – Convergence tolerance for the change of singular values of all corners in a single update. The default is
None, in which case convergence is not checked and it is up to user to implement convergence check.checkpoint_move (str | bool) – Whether to use checkpointing for the CTM updates. The default is
False. Otherwise, in case of PyTorch backend it can be set to ‘reentrant’ for reentrant checkpointing or ‘nonreentrant’ for non-reentrant checkpointing, see https://pytorch.org/docs/stable/checkpoint.html.use_qr (bool) – Whether to include intermediate QR decomposition while calculating projectors. The default is
True.
- Returns:
Generator if iterator is True.
CTMRG_out(NamedTuple) –
NamedTuple including fields:
sweepsnumber of performed ctmrg updates.max_dsvnorm of singular values change in the worst corner in the last sweep.max_denorm of elementwise difference of moduli of environment tensors elements in the last sweep.max_Dlargest bond dimension of environment tensors virtual legs.convergedwhether convergence based oncorner_tolhas been reached.
- classmethod from_dict(d, config=None)[source]#
De-serializes EnvCTM from the dictionary
d. Seeyastn.Tensor.from_dict()for further description.
- iterate_(opts_svd=None, moves=None, method=None, max_sweeps=None, iterator=None, corner_tol=None, *, opts=None, **kwargs)[source]#
Perform CTMRG updates
yastn.tn.fpeps.EnvCTM.update_()until convergence. Convergence can be measured based on singular values of CTM environment corner tensors.Outputs iterator if
iteratoris given, which allows inspectingenv, e.g., calculating expectation values, outside ofctmrg_function after every sweeps.- Parameters:
opts_svd (dict) – A dictionary of options to pass to SVD truncation algorithm. This sets EnvCTM bond dimension.
moves (str) – Specify a sequence of moves forming a single sweep. Individual moves are ‘l’, ‘r’, ‘t’, ‘b’, ‘h’, or ‘v’. Horizontal ‘h’ and vertical ‘v’ moves have all sites updated simultaneously. Left ‘l’, right ‘r’, top ‘t’, and bottom ‘b’ are executed causally, row after row or column after column. Argument specifies a sequence of individual moves, where sensible options are ‘hv’ and ‘lrtb’. The default is ‘hv’.
method (str) –
‘2x2’ or ‘1x2’ contained in method. The default is ‘2x2’.
‘2x2’ uses the standard 2x2 enlarged corners (forming 4x4 patch), enabling enlargement of EnvCTM bond dimensions. When some PEPS bonds are rank-1, it recognizes it to use 3x2 corners to prevent artificial collapse of EnvCTM bond dimensions to 1, which is important for hexagonal lattice.
‘1x2’ uses smaller 1x2 corners (forming 2x4 patch). It is significantly faster, but is less stable and does not allow for EnvCTM bond dimension growth.
max_sweeps (int) – The maximal number of sweeps.
iterator (bool) – If True,
ctmrg_returns a generator that would yield output after every sweep. The default is False, in which casectmrg_sweeps are performed immediately.corner_tol (float) – Convergence tolerance for the change of singular values of all corners in a single update. The default is
None, in which case convergence is not checked and it is up to user to implement convergence check.checkpoint_move (str | bool) – Whether to use checkpointing for the CTM updates. The default is
False. Otherwise, in case of PyTorch backend it can be set to ‘reentrant’ for reentrant checkpointing or ‘nonreentrant’ for non-reentrant checkpointing, see https://pytorch.org/docs/stable/checkpoint.html.use_qr (bool) – Whether to include intermediate QR decomposition while calculating projectors. The default is
True.
- Returns:
Generator if iterator is True.
CTMRG_out(NamedTuple) –
NamedTuple including fields:
sweepsnumber of performed ctmrg updates.max_dsvnorm of singular values change in the worst corner in the last sweep.max_denorm of elementwise difference of moduli of environment tensors elements in the last sweep.max_Dlargest bond dimension of environment tensors virtual legs.convergedwhether convergence based oncorner_tolhas been reached.
- measure_1site(O, site=None) dict#
Calculate local expectation values within CTM environment.
Returns a number if
siteis provided. IfNone, returns a dictionary {site: value} for all unique lattice sites.- Parameters:
env (EnvCtm) – Class containing CTM environment tensors along with lattice structure data.
O (Tensor) – Single-site operator
- measure_2site(O, P, xrange=None, yrange=None, pairs='corner <=', dirn='v', opts_svd=None, opts_var=None) dict[Site, float]#
Calculate expectation values \(\langle \textrm{O}_i \textrm{P}_j \rangle\) of local operators
OandPfor pairs of lattice sites \(i, j\).- Parameters:
O, P (yastn.Tensor) – one-site operators. It is possible to provide a dict of
yastn.tn.fpeps.Latticeobject mapping operators to sites. For each site, it is possible to provide a list or dict of operators, where the expectation value is calculated for each combination of those operators
- xrange: None | tuple[int, int]
range of rows forming a window, [r0, r1); r0 included, r1 excluded. For None, takes a single unit cell of the lattice, which is the default.
- yrange: None | tuple[int, int]
range of columns forming a window. For None, takes a single unit cell of the lattice, which is the default.
- pairs: str | list[tuple[tuple[int, int], tuple[int, int]]]
Limits the pairs of sites to calculate the expectation values. If ‘corner’ in pairs, O is limited to top-left corner of the lattice If ‘row’ in pairs, O is limited to top row of the lattice
- dirn: str
‘h’ or ‘v’, where the boundary MPSs used for truncation are, respectively, horizontal or vertical. The default is ‘v’.
- opts_svd: dict
Options passed to
yastn.linalg.svd()used to truncate virtual spaces of boundary MPSs used in sampling. The default isNone, in which case takeD_totalas the largest dimension from CTM environment.- opts_var: dict
Options passed to
yastn.tn.mps.compression_()used in the refining of boundary MPSs. The default isNone, in which case make 2 variational sweeps.
- measure_2x2(*operators, sites=None) float#
Calculate expectation value of a product of local operators in a \(2 \times 2\) window within the CTM environment. Perform exact contraction of the window.
- Parameters:
operators (Sequence[yastn.Tensor]) – List of local operators to calculate <O0_s0 O1_s1 …>.
sites (Sequence[tuple[int, int]]) – A list of sites [s0, s1, …] matching corresponding operators.
- measure_line(*operators, sites=None) float#
Calculate expectation value of a product of local operators along a horizontal or vertical line within CTM environment. Perform exact contraction of a width-one window.
- Parameters:
operators (Sequence[yastn.Tensor]) – List of local operators to calculate <O0_s0 O1_s1 …>.
sites (Sequence[tuple[int, int]]) – List of sites that should match operators.
- measure_nn(O, P, bond=None) dict#
Calculate nearest-neighbor expectation values within CTM environment.
Return a number if the nearest-neighbor
bondis provided. IfNone, returns a dictionary {bond: value} for all unique lattice bonds.- Parameters:
O, P (yastn.Tensor) – Calculate <O_s0 P_s1>. P is applied first, which might matter for fermionic operators.
bond (yastn.tn.fpeps.Bond | tuple[tuple[int, int], tuple[int, int]]) – Bond of the form (s0, s1). Sites s0 and s1 should be nearest-neighbors on the lattice.
- measure_nsite(*operators, sites=None) float#
Calculate expectation value of a product of local operators. Perform approximate contraction of a windows of PEPS sites within CTM environment using boundary MPS. The size of the window is taken to include provided sites.
- Parameters:
operators (Sequence[yastn.Tensor]) – List of local operators to calculate <O0_s0 O1_s1 …>.
sites (Sequence[int]) – A list of sites [s0, s1, …] matching corresponding operators.
- measure_nsite_exact(*operators, sites=None) float#
Calculate expectation value of a product of local operators in a \(Nx \times Ny\) window (determined by sites) within the CTM environment. Perform exact contraction of the window. If Nx <= Ny, contract from left to right. Otherwise, contract from top to bottom.
Note: use with caution for large windows, as the computational cost grows exponentially with the window size.
- Parameters:
operators (Sequence[yastn.Tensor]) – List of local operators to calculate <O0_s0 O1_s1 …>.
sites (Sequence[tuple[int, int]]) – A list of sites [s0, s1, …] matching corresponding operators.
- reset_(init='rand', leg=None, **kwargs)[source]#
Initialize CTMRG environment.
- Parameters:
init (str) – [‘eye’, ‘rand’, ‘dl’] For ‘eye’ starts with identity environments of dimension 1. For ‘rand’ sets environments randomly. For ‘dl’ and Env of double-layer PEPS, trace on-site tensors to initialize environment.
leg (None | yastn.Leg) – If not provided, random initialization has CTMRG bond dimension set to 1. Otherwise, the provided Leg is used to initialize CTMRG virtual legs. Leg signature is fixed to the default values.
- sample(projectors, number=1, xrange=None, yrange=None, dirn='v', opts_svd=None, opts_var=None, progressbar=False, return_probabilities=False, flatten_one=True, **kwargs) dict[Site, list]#
Sample random configurations from PEPS. Output a dictionary linking sites with lists of sampled projectors` keys for each site. Projectors should be summing up to identity – this is not checked.
- Parameters:
projectors (Dict[Any, yast.Tensor] | Sequence[yast.Tensor] | Dict[Site, Dict[Any, yast.Tensor]]) – Projectors to sample from. We can provide a dict(key: projector), where the sampled results will be given as keys, and the same set of projectors is used at each site. For a list of projectors, the keys follow from enumeration. Finally, we can provide a dictionary between each site and sets of projectors.
number (int) – Number of independent samples.
xrange (None | tuple[int, int]) – range of rows forming a window, [r0, r1); r0 included, r1 excluded. For None, takes a single unit cell of the lattice, which is the default.
yrange (None | tuple[int, int]) – range of columns forming a window. For None, takes a single unit cell of the lattice, which is the default.
dirn (str) – ‘h’ or ‘v’, where the boundary MPSs used for truncation are, respectively, horizontal or vertical. The default is ‘v’.
opts_svd (dict) – Options passed to
yastn.linalg.svd()used to truncate virtual spaces of boundary MPSs used in sampling. The default isNone, in which case takeD_totalas the largest dimension from CTM environment.opts_var (dict) – Options passed to
yastn.tn.mps.compression_()used in the refining of boundary MPSs. The default isNone, in which case make 2 variational sweeps.progressbar (bool) – Whether to display progressbar. The default is
False.return_probabilities (bool) – Whether to return a tuple (samples, probabilities). The default is
False, where a dict samples is returned.flatten_one (bool) – Whether, for number==1, pop one-element lists for each lattice site to return samples={site: ind, } instead of {site: [ind]}. The default is
True.
- to_dict(level=2, resolve_ops=False)[source]#
Serialize EnvCTM to a dictionary. Complementary function is
yastn.EnvCTM.from_dict()or a generalyastn.from_dict(). Seeyastn.Tensor.to_dict()for further description.
- transfer_matrix_spectrum(k=2, n=None, dirn='h', i=0, L=None, dtype='float64')#
Calculate dominant transfer matrix eigenvalues. Employs scipy.sparse.linalg.eigs for eigenvalue solver – as such, works with numpy backend only.
- Parameters:
k (int) – number of eigenvalues to recover; The default is 2.
n (tuple[int] | int | None) – charge of eigenvector. The default None gives zero charge.
dirn (str) – ‘h’ or ‘v’. Vertical of horizontal transfer matrix.
i (int) – index of row or column from which the transfer matrix is build.
L (None | int) – The length of transfer matrix. The default is None, for which it corresponds to the size of the unit cell.
dtype (str) – ‘float64’ or ‘complex128’, dtype used in initializing random starting vector and used in eigensolver.
- update_(opts_svd=None, moves=None, method=None, *, opts=None, **kwargs)[source]#
Perform one step of CTMRG update. Environment tensors are updated in place.
The function performs a CTMRG update for a square lattice using the corner transfer matrix renormalization group (CTMRG) algorithm. The update is performed in two steps: a horizontal move and a vertical move. The projectors for each move are calculated first, and then the tensors in the CTM environment are updated using the projectors. The boundary conditions of the lattice determine whether trivial projectors are needed for the move.
- Parameters:
opts_svd (dict) – A dictionary of options to pass to SVD truncation algorithm. This sets EnvCTM bond dimension.
moves (str) – Specify a sequence of moves forming a single sweep. Individual moves are ‘l’, ‘r’, ‘t’, ‘b’, ‘h’, or ‘v’. Horizontal ‘h’ and vertical ‘v’ moves have all sites updated simultaneously. Left ‘l’, right ‘r’, top ‘t’, and bottom ‘b’ are executed causally, row after row or column after column. Argument specifies a sequence of individual moves, where sensible options are ‘hv’ and ‘lrtb’. The default is ‘hv’.
method (str) – ‘2x2’ or ‘1x2’ in method. The default is ‘2x2 corner’. ‘2x2’ uses the standard 2x2 enlarged corners forming 4x4 patch, allowing to enlarge EnvCTM bond dimension. ‘1x2’ uses smaller 1x2 corners forming 2x4 patch. It is significantly faster, but is less stable and does not allow to grow EnvCTM bond dimension.
checkpoint_move (bool) – Whether to use (reentrant) checkpointing for the move. The default is
Falseopts_si (dict | SIOpts | None) – Enable recycled subspace-iteration projectors with
{'enabled': True}. Seeyastn.tn.fpeps.envs.SIOptsfor the full list of fields and their defaults, and the Subspace-iteration mode section of the CTM environment page for how they combine over a sweep.cutoff (float | None) – Pseudo-inverse cutoff in projector construction, regularizing values close to floating-point precision. Note: This cutoff is an absolute value, not relative to the largest singular value.
- Returns:
proj
- Return type:
Peps structure loaded with CTM projectors related to all lattice site.
- update_bond_(bond: tuple, opts_svd: dict | None = None, method: str | None = None, *, opts=None, **kwargs)[source]#
Update EnvCTM tensors related to a specific nearest-neighbor bond.
Intended primarily for FU evolution scheme – assuming fixed sectorial bond dimensions. May require using a dictionary “D_block” specifying sectorial bond dimensions in opts_svd’s passed to PEPS truncation and CTM.
- class yastn.tn.fpeps.envs.EnvCTM_local(tl: Tensor | None = None, t: Tensor | None = None, tr: Tensor | None = None, r: Tensor | None = None, br: Tensor | None = None, b: Tensor | None = None, bl: Tensor | None = None, l: Tensor | None = None)[source]#
Dataclass for CTM environment tensors associated with Peps lattice site. Contains fields
tl,t,tr,r,br,b,bl,l
- class yastn.tn.fpeps.envs.SI_state(age: int = 0, niter: int = 0, error: float = inf, rank: int = 0, bases: str = 'reused')[source]#
Recycling state of one SI projector pair.
agecounts how many times the pair has been updated with SI; used by redistribution scheduleredistribute_due().niteranderrordescribe the last update: the number of power updates made and the subspace error between the last two X, Y iterates.basesrecords where the last update got its bases from:'reused'when the incoming pair was used as it came,'rebased'when it was carried onto changed corner row legs, seesi_rebase_bases(), and'reinitialized'when it was discarded for a fresh random start.Create new instance of SI_state(age, niter, error, rank, bases)
See also
CTM options for every option accepted above, and Fixed-point CTMRG with implicit differentiation for the differentiable fixed-point variant.