From 81a2b571e6d481efb79c05b18e99760bfc1749e7 Mon Sep 17 00:00:00 2001 From: Jutho Haegeman Date: Thu, 21 Sep 2023 17:04:20 +0200 Subject: [PATCH] change factorization calling syntax; bump patch --- Project.toml | 2 +- src/auxiliary/deprecate.jl | 24 ++++++++++++ src/tensors/factorizations.jl | 69 ++++++++++++++--------------------- test/tensors.jl | 14 +++---- 4 files changed, 60 insertions(+), 49 deletions(-) diff --git a/Project.toml b/Project.toml index d0736c2c..1850e74c 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "TensorKit" uuid = "07d1fe3e-3e46-537d-9eac-e9e13d0d4cec" authors = ["Jutho Haegeman"] -version = "0.11.1" +version = "0.11.2" [deps] HalfIntegers = "f0d1745a-41c9-11e9-1dd9-e5d34d218721" diff --git a/src/auxiliary/deprecate.jl b/src/auxiliary/deprecate.jl index b9c5246d..7e282c64 100644 --- a/src/auxiliary/deprecate.jl +++ b/src/auxiliary/deprecate.jl @@ -6,4 +6,28 @@ import Base: eltype, transpose @deprecate permute(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple; copy::Bool=false) permute(t, (p1, p2); copy=copy) @deprecate transpose(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple; copy::Bool=false) transpose(t, (p1, p2); copy=copy) @deprecate braid(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple, levels; copy::Bool=false) braid(t, (p1, p2), levels; copy=copy) + + +Base.@deprecate(svd(t::AbstractTensorMap, leftind::IndexTuple, rightind::IndexTuple; + trunc::TruncationScheme=notrunc(), p::Real=2, alg::SVDAlg=SDD()), + tsvd(t, (leftind, rightind); trunc=trunc, p=p, alg=alg)) +Base.@deprecate(svd(t::AbstractTensorMap; + trunc::TruncationScheme=notrunc(), p::Real=2, alg::SVDAlg=SDD()), + tsvd(t; trunc=trunc, p=p, alg=alg)) +Base.@deprecate(svd!(t::AbstractTensorMap; + trunc::TruncationScheme=notrunc(), p::Real=2, alg::SVDAlg=SDD()), + tsvd(t; trunc=trunc, p=p, alg=alg)) + + +# TODO: deprecate + +tsvd(t::AbstractTensorMap, p₁::IndexTuple, p₂::IndexTuple; kwargs...) = tsvd(t, (p₁, p₂); kwargs...) +leftorth(t::AbstractTensorMap, p₁::IndexTuple, p₂::IndexTuple; kwargs...) = leftorth(t, (p₁, p₂); kwargs...) +rightorth(t::AbstractTensorMap, p₁::IndexTuple, p₂::IndexTuple; kwargs...) = rightorth(t, (p₁, p₂); kwargs...) +leftnull(t::AbstractTensorMap, p₁::IndexTuple, p₂::IndexTuple; kwargs...) = leftnull(t, (p₁, p₂); kwargs...) +rightnull(t::AbstractTensorMap, p₁::IndexTuple, p₂::IndexTuple; kwargs...) = rightnull(t, (p₁, p₂); kwargs...) +LinearAlgebra.eigen(t::AbstractTensorMap, p₁::IndexTuple, p₂::IndexTuple; kwargs...) = LinearAlgebra.eigen(t, (p₁, p₂); kwargs...) +eig(t::AbstractTensorMap, p₁::IndexTuple, p₂::IndexTuple; kwargs...) = eig(t, (p₁, p₂); kwargs...) +eigh(t::AbstractTensorMap, p₁::IndexTuple, p₂::IndexTuple; kwargs...) = eigh(t, (p₁, p₂); kwargs...) + #! format: on diff --git a/src/tensors/factorizations.jl b/src/tensors/factorizations.jl index 0c7a9009..15084cab 100644 --- a/src/tensors/factorizations.jl +++ b/src/tensors/factorizations.jl @@ -5,18 +5,8 @@ const OFA = OrthogonalFactorizationAlgorithm import LinearAlgebra: svd!, svd const SVDAlg = Union{SVD,SDD} -Base.@deprecate(svd(t::AbstractTensorMap, leftind::IndexTuple, rightind::IndexTuple; - trunc::TruncationScheme=notrunc(), p::Real=2, alg::SVDAlg=SDD()), - tsvd(t, leftind, rightind; trunc=trunc, p=p, alg=alg)) -Base.@deprecate(svd(t::AbstractTensorMap; - trunc::TruncationScheme=notrunc(), p::Real=2, alg::SVDAlg=SDD()), - tsvd(t; trunc=trunc, p=p, alg=alg)) -Base.@deprecate(svd!(t::AbstractTensorMap; - trunc::TruncationScheme=notrunc(), p::Real=2, alg::SVDAlg=SDD()), - tsvd(t; trunc=trunc, p=p, alg=alg)) - """ - tsvd(t::AbstractTensorMap, leftind::Tuple, rightind::Tuple; + tsvd(t::AbstractTensorMap, (leftind, rightind)::Index2Tuple; trunc::TruncationScheme = notrunc(), p::Real = 2, alg::Union{SVD, SDD} = SDD()) -> U, S, V, ϵ @@ -47,12 +37,12 @@ algorithm that computes the decomposition (`_gesvd` or `_gesdd`). Orthogonality requires `InnerProductStyle(t) <: HasInnerProduct`, and `tsvd(!)` is currently only implemented for `InnerProductStyle(t) === EuclideanProduct()`. """ -function tsvd(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple; kwargs...) - return tsvd!(permute(t, (p1, p2); copy=true); kwargs...) +function tsvd(t::AbstractTensorMap, (p₁, p₂)::Index2Tuple; kwargs...) + return tsvd!(permute(t, (p₁, p₂); copy=true); kwargs...) end """ - leftorth(t::AbstractTensorMap, leftind::Tuple, rightind::Tuple; + leftorth(t::AbstractTensorMap, (leftind, rightind)::Index2Tuple; alg::OrthogonalFactorizationAlgorithm = QRpos()) -> Q, R Create orthonormal basis `Q` for indices in `leftind`, and remainder `R` such that @@ -73,12 +63,12 @@ Orthogonality requires `InnerProductStyle(t) <: HasInnerProduct`, and `leftorth(!)` is currently only implemented for `InnerProductStyle(t) === EuclideanProduct()`. """ -function leftorth(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple; kwargs...) - return leftorth!(permute(t, (p1, p2); copy=true); kwargs...) +function leftorth(t::AbstractTensorMap, (p₁, p₂)::Index2Tuple; kwargs...) + return leftorth!(permute(t, (p₁, p₂); copy=true); kwargs...) end """ - rightorth(t::AbstractTensorMap, leftind::Tuple, rightind::Tuple; + rightorth(t::AbstractTensorMap, (leftind, rightind)::Index2Tuple; alg::OrthogonalFactorizationAlgorithm = LQpos()) -> L, Q Create orthonormal basis `Q` for indices in `rightind`, and remainder `L` such that @@ -101,12 +91,12 @@ Orthogonality requires `InnerProductStyle(t) <: HasInnerProduct`, and `rightorth(!)` is currently only implemented for `InnerProductStyle(t) === EuclideanProduct()`. """ -function rightorth(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple; kwargs...) - return rightorth!(permute(t, (p1, p2); copy=true); kwargs...) +function rightorth(t::AbstractTensorMap, (p₁, p₂)::Index2Tuple; kwargs...) + return rightorth!(permute(t, (p₁, p₂); copy=true); kwargs...) end """ - leftnull(t::AbstractTensor, leftind::Tuple, rightind::Tuple; + leftnull(t::AbstractTensor, (leftind, rightind)::Index2Tuple; alg::OrthogonalFactorizationAlgorithm = QRpos()) -> N Create orthonormal basis for the orthogonal complement of the support of the indices in @@ -127,12 +117,12 @@ Orthogonality requires `InnerProductStyle(t) <: HasInnerProduct`, and `leftnull(!)` is currently only implemented for `InnerProductStyle(t) === EuclideanProduct()`. """ -function leftnull(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple; kwargs...) - return leftnull!(permute(t, (p1, p2); copy=true); kwargs...) +function leftnull(t::AbstractTensorMap, (p₁, p₂)::Index2Tuple; kwargs...) + return leftnull!(permute(t, (p₁, p₂); copy=true); kwargs...) end """ - rightnull(t::AbstractTensor, leftind::Tuple, rightind::Tuple; + rightnull(t::AbstractTensor, (leftind, rightind)::Index2Tuple; alg::OrthogonalFactorizationAlgorithm = LQ(), atol::Real = 0.0, rtol::Real = eps(real(float(one(scalartype(t)))))*iszero(atol)) -> N @@ -155,12 +145,12 @@ Orthogonality requires `InnerProductStyle(t) <: HasInnerProduct`, and `rightnull(!)` is currently only implemented for `InnerProductStyle(t) === EuclideanProduct()`. """ -function rightnull(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple; kwargs...) - return rightnull!(permute(t, (p1, p2); copy=true); kwargs...) +function rightnull(t::AbstractTensorMap, (p₁, p₂)::Index2Tuple; kwargs...) + return rightnull!(permute(t, (p₁, p₂); copy=true); kwargs...) end """ - eigen(t::AbstractTensor, leftind::Tuple, rightind::Tuple; kwargs...) -> D, V + eigen(t::AbstractTensor, (leftind, rightind)::Index2Tuple; kwargs...) -> D, V Compute eigenvalue factorization of tensor `t` as linear map from `rightind` to `leftind`. @@ -178,13 +168,13 @@ matrices. See the corresponding documentation for more information. See also `eig` and `eigh` """ -function LinearAlgebra.eigen(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple; +function LinearAlgebra.eigen(t::AbstractTensorMap, (p₁, p₂)::Index2Tuple; kwargs...) - return eigen!(permute(t, (p1, p2); copy=true); kwargs...) + return eigen!(permute(t, (p₁, p₂); copy=true); kwargs...) end """ - eig(t::AbstractTensor, leftind::Tuple, rightind::Tuple; kwargs...) -> D, V + eig(t::AbstractTensor, (leftind, rightind)::Index2Tuple; kwargs...) -> D, V Compute eigenvalue factorization of tensor `t` as linear map from `rightind` to `leftind`. The function `eig` assumes that the linear map is not hermitian and returns type stable @@ -204,12 +194,12 @@ Accepts the same keyword arguments `scale`, `permute` and `sortby` as `eigen` of See also `eigen` and `eigh`. """ -function eig(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple; kwargs...) - return eig!(permute(t, (p1, p2); copy=true); kwargs...) +function eig(t::AbstractTensorMap, (p₁, p₂)::Index2Tuple; kwargs...) + return eig!(permute(t, (p₁, p₂); copy=true); kwargs...) end """ - eigh(t::AbstractTensorMap, leftind::Tuple, rightind::Tuple) -> D, V + eigh(t::AbstractTensorMap, (leftind, rightind)::Index2Tuple) -> D, V Compute eigenvalue factorization of tensor `t` as linear map from `rightind` to `leftind`. The function `eigh` assumes that the linear map is hermitian and `D` and `V` tensors with @@ -228,12 +218,12 @@ permute(t, (leftind, rightind)) * V = V * D See also `eigen` and `eig`. """ -function eigh(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple) - return eigh!(permute(t, (p1, p2); copy=true)) +function eigh(t::AbstractTensorMap, (p₁, p₂)::Index2Tuple) + return eigh!(permute(t, (p₁, p₂); copy=true)) end """ - isposdef(t::AbstractTensor, leftind::Tuple, rightind::Tuple) -> ::Bool + isposdef(t::AbstractTensor, (leftind, rightind)::Index2Tuple) -> ::Bool Test whether a tensor `t` is positive definite as linear map from `rightind` to `leftind`. @@ -241,13 +231,10 @@ If `leftind` and `rightind` are not specified, the current partition of left and indices of `t` is used. In that case, less memory is allocated if one allows the data in `t` to be destroyed/overwritten, by using `isposdef!(t)`. Note that the permuted tensor on which `isposdef!` is called should have equal domain and codomain, as otherwise it is -meaningless - -Accepts the same keyword arguments `scale`, `permute` and `sortby` as `eigen` of dense -matrices. See the corresponding documentation for more information. +meaningless. """ -function LinearAlgebra.isposdef(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple) - return isposdef!(permute(t, (p1, p2); copy=true)) +function LinearAlgebra.isposdef(t::AbstractTensorMap, (p₁, p₂)::Index2Tuple) + return isposdef!(permute(t, (p₁, p₂); copy=true)) end function tsvd(t::AbstractTensorMap; trunc::TruncationScheme=NoTruncation(), diff --git a/test/tensors.jl b/test/tensors.jl index 0a1d8edf..b6d7b6db 100644 --- a/test/tensors.jl +++ b/test/tensors.jl @@ -347,7 +347,7 @@ for V in spacelist TensorKit.QL(), TensorKit.QLpos(), TensorKit.Polar(), TensorKit.SVD(), TensorKit.SDD()) - Q, R = @constinferred leftorth(t, (3, 4, 2), (1, 5); alg=alg) + Q, R = @constinferred leftorth(t, ((3, 4, 2), (1, 5)); alg=alg) QdQ = Q' * Q @test QdQ ≈ one(QdQ) @test Q * R ≈ permute(t, ((3, 4, 2), (1, 5))) @@ -359,7 +359,7 @@ for V in spacelist @testset "leftnull with $alg" for alg in (TensorKit.QR(), TensorKit.SVD(), TensorKit.SDD()) - N = @constinferred leftnull(t, (3, 4, 2), (1, 5); alg=alg) + N = @constinferred leftnull(t, ((3, 4, 2), (1, 5)); alg=alg) NdN = N' * N @test NdN ≈ one(NdN) @test norm(N' * permute(t, ((3, 4, 2), (1, 5)))) < @@ -370,7 +370,7 @@ for V in spacelist TensorKit.LQ(), TensorKit.LQpos(), TensorKit.Polar(), TensorKit.SVD(), TensorKit.SDD()) - L, Q = @constinferred rightorth(t, (3, 4), (2, 1, 5); alg=alg) + L, Q = @constinferred rightorth(t, ((3, 4), (2, 1, 5)); alg=alg) QQd = Q * Q' @test QQd ≈ one(QQd) @test L * Q ≈ permute(t, ((3, 4), (2, 1, 5))) @@ -382,14 +382,14 @@ for V in spacelist @testset "rightnull with $alg" for alg in (TensorKit.LQ(), TensorKit.SVD(), TensorKit.SDD()) - M = @constinferred rightnull(t, (3, 4), (2, 1, 5); alg=alg) + M = @constinferred rightnull(t, ((3, 4), (2, 1, 5)); alg=alg) MMd = M * M' @test MMd ≈ one(MMd) @test norm(permute(t, ((3, 4), (2, 1, 5))) * M') < 100 * eps(norm(t)) end @testset "tsvd with $alg" for alg in (TensorKit.SVD(), TensorKit.SDD()) - U, S, V = @constinferred tsvd(t, (3, 4, 2), (1, 5); alg=alg) + U, S, V = @constinferred tsvd(t, ((3, 4, 2), (1, 5)); alg=alg) UdU = U' * U @test UdU ≈ one(UdU) VVd = V * V' @@ -440,8 +440,8 @@ for V in spacelist t = Tensor(rand, T, V1 ⊗ V1' ⊗ V2 ⊗ V2') @testset "eig and isposdef" begin - D, V = eigen(t, (1, 3), (2, 4)) - D̃, Ṽ = @constinferred eig(t, (1, 3), (2, 4)) + D, V = eigen(t, ((1, 3), (2, 4))) + D̃, Ṽ = @constinferred eig(t, ((1, 3), (2, 4))) @test D ≈ D̃ @test V ≈ Ṽ VdV = V' * V