## Learn to Use ITensor

main / classes / mps_mpo_algs C++v3 | C++v2

# Algorithms for MPS and MPO (also IQMPS and IQMPO)

## Summing MPS

• sum(MPS psi1, MPS psi2, Args args = Args::global()) -> MPS
sum(IQMPS psi1, IQMPS psi2, Args args = Args::global()) -> IQMPS

Return the sum of the MPS psi1 and ps2. The returned MPS will have an orthogonality center on site 1. Before being returned, the MPS representing the sum will be compressed using truncation parameters provided in the named arguments args.

Show Example
auto psi3 = sum(psi1,psi2,{"Maxm",500,"Cutoff",1E-8});

• sum(vector<MPS> terms, Args args = Args::global()) -> MPS
sum(vector<IQMPS> terms, Args args = Args::global()) -> IQMPS

Returns the sum of all the MPS provided in the vector terms as a single MPS, using the truncation accuracy parameters (such as "Cutoff" or "Maxm") provided in the named arguments args to control the accuracy of the sum.

This function uses a hierarchical, tree-like algorithm which first sums pairs of MPS, then pairs of pairs, etc. so that the largest bond dimensions are only reached toward the end of the process for maximum efficiency. Therefore using this algorithm can be much faster than calling the above two-argument sum function to sum the terms one at a time.

Show Example
auto terms = vector<MPS>(4);
terms.at(0) = psi0;
terms.at(1) = psi1;
terms.at(2) = psi2;
terms.at(3) = psi3;

auto res = sum(terms,{"Cutoff",1E-8});


## Overlaps, Matrix Elements, and Expectation Values

• overlap(MPS psi1, MPS psi2) -> Real
overlap(IQMPS psi1, IQMPS psi2) -> Real

overlapC(MPS psi1, MPS psi2) -> Cplx
overlapC(IQMPS psi1, IQMPS psi2) -> Cplx

Compute the exact overlap $\langle \psi_1|\psi_2 \rangle$ of two MPS or IQMPS. If the overlap value is expected to be a complex number use overlapC.

The algorithm used scales as $m^3 d$ where $m$ is typical bond dimension of the MPS and $d$ is the site dimension.

(In ITensor version 1.x this function was called psiphi. This name is still supported for backwards compatibility.)

• overlap(MPS psi1, MPO W, MPS psi2) -> Real
overlap(IQMPS psi1, IQMPO W, IQMPS psi2) -> Real

overlapC(MPS psi1, MPO W, MPS psi2) -> Cplx
overlapC(IQMPS psi1, IQMPO W, IQMPS psi2) -> Cplx

Compute the exact overlap (or matrix element) $\langle \psi_1|W|\psi_2 \rangle$ of two MPS psi1 and psi2 with respect to an MPO W.

The algorithm used scales as $m^3\, k\,d + m^2\, k^2\, d^2$ where $m$ is typical bond dimension of the MPS, $k$ is the typical MPO dimension, and $d$ is the site dimension.

(In ITensor version 1.x this function was called psiHphi. This name is still supported for backwards compatibility.)

• overlap(MPS psi1, MPO W1, MPO W2, MPS psi2) -> Real
overlap(IQMPS psi1, IQMPO W1, IQMPO W2, IQMPS psi2) -> Real

overlapC(MPS psi1, MPO W1, MPO W2, MPS psi2) -> Cplx
overlapC(IQMPS psi1, IQMPO W1, IQMPO W2, IQMPS psi2) -> Cplx

Compute the exact overlap (or matrix element) $\langle \psi_1|W_1 W_2 |\psi_2 \rangle$ of two MPS psi1 and psi2 with respect to two MPOs W1 and W2.

The algorithm used scales as $m^3\, k^2\,d + m^2\, k^3\, d^2$ where $m$ is typical bond dimension of the MPS, $k$ is the typical MPO dimension, and $d$ is the site dimension.

(In ITensor version 1.x this function was called psiHKphi. This name is still supported for backwards compatibility.)

## Multiplying MPOs

• nmultMPO(MPO A, MPO B, MPO & C, Args args = Args::global())
nmultMPO(IQMPO A, IQMPO B, IQMPO & C, Args args = Args::global())

Multiply MPOs A and B. On return, the result is stored in C. MPO tensors are multiplied one at a time from left to right and the resulting tensors are compressed using the truncation parameters (such as "Cutoff" and "Maxm") provided through the named arguments args.

Show Example
MPO C;
nmultMPO(A,B,C,{"Maxm",500,"Cutoff",1E-8});


## Applying MPO to MPS

• applyMPO(MPO K, MPS psi, Args args = Args::global()) -> MPS
applyMPO(IQMPO K, IQMPS psi, Args args = Args::global()) -> IQMPS

Apply an MPO K to an MPS psi, resulting in an approximation to the MPS phi:
$|\phi\rangle = K |\psi\rangle$ .
The resulting MPS is returned. The algorithm used is chosen with the parameter "Method" in the named arguments args.

The default algorithm used is the "density matrix" algorithm, chosen by setting the parameter "Method" to "DensityMatrix". If the input MPS has a typical bond dimension of $m$ and the MPO has typical bond dimension $k$ , this algorithm scales as $m^3 k^2 + m^2 k^3$ .

No approximation is made when applying the MPO, but after applying it the resulting MPS is compressed using the truncation parameters provided in the named arguments args.

An alternative algorithm can be chosen by setting the parameter "Method" to "Fit". This is a sweeping algorithm that iteratively optimizes the resulting MPS $|\phi\rangle$ (analogous to DMRG). This algorithm has better scaling in the MPO bond dimension $k$ compared to the "DensityMatrix" method, but is not guaranteed to converge (depending on the input MPO and MPS). The number of sweeps can be chosen with the parameter "Nsweep".

It is recommended to try the default "DensityMatrix" first because it is more reliable. Then, the "Fit" method can be tried if higher performance is required.

Named arguments recognized:

• "Method" — (default: "DensityMatrix") algorithm used for applying the MPO to the MPS. Currently available options are

• "DensityMatrix"
• "Fit"
• "Cutoff" — (default: 1E-13) truncation error cutoff for compressing resulting MPS

• "Maxm" — maximum bond dimension of resulting compressed MPS

• "Verbose" — (default: false) if true, prints extra output

• "Normalize" — (default: false) choose whether or not to normalize the output wavefunction

• "Nsweep" — (default: 1) sets the number of sweeps of the "Fit" algorithm

Show Example
//Use the method "DensityMatrix"
auto phi = applyMPO(K,psi,{"Method=","DensityMatrix","Maxm=",100,"Cutoff=",1E-8});

//Use the method "Fit" with 5 sweeps
auto phi2 = applyMPO(K,psi,{"Method=","Fit","Maxm=",100,"Cutoff=",1E-8,"Nsweep=",5});

• applyMPO(MPO K, MPS psi, MPS phi, Args args = Args::global()) -> MPS
applyMPO(IQMPO K, IQMPS psi, IQMPS phi, Args args = Args::global()) -> IQMPS

Similar to applyMPO above, but accepts a guess for the output wavefunction (the guess wavefunction phi is not overwritten).

Currently, this version of applyMPO only accepts "Fit" for the parameter "Method". Choosing a good guess state phi can improve the convergence of the "Fit" method.

Show Example
//Use the method "Fit" with 5 sweeps and a guess state phi
auto Kpsi = applyMPO(K,psi,phi,{"Method=","Fit","Maxm=",100,"Cutoff=",1E-8,"Nsweep=",2});

• checkMPOProd(MPS psi2, MPO K, MPS psi1) -> Real
checkMPOProd(IQMPS psi2, IQMPO K, IQMPS psi1) -> Real

Computes, without approximation, the difference $||\, |\psi_2\rangle - K |\psi_1\rangle ||^2$ , where K is an arbitrary MPO. This is especially useful for testing methods for applying an MPO to an MPS.

Show Example
//Approximate K*psi
auto phi = applyMPO(K,psi,{"Maxm=",200,"Cutoff=",1E-12});

//Check
Print(checkMPOProd(phi,K,psi)); //should be close to zero