Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "TensorAlgebra"
uuid = "68bd88dc-f39d-4e12-b2ca-f046b68fcc6a"
version = "0.17.7"
version = "0.17.8"
authors = ["ITensor developers <support@itensor.org> and contributors"]

[workspace]
Expand Down
4 changes: 4 additions & 0 deletions ext/TensorAlgebraTensorKitExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ TensorAlgebra.scalar(t::AbstractTensorMap) = TensorKit.scalar(t)
TensorAlgebra.data(t::TensorMap) = TensorAlgebra.data(t.data)
TensorAlgebra.data(t::DiagonalTensorMap) = TensorAlgebra.data(t.data)

# Duality queries on a single index space route to TensorKit's own space duality.
TensorAlgebra.isdual(V::ElementarySpace) = TensorKit.isdual(V)
TensorAlgebra.dual(V::ElementarySpace) = TensorKit.dual(V)

# The trivial length-1 axis of a space is its unit space (`oneunit`), the trivial-sector
# one-dimensional space; the length-`n` form is the direct sum of `n` unit spaces.
TensorAlgebra.trivialrange(V::ElementarySpace) = oneunit(V)
Expand Down
5 changes: 3 additions & 2 deletions src/TensorAlgebra.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module TensorAlgebra

export contract, contract!, eig_full, eig_trunc, eig_vals, eigh_full, eigh_trunc,
eigh_vals, gram_eigh_full, gram_eigh_full_with_pinv, invsqrth_safe, left_null,
export contract, contract!, dual, eig_full, eig_trunc, eig_vals, eigh_full, eigh_trunc,
eigh_vals, gram_eigh_full, gram_eigh_full_with_pinv, invsqrth_safe, isdual, left_null,
left_orth, left_polar, lq_compact, lq_full, project_hermitian, qr_compact,
qr_full, right_null, right_orth, right_polar, sqrth_invsqrth_safe, sqrth_safe,
svd_compact, svd_full, svd_trunc, svd_vals
Expand All @@ -24,6 +24,7 @@ include("matricize.jl")
include("concatenate.jl")
include("directsum.jl")
include("diagonal.jl")
include("dual.jl")
include("to_range.jl")
include("contract/contractalgorithm.jl")
include("contract/contract.jl")
Expand Down
21 changes: 21 additions & 0 deletions src/dual.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""
isdual(a) -> Bool

Returns `true` or `false` depending on if the axis `a` is dual. Falls back to `false`
for `AbstractUnitRange`.

See also [`dual`](@ref).
"""
function isdual end
isdual(::AbstractUnitRange) = false

"""
dual(a)

Returns the dual of the axis `a`. Falls back to returning `a` unchanged for
`AbstractUnitRange`.

See also [`isdual`](@ref).
"""
function dual end
dual(a::AbstractUnitRange) = a
14 changes: 14 additions & 0 deletions test/test_dual.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using TensorAlgebra: TensorAlgebra, dual, isdual
using Test: @test, @test_throws, @testset

@testset "dual/isdual fallbacks on ranges" begin
# An ordinary range has no arrow: never dual, and its own dual.
for r in (Base.OneTo(4), 2:5)
@test isdual(r) == false
@test dual(r) === r
end
# No universal fallback: a type with no duality concept errors instead of
# silently returning a default.
@test_throws MethodError isdual(3)
@test_throws MethodError dual(3)
end
2 changes: 2 additions & 0 deletions test/test_exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ using Test: @test, @testset
:TensorAlgebra,
:contract,
:contract!,
:dual,
:eig_full,
:eig_trunc,
:eig_vals,
Expand All @@ -15,6 +16,7 @@ using Test: @test, @testset
:gram_eigh_full,
:gram_eigh_full_with_pinv,
:invsqrth_safe,
:isdual,
:left_null,
:left_orth,
:left_polar,
Expand Down
7 changes: 7 additions & 0 deletions test/test_tensorkitext.jl
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,10 @@ using Test: @test, @test_throws, @testset
LinearAlgebra.tr(t)
end
end

@testset "dual/isdual on a TensorKit space" begin
V = Rep[U₁](0 => 2, 1 => 1)
@test TensorAlgebra.isdual(V) == false
@test TensorAlgebra.isdual(dual(V)) == true
@test TensorAlgebra.dual(V) == dual(V)
end