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..2c1f9f3265 100644 --- a/src/lib/ITensorMPS/src/abstractmps.jl +++ b/src/lib/ITensorMPS/src/abstractmps.jl @@ -1677,30 +1677,42 @@ function truncate!(M::AbstractMPS; alg="frobenius", 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]) + # TODO: Not sure how ths will work. Its a local module or "lib" as NDTensors calls it. Need to investigate this more to see how getting it here would work. Or just make it type Any? + 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`