From 02d33dbea1d673cdc64e8d4865a7639da04db9e8 Mon Sep 17 00:00:00 2001 From: Joey Date: Thu, 2 Oct 2025 18:06:14 -0400 Subject: [PATCH 01/34] Working ContractNetwork --- Project.toml | 6 +++++- src/ITensorNetworksNext.jl | 1 + src/contractnetwork.jl | 39 ++++++++++++++++++++++++++++++++++++ test/Project.toml | 2 ++ test/test_contractnetwork.jl | 38 +++++++++++++++++++++++++++++++++++ 5 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 src/contractnetwork.jl create mode 100644 test/test_contractnetwork.jl diff --git a/Project.toml b/Project.toml index ce4f361..2ade440 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "ITensorNetworksNext" uuid = "302f2e75-49f0-4526-aef7-d8ba550cb06c" authors = ["ITensor developers and contributors"] -version = "0.1.2" +version = "0.1.3" [deps] Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" @@ -9,12 +9,14 @@ BackendSelection = "680c2d7c-f67a-4cc9-ae9c-da132b1447a5" DataGraphs = "b5a273c3-7e6c-41f6-98bd-8d7f1525a36a" Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" +ITensorBase = "4795dd04-0d67-49bb-8f44-b89c448a1dc7" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" NamedDimsArrays = "60cbd0c0-df58-4cb7-918c-6f5607b73fde" NamedGraphs = "678767b0-92e7-4007-89e4-4527a8725b19" SimpleTraits = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" SplitApplyCombine = "03a91e81-4c3e-53e1-a0a4-9c0c8f19dd66" +TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" [compat] Adapt = "4.3.0" @@ -22,10 +24,12 @@ BackendSelection = "0.1.6" DataGraphs = "0.2.7" Dictionaries = "0.4.5" Graphs = "1.13.1" +ITensorBase = "0.2.13" LinearAlgebra = "1.10" MacroTools = "0.5.16" NamedDimsArrays = "0.7.13" NamedGraphs = "0.6.9" SimpleTraits = "0.9.5" SplitApplyCombine = "1.2.3" +TensorOperations = "5.3.1" julia = "1.10" diff --git a/src/ITensorNetworksNext.jl b/src/ITensorNetworksNext.jl index 89daa37..5b6752a 100644 --- a/src/ITensorNetworksNext.jl +++ b/src/ITensorNetworksNext.jl @@ -2,5 +2,6 @@ module ITensorNetworksNext include("abstracttensornetwork.jl") include("tensornetwork.jl") +include("contractnetwork.jl") end diff --git a/src/contractnetwork.jl b/src/contractnetwork.jl new file mode 100644 index 0000000..0bebc44 --- /dev/null +++ b/src/contractnetwork.jl @@ -0,0 +1,39 @@ +using TensorOperations: TensorOperations, optimaltree +using ITensorBase: inds, dim + +default_sequence_alg = "optimal" + +function contraction_sequence(::Algorithm"optimal", tn::Vector{<:AbstractArray}) + network = collect.(inds.(tn)) + #Converting dims to Float64 to minimize overflow issues + inds_to_dims = Dict(i => Float64(dim(i)) for i in unique(reduce(vcat, network))) + seq, _ = optimaltree(network, inds_to_dims) + return seq +end + +function contraction_sequence(::Algorithm"leftassociative", tn::Vector{<:AbstractArray}) + return Any[i for i in 1:length(tn)] +end + +function contraction_sequence(tn::Vector{<:AbstractArray}; alg=default_sequence_alg) + contraction_sequence(Algorithm(alg), tn) +end + +# Internal recursive worker +function recursive_contractnetwork(tn::Union{AbstractVector,AbstractArray}) + tn isa AbstractVector && return reduce(*, map(recursive_contractnetwork, tn)) + return tn +end + +# Recursive worker for ordering the tensors according to the sequence +rearrange(tn::Vector{<:AbstractArray}, i::Integer) = tn[i] +rearrange(tn::Vector{<:AbstractArray}, v::AbstractVector) = [rearrange(tn, s) for s in v] + +function contractnetwork(tn::Vector{<:AbstractArray}; sequence_alg=default_sequence_alg) + sequence = contraction_sequence(tn; alg=sequence_alg) + return recursive_contractnetwork(rearrange(tn, sequence)) +end + +function contractnetwork(tn::AbstractTensorNetwork; sequence_alg=default_sequence_alg) + return contractnetwork([tn[v] for v in vertices(tn)]; sequence_alg) +end diff --git a/test/Project.toml b/test/Project.toml index 94f32e3..842577b 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -8,6 +8,7 @@ NamedDimsArrays = "60cbd0c0-df58-4cb7-918c-6f5607b73fde" NamedGraphs = "678767b0-92e7-4007-89e4-4527a8725b19" SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb" +TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [compat] @@ -20,4 +21,5 @@ NamedDimsArrays = "0.7.14" NamedGraphs = "0.6.8" SafeTestsets = "0.1" Suppressor = "0.2.8" +TensorOperations = "5.3.1" Test = "1.10" diff --git a/test/test_contractnetwork.jl b/test/test_contractnetwork.jl new file mode 100644 index 0000000..a2cf648 --- /dev/null +++ b/test/test_contractnetwork.jl @@ -0,0 +1,38 @@ +using Graphs: edges +using NamedGraphs.GraphsExtensions: arranged_edges, incident_edges +using NamedGraphs.NamedGraphGenerators: named_grid +using ITensorBase: Index, ITensor +using ITensorNetworksNext: + TensorNetwork, linkinds, siteinds, contractnetwork, contraction_sequence +using Test: @test, @testset + +@testset "ContractNetwork" begin + @testset "Contract Vectors of ITensors" begin + i, j, k = Index(2), Index(2), Index(5) + A = ITensor([1.0 1.0; 0.5 1.0], i, j) + B = ITensor([2.0, 1.0], i) + C = ITensor([5.0, 1.0], j) + D = ITensor([-2.0, 3.0, 4.0, 5.0, 1.0], k) + + ABCD_1 = contractnetwork([A, B, C, D]; sequence_alg="leftassociative") + ABCD_2 = contractnetwork([A, B, C, D]; sequence_alg="optimal") + + @test ABCD_1 == ABCD_2 + end + + @testset "Contract One Dimensional Network" begin + dims = (4, 4) + g = named_grid(dims) + l = Dict(e => Index(2) for e in edges(g)) + l = merge(l, Dict(reverse(e) => l[e] for e in edges(g))) + tn = TensorNetwork(g) do v + is = map(e -> l[e], incident_edges(g, v)) + return randn(Tuple(is)) + end + + z1 = contractnetwork(tn; sequence_alg="optimal")[] + z2 = contractnetwork(tn; sequence_alg="leftassociative")[] + + @test abs(z1 - z2) / abs(z1) <= 1e-14 + end +end From 4d43eb5605fcbf8af6936f953942a443167df81e Mon Sep 17 00:00:00 2001 From: Joey Date: Fri, 3 Oct 2025 09:53:07 -0400 Subject: [PATCH 02/34] Better tolerance check on test --- test/test_contractnetwork.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_contractnetwork.jl b/test/test_contractnetwork.jl index a2cf648..d421136 100644 --- a/test/test_contractnetwork.jl +++ b/test/test_contractnetwork.jl @@ -33,6 +33,6 @@ using Test: @test, @testset z1 = contractnetwork(tn; sequence_alg="optimal")[] z2 = contractnetwork(tn; sequence_alg="leftassociative")[] - @test abs(z1 - z2) / abs(z1) <= 1e-14 + @test abs(z1 - z2) / abs(z1) <= 1e3*eps(Float64) end end From 5dcecfb9fffb0167343048b074effccde4d70db4 Mon Sep 17 00:00:00 2001 From: Joey Date: Sun, 5 Oct 2025 10:54:41 -0400 Subject: [PATCH 03/34] Contract Network Stuff --- src/contractnetwork.jl | 25 ++++++++----------------- test/test_contractnetwork.jl | 9 +++++---- 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/contractnetwork.jl b/src/contractnetwork.jl index 0bebc44..a846ef9 100644 --- a/src/contractnetwork.jl +++ b/src/contractnetwork.jl @@ -1,15 +1,6 @@ -using TensorOperations: TensorOperations, optimaltree using ITensorBase: inds, dim -default_sequence_alg = "optimal" - -function contraction_sequence(::Algorithm"optimal", tn::Vector{<:AbstractArray}) - network = collect.(inds.(tn)) - #Converting dims to Float64 to minimize overflow issues - inds_to_dims = Dict(i => Float64(dim(i)) for i in unique(reduce(vcat, network))) - seq, _ = optimaltree(network, inds_to_dims) - return seq -end +default_sequence_alg = "leftassociative" function contraction_sequence(::Algorithm"leftassociative", tn::Vector{<:AbstractArray}) return Any[i for i in 1:length(tn)] @@ -20,8 +11,8 @@ function contraction_sequence(tn::Vector{<:AbstractArray}; alg=default_sequence_ end # Internal recursive worker -function recursive_contractnetwork(tn::Union{AbstractVector,AbstractArray}) - tn isa AbstractVector && return reduce(*, map(recursive_contractnetwork, tn)) +function recursive_contractnetwork(tn::Union{AbstractVector,AbstractNamedDimsArray}) + tn isa AbstractVector && return prod(recursive_contractnetwork, tn) return tn end @@ -29,11 +20,11 @@ end rearrange(tn::Vector{<:AbstractArray}, i::Integer) = tn[i] rearrange(tn::Vector{<:AbstractArray}, v::AbstractVector) = [rearrange(tn, s) for s in v] -function contractnetwork(tn::Vector{<:AbstractArray}; sequence_alg=default_sequence_alg) - sequence = contraction_sequence(tn; alg=sequence_alg) - return recursive_contractnetwork(rearrange(tn, sequence)) +function contractnetwork(tn::Vector{<:AbstractArray}; sequence=default_sequence_alg) + contract_sequence = isa(sequence, String) ? contraction_sequence(tn; alg=sequence) : sequence + return recursive_contractnetwork(rearrange(tn, contract_sequence)) end -function contractnetwork(tn::AbstractTensorNetwork; sequence_alg=default_sequence_alg) - return contractnetwork([tn[v] for v in vertices(tn)]; sequence_alg) +function contractnetwork(tn::AbstractTensorNetwork; sequence=default_sequence_alg) + return contractnetwork([tn[v] for v in vertices(tn)]; sequence) end diff --git a/test/test_contractnetwork.jl b/test/test_contractnetwork.jl index d421136..5d01f12 100644 --- a/test/test_contractnetwork.jl +++ b/test/test_contractnetwork.jl @@ -4,6 +4,7 @@ using NamedGraphs.NamedGraphGenerators: named_grid using ITensorBase: Index, ITensor using ITensorNetworksNext: TensorNetwork, linkinds, siteinds, contractnetwork, contraction_sequence +using TensorOperations using Test: @test, @testset @testset "ContractNetwork" begin @@ -14,8 +15,8 @@ using Test: @test, @testset C = ITensor([5.0, 1.0], j) D = ITensor([-2.0, 3.0, 4.0, 5.0, 1.0], k) - ABCD_1 = contractnetwork([A, B, C, D]; sequence_alg="leftassociative") - ABCD_2 = contractnetwork([A, B, C, D]; sequence_alg="optimal") + ABCD_1 = contractnetwork([A, B, C, D]; sequence="leftassociative") + ABCD_2 = contractnetwork([A, B, C, D]; sequence="optimal") @test ABCD_1 == ABCD_2 end @@ -30,8 +31,8 @@ using Test: @test, @testset return randn(Tuple(is)) end - z1 = contractnetwork(tn; sequence_alg="optimal")[] - z2 = contractnetwork(tn; sequence_alg="leftassociative")[] + z1 = contractnetwork(tn; sequence="optimal")[] + z2 = contractnetwork(tn; sequence="leftassociative")[] @test abs(z1 - z2) / abs(z1) <= 1e3*eps(Float64) end From b56b75221d289f75aa47c730687ceb193bc486d3 Mon Sep 17 00:00:00 2001 From: Joey Date: Sun, 5 Oct 2025 10:57:11 -0400 Subject: [PATCH 04/34] Weak Dependencies --- Project.toml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 2ade440..98e45e2 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "ITensorNetworksNext" uuid = "302f2e75-49f0-4526-aef7-d8ba550cb06c" authors = ["ITensor developers and contributors"] -version = "0.1.3" +version = "0.1.5" [deps] Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" @@ -16,8 +16,13 @@ NamedDimsArrays = "60cbd0c0-df58-4cb7-918c-6f5607b73fde" NamedGraphs = "678767b0-92e7-4007-89e4-4527a8725b19" SimpleTraits = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" SplitApplyCombine = "03a91e81-4c3e-53e1-a0a4-9c0c8f19dd66" + +[weakdeps] TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" +[extensions] +ITensorNetworksNextTensorOperationsExt = "TensorOperations" + [compat] Adapt = "4.3.0" BackendSelection = "0.1.6" @@ -33,3 +38,10 @@ SimpleTraits = "0.9.5" SplitApplyCombine = "1.2.3" TensorOperations = "5.3.1" julia = "1.10" + +[extras] +TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["Test"] From 6543ad41a2d8118881ac16da73d28e72f4d54ea1 Mon Sep 17 00:00:00 2001 From: Joey Date: Sun, 5 Oct 2025 10:57:27 -0400 Subject: [PATCH 05/34] External Dependency --- .../ITensorNetworksNextTensorOperationsExt.jl | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl diff --git a/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl b/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl new file mode 100644 index 0000000..2c3b210 --- /dev/null +++ b/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl @@ -0,0 +1,14 @@ +module ITensorNetworksTensorOperationsExt + +using ITensorNetworksNext: ITensorNetworksNext +using TensorOperations: TensorOperations, optimaltree + +function ITensorNetworksNext.contraction_sequence(::Algorithm"optimal", tn::Vector{<:AbstractArray}) + network = collect.(inds.(tn)) + #Converting dims to Float64 to minimize overflow issues + inds_to_dims = Dict(i => Float64(dim(i)) for i in unique(reduce(vcat, network))) + seq, _ = optimaltree(network, inds_to_dims) + return seq +end + +end \ No newline at end of file From 87647df3db4972c4868d027a74c4d511e9aee567 Mon Sep 17 00:00:00 2001 From: Joey Date: Sun, 5 Oct 2025 11:16:14 -0400 Subject: [PATCH 06/34] Fix imports --- .../ITensorNetworksNextTensorOperationsExt.jl | 4 +++- src/contractnetwork.jl | 2 +- test/test_contractnetwork.jl | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl b/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl index 2c3b210..222babe 100644 --- a/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl +++ b/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl @@ -1,5 +1,7 @@ -module ITensorNetworksTensorOperationsExt +module ITensorNetworksNextTensorOperationsExt +using BackendSelection: @Algorithm_str, Algorithm +using ITensorBase: inds, dim using ITensorNetworksNext: ITensorNetworksNext using TensorOperations: TensorOperations, optimaltree diff --git a/src/contractnetwork.jl b/src/contractnetwork.jl index a846ef9..f20c34e 100644 --- a/src/contractnetwork.jl +++ b/src/contractnetwork.jl @@ -1,4 +1,4 @@ -using ITensorBase: inds, dim +using BackendSelection: @Algorithm_str, Algorithm default_sequence_alg = "leftassociative" diff --git a/test/test_contractnetwork.jl b/test/test_contractnetwork.jl index 5d01f12..7d9ce1f 100644 --- a/test/test_contractnetwork.jl +++ b/test/test_contractnetwork.jl @@ -4,7 +4,7 @@ using NamedGraphs.NamedGraphGenerators: named_grid using ITensorBase: Index, ITensor using ITensorNetworksNext: TensorNetwork, linkinds, siteinds, contractnetwork, contraction_sequence -using TensorOperations +using TensorOperations: TensorOperations using Test: @test, @testset @testset "ContractNetwork" begin From 9f218d77dd1ab3941c8450b19292537b40e70641 Mon Sep 17 00:00:00 2001 From: Joey Date: Sun, 5 Oct 2025 11:27:48 -0400 Subject: [PATCH 07/34] Force specification of contract alg --- src/contractnetwork.jl | 22 +++++++++++++++++----- test/test_contractnetwork.jl | 8 ++++---- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/contractnetwork.jl b/src/contractnetwork.jl index f20c34e..d474309 100644 --- a/src/contractnetwork.jl +++ b/src/contractnetwork.jl @@ -1,6 +1,13 @@ using BackendSelection: @Algorithm_str, Algorithm -default_sequence_alg = "leftassociative" +default_contract_alg = nothing + +#Algorithmic defaults +default_sequence(::Algorithm"exact") = "leftassociative" +function set_default_kwargs(alg::Algorithm"exact") + sequence = get(alg, :sequence, default_sequence(alg)) + return Algorithm("exact"; sequence) +end function contraction_sequence(::Algorithm"leftassociative", tn::Vector{<:AbstractArray}) return Any[i for i in 1:length(tn)] @@ -20,11 +27,16 @@ end rearrange(tn::Vector{<:AbstractArray}, i::Integer) = tn[i] rearrange(tn::Vector{<:AbstractArray}, v::AbstractVector) = [rearrange(tn, s) for s in v] -function contractnetwork(tn::Vector{<:AbstractArray}; sequence=default_sequence_alg) - contract_sequence = isa(sequence, String) ? contraction_sequence(tn; alg=sequence) : sequence +function contractnetwork(alg::Algorithm"exact", tn::Vector{<:AbstractArray}) + contract_sequence = isa(alg.sequence, String) ? contraction_sequence(tn; alg=alg.sequence) : sequence return recursive_contractnetwork(rearrange(tn, contract_sequence)) end -function contractnetwork(tn::AbstractTensorNetwork; sequence=default_sequence_alg) - return contractnetwork([tn[v] for v in vertices(tn)]; sequence) +function contractnetwork(alg::Algorithm"exact", tn::AbstractTensorNetwork) + return contractnetwork(alg, [tn[v] for v in vertices(tn)]) end + +function contractnetwork(tn::Union{AbstractTensorNetwork, Vector{<:AbstractArray}}; alg = default_contract_alg, kwargs...) + alg == nothing && error("Must specify an algorithm to contract the network with") + return contractnetwork(set_default_kwargs(Algorithm(alg; kwargs...)), tn) +end \ No newline at end of file diff --git a/test/test_contractnetwork.jl b/test/test_contractnetwork.jl index 7d9ce1f..e1b1301 100644 --- a/test/test_contractnetwork.jl +++ b/test/test_contractnetwork.jl @@ -15,8 +15,8 @@ using Test: @test, @testset C = ITensor([5.0, 1.0], j) D = ITensor([-2.0, 3.0, 4.0, 5.0, 1.0], k) - ABCD_1 = contractnetwork([A, B, C, D]; sequence="leftassociative") - ABCD_2 = contractnetwork([A, B, C, D]; sequence="optimal") + ABCD_1 = contractnetwork([A, B, C, D]; alg = "exact", sequence="leftassociative") + ABCD_2 = contractnetwork([A, B, C, D]; alg = "exact", sequence="optimal") @test ABCD_1 == ABCD_2 end @@ -31,8 +31,8 @@ using Test: @test, @testset return randn(Tuple(is)) end - z1 = contractnetwork(tn; sequence="optimal")[] - z2 = contractnetwork(tn; sequence="leftassociative")[] + z1 = contractnetwork(tn; alg = "exact", sequence="optimal")[] + z2 = contractnetwork(tn; alg = "exact", sequence="leftassociative")[] @test abs(z1 - z2) / abs(z1) <= 1e3*eps(Float64) end From 6c5ac550173d055b63947406b56d8a7f829bbb40 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 5 Oct 2025 15:29:42 +0000 Subject: [PATCH 08/34] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../ITensorNetworksNextTensorOperationsExt.jl | 2 +- src/contractnetwork.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl b/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl index 222babe..fddc257 100644 --- a/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl +++ b/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl @@ -13,4 +13,4 @@ function ITensorNetworksNext.contraction_sequence(::Algorithm"optimal", tn::Vect return seq end -end \ No newline at end of file +end diff --git a/src/contractnetwork.jl b/src/contractnetwork.jl index d474309..0001e2e 100644 --- a/src/contractnetwork.jl +++ b/src/contractnetwork.jl @@ -39,4 +39,4 @@ end function contractnetwork(tn::Union{AbstractTensorNetwork, Vector{<:AbstractArray}}; alg = default_contract_alg, kwargs...) alg == nothing && error("Must specify an algorithm to contract the network with") return contractnetwork(set_default_kwargs(Algorithm(alg; kwargs...)), tn) -end \ No newline at end of file +end From 4c16d569e851e1376eb3abbbe0c75a42132337cb Mon Sep 17 00:00:00 2001 From: Joey Date: Sun, 5 Oct 2025 12:05:23 -0400 Subject: [PATCH 09/34] Runic Formatting --- docs/make.jl | 22 +- docs/make_index.jl | 16 +- docs/make_readme.jl | 16 +- examples/README.jl | 2 +- .../ITensorNetworksNextTensorOperationsExt.jl | 2 +- src/abstracttensornetwork.jl | 258 +++++++++--------- src/contractnetwork.jl | 28 +- src/tensornetwork.jl | 70 ++--- test/runtests.jl | 80 +++--- test/test_aqua.jl | 2 +- test/test_basics.jl | 102 +++---- test/test_contractnetwork.jl | 48 ++-- 12 files changed, 324 insertions(+), 322 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 5a50658..1b29518 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -2,23 +2,23 @@ using ITensorNetworksNext: ITensorNetworksNext using Documenter: Documenter, DocMeta, deploydocs, makedocs DocMeta.setdocmeta!( - ITensorNetworksNext, :DocTestSetup, :(using ITensorNetworksNext); recursive=true + ITensorNetworksNext, :DocTestSetup, :(using ITensorNetworksNext); recursive = true ) include("make_index.jl") makedocs(; - modules=[ITensorNetworksNext], - authors="ITensor developers and contributors", - sitename="ITensorNetworksNext.jl", - format=Documenter.HTML(; - canonical="https://itensor.github.io/ITensorNetworksNext.jl", - edit_link="main", - assets=["assets/favicon.ico", "assets/extras.css"], - ), - pages=["Home" => "index.md", "Reference" => "reference.md"], + modules = [ITensorNetworksNext], + authors = "ITensor developers and contributors", + sitename = "ITensorNetworksNext.jl", + format = Documenter.HTML(; + canonical = "https://itensor.github.io/ITensorNetworksNext.jl", + edit_link = "main", + assets = ["assets/favicon.ico", "assets/extras.css"], + ), + pages = ["Home" => "index.md", "Reference" => "reference.md"], ) deploydocs(; - repo="github.com/ITensor/ITensorNetworksNext.jl", devbranch="main", push_preview=true + repo = "github.com/ITensor/ITensorNetworksNext.jl", devbranch = "main", push_preview = true ) diff --git a/docs/make_index.jl b/docs/make_index.jl index 44fa493..038bc87 100644 --- a/docs/make_index.jl +++ b/docs/make_index.jl @@ -2,20 +2,20 @@ using Literate: Literate using ITensorNetworksNext: ITensorNetworksNext function ccq_logo(content) - include_ccq_logo = """ + include_ccq_logo = """ ```@raw html Flatiron Center for Computational Quantum Physics logo. Flatiron Center for Computational Quantum Physics logo. ``` """ - content = replace(content, "{CCQ_LOGO}" => include_ccq_logo) - return content + content = replace(content, "{CCQ_LOGO}" => include_ccq_logo) + return content end Literate.markdown( - joinpath(pkgdir(ITensorNetworksNext), "examples", "README.jl"), - joinpath(pkgdir(ITensorNetworksNext), "docs", "src"); - flavor=Literate.DocumenterFlavor(), - name="index", - postprocess=ccq_logo, + joinpath(pkgdir(ITensorNetworksNext), "examples", "README.jl"), + joinpath(pkgdir(ITensorNetworksNext), "docs", "src"); + flavor = Literate.DocumenterFlavor(), + name = "index", + postprocess = ccq_logo, ) diff --git a/docs/make_readme.jl b/docs/make_readme.jl index 960d376..088dc58 100644 --- a/docs/make_readme.jl +++ b/docs/make_readme.jl @@ -2,20 +2,20 @@ using Literate: Literate using ITensorNetworksNext: ITensorNetworksNext function ccq_logo(content) - include_ccq_logo = """ + include_ccq_logo = """ Flatiron Center for Computational Quantum Physics logo. """ - content = replace(content, "{CCQ_LOGO}" => include_ccq_logo) - return content + content = replace(content, "{CCQ_LOGO}" => include_ccq_logo) + return content end Literate.markdown( - joinpath(pkgdir(ITensorNetworksNext), "examples", "README.jl"), - joinpath(pkgdir(ITensorNetworksNext)); - flavor=Literate.CommonMarkFlavor(), - name="README", - postprocess=ccq_logo, + joinpath(pkgdir(ITensorNetworksNext), "examples", "README.jl"), + joinpath(pkgdir(ITensorNetworksNext)); + flavor = Literate.CommonMarkFlavor(), + name = "README", + postprocess = ccq_logo, ) diff --git a/examples/README.jl b/examples/README.jl index 4aaa79b..e3ee854 100644 --- a/examples/README.jl +++ b/examples/README.jl @@ -1,5 +1,5 @@ # # ITensorNetworksNext.jl -# +# # [![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://itensor.github.io/ITensorNetworksNext.jl/stable/) # [![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://itensor.github.io/ITensorNetworksNext.jl/dev/) # [![Build Status](https://github.com/ITensor/ITensorNetworksNext.jl/actions/workflows/Tests.yml/badge.svg?branch=main)](https://github.com/ITensor/ITensorNetworksNext.jl/actions/workflows/Tests.yml?query=branch%3Amain) diff --git a/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl b/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl index 222babe..fddc257 100644 --- a/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl +++ b/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl @@ -13,4 +13,4 @@ function ITensorNetworksNext.contraction_sequence(::Algorithm"optimal", tn::Vect return seq end -end \ No newline at end of file +end diff --git a/src/abstracttensornetwork.jl b/src/abstracttensornetwork.jl index e666e93..73bf9d6 100644 --- a/src/abstracttensornetwork.jl +++ b/src/abstracttensornetwork.jl @@ -1,44 +1,44 @@ using Adapt: Adapt, adapt, adapt_structure using BackendSelection: @Algorithm_str, Algorithm using DataGraphs: - DataGraphs, - AbstractDataGraph, - edge_data, - underlying_graph, - underlying_graph_type, - vertex_data + DataGraphs, + AbstractDataGraph, + edge_data, + underlying_graph, + underlying_graph_type, + vertex_data using Dictionaries: Dictionary using Graphs: - Graphs, - AbstractEdge, - AbstractGraph, - Graph, - add_edge!, - add_vertex!, - bfs_tree, - center, - dst, - edges, - edgetype, - ne, - neighbors, - nv, - rem_edge!, - src, - vertices + Graphs, + AbstractEdge, + AbstractGraph, + Graph, + add_edge!, + add_vertex!, + bfs_tree, + center, + dst, + edges, + edgetype, + ne, + neighbors, + nv, + rem_edge!, + src, + vertices using LinearAlgebra: LinearAlgebra, factorize using MacroTools: @capture using NamedDimsArrays: dimnames using NamedGraphs: NamedGraphs, NamedGraph, not_implemented, steiner_tree using NamedGraphs.GraphsExtensions: - ⊔, directed_graph, incident_edges, rem_edges!, rename_vertices, vertextype + ⊔, directed_graph, incident_edges, rem_edges!, rename_vertices, vertextype using SplitApplyCombine: flatten -abstract type AbstractTensorNetwork{V,VD} <: AbstractDataGraph{V,VD,Nothing} end +abstract type AbstractTensorNetwork{V, VD} <: AbstractDataGraph{V, VD, Nothing} end function Graphs.rem_edge!(tn::AbstractTensorNetwork, e) - rem_edge!(underlying_graph(tn), e) - return tn + rem_edge!(underlying_graph(tn), e) + return tn end # TODO: Define a generic fallback for `AbstractDataGraph`? @@ -46,14 +46,14 @@ DataGraphs.edge_data_eltype(::Type{<:AbstractTensorNetwork}) = error("No edge da # Graphs.jl overloads function Graphs.weights(graph::AbstractTensorNetwork) - V = vertextype(graph) - es = Tuple.(edges(graph)) - ws = Dictionary{Tuple{V,V},Float64}(es, undef) - for e in edges(graph) - w = log2(dim(commoninds(graph, e))) - ws[(src(e), dst(e))] = w - end - return ws + V = vertextype(graph) + es = Tuple.(edges(graph)) + ws = Dictionary{Tuple{V, V}, Float64}(es, undef) + for e in edges(graph) + w = log2(dim(commoninds(graph, e))) + ws[(src(e), dst(e))] = w + end + return ws end # Copy @@ -71,85 +71,85 @@ Graphs.is_directed(::Type{<:AbstractTensorNetwork}) = false # Derived interface, may need to be overloaded function DataGraphs.underlying_graph_type(G::Type{<:AbstractTensorNetwork}) - return underlying_graph_type(data_graph_type(G)) + return underlying_graph_type(data_graph_type(G)) end # AbstractDataGraphs overloads function DataGraphs.vertex_data(graph::AbstractTensorNetwork, args...) - return error("Not implemented") + return error("Not implemented") end function DataGraphs.edge_data(graph::AbstractTensorNetwork, args...) - return error("Not implemented") + return error("Not implemented") end DataGraphs.underlying_graph(tn::AbstractTensorNetwork) = error("Not implemented") function NamedGraphs.vertex_positions(tn::AbstractTensorNetwork) - return NamedGraphs.vertex_positions(underlying_graph(tn)) + return NamedGraphs.vertex_positions(underlying_graph(tn)) end function NamedGraphs.ordered_vertices(tn::AbstractTensorNetwork) - return NamedGraphs.ordered_vertices(underlying_graph(tn)) + return NamedGraphs.ordered_vertices(underlying_graph(tn)) end function Adapt.adapt_structure(to, tn::AbstractTensorNetwork) - # TODO: Define and use: - # - # @preserve_graph map_vertex_data(adapt(to), tn) - # - # or just: - # - # @preserve_graph map(adapt(to), tn) - return map_vertex_data_preserve_graph(adapt(to), tn) + # TODO: Define and use: + # + # @preserve_graph map_vertex_data(adapt(to), tn) + # + # or just: + # + # @preserve_graph map(adapt(to), tn) + return map_vertex_data_preserve_graph(adapt(to), tn) end function linkinds(tn::AbstractTensorNetwork, edge::Pair) - return linkinds(tn, edgetype(tn)(edge)) + return linkinds(tn, edgetype(tn)(edge)) end function linkinds(tn::AbstractTensorNetwork, edge::AbstractEdge) - return nameddimsindices(tn[src(edge)]) ∩ nameddimsindices(tn[dst(edge)]) + return nameddimsindices(tn[src(edge)]) ∩ nameddimsindices(tn[dst(edge)]) end function linkaxes(tn::AbstractTensorNetwork, edge::Pair) - return linkaxes(tn, edgetype(tn)(edge)) + return linkaxes(tn, edgetype(tn)(edge)) end function linkaxes(tn::AbstractTensorNetwork, edge::AbstractEdge) - return axes(tn[src(edge)]) ∩ axes(tn[dst(edge)]) + return axes(tn[src(edge)]) ∩ axes(tn[dst(edge)]) end function linknames(tn::AbstractTensorNetwork, edge::Pair) - return linknames(tn, edgetype(tn)(edge)) + return linknames(tn, edgetype(tn)(edge)) end function linknames(tn::AbstractTensorNetwork, edge::AbstractEdge) - return dimnames(tn[src(edge)]) ∩ dimnames(tn[dst(edge)]) + return dimnames(tn[src(edge)]) ∩ dimnames(tn[dst(edge)]) end function siteinds(tn::AbstractTensorNetwork, v) - s = nameddimsindices(tn[v]) - for v′ in neighbors(tn, v) - s = setdiff(s, nameddimsindices(tn[v′])) - end - return s + s = nameddimsindices(tn[v]) + for v′ in neighbors(tn, v) + s = setdiff(s, nameddimsindices(tn[v′])) + end + return s end function siteaxes(tn::AbstractTensorNetwork, edge::AbstractEdge) - s = axes(tn[src(edge)]) ∩ axes(tn[dst(edge)]) - for v′ in neighbors(tn, v) - s = setdiff(s, axes(tn[v′])) - end - return s + s = axes(tn[src(edge)]) ∩ axes(tn[dst(edge)]) + for v′ in neighbors(tn, v) + s = setdiff(s, axes(tn[v′])) + end + return s end function sitenames(tn::AbstractTensorNetwork, edge::AbstractEdge) - s = dimnames(tn[src(edge)]) ∩ dimnames(tn[dst(edge)]) - for v′ in neighbors(tn, v) - s = setdiff(s, dimnames(tn[v′])) - end - return s + s = dimnames(tn[src(edge)]) ∩ dimnames(tn[dst(edge)]) + for v′ in neighbors(tn, v) + s = setdiff(s, dimnames(tn[v′])) + end + return s end function setindex_preserve_graph!(tn::AbstractTensorNetwork, value, vertex) - vertex_data(tn)[vertex] = value - return tn + vertex_data(tn)[vertex] = value + return tn end # TODO: Move to `BaseExtensions` module. function is_setindex!_expr(expr::Expr) - return is_assignment_expr(expr) && is_getindex_expr(first(expr.args)) + return is_assignment_expr(expr) && is_getindex_expr(first(expr.args)) end is_setindex!_expr(x) = false is_getindex_expr(expr::Expr) = (expr.head === :ref) @@ -162,118 +162,118 @@ is_assignment_expr(expr) = false # preserve_graph_function(::typeof(map_vertex_data)) = map_vertex_data_preserve_graph # Also allow annotating codeblocks like `@views`. macro preserve_graph(expr) - if !is_setindex!_expr(expr) - error( - "preserve_graph must be used with setindex! syntax (as @preserve_graph a[i,j,...] = value)", - ) - end - @capture(expr, array_[indices__] = value_) - return :(setindex_preserve_graph!($(esc(array)), $(esc(value)), $(esc.(indices)...))) + if !is_setindex!_expr(expr) + error( + "preserve_graph must be used with setindex! syntax (as @preserve_graph a[i,j,...] = value)", + ) + end + @capture(expr, array_[indices__] = value_) + return :(setindex_preserve_graph!($(esc(array)), $(esc(value)), $(esc.(indices)...))) end # Update the graph of the TensorNetwork `tn` to include # edges that should exist based on the tensor connectivity. function add_missing_edges!(tn::AbstractTensorNetwork) - foreach(v -> add_missing_edges!(tn, v), vertices(tn)) - return tn + foreach(v -> add_missing_edges!(tn, v), vertices(tn)) + return tn end # Update the graph of the TensorNetwork `tn` to include # edges that should be incident to the vertex `v` # based on the tensor connectivity. function add_missing_edges!(tn::AbstractTensorNetwork, v) - for v′ in vertices(tn) - if v ≠ v′ - e = v => v′ - if !isempty(linkinds(tn, e)) - add_edge!(tn, e) - end + for v′ in vertices(tn) + if v ≠ v′ + e = v => v′ + if !isempty(linkinds(tn, e)) + add_edge!(tn, e) + end + end end - end - return tn + return tn end # Fix the edges of the TensorNetwork `tn` to match # the tensor connectivity. function fix_edges!(tn::AbstractTensorNetwork) - foreach(v -> fix_edges!(tn, v), vertices(tn)) - return tn + foreach(v -> fix_edges!(tn, v), vertices(tn)) + return tn end # Fix the edges of the TensorNetwork `tn` to match # the tensor connectivity at vertex `v`. function fix_edges!(tn::AbstractTensorNetwork, v) - rem_incident_edges!(tn, v) - rem_edges!(tn, incident_edges(tn, v)) - add_missing_edges!(tn, v) - return tn + rem_incident_edges!(tn, v) + rem_edges!(tn, incident_edges(tn, v)) + add_missing_edges!(tn, v) + return tn end # Customization point. using NamedDimsArrays: AbstractNamedUnitRange, namedunitrange, nametype, randname function trivial_unitrange(type::Type{<:AbstractUnitRange}) - return Base.oneto(one(eltype(type))) + return Base.oneto(one(eltype(type))) end function rand_trivial_namedunitrange( - ::Type{<:AbstractNamedUnitRange{<:Any,R,N}} -) where {R,N} - return namedunitrange(trivial_unitrange(R), randname(N)) + ::Type{<:AbstractNamedUnitRange{<:Any, R, N}} + ) where {R, N} + return namedunitrange(trivial_unitrange(R), randname(N)) end dag(x) = x using NamedDimsArrays: nameddimsindices function insert_trivial_link!(tn, e) - add_edge!(tn, e) - l = rand_trivial_namedunitrange(eltype(nameddimsindices(tn[src(e)]))) - x = similar(tn[src(e)], (l,)) - x[1] = 1 - @preserve_graph tn[src(e)] = tn[src(e)] * x - @preserve_graph tn[dst(e)] = tn[dst(e)] * dag(x) - return tn + add_edge!(tn, e) + l = rand_trivial_namedunitrange(eltype(nameddimsindices(tn[src(e)]))) + x = similar(tn[src(e)], (l,)) + x[1] = 1 + @preserve_graph tn[src(e)] = tn[src(e)] * x + @preserve_graph tn[dst(e)] = tn[dst(e)] * dag(x) + return tn end function Base.setindex!(tn::AbstractTensorNetwork, value, v) - @preserve_graph tn[v] = value - fix_edges!(tn, v) - return tn + @preserve_graph tn[v] = value + fix_edges!(tn, v) + return tn end using NamedGraphs.OrdinalIndexing: OrdinalSuffixedInteger # Fix ambiguity error. function Base.setindex!(graph::AbstractTensorNetwork, value, vertex::OrdinalSuffixedInteger) - graph[vertices(graph)[vertex]] = value - return graph + graph[vertices(graph)[vertex]] = value + return graph end # Fix ambiguity error. function Base.setindex!(tn::AbstractTensorNetwork, value, edge::AbstractEdge) - return error("No edge data.") + return error("No edge data.") end # Fix ambiguity error. function Base.setindex!(tn::AbstractTensorNetwork, value, edge::Pair) - return error("No edge data.") + return error("No edge data.") end using NamedGraphs.OrdinalIndexing: OrdinalSuffixedInteger # Fix ambiguity error. function Base.setindex!( - tn::AbstractTensorNetwork, - value, - edge::Pair{<:OrdinalSuffixedInteger,<:OrdinalSuffixedInteger}, -) - return error("No edge data.") + tn::AbstractTensorNetwork, + value, + edge::Pair{<:OrdinalSuffixedInteger, <:OrdinalSuffixedInteger}, + ) + return error("No edge data.") end function Base.show(io::IO, mime::MIME"text/plain", graph::AbstractTensorNetwork) - println(io, "$(typeof(graph)) with $(nv(graph)) vertices:") - show(io, mime, vertices(graph)) - println(io, "\n") - println(io, "and $(ne(graph)) edge(s):") - for e in edges(graph) - show(io, mime, e) + println(io, "$(typeof(graph)) with $(nv(graph)) vertices:") + show(io, mime, vertices(graph)) + println(io, "\n") + println(io, "and $(ne(graph)) edge(s):") + for e in edges(graph) + show(io, mime, e) + println(io) + end println(io) - end - println(io) - println(io, "with vertex data:") - show(io, mime, axes.(vertex_data(graph))) - return nothing + println(io, "with vertex data:") + show(io, mime, axes.(vertex_data(graph))) + return nothing end Base.show(io::IO, graph::AbstractTensorNetwork) = show(io, MIME"text/plain"(), graph) diff --git a/src/contractnetwork.jl b/src/contractnetwork.jl index d474309..56ec3bb 100644 --- a/src/contractnetwork.jl +++ b/src/contractnetwork.jl @@ -5,22 +5,22 @@ default_contract_alg = nothing #Algorithmic defaults default_sequence(::Algorithm"exact") = "leftassociative" function set_default_kwargs(alg::Algorithm"exact") - sequence = get(alg, :sequence, default_sequence(alg)) - return Algorithm("exact"; sequence) + sequence = get(alg, :sequence, default_sequence(alg)) + return Algorithm("exact"; sequence) end function contraction_sequence(::Algorithm"leftassociative", tn::Vector{<:AbstractArray}) - return Any[i for i in 1:length(tn)] + return Any[i for i in 1:length(tn)] end -function contraction_sequence(tn::Vector{<:AbstractArray}; alg=default_sequence_alg) - contraction_sequence(Algorithm(alg), tn) +function contraction_sequence(tn::Vector{<:AbstractArray}; alg = default_sequence_alg) + return contraction_sequence(Algorithm(alg), tn) end # Internal recursive worker -function recursive_contractnetwork(tn::Union{AbstractVector,AbstractNamedDimsArray}) - tn isa AbstractVector && return prod(recursive_contractnetwork, tn) - return tn +function recursive_contractnetwork(tn::Union{AbstractVector, AbstractNamedDimsArray}) + tn isa AbstractVector && return prod(recursive_contractnetwork, tn) + return tn end # Recursive worker for ordering the tensors according to the sequence @@ -28,15 +28,15 @@ rearrange(tn::Vector{<:AbstractArray}, i::Integer) = tn[i] rearrange(tn::Vector{<:AbstractArray}, v::AbstractVector) = [rearrange(tn, s) for s in v] function contractnetwork(alg::Algorithm"exact", tn::Vector{<:AbstractArray}) - contract_sequence = isa(alg.sequence, String) ? contraction_sequence(tn; alg=alg.sequence) : sequence - return recursive_contractnetwork(rearrange(tn, contract_sequence)) + contract_sequence = isa(alg.sequence, String) ? contraction_sequence(tn; alg = alg.sequence) : sequence + return recursive_contractnetwork(rearrange(tn, contract_sequence)) end function contractnetwork(alg::Algorithm"exact", tn::AbstractTensorNetwork) - return contractnetwork(alg, [tn[v] for v in vertices(tn)]) + return contractnetwork(alg, [tn[v] for v in vertices(tn)]) end function contractnetwork(tn::Union{AbstractTensorNetwork, Vector{<:AbstractArray}}; alg = default_contract_alg, kwargs...) - alg == nothing && error("Must specify an algorithm to contract the network with") - return contractnetwork(set_default_kwargs(Algorithm(alg; kwargs...)), tn) -end \ No newline at end of file + alg == nothing && error("Must specify an algorithm to contract the network with") + return contractnetwork(set_default_kwargs(Algorithm(alg; kwargs...)), tn) +end diff --git a/src/tensornetwork.jl b/src/tensornetwork.jl index 3fd794b..7423669 100644 --- a/src/tensornetwork.jl +++ b/src/tensornetwork.jl @@ -7,68 +7,68 @@ using NamedGraphs.GraphsExtensions: arranged_edges, vertextype function _TensorNetwork end -struct TensorNetwork{V,VD,UG<:AbstractGraph{V},Tensors<:AbstractDictionary{V,VD}} <: - AbstractTensorNetwork{V,VD} - underlying_graph::UG - tensors::Tensors - global @inline function _TensorNetwork( - underlying_graph::UG, tensors::Tensors - ) where {V,VD,UG<:AbstractGraph{V},Tensors<:AbstractDictionary{V,VD}} - # This assumes the tensor connectivity matches the graph structure. - return new{V,VD,UG,Tensors}(underlying_graph, tensors) - end +struct TensorNetwork{V, VD, UG <: AbstractGraph{V}, Tensors <: AbstractDictionary{V, VD}} <: + AbstractTensorNetwork{V, VD} + underlying_graph::UG + tensors::Tensors + global @inline function _TensorNetwork( + underlying_graph::UG, tensors::Tensors + ) where {V, VD, UG <: AbstractGraph{V}, Tensors <: AbstractDictionary{V, VD}} + # This assumes the tensor connectivity matches the graph structure. + return new{V, VD, UG, Tensors}(underlying_graph, tensors) + end end DataGraphs.underlying_graph(tn::TensorNetwork) = getfield(tn, :underlying_graph) DataGraphs.vertex_data(tn::TensorNetwork) = getfield(tn, :tensors) function DataGraphs.underlying_graph_type(type::Type{<:TensorNetwork}) - return fieldtype(type, :underlying_graph) + return fieldtype(type, :underlying_graph) end # Determine the graph structure from the tensors. function TensorNetwork(t::AbstractDictionary) - g = NamedGraph(eachindex(t)) - for v1 in vertices(g) - for v2 in vertices(g) - if v1 ≠ v2 - if !isdisjoint(dimnames(t[v1]), dimnames(t[v2])) - add_edge!(g, v1 => v2) + g = NamedGraph(eachindex(t)) + for v1 in vertices(g) + for v2 in vertices(g) + if v1 ≠ v2 + if !isdisjoint(dimnames(t[v1]), dimnames(t[v2])) + add_edge!(g, v1 => v2) + end + end end - end end - end - return _TensorNetwork(g, t) + return _TensorNetwork(g, t) end function TensorNetwork(tensors::AbstractDict) - return TensorNetwork(Dictionary(tensors)) + return TensorNetwork(Dictionary(tensors)) end function TensorNetwork(graph::AbstractGraph, tensors::AbstractDictionary) - tn = TensorNetwork(tensors) - arranged_edges(tn) ⊆ arranged_edges(graph) || - error("The edges in the tensors do not match the graph structure.") - for e in setdiff(arranged_edges(graph), arranged_edges(tn)) - insert_trivial_link!(tn, e) - end - return tn + tn = TensorNetwork(tensors) + arranged_edges(tn) ⊆ arranged_edges(graph) || + error("The edges in the tensors do not match the graph structure.") + for e in setdiff(arranged_edges(graph), arranged_edges(tn)) + insert_trivial_link!(tn, e) + end + return tn end function TensorNetwork(graph::AbstractGraph, tensors::AbstractDict) - return TensorNetwork(graph, Dictionary(tensors)) + return TensorNetwork(graph, Dictionary(tensors)) end function TensorNetwork(f, graph::AbstractGraph) - return TensorNetwork(graph, Dict(v => f(v) for v in vertices(graph))) + return TensorNetwork(graph, Dict(v => f(v) for v in vertices(graph))) end function Base.copy(tn::TensorNetwork) - TensorNetwork(copy(underlying_graph(tn)), copy(vertex_data(tn))) + return TensorNetwork(copy(underlying_graph(tn)), copy(vertex_data(tn))) end TensorNetwork(tn::TensorNetwork) = copy(tn) TensorNetwork{V}(tn::TensorNetwork{V}) where {V} = copy(tn) function TensorNetwork{V}(tn::TensorNetwork) where {V} - g′ = convert_vertextype(V, underlying_graph(tn)) - d = vertex_data(tn) - d′ = dictionary(V(k) => d[k] for k in eachindex(d)) - return TensorNetwork(g′, d′) + g′ = convert_vertextype(V, underlying_graph(tn)) + d = vertex_data(tn) + d′ = dictionary(V(k) => d[k] for k in eachindex(d)) + return TensorNetwork(g′, d′) end NamedGraphs.convert_vertextype(::Type{V}, tn::TensorNetwork{V}) where {V} = tn diff --git a/test/runtests.jl b/test/runtests.jl index 98b2d2b..0008050 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -6,60 +6,62 @@ using Suppressor: Suppressor const pat = r"(?:--group=)(\w+)" arg_id = findfirst(contains(pat), ARGS) const GROUP = uppercase( - if isnothing(arg_id) - get(ENV, "GROUP", "ALL") - else - only(match(pat, ARGS[arg_id]).captures) - end, + if isnothing(arg_id) + get(ENV, "GROUP", "ALL") + else + only(match(pat, ARGS[arg_id]).captures) + end, ) "match files of the form `test_*.jl`, but exclude `*setup*.jl`" function istestfile(fn) - return endswith(fn, ".jl") && startswith(basename(fn), "test_") && !contains(fn, "setup") + return endswith(fn, ".jl") && startswith(basename(fn), "test_") && !contains(fn, "setup") end "match files of the form `*.jl`, but exclude `*_notest.jl` and `*setup*.jl`" function isexamplefile(fn) - return endswith(fn, ".jl") && !endswith(fn, "_notest.jl") && !contains(fn, "setup") + return endswith(fn, ".jl") && !endswith(fn, "_notest.jl") && !contains(fn, "setup") end @time begin - # tests in groups based on folder structure - for testgroup in filter(isdir, readdir(@__DIR__)) - if GROUP == "ALL" || GROUP == uppercase(testgroup) - groupdir = joinpath(@__DIR__, testgroup) - for file in filter(istestfile, readdir(groupdir)) - filename = joinpath(groupdir, file) - @eval @safetestset $file begin - include($filename) + # tests in groups based on folder structure + for testgroup in filter(isdir, readdir(@__DIR__)) + if GROUP == "ALL" || GROUP == uppercase(testgroup) + groupdir = joinpath(@__DIR__, testgroup) + for file in filter(istestfile, readdir(groupdir)) + filename = joinpath(groupdir, file) + @eval @safetestset $file begin + include($filename) + end + end end - end end - end - # single files in top folder - for file in filter(istestfile, readdir(@__DIR__)) - (file == basename(@__FILE__)) && continue # exclude this file to avoid infinite recursion - @eval @safetestset $file begin - include($file) + # single files in top folder + for file in filter(istestfile, readdir(@__DIR__)) + (file == basename(@__FILE__)) && continue # exclude this file to avoid infinite recursion + @eval @safetestset $file begin + include($file) + end end - end - # test examples - examplepath = joinpath(@__DIR__, "..", "examples") - for (root, _, files) in walkdir(examplepath) - contains(chopprefix(root, @__DIR__), "setup") && continue - for file in filter(isexamplefile, files) - filename = joinpath(root, file) - @eval begin - @safetestset $file begin - $(Expr( - :macrocall, - GlobalRef(Suppressor, Symbol("@suppress")), - LineNumberNode(@__LINE__, @__FILE__), - :(include($filename)), - )) + # test examples + examplepath = joinpath(@__DIR__, "..", "examples") + for (root, _, files) in walkdir(examplepath) + contains(chopprefix(root, @__DIR__), "setup") && continue + for file in filter(isexamplefile, files) + filename = joinpath(root, file) + @eval begin + @safetestset $file begin + $( + Expr( + :macrocall, + GlobalRef(Suppressor, Symbol("@suppress")), + LineNumberNode(@__LINE__, @__FILE__), + :(include($filename)), + ) + ) + end + end end - end end - end end diff --git a/test/test_aqua.jl b/test/test_aqua.jl index 34bfff1..0afead5 100644 --- a/test/test_aqua.jl +++ b/test/test_aqua.jl @@ -3,5 +3,5 @@ using Aqua: Aqua using Test: @testset @testset "Code quality (Aqua.jl)" begin - Aqua.test_all(ITensorNetworksNext) + Aqua.test_all(ITensorNetworksNext) end diff --git a/test/test_basics.jl b/test/test_basics.jl index 59e5e35..0c9d803 100644 --- a/test/test_basics.jl +++ b/test/test_basics.jl @@ -8,56 +8,56 @@ using NamedGraphs.NamedGraphGenerators: named_grid using Test: @test, @testset @testset "ITensorNetworksNext" begin - @testset "Construct TensorNetwork product state" begin - dims = (3, 3) - g = named_grid(dims) - s = Dict(v => Index(2) for v in vertices(g)) - tn = TensorNetwork(g) do v - return randn(s[v]) + @testset "Construct TensorNetwork product state" begin + dims = (3, 3) + g = named_grid(dims) + s = Dict(v => Index(2) for v in vertices(g)) + tn = TensorNetwork(g) do v + return randn(s[v]) + end + @test nv(tn) == 9 + @test ne(tn) == ne(g) + @test issetequal(vertices(tn), vertices(g)) + @test issetequal(arranged_edges(tn), arranged_edges(g)) + for v in vertices(tn) + @test siteinds(tn, v) == [s[v]] + end + for v1 in vertices(tn) + for v2 in vertices(tn) + v1 == v2 && continue + haslink = !isempty(linkinds(tn, v1 => v2)) + @test haslink == has_edge(tn, v1 => v2) + end + end + for e in edges(tn) + @test isone(length(only(linkinds(tn, e)))) + end + end + @testset "Construct TensorNetwork partition function" begin + dims = (3, 3) + g = named_grid(dims) + l = Dict(e => Index(2) for e in edges(g)) + l = merge(l, Dict(reverse(e) => l[e] for e in edges(g))) + tn = TensorNetwork(g) do v + is = map(e -> l[e], incident_edges(g, v)) + return randn(Tuple(is)) + end + @test nv(tn) == 9 + @test ne(tn) == ne(g) + @test issetequal(vertices(tn), vertices(g)) + @test issetequal(arranged_edges(tn), arranged_edges(g)) + for v in vertices(tn) + @test isempty(siteinds(tn, v)) + end + for v1 in vertices(tn) + for v2 in vertices(tn) + v1 == v2 && continue + haslink = !isempty(linkinds(tn, v1 => v2)) + @test haslink == has_edge(tn, v1 => v2) + end + end + for e in edges(tn) + @test only(linkinds(tn, e)) == l[e] + end end - @test nv(tn) == 9 - @test ne(tn) == ne(g) - @test issetequal(vertices(tn), vertices(g)) - @test issetequal(arranged_edges(tn), arranged_edges(g)) - for v in vertices(tn) - @test siteinds(tn, v) == [s[v]] - end - for v1 in vertices(tn) - for v2 in vertices(tn) - v1 == v2 && continue - haslink = !isempty(linkinds(tn, v1 => v2)) - @test haslink == has_edge(tn, v1 => v2) - end - end - for e in edges(tn) - @test isone(length(only(linkinds(tn, e)))) - end - end - @testset "Construct TensorNetwork partition function" begin - dims = (3, 3) - g = named_grid(dims) - l = Dict(e => Index(2) for e in edges(g)) - l = merge(l, Dict(reverse(e) => l[e] for e in edges(g))) - tn = TensorNetwork(g) do v - is = map(e -> l[e], incident_edges(g, v)) - return randn(Tuple(is)) - end - @test nv(tn) == 9 - @test ne(tn) == ne(g) - @test issetequal(vertices(tn), vertices(g)) - @test issetequal(arranged_edges(tn), arranged_edges(g)) - for v in vertices(tn) - @test isempty(siteinds(tn, v)) - end - for v1 in vertices(tn) - for v2 in vertices(tn) - v1 == v2 && continue - haslink = !isempty(linkinds(tn, v1 => v2)) - @test haslink == has_edge(tn, v1 => v2) - end - end - for e in edges(tn) - @test only(linkinds(tn, e)) == l[e] - end - end end diff --git a/test/test_contractnetwork.jl b/test/test_contractnetwork.jl index e1b1301..3473adb 100644 --- a/test/test_contractnetwork.jl +++ b/test/test_contractnetwork.jl @@ -3,37 +3,37 @@ using NamedGraphs.GraphsExtensions: arranged_edges, incident_edges using NamedGraphs.NamedGraphGenerators: named_grid using ITensorBase: Index, ITensor using ITensorNetworksNext: - TensorNetwork, linkinds, siteinds, contractnetwork, contraction_sequence + TensorNetwork, linkinds, siteinds, contractnetwork, contraction_sequence using TensorOperations: TensorOperations using Test: @test, @testset @testset "ContractNetwork" begin - @testset "Contract Vectors of ITensors" begin - i, j, k = Index(2), Index(2), Index(5) - A = ITensor([1.0 1.0; 0.5 1.0], i, j) - B = ITensor([2.0, 1.0], i) - C = ITensor([5.0, 1.0], j) - D = ITensor([-2.0, 3.0, 4.0, 5.0, 1.0], k) + @testset "Contract Vectors of ITensors" begin + i, j, k = Index(2), Index(2), Index(5) + A = ITensor([1.0 1.0; 0.5 1.0], i, j) + B = ITensor([2.0, 1.0], i) + C = ITensor([5.0, 1.0], j) + D = ITensor([-2.0, 3.0, 4.0, 5.0, 1.0], k) - ABCD_1 = contractnetwork([A, B, C, D]; alg = "exact", sequence="leftassociative") - ABCD_2 = contractnetwork([A, B, C, D]; alg = "exact", sequence="optimal") + ABCD_1 = contractnetwork([A, B, C, D]; alg = "exact", sequence = "leftassociative") + ABCD_2 = contractnetwork([A, B, C, D]; alg = "exact", sequence = "optimal") - @test ABCD_1 == ABCD_2 - end - - @testset "Contract One Dimensional Network" begin - dims = (4, 4) - g = named_grid(dims) - l = Dict(e => Index(2) for e in edges(g)) - l = merge(l, Dict(reverse(e) => l[e] for e in edges(g))) - tn = TensorNetwork(g) do v - is = map(e -> l[e], incident_edges(g, v)) - return randn(Tuple(is)) + @test ABCD_1 == ABCD_2 end - z1 = contractnetwork(tn; alg = "exact", sequence="optimal")[] - z2 = contractnetwork(tn; alg = "exact", sequence="leftassociative")[] + @testset "Contract One Dimensional Network" begin + dims = (4, 4) + g = named_grid(dims) + l = Dict(e => Index(2) for e in edges(g)) + l = merge(l, Dict(reverse(e) => l[e] for e in edges(g))) + tn = TensorNetwork(g) do v + is = map(e -> l[e], incident_edges(g, v)) + return randn(Tuple(is)) + end + + z1 = contractnetwork(tn; alg = "exact", sequence = "optimal")[] + z2 = contractnetwork(tn; alg = "exact", sequence = "leftassociative")[] - @test abs(z1 - z2) / abs(z1) <= 1e3*eps(Float64) - end + @test abs(z1 - z2) / abs(z1) <= 1.0e3 * eps(Float64) + end end From edf78b7aad2959af02727ca09a4a7c67c6c83275 Mon Sep 17 00:00:00 2001 From: Joey Date: Sun, 5 Oct 2025 12:11:22 -0400 Subject: [PATCH 10/34] Revert Project toml slightly --- Project.toml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Project.toml b/Project.toml index 57b537c..eada186 100644 --- a/Project.toml +++ b/Project.toml @@ -17,9 +17,6 @@ NamedGraphs = "678767b0-92e7-4007-89e4-4527a8725b19" SimpleTraits = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" SplitApplyCombine = "03a91e81-4c3e-53e1-a0a4-9c0c8f19dd66" -[weakdeps] -TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" - [extensions] ITensorNetworksNextTensorOperationsExt = "TensorOperations" @@ -41,7 +38,3 @@ julia = "1.10" [extras] TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[targets] -test = ["Test"] From f345f6c74e96f7858993ed45ec6df1d2c9211513 Mon Sep 17 00:00:00 2001 From: Joey Date: Mon, 6 Oct 2025 08:30:31 -0400 Subject: [PATCH 11/34] Remove extras from Project.toml --- Project.toml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Project.toml b/Project.toml index eada186..d7aea6d 100644 --- a/Project.toml +++ b/Project.toml @@ -34,7 +34,4 @@ NamedGraphs = "0.6.9, 0.7" SimpleTraits = "0.9.5" SplitApplyCombine = "1.2.3" TensorOperations = "5.3.1" -julia = "1.10" - -[extras] -TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" +julia = "1.10" \ No newline at end of file From 074e347d84e8d5e5280f3c22226ad3378939302f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 6 Oct 2025 12:30:44 +0000 Subject: [PATCH 12/34] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index d7aea6d..6896d9e 100644 --- a/Project.toml +++ b/Project.toml @@ -34,4 +34,4 @@ NamedGraphs = "0.6.9, 0.7" SimpleTraits = "0.9.5" SplitApplyCombine = "1.2.3" TensorOperations = "5.3.1" -julia = "1.10" \ No newline at end of file +julia = "1.10" From 8187ca7c52f5cf0ce150427c7d551307ecf88655 Mon Sep 17 00:00:00 2001 From: Joey Date: Mon, 6 Oct 2025 08:33:58 -0400 Subject: [PATCH 13/34] Add to weakdeps --- Project.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Project.toml b/Project.toml index d7aea6d..96ca8a9 100644 --- a/Project.toml +++ b/Project.toml @@ -17,6 +17,9 @@ NamedGraphs = "678767b0-92e7-4007-89e4-4527a8725b19" SimpleTraits = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" SplitApplyCombine = "03a91e81-4c3e-53e1-a0a4-9c0c8f19dd66" +[weakdeps] +TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" + [extensions] ITensorNetworksNextTensorOperationsExt = "TensorOperations" From 37d9a76f7bdc91729464b12c4fc48f542ea079ac Mon Sep 17 00:00:00 2001 From: Joey Date: Tue, 21 Oct 2025 19:21:17 -0400 Subject: [PATCH 14/34] Merge --- test/test_lazynameddimsarrays.jl | 70 -------------------------------- 1 file changed, 70 deletions(-) delete mode 100644 test/test_lazynameddimsarrays.jl diff --git a/test/test_lazynameddimsarrays.jl b/test/test_lazynameddimsarrays.jl deleted file mode 100644 index 4c38c5e..0000000 --- a/test/test_lazynameddimsarrays.jl +++ /dev/null @@ -1,70 +0,0 @@ -using Base.Broadcast: materialize -using ITensorNetworksNext.LazyNamedDimsArrays: LazyNamedDimsArray, Mul, lazy -using NamedDimsArrays: NamedDimsArray, inds, nameddims -using TermInterface: - arguments, - arity, - children, - head, - iscall, - isexpr, - maketerm, - operation, - sorted_arguments, - sorted_children -using Test: @test, @test_throws, @testset -using WrappedUnions: unwrap - -@testset "LazyNamedDimsArrays" begin - @testset "Basics" begin - a1 = nameddims(randn(2, 2), (:i, :j)) - a2 = nameddims(randn(2, 2), (:j, :k)) - a3 = nameddims(randn(2, 2), (:k, :l)) - l1, l2, l3 = lazy.((a1, a2, a3)) - for li in (l1, l2, l3) - @test li isa LazyNamedDimsArray - @test unwrap(li) isa NamedDimsArray - @test inds(li) == inds(unwrap(li)) - @test copy(li) == unwrap(li) - @test materialize(li) == unwrap(li) - end - l = l1 * l2 * l3 - @test copy(l) ≈ a1 * a2 * a3 - @test materialize(l) ≈ a1 * a2 * a3 - @test issetequal(inds(l), symdiff(inds.((a1, a2, a3))...)) - @test unwrap(l) isa Mul - @test unwrap(l).arguments == [l1 * l2, l3] - # TermInterface.jl - @test operation(unwrap(l)) ≡ * - @test arguments(unwrap(l)) == [l1 * l2, l3] - end - - @testset "TermInterface" begin - a1 = nameddims(randn(2, 2), (:i, :j)) - a2 = nameddims(randn(2, 2), (:j, :k)) - a3 = nameddims(randn(2, 2), (:k, :l)) - l1, l2, l3 = lazy.((a1, a2, a3)) - - @test_throws ErrorException arguments(l1) - @test_throws ErrorException arity(l1) - @test_throws ErrorException children(l1) - @test_throws ErrorException head(l1) - @test !iscall(l1) - @test !isexpr(l1) - @test_throws ErrorException operation(l1) - @test_throws ErrorException sorted_arguments(l1) - @test_throws ErrorException sorted_children(l1) - - l = l1 * l2 * l3 - @test arguments(l) == [l1 * l2, l3] - @test arity(l) == 2 - @test children(l) == [l1 * l2, l3] - @test head(l) ≡ * - @test iscall(l) - @test isexpr(l) - @test l == maketerm(LazyNamedDimsArray, *, [l1 * l2, l3], nothing) - @test operation(l) ≡ * - @test sorted_arguments(l) == [l1 * l2, l3] - @test sorted_children(l) == [l1 * l2, l3] - end -end From c73d264195012729b5d8c514cab18d64e915169f Mon Sep 17 00:00:00 2001 From: Joey Date: Thu, 23 Oct 2025 18:56:22 -0400 Subject: [PATCH 15/34] Working contract --- src/contractnetwork.jl | 10 ++++------ src/lazynameddimsarrays.jl | 2 +- test/test_contractnetwork.jl | 12 ++++-------- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/contractnetwork.jl b/src/contractnetwork.jl index 813858c..7e47e3b 100644 --- a/src/contractnetwork.jl +++ b/src/contractnetwork.jl @@ -1,5 +1,6 @@ using BackendSelection: @Algorithm_str, Algorithm -using ITensorNetworksNext.LazyNamedDimsArrays: LazyNamedDimsArray, nested_array_to_lazy_multiply, substitute_lazy, materialize +using ITensorNetworksNext.LazyNamedDimsArrays: nested_array_to_lazy_multiply, substitute_lazy, materialize, lazy, + symnameddims default_contract_alg = nothing @@ -20,11 +21,8 @@ end function contractnetwork(alg::Algorithm"exact", tn::Vector{<:AbstractArray}) contract_sequence = isa(alg.sequence, String) ? contraction_sequence(tn; alg = alg.sequence) : sequence - @show contract_sequence - @show materialize(contract_sequence) - contract_sequence = substitute_lazy(contract_sequence, Dict(i => lazy(tn[i]) for i in 1:length(tn))) - @show contract_sequence - #return materialize(substitute_lazy(contract_sequence, Dict(i => tn[i] for i in 1:length(tn)))) + contract_sequence = substitute_lazy(contract_sequence, Dict(symnameddims(i) => lazy(tn[i]) for i in 1:length(tn))) + return materialize(contract_sequence) end function contractnetwork(alg::Algorithm"exact", tn::AbstractTensorNetwork) diff --git a/src/lazynameddimsarrays.jl b/src/lazynameddimsarrays.jl index a4f64ab..6c7d70d 100644 --- a/src/lazynameddimsarrays.jl +++ b/src/lazynameddimsarrays.jl @@ -294,7 +294,7 @@ TermInterface.operation(m::Mul) = * union::Union{A, Mul{LazyNamedDimsArray{T, A}}} end function LazyNamedDimsArray(a::AbstractNamedDimsArray) - return LazyNamedDimsArray{eltype(a), typeof(a)}(a) + return LazyNamedDimsArray{eltype(typeof(a)), typeof(a)}(a) end function LazyNamedDimsArray(a::Mul{LazyNamedDimsArray{T, A}}) where {T, A} return LazyNamedDimsArray{T, A}(a) diff --git a/test/test_contractnetwork.jl b/test/test_contractnetwork.jl index 126e15c..ff7e061 100644 --- a/test/test_contractnetwork.jl +++ b/test/test_contractnetwork.jl @@ -3,7 +3,7 @@ using NamedGraphs.GraphsExtensions: arranged_edges, incident_edges using NamedGraphs.NamedGraphGenerators: named_grid using ITensorBase: Index, ITensor using ITensorNetworksNext: - TensorNetwork, linkinds, siteinds, contractnetwork, contraction_sequence, symnameddims, lazy + TensorNetwork, linkinds, siteinds, contractnetwork, contraction_sequence, symnameddims, lazy, substitute_lazy, materialize using TensorOperations: TensorOperations using Test: @test, @testset @@ -15,14 +15,10 @@ using Test: @test, @testset C = ITensor([5.0, 1.0], j) D = ITensor([-2.0, 3.0, 4.0, 5.0, 1.0], k) - #@show s1 * s2 - #seq = contraction_sequence([A, B, C, D]; alg = "optimal") - #@show seq + ABCD_1 = contractnetwork([A, B, C, D]; alg = "exact", sequence = "leftassociative") + ABCD_2 = contractnetwork([A, B, C, D]; alg = "exact", sequence = "optimal") - #ABCD_1 = contractnetwork([A, B, C, D]; alg = "exact", sequence = "leftassociative") - # ABCD_2 = contractnetwork([A, B, C, D]; alg = "exact", sequence = "optimal") - - # @test ABCD_1 == ABCD_2 + @test ABCD_1 == ABCD_2 end @testset "Contract One Dimensional Network" begin From aa0a9973ad587cec2cba18154f87136a1161d21e Mon Sep 17 00:00:00 2001 From: Joey Date: Thu, 23 Oct 2025 19:11:54 -0400 Subject: [PATCH 16/34] Attempt to fix the toml --- Project.toml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Project.toml b/Project.toml index a17fbc5..1d774b6 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "ITensorNetworksNext" uuid = "302f2e75-49f0-4526-aef7-d8ba550cb06c" -authors = ["ITensor developers and contributors"] version = "0.1.10" +authors = ["ITensor developers and contributors"] [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" @@ -10,22 +10,22 @@ BackendSelection = "680c2d7c-f67a-4cc9-ae9c-da132b1447a5" DataGraphs = "b5a273c3-7e6c-41f6-98bd-8d7f1525a36a" Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" -ITensorBase = "4795dd04-0d67-49bb-8f44-b89c448a1dc7" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" NamedDimsArrays = "60cbd0c0-df58-4cb7-918c-6f5607b73fde" NamedGraphs = "678767b0-92e7-4007-89e4-4527a8725b19" SimpleTraits = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" SplitApplyCombine = "03a91e81-4c3e-53e1-a0a4-9c0c8f19dd66" +TermInterface = "8ea1fca8-c5ef-4a55-8b96-4e9afe9c9a3c" +TypeParameterAccessors = "7e5a90cf-f82e-492e-a09b-e3e26432c138" +WrappedUnions = "325db55a-9c6c-5b90-b1a2-ec87e7a38c44" [weakdeps] +ITensorBase = "4795dd04-0d67-49bb-8f44-b89c448a1dc7" TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" [extensions] ITensorNetworksNextTensorOperationsExt = "TensorOperations" -TermInterface = "8ea1fca8-c5ef-4a55-8b96-4e9afe9c9a3c" -TypeParameterAccessors = "7e5a90cf-f82e-492e-a09b-e3e26432c138" -WrappedUnions = "325db55a-9c6c-5b90-b1a2-ec87e7a38c44" [compat] AbstractTrees = "0.4.5" @@ -41,8 +41,5 @@ NamedDimsArrays = "0.8" NamedGraphs = "0.6.9, 0.7" SimpleTraits = "0.9.5" SplitApplyCombine = "1.2.3" -TermInterface = "2" -TypeParameterAccessors = "0.4.4" -WrappedUnions = "0.3" TensorOperations = "5.3.1" julia = "1.10" From 1517613ae3bd894ef3c8f6be5b4f4d156caa28b1 Mon Sep 17 00:00:00 2001 From: Joey Date: Thu, 23 Oct 2025 19:16:54 -0400 Subject: [PATCH 17/34] Attempt to fix the toml --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 1d774b6..a8fa807 100644 --- a/Project.toml +++ b/Project.toml @@ -34,7 +34,7 @@ BackendSelection = "0.1.6" DataGraphs = "0.2.7" Dictionaries = "0.4.5" Graphs = "1.13.1" -ITensorBase = "0.2.13" +ITensorBase = "0.3" LinearAlgebra = "1.10" MacroTools = "0.5.16" NamedDimsArrays = "0.8" From 2cabf12d9da3320ba001121416ffcab37495c81b Mon Sep 17 00:00:00 2001 From: Joey Date: Thu, 23 Oct 2025 19:20:34 -0400 Subject: [PATCH 18/34] Attempt to fix the toml --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index a8fa807..aef63d1 100644 --- a/Project.toml +++ b/Project.toml @@ -10,6 +10,7 @@ BackendSelection = "680c2d7c-f67a-4cc9-ae9c-da132b1447a5" DataGraphs = "b5a273c3-7e6c-41f6-98bd-8d7f1525a36a" Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" +ITensorBase = "4795dd04-0d67-49bb-8f44-b89c448a1dc7" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" NamedDimsArrays = "60cbd0c0-df58-4cb7-918c-6f5607b73fde" @@ -21,7 +22,6 @@ TypeParameterAccessors = "7e5a90cf-f82e-492e-a09b-e3e26432c138" WrappedUnions = "325db55a-9c6c-5b90-b1a2-ec87e7a38c44" [weakdeps] -ITensorBase = "4795dd04-0d67-49bb-8f44-b89c448a1dc7" TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" [extensions] From 1fb1ea7bd669bf348c851666239bb726605ce1f5 Mon Sep 17 00:00:00 2001 From: Joseph Tindall <51231103+JoeyT1994@users.noreply.github.com> Date: Thu, 23 Oct 2025 19:23:50 -0400 Subject: [PATCH 19/34] Update ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl Co-authored-by: Matt Fishman --- .../ITensorNetworksNextTensorOperationsExt.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl b/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl index 836c2bd..acec9fc 100644 --- a/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl +++ b/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl @@ -1,7 +1,7 @@ module ITensorNetworksNextTensorOperationsExt using BackendSelection: @Algorithm_str, Algorithm -using ITensorBase: inds +using NamedDimsArrays: inds using ITensorNetworksNext: ITensorNetworksNext using ITensorNetworksNext.LazyNamedDimsArrays: nested_array_to_lazy_multiply using TensorOperations: TensorOperations, optimaltree From e02619051ed98a2ffbb4140f3d4c10180e384083 Mon Sep 17 00:00:00 2001 From: Joey Date: Thu, 23 Oct 2025 19:25:29 -0400 Subject: [PATCH 20/34] ITensorBase back to weak dep --- Project.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index aef63d1..3f4f7d2 100644 --- a/Project.toml +++ b/Project.toml @@ -10,7 +10,6 @@ BackendSelection = "680c2d7c-f67a-4cc9-ae9c-da132b1447a5" DataGraphs = "b5a273c3-7e6c-41f6-98bd-8d7f1525a36a" Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" -ITensorBase = "4795dd04-0d67-49bb-8f44-b89c448a1dc7" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" NamedDimsArrays = "60cbd0c0-df58-4cb7-918c-6f5607b73fde" @@ -22,6 +21,7 @@ TypeParameterAccessors = "7e5a90cf-f82e-492e-a09b-e3e26432c138" WrappedUnions = "325db55a-9c6c-5b90-b1a2-ec87e7a38c44" [weakdeps] +ITensorBase = "4795dd04-0d67-49bb-8f44-b89c448a1dc7" TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" [extensions] @@ -34,7 +34,6 @@ BackendSelection = "0.1.6" DataGraphs = "0.2.7" Dictionaries = "0.4.5" Graphs = "1.13.1" -ITensorBase = "0.3" LinearAlgebra = "1.10" MacroTools = "0.5.16" NamedDimsArrays = "0.8" From 3ddc3c212d1695c6737217afd46dae34c04c30a4 Mon Sep 17 00:00:00 2001 From: Joseph Tindall <51231103+JoeyT1994@users.noreply.github.com> Date: Thu, 23 Oct 2025 19:32:09 -0400 Subject: [PATCH 21/34] Update src/lazynameddimsarrays.jl Co-authored-by: Matt Fishman --- src/lazynameddimsarrays.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lazynameddimsarrays.jl b/src/lazynameddimsarrays.jl index 7077f43..3056cb3 100644 --- a/src/lazynameddimsarrays.jl +++ b/src/lazynameddimsarrays.jl @@ -417,11 +417,11 @@ Base.:*(a::SymbolicNamedDimsArray, b::SymbolicNamedDimsArray) = lazy(a) * lazy(b Base.:*(a::SymbolicNamedDimsArray, b::LazyNamedDimsArray) = lazy(a) * b Base.:*(a::LazyNamedDimsArray, b::SymbolicNamedDimsArray) = a * lazy(b) -function nested_array_to_lazy_multiply(arr) - if arr isa AbstractVector - return mapreduce(x -> nested_array_to_lazy_multiply(x), *, arr) +function contraction_sequence_to_expr(seq) + if seq isa AbstractVector + return prod(contraction_sequence_to_expr, seq) else - return symnameddims.(arr) + return symnameddims(seq) end end From f3be6c5a57414f0d84444383ef06a62259b63a17 Mon Sep 17 00:00:00 2001 From: Joey Date: Thu, 23 Oct 2025 19:52:13 -0400 Subject: [PATCH 22/34] Updates --- Project.toml | 1 - .../ITensorNetworksNextTensorOperationsExt.jl | 5 ++--- src/contractnetwork.jl | 19 ++++++++++++------- src/lazynameddimsarrays.jl | 8 -------- 4 files changed, 14 insertions(+), 19 deletions(-) diff --git a/Project.toml b/Project.toml index 3f4f7d2..3e7c0a8 100644 --- a/Project.toml +++ b/Project.toml @@ -21,7 +21,6 @@ TypeParameterAccessors = "7e5a90cf-f82e-492e-a09b-e3e26432c138" WrappedUnions = "325db55a-9c6c-5b90-b1a2-ec87e7a38c44" [weakdeps] -ITensorBase = "4795dd04-0d67-49bb-8f44-b89c448a1dc7" TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" [extensions] diff --git a/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl b/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl index acec9fc..f3b90bf 100644 --- a/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl +++ b/ext/ITensorNetworksNextTensorOperationsExt/ITensorNetworksNextTensorOperationsExt.jl @@ -2,8 +2,7 @@ module ITensorNetworksNextTensorOperationsExt using BackendSelection: @Algorithm_str, Algorithm using NamedDimsArrays: inds -using ITensorNetworksNext: ITensorNetworksNext -using ITensorNetworksNext.LazyNamedDimsArrays: nested_array_to_lazy_multiply +using ITensorNetworksNext: ITensorNetworksNext, contraction_sequence_to_expr using TensorOperations: TensorOperations, optimaltree function ITensorNetworksNext.contraction_sequence(::Algorithm"optimal", tn::Vector{<:AbstractArray}) @@ -11,7 +10,7 @@ function ITensorNetworksNext.contraction_sequence(::Algorithm"optimal", tn::Vect #Converting dims to Float64 to minimize overflow issues inds_to_dims = Dict(i => Float64(length(i)) for i in unique(reduce(vcat, network))) seq, _ = optimaltree(network, inds_to_dims) - return nested_array_to_lazy_multiply(seq) + return contraction_sequence_to_expr(seq) end end diff --git a/src/contractnetwork.jl b/src/contractnetwork.jl index 7e47e3b..949ab24 100644 --- a/src/contractnetwork.jl +++ b/src/contractnetwork.jl @@ -1,9 +1,7 @@ using BackendSelection: @Algorithm_str, Algorithm -using ITensorNetworksNext.LazyNamedDimsArrays: nested_array_to_lazy_multiply, substitute_lazy, materialize, lazy, +using ITensorNetworksNext.LazyNamedDimsArrays: substitute, materialize, lazy, symnameddims -default_contract_alg = nothing - #Algorithmic defaults default_sequence(::Algorithm"exact") = "leftassociative" function set_default_kwargs(alg::Algorithm"exact") @@ -11,8 +9,16 @@ function set_default_kwargs(alg::Algorithm"exact") return Algorithm("exact"; sequence) end +function contraction_sequence_to_expr(seq) + if seq isa AbstractVector + return prod(contraction_sequence_to_expr, seq) + else + return symnameddims(seq) + end +end + function contraction_sequence(::Algorithm"leftassociative", tn::Vector{<:AbstractArray}) - return nested_array_to_lazy_multiply(collect.(1:length(tn))) + return contraction_sequence_to_expr(collect.(1:length(tn))) end function contraction_sequence(tn::Vector{<:AbstractArray}; alg = default_sequence_alg) @@ -21,7 +27,7 @@ end function contractnetwork(alg::Algorithm"exact", tn::Vector{<:AbstractArray}) contract_sequence = isa(alg.sequence, String) ? contraction_sequence(tn; alg = alg.sequence) : sequence - contract_sequence = substitute_lazy(contract_sequence, Dict(symnameddims(i) => lazy(tn[i]) for i in 1:length(tn))) + contract_sequence = substitute(contract_sequence, Dict(symnameddims(i) => lazy(tn[i]) for i in 1:length(tn))) return materialize(contract_sequence) end @@ -29,7 +35,6 @@ function contractnetwork(alg::Algorithm"exact", tn::AbstractTensorNetwork) return contractnetwork(alg, [tn[v] for v in vertices(tn)]) end -function contractnetwork(tn::Union{AbstractTensorNetwork, Vector{<:AbstractArray}}; alg = default_contract_alg, kwargs...) - alg == nothing && error("Must specify an algorithm to contract the network with") +function contractnetwork(tn; alg, kwargs...) return contractnetwork(set_default_kwargs(Algorithm(alg; kwargs...)), tn) end diff --git a/src/lazynameddimsarrays.jl b/src/lazynameddimsarrays.jl index 3056cb3..23e0679 100644 --- a/src/lazynameddimsarrays.jl +++ b/src/lazynameddimsarrays.jl @@ -417,12 +417,4 @@ Base.:*(a::SymbolicNamedDimsArray, b::SymbolicNamedDimsArray) = lazy(a) * lazy(b Base.:*(a::SymbolicNamedDimsArray, b::LazyNamedDimsArray) = lazy(a) * b Base.:*(a::LazyNamedDimsArray, b::SymbolicNamedDimsArray) = a * lazy(b) -function contraction_sequence_to_expr(seq) - if seq isa AbstractVector - return prod(contraction_sequence_to_expr, seq) - else - return symnameddims(seq) - end -end - end From 744b28322c1348a33b4d4b4d101d7dcb650d07e9 Mon Sep 17 00:00:00 2001 From: Joey Date: Thu, 23 Oct 2025 19:54:49 -0400 Subject: [PATCH 23/34] Updates --- Project.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Project.toml b/Project.toml index 3e7c0a8..d8bfedc 100644 --- a/Project.toml +++ b/Project.toml @@ -40,4 +40,7 @@ NamedGraphs = "0.6.9, 0.7" SimpleTraits = "0.9.5" SplitApplyCombine = "1.2.3" TensorOperations = "5.3.1" +TermInterface = "2" +TypeParameterAccessors = "0.4.4" +WrappedUnions = "0.3" julia = "1.10" From 28b33ff4df575795ad826054880547afeee4748e Mon Sep 17 00:00:00 2001 From: Joey Date: Thu, 23 Oct 2025 19:55:20 -0400 Subject: [PATCH 24/34] Updates --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index d8bfedc..75a8c10 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "ITensorNetworksNext" uuid = "302f2e75-49f0-4526-aef7-d8ba550cb06c" -version = "0.1.10" authors = ["ITensor developers and contributors"] +version = "0.1.10" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" From 8c95173d1969d90084de24c156a2fd7f51847b58 Mon Sep 17 00:00:00 2001 From: Joey Date: Thu, 23 Oct 2025 20:42:10 -0400 Subject: [PATCH 25/34] Fix Bug --- src/contractnetwork.jl | 6 +++--- test/test_contractnetwork.jl | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/contractnetwork.jl b/src/contractnetwork.jl index 949ab24..5493f01 100644 --- a/src/contractnetwork.jl +++ b/src/contractnetwork.jl @@ -1,6 +1,6 @@ using BackendSelection: @Algorithm_str, Algorithm using ITensorNetworksNext.LazyNamedDimsArrays: substitute, materialize, lazy, - symnameddims + symnameddims, substitute_lazy #Algorithmic defaults default_sequence(::Algorithm"exact") = "leftassociative" @@ -18,7 +18,7 @@ function contraction_sequence_to_expr(seq) end function contraction_sequence(::Algorithm"leftassociative", tn::Vector{<:AbstractArray}) - return contraction_sequence_to_expr(collect.(1:length(tn))) + return contraction_sequence_to_expr(collect(1:length(tn))) end function contraction_sequence(tn::Vector{<:AbstractArray}; alg = default_sequence_alg) @@ -27,7 +27,7 @@ end function contractnetwork(alg::Algorithm"exact", tn::Vector{<:AbstractArray}) contract_sequence = isa(alg.sequence, String) ? contraction_sequence(tn; alg = alg.sequence) : sequence - contract_sequence = substitute(contract_sequence, Dict(symnameddims(i) => lazy(tn[i]) for i in 1:length(tn))) + contract_sequence = substitute_lazy(contract_sequence, Dict(symnameddims(i) => lazy(tn[i]) for i in 1:length(tn))) return materialize(contract_sequence) end diff --git a/test/test_contractnetwork.jl b/test/test_contractnetwork.jl index ff7e061..7c5f95e 100644 --- a/test/test_contractnetwork.jl +++ b/test/test_contractnetwork.jl @@ -3,7 +3,7 @@ using NamedGraphs.GraphsExtensions: arranged_edges, incident_edges using NamedGraphs.NamedGraphGenerators: named_grid using ITensorBase: Index, ITensor using ITensorNetworksNext: - TensorNetwork, linkinds, siteinds, contractnetwork, contraction_sequence, symnameddims, lazy, substitute_lazy, materialize + TensorNetwork, linkinds, siteinds, contractnetwork using TensorOperations: TensorOperations using Test: @test, @testset From 3ff8f30cfc00c678ca7dd84131299e38f9e9650a Mon Sep 17 00:00:00 2001 From: Joseph Tindall <51231103+JoeyT1994@users.noreply.github.com> Date: Fri, 24 Oct 2025 15:04:48 -0400 Subject: [PATCH 26/34] Update src/contractnetwork.jl Co-authored-by: Matt Fishman --- src/contractnetwork.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contractnetwork.jl b/src/contractnetwork.jl index 5493f01..6b19fb7 100644 --- a/src/contractnetwork.jl +++ b/src/contractnetwork.jl @@ -1,6 +1,6 @@ using BackendSelection: @Algorithm_str, Algorithm using ITensorNetworksNext.LazyNamedDimsArrays: substitute, materialize, lazy, - symnameddims, substitute_lazy + symnameddims #Algorithmic defaults default_sequence(::Algorithm"exact") = "leftassociative" From 25e8b1f001f4955219a1b9f5fe5cd139ae380470 Mon Sep 17 00:00:00 2001 From: Joseph Tindall <51231103+JoeyT1994@users.noreply.github.com> Date: Fri, 24 Oct 2025 15:04:57 -0400 Subject: [PATCH 27/34] Update src/contractnetwork.jl Co-authored-by: Matt Fishman --- src/contractnetwork.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contractnetwork.jl b/src/contractnetwork.jl index 6b19fb7..b7c4113 100644 --- a/src/contractnetwork.jl +++ b/src/contractnetwork.jl @@ -18,7 +18,7 @@ function contraction_sequence_to_expr(seq) end function contraction_sequence(::Algorithm"leftassociative", tn::Vector{<:AbstractArray}) - return contraction_sequence_to_expr(collect(1:length(tn))) + return prod(symnameddims, 1:length(tn)) end function contraction_sequence(tn::Vector{<:AbstractArray}; alg = default_sequence_alg) From a4b02242a3a182048b5716b6f3033e57f975b434 Mon Sep 17 00:00:00 2001 From: Joseph Tindall <51231103+JoeyT1994@users.noreply.github.com> Date: Fri, 24 Oct 2025 15:05:06 -0400 Subject: [PATCH 28/34] Update src/contractnetwork.jl Co-authored-by: Matt Fishman --- src/contractnetwork.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contractnetwork.jl b/src/contractnetwork.jl index b7c4113..228131c 100644 --- a/src/contractnetwork.jl +++ b/src/contractnetwork.jl @@ -27,7 +27,7 @@ end function contractnetwork(alg::Algorithm"exact", tn::Vector{<:AbstractArray}) contract_sequence = isa(alg.sequence, String) ? contraction_sequence(tn; alg = alg.sequence) : sequence - contract_sequence = substitute_lazy(contract_sequence, Dict(symnameddims(i) => lazy(tn[i]) for i in 1:length(tn))) + contract_sequence = substitute(contract_sequence, Dict(symnameddims(i) => lazy(tn[i]) for i in 1:length(tn))) return materialize(contract_sequence) end From bbe0bc0e8f8dac3721636af8e1a7818227d36ff1 Mon Sep 17 00:00:00 2001 From: Joey Date: Fri, 24 Oct 2025 15:15:43 -0400 Subject: [PATCH 29/34] Have sequence alg vs sequence --- src/contractnetwork.jl | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/contractnetwork.jl b/src/contractnetwork.jl index 228131c..230d242 100644 --- a/src/contractnetwork.jl +++ b/src/contractnetwork.jl @@ -3,10 +3,12 @@ using ITensorNetworksNext.LazyNamedDimsArrays: substitute, materialize, lazy, symnameddims #Algorithmic defaults -default_sequence(::Algorithm"exact") = "leftassociative" +default_sequence_alg(::Algorithm"exact") = "leftassociative" +default_sequence(::Algorithm"exact") = nothing function set_default_kwargs(alg::Algorithm"exact") - sequence = get(alg, :sequence, default_sequence(alg)) - return Algorithm("exact"; sequence) + sequence = get(alg, :sequence, nothing) + sequence_alg = get(alg, :sequence_alg, default_sequence_alg(alg)) + return Algorithm("exact"; sequence, sequence_alg) end function contraction_sequence_to_expr(seq) @@ -26,9 +28,14 @@ function contraction_sequence(tn::Vector{<:AbstractArray}; alg = default_sequenc end function contractnetwork(alg::Algorithm"exact", tn::Vector{<:AbstractArray}) - contract_sequence = isa(alg.sequence, String) ? contraction_sequence(tn; alg = alg.sequence) : sequence - contract_sequence = substitute(contract_sequence, Dict(symnameddims(i) => lazy(tn[i]) for i in 1:length(tn))) - return materialize(contract_sequence) + if haskey(alg, :sequence) && !isnothing(alg.sequence) + sequence = alg.sequence + else + sequence = contraction_sequence(tn; alg.sequence_alg) + end + + sequence = substitute(sequence, Dict(symnameddims(i) => lazy(tn[i]) for i in 1:length(tn))) + return materialize(sequence) end function contractnetwork(alg::Algorithm"exact", tn::AbstractTensorNetwork) From 39c4bc6cdfa0aa61feeae3be896ffc09f92b292b Mon Sep 17 00:00:00 2001 From: Joey Date: Fri, 24 Oct 2025 15:16:03 -0400 Subject: [PATCH 30/34] Have sequence alg vs sequence --- test/test_contractnetwork.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_contractnetwork.jl b/test/test_contractnetwork.jl index 7c5f95e..4b125f7 100644 --- a/test/test_contractnetwork.jl +++ b/test/test_contractnetwork.jl @@ -15,8 +15,8 @@ using Test: @test, @testset C = ITensor([5.0, 1.0], j) D = ITensor([-2.0, 3.0, 4.0, 5.0, 1.0], k) - ABCD_1 = contractnetwork([A, B, C, D]; alg = "exact", sequence = "leftassociative") - ABCD_2 = contractnetwork([A, B, C, D]; alg = "exact", sequence = "optimal") + ABCD_1 = contractnetwork([A, B, C, D]; alg = "exact", sequence_alg = "leftassociative") + ABCD_2 = contractnetwork([A, B, C, D]; alg = "exact", sequence_alg = "optimal") @test ABCD_1 == ABCD_2 end @@ -31,8 +31,8 @@ using Test: @test, @testset return randn(Tuple(is)) end - z1 = contractnetwork(tn; alg = "exact", sequence = "optimal")[] - z2 = contractnetwork(tn; alg = "exact", sequence = "leftassociative")[] + z1 = contractnetwork(tn; alg = "exact", sequence_alg = "optimal")[] + z2 = contractnetwork(tn; alg = "exact", sequence_alg = "leftassociative")[] @test abs(z1 - z2) / abs(z1) <= 1.0e3 * eps(Float64) end From fd1c7e157fa1e2da184d804eeb30ee29a01cc62a Mon Sep 17 00:00:00 2001 From: Joey Date: Fri, 24 Oct 2025 15:17:25 -0400 Subject: [PATCH 31/34] Fix typo --- src/contractnetwork.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/contractnetwork.jl b/src/contractnetwork.jl index 230d242..95d07ea 100644 --- a/src/contractnetwork.jl +++ b/src/contractnetwork.jl @@ -23,8 +23,8 @@ function contraction_sequence(::Algorithm"leftassociative", tn::Vector{<:Abstrac return prod(symnameddims, 1:length(tn)) end -function contraction_sequence(tn::Vector{<:AbstractArray}; alg = default_sequence_alg) - return contraction_sequence(Algorithm(alg), tn) +function contraction_sequence(tn::Vector{<:AbstractArray}; sequence_alg = default_sequence_alg) + return contraction_sequence(Algorithm(sequence_alg), tn) end function contractnetwork(alg::Algorithm"exact", tn::Vector{<:AbstractArray}) From 25b2cf64f4eaf481e0e8fc191ba81f55d673302d Mon Sep 17 00:00:00 2001 From: Joey Date: Fri, 24 Oct 2025 15:21:51 -0400 Subject: [PATCH 32/34] Fix typo --- src/contractnetwork.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contractnetwork.jl b/src/contractnetwork.jl index 95d07ea..fed4010 100644 --- a/src/contractnetwork.jl +++ b/src/contractnetwork.jl @@ -28,7 +28,7 @@ function contraction_sequence(tn::Vector{<:AbstractArray}; sequence_alg = defaul end function contractnetwork(alg::Algorithm"exact", tn::Vector{<:AbstractArray}) - if haskey(alg, :sequence) && !isnothing(alg.sequence) + if !isnothing(alg.sequence) sequence = alg.sequence else sequence = contraction_sequence(tn; alg.sequence_alg) From 7f27cdb5673bf7114cce38621e9d72143e9c2755 Mon Sep 17 00:00:00 2001 From: Joey Date: Fri, 24 Oct 2025 17:26:01 -0400 Subject: [PATCH 33/34] Fix default --- src/contractnetwork.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/contractnetwork.jl b/src/contractnetwork.jl index fed4010..d91658a 100644 --- a/src/contractnetwork.jl +++ b/src/contractnetwork.jl @@ -23,7 +23,7 @@ function contraction_sequence(::Algorithm"leftassociative", tn::Vector{<:Abstrac return prod(symnameddims, 1:length(tn)) end -function contraction_sequence(tn::Vector{<:AbstractArray}; sequence_alg = default_sequence_alg) +function contraction_sequence(tn::Vector{<:AbstractArray}; sequence_alg = default_sequence_alg(Algorithm("exact"))) return contraction_sequence(Algorithm(sequence_alg), tn) end @@ -31,7 +31,7 @@ function contractnetwork(alg::Algorithm"exact", tn::Vector{<:AbstractArray}) if !isnothing(alg.sequence) sequence = alg.sequence else - sequence = contraction_sequence(tn; alg.sequence_alg) + sequence = contraction_sequence(tn; sequence_alg = alg.sequence_alg) end sequence = substitute(sequence, Dict(symnameddims(i) => lazy(tn[i]) for i in 1:length(tn))) From 5a7dc37f8b672b0f19864d55e5c09f9e3beddbae Mon Sep 17 00:00:00 2001 From: Joey Date: Sun, 26 Oct 2025 10:22:52 -0400 Subject: [PATCH 34/34] Contractnetwork -> contract_network --- Project.toml | 2 +- src/ITensorNetworksNext.jl | 2 +- src/{contractnetwork.jl => contract_network.jl} | 10 +++++----- ...t_contractnetwork.jl => test_contract_network.jl} | 12 ++++++------ 4 files changed, 13 insertions(+), 13 deletions(-) rename src/{contractnetwork.jl => contract_network.jl} (79%) rename test/{test_contractnetwork.jl => test_contract_network.jl} (69%) diff --git a/Project.toml b/Project.toml index 75a8c10..42df730 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "ITensorNetworksNext" uuid = "302f2e75-49f0-4526-aef7-d8ba550cb06c" authors = ["ITensor developers and contributors"] -version = "0.1.10" +version = "0.1.11" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" diff --git a/src/ITensorNetworksNext.jl b/src/ITensorNetworksNext.jl index f8deb49..b59c3bd 100644 --- a/src/ITensorNetworksNext.jl +++ b/src/ITensorNetworksNext.jl @@ -3,6 +3,6 @@ module ITensorNetworksNext include("lazynameddimsarrays.jl") include("abstracttensornetwork.jl") include("tensornetwork.jl") -include("contractnetwork.jl") +include("contract_network.jl") end diff --git a/src/contractnetwork.jl b/src/contract_network.jl similarity index 79% rename from src/contractnetwork.jl rename to src/contract_network.jl index d91658a..67d69e0 100644 --- a/src/contractnetwork.jl +++ b/src/contract_network.jl @@ -27,7 +27,7 @@ function contraction_sequence(tn::Vector{<:AbstractArray}; sequence_alg = defaul return contraction_sequence(Algorithm(sequence_alg), tn) end -function contractnetwork(alg::Algorithm"exact", tn::Vector{<:AbstractArray}) +function contract_network(alg::Algorithm"exact", tn::Vector{<:AbstractArray}) if !isnothing(alg.sequence) sequence = alg.sequence else @@ -38,10 +38,10 @@ function contractnetwork(alg::Algorithm"exact", tn::Vector{<:AbstractArray}) return materialize(sequence) end -function contractnetwork(alg::Algorithm"exact", tn::AbstractTensorNetwork) - return contractnetwork(alg, [tn[v] for v in vertices(tn)]) +function contract_network(alg::Algorithm"exact", tn::AbstractTensorNetwork) + return contract_network(alg, [tn[v] for v in vertices(tn)]) end -function contractnetwork(tn; alg, kwargs...) - return contractnetwork(set_default_kwargs(Algorithm(alg; kwargs...)), tn) +function contract_network(tn; alg, kwargs...) + return contract_network(set_default_kwargs(Algorithm(alg; kwargs...)), tn) end diff --git a/test/test_contractnetwork.jl b/test/test_contract_network.jl similarity index 69% rename from test/test_contractnetwork.jl rename to test/test_contract_network.jl index 4b125f7..2b7b945 100644 --- a/test/test_contractnetwork.jl +++ b/test/test_contract_network.jl @@ -3,11 +3,11 @@ using NamedGraphs.GraphsExtensions: arranged_edges, incident_edges using NamedGraphs.NamedGraphGenerators: named_grid using ITensorBase: Index, ITensor using ITensorNetworksNext: - TensorNetwork, linkinds, siteinds, contractnetwork + TensorNetwork, linkinds, siteinds, contract_network using TensorOperations: TensorOperations using Test: @test, @testset -@testset "ContractNetwork" begin +@testset "contract_network" begin @testset "Contract Vectors of ITensors" begin i, j, k = Index(2), Index(2), Index(5) A = ITensor([1.0 1.0; 0.5 1.0], i, j) @@ -15,8 +15,8 @@ using Test: @test, @testset C = ITensor([5.0, 1.0], j) D = ITensor([-2.0, 3.0, 4.0, 5.0, 1.0], k) - ABCD_1 = contractnetwork([A, B, C, D]; alg = "exact", sequence_alg = "leftassociative") - ABCD_2 = contractnetwork([A, B, C, D]; alg = "exact", sequence_alg = "optimal") + ABCD_1 = contract_network([A, B, C, D]; alg = "exact", sequence_alg = "leftassociative") + ABCD_2 = contract_network([A, B, C, D]; alg = "exact", sequence_alg = "optimal") @test ABCD_1 == ABCD_2 end @@ -31,8 +31,8 @@ using Test: @test, @testset return randn(Tuple(is)) end - z1 = contractnetwork(tn; alg = "exact", sequence_alg = "optimal")[] - z2 = contractnetwork(tn; alg = "exact", sequence_alg = "leftassociative")[] + z1 = contract_network(tn; alg = "exact", sequence_alg = "optimal")[] + z2 = contract_network(tn; alg = "exact", sequence_alg = "leftassociative")[] @test abs(z1 - z2) / abs(z1) <= 1.0e3 * eps(Float64) end