# TwoSiteMixer

Inheritance Diagram

Methods

 `TwoSiteMixer.__init__`(*args, **kwargs) `TwoSiteMixer.mix_and_decompose_1site`(engine, ...) Decompose single-site wavefunction and expand/mix an adjacent bond. `TwoSiteMixer.mix_and_decompose_2site`(engine, ...) Decompose two-site wavefunction and expand/mix enclosed bond(s). `TwoSiteMixer.mixed_svd_2site`(engine, theta, ...) Mix and SVD-like decompose a two-site wavefunction. `TwoSiteMixer.perturb_svd`(engine, theta, i0, ...) Update the amplitude, possibly disable the mixer.

Class Attributes and Properties

 `TwoSiteMixer.can_decompose_1site` `TwoSiteMixer.deprecated` `TwoSiteMixer.update_sites`
class tenpy.algorithms.dmrg.TwoSiteMixer(*args, **kwargs)[source]
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.

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.

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