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]))
error("In replacebond!, got ortho = $ortho, only currently supports `left` and `right`.")
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.