Mixer

Inheritance Diagram

Inheritance diagram of tenpy.algorithms.mps_common.Mixer

Methods

Mixer.__init__(options[, sweep_activated])

Mixer.mix_and_decompose_1site(engine, theta, ...)

Decompose single-site wavefunction and expand/mix an adjacent bond.

Mixer.mix_and_decompose_2site(engine, theta, ...)

Decompose two-site wavefunction and expand/mix enclosed bond(s).

Mixer.mixed_svd_2site(engine, theta, i0, ...)

Mix and SVD-like decompose a two-site wavefunction.

Mixer.update_amplitude(sweeps)

Update the amplitude, possibly disable the mixer.

Class Attributes and Properties

Mixer.can_decompose_1site

class tenpy.algorithms.mps_common.Mixer(options, sweep_activated=0)[source]

Bases: object

Base class for a general Mixer.

Mixers are optional algorithmic steps during sweeping MPS algorithms that increase the variational power and / or improve convergence. They expand the virtual Hilbert space associated with a single bond of the MPS, while keeping the physical state itself unchanged (up to possible truncation). This allows subsequent updates adjacent to that bond to explore a larger variational space. In particular, applying the mixer to a bond i0, i0 + 1 of an MPS with tensors M_i – a.k.a. expanding that bond – gives us two new tensors M_new_i0 and M_new_i1 such that:

|   -- M_i0 --- M_i1 --   ~=   -- M_new_i0 === M_new_i1 ---
|       |        |                   |            |

I.e. such that the physical state represented by the MPS is unchanged. We use double lines (===) to emphasize that the central virtual index on the right side has a larger dimension than its counterpart on the left.

While the above picture gives possibly the best intuitive understanding of what mixing does to an MPS, we only implement the combination of two conceptually separate algorithmic steps; Namely the SVD of a theta wave function (either on 1 or on 2 sites) that is usually done in sweeping algorithms anyway, together with the expansion of a bond, as shown above. This simplifies the implementation and different Mixer subclasses may choose to perform these steps in different orders or even inseparably.

Different mixers typically implement _either_ mixed_svd_2site() _or_ mix_and_decompose_1site() but not both. This in turn means that all mixers offer mix_and_decompose_2site(), which serves as the access point e.g. for two-site DMRG.

Parameters:
  • options (dict) – Optional parameters as described in the following table. See Mixer.

  • sweep_activated (int) – The first sweep where the mixer was activated; disable_after is relative to that.

Options

config Mixer
option summary

amplitude

Initial :attr:`amplitude` of the mixer.

decay

To slowly turn off the mixer, we divide `amplitude` by `decay` after each s [...]

disable_after

We disable the mixer completely after this number of sweeps. [...]

option amplitude: float | None

Initial amplitude of the mixer.

option decay: float | None

To slowly turn off the mixer, we divide amplitude by decay after each sweep. (Should be >= 1.). Or None, in which case the amplitude does not decay.

option disable_after: int | None

We disable the mixer completely after this number of sweeps. None means to never disable the mixer.

can_decompose_1site

Class attribute indicating if mix_and_decompose_1site() is implemented.

Type:

bool

amplitude

Current amplitude of the mixer. Meaning is specific to the concrete Mixer subclass. A value of None indicates that the given mixer has no tuneable amplitude.

Type:

float | None

decay

If both amplitude and decay are not None, the amplitude is divided by decay after each sweep.

Type:

float | None

disable_after

We disable the mixer completely after this number of sweeps. None means to never disable the mixer.

Type:

int | None

update_amplitude(sweeps)[source]

Update the amplitude, possibly disable the mixer.

Parameters:

sweeps (int) – The total number of performed sweeps, to check if we need to disable the mixer.

Returns:

mixer – Returns self if we should continue mixing, or None, if the mixer should be disabled.

Return type:

Mixer | None

mixed_svd_2site(engine: Sweep, theta: Array, i0: int, mix_left: bool, mix_right: bool, qtotal_LR=[None, None])[source]

Mix and SVD-like decompose a two-site wavefunction.

The goal is to split theta as follows:

|   -- theta --   ==>   -- U === S --- VH --
|      |   |               |           |

The LHS is equal to the RHS up to truncation and rescaling (we normalize to norm(S)==1). The double lines (===) indicate the mixed/expanded bond, here e.g. for mix_left=True, mix_right=False. U and VH are isometries like in an SVD, but S may be a general bond-matrix and in particular not necessarily diagonal or even square. Either one (or both) of the bonds next to S can be expanded / mixed. The isometry on a non-mixed side (e.g. U if mix_left=False) could have been obtained from an SVD of theta.

Parameters:
  • engine (Sweep) – The engine that is using this mixer.

  • theta (2D Array) – Two-site wavefunction prepared for SVD. Labels '(vL.p0)', '(p1.vR)'.

  • i0 (int) – The site index of the left site, i.e. such that theta lives on sites i0, i0 + 1.

  • mix_left (bool) – If the virtual index left of S should be expanded.

  • mix_right (bool) – If the virtual index right of S should be expanded.

  • qtotal_LR ([{charges}, {charges}] | None) – The desired qtotal for U and VH, respectively. If None, the qtotal are arbitrary.

Returns:

  • U (Array) – Left isometry as defined above. Labels '(vL.p)', 'vR'.

  • S (1D ndarray | 2D Array) – Singular values (1D ndarray) or general bond matrix (2D Array, labels 'vL', 'vR').

  • VH (Array) – Right isometry as defined above. Labels 'vL', '(p.vR)'.

  • err (TruncationError) – The truncation error introduced.

  • S_approx (ndarray) – Approximation of the singular values of theta. Exact if available.

mix_and_decompose_1site(engine: Sweep, theta: Array, i0: int, move_right: bool)[source]

Decompose single-site wavefunction and expand/mix an adjacent bond.

For a right move, we decompose:

|   -- theta --   ==>   -- U === S === VH --
|        |                 |

For a left move:

|   -- theta --   ==>   -- U === S === VH --
|        |                             |

The LHS is equal to the RHS up to truncation and rescaling (we normalize to norm(S)==1). The double lines (===) indicate the mixed/expanded bonds. Only the tensor with a physical leg (e.g. U for a right move) is an isometry and is equivalent to the corresponding output of mixed_svd_2site(). It carries the qtotal of theta. The other (e.g. VH for a right move) is in general not isometric. S are the usual singular values.

The mixer can be injected in a sweeping algorithm by replacing the usual SVD of theta that shifts the canonical form with this method.

Parameters:
  • engine (Sweep) – The engine that is using this mixer.

  • theta (2D Array) – Single-site wavefunction prepared for SVD. Labels either '(vL.p0)', 'vR' for a right move, or 'vL', '(p0.vR)' for a left move.

  • i0 (int) – The site that theta lives on. The bond to be expanded is i0, i0 + 1 for a right move or i0 - 1, i0 for a left move.

  • move_right (bool | None) – Whether we move to the right (True), left (False), or dont move (None).

Returns:

  • U (Array) – Left part as defined above. Isometric for a right move. Labels '(vL.p)', 'vR' for a right move or 'vL', '(p.vR)' for a left move.

  • S (1D ndarray) – Singular values on the new bond.

  • VH (Array) – Right part as defined above. Isometric for a left move. Labels 'vL', '(p.vR)' for a right move or '(vL.p)', 'vR' for a left move.

  • err (TruncationError) – The truncation error introduced.

mix_and_decompose_2site(engine: Sweep, theta: Array, i0: int, mix_left: bool, mix_right: bool, qtotal_LR=None)[source]

Decompose two-site wavefunction and expand/mix enclosed bond(s).

This is a weaker version of mixed_svd_2site(). The decomposition is also:

|   -- theta --   ==>   -- U === S --- VH --
|      |   |               |           |

But only the tensors on mixed sites (e.g. only U for the case depicted above, i.e. mix_left=True, mix_right=False) are guaranteed to be isometric, while any non-mixed tensor (VH in this example) is in general not isometric. Other than that, parameters and returns are the same as for mixed_svd_2site().

The reason to relax the isometry condition is that the decomposition described above can be done using mix_and_decompose_1site() if mixed_svd_2site() is not implemented.