Creating MPS and MPO#

Initializing empty MPS/MPO#

MPS and MPO are instances of class yastn.tn.mps.MpsMpoOBC.

class yastn.tn.mps.MpsMpoOBC(N=1, nr_phys=1)[source]#

Initialize empty MPS (nr_phys=1) or MPO (nr_phys=2) for system of N sites. Empty MPS/MPO has no tensors assigned.

MpsMpoOBC tensors (sites) are indexed by integers \(0, 1, 2, \ldots, N-1\), where \(0\) corresponds to the ‘first’ site. They can be accessed with [] operator. MPS/MPO can contain a central block associated with a bond and indexed by a tuple \((n, n+1)\). At most one central block is allowed.

The legs’ order of each tensor is: (0) virtual leg pointing towards the first site, (1) 1st physical leg, i.e., \(|\textrm{ket}\rangle\), (2) virtual leg pointing towards the last site, and, in case of MPO, (3) 2nd physical leg, i.e., \(\langle \textrm{bra}|\).

The canonical form can be used with the MPS/MPO freely. If the MPS/MPO is not normalized the amplitude is kept as self.factor paramter of the object. If the object is normalized, then self.factor=1.

One can directly create a new empty MPS of N sites using yastn.tn.mps.Mps(N). Similarly, yastn.tn.mps.Mpo(N) initializes MPO. The new instances start without any tensors defined.

yastn.tn.mps.Mps(N) yastn.tn.mps.MpsMpoOBC[source]#

Generate empty MPS for system of N sites, fixing nr_phys=1.

yastn.tn.mps.Mpo(N, periodic=False) yastn.tn.mps.MpsMpoOBC | yastn.tn.mps.MpoPBC[source]#

Generate empty MPO for system of N sites, fixing nr_phys=2.

A flag periodic allows initializing periodic MPO, which is a special class supported as an operator in MPS environments.

Setting MPS/MPO tensors by hand#

An empty MPS/MPO can be filled with tensors by setting them one by one.

import yastn
import yastn.tn.mps as mps

# create empty MPS over three sites
psi = mps.Mps(3)

# create 3x2x3 random dense tensor
config = yastn.make_config()  # config for dense tensors
legs = [yastn.Leg(config, s=-1, D=(3,)),
        yastn.Leg(config, s=1, D=(2,)),
        yastn.Leg(config, s=1, D=(3,))]
A_1 = yastn.rand(config, legs=legs)

# assign tensor to site 1
psi[1] = A_1

Tensor should be of the rank expected for MPS or MPO. The virtual dimensions/spaces of the neighboring MPS/MPO tensors should be consistent, which, however, is not tested during direct assigment. For examples showing creation of MPS/MPO by hand, see Ground state of Spin-1 AKLT model and MPO for hopping model with U(1) symmetry.

Initializing product MPS/MPO#

yastn.tn.mps.product_mps(vectors, N=None) yastn.tn.mps.MpsMpoOBC[source]#

Generate an MPS with bond-dimension 1 from a list of vectors that get assigned to consecutive MPS sites.

If N is provided, vectors are cyclicly iterated to fill in N MPS sites.

Parameters:
  • vectors (Sequence[yastn.Tensor] | yastn.Tensor) – Tensors will be attributed to consecutive MPS sites. They can have non-zero charges that will be converted into matching MPS virtual legs. Each tensor should have ndim=1 and, typically, the signature s=+1. The latter is not enforced.

  • N (Optional[int]) – number of MPS sites. By default, it is equal to the number of provided vectors.

yastn.tn.mps.product_mpo(operators, N=None) yastn.tn.mps.MpsMpoOBC[source]#

Generate an MPO with bond-dimension 1 from a list of operators that get assigned to consecutive MPO sites.

If N is provided, operators are cyclicly iterated to fill in N MPO sites.

Parameters:
  • operators (Sequence[yastn.Tensor] | yastn.Tensor) – Tensors will be attributed to consecutive MPS sites. They can have non-zero charges, that will be converted into matching MPO virtual legs. Each tensor should have ndim=2 and, typically, the signature s=(+1, -1). The latter is not enforced.

  • N (Optional[int]) – number of MPO sites. By default, it is equal to the number of provided operators.

Example

# This function can help set up an identity MPO,
# which is the base ingredient for a few other functions
# generating more complicated MPOs and MPSs.

import yastn
import yastn.tn.mps as mps

ops = yastn.operators.Spin12(sym='Z2')
I = mps.product_mpo(ops.I(), N=8)

# Here, each site has the same local physical Hilbert space
# of dimension 2, consistent with predefined spin-1/2 operators.
# The MPO I uniquely identifies those local Hilbert spaces.

Initializing random MPS/MPO#

yastn.tn.mps.random_mps(I, n=None, D_total=8, sigma=1, dtype='float64') yastn.tn.mps.MpsMpoOBC[source]#

Generate a random MPS of total charge n and bond dimension D_total.

Local Hilbert spaces are read from ket spaces of provided MPS or MPO I. For instance, I can be an identity MPO. The number of sites and Tensor config is also inherited from I.

Parameters:
  • I (yastn.tn.mps.MpsMpoOBC) – MPS or MPO that defines local Hilbert spaces.

  • n (int) – Total charge of MPS. Virtual MPS spaces are drawn randomly from a normal distribution, whose mean value changes linearly along the chain from n to 0.

  • D_total (int) – Largest bond dimension. Due to the random and local nature of the procedure, the desired total bond dimension might not be reached on some bonds, in particular, for higher symmetries.

  • sigma (int) – The standard deviation of the normal distribution.

  • dtype (string) – Number format, i.e., 'float64' or 'complex128'

Example

import yastn
import yastn.tn.mps as mps

ops = yastn.operators.SpinlessFermions(sym='U1')
I = mps.product_mpo(ops.I(), N=13)
psi = mps.random_mps(I, n=6, D_total=8)

# Random MPS with 13 sites occupied by 6 fermions (fixed by U1 symmetry),
# and maximal bond dimension 8.
yastn.tn.mps.random_mpo(I, D_total=8, sigma=1, dtype='float64') yastn.tn.mps.MpsMpoOBC[source]#

Generate a random MPO with bond dimension D_total.

The number of sites and local bra and ket spaces of MPO follow from provided MPO I, e.g., an identity MPO. I can be an MPS, in which case its ket spaces are used and conjugated for bra spaces.

Parameters:
  • I (yastn.tn.mps.MpsMpoOBC) – MPS or MPO that defines local spaces.

  • D_total (int) – Largest bond dimension. Due to the random and local nature of the procedure, the desired total bond dimension might not be reached on some bonds, in particular, for higher symmetries.

  • sigma (int) – Standard deviation of a normal distribution from which dimensions of charge sectors are drawn.

  • dtype (string) – number format, i.e., 'float64' or 'complex128'

Generating MPO using Hterm#

We provide functionality to build MPO representations for a broad class of operators, e.g., Hamiltonians, given as a sum of products of local (on-site) operators. They are encoded as a list of mps.Hterm, where each mps.Hterm represents a product of local operators, including the numerical coefficient (amplitude) in front of that product.

To generate the corresponding MPO use mps.generate_mpo(I, terms), where terms is a list of Hterm-s and I is the identity MPO. The latter can be conveniently created as shown in mps.product_mpo. For an example, see MPO for spinless fermions with long-range hopping via Hterms.

class yastn.tn.mps.Hterm(amplitude: float = 1.0, positions: tuple = (), operators: tuple = ())[source]#

Defines a product operator \(O=`amplitude`{\times}\bigotimes_i o_i\) of local operators \(o_i\). Local operators that are not explicitly specified are assumed to be identity operators.

If operators are fermionic, execution of swap gates enforces fermionic order, with the last operator in operators acting first.

Parameters:
  • amplitude (number) – numerical multiplier in front of the operator product.

  • positions (Sequence[int]) – positions of the local operators \(o_i\) in the product different than identity.

  • operators (Sequence[yastn.Tensor]) – local operators in the product that are different than the identity. i-th operator is acting at positions[i]. Each operator should have ndim=2 and signature s=(+1, -1).

Create new instance of Hterm(amplitude, positions, operators)

yastn.tn.mps.generate_mpo(I, terms=None, opts_svd=None) yastn.tn.mps.MpsMpoOBC[source]#

Generate MPO provided a list of Hterm-s and identity MPO I.

It employs mps.generate_mpo_preprocessing and mps.generate_mpo_fast, but without bookkeeping the template obtained in the preprocessing step. The latter would speed up the generation of MPOs for different amplitudes in front of the same set of product operators.

Parameters:
  • terms (Sequence[yastn.tn.mps.Hterm]) – Product operators making up MPO.

  • I (yastn.tn.mps.MpsMpoOBC) – Identity MPO.

  • opts (dict) – Options passed to yastn.linalg.svd_with_truncation(). The function employs SVD while compressing the MPO bond dimensions. Default None sets truncation tol close to the numerical precision, which typically results in lossless compression.

yastn.tn.mps.generate_mpo_fast(template, amplitudes, opts_svd=None) yastn.tn.mps.MpsMpoOBC[source]#

Fast generation of MPOs representing Sequence[Hterm] that differ only in amplitudes.

Preprocessing in yastn.tn.mps.generate_mpo() might be slow. When only amplitudes in Hterms are changing, e.g., for time-dependent Hamiltonian, MPO generation can be significantly speeded up by precalculating and reusing amplitude-independent template. The latter is done with yastn.tn.mps.generate_mpo_preprocessing().

Parameters:
  • template (NamedTuple) – Calculated with mps.generate_mpo_preprocessing.

  • amplidutes (Sequence[numbers]) – List of amplitudes that would appear in Hterm. The order of the list should match the order of Sequence[Hterm] supplemented to mps.generate_mpo_preprocessing.

  • opts (dict) – Options passed to yastn.linalg.svd_with_truncation(). The function employs SVD while compressing the MPO bond dimensions. Default None sets truncation tol close to the numerical precision, which typically results in lossless compression.

yastn.tn.mps.generate_mpo_preprocessing(I, terms=None) GenerateMpoTemplate | tuple[GenerateMpoTemplate, list[float]][source]#

Precompute an amplitude-independent template that is used to generate MPO with mps.generate_mpo_fast

Parameters:
  • I (yastn.tn.mps.MpsMpoOBC) – identity MPO.

  • terms (list of Hterm) – product operators making up the MPO.

Generator class for MPO/MPS (beta)#

A class supporting automatizes generation of MPOs from LaTeX-like expressions.

class yastn.tn.mps.Generator(N, operators, map=None, Is=None, parameters=None, opts={'tol': 1e-13})[source]#

Generator is a convenience class building MPOs from a set of local operators.

Parameters:
  • N (int) – number of sites of MPO.

  • operators (object or dict[str, yastn.Tensor]) – a set of local operators, e.g., an instance of yastn.operators.Spin12. Or a dictionary with string-labeled local operators, including at least {'I': <identity operator>,...}.

  • map (dict[int, int]) – custom labels of N sites indexed from 0 to N-1 , e.g., {3: 0, 21: 1, ...}. If None, the sites are labled as {site: site for site in range(N)}.

  • Is (dict[int, str]) – For each site (using default or custom label), specify identity operator by providing its string key as defined in operators. If None, assumes {i: 'I' for i in range(N)}, which is compatible with all predefined operators.

  • parameters (dict) – Default parameters used by the interpreters Generator.mpo() and Generator.mps(). If None, uses default {'sites': [*map.keys()]}.

  • opts (dict) – used if compression is needed. Options passed to yastn.linalg.svd_with_truncation().

We can directly output identity MPO built from the identity I from the operator generator class.

Generator.I() yastn.tn.mps.MpsMpoOBC[source]#

Identity MPO derived from identity in local operators class.

Generator.mpo_from_latex(H_str, parameters=None, opts=None) yastn.tn.mps.MpsMpoOBC[source]#

Convert latex-like string to yastn.tn.mps MPO.

Parameters:
  • H_str (str) – The definition of the MPO given as latex expression. The definition uses string names of the operators given in. The assignment of the location is given e.g. for ‘cp’ operator as ‘cp_{j}’ (always with {}-brackets!) for ‘cp’ operator acting on site ‘j’. The space and * are interpreted as multiplication by a number of by an operator. E.g., to multiply by a number use ‘g * cp_j c_{j+1}’ where ‘g’ has to be defines in ‘parameters’ or writen directly as a number, You can define automatic summation with expression ‘sum_{j in A}’, where A has to be iterable, one-dimensional object with specified values of ‘j’.

  • parameters (dict) – Keys for the dict define the expressions that occur in H_str

Generator supports latex-like string instructions to help building MPOs. For examples, see Generate MPO from LaTex.

Generator allows initialization of MPS and MPO filled with random tensors, where local Hilbert spaces are read from the identity operator in the Generator. It also provides a direct link to a random number generator in the backend to fix the seed.

Generator.random_mps(n=None, D_total=8, sigma=1, dtype='float64') yastn.tn.mps.MpsMpoOBC[source]#

Generate a random MPS of total charge n and bond dimension D_total.

See, mps.random_mps.

Generator.random_mpo(D_total=8, sigma=1, dtype='float64') yastn.tn.mps.MpsMpoOBC[source]#

Generate a random MPO with bond dimension D_total.

See, mps.random_mps.

Generator.random_seed(seed)[source]#

Set seed for random number generator used in backend (of self.config).

Parameters:

seed (int) – Seed number for random number generator.

Making a copy of MPS/MPO#

To create an independent copy or clone of MPS/MPO psi call psi.copy() or psi.clone(), respectively. It is also possible to make a shallow copy with psi.shallow_copy(), where explicit copies of data tensors are not created.

MpsMpoOBC.shallow_copy() yastn.tn.mps.MpsMpoOBC#

New instance of yastn.tn.mps.MpsMpoOBC pointing to the same tensors as the old one.

Shallow copy is usually sufficient to retain the old MPS/MPO.

MpsMpoOBC.copy() yastn.tn.mps.MpsMpoOBC#

Makes a copy of MPS or MPO by copying all yastn.Tensor’s into a new and independent yastn.tn.mps.MpsMpoOBC.

MpsMpoOBC.clone() yastn.tn.mps.MpsMpoOBC#

Makes a clone of MPS or MPO by cloning all yastn.Tensor’s into a new and independent yastn.tn.mps.MpsMpoOBC.

Import and export MPS/MPO from/to different formats#

MPS/MPO can be saved as Python dict or HDF5 file. The MPS/MPO previously serialized by yastn.tn.mps.MpsMpoOBC.save_to_dict() or yastn.tn.mps.MpsMpoOBC.save_to_hdf5() can be again deserialized into MPS/MPO.

Examples of exporting and loading MPS/MPO can be found in Save and load MPS/MPO.

MpsMpoOBC.save_to_dict() dict[str, dict | number]#

Serialize MPS/MPO into a dictionary.

Each element represents serialized yastn.Tensor (see, yastn.Tensor.save_to_dict()) of the MPS/MPO. Absorbs central block if it exists.

MpsMpoOBC.save_to_hdf5(file, my_address)#

Save MPS/MPO into a HDF5 file.

Parameters:
  • file (File) – A pointer to a file opened by the user

  • my_address (str) – Name of a group in the file, where the Mps will be saved, e.g., ‘state/’

mps.load_from_dict(in_dict) yastn.tn.mps.MpsMpo#

Create MPS/MPO from dictionary.

Parameters:
  • config (module | _config(NamedTuple)) – YASTN configuration

  • in_dict (dict) – dictionary containing serialized MPS/MPO, i.e., a result of yastn.tn.mps.MpsMpo.save_to_dict().

mps.load_from_hdf5(file, my_address) yastn.tn.mps.MpsMpo#

Create MPS/MPO from HDF5 file.

Parameters:
  • config (module | _config(NamedTuple)) – YASTN configuration

  • file (File) – A pointer to a file opened by the user

  • my_address (str) – Name of a group in the file, where the Mps is saved, e.g., ‘./state/’