diff --git a/Project.toml b/Project.toml index ba52ac3..b246193 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "ITensorBase" uuid = "4795dd04-0d67-49bb-8f44-b89c448a1dc7" -version = "0.8.5" +version = "0.8.6" authors = ["ITensor developers and contributors"] [workspace] @@ -52,7 +52,7 @@ Mooncake = "0.4.202, 0.5" OrderedCollections = "1.6" Random = "1.10" SimpleTraits = "0.9.4" -TensorAlgebra = "0.11, 0.12" +TensorAlgebra = "0.12.4" TensorOperations = "5.3.1" TermInterface = "2" TupleTools = "1.6" diff --git a/src/index.jl b/src/index.jl index b3ac746..0d2dd77 100644 --- a/src/index.jl +++ b/src/index.jl @@ -130,12 +130,13 @@ function Base.show(io::IO, i::IndexName) end """ - Index(length) - Index(range) + Index(space) An index of an `ITensor`: a named unit range whose name is a freshly minted, unique -identifier carrying tags and a prime level. `Index(2)` makes an index of length `2` over -`Base.OneTo(2)`, and `Index(1:3)` makes one over an explicit range. Each call mints a new +identifier carrying tags and a prime level. The argument is a space that is converted to a +range: `Index(2)` makes an index of length `2` over `Base.OneTo(2)`, +`Index(1:3)` makes one over an explicit range, and (with GradedArrays loaded) +`Index([U1(0) => 2, U1(1) => 3])` makes one over a graded range. Each call mints a new name, so two indices built the same way are still distinct, and tensors share a dimension only when they share the same `Index`. diff --git a/src/namedunitrange.jl b/src/namedunitrange.jl index 34211d4..c2892f2 100644 --- a/src/namedunitrange.jl +++ b/src/namedunitrange.jl @@ -1,3 +1,5 @@ +using TensorAlgebra: to_range + """ NamedUnitRange{Name} @@ -26,14 +28,28 @@ unnamed(i::NamedUnitRange) = i.value name(i::NamedUnitRange) = i.name unnamedtype(::Type{<:NamedUnitRange{<:Any, <:Any, Unnamed}}) where {Unnamed} = Unnamed -# Construct from a range or length, minting a fresh name of the requested flavor. -# Generic over the name type via `uniquename`, so `Index(3)` (with `Index` a -# `NamedUnitRange{IndexName}` alias) needs no `Index`-specific constructor. -function NamedUnitRange{Name}(r::AbstractUnitRange) where {Name} - return NamedUnitRange(r, uniquename(Name)) +# Construct from a space, minting a fresh name of the requested flavor. The space is +# anything `to_range` accepts (an `Integer`, an existing range, or a sector-pair vector +# when GradedArrays is loaded), so `Index(2)`, `Index(1:3)`, and +# `Index([U1(0) => 2, U1(1) => 3])` all work. Generic over the name type via `uniquename`, +# so `Index` (a `NamedUnitRange{IndexName}` alias) needs no `Index`-specific constructor. +function NamedUnitRange{Name}(space) where {Name} + return NamedUnitRange{Name}(space, uniquename(Name)) +end +# A space and an explicit name, name type fixed by the `Name` parameter: convert the space +# to a range, then fall through to the base case below. +function NamedUnitRange{Name}(space, name) where {Name} + return NamedUnitRange{Name}(to_range(space), name) +end +# Base case: a ready-made range and a name. Fixing `Name` here rather than inferring it +# from `name` keeps the result a `NamedUnitRange{Name}` even if `uniquename(Name)` returns +# a different concrete type. +function NamedUnitRange{Name}(unnamed::AbstractUnitRange, name) where {Name} + return NamedUnitRange{Name, eltype(unnamed), typeof(unnamed)}(unnamed, name) end -function NamedUnitRange{Name}(length::Integer) where {Name} - return NamedUnitRange{Name}(Base.OneTo(length)) +# A space and an explicit name, name type inferred from `name`. +function NamedUnitRange(space, name) + return NamedUnitRange(to_range(space), name) end # This can be customized to output different named unit range types. diff --git a/test/test_basics.jl b/test/test_basics.jl index 587fd22..33a073e 100644 --- a/test/test_basics.jl +++ b/test/test_basics.jl @@ -58,6 +58,14 @@ using UUIDs: UUID @test plev(i) == 0 @test length(tags(i)) == 0 + # An integer length is routed through `to_range` to a `Base.OneTo`, and an + # explicit range is passed through unchanged. + i = Index(3) + @test unnamed(i) === Base.OneTo(3) + i = Index(2:4) + @test length(i) == 3 + @test unnamed(i) === 2:4 + i = settag(Index(2), "X", "Y") @test length(i) == 2 @test hastag(i, "X")