Is there a way to keep zero singular values during SVD? Sometimes, it is not desirable for me that the SVD can change the size of my tensors (think of single-site DMRG, for instance, but not only that). I tried cutoff = 0 and setting a minim, but it does not seem to work, and the tensors still get truncated.
Here is a working example, in the first block psi will have uniform bond dimension D=10
using ITensors, ITensorMPS
sites = siteinds("S=1/2",5);
psi = randomMPS(sites)
function pad_mp!(psi, targetD)
linds = linkinds(psi)
for i = 1:length(psi)-1
if dim(linds[i]) < targetD
paddelta = delta(Index(targetD,tags(linds[i])), linds[i])
psi[i] *= paddelta
psi[i+1] *= paddelta
end
end
end
pad_mp!(psi, 10)
psi
while in the second block the bond dimension of the first site will change:
I think the issue is not due to truncation but is related to how the SVD works in Julia. Consider psi[1] as a matrix instead of an ITensor. Taking the SVD of psi gives
a = array(psi[1])
u,s,v = svd(a)
If you look at the dimensions of these SVD factors you will see that u is a 2x2 matrix s is a length 2 vector and v is a 2x10 matrix. In some languages v is a 10x10 matrix but that is not the case in julia. Our ITensor implementation is consistent these dimensions however we represent the vector S as a diagonal (sparse) 2x2 matrix. So when you contract V with psi[2] you are effectively tracing out the order-10 bond dimension and replacing it with the exact rank of the matrix.
I see, may I suggest that a redefinition of mindim in svd() to take care of this case, doing the necessary padding, could be useful? With 1-site variational algorithms in mind, this can be confusing if you don’t expect the bond dimension to change.
I am not sure if we want to deviate from the way Julia defines SVD however there is a simple fix that you can add to your code to recover the padded bond dimension using a delta object.
Also, just wanted to add that the the SVD behavior provided by Julia is not unique to Julia, but is commonly known as the “thin SVD” and is pretty much the standard in numerical packages.
So @DanielSic Daniel, I would just say that the expectation that the bond dimension doesn’t change or vary is only really valid in the “bulk” of an MPS when doing single-site methods. My personal view is that it’s best to let MPS bond dimensions get thinner as they approach the edge of the system, otherwise certain important properties like left and right orthogonality conditions will break down or have to be generalized and it’s cleaner to just let the bond dimensions get smaller near the edges.
Are you saying that re-padding, as proposed by @kmp5, would break the orthogonality of the MPS? This is quite bad for me because right now I orthogonalize first and then pad. If I have to first pad and then orthogonalize, then this happens after the padding:
orthogonalize!(psi,1)
linkdims(psi)
4-element Vector{Int64}:
10
8
4
2
Which I think comes again from the thin SVD and is not really the bond dimension ansatz I would want to explore in a hypothetical D=10 step of a single site variational method (and it is not just an edge thing).
(On a side note, I just realized that orthogonalize!() does not accept a cutoff keyword, so I can’t use cutoff = -1 here)