Hi!
I am sorry if this is a duplicate, as I would expect it to be answered somewhere but I could genuinely not find the answer. Shortly stated: I want to retrieve the sum of discarded squared singular values when using the svd on a MPS with the maxdim argument. Is there a way of doing so?
I can compute the svd without truncation, retrieve the singular values from S and then perform some truncation, but that is probably far from efficient. Digging in the source code I have also figured out that the svd function returns more than just U, S and V, and one can obtain a Spectrum object, which contains the (conserved) singular values and some error term: what is the latter? I could not relate it to the discarded singular values and could not find any documentation on that.
Here an example: I start from some MPS, and apply a unitary to two neighbouring sites
inds_sites = siteinds("Qubit", 8)
psi = randomMPS(inds_sites, linkdims=8)
q=4
new_T = psi[q] * psi[q+1] * op("RandomUnitary", [inds_sites[q], inds_sites[q+1]])
noprime!(new_T)
Then I want to perform a svd with maximum bond dimension. For reference, if I give no truncation indications I get
U, S, V, spec = svd(new_T, uniqueinds(psi[q], psi[q+1])); spec
>>> Spectrum{Vector{Float64}, Float64}([1.3888894384006771, 1.16280226828166, 1.0076611812149532, 0.9505778312199186, 0.7606731410439445, 0.6710854849239525, 0.595632286840479, 0.46336037208905767, 0.32191293790266035, 0.20206667411714405, 0.1809923124921696, 0.1336780702863157, 0.08791572340819503, 0.055008793515782126, 0.01707487116659689, 0.0006686130965095594], 0.0)
I know that the first element of spec is the list of the singular values (which are also on the diagonal of S) squared, so spec.eigs == diag(S).^2
. Now when imposing a truncation I get
U, S, V, spec = svd(new_T, uniqueinds(psi[q], psi[q+1]), maxdim=8); spec
Spectrum{Vector{Float64}, Float64}([1.3888894384006771, 1.16280226828166, 1.0076611812149532, 0.9505778312199186, 0.7606731410439445, 0.6710854849239525, 0.595632286840479, 0.46336037208905767], 0.12491474949817141)
Now, is there a way to retrieve the same U, S and V, and also to get the sum of discarded singular values squared? In an attempt, I tried to figure out what this spec.truncerr = 0.12491474949817141
is. I thought it would be truncerr = \sum_{i=9}^{16} s_i^2 or truncerr = \sqrt{ 2 \sum_{i=9}^{16} s_i^2 } but it seems not to be the case
discarded_singvals = [0.32191293790266035, 0.20206667411714405, 0.1809923124921696, 0.1336780702863157, 0.08791572340819503, 0.055008793515782126, 0.01707487116659689, 0.0006686130965095594]
sum(discarded_singvals) = 0.9993179959853734
sqrt(2*sum(discarded_singvals)) = 1.4137312304574539
Sorry for the long post, I tried to make my doubt as clear as possible.
Some details about my settings:
- Julia Version 1.8.5
- ITensors v0.3.30
Thanks a lot for any help!