CCmatrix for different states

Hi there,

I’m wondering if I can calculate something similar to the built in CCmatrix function but with different states, that is, in my case \langle \psi_1 |c^{\dagger}_i c_j|\psi_2 \rangle .

My very naive (and presumably very inefficient) first attempt doesn’t seem to agree with the built-in function when psi1=psi2, so I must have been doing something wrong here. If you could point it out that would be very helpful. Or let me know if I should just do modify the built-in function and carry out the site-by-site calculation.

For your reference, psi are various excited states from a DMRG calculation of a 1-D fermionic chain with QN conservation.

  L = length(psi1)
  # type? fix if necessary
  corr = zeros( (L, L) )
  # get site indices

  s1 = siteinds(psi1)
  s2 = siteinds(psi2)

  for j = 1:L
    replaceind!(psi1[j], s1[j], s2[j])
  end 

  # init post-operated state array
  allleft = []
  allright = []

  operator = "C"
  for site in 1:L

    psileft = deepcopy(psi1)
    psiright = deepcopy(psi2)

    orthogonalize!(psileft,site)
    orthogonalize!(psiright, site)

    # using s2 since indices are set the same
    curleft =  op( operator, s2, site) * psileft[site]
    curright =  op( operator, s2, site) * psiright[site]
    #noprime!(curleft)
  
    psileft[site] = curleft
    psiright[site] = curright

    operator = "$operator * F"
    append!(allleft, [psileft])
    append!(allright, [psiright])
    
  end 

  
  # explicitly calculate inner product of post-operated states

  for i in 1:L
    for j in 1:L
      corr[ i, j] = inner( allleft[i]', allright[j])
    end 
  end 


  return corr

Good question – your approach here seems reasonable in terms of a method that could work, though it will be a lot slower for larger systems or bigger (larger bond dimension) states that the method we use inside the correlation_matrix function. In terms of why it’s giving different results, I would bet its something to do with the handling of the Jordan-Wigner string (F operators) here, which can be very tricky to do correctly.

Another way to go, especially if you get your code above to work but find it’s too slow, would be to take the code from inside the correlation_matrix function and generalize it so that everywhere the tensors from the state psi are conjugated to make the “bra” tensors, you instead use tensors from a different MPS psi2. But there would be one additional subtlety, which is that because they are two different MPS, you can’t take advantage of the orthogonality conditions to “cancel” any tensors so you would need to include the overlaps all the way from the left and right edges of the system at each step of the calculation.

Going back to your code, I would suggest first testing it on a case where the operators don’t carry any J-W string (so operators like \hat{n}_i and \hat{n}_j) and compare to what correlation_matrix gives just to make sure that case is working. Perhaps you already did that. Then you can be pretty sure that if the c and c^\dagger correlator isn’t working that it’s an issue with the string.

Thanks for the advice. Indeed, after benchmarking with N_iN_j the problem seems to be the Jordan Wigner String.

I then realized the string that I used was basically a product of -1s acting on one site, which was problematic, so I added this section that applies the F operator to each site individually

for prev in 1:site-1

  prevleft  = op("F", s2, prev) * psileft[prev]
  psileft[prev] = prevleft

  prevright = op("F", s2, prev) * psiright[prev]
  psiright[prev] = prevright

end 

Now the code seems to work properly. Again, this is a lot of repeated calculations, so I will look into the ccmatrix source code to see if I can get any speedups.

Yes that code looks like the right approach in terms of getting correct results. Sounds like you are on the right track.