From 01792682a40f33753e46d949190b315c380360b7 Mon Sep 17 00:00:00 2001 From: Matthew Fishman Date: Tue, 23 Jun 2026 17:45:15 -0400 Subject: [PATCH 1/2] Rename TensorNetwork to ITensorNetwork and adopt the v0.10 next-generation stack Renames the TensorNetwork type to ITensorNetwork, along with AbstractTensorNetwork and the TensorNetworkGenerators submodule, and moves onto ITensorBase v0.7, TensorAlgebra v0.10, and GradedArrays v0.10. Factorization call sites move to MatrixAlgebraKit and TensorAlgebra.MatrixAlgebra, where ITensorBase defines its named-tensor methods. --- Project.toml | 6 +- docs/Project.toml | 2 +- docs/src/reference.md | 2 +- examples/Project.toml | 2 +- .../ITensorNetworkGenerators.jl} | 2 +- .../delta_network.jl | 12 +-- .../ising_network.jl | 2 +- src/ITensorNetworksNext.jl | 2 +- src/abstracttensornetwork.jl | 54 ++++++----- src/apply/apply_operators.jl | 27 +++--- src/beliefpropagation/normnetwork.jl | 8 +- src/tensornetwork.jl | 95 ++++++++++--------- test/Project.toml | 12 ++- test/test_algorithmsinterfaceextensions.jl | 5 +- test/test_apply_operator.jl | 12 +-- test/test_basics.jl | 10 +- test/test_beliefpropagation.jl | 20 ++-- test/test_contract_network.jl | 4 +- ...rs.jl => test_itensornetworkgenerators.jl} | 4 +- test/test_tensornetwork.jl | 32 +++---- 20 files changed, 163 insertions(+), 150 deletions(-) rename src/{TensorNetworkGenerators/TensorNetworkGenerators.jl => ITensorNetworkGenerators/ITensorNetworkGenerators.jl} (75%) rename src/{TensorNetworkGenerators => ITensorNetworkGenerators}/delta_network.jl (76%) rename src/{TensorNetworkGenerators => ITensorNetworkGenerators}/ising_network.jl (94%) rename test/{test_tensornetworkgenerators.jl => test_itensornetworkgenerators.jl} (95%) diff --git a/Project.toml b/Project.toml index bd5f615..2770328 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "ITensorNetworksNext" uuid = "302f2e75-49f0-4526-aef7-d8ba550cb06c" -version = "0.6.1" +version = "0.7.0" authors = ["ITensor developers and contributors"] [workspace] @@ -30,7 +30,7 @@ Combinatorics = "1" DataGraphs = "0.4" Dictionaries = "0.4.5" Graphs = "1.13.1" -ITensorBase = "0.6.3" +ITensorBase = "0.7" LinearAlgebra = "1.10" MacroTools = "0.5.16" MatrixAlgebraKit = "0.6" @@ -38,5 +38,5 @@ NamedGraphs = "0.11" Random = "1.10" SimpleTraits = "0.9.5" SplitApplyCombine = "1.2.3" -TensorAlgebra = "0.9.7" +TensorAlgebra = "0.10" julia = "1.10" diff --git a/docs/Project.toml b/docs/Project.toml index 1d28200..f01c94b 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -10,5 +10,5 @@ path = ".." [compat] Documenter = "1" ITensorFormatter = "0.2.27" -ITensorNetworksNext = "0.6" +ITensorNetworksNext = "0.7" Literate = "2" diff --git a/docs/src/reference.md b/docs/src/reference.md index e61d671..4b4c04c 100644 --- a/docs/src/reference.md +++ b/docs/src/reference.md @@ -1,5 +1,5 @@ # Reference ```@autodocs -Modules = [ITensorNetworksNext, ITensorNetworksNext.TensorNetworkGenerators] +Modules = [ITensorNetworksNext, ITensorNetworksNext.ITensorNetworkGenerators] ``` diff --git a/examples/Project.toml b/examples/Project.toml index 9a19828..ad5bc0b 100644 --- a/examples/Project.toml +++ b/examples/Project.toml @@ -5,4 +5,4 @@ ITensorNetworksNext = "302f2e75-49f0-4526-aef7-d8ba550cb06c" path = ".." [compat] -ITensorNetworksNext = "0.6" +ITensorNetworksNext = "0.7" diff --git a/src/TensorNetworkGenerators/TensorNetworkGenerators.jl b/src/ITensorNetworkGenerators/ITensorNetworkGenerators.jl similarity index 75% rename from src/TensorNetworkGenerators/TensorNetworkGenerators.jl rename to src/ITensorNetworkGenerators/ITensorNetworkGenerators.jl index 96dae41..3fdc851 100644 --- a/src/TensorNetworkGenerators/TensorNetworkGenerators.jl +++ b/src/ITensorNetworkGenerators/ITensorNetworkGenerators.jl @@ -1,4 +1,4 @@ -module TensorNetworkGenerators +module ITensorNetworkGenerators export delta_network, ising_network diff --git a/src/TensorNetworkGenerators/delta_network.jl b/src/ITensorNetworkGenerators/delta_network.jl similarity index 76% rename from src/TensorNetworkGenerators/delta_network.jl rename to src/ITensorNetworkGenerators/delta_network.jl index 3af2912..7b1370a 100644 --- a/src/TensorNetworkGenerators/delta_network.jl +++ b/src/ITensorNetworkGenerators/delta_network.jl @@ -1,6 +1,6 @@ -using ..ITensorNetworksNext: TensorNetwork +using ..ITensorNetworksNext: ITensorNetwork using Graphs: AbstractGraph -using ITensorBase: NamedUnitRange, denamed, name, nameddims +using ITensorBase: NamedUnitRange, name, nameddims, unnamed using NamedGraphs.GraphsExtensions: incident_edges diaglength(a::AbstractArray) = minimum(size(a)) @@ -29,20 +29,20 @@ function diagonaltensor( diag::AbstractVector, is::Tuple{NamedUnitRange, Vararg{NamedUnitRange}} ) - return nameddims(diagonaltensor(diag, denamed.(is)), name.(is)) + return nameddims(diagonaltensor(diag, unnamed.(is)), name.(is)) end -delta(elt::Type, is) = diagonaltensor(ones(elt, minimum(length ∘ denamed, is)), is) +delta(elt::Type, is) = diagonaltensor(ones(elt, minimum(length, is)), is) """ delta_network(f, elt::Type = Float64, g::AbstractGraph) -Construct a TensorNetwork on the graph `g` with element type `elt` that has delta tensors +Construct a ITensorNetwork on the graph `g` with element type `elt` that has delta tensors on each vertex. Link dimensions are defined using the function `f(e)` that should take an edge `e` as an input and should output the link index on that edge. """ function delta_network(f, elt::Type, g::AbstractGraph) - return tn = TensorNetwork(g) do v + return tn = ITensorNetwork(g) do v is = Tuple(f.(incident_edges(g, v))) return delta(elt, is) end diff --git a/src/TensorNetworkGenerators/ising_network.jl b/src/ITensorNetworkGenerators/ising_network.jl similarity index 94% rename from src/TensorNetworkGenerators/ising_network.jl rename to src/ITensorNetworkGenerators/ising_network.jl index 86c66aa..3cdf9a2 100644 --- a/src/TensorNetworkGenerators/ising_network.jl +++ b/src/ITensorNetworkGenerators/ising_network.jl @@ -18,7 +18,7 @@ end """ ising_network(f, β::Number, g::AbstractGraph) -Construct a TensorNetwork on the graph `g` with inverse temperature `β` that has Ising +Construct a ITensorNetwork on the graph `g` with inverse temperature `β` that has Ising partition function tensors on each vertex. Link dimensions are defined using the function `f(e)` that should take an edge `e` as an input and should output the link index on that edge. diff --git a/src/ITensorNetworksNext.jl b/src/ITensorNetworksNext.jl index 50f3970..92a541f 100644 --- a/src/ITensorNetworksNext.jl +++ b/src/ITensorNetworksNext.jl @@ -12,7 +12,7 @@ include("select_algorithm.jl") include("AlgorithmsInterfaceExtensions/AlgorithmsInterfaceExtensions.jl") include("abstracttensornetwork.jl") include("tensornetwork.jl") -include("TensorNetworkGenerators/TensorNetworkGenerators.jl") +include("ITensorNetworkGenerators/ITensorNetworkGenerators.jl") include("contract_network.jl") include("beliefpropagation/messagecache.jl") diff --git a/src/abstracttensornetwork.jl b/src/abstracttensornetwork.jl index 809f9e4..664a224 100644 --- a/src/abstracttensornetwork.jl +++ b/src/abstracttensornetwork.jl @@ -11,13 +11,13 @@ using NamedGraphs.GraphsExtensions: directed_graph, incident_edges, rem_edges!, using NamedGraphs.OrdinalIndexing: OrdinalSuffixedInteger using NamedGraphs: NamedGraphs, NamedGraph, not_implemented, similar_graph -abstract type AbstractTensorNetwork{V, VD} <: AbstractDataGraph{V, VD, Nothing} end +abstract type AbstractITensorNetwork{V, VD} <: AbstractDataGraph{V, VD, Nothing} end # Need to be careful about removing edges from tensor networks in case there is a bond -Graphs.rem_edge!(::AbstractTensorNetwork, edge) = not_implemented() +Graphs.rem_edge!(::AbstractITensorNetwork, edge) = not_implemented() # Graphs.jl overloads -function Graphs.weights(graph::AbstractTensorNetwork) +function Graphs.weights(graph::AbstractITensorNetwork) V = vertextype(graph) es = Tuple.(edges(graph)) ws = Dictionary{Tuple{V, V}, Float64}(es, undef) @@ -29,28 +29,28 @@ function Graphs.weights(graph::AbstractTensorNetwork) end # Copy -Base.copy(::AbstractTensorNetwork) = not_implemented() +Base.copy(::AbstractITensorNetwork) = not_implemented() # Iteration -Base.iterate(tn::AbstractTensorNetwork, args...) = iterate(vertex_data(tn), args...) -Base.keys(tn::AbstractTensorNetwork) = vertices(tn) +Base.iterate(tn::AbstractITensorNetwork, args...) = iterate(vertex_data(tn), args...) +Base.keys(tn::AbstractITensorNetwork) = vertices(tn) # TODO: This contrasts with the `DataGraphs.AbstractDataGraph` definition, # where it is defined as the `vertextype`. Does that cause problems or should it be changed? -Base.eltype(tn::AbstractTensorNetwork) = eltype(vertex_data(tn)) +Base.eltype(tn::AbstractITensorNetwork) = eltype(vertex_data(tn)) # Overload if needed -Graphs.is_directed(::Type{<:AbstractTensorNetwork}) = false +Graphs.is_directed(::Type{<:AbstractITensorNetwork}) = false -DataGraphs.underlying_graph(::AbstractTensorNetwork) = not_implemented() -function NamedGraphs.vertex_positions(tn::AbstractTensorNetwork) +DataGraphs.underlying_graph(::AbstractITensorNetwork) = not_implemented() +function NamedGraphs.vertex_positions(tn::AbstractITensorNetwork) return NamedGraphs.vertex_positions(underlying_graph(tn)) end -function NamedGraphs.ordered_vertices(tn::AbstractTensorNetwork) +function NamedGraphs.ordered_vertices(tn::AbstractITensorNetwork) return NamedGraphs.ordered_vertices(underlying_graph(tn)) end -function Adapt.adapt_structure(to, tn::AbstractTensorNetwork) +function Adapt.adapt_structure(to, tn::AbstractITensorNetwork) # TODO: Define and use: # # @preserve_graph map_vertex_data(adapt(to), tn) @@ -135,14 +135,14 @@ macro preserve_graph(expr) return :(setindex_preserve_graph!($(esc(array)), $(esc(value)), $(esc.(indices)...))) end -# Update the graph of the TensorNetwork `tn` to include +# Update the graph of the ITensorNetwork `tn` to include # edges that should exist based on the tensor connectivity. function add_missing_edges!(tn::AbstractGraph) foreach(v -> add_missing_edges!(tn, v), vertices(tn)) return tn end -# Update the graph of the TensorNetwork `tn` to include +# Update the graph of the ITensorNetwork `tn` to include # edges that should be incident to the vertex `v` # based on the tensor connectivity. function add_missing_edges!(tn::AbstractGraph, v) @@ -157,13 +157,13 @@ function add_missing_edges!(tn::AbstractGraph, v) return tn end -# Fix the edges of the TensorNetwork `tn` to match +# Fix the edges of the ITensorNetwork `tn` to match # the tensor connectivity. function fix_edges!(tn::AbstractGraph) foreach(v -> fix_edges!(tn, v), vertices(tn)) return tn end -# Fix the edges of the TensorNetwork `tn` to match +# Fix the edges of the ITensorNetwork `tn` to match # the tensor connectivity at vertex `v`. function fix_edges!(tn::AbstractGraph, v) for e in incident_edges(tn, v) @@ -176,12 +176,12 @@ function fix_edges!(tn::AbstractGraph, v) return tn end -using ITensorBase: denamedtype, named, nametype, uniquename +using ITensorBase: named, nametype, uniquename, unnamedtype using TensorAlgebra: trivialrange function insertlink!(tn, e) add_edge!(tn, e) T = eltype(inds(tn[src(e)])) - l = named(trivialrange(denamedtype(T)), uniquename(nametype(T))) + l = named(trivialrange(unnamedtype(T)), uniquename(nametype(T))) x = fill!(similar(tn[src(e)], (l,)), one(eltype(tn[src(e)]))) @preserve_graph tn[src(e)] = tn[src(e)] * x @preserve_graph tn[dst(e)] = tn[dst(e)] * conj(x) @@ -202,28 +202,32 @@ function randlinknames(tn) return new_tn end -function Base.setindex!(tn::AbstractTensorNetwork, value, v) +function Base.setindex!(tn::AbstractITensorNetwork, value, v) @preserve_graph tn[v] = value fix_edges!(tn, v) return tn end # Fix ambiguity error. -function Base.setindex!(graph::AbstractTensorNetwork, value, vertex::OrdinalSuffixedInteger) +function Base.setindex!( + graph::AbstractITensorNetwork, + value, + vertex::OrdinalSuffixedInteger + ) graph[vertices(graph)[vertex]] = value return graph end -Base.setindex!(tn::AbstractTensorNetwork, value, edge::AbstractEdge) = not_implemented() -Base.setindex!(tn::AbstractTensorNetwork, value, edge::Pair) = not_implemented() +Base.setindex!(tn::AbstractITensorNetwork, value, edge::AbstractEdge) = not_implemented() +Base.setindex!(tn::AbstractITensorNetwork, value, edge::Pair) = not_implemented() # Fix ambiguity error. function Base.setindex!( - tn::AbstractTensorNetwork, + tn::AbstractITensorNetwork, value, edge::Pair{<:OrdinalSuffixedInteger, <:OrdinalSuffixedInteger} ) return not_implemented() end -function Base.show(io::IO, mime::MIME"text/plain", graph::AbstractTensorNetwork) +function Base.show(io::IO, mime::MIME"text/plain", graph::AbstractITensorNetwork) println(io, "$(typeof(graph)) with $(nv(graph)) vertices:") show(io, mime, vertices(graph)) println(io, "\n") @@ -238,4 +242,4 @@ function Base.show(io::IO, mime::MIME"text/plain", graph::AbstractTensorNetwork) return nothing end -Base.show(io::IO, graph::AbstractTensorNetwork) = show(io, MIME"text/plain"(), graph) +Base.show(io::IO, graph::AbstractITensorNetwork) = show(io, MIME"text/plain"(), graph) diff --git a/src/apply/apply_operators.jl b/src/apply/apply_operators.jl index a9413c1..74836b8 100644 --- a/src/apply/apply_operators.jl +++ b/src/apply/apply_operators.jl @@ -5,8 +5,9 @@ using Graphs: dst, src, vertices using ITensorBase: ITensorBase as ITB, AbstractITensor, dimnames, domainnames, operator, replacedimnames using LinearAlgebra: norm +using MatrixAlgebraKit: qr_compact, svd_trunc using NamedGraphs.GraphsExtensions: all_edges, boundary_edges -using TensorAlgebra: TensorAlgebra as TA, gram_eigh_full, gram_eigh_full_with_pinv +using TensorAlgebra.MatrixAlgebra: gram_eigh_full, gram_eigh_full_with_pinv # === Top-level user entry point === @@ -15,7 +16,7 @@ using TensorAlgebra: TensorAlgebra as TA, gram_eigh_full, gram_eigh_full_with_pi Apply each operator in `operators` (a sequence of single-tensor or two-tensor operators) to `state` in turn, updating `env` to reflect each application. -`state` is an `AbstractTensorNetwork`, `env` is a per-edge environment cache +`state` is an `AbstractITensorNetwork`, `env` is a per-edge environment cache (typically built by `identity_norm_message_env(state)` or one of the related `*_norm_message_env` constructors), and the returned `(state, env)` pair has the operators applied. `kwargs` are forwarded to the per-operator algorithm @@ -205,8 +206,8 @@ end # === BP simple-update implementation === function apply_gate_bp!( - dest::AbstractTensorNetwork, op::AbstractITensor, - state::AbstractTensorNetwork, env; kwargs... + dest::AbstractITensorNetwork, op::AbstractITensor, + state::AbstractITensorNetwork, env; kwargs... ) op_in = domainnames(op) vs = [v for v in vertices(state) if !isempty(intersect(op_in, sitenames(state, v)))] @@ -217,15 +218,15 @@ function apply_gate_bp!( end function apply_gate_bp_nsite!( - ::Val{N}, dest::AbstractTensorNetwork, op::AbstractITensor, - state::AbstractTensorNetwork, env, vs; kwargs... + ::Val{N}, dest::AbstractITensorNetwork, op::AbstractITensor, + state::AbstractITensorNetwork, env, vs; kwargs... ) where {N} return throw(ArgumentError("$N-site gate decomposition not implemented")) end function apply_gate_bp_nsite!( - ::Val{1}, dest::AbstractTensorNetwork, op::AbstractITensor, - state::AbstractTensorNetwork, env, vs; + ::Val{1}, dest::AbstractITensorNetwork, op::AbstractITensor, + state::AbstractITensorNetwork, env, vs; normalize, kwargs... ) v = only(vs) @@ -242,8 +243,8 @@ function apply_gate_bp_nsite!( end function apply_gate_bp_nsite!( - ::Val{2}, dest::AbstractTensorNetwork, op::AbstractITensor, - state::AbstractTensorNetwork, env, vs; + ::Val{2}, dest::AbstractITensorNetwork, op::AbstractITensor, + state::AbstractITensorNetwork, env, vs; trunc, normalize ) v1, v2 = vs @@ -258,10 +259,10 @@ function apply_gate_bp_nsite!( ψ_v1 = prod([[state[v1]]; gauges_v1]) ψ_v2 = prod([[state[v2]]; gauges_v2]) - Q_v1, R_v1 = TA.qr(ψ_v1, setdiff(dimnames(ψ_v1), dimnames(ψ_v2), dimnames(op))) - Q_v2, R_v2 = TA.qr(ψ_v2, setdiff(dimnames(ψ_v2), dimnames(ψ_v1), dimnames(op))) + Q_v1, R_v1 = qr_compact(ψ_v1, setdiff(dimnames(ψ_v1), dimnames(ψ_v2), dimnames(op))) + Q_v2, R_v2 = qr_compact(ψ_v2, setdiff(dimnames(ψ_v2), dimnames(ψ_v1), dimnames(op))) op_R_v1v2 = ITB.apply(op, R_v1 * R_v2) - U_v1, S, U_v2 = TA.svd(op_R_v1v2, setdiff(dimnames(R_v1), dimnames(R_v2)); trunc) + U_v1, S, U_v2 = svd_trunc(op_R_v1v2, setdiff(dimnames(R_v1), dimnames(R_v2)); trunc) if normalize S = S / norm(S) end diff --git a/src/beliefpropagation/normnetwork.jl b/src/beliefpropagation/normnetwork.jl index 50b6c71..60ef064 100644 --- a/src/beliefpropagation/normnetwork.jl +++ b/src/beliefpropagation/normnetwork.jl @@ -1,7 +1,7 @@ using DataGraphs: underlying_graph using Graphs: dst, edges, edgetype, src -using ITensorBase: codomainnames, denamed, domainnames, name, operator, replacedimnames, - similar_operator, state, uniquename +using ITensorBase: codomainnames, domainnames, name, operator, replacedimnames, + similar_operator, state, uniquename, unnamed using NamedGraphs.GraphsExtensions: all_edges, incident_edges using Random: Random, rand!, randn! @@ -38,7 +38,7 @@ function similar_norm_message_env(tn) v1, v2 = src(e), dst(e) ket_axes = linkinds(tn, e) ket_names = name.(ket_axes) - unnamed_axes = denamed.(ket_axes) + unnamed_axes = unnamed.(ket_axes) bra_names = uniquename.(ket_names) # Message axes are dual to the link they contract against in the factor. push!( @@ -146,7 +146,7 @@ function normnetwork(tn) for e in edges(tn) ) merge!(linknames_map, Dict(reverse(e) => m for (e, m) in linknames_map)) - norm_tn = TensorNetwork(underlying_graph(tn)) do v + norm_tn = ITensorNetwork(underlying_graph(tn)) do v t = tn[v] ket_to_bra = Dict(p for e in incident_edges(tn, v) for p in linknames_map[e]) return t * replacedimnames(n -> get(ket_to_bra, n, n), conj(t)) diff --git a/src/tensornetwork.jl b/src/tensornetwork.jl index 3c6aa47..996075e 100644 --- a/src/tensornetwork.jl +++ b/src/tensornetwork.jl @@ -16,8 +16,13 @@ using NamedGraphs: function _TensorNetwork end -struct TensorNetwork{V, VD, UG <: AbstractGraph{V}, Tensors <: AbstractDictionary{V, VD}} <: - AbstractTensorNetwork{V, VD} +struct ITensorNetwork{ + V, + VD, + UG <: AbstractGraph{V}, + Tensors <: AbstractDictionary{V, VD}, + } <: + AbstractITensorNetwork{V, VD} underlying_graph::UG tensors::Tensors global @inline function _TensorNetwork( @@ -28,22 +33,22 @@ struct TensorNetwork{V, VD, UG <: AbstractGraph{V}, Tensors <: AbstractDictionar end end # This assumes the tensor connectivity matches the graph structure. -function TensorNetwork(graph::AbstractGraph, tensors) - return TensorNetwork(graph, Dictionary(keys(tensors), values(tensors))) +function ITensorNetwork(graph::AbstractGraph, tensors) + return ITensorNetwork(graph, Dictionary(keys(tensors), values(tensors))) end -function TensorNetwork(graph::AbstractGraph, tensors::AbstractDictionary) +function ITensorNetwork(graph::AbstractGraph, tensors::AbstractDictionary) tn = _TensorNetwork(graph, tensors) fix_links!(tn) return tn end -function TensorNetwork{V, VD, UG, Tensors}( +function ITensorNetwork{V, VD, UG, Tensors}( graph::UG ) where {V, VD, UG <: AbstractGraph{V}, Tensors} return _TensorNetwork(graph, Tensors()) end -function Graphs.rem_vertex!(tn::TensorNetwork, v) +function Graphs.rem_vertex!(tn::ITensorNetwork, v) delete!(tn.tensors, v) rem_vertex!(tn.underlying_graph, v) return tn @@ -51,16 +56,16 @@ end # DataGraphs interface -DataGraphs.underlying_graph(tn::TensorNetwork) = tn.underlying_graph +DataGraphs.underlying_graph(tn::ITensorNetwork) = tn.underlying_graph -DataGraphs.is_vertex_assigned(tn::TensorNetwork, v) = haskey(tn.tensors, v) -DataGraphs.is_edge_assigned(tn::TensorNetwork, e) = false +DataGraphs.is_vertex_assigned(tn::ITensorNetwork, v) = haskey(tn.tensors, v) +DataGraphs.is_edge_assigned(tn::ITensorNetwork, e) = false -DataGraphs.get_vertex_data(tn::TensorNetwork, v) = tn.tensors[v] +DataGraphs.get_vertex_data(tn::ITensorNetwork, v) = tn.tensors[v] -DataGraphs.set_vertex_data!(tn::TensorNetwork, val, v) = set!(tn.tensors, v, val) +DataGraphs.set_vertex_data!(tn::ITensorNetwork, val, v) = set!(tn.tensors, v, val) -function DataGraphs.underlying_graph_type(type::Type{<:TensorNetwork}) +function DataGraphs.underlying_graph_type(type::Type{<:ITensorNetwork}) return fieldtype(type, :underlying_graph) end @@ -82,13 +87,13 @@ function tensornetwork_edges(edgetype::Type, tensors) end tensornetwork_edges(tensors) = tensornetwork_edges(NamedEdge, tensors) -function TensorNetwork(f::Base.Callable, graph::AbstractGraph) - return TensorNetwork(graph, Dictionary(map(f, vertices(graph)))) +function ITensorNetwork(f::Base.Callable, graph::AbstractGraph) + return ITensorNetwork(graph, Dictionary(map(f, vertices(graph)))) end # Insert trivial links for missing edges, and also check # the vertices and edges are consistent between the graph and tensors. -function fix_links!(tn::AbstractTensorNetwork) +function fix_links!(tn::AbstractITensorNetwork) graph = underlying_graph(tn) tensors = vertex_data(tn) @assert issetequal(vertices(graph), keys(tensors)) "Graph vertices and tensor keys must match." @@ -102,27 +107,27 @@ function fix_links!(tn::AbstractTensorNetwork) end # Determine the graph structure from the tensors. -function TensorNetwork(tensors) +function ITensorNetwork(tensors) graph = NamedGraph(keys(tensors)) add_edges!(graph, tensornetwork_edges(tensors)) return _TensorNetwork(graph, tensors) end -function Base.copy(tn::TensorNetwork) - return TensorNetwork(copy(underlying_graph(tn)), copy(vertex_data(tn))) +function Base.copy(tn::ITensorNetwork) + return ITensorNetwork(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} +ITensorNetwork(tn::ITensorNetwork) = copy(tn) +ITensorNetwork{V}(tn::ITensorNetwork{V}) where {V} = copy(tn) +function ITensorNetwork{V}(tn::ITensorNetwork) where {V} g = convert_vertextype(V, underlying_graph(tn)) d = dictionary(V(k) => tn[k] for k in vertices(tn)) - return TensorNetwork(g, d) + return ITensorNetwork(g, d) end -NamedGraphs.convert_vertextype(::Type{V}, tn::TensorNetwork{V}) where {V} = tn -NamedGraphs.convert_vertextype(V::Type, tn::TensorNetwork) = TensorNetwork{V}(tn) +NamedGraphs.convert_vertextype(::Type{V}, tn::ITensorNetwork{V}) where {V} = tn +NamedGraphs.convert_vertextype(V::Type, tn::ITensorNetwork) = ITensorNetwork{V}(tn) -function Graphs.rem_edge!(tn::TensorNetwork, e) +function Graphs.rem_edge!(tn::ITensorNetwork, e) if !has_edge(underlying_graph(tn), e) return false end @@ -138,7 +143,7 @@ function Graphs.rem_edge!(tn::TensorNetwork, e) end function NamedGraphs.similar_graph( - type::Type{<:TensorNetwork}, + type::Type{<:ITensorNetwork}, vertices = vertextype(type)[] ) DT = fieldtype(type, :tensors) @@ -149,7 +154,7 @@ function NamedGraphs.similar_graph( return _TensorNetwork(underlying_graph, empty_dict) end function NamedGraphs.similar_graph( - graph::TensorNetwork, + graph::ITensorNetwork, VD::Type, ::Type{<:Nothing}, vertices @@ -162,7 +167,7 @@ function NamedGraphs.similar_graph( return _TensorNetwork(new_underlying_graph, empty_dict) end -function NamedGraphs.induced_subgraph_from_vertices(graph::TensorNetwork, subvertices) +function NamedGraphs.induced_subgraph_from_vertices(graph::ITensorNetwork, subvertices) return induced_subgraph_tensornetwork(graph, subvertices) end @@ -170,7 +175,7 @@ function induced_subgraph_tensornetwork(graph, subvertices) underlying_subgraph, vlist = Graphs.induced_subgraph(underlying_graph(graph), subvertices) - subgraph = TensorNetwork(underlying_subgraph) do vertex + subgraph = ITensorNetwork(underlying_subgraph) do vertex return graph[vertex] end @@ -178,52 +183,52 @@ function induced_subgraph_tensornetwork(graph, subvertices) end ## PartitionedGraphs -function PartitionedGraphs.partitioned_vertices(tn::TensorNetwork) +function PartitionedGraphs.partitioned_vertices(tn::ITensorNetwork) return partitioned_vertices(tn.underlying_graph) end -function PartitionedGraphs.quotient_graph(tn::TensorNetwork) +function PartitionedGraphs.quotient_graph(tn::ITensorNetwork) ug = quotient_graph(underlying_graph(tn)) inds = Indices(parent_graph_indices(QuotientVertices(tn))) data = map(v -> tn[QuotientVertex(v)], inds) - return TensorNetwork(ug, data) + return ITensorNetwork(ug, data) end # TODO: This method should not be required with a better interface with a better # DataGraphsPartitionedGraphsExt interface. -function PartitionedGraphs.quotient_graph_type(type::Type{<:TensorNetwork}) +function PartitionedGraphs.quotient_graph_type(type::Type{<:ITensorNetwork}) UG = quotient_graph_type(underlying_graph_type(type)) VD = Vector{vertex_data_type(type)} V = vertextype(UG) - return TensorNetwork{V, VD, UG, Dictionary{V, VD}} + return ITensorNetwork{V, VD, UG, Dictionary{V, VD}} end # Partition the underlying graph of the tensor network; does not affect the data. -function PartitionedGraphs.partitionedgraph(tn::TensorNetwork, parts) +function PartitionedGraphs.partitionedgraph(tn::ITensorNetwork, parts) pg = partitionedgraph(underlying_graph(tn), parts) - return TensorNetwork(pg, copy(vertex_data(tn))) + return ITensorNetwork(pg, copy(vertex_data(tn))) end -PartitionedGraphs.departition(tn::TensorNetwork) = tn +PartitionedGraphs.departition(tn::ITensorNetwork) = tn function PartitionedGraphs.departition( - tn::TensorNetwork{<:Any, <:Any, <:AbstractPartitionedGraph} + tn::ITensorNetwork{<:Any, <:Any, <:AbstractPartitionedGraph} ) - return TensorNetwork(departition(underlying_graph(tn)), vertex_data(tn)) + return ITensorNetwork(departition(underlying_graph(tn)), vertex_data(tn)) end -NamedGraphs.to_graph_index(::TensorNetwork, vertex::QuotientVertex) = vertex +NamedGraphs.to_graph_index(::ITensorNetwork, vertex::QuotientVertex) = vertex # When getting data according the quotient vertices, take a lazy contraction. -function DataGraphs.get_index_data(tn::TensorNetwork, vertex::QuotientVertex) +function DataGraphs.get_index_data(tn::ITensorNetwork, vertex::QuotientVertex) data = collect(map(v -> tn[v], vertices(tn, vertex))) return mapreduce(lazy, *, data) end -function DataGraphs.is_graph_index_assigned(tn::TensorNetwork, vertex::QuotientVertex) +function DataGraphs.is_graph_index_assigned(tn::ITensorNetwork, vertex::QuotientVertex) return isassigned(tn, Vertices(vertices(tn, vertex))) end -function PartitionedGraphs.quotientview(tn::TensorNetwork) +function PartitionedGraphs.quotientview(tn::ITensorNetwork) qview = QuotientView(underlying_graph(tn)) tensors = map(qv -> vertex_data(tn)[Indices(qv)], Indices(quotientvertices(tn))) - return TensorNetwork(qview, tensors) + return ITensorNetwork(qview, tensors) end diff --git a/test/Project.toml b/test/Project.toml index ac2e588..4ed160a 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -20,6 +20,10 @@ TensorAlgebra = "68bd88dc-f39d-4e12-b2ca-f046b68fcc6a" TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +[sources.GradedArrays] +rev = "mf/drop-blocksparsearrays" +url = "https://github.com/ITensor/GradedArrays.jl" + [sources.ITensorNetworksNext] path = ".." @@ -28,10 +32,10 @@ AlgorithmsInterface = "0.1" Aqua = "0.8.14" DataGraphs = "0.4" Dictionaries = "0.4.5" -GradedArrays = "0.9.4" +GradedArrays = "0.10" Graphs = "1.13.1" -ITensorBase = "0.6.3" -ITensorNetworksNext = "0.6" +ITensorBase = "0.7" +ITensorNetworksNext = "0.7" ITensorPkgSkeleton = "0.3.42" MatrixAlgebraKit = "0.6" NamedGraphs = "0.11.5" @@ -40,6 +44,6 @@ Random = "1.10" SafeTestsets = "0.1" StableRNGs = "1" Suppressor = "0.2.8" -TensorAlgebra = "0.9.7" +TensorAlgebra = "0.10" TensorOperations = "5.3.1" Test = "1.10" diff --git a/test/test_algorithmsinterfaceextensions.jl b/test/test_algorithmsinterfaceextensions.jl index f580826..290ebb8 100644 --- a/test/test_algorithmsinterfaceextensions.jl +++ b/test/test_algorithmsinterfaceextensions.jl @@ -1,5 +1,6 @@ -import AlgorithmsInterface as AI -import ITensorNetworksNext.AlgorithmsInterfaceExtensions as AIE +using AlgorithmsInterface: AlgorithmsInterface as AI +using ITensorNetworksNext.AlgorithmsInterfaceExtensions: + AlgorithmsInterfaceExtensions as AIE using Test: @test, @test_throws, @testset # Concrete `NestedAlgorithm` subtype: holds a flat list of child algorithms diff --git a/test/test_apply_operator.jl b/test/test_apply_operator.jl index 554aadb..21dd914 100644 --- a/test/test_apply_operator.jl +++ b/test/test_apply_operator.jl @@ -1,12 +1,10 @@ -import ITensorBase as ITB -import TensorAlgebra as TA using GradedArrays: U1, gradedrange using Graphs: dst, edges, src, vertices -using ITensorBase: Index, name, operator, setname, uniquename -using ITensorNetworksNext: TensorNetwork, apply_operator, apply_operators, +using ITensorBase: ITensorBase as ITB, Index, name, operator, setname, uniquename +using ITensorNetworksNext: ITensorNetwork, apply_operator, apply_operators, beliefpropagation_normnetwork, identity_norm_message_env, insertlink!, ones_norm_message_env -using MatrixAlgebraKit: truncrank +using MatrixAlgebraKit: svd_trunc, truncrank using NamedGraphs.NamedGraphGenerators: named_cycle_graph, named_path_graph using NamedGraphs: NamedGraph using Random: AbstractRNG @@ -24,7 +22,7 @@ function randn_operator(rng::AbstractRNG, elt::Type, domain_namedaxes) end function random_state(rng::AbstractRNG, elt::Type, g, site_axes; nlayers, trunc) - state = TensorNetwork(NamedGraph(collect(vertices(g)))) do v + state = ITensorNetwork(NamedGraph(collect(vertices(g)))) do v return randn(rng, elt, (site_axes[v],)) end for e in edges(g) @@ -75,7 +73,7 @@ end gate = randn_operator(rng, T, (site_axes[2], site_axes[3])) gated_full = ITB.apply(gate, prod(state)) left = [name(site_axes[v]) for v in 1:2] - U, S, Vt = TA.svd(gated_full, left; trunc = truncrank(k)) + U, S, Vt = svd_trunc(gated_full, left; trunc = truncrank(k)) gated, _ = apply_operator(gate, state, env; trunc = truncrank(k)) @test prod(gated) ≈ U * S * Vt rtol = eps(real(T))^(1 / 3) end diff --git a/test/test_basics.jl b/test/test_basics.jl index 9b0197c..64636f0 100644 --- a/test/test_basics.jl +++ b/test/test_basics.jl @@ -1,17 +1,17 @@ using Dictionaries: Indices using Graphs: dst, edges, has_edge, ne, nv, src, vertices using ITensorBase: Index, dimnames -using ITensorNetworksNext: TensorNetwork, linkinds, siteinds +using ITensorNetworksNext: ITensorNetwork, linkinds, siteinds using NamedGraphs.GraphsExtensions: arranged_edges, incident_edges using NamedGraphs.NamedGraphGenerators: named_grid using Test: @test, @testset @testset "ITensorNetworksNext" begin - @testset "Construct TensorNetwork product state" begin + @testset "Construct ITensorNetwork 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 + tn = ITensorNetwork(g) do v return randn(s[v]) end @test nv(tn) == 9 @@ -32,12 +32,12 @@ using Test: @test, @testset @test isone(length(only(linkinds(tn, e)))) end end - @testset "Construct TensorNetwork partition function" begin + @testset "Construct ITensorNetwork 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 + tn = ITensorNetwork(g) do v is = map(e -> l[e], incident_edges(g, v)) return randn(Tuple(is)) end diff --git a/test/test_beliefpropagation.jl b/test/test_beliefpropagation.jl index 29979e1..8b548d0 100644 --- a/test/test_beliefpropagation.jl +++ b/test/test_beliefpropagation.jl @@ -1,10 +1,10 @@ -import AlgorithmsInterface as AI +using AlgorithmsInterface: AlgorithmsInterface as AI using DataGraphs: edge_data, edge_data_type using Dictionaries: Dictionary, dictionary, set! using Graphs: AbstractGraph, dst, edges, has_edge, src, vertices using ITensorBase: ITensor, Index, inds, name, noprime, prime -using ITensorNetworksNext: ITensorNetworksNext, MessageCache, StopWhenConverged, - TensorNetwork, bethe_free_energy, edge_scalar, incoming_messages, linkinds, +using ITensorNetworksNext: ITensorNetworksNext, ITensorNetwork, MessageCache, + StopWhenConverged, bethe_free_energy, edge_scalar, incoming_messages, linkinds, messagecache, region_scalar, subgraph, vertex_scalar, vertex_scalars using LinearAlgebra: LinearAlgebra using NamedGraphs.GraphsExtensions: all_edges, arranged_edges, incident_edges, vertextype @@ -34,7 +34,7 @@ function spin_ice_tensornetwork(g) t = t_data[linkinds...] set!(ts, v, t) end - return TensorNetwork(g, ts) + return ITensorNetwork(g, ts) end @testset "Belief propagation" begin @@ -45,7 +45,7 @@ end 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 + tn = ITensorNetwork(g) do v is = map(e -> l[e], incident_edges(g, v)) return randn(Tuple(is)) end @@ -85,7 +85,7 @@ end g = named_path_graph(3) 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 + tn = ITensorNetwork(g) do v is = map(e -> l[e], incident_edges(g, v)) return randn(ComplexF32, Tuple(is)) end @@ -118,7 +118,7 @@ end g = named_grid((3,)) 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 + tn = ITensorNetwork(g) do v is = map(e -> l[e], incident_edges(g, v)) return randn(Tuple(is)) end @@ -134,7 +134,7 @@ end g = named_grid((2,)) 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 + tn = ITensorNetwork(g) do v is = map(e -> l[e], incident_edges(g, v)) return randn(Tuple(is)) end @@ -158,7 +158,7 @@ end 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 + tn = ITensorNetwork(g) do v is = map(e -> l[e], incident_edges(g, v)) return randn(rng, T, Tuple(is)) end @@ -179,7 +179,7 @@ end g = named_comb_tree(dims) l = Dict(e => Index(3) for e in edges(g)) l = merge(l, Dict(reverse(e) => l[e] for e in edges(g))) - tn = TensorNetwork(g) do v + tn = ITensorNetwork(g) do v is = map(e -> l[e], incident_edges(g, v)) return randn(rng, T, Tuple(is)) end diff --git a/test/test_contract_network.jl b/test/test_contract_network.jl index 6525764..b5383ef 100644 --- a/test/test_contract_network.jl +++ b/test/test_contract_network.jl @@ -1,7 +1,7 @@ using Graphs: edges using ITensorBase: Greedy, Index, Optimal using ITensorNetworksNext: - Exact, LeftAssociative, TensorNetwork, contract_network, linkinds, siteinds + Exact, ITensorNetwork, LeftAssociative, contract_network, linkinds, siteinds using NamedGraphs.GraphsExtensions: arranged_edges, incident_edges using NamedGraphs.NamedGraphGenerators: named_grid using TensorOperations: TensorOperations @@ -28,7 +28,7 @@ using Test: @test, @testset 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 + tn = ITensorNetwork(g) do v is = map(e -> l[e], incident_edges(g, v)) return randn(Tuple(is)) end diff --git a/test/test_tensornetworkgenerators.jl b/test/test_itensornetworkgenerators.jl similarity index 95% rename from test/test_tensornetworkgenerators.jl rename to test/test_itensornetworkgenerators.jl index e8198df..3656ca6 100644 --- a/test/test_tensornetworkgenerators.jl +++ b/test/test_itensornetworkgenerators.jl @@ -1,6 +1,6 @@ using Graphs: edges, ne, nv, vertices using ITensorBase: Index, inds -using ITensorNetworksNext.TensorNetworkGenerators: delta, delta_network, ising_network +using ITensorNetworksNext.ITensorNetworkGenerators: delta, delta_network, ising_network using ITensorNetworksNext: contract_network using NamedGraphs.GraphsExtensions: arranged_edges, incident_edges using NamedGraphs.NamedGraphGenerators: named_grid @@ -8,7 +8,7 @@ using Test: @test, @testset !@isdefined(TestUtils) && include("utils.jl") -@testset "TensorNetworkGenerators" begin +@testset "ITensorNetworkGenerators" begin @testset "Delta Network" begin dims = (3, 3) g = named_grid(dims) diff --git a/test/test_tensornetwork.jl b/test/test_tensornetwork.jl index 3f3cbd1..4efe4cb 100644 --- a/test/test_tensornetwork.jl +++ b/test/test_tensornetwork.jl @@ -3,7 +3,7 @@ using Graphs: add_edge!, add_vertex!, dst, edges, edgetype, has_edge, has_vertex is_directed, ne, nv, rem_vertex!, src, vertices using ITensorBase: Index, LazyITensor using ITensorNetworksNext: - TensorNetwork, fix_edges!, linkaxes, linkinds, linknames, siteaxes, siteinds, sitenames + ITensorNetwork, fix_edges!, linkaxes, linkinds, linknames, siteaxes, siteinds, sitenames using NamedGraphs.GraphsExtensions: incident_edges, subgraph, vertextype using NamedGraphs.NamedGraphGenerators: named_grid, named_path_graph using NamedGraphs.PartitionedGraphs: AbstractPartitionedGraph, QuotientVertex, departition, @@ -12,11 +12,11 @@ using NamedGraphs.PartitionedGraphs: AbstractPartitionedGraph, QuotientVertex, d using NamedGraphs: convert_vertextype, similar_graph using Test: @test, @test_throws, @testset -@testset "`TensorNetwork`" begin +@testset "`ITensorNetwork`" begin @testset "Basics" begin g = named_grid((2, 2)) s = Dict(v => Index(2) for v in vertices(g)) - tn = TensorNetwork(g) do v + tn = ITensorNetwork(g) do v return randn(s[v]) end @@ -26,7 +26,7 @@ using Test: @test, @test_throws, @testset @test issetequal(keys(tn), vertices(tn)) # `eltype` matches the eltype of the vertex data. @test eltype(tn) === eltype(vertex_data(tn)) - # `is_directed` is `false` for AbstractTensorNetwork. + # `is_directed` is `false` for AbstractITensorNetwork. @test !is_directed(typeof(tn)) # `show` MIME and default both succeed and mention vertices/edges. @@ -60,7 +60,7 @@ using Test: @test, @test_throws, @testset l = Dict(e => Index(2) for e in edges(g)) l = merge(l, Dict(reverse(e) => l[e] for e in edges(g))) s = Dict(v => Index(2) for v in vertices(g)) - tn = TensorNetwork(g) do v + tn = ITensorNetwork(g) do v is = map(e -> l[e], incident_edges(g, v)) return randn((s[v], is...)) end @@ -84,14 +84,14 @@ using Test: @test, @test_throws, @testset g = named_grid((3,)) 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 + tn = ITensorNetwork(g) do v is = map(e -> l[e], incident_edges(g, v)) return randn(Tuple(is)) end sub_vs = [(1,), (2,)] subtn = subgraph(tn, sub_vs) - @test subtn isa TensorNetwork + @test subtn isa ITensorNetwork @test issetequal(vertices(subtn), sub_vs) @test has_edge(subtn, (1,) => (2,)) end @@ -100,12 +100,12 @@ using Test: @test, @test_throws, @testset dims = (3, 3) g = named_grid(dims) s = Dict(v => Index(2) for v in vertices(g)) - tn = TensorNetwork(g) do v + tn = ITensorNetwork(g) do v return randn(s[v]) end stn = similar_graph(tn) - @test stn isa TensorNetwork + @test stn isa ITensorNetwork @test vertices(stn) == vertices(tn) @test edges(stn) == edges(tn) @test isempty(assigned_vertex_data(stn)) @@ -127,7 +127,7 @@ using Test: @test, @test_throws, @testset @test stn isa typeof(tn) ctn = convert_vertextype(Tuple{Float64, Float64}, tn) - @test ctn isa TensorNetwork + @test ctn isa ITensorNetwork @test vertextype(ctn) == Tuple{Float64, Float64} @test collect(vertex_data(ctn)) == collect(vertex_data(tn)) end @@ -136,7 +136,7 @@ using Test: @test, @test_throws, @testset dims = (3, 3) g = named_grid(dims) s = Dict(v => Index(2) for v in vertices(g)) - tn = TensorNetwork(g) do v + tn = ITensorNetwork(g) do v return randn(s[v]) end @@ -164,7 +164,7 @@ using Test: @test, @test_throws, @testset @testset "`quotient_graph` (default partitioning)" begin qtn = quotient_graph(tn) - @test qtn isa TensorNetwork + @test qtn isa ITensorNetwork @test nv(qtn) == 1 @test ne(qtn) == 0 v = only(collect(vertices(qtn))) @@ -173,14 +173,14 @@ using Test: @test, @test_throws, @testset @testset "`quotient_graph_type`" begin QT = quotient_graph_type(typeof(tn)) - @test QT <: TensorNetwork + @test QT <: ITensorNetwork qtn = quotient_graph(tn) @test vertextype(qtn) === vertextype(QT) end @testset "`partitionedgraph(tn, parts)`" begin ptn = partitionedgraph(tn, row_parts) - @test ptn isa TensorNetwork + @test ptn isa ITensorNetwork # The set of underlying vertices/edges is preserved. @test issetequal(vertices(ptn), vertices(tn)) @test issetequal(edges(ptn), edges(tn)) @@ -211,7 +211,7 @@ using Test: @test, @test_throws, @testset @testset "`quotient_graph` of partitioned tn" begin ptn = partitionedgraph(tn, row_parts) qtn = quotient_graph(ptn) - @test qtn isa TensorNetwork + @test qtn isa ITensorNetwork @test nv(qtn) == dims[2] # The row-partitioned grid quotients to a path graph of length `dims[2]`. @test ne(qtn) == dims[2] - 1 @@ -227,7 +227,7 @@ using Test: @test, @test_throws, @testset # `departition` on a partitioned tn unwraps one layer of partitioning. ptn = partitionedgraph(tn, row_parts) dtn = departition(ptn) - @test dtn isa TensorNetwork + @test dtn isa ITensorNetwork @test issetequal(vertices(dtn), vertices(tn)) @test issetequal(edges(dtn), edges(tn)) end From d23eb8c10516de8c9890fd1c34286d72b6bf5b8a Mon Sep 17 00:00:00 2001 From: Matthew Fishman Date: Tue, 23 Jun 2026 19:45:58 -0400 Subject: [PATCH 2/2] Drop the GradedArrays branch pin now that v0.10 is registered --- test/Project.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/Project.toml b/test/Project.toml index 4ed160a..9369470 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -20,10 +20,6 @@ TensorAlgebra = "68bd88dc-f39d-4e12-b2ca-f046b68fcc6a" TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" -[sources.GradedArrays] -rev = "mf/drop-blocksparsearrays" -url = "https://github.com/ITensor/GradedArrays.jl" - [sources.ITensorNetworksNext] path = ".."