Skip to content

Commit a3509ff

Browse files
mtfishmanclaude
andauthored
[BREAKING] Drop IndsNetwork/graph ITensorNetwork ctors and ttn/mps generic ctors (#356)
## Summary Continues the post-#355 cleanup. Drops the rest of the higher-level `ITensorNetwork` and `ttn` / `mps` constructor surface that wrapped the old `IndsNetwork`-based code paths, plus the `ttn(::OpSum, ::IndsNetwork)` and `ttn(::ITensor, ::IndsNetwork)` dispatches (canonical name is now `TreeTensorNetwork`; `mpo` continues to dispatch through to it). Surviving construction surface: `ITensorNetwork(tensors)`, `ITensorNetwork(tensors, graph)`, and `TreeTensorNetwork(::OpSum / ::ITensor / ::ITensorNetwork, ...)`. Adds `factorize_edge!` and `Graphs.add_edge!` on `AbstractITensorNetwork`. Internal callers that built `ITensorNetwork(::IndsNetwork)` placeholders now build `ITensorNetwork(tensors, graph)` directly. Folds in two bug fixes (missing `trivial_space` import; `_siteinds` returning `Tuple` instead of `Vector{Index}`). `test/utils.jl` substantially simplified (~261 → ~75 effective lines): surviving helpers are `random_tensornetwork`, `productstate`, and `ModelHamiltonians`; `Distributions` dep dropped. Docs updated to the canonical construction. `Project.toml` bumped 0.21 → 0.22.0-DEV (breaking; accumulator pattern — a strip-suffix PR will release 0.22.0 once v0.22 cleanups are batched). --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 9a4c4a7 commit a3509ff

35 files changed

Lines changed: 361 additions & 693 deletions

Project.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "ITensorNetworks"
22
uuid = "2919e153-833c-4bdc-8836-1ea460a35fc7"
3-
version = "0.21.1"
3+
version = "0.22.0-DEV"
44
authors = ["Matthew Fishman <mfishman@flatironinstitute.org>, Joseph Tindall <jtindall@flatironinstitute.org> and contributors"]
55

66
[workspace]
@@ -15,7 +15,6 @@ Compat = "34da2185-b29b-5c13-b0c7-acf172513d20"
1515
ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9"
1616
DataGraphs = "b5a273c3-7e6c-41f6-98bd-8d7f1525a36a"
1717
Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4"
18-
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
1918
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
2019
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
2120
ITensors = "9136182c-28ba-11e9-034c-db9fb085ebd5"
@@ -54,7 +53,6 @@ Compat = "3, 4"
5453
ConstructionBase = "1.6"
5554
DataGraphs = "0.4"
5655
Dictionaries = "0.4"
57-
Distributions = "0.25.86"
5856
DocStringExtensions = "0.9"
5957
Graphs = "1.8"
6058
ITensors = "0.7, 0.8, 0.9"

docs/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ path = ".."
1616
Documenter = "1.10"
1717
Graphs = "1"
1818
ITensorFormatter = "0.2.27"
19-
ITensorNetworks = "0.21"
19+
ITensorNetworks = "0.22"
2020
ITensors = "0.9"
2121
Literate = "2.20.1"
2222
NamedGraphs = "0.11"

docs/make.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ DocMeta.setdocmeta!(
1414
using Graphs: dst, edges, src, vertices
1515
using ITensorNetworks
1616
using ITensorNetworks:
17-
TreeTensorNetwork, expect, loginner, mps, orthogonalize, siteinds, truncate, ttn
17+
TreeTensorNetwork, expect, loginner, orthogonalize, siteinds, truncate
1818
using ITensors: inner
1919
using LinearAlgebra: norm, normalize
2020
using OMEinsumContractionOrders

docs/src/computing_properties.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
```@setup main
44
using Graphs: edges, vertices
5-
using ITensorNetworks: ITensorNetwork, expect, inner, loginner, normalize, siteinds, ttn
5+
using ITensorNetworks:
6+
ITensorNetwork, TreeTensorNetwork, expect, inner, loginner, normalize, siteinds
67
using ITensors: Index, random_itensor
78
using LinearAlgebra: norm
89
using NamedGraphs.GraphsExtensions: incident_edges
@@ -20,10 +21,10 @@ end
2021
2122
g = named_grid((4,))
2223
s = siteinds("S=1/2", g)
23-
phi = normalize(ttn(random_state(g, s; link_space = 2)))
24-
psi = normalize(ttn(random_state(g, s; link_space = 2)))
25-
x = normalize(ttn(random_state(g, s; link_space = 2)))
26-
y = normalize(ttn(random_state(g, s; link_space = 2)))
24+
phi = normalize(TreeTensorNetwork(random_state(g, s; link_space = 2)))
25+
psi = normalize(TreeTensorNetwork(random_state(g, s; link_space = 2)))
26+
x = normalize(TreeTensorNetwork(random_state(g, s; link_space = 2)))
27+
y = normalize(TreeTensorNetwork(random_state(g, s; link_space = 2)))
2728
v = first(vertices(psi))
2829
```
2930

docs/src/deprecated_methods.md

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,6 @@
22

33
Suggestions of methods which could be deleted.
44

5-
## ITensorNetwork Methods
6-
7-
#### ITensorNetwork Constructors
8-
9-
* From a named graph, forwards to construction from `IndsNetwork` (`itensornetwork.jl`):
10-
```julia
11-
ITensorNetwork{V}(g::NamedGraph)
12-
ITensorNetwork(eltype::Type, undef::UndefInitializer, graph::AbstractNamedGraph; kws...)
13-
ITensorNetwork(f, graph::AbstractNamedGraph; kwargs...)
14-
ITensorNetwork(graph::AbstractNamedGraph; kwargs...)
15-
```
16-
17-
* From a simple graph, forwards to construction from `IndsNetwork` (`itensornetwork.jl`):
18-
```julia
19-
ITensorNetwork(eltype::Type, undef::UndefInitializer, graph::AbstractSimpleGraph; kws...)
20-
ITensorNetwork(f, graph::AbstractSimpleGraph; kwargs...)
21-
ITensorNetwork(graph::AbstractSimpleGraph; kwargs...)
22-
```
23-
24-
* From a function over vertices or from a "value" (e.g. a string like `"Up"`,
25-
an `Op`, an array, or a per-vertex dict/array) that is converted to a callable and used
26-
to initialize each vertex tensor (`itensornetwork.jl`):
27-
```julia
28-
ITensorNetwork(value, is::IndsNetwork; kwargs...)
29-
ITensorNetwork(elt::Type, f, is::IndsNetwork; link_space = trivial_space(is), kws...)
30-
ITensorNetwork(itensor_constructor::Function, is::IndsNetwork; link_space = trivial_space(is), kwargs...)
31-
```
32-
33-
* Construct an `ITensorNetwork` from an `IndsNetwork`. Initializes ITensors with `undef` storage on each vertex
34-
of the `IndsNetwork` with the corresponding indices (`itensornetwork.jl`):
35-
```julia
36-
ITensorNetwork(eltype::Type, undef::UndefInitializer, is::IndsNetwork; kwargs...)
37-
ITensorNetwork(eltype::Type, is::IndsNetwork; kwargs...)
38-
ITensorNetwork(undef::UndefInitializer, is::IndsNetwork; kwargs...)
39-
ITensorNetwork(is::IndsNetwork; kwargs...)
40-
```
41-
425
## Global Operations on ITensorNetworks
436

447

docs/src/experimental_methods.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Methods which still need to be discussed, modified, or deprecated.
5050

5151
* From an `OpSum`, using `opsum_to_ttn.jl` code:
5252
```julia
53-
ttn(os::OpSum, sites::IndsNetwork; kws...)
53+
TreeTensorNetwork(os::OpSum, sites::IndsNetwork; kws...)
5454
```
5555

5656
* From `OpSum`, assuming path graph (`opsum_to_ttn.jl`):

docs/src/interface_methods.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,20 @@ Recommended methods for building applications on top of ITensorNetworks.
66

77
These ITensorNetwork constructor interfaces are foundational to other constructors:
88

9-
* From dictionary-like objects, including other `ITensorNetwork` objects, or a `Dict`
10-
from vertices to `ITensor`. The `tensors` can be a collection of `ITensor`s in which case
11-
the vertex labels are auto-assigned to `eachindex(tensors)` and edges are inferred
12-
from shared indices between the `ITensor`s.
9+
* From a collection of `ITensor`s indexed by vertex (a `Dict`, `Dictionary`, or
10+
`Vector{ITensor}` with linear-index vertex labels). Edges are inferred from shared
11+
`Index` objects between the tensors.
1312
```julia
1413
# `keys(tensors)` are vertices, `values(tensors)` are tensors on those vertices
1514
ITensorNetwork(tensors)
1615
ITensorNetwork{V}(tensors)
1716
```
1817

19-
* From collections of vertices and tensors. E.g. a `Vector{Int}` and a `Vector{ITensor}`.
18+
* From a collection of `ITensor`s placed at the vertices of a given `NamedGraph`. No
19+
edge inference; the graph's edges are used as-is.
2020
```julia
21-
ITensorNetwork(vertices, tensors)
22-
ITensorNetwork{V}(vertices, tensors)
21+
ITensorNetwork(tensors, graph::NamedGraph)
22+
ITensorNetwork{V}(tensors, graph::NamedGraph)
2323
```
2424

2525

docs/src/itensor_networks.md

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,49 +11,58 @@ Key facts:
1111
- The underlying graph is a [`NamedGraph`](https://github.com/ITensor/NamedGraphs.jl), so
1212
vertices can be any hashable Julia value: integers, tuples, strings, etc.
1313
- Each vertex holds exactly one `ITensor`.
14-
- Edges and link indices are either inferred from shared `Index` objects (when constructing
15-
from a collection of `ITensor`s) or inserted automatically (when constructing from an
16-
`IndsNetwork`).
14+
- Edges are either inferred from shared `Index` objects (when constructing from a
15+
collection of `ITensor`s) or taken from a graph passed explicitly alongside the tensors.
1716

1817
## Construction
1918

20-
The most common entry point is an `IndsNetwork` — a graph whose vertices and edges carry
21-
`Index` objects. Generate site indices with the `siteinds` function which takes a site
22-
type string (such as "S=1/2" or "Electron") and a NamedGraph. The NamedGraph can be
23-
generated from functions such as `named_grid`, `named_comb_tree`, etc. from the NamedGraphs.jl
24-
`NamedGraphGenerators` module:
19+
When you already have `ITensor`s in hand, edges are inferred automatically from shared
20+
indices:
2521

2622
```@example main
2723
using Graphs: edges, ne, neighbors, nv, vertices
2824
using ITensorNetworks: ITensorNetwork, add, linkinds, siteinds
2925
using ITensors: Index, ITensor
3026
using NamedGraphs.NamedGraphGenerators: named_grid
3127
32-
# 3×3 square-lattice tensor network
33-
g = named_grid((3, 3))
34-
s = siteinds("S=1/2", g) # one spin-½ Index per vertex
35-
36-
# Zero-initialized, bond dimension 2
37-
ψ = ITensorNetwork(s; link_space = 2)
38-
39-
# Product state — every site in the |↑⟩ state
40-
ψ = ITensorNetwork("Up", s)
28+
i, j, k = Index(2, "i"), Index(2, "j"), Index(2, "k")
29+
A, B, C = ITensor(i, j), ITensor(j, k), ITensor(k)
4130
42-
# Staggered initialization with a vertex-dependent function
43-
ψ = ITensorNetwork(v -> isodd(sum(v)) ? "Up" : "Dn", s)
31+
tn = ITensorNetwork([A, B, C]) # integer vertices 1, 2, 3
32+
tn = ITensorNetwork(Dict("A" => A, "B" => B, "C" => C)) # named vertices via a Dict
4433
```
4534

46-
When you already have `ITensor`s in hand, edges are inferred automatically from shared
47-
indices:
35+
If you want to control edges directly — for example to build a structured network on a
36+
prescribed lattice and fill in tensors later — pass a `NamedGraph` along with a
37+
collection of `ITensor`s indexed by vertex. To create a tensor network with shared link
38+
indices on each edge, build the indices once per edge and reuse them at both endpoints:
4839

4940
```@example main
50-
i, j, k = Index(2, "i"), Index(2, "j"), Index(2, "k")
51-
A, B, C = ITensor(i, j), ITensor(j, k), ITensor(k)
41+
using ITensors: random_itensor
42+
using NamedGraphs: NamedGraph
43+
using NamedGraphs.GraphsExtensions: edgetype, incident_edges
5244
53-
tn = ITensorNetwork([A, B, C]) # integer vertices 1, 2, 3
54-
tn = ITensorNetwork(Dict("A" => A, "B" => B, "C" => C)) # named vertices via a Dict
45+
g = NamedGraph(named_grid((3, 3)))
46+
s = siteinds("S=1/2", g) # one spin-½ site Index per vertex
47+
48+
# One shared link Index per edge; bond dimension χ
49+
χ = 2
50+
links = Dict(e => Index(χ, "Link") for e in edges(g))
51+
52+
# Per-vertex tensor: the site Index plus the link Index of every incident edge
53+
tensors = Dict(map(collect(vertices(g))) do v
54+
site_v = s[v]
55+
link_v = [haskey(links, e) ? links[e] : links[reverse(e)] for e in incident_edges(g, v)]
56+
return v => random_itensor(site_v..., link_v...)
57+
end)
58+
59+
ψ = ITensorNetwork(tensors, g)
5560
```
5661

62+
Higher-level construction routines (random networks, product states, OpSum-derived
63+
TTNs, etc.) are provided by sibling functions like `TreeTensorNetwork(opsum, sites)`
64+
and the test-only helpers in `test/utils.jl`.
65+
5766
```@docs; canonical=false
5867
ITensorNetworks.ITensorNetwork
5968
```
@@ -77,7 +86,7 @@ linkinds(ψ) # IndsNetwork of bond (virtual) indices
7786
Two networks with the same graph and site indices can be added. The result represents the
7887
tensor network `ψ₁ + ψ₂` and has bond dimension equal to the **sum** of the two input bond
7988
dimensions. Individual bonds of the result can be recompressed with `truncate(tn, edge)`.
80-
For `TreeTensorNetwork`, the no-argument form `truncate(ttn; kwargs...)` sweeps and
89+
For `TreeTensorNetwork`, the no-argument form `truncate(tn; kwargs...)` sweeps and
8190
recompresses all bonds at once.
8291

8392
```@example main
@@ -101,7 +110,7 @@ edge = (1, 2) => (1, 3)
101110
```
102111

103112
Truncation parameters (`cutoff`, `maxdim`, `mindim`, …) are forwarded to `ITensors.svd`.
104-
For a `TreeTensorNetwork`, the sweep-based `truncate(ttn; kwargs...)` is usually more
113+
For a `TreeTensorNetwork`, the sweep-based `truncate(tn; kwargs...)` is usually more
105114
convenient because it recompresses the entire network at once with controlled errors;
106115
see the [Tree Tensor Networks](@ref) page.
107116

docs/src/solvers.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ variational sweep algorithm.
1717

1818
```@example main
1919
using Graphs: vertices
20-
using ITensorNetworks: ITensorNetwork, dmrg, dst, edges, normalize, siteinds, src, ttn
20+
using ITensorNetworks:
21+
ITensorNetwork, TreeTensorNetwork, dmrg, dst, edges, normalize, siteinds, src
2122
using ITensors: Index, OpSum, random_itensor
2223
using NamedGraphs.GraphsExtensions: incident_edges
2324
using NamedGraphs.NamedGraphGenerators: named_comb_tree
@@ -29,7 +30,7 @@ function random_state(g, s; link_space)
2930
v => random_itensor(only(s[v]), (l[e] for e in incident_edges(g, v))...)
3031
for v in vertices(g)
3132
)
32-
return ITensorNetwork(ts)
33+
return ITensorNetwork(ts, g)
3334
end
3435
3536
# Build a Heisenberg Hamiltonian on a comb tree
@@ -41,11 +42,11 @@ H = let h = OpSum()
4142
h += 0.5, "S-", src(e), "S+", dst(e)
4243
h += "Sz", src(e), "Sz", dst(e)
4344
end
44-
ttn(h, s)
45+
TreeTensorNetwork(h, s)
4546
end
4647
4748
# Random initial state (normalise first!)
48-
psi0 = normalize(ttn(random_state(g, s; link_space = 2)))
49+
psi0 = normalize(TreeTensorNetwork(random_state(g, s; link_space = 2)))
4950
5051
# Run DMRG
5152
energy, psi = dmrg(H, psi0;

docs/src/tree_tensor_networks.md

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,48 +11,56 @@ records which vertices currently form the orthogonality center of the network. A
1111
update this field as the gauge changes.
1212

1313
**MPS** (matrix product states) are the special case of a `TreeTensorNetwork` on a
14-
1D path graph. The [`mps`](@ref ITensorNetworks.mps) constructor enforces this topology
15-
and provides a convenient interface for 1D calculations.
14+
1D path graph.
1615

1716
## Construction
1817

19-
### From an `IndsNetwork` or graph
18+
### From an `OpSum` (Hamiltonian)
2019

21-
```@example main
22-
using Graphs: vertices
23-
using ITensorNetworks: ITensorNetwork, TreeTensorNetwork, mps, ortho_region, orthogonalize,
24-
siteinds, ttn
25-
using ITensors: ITensors
26-
using LinearAlgebra: norm
27-
using NamedGraphs.NamedGraphGenerators: named_comb_tree
28-
29-
# Comb-tree TTN (a popular tree topology for 2D-like systems)
30-
g = named_comb_tree((3, 2))
31-
sites = siteinds("S=1/2", g)
32-
33-
psi = ttn(sites) # zero-initialised
34-
psi = ttn(v -> "Up", sites) # product state
35-
36-
# 1D MPS
37-
s1d = siteinds("S=1/2", 6)
38-
mps_state = mps(v -> "Up", s1d) # product MPS
39-
```
20+
A common way to obtain a Hamiltonian-shaped TTN is to convert an `OpSum` over an
21+
`IndsNetwork` of site indices.
4022

4123
```@docs; canonical=false
42-
ITensorNetworks.ttn
43-
ITensorNetworks.mps
24+
ITensorNetworks.TreeTensorNetwork(::ITensors.Ops.OpSum, ::ITensorNetworks.IndsNetwork)
4425
```
4526

46-
### The `TreeTensorNetwork` type and conversion
27+
### From an existing `ITensorNetwork`
4728

4829
The `TreeTensorNetwork` struct wraps an `ITensorNetwork` and records the current
4930
orthogonality region. Use the `TreeTensorNetwork` constructor to convert a plain
5031
`ITensorNetwork` with tree topology into a `TTN`, and `ITensorNetwork` to strip the
5132
gauge metadata when you need a plain network again.
5233

5334
```@example main
54-
itn = ITensorNetwork(psi) # TTN → ITensorNetwork
55-
psi = TreeTensorNetwork(itn) # ITensorNetwork → TTN
35+
using Graphs: edges, vertices
36+
using ITensorNetworks: ITensorNetwork, TreeTensorNetwork, ortho_region, orthogonalize,
37+
siteinds
38+
using ITensors: ITensors, Index, random_itensor
39+
using LinearAlgebra: norm
40+
using NamedGraphs: NamedGraph
41+
using NamedGraphs.GraphsExtensions: incident_edges
42+
using NamedGraphs.NamedGraphGenerators: named_comb_tree
43+
44+
# Comb-tree TTN (a popular tree topology for 2D-like systems)
45+
g = NamedGraph(named_comb_tree((3, 2)))
46+
sites = siteinds("S=1/2", g)
47+
48+
# Build a structured `ITensorNetwork` with shared link indices on each edge
49+
χ = 2
50+
links = Dict(e => Index(χ, "Link") for e in edges(g))
51+
tensors = Dict(map(collect(vertices(g))) do v
52+
site_v = sites[v]
53+
link_v = [haskey(links, e) ? links[e] : links[reverse(e)] for e in incident_edges(g, v)]
54+
return v => random_itensor(site_v..., link_v...)
55+
end)
56+
itn = ITensorNetwork(tensors, g)
57+
psi = TreeTensorNetwork(itn)
58+
```
59+
60+
To strip the gauge metadata back to a plain `ITensorNetwork`:
61+
62+
```@example main
63+
itn_again = ITensorNetwork(psi) # TTN → ITensorNetwork
5664
```
5765

5866
```@docs; canonical=false
@@ -67,14 +75,16 @@ tree edges. Truncation parameters (e.g. `cutoff`, `maxdim`) are forwarded to the
6775
factorisation step.
6876

6977
```@example main
70-
g = named_comb_tree((3, 1))
71-
sites = siteinds("S=1/2", g)
72-
A = ITensors.random_itensor(only(sites[(1, 1)]), only(sites[(2, 1)]), only(sites[(3, 1)]))
73-
ttn_A = ttn(A, sites)
78+
g_small = named_comb_tree((3, 1))
79+
sites_small = siteinds("S=1/2", g_small)
80+
A = ITensors.random_itensor(
81+
only(sites_small[(1, 1)]), only(sites_small[(2, 1)]), only(sites_small[(3, 1)])
82+
)
83+
ttn_A = TreeTensorNetwork(A, sites_small)
7484
```
7585

7686
```@docs; canonical=false
77-
ITensorNetworks.ttn(::ITensors.ITensor, ::ITensorNetworks.IndsNetwork)
87+
ITensorNetworks.TreeTensorNetwork(::ITensors.ITensor, ::ITensorNetworks.IndsNetwork)
7888
```
7989

8090
## Orthogonal Gauge

0 commit comments

Comments
 (0)