Calculating excited states in infinite DMRG

+1 vote
asked Mar 11 by chengshu (450 points)

Hi Miles,

I'm trying to do excited states calculation in infinite DMRG. A naïve adaption of the sample code from http://itensor.org/docs.cgi?page=formulas/excited_dmrg does not work, which I copy below:

auto psi = MPS(state);
auto res = idmrg(psi,H,sweeps,{"OutputLevel",1});

auto wfs = std::vector<MPS>(1);
wfs.at(0) = psi;

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

What is the correct way of doing this? Thanks very much!

Best,
Chengshu

1 Answer

0 votes
answered Mar 12 by miles (11,590 points)

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

commented Mar 12 by chengshu (450 points)
Hi Miles, it seems that the code can not compile. When I try "make" I get error massage which reads

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.
commented Mar 12 by miles (11,590 points)
Oh, I didn't see that you were doing infinite DMRG. We don't offer a version of idmrg that can do excited states. I'm not sure if it's very easy to do this. The first thing that comes to mind is the work by Verstraete on "tangent space" methods to get excited states of infinite MPS. There is similar work by Garnet Chan. But these ideas would require writing a lot of custom code to implement. ITensor would be ideal for doing it but we don't have it coded up for you as a black box.
commented Mar 12 by chengshu (450 points)
Thanks for the information (both on finite and infinite DMRG). I'll begin to do some reading then.
Welcome to ITensor Support Q&A, where you can ask questions and receive answers from other members of the community.

Formatting Tips:
  • To format code, indent by four spaces
  • To format inline LaTeX, surround it by @@ on both sides
  • To format LaTeX on its own line, surround it by $$ above and below
If you cannot register due to firewall issues (e.g. you cannot see the capcha box) please email Miles Stoudenmire to ask for an account.

To report ITensor bugs, please use the issue tracker.
...