Transforming a Set of Gates into an MPO

Here we describe how to transform a set of gates into an MPO.

Imagine we have a Hamiltonian that is a sum of local terms

$$ H = \sum_j h_{j,j+1} $$

where @@h_{j,j+1}@@ only acts non-trivially on sites j and (j+1).

Part of a Trotter decomposition may look like:

$$ e^{-\tau H} \approx e^{-\tau h_{1,2}} e^{-\tau h_{2,3}} \cdots e^{-\tau h_{N-1,N}} $$

We can turn this into an MPO with the following code:

#include "itensor/all.h"

using namespace itensor;
using std::vector;

int 
main()
  {
  // Create the sites
  auto N = 20;
  auto s = SpinHalf(N,{"ConserveQNs=",false});

  // Create the gates
  auto tau = 0.1; // Time step
  auto G = vector<ITensor>(N);
  for(auto j : range1(N-1))
    {
    G[j] = expHermitian(op(s,"Sx",j)*op(s,"Sx",j+1),-tau);
    }

  // Split up the gates
  auto A = vector<ITensor>(N);
  auto B = vector<ITensor>(N);
  for(auto j : range1(N-1))
    {
    auto [Aj,Bj] = factor(G[j],{s(j),prime(s(j))});
    A[j] = Aj;
    B[j] = Bj;
    }

  // Some temporary internal indices
  auto t = vector<Index>(N+1);
  for(auto j : range1(N))
    {
    t[j] = sim(s(j));
    }

  // Replace internal indices
  // so that the correct indices contract
  for(auto j : range1(2,N-1))
    {
    B[j-1] *= delta(prime(s(j)),t[j]);
    A[j] *= delta(s(j),t[j]);
    }

  // Create and store the MPO tensors
  auto M = MPO(N);
  M.set(1,A[1]);
  for(auto j : range1(2,N-1))
    {
    M.set(j,B[j-1]*A[j]);
    }
  M.set(N,B[N-1]);

  ///////////////////////////////////////////////
  //
  // As a test, apply this MPO to a state
  // and compare to applying the gates
  //

  // Create a starting state
  auto init = InitState(s);
  for(auto j : range1(N))
    {
    init.set(j, "Up"); 
    }
  auto psi = MPS(init);

  // Apply our MPO to the starting state
  auto Mpsi = applyMPO(M,psi);

  // Now compare to applying the gates
  auto Gpsi = psi;

  // Put the orthogonality center at position 1
  Gpsi.position(1);
  for(auto j : range1(1,N-1))
    {
    auto phi = Gpsi(j)*Gpsi(j+1)*G[j];
    phi.noPrime();
    auto [U,S,V] = svd(phi,inds(Gpsi(j)));
    Gpsi.set(j,U);
    Gpsi.set(j+1,S*V);
    }

  PrintData(inner(Mpsi,Mpsi));
  PrintData(inner(Gpsi,Gpsi));
  PrintData(inner(Gpsi,Mpsi));

  return 0;
  }

 Download the full example code


Back to Formulas
Back to Main