Algebra#
Multiplication by a scalar#
MPS/MPO can be multiplied by a scalar using regular *
and /
operators,
i.e., B = a * A
, B = A * a
or B = A / a
.
Conjugation and transpose#
- MpsMpoOBC.conj() yastn.tn.mps.MpsMpoOBC #
Makes a conjugation of the object.
- MpsMpoOBC.transpose() yastn.tn.mps.MpsMpoOBC #
Transpose of MPO. For MPS, return self.
- property MpsMpoOBC.T: yastn.tn.mps.MpsMpo#
Transpose of MPO. For MPS, return self.
Same as
self.transpose()
- MpsMpoOBC.conjugate_transpose() yastn.tn.mps.MpsMpo #
Transpose and conjugate MPO. For MPS, return self.conj().
- property MpsMpoOBC.H: yastn.tn.mps.MpsMpo#
Transpose and conjugate of MPO. For MPS, return self.conj().
Same as
self.transpose()
- MpsMpoOBC.reverse_sites() yastn.tn.mps.MpsMpo #
New MPS/MPO with reversed order of sites and respectively transposed virtual tensor legs.
Addition of MPS/MPO#
Two MPS’s or two MPO’s can be added up, provided that their length, physical dimensions, and symmetry agree.
The sum of two such objects A
and B
results in new MPS/MPO C = A + B
, with tensor of C
given by the direct sum of A
’s
and B
’s tensors along virtual dimension.
# a product of two MPS's
___ ___ ___ ___ ___ ___ ___ ___
A |___|-D-|___|--|___|--|___| | | | | | | | |
C = + = __ d| ___ | ___ | ___ | = | |-2D-| |--| |--| |
B |___|:D-|___|:-|___|:-|___|: |___| |___| |___| |___|
d| | | | | | | | d| | | |
\/ \/ \/ \/
To add many MPS/MPOs \(A_0, A_1,\dots\) at once, use yastn.tn.mps.add(A_0, A_1,...)
.
- yastn.tn.mps.add(*states, amplitudes=None) yastn.tn.mps.MpsMpoOBC [source]#
Linear superposition of several MPS/MPOs with specific amplitudes, i.e., \(\sum_j \textrm{amplitudes[j]}{\times}\textrm{states[j]}\).
Compression (truncation of bond dimensions) is not performed.
- Parameters:
states (Sequence[yastn.tn.mps.MpsMpoOBC])
amplitudes (Sequence[scalar]) – If
None
, all amplitudes are assumed to be 1.
Following example show an addition of two MPSs:
import yastn
import yastn.tn.mps as mps
def addition_example(tol=1e-12, config=None):
# Define random MPS's without any symmetry
#
opts_config = {} if config is None else \
{'backend': config.backend,
'default_device': config.default_device}
# pytest uses config to inject various backends and devices for testing
ops = yastn.operators.Qdit(d=2, **opts_config)
I = mps.product_mpo(ops.I(), N=8)
psi0 = mps.random_mps(I, D_total=5)
psi1 = mps.random_mps(I, D_total=3, dtype='complex128')
# We want to calculate: res = psi0 + 2 * psi1. There is a couple of ways:
# A/
resA = mps.add(psi0, 2.0 * psi1)
# B/
resB = mps.add(psi0, psi1, amplitudes=[1.0, 2.0])
# C/
resC = psi0 + 2.0 * psi1
nresA, nresB, nresC = resA.norm(), resB.norm(), resC.norm()
assert abs(mps.vdot(resA, resB) / (nresA * nresB) - 1) < tol
assert abs(mps.vdot(resA, resC) / (nresA * nresC) - 1) < tol
assert (x.get_bond_dimensions() == (1, 8, 8, 8, 8, 8, 8, 8, 1)
for x in (resA, resB, resC))
Products of MPO and MPS#
API supports product @
of
i) MPO with MPS resulting in a new MPS in analogy with \(\hat{O}|\psi\rangle = |\phi\rangle\) (i.e. matrix-vector multiplication).
# a product of MPO O and MPS A
___ ___ ___
|___|--D'--|___|--...--|___| ___ ___ ___
C = O @ A = _|_ _|_ _|_ = |___|-DxD'-|___|--...--|___|
|___|--D --|___|--...--|___| | | |
| | |
ii) two MPOs resulting in a new MPO corresponding to usual operator product \(\hat{O}\hat{P} = \hat{C}\) (matrix-matrix multiplication).
# a product of two MPO's O and P
_|d_ _|_ _|_
|___|--D---|___|--...--|___| _|d _|_ _|_
C = O @ P = _|_ _|_ _|_ = |___|--DxD'--|___|--...--|___|
|___|--D'--|___|--...--|___| |d | |
|d | |
One can either use call C = A @ B
or in a more verbose form
C = mps.multiply(A, B)
. See examples here: Multiplication.
- yastn.tn.mps.multiply(a, b, mode=None) yastn.tn.mps.MpsMpoOBC [source]#
Performs MPO-MPS product resulting in a new MPS, or MPO-MPO product resulting in a new MPO.
For MPS/MPO with no symmetry, the bond dimensions of the result are given by the product of the bond dimensions of the inputs. For symmetric MPS/MPO the virtual spaces of the result are given by fusion (i.e. resolving tensor product into direct sum) of the virtual spaces of the inputs.
\[V^{\textrm{result}}_{j,j+1} = V^{a}_{j,j+1} \otimes V^{b}_{j,j+1} = \sum_{c} V^{\textrm{result},c}_{j,j+1},\]where the charge sectors \(V^{\textrm{result},c}\) are computed during fusion.
Note
One can equivalently call
a @ b
.- Parameters:
a, b (yastn.tn.mps.MpsMpoOBC, yastn.tn.mps.MpsMpoOBC) – a pair of MPO and MPS or two MPO’s to be multiplied
mode (str) – mode for
Tensor.fuse_legs()
; IfNone
(default) use default setting from YASTN tensor’s configuration.
Multiplication with truncation#
A fast procedure to multiply MPO by MPO/MPS while performing truncation is a zipper. The result can be subsequently fine-tuned using variational optimization.
- yastn.tn.mps.zipper(a, b, opts_svd=None, normalize=True, return_discarded=False) yastn.tn.mps.MpsMpoOBC [source]#
Apply MPO a on MPS/MPS b, performing svd compression during the sweep.
Perform canonization of
b
to the last site. Next, sweep back attaching elements ofa
one at a time and truncating the resulting bond dimensions along the way. The resulting state is canonized to the first site and normalized to unity.- Parameters:
a, b (yastn.tn.mps.MpsMpoOBC)
opts_svd (dict) – truncation parameters for
yastn.linalg.truncation_mask()
.normalize (bool) – Whether to keep track of the norm of the initial state projected on the direction of the truncated state; default is True, i.e., sets the norm to unity. The individual tensors at the end of the procedure are in a proper canonical form.
return_discarded (bool) – Whether to return the approximation discarded weights together with the resulting MPS/MPO. Default is False, i.e., returns only MPS/MPO. Discarded weight approximates norm of truncated elements normalized by the norm of the untruncated state.