From c8459471e67c4163539808b8d432032bdde93838 Mon Sep 17 00:00:00 2001 From: Joey Date: Fri, 13 Sep 2024 10:19:49 -0400 Subject: [PATCH 01/10] Blah --- examples/test.jl | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 examples/test.jl diff --git a/examples/test.jl b/examples/test.jl new file mode 100644 index 00000000..6bf1bfcf --- /dev/null +++ b/examples/test.jl @@ -0,0 +1,21 @@ +using ITensorNetworks: IndsNetwork, siteinds, ttn +using ITensorNetworks.ModelHamiltonians: ising +using ITensors: Index, OpSum, terms, sites +using NamedGraphs.NamedGraphGenerators: named_grid +using NamedGraphs.GraphsExtensions: rem_vertex + +function filter_terms(H, verts) + H_new = OpSum() + for term in terms(H) + if isempty(filter(v -> v ∈ verts, sites(term))) + H_new += term + end + end + return H_new +end + +g = named_grid((8,1)) +s = siteinds("S=1/2", g) +H = ising(s) +H_mod = filter_terms(H, [(4,1)]) +ttno = ttn(H_mod, s) \ No newline at end of file From 6ff0cd572c947e9b1ed3642e690b43233277beb0 Mon Sep 17 00:00:00 2001 From: Joey Date: Thu, 17 Oct 2024 14:56:22 +0100 Subject: [PATCH 02/10] Bug fix in current ortho. Change test --- .../alternating_update/region_update.jl | 45 ++++++++----------- .../test_solvers/test_dmrg.jl | 12 ++--- 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/src/solvers/alternating_update/region_update.jl b/src/solvers/alternating_update/region_update.jl index b92adc8c..97241c20 100644 --- a/src/solvers/alternating_update/region_update.jl +++ b/src/solvers/alternating_update/region_update.jl @@ -7,36 +7,27 @@ function current_ortho(sweep_plan, which_region_update) if !isa(region, AbstractEdge) && length(region) == 1 return only(current_verts) end - if which_region_update == length(regions) - # look back by one should be sufficient, but may be brittle? - overlapping_vertex = only( - intersect(current_verts, support(regions[which_region_update - 1])) - ) - return overlapping_vertex - else - # look forward - other_regions = filter( - x -> !(issetequal(x, current_verts)), support.(regions[(which_region_update + 1):end]) + # look forward + other_regions = filter( + x -> !(issetequal(x, current_verts)), support.(regions[(which_region_update + 1):end]) + ) + # find the first region that has overlapping support with current region + ind = findfirst(x -> !isempty(intersect(support(x), support(region))), other_regions) + if isnothing(ind) + # look backward + other_regions = reverse( + filter( + x -> !(issetequal(x, current_verts)), support.(regions[1:(which_region_update - 1)]) + ), ) - # find the first region that has overlapping support with current region ind = findfirst(x -> !isempty(intersect(support(x), support(region))), other_regions) - if isnothing(ind) - # look backward - other_regions = reverse( - filter( - x -> !(issetequal(x, current_verts)), - support.(regions[1:(which_region_update - 1)]), - ), - ) - ind = findfirst(x -> !isempty(intersect(support(x), support(region))), other_regions) - end - @assert !isnothing(ind) - future_verts = union(support(other_regions[ind])) - # return ortho_ceter as the vertex in current region that does not overlap with following one - overlapping_vertex = intersect(current_verts, future_verts) - nonoverlapping_vertex = only(setdiff(current_verts, overlapping_vertex)) - return nonoverlapping_vertex end + @assert !isnothing(ind) + future_verts = union(support(other_regions[ind])) + # return ortho_ceter as the vertex in current region that does not overlap with following one + overlapping_vertex = intersect(current_verts, future_verts) + nonoverlapping_vertex = only(setdiff(current_verts, overlapping_vertex)) + return nonoverlapping_vertex end function region_update( diff --git a/test/test_treetensornetworks/test_solvers/test_dmrg.jl b/test/test_treetensornetworks/test_solvers/test_dmrg.jl index cf8a1caf..004ec561 100644 --- a/test/test_treetensornetworks/test_solvers/test_dmrg.jl +++ b/test/test_treetensornetworks/test_solvers/test_dmrg.jl @@ -1,7 +1,7 @@ @eval module $(gensym()) using DataGraphs: edge_data, vertex_data using Dictionaries: Dictionary -using Graphs: nv, vertices +using Graphs: nv, vertices, uniform_tree using ITensorMPS: ITensorMPS using ITensorNetworks: ITensorNetworks, @@ -19,6 +19,7 @@ using ITensorNetworks.ITensorsExtensions: replace_vertices using ITensorNetworks.ModelHamiltonians: ModelHamiltonians using ITensors: ITensors using KrylovKit: eigsolve +using NamedGraphs: NamedGraph, rename_vertices using NamedGraphs.NamedGraphGenerators: named_comb_tree using Observers: observer using StableRNGs: StableRNG @@ -313,11 +314,12 @@ end nsites = 2 nsweeps = 10 - c = named_comb_tree((3, 2)) - s = siteinds("S=1/2", c) - os = ModelHamiltonians.heisenberg(c) - H = ttn(os, s) rng = StableRNG(1234) + g = NamedGraph(uniform_tree(10)) + g = rename_vertices(v -> (v, 1), g) + s = siteinds("S=1/2", g) + os = ModelHamiltonians.heisenberg(g) + H = ttn(os, s) psi = random_ttn(rng, s; link_space=5) e, psi = dmrg(H, psi; nsweeps, maxdim, nsites) From d0967229e2c9c0d645ad110bb3944566b52d3385 Mon Sep 17 00:00:00 2001 From: Joey Date: Tue, 26 Nov 2024 13:50:41 -0500 Subject: [PATCH 03/10] Fix bug --- src/abstractitensornetwork.jl | 40 ++++++++++++------- .../abstracttreetensornetwork.jl | 12 ++++-- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/abstractitensornetwork.jl b/src/abstractitensornetwork.jl index fc0edce4..afdbbb41 100644 --- a/src/abstractitensornetwork.jl +++ b/src/abstractitensornetwork.jl @@ -19,6 +19,7 @@ using Graphs: using ITensors: ITensors, ITensor, + @Algorithm_str, addtags, combiner, commoninds, @@ -44,7 +45,7 @@ using MacroTools: @capture using NamedGraphs: NamedGraphs, NamedGraph, not_implemented, steiner_tree using NamedGraphs.GraphsExtensions: ⊔, directed_graph, incident_edges, rename_vertices, vertextype -using NDTensors: NDTensors, dim +using NDTensors: NDTensors, dim, Algorithm using SplitApplyCombine: flatten abstract type AbstractITensorNetwork{V} <: AbstractDataGraph{V,ITensor,ITensor} end @@ -585,17 +586,22 @@ function LinearAlgebra.factorize(tn::AbstractITensorNetwork, edge::Pair; kwargs. end # For ambiguity error; TODO: decide whether to use graph mutating methods when resulting graph is unchanged? -function orthogonalize_walk(tn::AbstractITensorNetwork, edge::AbstractEdge; kwargs...) - return orthogonalize_walk(tn, [edge]; kwargs...) +function gauge_walk( + alg::Algorithm, tn::AbstractITensorNetwork, edge::AbstractEdge; kwargs... +) + return gauge_walk(tn, [edge]; kwargs...) end -function orthogonalize_walk(tn::AbstractITensorNetwork, edge::Pair; kwargs...) - return orthogonalize_walk(tn, edgetype(tn)(edge); kwargs...) +function gauge_walk(alg::Algorithm, tn::AbstractITensorNetwork, edge::Pair; kwargs...) + return gauge_walk(alg::Algorithm, tn, edgetype(tn)(edge); kwargs...) end # For ambiguity error; TODO: decide whether to use graph mutating methods when resulting graph is unchanged? -function orthogonalize_walk( - tn::AbstractITensorNetwork, edges::Vector{<:AbstractEdge}; kwargs... +function gauge_walk( + alg::Algorithm"orthogonalize", + tn::AbstractITensorNetwork, + edges::Vector{<:AbstractEdge}; + kwargs..., ) # tn = factorize(tn, edge; kwargs...) # # TODO: Implement as `only(common_neighbors(tn, src(edge), dst(edge)))` @@ -612,22 +618,28 @@ function orthogonalize_walk( return tn end -function orthogonalize_walk(tn::AbstractITensorNetwork, edges::Vector{<:Pair}; kwargs...) - return orthogonalize_walk(tn, edgetype(tn).(edges); kwargs...) +function gauge_walk( + alg::Algorithm, tn::AbstractITensorNetwork, edges::Vector{<:Pair}; kwargs... +) + return gauge_walk(alg, tn, edgetype(tn).(edges); kwargs...) end -# Orthogonalize an ITensorNetwork towards a region, treating +# Gauge a ITensorNetwork towards a region, treating # the network as a tree spanned by a spanning tree. -function tree_orthogonalize(ψ::AbstractITensorNetwork, region::Vector) +function tree_gauge(alg::Algorithm, ψ::AbstractITensorNetwork, region::Vector) region_center = length(region) != 1 ? first(center(steiner_tree(ψ, region))) : only(region) path = post_order_dfs_edges(bfs_tree(ψ, region_center), region_center) path = filter(e -> !((src(e) ∈ region) && (dst(e) ∈ region)), path) - return orthogonalize_walk(ψ, path) + return gauge_walk(alg, ψ, path) +end + +function tree_gauge(alg::Algorithm, ψ::AbstractITensorNetwork, region) + return tree_gauge(alg, ψ, [region]) end -function tree_orthogonalize(ψ::AbstractITensorNetwork, region) - return tree_orthogonalize(ψ, [region]) +function tree_orthogonalize(ψ::AbstractITensorNetwork, region; kwargs...) + return tree_gauge(Algorithm("orthogonalize"), ψ, region; kwargs...) end # TODO: decide whether to use graph mutating methods when resulting graph is unchanged? diff --git a/src/treetensornetworks/abstracttreetensornetwork.jl b/src/treetensornetworks/abstracttreetensornetwork.jl index 8815b33f..f6c8f49f 100644 --- a/src/treetensornetworks/abstracttreetensornetwork.jl +++ b/src/treetensornetworks/abstracttreetensornetwork.jl @@ -8,7 +8,7 @@ using NamedGraphs.GraphsExtensions: a_star using NamedGraphs: namedgraph_a_star, steiner_tree using IsApprox: IsApprox, Approx -using ITensors: ITensors, @Algorithm_str, directsum, hasinds, permute, plev +using ITensors: ITensors, Algorithm, @Algorithm_str, directsum, hasinds, permute, plev using ITensorMPS: ITensorMPS, linkind, loginner, lognorm, orthogonalize using TupleTools: TupleTools @@ -35,19 +35,23 @@ function set_ortho_region(tn::AbstractTTN, new_region) return error("Not implemented") end -function ITensorMPS.orthogonalize(ttn::AbstractTTN, region::Vector; kwargs...) +function gauge(alg::Algorithm, ttn::AbstractTTN, region::Vector; kwargs...) issetequal(region, ortho_region(ttn)) && return ttn st = steiner_tree(ttn, union(region, ortho_region(ttn))) path = post_order_dfs_edges(st, first(region)) path = filter(e -> !((src(e) ∈ region) && (dst(e) ∈ region)), path) if !isempty(path) - ttn = typeof(ttn)(orthogonalize_walk(ITensorNetwork(ttn), path; kwargs...)) + ttn = typeof(ttn)(gauge_walk(alg, ITensorNetwork(ttn), path; kwargs...)) end return set_ortho_region(ttn, region) end +function gauge(alg::Algorithm, ttn::AbstractTTN, region; kwargs...) + return gauge(alg, ttn, [region]; kwargs...) +end + function ITensorMPS.orthogonalize(ttn::AbstractTTN, region; kwargs...) - return orthogonalize(ttn, [region]; kwargs...) + return gauge(Algorithm("orthogonalize"), ttn, region; kwargs...) end function tree_orthogonalize(ttn::AbstractTTN, args...; kwargs...) From 9d6c1bcb7aa8b36163df43e95b063dd9cd03761f Mon Sep 17 00:00:00 2001 From: Joey Date: Wed, 19 Mar 2025 12:07:10 -0700 Subject: [PATCH 04/10] File removed --- examples/test.jl | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 examples/test.jl diff --git a/examples/test.jl b/examples/test.jl deleted file mode 100644 index 6bf1bfcf..00000000 --- a/examples/test.jl +++ /dev/null @@ -1,21 +0,0 @@ -using ITensorNetworks: IndsNetwork, siteinds, ttn -using ITensorNetworks.ModelHamiltonians: ising -using ITensors: Index, OpSum, terms, sites -using NamedGraphs.NamedGraphGenerators: named_grid -using NamedGraphs.GraphsExtensions: rem_vertex - -function filter_terms(H, verts) - H_new = OpSum() - for term in terms(H) - if isempty(filter(v -> v ∈ verts, sites(term))) - H_new += term - end - end - return H_new -end - -g = named_grid((8,1)) -s = siteinds("S=1/2", g) -H = ising(s) -H_mod = filter_terms(H, [(4,1)]) -ttno = ttn(H_mod, s) \ No newline at end of file From b7a27c50ee62e6cfe91c588dcc3f84db33317efd Mon Sep 17 00:00:00 2001 From: Joey Date: Fri, 25 Apr 2025 10:07:11 -0400 Subject: [PATCH 05/10] Better Form Constructor --- Project.toml | 2 +- src/formnetworks/bilinearformnetwork.jl | 14 ++++++++++--- src/gauging.jl | 6 +++++- test/test_forms.jl | 26 +++++++++++++++++++++++-- 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/Project.toml b/Project.toml index 069691c6..5fb1bec0 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "ITensorNetworks" uuid = "2919e153-833c-4bdc-8836-1ea460a35fc7" authors = ["Matthew Fishman , Joseph Tindall and contributors"] -version = "0.13.5" +version = "0.13.6" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" diff --git a/src/formnetworks/bilinearformnetwork.jl b/src/formnetworks/bilinearformnetwork.jl index 880546ab..4a6cb7f7 100644 --- a/src/formnetworks/bilinearformnetwork.jl +++ b/src/formnetworks/bilinearformnetwork.jl @@ -60,9 +60,17 @@ function BilinearFormNetwork( ) @assert issetequal(flatten_siteinds(bra), flatten_siteinds(ket)) link_space = isempty(flatten_siteinds(bra)) ? 1 : nothing - operator_inds = union_all_inds(siteinds(ket), dual_site_index_map(siteinds(ket))) - # TODO: Define and use `identity_network` here. - O = ITensorNetwork(Op("I"), operator_inds; link_space) + s = siteinds(ket) + s_mapped = dual_site_index_map(s) + operator_inds = union_all_inds(s, s_mapped) + constructor_f = + v -> + inds -> if !isempty(inds) + reduce(*, [delta(s, sm) for (s, sm) in zip(s[v], s_mapped[v])]) + else + ITensor(one(Bool)) + end + O = ITensorNetwork(constructor_f, operator_inds; link_space) return BilinearFormNetwork(O, bra, ket; dual_site_index_map, kwargs...) end diff --git a/src/gauging.jl b/src/gauging.jl index 49384ca6..7a1f2e73 100644 --- a/src/gauging.jl +++ b/src/gauging.jl @@ -134,7 +134,11 @@ function VidalITensorNetwork( if isnothing(cache!) cache! = Ref(default_norm_cache(ψ)) end - cache![] = update(cache![]; cache_update_kwargs...) + + if update_cache + cache![] = update(cache![]; cache_update_kwargs...) + end + return vidalitensornetwork_preserve_cache(ψ; cache=cache![], kwargs...) end diff --git a/test/test_forms.jl b/test/test_forms.jl index 962bc960..1a267c8e 100644 --- a/test/test_forms.jl +++ b/test/test_forms.jl @@ -1,7 +1,7 @@ @eval module $(gensym()) using DataGraphs: underlying_graph using Graphs: nv -using NamedGraphs.NamedGraphGenerators: named_grid +using NamedGraphs.NamedGraphGenerators: named_comb_tree, named_grid using ITensorNetworks: BeliefPropagationCache, BilinearFormNetwork, @@ -12,16 +12,18 @@ using ITensorNetworks: dual_index_map, environment, flatten_siteinds, + inner, ket_network, ket_vertex, operator_network, random_tensornetwork, + scalar, siteinds, state_vertices, tensornetwork, union_all_inds, update -using ITensors: contract, dag, inds, prime, random_itensor +using ITensors: Index, contract, dag, inds, prime, random_itensor, sim using LinearAlgebra: norm using StableRNGs: StableRNG using TensorOperations: TensorOperations @@ -84,5 +86,25 @@ using Test: @test, @testset ∂qf_∂v_bp = contract(∂qf_∂v_bp) ∂qf_∂v_bp /= norm(∂qf_∂v_bp) @test ∂qf_∂v_bp ≈ ∂qf_∂v + + #Test having non-uniform number of site indices per vertex + g = named_comb_tree((3, 3)) + s = siteinds("S=1/2", g) + s = union_all_inds(s, sim(s)) + s[(1, 1)] = Index[] + s[(3, 3)] = Index[first(s[(3, 3)])] + χ = 2 + rng = StableRNG(1234) + ψket = random_tensornetwork(rng, ComplexF64, s; link_space=χ) + ψbra = random_tensornetwork(rng, ComplexF64, s; link_space=χ) + + blf = BilinearFormNetwork(ψbra, ψket) + @test scalar(blf; alg="exact") ≈ inner(ψbra, ψket; alg="exact") + + lf = LinearFormNetwork(ψbra, ψket) + @test scalar(lf; alg="exact") ≈ inner(ψbra, ψket; alg="exact") + + qf = QuadraticFormNetwork(ψket) + @test scalar(qf; alg="exact") ≈ inner(ψket, ψket; alg="exact") end end From 1f0e0a3a31867527fd18ccbbac7a71ca7941055b Mon Sep 17 00:00:00 2001 From: Joey Date: Fri, 25 Apr 2025 10:16:04 -0400 Subject: [PATCH 06/10] Formatting --- src/formnetworks/bilinearformnetwork.jl | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/formnetworks/bilinearformnetwork.jl b/src/formnetworks/bilinearformnetwork.jl index 4a6cb7f7..53c27587 100644 --- a/src/formnetworks/bilinearformnetwork.jl +++ b/src/formnetworks/bilinearformnetwork.jl @@ -64,12 +64,11 @@ function BilinearFormNetwork( s_mapped = dual_site_index_map(s) operator_inds = union_all_inds(s, s_mapped) constructor_f = - v -> - inds -> if !isempty(inds) - reduce(*, [delta(s, sm) for (s, sm) in zip(s[v], s_mapped[v])]) - else - ITensor(one(Bool)) - end + v -> inds -> if !isempty(inds) + reduce(*, [delta(s, sm) for (s, sm) in zip(s[v], s_mapped[v])]) + else + ITensor(one(Bool)) + end O = ITensorNetwork(constructor_f, operator_inds; link_space) return BilinearFormNetwork(O, bra, ket; dual_site_index_map, kwargs...) end From 30b5c3481efac1bb39ebd5b5b7a7f898566fecde Mon Sep 17 00:00:00 2001 From: Joey Date: Fri, 25 Apr 2025 10:51:49 -0400 Subject: [PATCH 07/10] Disable EinExprs call to KaHyPar --- test/test_contraction_sequence.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_contraction_sequence.jl b/test/test_contraction_sequence.jl index 3ceac169..cbc55477 100644 --- a/test/test_contraction_sequence.jl +++ b/test/test_contraction_sequence.jl @@ -1,5 +1,5 @@ @eval module $(gensym()) -using EinExprs: Exhaustive, Greedy, HyPar +using EinExprs: Exhaustive, Greedy using ITensorNetworks: contraction_sequence, norm_sqr_network, random_tensornetwork, siteinds using ITensors: ITensors, contract @@ -49,9 +49,9 @@ using Test: @test, @testset Pkg.rm("KaHyPar"; io=devnull) res_kahypar_bipartite = contract(tn; sequence=seq_kahypar_bipartite)[] @test res_optimal ≈ res_kahypar_bipartite - seq_einexprs_kahypar = contraction_sequence(tn; alg="einexpr", optimizer=HyPar()) - res_einexprs_kahypar = contract(tn; sequence=seq_einexprs_kahypar)[] - @test res_einexprs_kahypar ≈ res_optimal + # seq_einexprs_kahypar = contraction_sequence(tn; alg="einexpr", optimizer=HyPar()) + # res_einexprs_kahypar = contract(tn; sequence=seq_einexprs_kahypar)[] + # @test res_einexprs_kahypar ≈ res_optimal end end end From 89a1c9118ffb576f55971053acd0f223d5d53b51 Mon Sep 17 00:00:00 2001 From: Joey Date: Fri, 25 Apr 2025 12:00:18 -0400 Subject: [PATCH 08/10] Get QNs working for the new FormConstructors --- src/ITensorNetworks.jl | 1 - src/contraction_tree_to_graph.jl | 82 ---------------------- src/formnetworks/bilinearformnetwork.jl | 2 +- test/test_contraction_sequence_to_graph.jl | 48 ------------- test/test_expect.jl | 3 +- 5 files changed, 3 insertions(+), 133 deletions(-) delete mode 100644 src/contraction_tree_to_graph.jl delete mode 100644 test/test_contraction_sequence_to_graph.jl diff --git a/src/ITensorNetworks.jl b/src/ITensorNetworks.jl index 1aa80435..78eddcfa 100644 --- a/src/ITensorNetworks.jl +++ b/src/ITensorNetworks.jl @@ -31,7 +31,6 @@ include("formnetworks/abstractformnetwork.jl") include("formnetworks/bilinearformnetwork.jl") include("formnetworks/linearformnetwork.jl") include("formnetworks/quadraticformnetwork.jl") -include("contraction_tree_to_graph.jl") include("gauging.jl") include("utils.jl") include("update_observer.jl") diff --git a/src/contraction_tree_to_graph.jl b/src/contraction_tree_to_graph.jl deleted file mode 100644 index d026376e..00000000 --- a/src/contraction_tree_to_graph.jl +++ /dev/null @@ -1,82 +0,0 @@ -using AbstractTrees: Leaves, PostOrderDFS -using Graphs: add_vertex!, dst, edges, rem_vertex!, src -using NamedGraphs: NamedDiGraph, NamedGraph -using NamedGraphs.GraphsExtensions: is_leaf_edge, root_vertex - -""" -Take a contraction sequence and return a directed graph. -""" -function contraction_sequence_to_digraph(contract_sequence) - g = NamedDiGraph() - leaves = collect(Leaves(contract_sequence)) - seq_to_v = Dict() - for seq in PostOrderDFS(contract_sequence) - if !(seq isa Array) - v = ([seq], setdiff(leaves, [seq])) - add_vertex!(g, v) - else - group1 = collect(Leaves(seq[1])) - group2 = collect(Leaves(seq[2])) - remaining_verts = setdiff(leaves, vcat(group1, group2)) - v = (group1, group2, remaining_verts) - add_vertex!(g, v) - c1 = get(seq_to_v, seq[1], nothing) - c2 = get(seq_to_v, seq[2], nothing) - add_edge!(g, v => c1) - add_edge!(g, v => c2) - end - seq_to_v[seq] = v - end - return g -end - -""" -Take a contraction_sequence and return a graphical representation of it. The leaves of the graph represent the leaves of the sequence whilst the internal_nodes of the graph -define a tripartition of the graph and thus are named as an n = 3 element tuples, which each element specifying the keys involved. -Edges connect parents/children within the contraction sequence. -""" -function contraction_sequence_to_graph(contract_sequence) - direct_g = contraction_sequence_to_digraph(contract_sequence) - g = NamedGraph(vertices(direct_g)) - for e in edges(direct_g) - add_edge!(g, e) - end - root = root_vertex(direct_g) - c1, c2 = child_vertices(direct_g, root) - rem_vertex!(g, root) - add_edge!(g, c1 => c2) - return g -end - -"""Get the vertex bi-partition that a given edge represents""" -function contraction_tree_leaf_bipartition(g::AbstractGraph, e) - if (!is_leaf_edge(g, e)) - vsrc_set, vdst_set = [Set(vni) for vni in src(e)], [Set(vni) for vni in dst(e)] - c1, c2, c3 = [src(e)[1]..., src(e)[2]...], - [src(e)[2]..., src(e)[3]...], - [src(e)[1]..., src(e)[3]...] - left_bipartition = if Set(c1) ∈ vdst_set - c1 - elseif Set(c2) ∈ vdst_set - c2 - else - c3 - end - - c1, c2, c3 = [dst(e)[1]..., dst(e)[2]...], - [dst(e)[2]..., dst(e)[3]...], - [dst(e)[1]..., dst(e)[3]...] - right_bipartition = if Set(c1) ∈ vsrc_set - c1 - elseif Set(c2) ∈ vsrc_set - c2 - else - c3 - end - else - left_bipartition = filter(vs -> Set(vs) ∈ [Set(vni) for vni in dst(e)], src(e))[1] - right_bipartition = setdiff(src(e), left_bipartition) - end - - return left_bipartition, right_bipartition -end diff --git a/src/formnetworks/bilinearformnetwork.jl b/src/formnetworks/bilinearformnetwork.jl index 53c27587..5021014a 100644 --- a/src/formnetworks/bilinearformnetwork.jl +++ b/src/formnetworks/bilinearformnetwork.jl @@ -65,7 +65,7 @@ function BilinearFormNetwork( operator_inds = union_all_inds(s, s_mapped) constructor_f = v -> inds -> if !isempty(inds) - reduce(*, [delta(s, sm) for (s, sm) in zip(s[v], s_mapped[v])]) + reduce(*, [delta(dag(s), sm) for (s, sm) in zip(s[v], s_mapped[v])]) else ITensor(one(Bool)) end diff --git a/test/test_contraction_sequence_to_graph.jl b/test/test_contraction_sequence_to_graph.jl deleted file mode 100644 index 1d4ed064..00000000 --- a/test/test_contraction_sequence_to_graph.jl +++ /dev/null @@ -1,48 +0,0 @@ -@eval module $(gensym()) -using Graphs: vertices -using ITensorNetworks: - contraction_sequence, - contraction_sequence_to_digraph, - contraction_sequence_to_graph, - contraction_tree_leaf_bipartition, - random_tensornetwork -using NamedGraphs.GraphsExtensions: - is_leaf_vertex, leaf_vertices, non_leaf_edges, root_vertex -using NamedGraphs.NamedGraphGenerators: named_grid -using StableRNGs: StableRNG -using TensorOperations: TensorOperations -using Test: @test, @testset -@testset "contraction_sequence_to_graph" begin - n = 3 - dims = (n, n) - g = named_grid(dims) - rng = StableRNG(1234) - tn = random_tensornetwork(rng, g; link_space=2) - seq = contraction_sequence(tn) - g_directed_seq = contraction_sequence_to_digraph(seq) - g_seq_leaves = leaf_vertices(g_directed_seq) - @test length(g_seq_leaves) == n * n - @test 2 * length(g_seq_leaves) - 1 == length(vertices(g_directed_seq)) - @test root_vertex(g_directed_seq)[3] == [] - - g_seq = contraction_sequence_to_graph(seq) - @test length(g_seq_leaves) == n * n - @test 2 * length(g_seq_leaves) - 2 == length(vertices(g_seq)) - - for eb in non_leaf_edges(g_seq) - vs = contraction_tree_leaf_bipartition(g_seq, eb) - @test length(vs) == 2 - @test Set([v.I for v in vcat(vs[1], vs[2])]) == Set(vertices(tn)) - end - #Check all internal vertices define a correct tripartition and all leaf vertices define a bipartition (tensor on that leafs vs tensor on rest of tree) - for v in vertices(g_seq) - if (!is_leaf_vertex(g_seq, v)) - @test length(v) == 3 - @test Set([vsi.I for vsi in vcat(v[1], v[2], v[3])]) == Set(vertices(tn)) - else - @test length(v) == 2 - @test Set([vsi.I for vsi in vcat(v[1], v[2])]) == Set(vertices(tn)) - end - end -end -end diff --git a/test/test_expect.jl b/test/test_expect.jl index 093b7df2..f3b8c869 100644 --- a/test/test_expect.jl +++ b/test/test_expect.jl @@ -40,10 +40,11 @@ using Test: @test, @testset sz_exact = expect(ψ, "Sz"; alg="exact") @test sz_bp ≈ sz_exact - #Test with QNS, product state so should be immediately exact + #Test with Quantum Numbers, product state so BP should be exact L, χ = 2, 2 g = named_grid((L, L)) s = siteinds("S=1/2", g; conserve_qns=true) + ψ = ITensorNetwork(v -> isodd(sum(v)) ? "↑" : "↓", s) sz_bp = expect(ψ, "Sz"; alg="bp") From 03515161f9d455aaba6f9e20347d7a8aa3ec9cd8 Mon Sep 17 00:00:00 2001 From: Joey Date: Sat, 26 Apr 2025 10:01:16 -0400 Subject: [PATCH 09/10] Changes --- src/formnetworks/bilinearformnetwork.jl | 17 ++++++++++------- test/test_contraction_sequence.jl | 1 + 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/formnetworks/bilinearformnetwork.jl b/src/formnetworks/bilinearformnetwork.jl index 5021014a..f0c60195 100644 --- a/src/formnetworks/bilinearformnetwork.jl +++ b/src/formnetworks/bilinearformnetwork.jl @@ -52,6 +52,12 @@ function Base.copy(blf::BilinearFormNetwork) ) end +function itensor_identity_map(i_pairs::Vector) + return prod(i_pairs; init=ITensor(one(Bool))) do i_pair + return delta(Bool, dag(first(i_pair)), last(i_pair)) + end +end + function BilinearFormNetwork( bra::AbstractITensorNetwork, ket::AbstractITensorNetwork; @@ -63,13 +69,10 @@ function BilinearFormNetwork( s = siteinds(ket) s_mapped = dual_site_index_map(s) operator_inds = union_all_inds(s, s_mapped) - constructor_f = - v -> inds -> if !isempty(inds) - reduce(*, [delta(dag(s), sm) for (s, sm) in zip(s[v], s_mapped[v])]) - else - ITensor(one(Bool)) - end - O = ITensorNetwork(constructor_f, operator_inds; link_space) + + O = ITensorNetwork(operator_inds; link_space) do v + inds -> itensor_identity_map(s[v] .=> s_mapped[v]) + end return BilinearFormNetwork(O, bra, ket; dual_site_index_map, kwargs...) end diff --git a/test/test_contraction_sequence.jl b/test/test_contraction_sequence.jl index cbc55477..0fad02ba 100644 --- a/test/test_contraction_sequence.jl +++ b/test/test_contraction_sequence.jl @@ -49,6 +49,7 @@ using Test: @test, @testset Pkg.rm("KaHyPar"; io=devnull) res_kahypar_bipartite = contract(tn; sequence=seq_kahypar_bipartite)[] @test res_optimal ≈ res_kahypar_bipartite + #These tests were leading to CI issues that need to be investigated # seq_einexprs_kahypar = contraction_sequence(tn; alg="einexpr", optimizer=HyPar()) # res_einexprs_kahypar = contract(tn; sequence=seq_einexprs_kahypar)[] # @test res_einexprs_kahypar ≈ res_optimal From a15347a3b90554d8826ebe7a751e909039ce10c1 Mon Sep 17 00:00:00 2001 From: Joseph Tindall <51231103+JoeyT1994@users.noreply.github.com> Date: Sun, 27 Apr 2025 13:44:58 -0400 Subject: [PATCH 10/10] Update src/formnetworks/bilinearformnetwork.jl Co-authored-by: Matt Fishman --- src/formnetworks/bilinearformnetwork.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/formnetworks/bilinearformnetwork.jl b/src/formnetworks/bilinearformnetwork.jl index f0c60195..3988dcbc 100644 --- a/src/formnetworks/bilinearformnetwork.jl +++ b/src/formnetworks/bilinearformnetwork.jl @@ -71,7 +71,7 @@ function BilinearFormNetwork( operator_inds = union_all_inds(s, s_mapped) O = ITensorNetwork(operator_inds; link_space) do v - inds -> itensor_identity_map(s[v] .=> s_mapped[v]) + return inds -> itensor_identity_map(s[v] .=> s_mapped[v]) end return BilinearFormNetwork(O, bra, ket; dual_site_index_map, kwargs...) end