# Mixer¶

Inheritance Diagram 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

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 phyiscal 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 inseperably.

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 avaible.

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 mive) 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.