MPO
full name: tenpy.networks.mpo.MPO
parent module:
tenpy.networks.mpotype: class
Inheritance Diagram

Methods
|
|
|
Apply self to an MPS psi and compress psi in place. |
|
Applies an MPO to an MPS (in place) naively, without compression. |
|
Applies an MPO to an MPS (in place) with the zip-up method. |
|
Make a shallow copy of self. |
Return hermitian conjugate copy of self. |
|
|
The Frobenius distance induced by the inner product |
|
Repeat the unit cell for infinite MPS boundary conditions; in place. |
|
Calculate |
|
Calculate |
|
Calculate |
|
Calculate |
|
Extract a segment from the MPO. |
|
Initialize an MPO from grids. |
|
Load instance from a HDF5 file. |
|
Create a (finite) MPO wave packet representing |
|
Return index of IdL at bond to the left of site i. |
|
Return index of IdR at bond to the right of site i. |
|
Return W at site i. |
|
Get the i-th site. |
|
Modify self inplace to group sites. |
|
Check if self and other represent the same MPO to precision eps. |
|
Check if self is a hermitian MPO. |
|
Creates the U_I or U_II propagator. |
|
Creates the \(U_I\) propagator with W_I tensors. |
|
Creates the \(U_{II}\) propagator. |
|
Overlap between two MPOs. |
|
Compute a new MPO \(alpha * 1 + beta * \mathtt{self}\). |
|
Get prefactor for a given string of operators in self. |
|
Export self into a HDF5 file. |
|
Set W at site i. |
|
Shift an Array by an integer multiple of unit cells. |
|
Shift a site by an integer multiple of unit cells. |
|
Shift charges by an integer multiple of unit cells. |
Sort virtual legs by charges. |
|
Sanity check, raises ValueErrors, if something is wrong. |
|
|
Obtain a TermList represented by self. |
|
Calculate |
Class Attributes and Properties
Number of physical sites; for an iMPS the len of the MPS unit cell. |
|
Number of sites per horizontal lattice spacing. |
|
Dimensions of the virtual bonds. |
|
List of local physical dimensions. |
|
Distinguish MPS vs iMPS. |
|
Slice of the non-trivial bond indices, depending on |
- class tenpy.networks.mpo.MPO(sites, Ws, bc='finite', IdL=None, IdR=None, max_range=None, explicit_plus_hc=False, mps_unit_cell_width=None)[source]
Bases:
MPSGeometryMatrix product operator, finite (MPO) or infinite (iMPO).
- Parameters:
Ws (list of
Array) – The matrices of the MPO. Should have labelswL, wR, p, p*. Finite boundary conditions requireWs[0].get_leg('wL').ind_len == 1, and similarlyWs[-1].get_leg('wR').ind_len == 1IdL ((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.
Nonefor 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.
unit_cell_width (int) – See
mps_unit_cell_width.
- bc
Boundary conditions as described in
mps.'finite'requiresWs[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.
Nonefor unknown.- Type:
int | np.inf | None
- grouped
Number of sites grouped together, see
group_sites().- Type:
- 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:
- _graph
Represents the graph structure of self. _graph[j_site][(i,j)] = op where op=self._W[j_site][i,j] iff npc.norm(op)>0 Defaults to None if the graph is invalid or has not yet been built
- Type:
None | list of {dict of {(int,int):
Array}}
- _outer_permutation
Relevant only for iMPOs and segment MPOs with contractible outer virtual legs: self._W[0].get_leg(“wL”), self._W[-1].get_leg(“wR”) Ordering of the outer virtual legs such that self is upper triangular w.r.t. the whole unit cell. Follows the constraint _outer_permutation[0] = self.IdL[0], _outer_permutation[-1] = self.IdR[-1] Defaults to None if the ordering has not yet been checked of False if ordering the MPO is not possible Note: This ordering is valid only with respect to the whole unit cell, not for internal ‘wL’/’wR’ legs.
- _cycles
Contains one entry _cycles[i0] = [i0, i1, …, iL = i0] for each index i0 of the outer virtual leg that connects to itself. The cycle is _W[0][i0, i1] * _W[1][i1, i2] * … * _W[L-1][iL-1, iL] Defaults to None if
_outer_permutationdoes not exist.- Type:
None | dict {int: list of int}
- 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,unit_cell_width(under these names),_Was"tensors",IdLas"index_identity_left",IdRas"index_identity_right", andbcas"boundary_condition". Moreover, it savesL,explicit_plus_hcandgroupedas HDF5 attributes, as well as the maximum ofchiunder the namemax_bond_dimension.
- 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, mps_unit_cell_width=None)[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 (seegrid_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 tolegs[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. (TheMPOGraphcan handle those cases, though.)max_range (int | np.inf | None) – Maximum range of hopping/interactions (in unit of sites) of the MPO.
Nonefor unknown.explicit_plus_hc (bool) – If True, the Hermitian conjugate of the MPO is computed at runtime, rather than saved in the MPO.
unit_cell_width (int) – See
mps_unit_cell_width.
See also
grid_insert_opsused to plug in entries of the grid.
tenpy.linalg.np_conserved.grid_outerused for final conversion.
- classmethod from_wavepacket(sites, coeff, op, eps=1e-15, unit_cell_width=None)[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:
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.0, 10.0, 5.0 >>> x = np.arange(L) >>> coeff = np.exp(-1.0j * 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, unit_cell_width=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.0e-10) True
- property chi
Dimensions of the virtual bonds.
- 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:
- Returns:
cp – A copy of self with “segment” boundary conditions.
- Return type:
See also
tenpy.networks.mps.MPS.extract_segmentsimilar method for MPS.
- sort_legcharges()[source]
Sort virtual legs by charges. In place.
The MPO seen as matrix of the
wL, wRlegs 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') ormake_U_II()('II').
- Returns:
U – The propagator, i.e. approximation \(U ~= exp(H*dt)\)
- Return type:
- 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_power()orexpectation_value_TM().- Parameters:
- 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.
- expectation_value_TM(psi, tol=1e-10, init_env_data={})[source]
Calculate
<psi|self|psi>/<psi|psi> / Lfrom 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
IdLandIdRdefined.Diagonalizing the
MPOTransferMatrixallows to find energy densities for infinite systems even for hamiltonians with infinite (exponentially decaying) range.- Parameters:
- 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
IdLandIdRdefined. 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 thanexpectation_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_rangesites, 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
normof 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 fromexpectation_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:
- Returns:
prefactor – The prefactor obtained from
trace(dagger(ops), H) / norm, wherenorm = trace(dagger(ops), ops)- Return type:
- 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 inrange(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:
- 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 + 2 * max_range). None defaults tomax_range(orLin case this is infinite or None).
- Returns:
equal – Whether self equals other to the desired precision.
- Return type:
- 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 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 [...]
Whether to combine legs into pipes. This combines the virtual and [...]
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.
Specifies which :class:`Mixer` to use, if any. [...]
mixer_params (from Sweep) in DMRGEngine.mixer_activate
Mixer parameters as described in :cfg:config:`Mixer`.
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 [...]
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.
-
option compression_method:
- 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 useapply()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 useapply()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 bond dimension will be truncated to `m_temp * chi_max`
Truncation parameters as described in :cfg:config:`truncation`.
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
- plus_identity(alpha, beta, sites=[0])[source]
Compute a new MPO \(alpha * 1 + beta * \mathtt{self}\).
This can e.g. be used to make a simple (non-unitary) first-order approximation to the time evolution unitary \(e^{-i t H} \approx 1 - i t H\).
This function only works for finite MPOs for now.
- Parameters:
- Returns:
mpo – MPO representing the operator \(\alpha * 1 + \beta O\)
- Return type:
Notes
There is significant freedom in how we incorporate the linear combination into the MPO structure. One naive choice is to only modify the first tensor.
The first tensor (ignoring the second wL entry since it’s unnecessary):
[1 C D] -> [beta*1 beta*C alpha*1+beta*D]
Another choice is to modify N tensors specified by the input argument sites.
- overlap(other, understood_infinite: bool = False, num_sites: int = None)[source]
Overlap between two MPOs.
For finite MPOs, this is the Frobenius inner product:
<self|other> = Tr[hconj(self) @ other]
For infinite MPOs, the TD limit of that overlap is always either 0, 1 or infinite, i.e. it is not helpful. Instead we choose a finite section of the infinite overlap diagram and project onto
IdLon the left andIdRon the right. This means we effectively compute the overlap between those contributions to the MPOs that act trivially outside the finite section. The main motivation is a distance measure inis_equal().- Parameters:
other (MPO) – The other operator. Must have the same
finite, and if finite the sameL.understood_infinite (bool) – For infinite MPOs, the overlap has an unusual definition, see above. Set this flag to confirm you understand this and suppress the warning.
num_sites (int) – Ignored for finite MPOs. For infinite MPOs, the number of sites that we contract. We project onto IdL on site
0, contract tensors fromrange(num_sites), and then project onto IdR. By default, we useL + 2 * max_rangeof whichever MPO has the larger value, where we substituteLfor an unknown or infinitemax_range.
- distance(other, understood_infinite: bool = False, num_sites: int = None)[source]
The Frobenius distance induced by the inner product
overlap().
- property L
Number of physical sites; for an iMPS the len of the MPS unit cell.
- property N_sites_per_hor_spacing
Number of sites per horizontal lattice spacing.
This is the number of MPS sites one has to traverse to travel one lattice spacing in the first dimension, such that
self.unit_cell_width * N_sites_per_hor_spacing == self.L.
- property dim
List of local physical dimensions.
- property finite
Distinguish MPS vs iMPS.
True for an MPS (
bc='finite', 'segment'), False for an iMPS (bc='infinite').
- get_site(i)[source]
Get the i-th site.
This is
self.sites[i]if i is in the unit cell and takes care of shifting the charges otherwise.
- property nontrivial_bonds
Slice of the non-trivial bond indices, depending on
self.bc.
- shift_Array_unit_cells(arr, num_unit_cells, inplace: bool = False)[source]
Shift an Array by an integer multiple of unit cells.
See the notes on Dipole Conservation.
A unit cell has length
Land a shift by one unit cell is purely horizontal and shifts byunit_cell_widthlattice spacings.
- shift_Site_unit_cells(site, num_unit_cells)[source]
Shift a site by an integer multiple of unit cells.
See the notes on Dipole Conservation.
A unit cell has length
Land a shift by one unit cell is purely horizontal and shifts byunit_cell_widthlattice spacings.
- shift_charges_unit_cells(charges, num_unit_cells)[source]
Shift charges by an integer multiple of unit cells.
See the notes on Dipole Conservation.
A unit cell has length
Land a shift by one unit cell is purely horizontal and shifts byunit_cell_widthlattice spacings.Essentially, this is a convenience wrapper around \(tenpy.linalg.charges.ChargeInfo.shift_charges_horizontal\).
- Parameters:
charges (2D ndarray of dtype QTYPE) – The charges to shift.
num_unit_cells (int) – The number of unit cells.
- Returns:
The shifted charges.
- Return type:
2D ndarray of dtype QTYPE