# Purpose of various actions and parameters in replacebond! function?

+1 vote

I am curious about the purpose of various actions and parameters within the replacebond! function in src/mps/mps.jl. Some of these things don't have obvious use in the code, or I tried to look into the ITensors.jl code for them but didn't get much clarity. Since I am trying to make modified versions of this function for various purposes, I thought I should make sure I understand all of the parts.

(1) What is the purpose of spec, and of the Spectrum object type more generally? I see that spec comes from the factorization "L,R,spec = factorize(...)", and I see that it is returned at the end of the replacebond! function, but what is it supposed to accomplish? In particular, when the dmrg function calls replacebond!, it doesn't use spec for anything, as far as I can tell.

(2) I see that the normalize parameter is set to false by default. Under what circumstances would one likely wish to set it to true, and in such situations, what is it meant to accomplish? I see the lines of the form "normalize && (M[b] ./= norm(M[b]))" near the end of the method, but it's not clear to me when we should be using this and why by default we choose not to.

(3) What is the purpose of setleftlim! and setrightlim!, and more broadly, what is the purpose of leftlim and rightlim at all? I see lines of the form "leftlim(M) == b-1 && setleftlim!(M, leftlim(M)+1)" near the end of the method, but again, it's not clear to me why we are doing this. I notice that we increase leftlim(M) and rightlim(M) by 1 when ortho == "left" and decrease both by 1 when ortho == "right", so that part makes sense (i.e. sweeping to the left versus sweeping to the right). But what is this trying to achieve? And in general, what values are leftlim(M) and rightlim(M) supposed to be in a given situation?

1) The Spectrum object returns the eigenspectrum of the density matrix (the squared singular values). The idea is that, in the process of calculating the factors L and R, the eigenspectrum is often easily calculated as well, and it is a useful quantity for determining things like the entanglement entropy. It is returned so that you don't have to do extra work to calculate the eigenspectrum from either L or R, and users may want to print the eigenspectrum or return it from dmrg and perform calculation with it.
2) You may want to set normalize to true in cases like imaginary time evolution with TEBD, where if you don't normalize then the state's normalization will approach zero after some number of steps. replacebond! is a convenient place for that normalization to occur. By default it is chosen to be false, since it is application-dependent when someone may want that to occur, and users might want to normalize manually in case they want to save the norm (if it is physically relevant, for example).
3) The MPS/MPO types in ITensor can mostly be thought of as just vectors of ITensors that make up the MPS/MPO. However, they are a little more sophisticated than that, since they keep track of the orthogonality of the MPS/MPO. Information about the orthogonality is useful in various functions, where if you know the orthogonality than you can simplify certain expressions. So l = leftlim(M) is supposed to be set to l, such that sites 1:l are guaranteed to be left orthogonal, and r = rightlim(M) is supposed to be set to r, such that sites r:length(M) are guaranteed to be right orthogonal.
This is helpful so that certain functions can assume that an MPS has a certain orthogonality so that they don't have to do extra work to reorthogonalize. For example, the sample function, which takes random samples of an MPS, assumes a certain orthogonality of the MPS that is input. In functions that manipulate tensors of an MPS/MPO, it is therefore good practice to keep track of the orthogonality so that extra work doesn't have to be done to unnecessarily reorthogonalize the MPS (or check for the orthogonality, which would be nearly as much work). Not keeping track of the orthogonality wouldn't lead to wrong code, but in general would require extra unnecessary work to be done.