From 85bb89f44d4d145543e425945f3e43916b68d156 Mon Sep 17 00:00:00 2001 From: Matthew Fishman Date: Fri, 24 Jul 2026 10:47:38 -0400 Subject: [PATCH] Forward `dual`/`isdual` through `NamedUnitRange` ## Summary Forwards the `dual` and `isdual` generics owned by TensorAlgebra (added in https://github.com/ITensor/TensorAlgebra.jl/pull/214) through `NamedUnitRange`, so `isdual(index)` and `dual(index)` work directly on an `Index` instead of reaching into the wrapped range. Mirrors the existing `conj` forwarding. Bumps the TensorAlgebra compat floor to 0.17.8. --- Project.toml | 4 ++-- src/namedunitrange.jl | 6 +++++- test/test_tensorkitext.jl | 6 ++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Project.toml b/Project.toml index c1a0f85..ed3641f 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "ITensorBase" uuid = "4795dd04-0d67-49bb-8f44-b89c448a1dc7" -version = "0.13.4" +version = "0.13.5" authors = ["ITensor developers and contributors"] [workspace] @@ -48,7 +48,7 @@ Mooncake = "0.4.202, 0.5" OMEinsumContractionOrders = "1.3" Random = "1.10" SimpleTraits = "0.9.4" -TensorAlgebra = "0.17.5" +TensorAlgebra = "0.17.8" TensorKit = "0.17" TermInterface = "2" TupleTools = "1.6" diff --git a/src/namedunitrange.jl b/src/namedunitrange.jl index ffe5a83..8974111 100644 --- a/src/namedunitrange.jl +++ b/src/namedunitrange.jl @@ -1,4 +1,4 @@ -using TensorAlgebra: TensorAlgebra, to_range, trivialrange, ungrade +using TensorAlgebra: TensorAlgebra, dual, isdual, to_range, trivialrange, ungrade """ NamedUnitRange{Name} @@ -115,6 +115,10 @@ Base.hash(r::NamedUnitRange, h::UInt) = hash_named(:NamedArray, ungrade(r), h) # otherwise short-circuit before the inner range is touched. Base.conj(r::NamedUnitRange) = named(conj(unnamed(r)), name(r)) +# Forward `dual`/`isdual` to the underlying range so an index answers its duality directly. +TensorAlgebra.dual(r::NamedUnitRange) = named(dual(unnamed(r)), name(r)) +TensorAlgebra.isdual(r::NamedUnitRange) = isdual(unnamed(r)) + # Unit range functionality. Base.first(r::NamedUnitRange) = named(first(unnamed(r)), name(r)) Base.last(r::NamedUnitRange) = named(last(unnamed(r)), name(r)) diff --git a/test/test_tensorkitext.jl b/test/test_tensorkitext.jl index 2ffca07..9ab6988 100644 --- a/test/test_tensorkitext.jl +++ b/test/test_tensorkitext.jl @@ -36,6 +36,12 @@ using Test: @test, @test_throws, @testset @test unnamed(conj(i)) == dual(Vi) @test name(conj(i)) == name(i) + # `isdual`/`dual` forward to the underlying space. + @test TensorAlgebra.isdual(i) == false + @test TensorAlgebra.isdual(conj(i)) == true + @test unnamed(TensorAlgebra.dual(i)) == dual(Vi) + @test name(TensorAlgebra.dual(i)) == name(i) + # Equality is dual-insensitive: an index equals its dual (same name, same ungraded # extent), hashes match, and a fresh index of the same space is a distinct leg. This is # what lets `Base` set-ops / `Dict` / `Set` treat an index and its dual as one leg on a