diff --git a/docs/src/Changelog.md b/docs/src/Changelog.md index f2824dcde..6309d0c03 100644 --- a/docs/src/Changelog.md +++ b/docs/src/Changelog.md @@ -20,6 +20,18 @@ When releasing a new version, move the "Unreleased" changes to a new version sec ## [Unreleased](https://github.com/QuantumKitHub/TensorKit.jl/compare/v0.16.0...HEAD) +### Added + +- Extended support for selecting storage types in the `TensorMap` constructors ([#327](https://github.com/QuantumKitHub/TensorKit.jl/pull/327)) +- `similar_diagonal` to handle storage types when constructing diagonals ([#330](https://github.com/QuantumKitHub/TensorKit.jl/pull/330)) +- `LinearAlgebra.svd` overloads + +### Fixed + +- Issue with using relative tolerances in truncation schemes ([#314](https://github.com/QuantumKitHub/TensorKit.jl/issues/314)) +- Using `scalartype` instead of `eltype` in BLAS contraction ([#326](https://github.com/QuantumKitHub/TensorKit.jl/pull/326)) +- Divide by zero error in `show` for empty tensors ([#329](https://github.com/QuantumKitHub/TensorKit.jl/pull/329)) + ## [0.16.0](https://github.com/QuantumKitHub/TensorKit.jl/releases/tag/v0.16.0) - 2025-12-08 ### Added diff --git a/src/factorizations/factorizations.jl b/src/factorizations/factorizations.jl index 02f1712eb..6a23ef045 100644 --- a/src/factorizations/factorizations.jl +++ b/src/factorizations/factorizations.jl @@ -12,7 +12,7 @@ using ..TensorKit: AdjointTensorMap, SectorDict, SectorVector, using LinearAlgebra: LinearAlgebra, BlasFloat, Diagonal, svdvals, svdvals!, eigen, eigen!, - isposdef, isposdef!, ishermitian + isposdef, isposdef! using TensorOperations: Index2Tuple @@ -37,10 +37,10 @@ TensorKit.one!(A::AbstractMatrix) = MatrixAlgebraKit.one!(A) #------------------------------# function LinearAlgebra.eigen(t::AbstractTensorMap; kwargs...) - return ishermitian(t) ? eigh_full(t; kwargs...) : eig_full(t; kwargs...) + return LinearAlgebra.ishermitian(t) ? eigh_full(t; kwargs...) : eig_full(t; kwargs...) end function LinearAlgebra.eigen!(t::AbstractTensorMap; kwargs...) - return ishermitian(t) ? eigh_full!(t; kwargs...) : eig_full!(t; kwargs...) + return LinearAlgebra.ishermitian(t) ? eigh_full!(t; kwargs...) : eig_full!(t; kwargs...) end function LinearAlgebra.eigvals(t::AbstractTensorMap; kwargs...) @@ -49,6 +49,11 @@ function LinearAlgebra.eigvals(t::AbstractTensorMap; kwargs...) end LinearAlgebra.eigvals!(t::AbstractTensorMap; kwargs...) = eig_vals!(t) +LinearAlgebra.svd(t::AbstractTensorMap; full::Bool = false) = + full ? svd_full(t) : svd_compact(t) +LinearAlgebra.svd!(t::AbstractTensorMap; full::Bool = false) = + full ? svd_full!(t) : svd_compact!(t) + function LinearAlgebra.svdvals(t::AbstractTensorMap) tcopy = copy_oftype(t, factorisation_scalartype(svd_vals!, t)) return LinearAlgebra.svdvals!(tcopy) diff --git a/src/factorizations/truncation.jl b/src/factorizations/truncation.jl index 42d1e3248..b9d060fec 100644 --- a/src/factorizations/truncation.jl +++ b/src/factorizations/truncation.jl @@ -145,8 +145,7 @@ end # Find truncation # --------------- # auxiliary functions -rtol_to_atol(S, p, atol, rtol) = - rtol == 0 ? atol : max(atol, TensorKit._norm(S, p, norm(zero(scalartype(valtype(S))))) * rtol) +rtol_to_atol(S, p, atol, rtol) = rtol == 0 ? atol : max(atol, norm(S, p) * rtol) function _compute_truncerr(Σdata, truncdim, p = 2) I = keytype(Σdata) diff --git a/test/tensors/factorizations.jl b/test/tensors/factorizations.jl index e63312f9c..b017b746b 100644 --- a/test/tensors/factorizations.jl +++ b/test/tensors/factorizations.jl @@ -282,13 +282,14 @@ for V in spacelist @test norm(t - U3 * S3 * Vᴴ3) ≈ ϵ3 atol = eps(real(T))^(4 / 5) @test space(S3, 1) ≾ space(S2, 1) - trunc = truncerror(; atol = ϵ2) - U4, S4, Vᴴ4, ϵ4 = @constinferred svd_trunc(t; trunc) - @test t * Vᴴ4' ≈ U4 * S4 - @test isisometric(U4) - @test isisometric(Vᴴ4; side = :right) - @test norm(t - U4 * S4 * Vᴴ4) ≈ ϵ4 atol = eps(real(T))^(4 / 5) - @test ϵ4 ≤ ϵ2 + for trunc in (truncerror(; atol = ϵ2), truncerror(; rtol = ϵ2 / norm(t))) + U4, S4, Vᴴ4, ϵ4 = @constinferred svd_trunc(t; trunc) + @test t * Vᴴ4' ≈ U4 * S4 + @test isisometric(U4) + @test isisometric(Vᴴ4; side = :right) + @test norm(t - U4 * S4 * Vᴴ4) ≈ ϵ4 atol = eps(real(T))^(4 / 5) + @test ϵ4 ≤ ϵ2 + end trunc = truncrank(nvals) & trunctol(; atol = λ - 10eps(λ)) U5, S5, Vᴴ5, ϵ5 = @constinferred svd_trunc(t; trunc)