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}|\).
Parameter
self.factorallows separating the norm of the object (potentially different from \(1\)) from the canonical form of MPS or MPO tensors.
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.Mpo(N, periodic=False) MpsMpoOBC | MpoPBC[source]#
Generate empty MPO for system of N sites, fixing
nr_phys=2.A flag
periodicallows 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 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) MpsMpoOBC[source]#
Generate an MPS with bond-dimension 1 from a list of vectors that get assigned to consecutive MPS sites.
If
Nis provided, vectors are cyclicly iterated to fill inNMPS 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.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) MpsMpoOBC[source]#
Generate an MPO with bond-dimension 1 from a list of operators that get assigned to consecutive MPO sites.
If
Nis provided, operators are cyclicly iterated to fill inNMPO 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.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, distribution=(-1, 1), dtype='float64', **kwargs) MpsMpoOBC[source]#
Generate a random MPS of total charge
nand bond dimensionD_total.Local Hilbert spaces are read from ket spaces of provided MPS or MPO
I. For instance,Ican be an identity MPO. The number of sites and Tensor config is also inherited fromI.- Parameters:
I (MpsMpoOBC) – MPS or MPO that defines local Hilbert spaces.
n (int | tuple[int] | Sequence[number] | Sequence[tulpe[numbers]] | None) – Total charge of MPS, which equalls the charge on the first virtual leg of MPS. Virtual charge bond dimensions along the MPS are drawn from a normal distribution with specified mean.
ncan be a list that provides the means for all virtual legs (with zero charge on the last leg). Ifnis a single charge, the means change linearly along the chain fromnto 0. If None, which is the default, the MPS charge is set to zero.D_total (int) – Largest bond dimension. Note that due to the local (and potentially random) 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.
distribution (tuple[float, float] | str) – Passed to
yastn.rand(). Range of random numbers, or a string ‘normal’ for normal distribution. The default is (-1, 1).dtype (str) – Passed to
yastn.rand(). Number format, i.e.,'float64'or'complex128'.kwargs (dict) – Further parameters passed to
yastn.gaussian_leg().
Example
import numpy as np import yastn import yastn.tn.mps as mps ops = yastn.operators.SpinlessFermions(sym='U1') N = 13 I = mps.product_mpo(ops.I(), N=N) 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. n_profile = np.cos(np.linspace(0, np.pi / 2, N + 1)) * 7 phi = mps.random_mps(I, n=n_profile, D_total=32, sigma=2) # Here mean virtual charges along the chain are distributed according to n_profile, # sigma = 2 gives a broader spread of charges on virtual legs. # MPS encodes a state with 7 particles.
- yastn.tn.mps.random_mpo(I, D_total=8, sigma=1, distribution=(-1, 1), dtype='float64', **kwargs) 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.Ican be an MPS, in which case its ket spaces are used and conjugated for bra spaces.- Parameters:
I (MpsMpoOBC) – MPS or MPO that defines local spaces.
D_total (int) – Largest bond dimension. Note that 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.
distribution (tuple[float, float] | str) – Passed to
yastn.rand(). Range of random numbers, or a string ‘normal’ for normal distribution. The default is (-1, 1).dtype (str) – Passed to
yastn.rand(). Number format, i.e.,'float64'or'complex128'.kwargs (dict) – Further parameters passed to
yastn.gaussian_leg().
Generating MPO using Hterm#
See examples at Building 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 gatesenforces 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 havendim=2and signature matching local identity.
Create new instance of Hterm(amplitude, positions, operators)
- yastn.tn.mps.generate_mpo(I, terms=None, opts_svd=None, N=None, f_map=None) MpsMpoOBC[source]#
Generate MPO provided a list of
Hterm-s and identity operatorI.Apply
yastn.swap_gate()to introduce fermionic degrees of freedom, where the fermionic order matches the order of sites in Mps. With this respect, local operators specified in term.operators are applied starting with the last element, i.e., from right to left.The function compresses MPO using a series of SVDs. It might get expensive if the number of terms is large, e.g., for all-to-all 2-site terms and N in hundreds. If this becomes an issue, it is best to use some divide-and-conquer strategy or precompute desired MPO.
- Parameters:
I (yastn.tn.mps.MpsMpoOBC | yastn.Tensor | Sequence[yastn.Tensor]) – Identity MPO, which specifies local identity operators at each site and the number of sites. It is also possible to provide a local identity operator or list of such operators, together with
N, following the syntax ofmps.product_mpo.terms (Sequence[yastn.tn.mps.Hterm]) – Product operators making up MPO.
opts_svd (dict) – Options passed to
yastn.linalg.svd_with_truncation(). The function employs SVD while compressing the MPO bond dimensions. DefaultNonesets truncationtolclose to the numerical precision, which typically results in lossless compression.N (int) – Number of MPO sites. If identity MPO is provided, it is overridden by
I.N.f_map (Sequence[int] | None) – A map between the site index and its position in the fermionic order. The default is
None, in which case fermionic order coincides with the linear order of site indices.
Generator class for MPO/MPS (beta)#
A class supporting automatizes generation of MPOs from LaTeX-like expressions.
See examples at Generator class for MPO/MPS.
- 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, ...}. IfNone, 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. IfNone, assumes{i: 'I' for i in range(N)}, which is compatible with all predefinedoperators.parameters (dict) – Default parameters used by the interpreters
Generator.mpo()andGenerator.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.mpo_from_latex(H_str, parameters=None, opts=None) 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
cpoperator ascp_{j}(always with{}-brackets!) forcpoperator acting on sitej. The space and * are interpreted as multiplication by a number of by an operator. E.g., to multiply by a number useg * cp_j c_{j+1}whereghas to be defines inparametersor writen directly as a number, You can define automatic summation with expression\sum_{j \in A}, whereAhas to be iterable, one-dimensional object with specified values ofj.parameters (dict) – Keys for the dict define the expressions that occur in
H_str.opts (dict) – Options passed to
yastn.linalg.truncation_mask(). It includes information on how to truncate the Schmidt values.
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', **kwargs) MpsMpoOBC[source]#
Generate a random MPS of total charge
nand bond dimensionD_total.Equivalent to
mps.random_mps.
- Generator.random_mpo(D_total=8, sigma=1, dtype='float64', **kwargs) MpsMpoOBC[source]#
Generate a random MPO with bond dimension
D_total.Equivalent to
mps.random_mps.
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() _MpsMpoParent#
New instance of
yastn.tn.mps.MpsMpoOBCpointing to the same tensors as the old one.Shallow copy is usually sufficient to retain the old MPS/MPO.
- MpsMpoOBC.copy() _MpsMpoParent#
Makes a copy of MPS or MPO by
copyingallyastn.Tensor’s into a new and independentyastn.tn.mps.MpsMpoOBC.
- MpsMpoOBC.clone() _MpsMpoParent#
Makes a clone of MPS or MPO by
cloningallyastn.Tensor’s into a new and independentyastn.tn.mps.MpsMpoOBC.
Import and export MPS/MPO from/to different formats#
See examples at Save and load MPS/MPO.
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.
- 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) MpsMpoOBC#
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.MpsMpoOBC.save_to_dict().
- mps.load_from_hdf5(file, my_address) MpsMpoOBC#
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/’
Initializing MPS/MPO from tensor#
For very small systems, it is possible to turn MPS/MPO into a single tensor and generate MPS/MPO from a tensor.
- MpsMpoOBC.to_tensor() Tensor[source]#
Contract MPS/MPO to a single tensor. Should only be used for a system with a very few sites.
Tensor leg order ┌─────────── ... ──────┐ | MPS | └──┬─────┬── ... ───┬──┘ | | | 0 1 N-1 1 3 2N-1 | | | ┌──┴─────┴── ... ───┴──┐ | MPO | └──┬─────┬── ... ───┬──┘ | | | 0 2 2N-2
- yastn.tn.mps.mps_from_tensor(ten, nr_phys=1, canonize='last', opts_svd=None) MpsMpoOBC[source]#
Generate MPS from a tensor if
nr_phys=1(the default) and MPO fornr_phys=2┌─────────── ... ──────┐ | | ==> MPS of N sites └──┬─────┬── ... ───┬──┘ | | | 0 1 N-1 1 3 2N-1 | | | ┌──┴─────┴── ... ───┴──┐ | | ==> MPO of N sites └──┬─────┬── ... ───┬──┘ | | | 0 2 2N-2
- Parameters:
canonize (str) – ‘first’, ‘last’, or ‘balance’. The default is ‘first’. Canonize to ‘first’ or ‘last’ site. For ‘balance’, square roots of singular values are attached symmetrically to left and right tensors.
opts_svd (dict | None) – Truncate MPS/MPO by passing svd_opts to
yastn.linalg.truncation_mask(). The default is None, which sets truncation tolerance to 1e-14.
- yastn.tn.mps.mpo_from_tensor(ten, canonize='balance', opts_svd=None) MpsMpoOBC[source]#
Generate MPO from a tensor. Shortcut for
yastn.tn.mps.mps_from_tensor()withnr_phys=2.