Hi Chengshu,

Your code looks correct. It's just that the algorithm is not guaranteed to find the first excited state every time. The key thing you need to experiment with is the "Weight" parameter which is the penalty for psi1 and psi0 to have a non-zero overlap. I would start with a weight of 1.0 and experiment with other values if that doesn't work. Also start out on small systems where you know the answer. Finally, make sure the ground state is very well converged before trying to get the first excited state.

Even when you use this algorithm very carefully, it can sometimes miss excited states (it depends on how you initialize the MPS and how you optimize them). So you might get the ground state, first excited state, then the third excited state, and then the second excited state.

There is another approach to getting excited states with DMRG called "multiple targeting". We don't offer a black-box interface for that algorithm in ITensor right now but it would certainly be possible to implement and I think our Davidson code is set up to do it. That's something you could try to code yourself if the above method continues not to work.

Miles

idmrg3.cc: In function ‘int main(int, char**)’:

idmrg3.cc:40:72: error: no matching function for call to ‘idmrg(itensor::MPSt<itensor::ITensorT<itensor::Index> >&, itensor::MPO&, std::vector<itensor::MPSt<itensor::ITensorT<itensor::Index> > >&, itensor::Sweeps&, <brace-enclosed initializer list>)’

auto res1 = idmrg(psi1,H,wfs,sweeps,{"OutputLevel",1,"Weight",20.0});

^

In file included from /global/scratch/chengshu/itensor-Nov_23/itensor/all_mps.h:27:0,

from /global/scratch/chengshu/itensor-Nov_23/itensor/all.h:20,

from idmrg3.cc:1:

/global/scratch/chengshu/itensor-Nov_23/itensor/mps/idmrg.h:380:1: note: candidate: template<class Tensor> itensor::idmrgRVal<Tensor> itensor::idmrg(itensor::MPSt<T>&, const itensor::MPOt<Tensor>&, const itensor::Sweeps&, const itensor::Args&)

idmrg(MPSt<Tensor> & psi,

^

/global/scratch/chengshu/itensor-Nov_23/itensor/mps/idmrg.h:380:1: note: template argument deduction/substitution failed:

idmrg3.cc:40:72: note: cannot convert ‘wfs’ (type ‘std::vector<itensor::MPSt<itensor::ITensorT<itensor::Index> > >’) to type ‘const itensor::Sweeps&’

auto res1 = idmrg(psi1,H,wfs,sweeps,{"OutputLevel",1,"Weight",20.0});

^

In file included from /global/scratch/chengshu/itensor-Nov_23/itensor/all_mps.h:27:0,

from /global/scratch/chengshu/itensor-Nov_23/itensor/all.h:20,

from idmrg3.cc:1:

/global/scratch/chengshu/itensor-Nov_23/itensor/mps/idmrg.h:364:1: note: candidate: template<class Tensor> itensor::idmrgRVal<Tensor> itensor::idmrg(itensor::MPSt<T>&, const itensor::MPOt<Tensor>&, const itensor::Sweeps&, itensor::DMRGObserver<Tensor>&, const itensor::Args&)

idmrg(MPSt<Tensor> & psi,

^

/global/scratch/chengshu/itensor-Nov_23/itensor/mps/idmrg.h:364:1: note: template argument deduction/substitution failed:

idmrg3.cc:40:72: note: cannot convert ‘wfs’ (type ‘std::vector<itensor::MPSt<itensor::ITensorT<itensor::Index> > >’) to type ‘const itensor::Sweeps&’

auto res1 = idmrg(psi1,H,wfs,sweeps,{"OutputLevel",1,"Weight",20.0});

^

In file included from /global/scratch/chengshu/itensor-Nov_23/itensor/all_mps.h:27:0,

from /global/scratch/chengshu/itensor-Nov_23/itensor/all.h:20,

from idmrg3.cc:1:

/global/scratch/chengshu/itensor-Nov_23/itensor/mps/idmrg.h:391:1: note: candidate: template<class Tensor> itensor::idmrgRVal<Tensor> itensor::idmrg(itensor::MPSt<T>&, const itensor::MPOt<Tensor>&, const itensor::idmrgRVal<Tensor>&, const itensor::Sweeps&, const itensor::Args&)

idmrg(MPSt<Tensor> & psi,

^

/global/scratch/chengshu/itensor-Nov_23/itensor/mps/idmrg.h:391:1: note: template argument deduction/substitution failed:

idmrg3.cc:40:72: note: ‘std::vector<itensor::MPSt<itensor::ITensorT<itensor::Index> > >’ is not derived from ‘const itensor::idmrgRVal<Tensor>’

auto res1 = idmrg(psi1,H,wfs,sweeps,{"OutputLevel",1,"Weight",20.0});

^

In file included from /global/scratch/chengshu/itensor-Nov_23/itensor/all_mps.h:27:0,

from /global/scratch/chengshu/itensor-Nov_23/itensor/all.h:20,

from idmrg3.cc:1:

/global/scratch/chengshu/itensor-Nov_23/itensor/mps/idmrg.h:105:1: note: candidate: template<class Tensor> itensor::idmrgRVal<Tensor> itensor::idmrg(itensor::MPSt<T>&, itensor::MPOt<Tensor>, itensor::idmrgRVal<Tensor>, const itensor::Sweeps&, itensor::DMRGObserver<Tensor>&, itensor::Args)

idmrg(MPSt<Tensor> & psi,

^

/global/scratch/chengshu/itensor-Nov_23/itensor/mps/idmrg.h:105:1: note: template argument deduction/substitution failed:

idmrg3.cc:40:72: note: ‘std::vector<itensor::MPSt<itensor::ITensorT<itensor::Index> > >’ is not derived from ‘itensor::idmrgRVal<Tensor>’

auto res1 = idmrg(psi1,H,wfs,sweeps,{"OutputLevel",1,"Weight",20.0});

So I guess there is something wrong in the code.