diff --git a/Project.toml b/Project.toml index 9bcdecf..7a0240c 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "ITensorBase" uuid = "4795dd04-0d67-49bb-8f44-b89c448a1dc7" -version = "0.7.0" +version = "0.8.0" 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.10" +TensorAlgebra = "0.11" TensorOperations = "5.3.1" TermInterface = "2" TupleTools = "1.6" diff --git a/docs/Project.toml b/docs/Project.toml index 03cbb58..1267e43 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -12,9 +12,9 @@ path = ".." [compat] Documenter = "1" -ITensorBase = "0.7" +ITensorBase = "0.8" ITensorFormatter = "0.2.27" Literate = "2" MatrixAlgebraKit = "0.2, 0.3, 0.4, 0.5, 0.6" -TensorAlgebra = "0.10" +TensorAlgebra = "0.11" Test = "1.10" diff --git a/examples/Project.toml b/examples/Project.toml index 16bf8e1..f0ab5f4 100644 --- a/examples/Project.toml +++ b/examples/Project.toml @@ -6,5 +6,5 @@ MatrixAlgebraKit = "6c742aac-3347-4629-af66-fc926824e5e4" path = ".." [compat] -ITensorBase = "0.7" +ITensorBase = "0.8" MatrixAlgebraKit = "0.2, 0.3, 0.4, 0.5, 0.6" diff --git a/ext/ITensorBaseMooncakeExt/ITensorBaseMooncakeExt.jl b/ext/ITensorBaseMooncakeExt/ITensorBaseMooncakeExt.jl index 7aeaa75..aebc80f 100644 --- a/ext/ITensorBaseMooncakeExt/ITensorBaseMooncakeExt.jl +++ b/ext/ITensorBaseMooncakeExt/ITensorBaseMooncakeExt.jl @@ -1,14 +1,12 @@ module ITensorBaseMooncakeExt -using ITensorBase: AbstractITensor, NamedUnitRange, blockedperm_nameddims, dimnames, - dimnames_setdiff, inds, name, to_inds, uniquename +using ITensorBase: AbstractITensor, NamedUnitRange, dimnames, dimnames_setdiff, inds, name, + nameperm, to_inds, uniquename using Mooncake: Mooncake, @zero_derivative, DefaultCtx -using TensorAlgebra: blockedperm Mooncake.tangent_type(::Type{<:NamedUnitRange}) = Mooncake.NoTangent -@zero_derivative DefaultCtx Tuple{typeof(blockedperm), AbstractITensor, Any, Any} -@zero_derivative DefaultCtx Tuple{typeof(blockedperm_nameddims), Any, Any, Any} +@zero_derivative DefaultCtx Tuple{typeof(nameperm), Any, Any, Any} # `dimnames(::ITensor)` returns the stored names `Vector` directly, so its output # aliases a field, where `@zero_derivative` is documented to be incorrect. Let # Mooncake differentiate it through the underlying `getfield`, whose built-in rule diff --git a/src/itensor.jl b/src/itensor.jl index a2af537..725b288 100644 --- a/src/itensor.jl +++ b/src/itensor.jl @@ -1,16 +1,17 @@ -# TODO: Check `allunique(dimnames)`? struct ITensor{DimName} <: AbstractITensor{DimName} unnamed::AbstractArray dimnames::Vector{DimName} + function ITensor{DimName}(unnamed::AbstractArray, dimnames) where {DimName} + dimnames = collect(DimName, dimnames) + ndims(unnamed) == length(dimnames) || + throw(ArgumentError("Number of named dims must match ndims.")) + allunique(dimnames) || + throw(ArgumentError("Dimension names must be distinct, got $(dimnames).")) + return new{DimName}(unnamed, dimnames) + end end -# TODO: Check `allunique(dimnames)`? -function ITensor(unnamed::AbstractArray, dims) - ndims(unnamed) == length(dims) || - throw(ArgumentError("Number of named dims must match ndims.")) - dimnames = collect(dims) - return ITensor{eltype(dimnames)}(unnamed, dimnames) -end +ITensor(unnamed::AbstractArray, dims) = ITensor{eltype(dims)}(unnamed, dims) ITensor(a::AbstractITensor, inds) = throw(ArgumentError("Already named.")) ITensor(a::AbstractITensor) = ITensor(unnamed(a), dimnames(a)) diff --git a/src/tensoralgebra.jl b/src/tensoralgebra.jl index 689e7b2..05a7c62 100644 --- a/src/tensoralgebra.jl +++ b/src/tensoralgebra.jl @@ -74,42 +74,23 @@ function mul!_nameddims( return a_dest end -function TA.blockedperm(na::AbstractITensor, nameddim_blocks::Tuple...) - return blockedperm_nameddims(na, nameddim_blocks...) -end -function blockedperm_nameddims(a::AbstractITensor, nameddim_blocks::Tuple...) - dimname_blocks = map(group -> name.(group), nameddim_blocks) - dimnames_a = dimnames(a) - perms = map(dimname_blocks) do dimname_block - return TA.BaseExtensions.indexin(dimname_block, dimnames_a) - end - return TA.permmortar(perms) +# Locate the named-dimension groups `group1`, `group2` within `a`, returning their two +# positional index groups. +function nameperm(a::AbstractITensor, group1, group2) + return TA.biperm(dimnames(a), name.(group1), name.(group2)) end # i, j, k, l = named.((2, 2, 2, 2), ("i", "j", "k", "l")) # a = randn(i, j, k, l) -# matricize(a, (i, k) => "a") # matricize(a, (i, k) => "a", (j, l) => "b") -# TODO: Rewrite in terms of `matricize(a, .., (1, 3))` interface. function TA.matricize(a::AbstractITensor, fusions::Vararg{Pair, 2}) return matricize_nameddims(a, fusions...) end function matricize_nameddims(na::AbstractITensor, fusions::Vararg{Pair, 2}) - dimnames_fuse = map(group -> name.(group), first.(fusions)) - dimnames_fused = last.(fusions) - if sum(length, dimnames_fuse) < ndims(na) - # Not all names are specified - dimnames_unspecified = dimnames_setdiff(dimnames(na), dimnames_fuse...) - dimnames_fuse = vcat( - tuple.(dimnames_unspecified), collect(dimnames_fuse) - ) - dimnames_fused = vcat( - dimnames_unspecified, collect(dimnames_fused) - ) - end - perm = TA.blockedperm(na, dimnames_fuse...) - a_fused = TA.matricize(unnamed(na), perm) - return nameddims(a_fused, dimnames_fused) + group1, group2 = first.(fusions) + perm_codomain, perm_domain = nameperm(na, group1, group2) + a_fused = TA.matricize(unnamed(na), perm_codomain, perm_domain) + return nameddims(a_fused, last.(fusions)) end function TA.unmatricize(na::AbstractITensor, splitters::Vararg{Pair, 2}) diff --git a/test/Project.toml b/test/Project.toml index 5186c3e..93619d7 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -31,7 +31,7 @@ Adapt = "4" Aqua = "0.8.9" BlockArrays = "1" Combinatorics = "1" -ITensorBase = "0.7" +ITensorBase = "0.8" ITensorPkgSkeleton = "0.3.42" JLArrays = "0.2, 0.3" LinearAlgebra = "1.10" @@ -41,7 +41,7 @@ Random = "1.10" SafeTestsets = "0.1" StableRNGs = "1" Suppressor = "0.2" -TensorAlgebra = "0.10" +TensorAlgebra = "0.11" TensorOperations = "5.3.1" TermInterface = "2" Test = "1.10" diff --git a/test/test_mooncakeext.jl b/test/test_mooncakeext.jl index 45ce31a..b54fd85 100644 --- a/test/test_mooncakeext.jl +++ b/test/test_mooncakeext.jl @@ -1,9 +1,8 @@ -using ITensorBase: ITensor, Name, NamedUnitRange, blockedperm_nameddims, dimnames, - dimnames_setdiff, inds, name, to_inds, uniquename +using ITensorBase: ITensor, Name, NamedUnitRange, dimnames, dimnames_setdiff, inds, name, + nameperm, to_inds, uniquename using LinearAlgebra: mul! using Mooncake: Mooncake using Random: Random -using TensorAlgebra: blockedperm using Test: @test, @testset @testset "MooncakeExt" begin @@ -21,9 +20,8 @@ using Test: @test, @testset a1 = randn(elt, (2, 2))[i, j] a2 = randn(elt, (2, 2))[j, k] - Mooncake.TestUtils.test_rule(rng, blockedperm, a1, (i,), (j,); mode, is_primitive) Mooncake.TestUtils.test_rule( - rng, blockedperm_nameddims, a1, (i,), (j,); mode, is_primitive + rng, nameperm, a1, (i,), (j,); mode, is_primitive ) Mooncake.TestUtils.test_rule(rng, dimnames, a1; mode, is_primitive) Mooncake.TestUtils.test_rule(rng, dimnames, a1, 1; mode, is_primitive)