Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "ITensorNetworks"
uuid = "2919e153-833c-4bdc-8836-1ea460a35fc7"
version = "0.21.5"
version = "0.22.0"
authors = ["Matthew Fishman <mfishman@flatironinstitute.org>, Joseph Tindall <jtindall@flatironinstitute.org> and contributors"]

[workspace]
Expand Down Expand Up @@ -54,7 +54,7 @@ Adapt = "4"
Combinatorics = "1"
Compat = "3, 4"
ConstructionBase = "1.6"
DataGraphs = "0.4.1, 0.5"
DataGraphs = "0.6"
Dictionaries = "0.4"
Distributions = "0.25.86"
DocStringExtensions = "0.9"
Expand All @@ -66,7 +66,7 @@ IterTools = "1.4"
KrylovKit = "0.6, 0.7, 0.8, 0.9, 0.10"
MacroTools = "0.5"
NDTensors = "0.3, 0.4"
NamedGraphs = "0.11.1, 0.12, 0.13"
NamedGraphs = "0.14"
OMEinsumContractionOrders = "0.8.3, 0.9, 1"
SerializedElementArrays = "0.1"
SimpleTraits = "0.9"
Expand Down
4 changes: 2 additions & 2 deletions docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ path = ".."
Documenter = "1.10"
Graphs = "1"
ITensorFormatter = "0.2.27"
ITensorNetworks = "0.21"
ITensorNetworks = "0.22"
ITensors = "0.9"
Literate = "2.20.1"
NamedGraphs = "0.11, 0.12, 0.13"
NamedGraphs = "0.14"
OMEinsumContractionOrders = "1.2.2"
TensorOperations = "5.5"
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ makedocs(;
"Deprecated Methods" => "deprecated_methods.md",
],
"API Reference" => "reference.md",
"Changelog" => "changelog.md",
]
)

Expand Down
22 changes: 22 additions & 0 deletions docs/src/changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Changelog

## [0.22.0](https://github.com/ITensor/ITensorNetworks.jl/compare/v0.21.5...v0.22.0) - 2026-09-09

### Breaking changes

- Requires NamedGraphs v0.14. The network types here are `AbstractNamedGraph`
subtypes, so its breaking changes carry through to them, including the output
types of `vertices` and `edges` and the return values of the mutating
functions. See the
[NamedGraphs changelog](https://itensor.github.io/NamedGraphs.jl/stable/changelog/)
([#385](https://github.com/ITensor/ITensorNetworks.jl/pull/385)).
- The leaf type of a contraction sequence is `ITensorNetworks.Key`, where it was
`NamedGraphs.Keys.Key`
([#385](https://github.com/ITensor/ITensorNetworks.jl/pull/385)).

### Non-breaking changes

- `gauge_walk` and the `edges` keyword of `combine_linkinds` take any collection
of edges, where they previously required a `Vector` and so rejected the
iterator that `edges` now returns
([#385](https://github.com/ITensor/ITensorNetworks.jl/pull/385)).
3 changes: 1 addition & 2 deletions docs/src/computing_properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ using Graphs: edges, vertices
using ITensorNetworks: ITensorNetwork, expect, inner, loginner, normalize, siteinds, ttn
using ITensors: Index, random_itensor
using LinearAlgebra: norm
using NamedGraphs.GraphsExtensions: incident_edges
using NamedGraphs.NamedGraphGenerators: named_grid
using NamedGraphs: incident_edges, named_grid

function random_state(g, s; link_space)
l = Dict(e => Index(link_space, "Link") for e in edges(g))
Expand Down
2 changes: 1 addition & 1 deletion docs/src/developer_methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@
* Tree-traversal sequence: cover `g` with a forest, then for each tree push a post-order
DFS sweep followed by its reverse — gives a back-and-forth sequence covering every edge (`edge_sequences.jl`):
```julia
edge_sequence(::Algorithm"forest_cover", g; root_vertex = GraphsExtensions.default_root_vertex)
edge_sequence(::Algorithm"forest_cover", g; root_vertex = default_root_vertex)
```

* Parallel sequence: each edge (and its reverse) as its own one-edge group, suitable
Expand Down
4 changes: 2 additions & 2 deletions docs/src/experimental_methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,13 @@ Methods which still need to be discussed, modified, or deprecated.
* Sweep-based truncation. The whole-TTN form orthogonalizes towards `src(e)` before
each bond truncation; the edge form lifts `truncate` from the underlying `ITensorNetwork` (`treetensornetworks/abstracttreetensornetwork.jl`):
```julia
truncate(tn::AbstractTTN; root_vertex = GraphsExtensions.default_root_vertex(tn), kwargs...)
truncate(tn::AbstractTTN; root_vertex = default_root_vertex(tn), kwargs...)
truncate(tn::AbstractTTN, edge::AbstractEdge; kwargs...)
```

* Contract the whole tree into a single `ITensor` via a reverse post-order DFS sequence (`treetensornetworks/abstracttreetensornetwork.jl`):
```julia
contract(tn::AbstractTTN, root_vertex = GraphsExtensions.default_root_vertex(tn); kwargs...)
contract(tn::AbstractTTN, root_vertex = default_root_vertex(tn); kwargs...)
```

* Inner product `⟨x|y⟩`, matrix element `⟨y|A|x⟩`, and four-network form `⟨B|y|A|x⟩`,
Expand Down
5 changes: 2 additions & 3 deletions docs/src/itensor_networks.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,13 @@ Key facts:
The most common entry point is an `IndsNetwork` — a graph whose vertices and edges carry
`Index` objects. Generate site indices with the `siteinds` function which takes a site
type string (such as "S=1/2" or "Electron") and a NamedGraph. The NamedGraph can be
generated from functions such as `named_grid`, `named_comb_tree`, etc. from the NamedGraphs.jl
`NamedGraphGenerators` module:
generated from functions such as `named_grid`, `named_comb_tree`, etc. from NamedGraphs.jl:

```@example main
using Graphs: edges, ne, neighbors, nv, vertices
using ITensorNetworks: ITensorNetwork, add, linkinds, siteinds
using ITensors: Index, ITensor
using NamedGraphs.NamedGraphGenerators: named_grid
using NamedGraphs: named_grid

# 3×3 square-lattice tensor network
g = named_grid((3, 3))
Expand Down
3 changes: 1 addition & 2 deletions docs/src/solvers.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ variational sweep algorithm.
using Graphs: vertices
using ITensorNetworks: ITensorNetwork, dmrg, dst, edges, normalize, siteinds, src, ttn
using ITensors: Index, OpSum, random_itensor
using NamedGraphs.GraphsExtensions: incident_edges
using NamedGraphs.NamedGraphGenerators: named_comb_tree
using NamedGraphs: incident_edges, named_comb_tree

function random_state(g, s; link_space)
l = Dict(e => Index(link_space, "Link") for e in edges(g))
Expand Down
2 changes: 1 addition & 1 deletion docs/src/tree_tensor_networks.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ using ITensorNetworks: ITensorNetwork, TreeTensorNetwork, mps, ortho_region, ort
siteinds, ttn
using ITensors: ITensors
using LinearAlgebra: norm
using NamedGraphs.NamedGraphGenerators: named_comb_tree
using NamedGraphs: named_comb_tree

# Comb-tree TTN (a popular tree topology for 2D-like systems)
g = named_comb_tree((3, 2))
Expand Down
2 changes: 1 addition & 1 deletion examples/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ ITensorNetworks = "2919e153-833c-4bdc-8836-1ea460a35fc7"
path = ".."

[compat]
ITensorNetworks = "0.21"
ITensorNetworks = "0.22"
6 changes: 2 additions & 4 deletions src/abstractindsnetwork.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ using DataGraphs: DataGraphs, AbstractDataGraph, DataGraph, IsUnderlyingGraph, e
set_edge_data!, set_vertex_data!, underlying_graph_type, vertex_data
using Graphs: Graphs, AbstractEdge
using ITensors: ITensors, unioninds
using NamedGraphs.GraphsExtensions:
GraphsExtensions, directed_graph, incident_edges, rename_vertices
using NamedGraphs: NamedGraphs
using NamedGraphs: NamedGraphs, directed_graph, incident_edges, rename_vertices

abstract type AbstractIndsNetwork{V, I} <: AbstractDataGraph{V, Vector{I}, Vector{I}} end

Expand All @@ -15,7 +13,7 @@ data_graph(graph::AbstractIndsNetwork) = not_implemented()

# Overload if needed
Graphs.is_directed(::Type{<:AbstractIndsNetwork}) = false
GraphsExtensions.directed_graph(is::AbstractIndsNetwork) = directed_graph(data_graph(is))
NamedGraphs.directed_graph(is::AbstractIndsNetwork) = directed_graph(data_graph(is))

# AbstractDataGraphs overloads
DataGraphs.underlying_graph(is::AbstractIndsNetwork) = underlying_graph(data_graph(is))
Expand Down
44 changes: 13 additions & 31 deletions src/abstractitensornetwork.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ using DataGraphs: DataGraphs, edge_data, get_vertex_data, is_vertex_assigned,
set_vertex_data!, underlying_graph, underlying_graph_type, vertex_data
using Dictionaries: Dictionary
using Graphs: Graphs, Graph, add_edge!, add_vertex!, bfs_tree, center, dst, edges, edgetype,
ne, neighbors, rem_edge!, src, vertices
ne, neighbors, rem_edge!, src, steiner_tree, vertices
using ITensors: ITensors, @Algorithm_str, ITensor, addtags, combiner, commoninds,
commontags, contract, dag, inds, noprime, onehot, prime, replaceprime, replacetags,
setprime, settags, sim, swaptags, tags
using LinearAlgebra: LinearAlgebra, factorize
using MacroTools: @capture
using NDTensors: NDTensors, Algorithm, dim, scalartype
using NamedGraphs.GraphsExtensions:
directed_graph, incident_edges, rename_vertices, vertextype, ⊔
using NamedGraphs: NamedGraphs, NamedGraph, Vertices, not_implemented, steiner_tree
using NamedGraphs: NamedGraphs, NamedGraph, Vertices, directed_graph, incident_edges,
not_implemented, rename_vertices, vertextype, ⊔
using SplitApplyCombine: flatten

abstract type AbstractITensorNetwork{V} <: AbstractDataGraph{V, ITensor, ITensor} end
Expand Down Expand Up @@ -54,7 +53,7 @@ Base.eltype(tn::AbstractITensorNetwork) = eltype(vertex_data(tn))

# Overload if needed
Graphs.is_directed(::Type{<:AbstractITensorNetwork}) = false
GraphsExtensions.directed_graph(is::AbstractITensorNetwork) = directed_graph(data_graph(is))
NamedGraphs.directed_graph(is::AbstractITensorNetwork) = directed_graph(data_graph(is))

# Derived interface, may need to be overloaded
function DataGraphs.underlying_graph_type(G::Type{<:AbstractITensorNetwork})
Expand Down Expand Up @@ -143,13 +142,6 @@ function fix_edges!(tn::AbstractITensorNetwork, v)
return tn
end

function NamedGraphs.vertex_positions(tn::AbstractITensorNetwork)
return NamedGraphs.vertex_positions(underlying_graph(tn))
end
function NamedGraphs.ordered_vertices(tn::AbstractITensorNetwork)
return NamedGraphs.ordered_vertices(underlying_graph(tn))
end

function Adapt.adapt_structure(to, tn::AbstractITensorNetwork)
# TODO: Define and use:
#
Expand Down Expand Up @@ -593,25 +585,17 @@ function gauge_edge(
return tn
end

# For ambiguity error; TODO: decide whether to use graph mutating methods when resulting graph is unchanged?
function gauge_walk(
alg::Algorithm, tn::AbstractITensorNetwork, edges::Vector{<:AbstractEdge}; kwargs...
)
# TODO: decide whether to use graph mutating methods when resulting graph is unchanged?
function gauge_walk(alg::Algorithm, tn::AbstractITensorNetwork, edges; kwargs...)
tn = copy(tn)
for edge in edges
tn = gauge_edge(alg, tn, edge; kwargs...)
tn = gauge_edge(alg, tn, edgetype(tn)(edge); kwargs...)
end
return tn
end

function gauge_walk(alg::Algorithm, tn::AbstractITensorNetwork, edge::Pair; kwargs...)
return gauge_edge(alg::Algorithm, tn, edgetype(tn)(edge); kwargs...)
end

function gauge_walk(
alg::Algorithm, tn::AbstractITensorNetwork, edges::Vector{<:Pair}; kwargs...
)
return gauge_walk(alg, tn, edgetype(tn).(edges); kwargs...)
return gauge_edge(alg, tn, edgetype(tn)(edge); kwargs...)
end

function tree_gauge(alg::Algorithm, ψ::AbstractITensorNetwork, region)
Expand Down Expand Up @@ -734,9 +718,7 @@ function combine_linkinds(tn::AbstractITensorNetwork, combiners)
return combined_tn
end

function combine_linkinds(
tn::AbstractITensorNetwork; edges::Vector{<:Union{Pair, AbstractEdge}} = edges(tn)
)
function combine_linkinds(tn::AbstractITensorNetwork; edges = edges(tn))
combiners = linkinds_combiners(tn; edges)
return combine_linkinds(tn, combiners)
end
Expand Down Expand Up @@ -871,18 +853,18 @@ See also: `Base.:+` for `TreeTensorNetwork`, `truncate`.
function add(tn1::AbstractITensorNetwork, tn2::AbstractITensorNetwork)
@assert issetequal(vertices(tn1), vertices(tn2))

tn1 = combine_linkinds(tn1; edges = filter(is_multi_edge(tn1), edges(tn1)))
tn2 = combine_linkinds(tn2; edges = filter(is_multi_edge(tn2), edges(tn2)))
tn1 = combine_linkinds(tn1; edges = filter(is_multi_edge(tn1), collect(edges(tn1))))
tn2 = combine_linkinds(tn2; edges = filter(is_multi_edge(tn2), collect(edges(tn2))))

edges_tn1, edges_tn2 = edges(tn1), edges(tn2)
edges_tn1, edges_tn2 = collect(edges(tn1)), collect(edges(tn2))

if !issetequal(edges_tn1, edges_tn2)
new_edges = union(edges_tn1, edges_tn2)
tn1 = insert_linkinds(tn1, new_edges)
tn2 = insert_linkinds(tn2, new_edges)
end

edges_tn1, edges_tn2 = edges(tn1), edges(tn2)
edges_tn1, edges_tn2 = collect(edges(tn1)), collect(edges(tn2))
@assert issetequal(edges_tn1, edges_tn2)

tn12 = copy(tn1)
Expand Down
5 changes: 2 additions & 3 deletions src/caches/abstractbeliefpropagationcache.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ using LinearAlgebra: diag, dot
using NDTensors: NDTensors
using NamedGraphs.PartitionedGraphs: PartitionedGraph, PartitionedGraphs, QuotientVertex,
boundary_quotientedges, quotientedges, quotientvertices, unpartitioned_graph
using NamedGraphs.SimilarType: SimilarType
using NamedGraphs: to_graph_index
using NamedGraphs: NamedGraphs, to_graph_index
using SimpleTraits: SimpleTraits, @traitfn, Not
using SplitApplyCombine: group

abstract type AbstractBeliefPropagationCache{V, PV} <: AbstractITensorNetwork{V} end

function SimilarType.similar_type(bpc::AbstractBeliefPropagationCache)
function NamedGraphs.similar_type(bpc::AbstractBeliefPropagationCache)
return typeof(tensornetwork(bpc))
end

Expand Down
9 changes: 5 additions & 4 deletions src/contract.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using ITensors.NDTensors: @Algorithm_str, Algorithm, NDTensors, contract
using ITensors: ITensor, scalar
using LinearAlgebra: normalize!
using NamedGraphs.OrdinalIndexing: th
using NamedGraphs: NamedGraphs
using NamedGraphs: decoded_vertex, encoded_vertex, to_graph_index

function NDTensors.contract(tn::AbstractITensorNetwork; alg = "exact", kwargs...)
return contract(Algorithm(alg), tn; kwargs...)
Expand All @@ -15,8 +14,10 @@ function NDTensors.contract(
sequence = contraction_sequence(tn; contraction_sequence_kwargs...),
kwargs...
)
sequence_linear_index = deepmap(v -> NamedGraphs.vertex_positions(tn)[v], sequence)
ts = map(v -> tn[v], (1:nv(tn))th)
sequence_linear_index = deepmap(
v -> encoded_vertex(tn, to_graph_index(tn, v)), sequence
)
ts = map(code -> tn[decoded_vertex(tn, code)], 1:nv(tn))
return contract(ts; sequence = sequence_linear_index, kwargs...)
end

Expand Down
32 changes: 25 additions & 7 deletions src/contraction_sequences.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
using Graphs: vertices
using Graphs: nv, vertices
using ITensors.NDTensors: @Algorithm_str, Algorithm
using ITensors: ITensor
using NamedGraphs.Keys: Key
using NamedGraphs.OrdinalIndexing: th
using ITensors: ITensors, ITensor
using NamedGraphs: NamedGraphs, decoded_vertex

# A key (index) type, used for unambiguously identifying an object as a key or
# index of an indexable object rather than as a container to descend into. That
# distinction matters for the nested structure of a contraction sequence, whose
# leaves are vertices that may themselves be containers:
#
# [Key([1, 2]), [Key([3, 4]), Key([5, 6])]]
struct Key{K}
I::K
end
Key(I...) = Key(I)

Base.show(io::IO, I::Key) = print(io, "Key(", I.I, ")")

NamedGraphs.to_graph_index(graph, key::Key) = key.I

# Patch for contraction sequences with `Key`
# leaf values.
# TODO: Move patch to `ITensors.jl`.
ITensors._contract(As, index::Key) = As[index]

const ITensorList = Union{Vector{ITensor}, Tuple{Vararg{ITensor}}}

Expand All @@ -24,9 +43,8 @@ function deepmap(f, tree; filter = (x -> x isa AbstractArray))
end

function contraction_sequence(tn::AbstractITensorNetwork; kwargs...)
# TODO: Use `token_vertex` and/or `token_vertices` here.
ts = map(v -> tn[v], (1:nv(tn))th)
ts = map(code -> tn[decoded_vertex(tn, code)], 1:nv(tn))
seq_linear_index = contraction_sequence(ts; kwargs...)
# TODO: Use `Functors.fmap` or `StructWalk`?
return deepmap(n -> Key(vertices(tn)[n * th]), seq_linear_index)
return deepmap(code -> Key(decoded_vertex(tn, code)), seq_linear_index)
end
10 changes: 5 additions & 5 deletions src/edge_sequences.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using Graphs: IsDirected, connected_components, edges, edgetype
using ITensors.NDTensors: @Algorithm_str, Algorithm
using NamedGraphs.GraphsExtensions:
GraphsExtensions, forest_cover, subgraph, undirected_graph
using NamedGraphs.PartitionedGraphs: PartitionedGraph, QuotientEdge, quotient_graph
using NamedGraphs: NamedGraphs
using NamedGraphs:
NamedGraphs, default_root_vertex, forest_cover, subgraph, undirected_graph
using SimpleTraits: SimpleTraits, @traitfn, Not

default_edge_sequence_alg() = "forest_cover"
Expand Down Expand Up @@ -32,7 +31,7 @@ end
@traitfn function edge_sequence(
::Algorithm"forest_cover",
g::::(!IsDirected);
root_vertex = GraphsExtensions.default_root_vertex
root_vertex = default_root_vertex
)
forests = forest_cover(g)
edges = edgetype(g)[]
Expand All @@ -47,5 +46,6 @@ end
end

@traitfn function edge_sequence(::Algorithm"parallel", g::::(!IsDirected))
return [[e] for e in vcat(edges(g), reverse.(edges(g)))]
es = collect(edges(g))
return [[e] for e in vcat(es, reverse.(es))]
end
Loading
Loading