# How to evaluate two-point correlator matrix element

I understand how to go about measuring a two-point correlator with respect to some eigenstate of the Hamiltonian - we simply follow the prescription outlined here . However how would we go about calculating < phi|OP1OP2|psi>, for two different eigenstates |phi> and |psi>? My attempt at the code is

auto op_i = sites.op(opi,i);
auto op_j = sites.op(opj,j);

psi1.position(i);
psi2.position(i);

auto C = psi2.A(i)*op_i*dag(prime(psi1.A(i),Site,ir));

for(int k = i+1; k < j; ++k)
{
C *= psi1.A(k);
}

C *= psi1.A(j);
C *= op_j;

C *= dag(prime(psi2.A(j),jl,Site));
complex<double> result = C.cplx();
return result;


Similarly to calculate an expectation value of one operator, we take

auto opi = sites.op(op_i,i);
psi.position(i);
complex<double> result = (dag(prime(psi.A(i),Site))*opi*psi.A(i)).cplx();
return result;


Whereas the matrix element generalization

auto opi = sites.op(op_i,i);
psi1.position(i);
psi2.position(i);
complex<double> result = (dag(prime(psi1.A(i),Site))*opi*psi2.A(i)).cplx();
return result;


does not work. In the case of a two point correlator, I'm told that I need to pass 4 indices to .cplx(), and in the case of the matrix element I'm missing two indices. What am I missing? Thanks!

+1 vote
selected by

Hi, so you are on the right track; however, because these are two different MPS, they will have in general totally different bond/virtual/link indices. So the trick used in the code formula you based your code on will not work, specifically the part where the code skips over the MPS "A" tensors to the left of site i.

Instead, you will have to contract the two MPS together without using any aspect of their respective self-orthogonality properties.

Here is link to a new code formula I just posted for doing this, in response to your question:
http://itensor.org/docs.cgi?page=formulas/two_mps

commented by (350 points)
Unbelievable! Exactly what I needed thank you Miles. So say if i is 1, then would my definition of M change to M = psi.A(1)*op_i*dag(prime(phi.A(1),"Link")); ?
commented by (70.1k points)
Almost: you'd need to remove the Link argument from the priming function. (If you don't mind me suggesting, I'd suggest that when you read and develop code like this, that you always draw the associated diagrams.) The reason to remove the Link IndexType from the arguments to prime is that you also want to prime the Site index of that tensor, so that it contracts with the primed site index of op_i.

By the way, I made a small mistake in that code formula, which I just now fixed: the Link arguments should not be strings. The reason I had made them strings is that in the upcoming new version of ITensor, we are overhauling the IndexType system and replacing it with a string-based "tags" system.
commented by (350 points)
Understood. Thank you!