# leftlim and rightlim initialization present in randomizeMPS! but not productMPS

+1 vote

I happened to notice that, in ITensors.jl/mps.jl, the randomizeMPS! function has lines of code that initialize leftlim and rightlim to 0 and 2, respectively, while the productMPS function does not.

Tto the best of my understanding, leftlim and rightlim are supposed to represent the boundaries of the region currently being optimized. So for 2-site DMRG, for example, leftlim and rightlim start out as 0 and 2 at the beginning of a sweep, and in the forward sweep change to 1 and 3, then 2 and 4, and so on, until N-1 and N+1 (where N is the length of the MPS), and then they shift back during the backward sweep. (Please correct me if I am wrong about this claimed purpose of leftlim and right lim.)

However, based on the existing code in the replacebond! function in mps.jl, this shifting only happens if the initialization is done properly, since leftlim and rightlim will only shift at all if they are in the positions they are supposed to be in earlier. For reference, I have included the code below that specifies this:

if ortho == "left"
leftlim(M) == b-1 && setleftlim!(M, leftlim(M)+1)
rightlim(M) == b+1 && setrightlim!(M, rightlim(M)+1)
normalize && (M[b+1] ./= norm(M[b+1]))
elseif ortho == "right"
leftlim(M) == b && setleftlim!(M, leftlim(M)-1)
rightlim(M) == b+2 && setrightlim!(M, rightlim(M)-1)
normalize && (M[b] ./= norm(M[b]))
else
error("In replacebond!, got ortho = \$ortho, only currently supports left and right.")
end


Because of all of this, it seems that leftlim and rightlim only shift in the way I think they are supposed to if you construct your initial state using randomMPS, not if you use productMPS. Is there a reason for this? This seems to be a mistake to me, but I can't be totally sure.

Hi Sujay,
Happy to discuss more, but most of your question can probably be answered by addressing the true purpose of leftlim and rightlim. They do not represent the boundaries of the region currently optimized (though in an optimization context they might correspond to these regions). What they actually represent are the orthogonality properties of the MPS, or at least as much that we can guarantee in the code in an automated way. (What I mean by that last part is that the MPS might be orthogonal over an even larger region than indicated by leftlim and rightlim but at a minimum it is guaranteed to be orthogonal up to leftlim and rightlim.)

You probably already know what I mean by parts of the MPS being orthogonal, but to be clear the meaning of leftlim is that the MPS tensors 1:leftlim are all left-orthogonal (square to an identity when contracted over both their left index and site index) and the MPS tensors rightlim:N are all right-orthogonal. Again other MPS tensors might be right or left orthogonal besides the ones in (1:leftlim) and (rightlim:N) but we only guarantee the ones in those ranges in terms of our algorithms.

The specific case of the productMPS function is one where we could, and probably should, strengthen this guarantee. I gather that right now leftlim and rightlim just remain at their most conservative settings of leftlim=0 and rightlim=N+1 i.e. not guaranteeing any orthogonality. Whereas productMPS is a special case where all of the MPS tensors are simulaneously both left and right orthogonal. So we could instead say set leftlim=0 and rightlim=2 for productMPS or some other setting.

The randomMPS function doesn't specifically "shift" leftlim and rightlim: rather it sets them because it constructs the MPS out of a quantum circuit that ensures the property that all MPS tensors from 2:N are right-orthogonal. The MPS tensor at site 1 is the "orthogonality center" of this MPS gauge (so called right-orthogonal gauge).

What does shift the leftlim and rightlim values are functions like replacebond! as you mention, which is used internally by DMRG and other algorithms (or you can use it directly). In a sense, this is its main purpose i.e. to update an MPS locally while correctly shifting leftlim and rightlim, as well as selecting among various algorithms for you based on truncation and accuracy settings. Doing this correctly "by hand" could be error prone so we introduced this function to help.

Finally, what is the real purpose of even having leftlim and rightlim? It is for two reasons: correctness and efficiency. There is a correctness aspect where truncating an MPS locally without including the orthogonality center can lead to an uncontrolled / unknown error. Another reason is efficiency: having a known leftlim and rightlim means that for many purposes the left- and right-orthogonal tensors can be omitted from certain algorithmic steps which cuts down on computation by quite a lot without sacrificing correctness or accuracy.

Hope that helps - this is giving me some ideas of things we should put into the docs -

Miles

commented by (1.1k points)
Sorry for the late reply; thank you! This really clears it up for me.
commented by (70.1k points)