+1 vote
asked by (1.1k points)
edited by

I am working on generalizing DMRG, for which only the 2-site version is currently supported, to a generalized n-site DMRG. I opened a pull request for it here (https://github.com/ITensor/ITensors.jl/pull/434), and it passes all of the provided tests. But I later realized that it still throws an error if one tries to call DMRG with an MPS vector as an input (i.e. if one is trying to compute excited states, as opposed to just the ground state). After examining the error messages and scouring the repository for a while, I am now fairly certain that the issue is that I have yet to adapt the following function, which appears in ITensors.jl/src/mps/projmps.jl:

function product(P::ProjMPS,
  if nsite(P) != 2
    error("Only two-site ProjMPS currently supported")

  Lpm = dag(prime(P.M[P.lpos+1],"Link"))
  !isnothing(lproj(P)) && (Lpm *= lproj(P))

  Rpm = dag(prime(P.M[P.rpos-1],"Link"))
  !isnothing(rproj(P)) && (Rpm *= rproj(P))

  pm = Lpm*Rpm

  pv = scalar(pm*v)

  Mv = pv*dag(pm)

  return noprime(Mv)

I understand that this function multiplies a ProjMPS object and an ITensor object, and that there is a similar function "product(P::ProjMPS, v::ITensor)::ITensor" in ITensors.jl/src/mps/projmpo_mps.jl that calls this first one repeatedly. I also understand that this ultimately works in service of adding a penalizing term w|psi><psi| to the Hamiltonian for some weight w and MPS |psi>. However, I am generally finding this method itself very hard to parse. Would it be possible to get a simple explanation of what this method is really doing, as well as an explanation of what would need to be changed to adapt this to n-site DMRG (and how hard you expect this to be)?

1 Answer

+1 vote
answered by (70.1k points)

Hi Sujay,
To answer your question I thought it would be easier to show you some diagrams, which I uploaded to this link:


Can you please let me know if those notes answer your question and give a clear enough idea of what the code there is doing?

The purpose of this ProjMPS overall is to make a Hamiltonian term that is equal to |M><M| for some state M (represented as an MPS) then include this Hamiltonian term in an efficient way within a DMRG calculation that's optimizing an MPS psi.

I think the code there already partially works for n-site DMRG, because you can see that makeL! and makeR! (which are called by position!) query a parameter P.nsite which right now is always set to 2 but could be adjusted. Then the code in product would need to be extended to multiply on the center "n" tensors of M in the lower part of the diagram in the notes, rather than just the two center tensors right now. These two tensors right now are getting included by the lines:

Lpm = dag(prime(P.M[P.lpos+1],"Link"))


Rpm = dag(prime(P.M[P.rpos-1],"Link"))


commented by (1.1k points)
Hi Miles, thank you so much! I was ultimately able to figure out how to adapt this function to n-site DMRG some time last week, but I forgot to update this question with that information. But your answer was still very helpful. By the way, since this lets us handle excited states now, I updated the n-site DMRG code for ITensors.jl in this pull request (https://github.com/ITensor/ITensors.jl/pull/434).
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
  • For LaTeX, it may be necessary to backslash-escape underscore characters to obtain proper formatting. So for example writing \sum\_i to represent a sum over i.
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.