MPO

Inheritance Diagram

Inheritance diagram of tenpy.networks.mpo.MPO

Methods

MPO.__init__(sites, Ws[, bc, IdL, IdR, ...])

MPO.apply(psi, options)

Apply self to an MPS psi and compress psi in place.

MPO.apply_naively(psi)

Applies an MPO to an MPS (in place) naively, without compression.

MPO.apply_zipup(psi, options)

Applies an MPO to an MPS (in place) with the zip-up method.

MPO.copy()

Make a shallow copy of self.

MPO.dagger()

Return hermitian conjugate copy of self.

MPO.enlarge_mps_unit_cell([factor])

Repeat the unit cell for infinite MPS boundary conditions; in place.

MPO.expectation_value(psi[, tol, max_range, ...])

Calculate <psi|self|psi>/<psi|psi> (or density for infinite).

MPO.expectation_value_TM(psi[, tol, ...])

Calculate <psi|self|psi>/<psi|psi> / L from the MPOTransferMatrix.

MPO.expectation_value_finite(psi[, ...])

Calculate <psi|self|psi>/<psi|psi> for finite MPS.

MPO.expectation_value_power(psi[, tol, ...])

Calculate <psi|self|psi>/<psi|psi> with a power-method.

MPO.extract_segment(first, last)

Extract a segment from the MPO.

MPO.from_grids(sites, grids[, bc, IdL, IdR, ...])

Initialize an MPO from grids.

MPO.from_hdf5(hdf5_loader, h5gr, subpath)

Load instance from a HDF5 file.

MPO.from_wavepacket(sites, coeff, op[, eps])

Create a (finite) MPO wave packet representing sum_i coeff[i] op_i.

MPO.get_IdL(i)

Return index of IdL at bond to the left of site i.

MPO.get_IdR(i)

Return index of IdR at bond to the right of site i.

MPO.get_W(i[, copy])

Return W at site i.

MPO.group_sites([n, grouped_sites])

Modify self inplace to group sites.

MPO.is_equal(other[, eps, max_range])

Check if self and other represent the same MPO to precision eps.

MPO.is_hermitian([eps, max_range])

Check if self is a hermitian MPO.

MPO.make_U(dt[, approximation])

Creates the U_I or U_II propagator.

MPO.make_U_I(dt)

Creates the \(U_I\) propagator with W_I tensors.

MPO.make_U_II(dt)

Creates the \(U_II\) propagator.

MPO.prefactor(i, ops)

Get prefactor for a given string of operators in self.

MPO.save_hdf5(hdf5_saver, h5gr, subpath)

Export self into a HDF5 file.

MPO.set_W(i, W)

Set W at site i.

MPO.sort_legcharges()

Sort virtual legs by charges.

MPO.test_sanity()

Sanity check, raises ValueErrors, if something is wrong.

MPO.to_TermList(op_basis[, start, ...])

Obtain a TermList represented by self.

MPO.variance(psi[, exp_val])

Calculate <psi|self^2|psi> - <psi|self|psi>^2.

Class Attributes and Properties

MPO.L

Number of physical sites; for an iMPO the len of the MPO unit cell.

MPO.chi

Dimensions of the virtual bonds.

MPO.dim

List of local physical dimensions.

MPO.finite

Distinguish MPO vs iMPO.

class tenpy.networks.mpo.MPO(sites, Ws, bc='finite', IdL=None, IdR=None, max_range=None, explicit_plus_hc=False)[source]

Bases: object

Matrix product operator, finite (MPO) or infinite (iMPO).

Parameters:
  • sites (list of Site) – Defines the local Hilbert space for each site.

  • Ws (list of Array) – The matrices of the MPO. Should have labels wL, wR, p, p*.

  • bc ({'finite' | 'segment' | 'infinite'}) – Boundary conditions as described in mps. 'finite' requires Ws[0].get_leg('wL').ind_len = 1.

  • IdL ((iterable of) {int | None}) – Indices on the bonds, which correspond to ‘only identities to the left’. A single entry holds for all bonds.

  • IdR ((iterable of) {int | None}) – Indices on the bonds, which correspond to ‘only identities to the right’.

  • max_range (int | np.inf | None) – Maximum range of hopping/interactions (in unit of sites) of the MPO. None for unknown.

  • explicit_plus_hc (bool) – If True, this flag indicates that the hermitian conjugate of the MPO should be computed and added at runtime, i.e., self is not (necessarily) hermitian.

chinfo

The nature of the charge.

Type:

ChargeInfo

sites

Defines the local Hilbert space for each site.

Type:

list of Site

dtype

The data type of the _W.

Type:

type

bc

Boundary conditions as described in mps. 'finite' requires Ws[0].get_leg('wL').ind_len = 1.

Type:

{‘finite’ | ‘segment’ | ‘infinite’}

IdL

Indices on the bonds (length L`+1), which correspond to ‘only identities to the left’. ``None` for bonds where it is not set. In standard form, this is 0 (except for unset bonds in finite case)

Type:

list of {int | None}

IdR

Indices on the bonds (length L`+1), which correspond to ‘only identities to the right’. ``None` for bonds where it is not set. In standard form, this is the last index on the bond (except for unset bonds in finite case).

Type:

list of {int | None}

max_range

Maximum range of hopping/interactions (in unit of sites) of the MPO. None for unknown.

Type:

int | np.inf | None

grouped

Number of sites grouped together, see group_sites().

Type:

int

explicit_plus_hc

If True, this flag indicates that the hermitian conjugate of the MPO should be computed and added at runtime, i.e., self is not (necessarily) hermitian.

Type:

bool

_W

The matrices of the MPO. Labels are 'wL', 'wR', 'p', 'p*'.

Type:

list of Array

_valid_bc

Class attribute. Valid boundary conditions; the same as for an MPS.

Type:

tuple of str

copy()[source]

Make a shallow copy of self.

save_hdf5(hdf5_saver, h5gr, subpath)[source]

Export self into a HDF5 file.

This method saves all the data it needs to reconstruct self with from_hdf5().

Specifically, it saves sites, chinfo, max_range (under these names), _W as "tensors", IdL as "index_identity_left", IdR as "index_identity_right", and bc as "boundary_condition". Moreover, it saves L, explicit_plus_hc and grouped as HDF5 attributes, as well as the maximum of chi under the name max_bond_dimension.

Parameters:
  • hdf5_saver (Hdf5Saver) – Instance of the saving engine.

  • h5gr (:class`Group`) – HDF5 group which is supposed to represent self.

  • subpath (str) – The name of h5gr with a '/' in the end.

classmethod from_hdf5(hdf5_loader, h5gr, subpath)[source]

Load instance from a HDF5 file.

This method reconstructs a class instance from the data saved with save_hdf5().

Parameters:
  • hdf5_loader (Hdf5Loader) – Instance of the loading engine.

  • h5gr (Group) – HDF5 group which is represent the object to be constructed.

  • subpath (str) – The name of h5gr with a '/' in the end.

Returns:

obj – Newly generated class instance containing the required data.

Return type:

cls

classmethod from_grids(sites, grids, bc='finite', IdL=None, IdR=None, Ws_qtotal=None, legs=None, max_range=None, explicit_plus_hc=False)[source]

Initialize an MPO from grids.

Parameters:
  • sites (list of Site) – Defines the local Hilbert space for each site.

  • grids (list of list of list of entries) – For each site (outer-most list) a matrix-grid (corresponding to wL, wR) with entries being or representing (see grid_insert_ops()) onsite-operators.

  • bc ({'finite' | 'segment' | 'infinite'}) – Boundary conditions as described in mps.

  • IdL ((iterable of) {int | None}) – Indices on the bonds, which correspond to ‘only identities to the left’. A single entry holds for all bonds.

  • IdR ((iterable of) {int | None}) – Indices on the bonds, which correspond to ‘only identities to the right’.

  • Ws_qtotal ((list of) total charge) – The qtotal to be used for each grid. Defaults to zero charges.

  • legs (list of LegCharge) – List of charges for ‘wL’ legs left of each W, L + 1 entries. The last entry should be the conjugate of the ‘wR’ leg, i.e. identical to legs[0] for ‘infinite’ bc. By default, determine the charges automatically. This is limited to cases where there are no “dangling open ends” in the MPO graph. (The MPOGraph can handle those cases, though.)

  • max_range (int | np.inf | None) – Maximum range of hopping/interactions (in unit of sites) of the MPO. None for unknown.

  • explicit_plus_hc (bool) – If True, the Hermitian conjugate of the MPO is computed at runtime, rather than saved in the MPO.

See also

grid_insert_ops

used to plug in entries of the grid.

tenpy.linalg.np_conserved.grid_outer

used for final conversion.

classmethod from_wavepacket(sites, coeff, op, eps=1e-15)[source]

Create a (finite) MPO wave packet representing sum_i coeff[i] op_i.

Note that we define it only for finite systems; a generalization to infinite systems is not straight forward due to normalization issues: the individual terms vanish in the thermodynamic limit!

Parameters:
  • sites (list of Site) – Defines the local Hilbert space for each site.

  • coeff (list of float/complex) – Wave packet coefficients.

  • op (str) – Name of the operator to be applied.

  • eps (float) – Discard terms where abs(coeff[i]) < eps.

Examples

Say you have fermions, so op='Cd', and want to create a gaussian wave packet \(\sum_x \alpha_x c^\dagger_x\) with \(\alpha_x \propto e^{-0.5(x-x_0)^2/\sigma^2} e^{i k_0 x}\). Then you would use

>>> L, k0, x0, sigma, = 50, np.pi/8., 10., 5.
>>> x = np.arange(L)
>>> coeff = np.exp(-1.j * k0 * x) * np.exp(- 0.5 * (x - x0)**2 / sigma**2)
>>> coeff /= np.linalg.norm(coeff)
>>> site = FermionSite(conserve='N')
>>> wp = MPO.from_wavepacket([site] * L, coeff, 'Cd')
>>> wp.chi == [1] + [2] * (L - 1) + [1]
True

Indeed, we can apply this to a (vacuum) MPS and get the correct state:

>>> psi = MPS.from_product_state([site] * L, ['empty'] * L)
>>> wp.apply(psi, dict(compression_method='SVD'))
TruncationError()
>>> C = psi.correlation_function('Cd', 'C')
>>> C_expected = np.conj(coeff)[:, np.newaxis] * coeff[np.newaxis, :]
>>> bool(np.max(np.abs(C - C_expected) ) < 1.e-10)
True
test_sanity()[source]

Sanity check, raises ValueErrors, if something is wrong.

property L

Number of physical sites; for an iMPO the len of the MPO unit cell.

property dim

List of local physical dimensions.

property finite

Distinguish MPO vs iMPO.

True for an MPO (bc='finite', 'segment'), False for an iMPO (bc='infinite').

property chi

Dimensions of the virtual bonds.

get_W(i, copy=False)[source]

Return W at site i.

set_W(i, W)[source]

Set W at site i.

get_IdL(i)[source]

Return index of IdL at bond to the left of site i.

May be None.

get_IdR(i)[source]

Return index of IdR at bond to the right of site i.

May be None.

enlarge_mps_unit_cell(factor=2)[source]

Repeat the unit cell for infinite MPS boundary conditions; in place.

Parameters:

factor (int) – The new number of sites in the unit cell will be increased from L to factor*L.

group_sites(n=2, grouped_sites=None)[source]

Modify self inplace to group sites.

Group each n sites together using the GroupedSite. This might allow to do TEBD with a Trotter decomposition, or help the convergence of DMRG (in case of too long range interactions).

Parameters:
  • n (int) – Number of sites to be grouped together.

  • grouped_sites (None | list of GroupedSite) – The sites grouped together.

extract_segment(first, last)[source]

Extract a segment from the MPO.

Parameters:
  • first (int) – The first and last site to include into the segment.

  • last (int) – The first and last site to include into the segment.

Returns:

cp – A copy of self with “segment” boundary conditions.

Return type:

MPO

See also

tenpy.networks.mps.MPS.extract_segment

similar method for MPS.

sort_legcharges()[source]

Sort virtual legs by charges. In place.

The MPO seen as matrix of the wL, wR legs is usually very sparse. This sparsity is captured by the LegCharges for these bonds not being sorted and bunched. This requires a tensordot to do more block-multiplications with smaller blocks. This is in general faster for large blocks, but might lead to a larger overhead for small blocks. Therefore, this function allows to sort the virtual legs by charges.

make_U(dt, approximation='II')[source]

Creates the U_I or U_II propagator.

Approximations of MPO exponentials following [zaletel2015].

Parameters:
  • dt (float|complex) – The time step per application of the propagator. Should be imaginary for real time evolution!

  • approximation ('I' | 'II') – Selects the approximation, make_U_I() ('I') or make_U_II() ('II').

Returns:

U – The propagator, i.e. approximation \(U ~= exp(H*dt)\)

Return type:

MPO

make_U_I(dt)[source]

Creates the \(U_I\) propagator with W_I tensors.

Parameters:

dt (float|complex) – The time step per application of the propagator. Should be imaginary for real time evolution!

Returns:

UI – The propagator, i.e. approximation \(U_I ~= exp(H*dt)\)

Return type:

MPO

make_U_II(dt)[source]

Creates the \(U_II\) propagator.

Parameters:

dt (float|complex) – The time step per application of the propagator. Should be imaginary for real time evolution!

Returns:

U_II – The propagator, i.e. approximation \(UII ~= exp(H*dt)\)

Return type:

MPO

expectation_value(psi, tol=1e-10, max_range=100, init_env_data={})[source]

Calculate <psi|self|psi>/<psi|psi> (or density for infinite).

For infinite MPS, it assumes that self is extensive, e.g. a Hamiltonian but not a unitary, and returns the expectation value density. For finite MPS, it just returns the total value.

This function is just a small wrapper around expectation_value_finite(), expectation_value_powermethod() or expectation_value_transfer_matrix().

Parameters:
  • psi (MPS) – The state in which to calculate the expectation value.

  • tol – See expectation_value_powermethod().

  • max_range – See expectation_value_powermethod().

  • init_env_data (dict) – Optional environment data, if known.

Returns:

exp_val – The expectation value of self with respect to the state psi. For an infinite MPS: the (energy) density per site.

Return type:

float/complex

expectation_value_finite(psi, init_env_data={})[source]

Calculate <psi|self|psi>/<psi|psi> for finite MPS.

Parameters:
  • psi (MPS) – The state in which to calculate the expectation value.

  • init_env_data (dict) – Optional environment data (for segment MPS).

Returns:

exp_val – The expectation value of self with respect to the state psi (extensive, not the density).

Return type:

float/complex

expectation_value_TM(psi, tol=1e-10, init_env_data={})[source]

Calculate <psi|self|psi>/<psi|psi> / L from the MPOTransferMatrix.

Only for infinite MPS, and assumes that the Hamiltonian is an extensive sum of (quasi)local terms, and that the MPO has all IdL and IdR defined.

Diagonalizing the MPOTransferMatrix allows to find energy densities for infinite systems even for hamiltonians with infinite (exponentially decaying) range.

Parameters:
  • psi (MPS) – The state in which to calculate the expectation value.

  • tol (float) – Precision for finding the eigenvectors of the transfer matrix.

  • init_env_data (dict) – Optional guess for the environment data.

Returns:

exp_val – The expectation value density of self with respect to the state psi.

Return type:

float/complex

expectation_value_power(psi, tol=1e-10, max_range=100)[source]

Calculate <psi|self|psi>/<psi|psi> with a power-method.

Only for infinite MPS, and assumes that the Hamiltonian is an extensive sum of (quasi)local terms, and that the MPO has all IdL and IdR defined. Only for infinite MPS.

Instead of diagonalizing the MPOTransferMatrix like expectation_value_TM(), this method uses just considers terms of the MPO starting in the first unit cell and then continues to contract tensors until convergence. For infinite-range MPOs, this converges like a power-method (i.e. slower than expectation_value_TM()), but for finite-range MPOs it’s likely faster, and conceptually cleaner.

Parameters:
  • psi (MPS) – The state in which to calculate the expectation value.

  • tol (float) – For infinite MPO containing exponentially decaying long-range terms, stop evaluating further terms if the terms in LP have norm < tol.

  • max_range (int) – Ignored for finite psi. Contract at most self.L * max_range sites, even if tol is not reached. In that case, issue a warning.

Returns:

exp_val – The expectation value of self with respect to the state psi. For an infinite MPS: the density per site.

Return type:

float/complex

variance(psi, exp_val=None)[source]

Calculate <psi|self^2|psi> - <psi|self|psi>^2.

Works only for finite systems. Ignores the norm of psi.

Todo

This is a naive, expensive implementation contracting the full network. Try to follow arXiv:1711.01104 for a better estimate; would that even work in the infinite limit?

Parameters:
  • psi (MPS) – State for which the variance should be taken.

  • exp_val (float/complex | None) – The result of <psi|self|psi> = self.expectation_value(psi) if known; otherwise obtained from expectation_value(). (Set this to 0 to obtain only the part <psi|self^2|psi>.)

prefactor(i, ops)[source]

Get prefactor for a given string of operators in self.

Parameters:
  • i (int) – First site with non-identity operator.

  • ops (list of str) – String of operators for which the prefactor is to be determined; the first entry is the name for the operator acting on site i, second entry on site i + 1, etc.

Returns:

prefactor – The prefactor obtained from trace(dagger(ops), H) / norm, where norm = trace(dagger(ops), ops)

Return type:

float

to_TermList(op_basis, start=None, max_range=None, cutoff=1e-12, ignore=['Id', 'JW'])[source]

Obtain a TermList represented by self.

This function is meant for debugging MPOs to make sure they have the terms one expects. Be aware of pitfalls with operator orthonormality, e.g. for fermions N = 0.5 * (Id + JW) might not appear as you expect due to ignore.

Parameters:
  • op_basis ((list of) list of str) – Local basis of operators in which to represent all terms of self, e.g. ['Id', 'Sx', 'Sy', 'Sz'] for spin-1/2 or ['Id', 'JW', 'C', 'Cd'] for fermions. Should be orthogonal with respect to the operator product <A|B> = tr(A^dagger B).

  • start ((list of) int) – Extract terms starting on that/these sites, going to the right, i.e. the left-most index within each term is in start. If None, take all terms starting in range(L), i.e. one MPS unit cell for infinite systems.

  • cutoff (float) – Drop terms with prefactors (roughly) smaller than that. Strictly speaking, it might also drop larger terms if the term has larger weight on the right (in the MPO) than on the left.

  • ignore (list of str) – Filter terms to not contain these operator names when they’re not the left/rightmost operators in a term.

Returns:

term_list – The terms in self with left-most index in start.

Return type:

TermList

dagger()[source]

Return hermitian conjugate copy of self.

is_hermitian(eps=1e-10, max_range=None)[source]

Check if self is a hermitian MPO.

Shorthand for self.is_equal(self.dagger(), eps, max_range).

is_equal(other, eps=1e-10, max_range=None)[source]

Check if self and other represent the same MPO to precision eps.

To compare them efficiently we view self and other as MPS and compare the overlaps abs(<self|self> + <other|other> - 2 Re(<self|other>)) < eps*(<self|self>+<other|other>)

Parameters:
  • other (MPO) – The MPO to compare to.

  • eps (float) – Precision threshold what counts as zero.

  • max_range (None | int) – Ignored for finite MPS; for finite MPS we consider only the terms contained in the sites with indices range(self.L + max_range). None defaults to max_range (or L in case this is infinite or None).

Returns:

equal – Whether self equals other to the desired precision.

Return type:

bool

apply(psi, options)[source]

Apply self to an MPS psi and compress psi in place.

For infinite MPS, the assumed form of self is a product (e.g. a time evolution operator \(U= e^{-iH dt}\), not an (extensive) sum as a Hamiltonian would have. See A warning about infinite MPS for more details.

Options

config ApplyMPO
option summary

chi_list (from Sweep) in IterativeSweeps.reset_stats

By default (``None``) this feature is disabled. [...]

chi_list_reactivates_mixer (from Sweep) in IterativeSweeps.sweep

If True, the mixer is reset/reactivated each time the bond dimension growth [...]

combine (from Sweep) in Sweep

Whether to combine legs into pipes. This combines the virtual and [...]

compression_method

Mandatory. [...]

lanczos_params (from Sweep) in Sweep

Lanczos parameters as described in :cfg:config:`KrylovBased`.

m_temp (from ZipUpApplyMPO) in MPO.apply_zipup

bond dimension will be truncated to `m_temp * chi_max`

max_hours (from IterativeSweeps) in DMRGEngine.stopping_criterion

If the DMRG took longer (measured in wall-clock time), [...]

max_N_sites_per_ring (from Algorithm) in Algorithm

Threshold for raising errors on too many sites per ring. Default ``18``. [...]

max_sweeps (from IterativeSweeps) in DMRGEngine.stopping_criterion

Maximum number of sweeps to perform.

max_trunc_err (from IterativeSweeps) in IterativeSweeps

Threshold for raising errors on too large truncation errors. Default ``0.00 [...]

min_sweeps (from IterativeSweeps) in DMRGEngine.stopping_criterion

Minimum number of sweeps to perform.

mixer (from Sweep) in DMRGEngine.mixer_activate

Specifies which :class:`Mixer` to use, if any. [...]

mixer_params (from Sweep) in DMRGEngine.mixer_activate

Mixer parameters as described in :cfg:config:`Mixer`.

start_env (from Sweep) in DMRGEngine.init_env

Number of sweeps to be performed without optimization to update the environment.

start_env_sites (from VariationalCompression) in VariationalCompression

Number of sites to contract for the initial LP/RP environment in case of in [...]

tol_theta_diff (from VariationalCompression) in VariationalCompression

Stop after less than `max_sweeps` sweeps if the 1-site wave function change [...]

trunc_params

Truncation parameters as described in :cfg:config:`truncation`.

trunc_weight (from ZipUpApplyMPO) in MPO.apply_zipup

reduces cut for Schmidt values to `trunc_weight * svd_min`

option compression_method: 'SVD' | 'variational' | 'zip_up'

Mandatory. Selects the method to be used for compression. For the SVD compression, trunc_params is the only other option used.

option trunc_params: dict

Truncation parameters as described in truncation.

Parameters:
  • psi (MPS) – The state to which self should be applied, in place.

  • options (dict) – See above.

apply_naively(psi)[source]

Applies an MPO to an MPS (in place) naively, without compression.

This function simply contracts the W tensors of the MPO to the B tensors of the MPS, resulting in an MPS with bond dimension self.chi * psi.chi.

Warning

This function sets only a wild guess for the new singular values. You should either compress the MPS or at least call canonical_form(). If you use apply() instead, this will be done automatically.

Parameters:

psi (MPS) – The MPS to which self should be applied. Modified in place!

apply_zipup(psi, options)[source]

Applies an MPO to an MPS (in place) with the zip-up method.

Described in Ref. [stoudenmire2010].

The ‘W’ tensors are contracted to the ‘B’ tensors with intermediate SVD compressions, truncated to bond dimensions chi_max * m_temp.

Warning

The MPS afterwards is only approximately in canonical form (under the assumption that self is close to unity). You should either compress the MPS or at least call canonical_form(). If you use apply() instead, this will be done automatically.

Parameters:
  • psi (MPS) – The MPS to which self should be applied. Modified in place!

  • trunc_params (dict) – Truncation parameters as described in truncation.

Options

config ZipUpApplyMPO
option summary

m_temp

bond dimension will be truncated to `m_temp * chi_max`

trunc_params

Truncation parameters as described in :cfg:config:`truncation`.

trunc_weight

reduces cut for Schmidt values to `trunc_weight * svd_min`

option trunc_params: dict

Truncation parameters as described in truncation.

option m_temp: int

bond dimension will be truncated to m_temp * chi_max

option trunc_weight: float

reduces cut for Schmidt values to trunc_weight * svd_min