# Excited state orthogonality.

+1 vote

Hi,
I ran into some minor trouble trying to test-run some of the code examples from the Tensor homepage for my system.

1. I have my custom hamiltonian MPO and I wanted to compute the excited state. Actually, for this test case, there are a number of degenerate groundstates, so the code should find another one with the same energy. It does, but when I compute overlap with the first gs, it's not at all orthogonal.
Here is how I've done it:

auto psi = MPS(initState);
Real energy = dmrg(psi,H,sweeps);
auto wfs=std::vector(1);
wfs.at(0) = psi;

auto psi1 = MPS(sites);
auto energy1 = dmrg(psi1,H,wfs,sweeps,{"Weight=",1000.0})

psi.position(N/2);
psi1.position(N/2);
auto overlap1 = (dag(psi.A(N/2))*psi1.A(N/2)).toComplex();

So I get correct (small system, I checked by exact diagonalisation ) gs. energy and also the excited one being equal to gs, as it should be, but the overlaps are complex numbers of roughly this magnitude (-0.216118,-0.107735). Which does not seem very orthogonal, given that H has couplings of order 1 and the weight used to penalize overlap with the first ground state is three orders of magnitude larger.

Do you perhaps have an idea what's going on?

1. A minor question: one of the examples on the site was computing MPS overlap simply by calling "overlap(psi,psi1)"
Is this implemented? When I tried I get:

iq2chainsimple2.cc:155:18: error: use of undeclared identifier 'overlap'; did you mean 'overlaps'?
auto overlap2 = overlap(psi,psi1);
^~~~~~~
overlaps
/Users/matthew/Programming/itensor/itensor/matrix/matrixref.h:675:1: note: 'overlaps' declared here
overlaps(const VectorRef & A, const VectorRef & B)
^
iq2chainsimple2.cc:155:26: error: no viable conversion from 'itensor::MPSt' to 'const itensor::VectorRef'
auto overlap2 = overlap(psi,psi1);
^~~
/Users/matthew/Programming/itensor/itensor/matrix/matrixref.h:528:19: note: candidate constructor not viable: no known conversion from
'itensor::MPSt' to 'const itensor::VectorRef &' for 1st argument
inline VectorRef::VectorRef(const VectorRef & V)
^
/Users/matthew/Programming/itensor/itensor/matrix/matrixref.h:675:28: note: passing argument to parameter 'A' here
overlaps(const VectorRef & A, const VectorRef & B)

Hi, so it looks like you're mostly doing things correctly, but here are some comments on what to fix:

• Try some different Weight values. You may need to take the weight to be 1000, but I would start with some smaller values first to see if those work already.

• Make sure to do many more sweeps for the excited state than you would need for the ground state. For a variety of reasons, DMRG has a harder time "finding" excited states and even other ground states (e.g. excited states often have a non-uniform spatial profile for finite-size, open-boundary systems and it takes many sweeps to correctly make this profile reflection symmetric).

• As you mentioned in your separate email to me, it's not correct to just use a single tensor from psi and a single tensor from psi1 to compute the overlap. The reason is that if an MPS is "gauged" so its tensors are left- and right-orthogonal, that only means they cancel when contracted with themselves, not the tensors of a different MPS.

• The correct way to compute the overlap of two different MPS in version 1.3.x is to use the psiphi(psi1,psi2); function. In version 2.0.x I've renamed this to overlap(psi1,psi2); although the function name psiphi(...) is still allowed for backwards compatibility.

As a note, what overlap(psi1,psi2); does is to compute the full overlap diagram involving all tensors of both MPS. But this is still a pretty efficient operation, of order N*m^3 but with a small prefactor.

commented by (170 points)