From fad8eb07d9cb8783dcd8e08dc39d2811c88bbf85 Mon Sep 17 00:00:00 2001 From: Bobby Date: Mon, 8 Jul 2024 23:40:39 -0400 Subject: [PATCH] [ITensors] add kwarg to truncate! to return RankFactorization.Spectrum (#1516) The purpose of this commit is to allow the truncation error from an operation to be returned. This is the first step envisioned for that functionality. The spectrum and truncation error from calling svd() on ITensors is not accessible from calls to truncate! and truncate. This allows the Spectrum type (which contains the spectrum and the error) to be optionally returned. This required importing RankFactorization.Spectrum in ITensors (so an added import in imports.jl) and then slightly refactoring the definition of truncate! and truncate. This commit makes a named tuple with each element being "bond_n" where n is `1` to `N-1` bonds and each element of the named tuple corresponds to the Spectrum returned from the call to svd as the bonds are swept over during the call to truncate. All tests were run with 92979 passing and 73 broken. Total tests were 93052. --- src/imports.jl | 1 + src/lib/ITensorMPS/src/abstractmps.jl | 24 ++++++++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/imports.jl b/src/imports.jl index 727ab54f83..b41e28202f 100644 --- a/src/imports.jl +++ b/src/imports.jl @@ -182,6 +182,7 @@ import ITensors.NDTensors: truncate!, using_tblis, vector, + RankFactorization.Spectrum, # Deprecated addblock!, store diff --git a/src/lib/ITensorMPS/src/abstractmps.jl b/src/lib/ITensorMPS/src/abstractmps.jl index 629075f183..b5e20b50c4 100644 --- a/src/lib/ITensorMPS/src/abstractmps.jl +++ b/src/lib/ITensorMPS/src/abstractmps.jl @@ -1671,36 +1671,48 @@ provided as keyword arguments. Keyword arguments: * `site_range`=1:N - only truncate the MPS bonds between these sites +* `return_spectrum=false` - in addition to returning the MPS, also return a named tuple containing the of type `Spectrum` for each bond in the MPS. `Spectrum` contains a Vector of `Float64` called `eigs` that contains the singular values at each bond and the truncation error performed at that bond. For example, `_, spec = truncate!(m, maxdim=5)` and then inspect the singular values and truncation error at bond 3 by doing `spec.bond_3.eigs` or `spec.bond_3.truncerr`, respectively. """ function truncate!(M::AbstractMPS; alg="frobenius", kwargs...) return truncate!(Algorithm(alg), M; kwargs...) end function truncate!( - ::Algorithm"frobenius", M::AbstractMPS; site_range=1:length(M), kwargs... + ::Algorithm"frobenius", + M::AbstractMPS; + site_range=1:length(M), + return_spectrum=false, + kwargs..., ) N = length(M) + Nbonds = N - 1 + bond_names = Tuple([Symbol("bond_$(α)") for α in 1:Nbonds]) + spectrums = Vector{Spectrum}(undef, Nbonds) # Left-orthogonalize all tensors to make # truncations controlled orthogonalize!(M, last(site_range)) # Perform truncations in a right-to-left sweep - for j in reverse((first(site_range) + 1):last(site_range)) + for (idx, j) in enumerate(reverse((first(site_range) + 1):last(site_range))) rinds = uniqueinds(M[j], M[j - 1]) ltags = tags(commonind(M[j], M[j - 1])) - U, S, V = svd(M[j], rinds; lefttags=ltags, kwargs...) + U, S, V, spec = svd(M[j], rinds; lefttags=ltags, kwargs...) + spectrums[idx] = spec M[j] = U M[j - 1] *= (S * V) setrightlim!(M, j) end - return M + if return_spectrum + return M, NamedTuple{bond_names}(spectrums) + else + return M + end end function truncate(ψ0::AbstractMPS; kwargs...) ψ = copy(ψ0) - truncate!(ψ; kwargs...) - return ψ + return truncate!(ψ; kwargs...) end # Make `*` an alias for `contract` of two `AbstractMPS`