Skip to content

Commit 9ef3eb6

Browse files
mtfishmanclaude
andcommitted
[BREAKING] Drop ttn/mps name aliases and simplify test/utils.jl
Follow-up to the IndsNetwork/graph ctor removal in the same branch. Drop the `ttn` / `mps` short-name surface entirely (rather than narrowing it): the surviving constructors keep the canonical `TreeTensorNetwork` name. This covers `ttn(::OpSum, ::IndsNetwork)` (and its `eltype`-leading variant) and `ttn(::ITensor, ::IndsNetwork)`. `mpo` continues to dispatch through to `TreeTensorNetwork(::OpSum, ::IndsNetwork)`. Docs: drop `ttn` / `mps` from `using ITensorNetworks` in `docs/make.jl` and the `mps`-specific section from `tree_tensor_networks.md`; rewrite the constructor examples in `itensor_networks.md` and `tree_tensor_networks.md` to build link inds explicitly with `random_itensor` so they don't fall back to `EmptyNumber` placeholders that fail the downstream `add` / `qr` / `directsum` examples; rename `ttn` callsites to `TreeTensorNetwork` in `solvers.md` and `experimental_methods.md`. Fixes the docs build failure on PR #356. `src/abstractitensornetwork.jl`: `_siteinds` now `collect`s the inds before iterating, so the return type is a `Vector{Index}` rather than a `Tuple`. The `IndsNetwork` `vertex_data` setter expects a vector, and the previous behaviour produced a `Tuple` whenever a vertex's tensor had no shared neighbour inds. Also rename `truncate(ttn) → truncate(tn)` in a docstring. `test/utils.jl`: substantial simplification (~261 → ~75 effective lines). Drop `random_mps`, `random_ttn`, `Op`-handling, the `generic_state` machinery, and the `@traitfn` indirection. Surviving surface: `random_tensornetwork` (graph or `IndsNetwork` input, eltype + distribution variants), `productstate` (renamed from `tensornetworkstate`, since it only builds product states; routed through `insert_linkinds` so the default `link_space` follows `trivial_space` and stays QN-aware), and the `ModelHamiltonians` submodule. Test callsites updated: `ttn(state, s) → TreeTensorNetwork(productstate(state, s))`, `ttn(os, s) → TreeTensorNetwork(os, s)`, `ttn(A, is; cutoff) → TreeTensorNetwork(A, is; cutoff)`, and `tensornetworkstate → productstate`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent e0dd1bb commit 9ef3eb6

24 files changed

Lines changed: 208 additions & 295 deletions

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/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/itensor_networks.md

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,36 @@ tn = ITensorNetwork([A, B, C]) # integer vertices 1, 2, 3
3232
tn = ITensorNetwork(Dict("A" => A, "B" => B, "C" => C)) # named vertices via a Dict
3333
```
3434

35-
If you want to control edges directly — for example to build an empty network on a
35+
If you want to control edges directly — for example to build a structured network on a
3636
prescribed lattice and fill in tensors later — pass a `NamedGraph` along with a
37-
collection of `ITensor`s indexed by vertex:
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:
3839

3940
```@example main
40-
g = named_grid((3, 3))
41-
s = siteinds("S=1/2", g) # one spin-½ Index per vertex
41+
using ITensors: random_itensor
42+
using NamedGraphs: NamedGraph
43+
using NamedGraphs.GraphsExtensions: edgetype, incident_edges
44+
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)
4258
43-
# Build site tensors on the 3×3 lattice with one (placeholder) site index each
44-
tensors = Dict(v => ITensor(s[v]...) for v in vertices(g))
4559
ψ = ITensorNetwork(tensors, g)
4660
```
4761

4862
Higher-level construction routines (random networks, product states, OpSum-derived
49-
TTNs, etc.) are provided by sibling functions like `ttn(opsum, sites)` and the test-only
50-
helpers in `test/utils.jl`.
63+
TTNs, etc.) are provided by sibling functions like `TreeTensorNetwork(opsum, sites)`
64+
and the test-only helpers in `test/utils.jl`.
5165

5266
```@docs; canonical=false
5367
ITensorNetworks.ITensorNetwork
@@ -72,7 +86,7 @@ linkinds(ψ) # IndsNetwork of bond (virtual) indices
7286
Two networks with the same graph and site indices can be added. The result represents the
7387
tensor network `ψ₁ + ψ₂` and has bond dimension equal to the **sum** of the two input bond
7488
dimensions. Individual bonds of the result can be recompressed with `truncate(tn, edge)`.
75-
For `TreeTensorNetwork`, the no-argument form `truncate(ttn; kwargs...)` sweeps and
89+
For `TreeTensorNetwork`, the no-argument form `truncate(tn; kwargs...)` sweeps and
7690
recompresses all bonds at once.
7791

7892
```@example main
@@ -96,7 +110,7 @@ edge = (1, 2) => (1, 3)
96110
```
97111

98112
Truncation parameters (`cutoff`, `maxdim`, `mindim`, …) are forwarded to `ITensors.svd`.
99-
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
100114
convenient because it recompresses the entire network at once with controlled errors;
101115
see the [Tree Tensor Networks](@ref) page.
102116

docs/src/solvers.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ variational sweep algorithm.
1818
```@example main
1919
using Graphs: vertices
2020
using ITensorNetworks:
21-
ITensorNetwork, TreeTensorNetwork, dmrg, dst, edges, normalize, siteinds, src, ttn
21+
ITensorNetwork, TreeTensorNetwork, dmrg, dst, edges, normalize, siteinds, src
2222
using ITensors: Index, OpSum, random_itensor
2323
using NamedGraphs.GraphsExtensions: incident_edges
2424
using NamedGraphs.NamedGraphGenerators: named_comb_tree
@@ -30,7 +30,7 @@ function random_state(g, s; link_space)
3030
v => random_itensor(only(s[v]), (l[e] for e in incident_edges(g, v))...)
3131
for v in vertices(g)
3232
)
33-
return ITensorNetwork(ts)
33+
return ITensorNetwork(ts, g)
3434
end
3535
3636
# Build a Heisenberg Hamiltonian on a comb tree
@@ -42,7 +42,7 @@ H = let h = OpSum()
4242
h += 0.5, "S-", src(e), "S+", dst(e)
4343
h += "Sz", src(e), "Sz", dst(e)
4444
end
45-
ttn(h, s)
45+
TreeTensorNetwork(h, s)
4646
end
4747
4848
# Random initial state (normalise first!)

docs/src/tree_tensor_networks.md

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ A common way to obtain a Hamiltonian-shaped TTN is to convert an `OpSum` over an
2121
`IndsNetwork` of site indices.
2222

2323
```@docs; canonical=false
24-
ITensorNetworks.ttn(::ITensors.Ops.OpSum, ::ITensorNetworks.IndsNetwork)
24+
ITensorNetworks.TreeTensorNetwork(::ITensors.Ops.OpSum, ::ITensorNetworks.IndsNetwork)
2525
```
2626

2727
### From an existing `ITensorNetwork`
@@ -32,21 +32,28 @@ orthogonality region. Use the `TreeTensorNetwork` constructor to convert a plain
3232
gauge metadata when you need a plain network again.
3333

3434
```@example main
35-
using Graphs: vertices
35+
using Graphs: edges, vertices
3636
using ITensorNetworks: ITensorNetwork, TreeTensorNetwork, ortho_region, orthogonalize,
37-
siteinds, ttn
38-
using ITensors: ITensors, ITensor
37+
siteinds
38+
using ITensors: ITensors, Index, random_itensor
3939
using LinearAlgebra: norm
4040
using NamedGraphs: NamedGraph
41+
using NamedGraphs.GraphsExtensions: incident_edges
4142
using NamedGraphs.NamedGraphGenerators: named_comb_tree
4243
4344
# Comb-tree TTN (a popular tree topology for 2D-like systems)
44-
g = named_comb_tree((3, 2))
45+
g = NamedGraph(named_comb_tree((3, 2)))
4546
sites = siteinds("S=1/2", g)
4647
47-
# Build an `ITensorNetwork` from explicit per-vertex tensors and wrap as a TTN
48-
tensors = Dict(v => ITensor(sites[v]...) for v in vertices(g))
49-
itn = ITensorNetwork(tensors, NamedGraph(g))
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)
5057
psi = TreeTensorNetwork(itn)
5158
```
5259

@@ -68,14 +75,16 @@ tree edges. Truncation parameters (e.g. `cutoff`, `maxdim`) are forwarded to the
6875
factorisation step.
6976

7077
```@example main
71-
g = named_comb_tree((3, 1))
72-
sites = siteinds("S=1/2", g)
73-
A = ITensors.random_itensor(only(sites[(1, 1)]), only(sites[(2, 1)]), only(sites[(3, 1)]))
74-
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)
7584
```
7685

7786
```@docs; canonical=false
78-
ITensorNetworks.ttn(::ITensors.ITensor, ::ITensorNetworks.IndsNetwork)
87+
ITensorNetworks.TreeTensorNetwork(::ITensors.ITensor, ::ITensorNetworks.IndsNetwork)
7988
```
8089

8190
## Orthogonal Gauge

src/abstractitensornetwork.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ end
274274
#
275275

276276
function _siteinds(tn::AbstractITensorNetwork, vertex)
277-
s = inds(tn[vertex])
277+
s = collect(inds(tn[vertex]))
278278
for v in neighbors(tn, vertex)
279279
s = setdiff(s, inds(tn[v]))
280280
end
@@ -681,7 +681,7 @@ Truncation parameters are passed as keyword arguments and forwarded to `ITensors
681681
- `mindim`: Minimum number of singular values to keep.
682682
683683
This operates on a single bond. For `TreeTensorNetwork`, the no-argument form
684-
`truncate(ttn; kwargs...)` sweeps all bonds and is generally preferred for full
684+
`truncate(tn; kwargs...)` sweeps all bonds and is generally preferred for full
685685
recompression after addition or subspace expansion.
686686
687687
See also: `Base.truncate(::AbstractTreeTensorNetwork)`.

src/itensornetwork.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ julia> tn = ITensorNetwork([ITensor(i, j), ITensor(j, k)]);
3838
3939
```
4040
41-
See also: `IndsNetwork`, [`ttn`](@ref ITensorNetworks.ttn), [`TreeTensorNetwork`](@ref ITensorNetworks.TreeTensorNetwork).
41+
See also: `IndsNetwork`, [`TreeTensorNetwork`](@ref ITensorNetworks.TreeTensorNetwork).
4242
"""
4343
const _ITensorCollection = Union{
4444
AbstractVector{<:ITensor},

src/solvers/eigsolve.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ DMRG-like sweep algorithm on a `TreeTensorNetwork`.
7070
# Arguments
7171
7272
- `operator`: The operator to diagonalize, typically a `TreeTensorNetwork` representing a
73-
Hamiltonian constructed from an `OpSum` (e.g. via `ttn(opsum, sites)`).
73+
Hamiltonian constructed from an `OpSum` (e.g. via `TreeTensorNetwork(opsum, sites)`).
7474
- `init_state`: Initial guess for the eigenvector as a `TreeTensorNetwork`.
7575
- `nsweeps`: Number of sweeps over the network.
7676
- `nsites=1`: Number of sites optimized simultaneously per local update step (1 or 2).

src/treetensornetworks/opsum_to_ttn/opsum_to_ttn.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -636,12 +636,12 @@ function sortmergeterms(os::OpSum{C}) where {C}
636636
end
637637

638638
"""
639-
ttn(os::OpSum, sites::IndsNetwork{<:Index}; kwargs...)
640-
ttn(eltype::Type{<:Number}, os::OpSum, sites::IndsNetwork{<:Index}; kwargs...)
639+
TreeTensorNetwork(os::OpSum, sites::IndsNetwork{<:Index}; kwargs...)
640+
TreeTensorNetwork(eltype::Type{<:Number}, os::OpSum, sites::IndsNetwork{<:Index}; kwargs...)
641641
642642
Convert an OpSum object `os` to a TreeTensorNetwork, with indices given by `sites`.
643643
"""
644-
function ttn(
644+
function TreeTensorNetwork(
645645
os::OpSum,
646646
sites::IndsNetwork;
647647
root_vertex = GraphsExtensions.default_root_vertex(sites),
@@ -658,16 +658,16 @@ function ttn(
658658
end
659659

660660
function mpo(os::OpSum, external_inds::Vector; kwargs...)
661-
return ttn(os, path_indsnetwork(external_inds); kwargs...)
661+
return TreeTensorNetwork(os, path_indsnetwork(external_inds); kwargs...)
662662
end
663663
function mpo(os::OpSum, s::IndsNetwork; kwargs...)
664664
# TODO: Check it is a path graph.
665-
return ttn(os, s; kwargs...)
665+
return TreeTensorNetwork(os, s; kwargs...)
666666
end
667667

668668
# Catch-all for leaf eltype specification
669-
function ttn(eltype::Type{<:Number}, os, sites::IndsNetwork; kwargs...)
670-
return NDTensors.convert_scalartype(eltype, ttn(os, sites; kwargs...))
669+
function TreeTensorNetwork(eltype::Type{<:Number}, os, sites::IndsNetwork; kwargs...)
670+
return NDTensors.convert_scalartype(eltype, TreeTensorNetwork(os, sites; kwargs...))
671671
end
672672

673673
#

src/treetensornetworks/treetensornetwork.jl

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
using DataGraphs: underlying_graph
12
using Dictionaries: Indices
23
using Graphs: path_graph
34
using ITensors: ITensor
45
using LinearAlgebra: factorize, normalize
56
using NamedGraphs.GraphsExtensions: GraphsExtensions, vertextype
6-
using NamedGraphs: similar_graph
7+
using NamedGraphs: NamedGraph, similar_graph
78

89
"""
910
TreeTensorNetwork{V} <: AbstractTreeTensorNetwork{V}
@@ -14,10 +15,10 @@ center of the network.
1415
1516
`TTN` is an alias for `TreeTensorNetwork`.
1617
17-
Use [`ttn`](@ref) or [`mps`](@ref) to construct instances, and [`orthogonalize`](@ref) to
18-
bring the network into a canonical gauge.
18+
Use the [`TreeTensorNetwork`](@ref) constructors to build instances, and
19+
[`orthogonalize`](@ref) to bring the network into a canonical gauge.
1920
20-
See also: [`ITensorNetwork`](@ref), [`ttn`](@ref), [`mps`](@ref).
21+
See also: [`ITensorNetwork`](@ref).
2122
"""
2223
struct TreeTensorNetwork{V} <: AbstractTreeTensorNetwork{V}
2324
tensornetwork::ITensorNetwork{V}
@@ -52,21 +53,25 @@ Throws an error if the underlying graph of `tn` is not a tree.
5253
```jldoctest
5354
julia> using NamedGraphs.NamedGraphGenerators: named_comb_tree
5455
56+
julia> using NamedGraphs: NamedGraph
57+
5558
julia> using Graphs: vertices
5659
60+
julia> using ITensors: ITensor
61+
5762
julia> g = named_comb_tree((2, 2));
5863
5964
julia> s = siteinds("S=1/2", g);
6065
61-
julia> itn = ITensorNetwork(s; link_space = 2);
66+
julia> tensors = Dict(v => ITensor(s[v]...) for v in vertices(g));
6267
63-
julia> root_vertex = first(vertices(itn));
68+
julia> itn = ITensorNetwork(tensors, NamedGraph(g));
6469
65-
julia> ttn_state = TreeTensorNetwork(itn; ortho_region = [root_vertex]);
70+
julia> ttn_state = TreeTensorNetwork(itn; ortho_region = [first(vertices(itn))]);
6671
6772
```
6873
69-
See also: [`ttn`](@ref), [`ITensorNetwork`](@ref), [`orthogonalize`](@ref).
74+
See also: [`ITensorNetwork`](@ref), [`orthogonalize`](@ref).
7075
"""
7176
function TreeTensorNetwork(tn::ITensorNetwork; ortho_region = vertices(tn))
7277
return _TreeTensorNetwork(tn, ortho_region)
@@ -88,7 +93,7 @@ end
8893
Convert a `TreeTensorNetwork` to a plain `ITensorNetwork`, discarding orthogonality
8994
metadata. The returned network shares the same underlying tensor data.
9095
91-
See also: [`TreeTensorNetwork`](@ref), [`ttn`](@ref).
96+
See also: [`TreeTensorNetwork`](@ref).
9297
"""
9398
ITensorNetwork(tn::TTN) = copy(tn.tensornetwork)
9499

@@ -123,33 +128,16 @@ function set_ortho_region(tn::TTN, ortho_region)
123128
end
124129

125130
"""
126-
ttn(a::ITensor, is::IndsNetwork; ortho_region=..., kwargs...) -> TreeTensorNetwork
131+
TreeTensorNetwork(a::ITensor, is::IndsNetwork; ortho_region=..., kwargs...) -> TreeTensorNetwork
127132
128133
Decompose a dense `ITensor` `a` into a `TreeTensorNetwork` with the tree structure
129134
described by the `IndsNetwork` `is`.
130135
131136
Successive QR/SVD factorizations are applied following a post-order DFS traversal from the
132137
root vertex, then the network is orthogonalized to `ortho_region` (defaults to the root).
133138
Extra `kwargs` (e.g. `cutoff`, `maxdim`) are forwarded to the factorization.
134-
135-
# Example
136-
137-
```jldoctest
138-
julia> using NamedGraphs.NamedGraphGenerators: named_comb_tree
139-
140-
julia> using ITensors: ITensors
141-
142-
julia> g = named_comb_tree((3, 1));
143-
144-
julia> s = siteinds("S=1/2", g);
145-
146-
julia> A = ITensors.random_itensor(only(s[(1, 1)]), only(s[(2, 1)]), only(s[(3, 1)]));
147-
148-
julia> ttn_A = ttn(A, s);
149-
150-
```
151139
"""
152-
function ttn(
140+
function TreeTensorNetwork(
153141
a::ITensor,
154142
is::IndsNetwork;
155143
ortho_region = Indices([GraphsExtensions.default_root_vertex(is)]),
@@ -160,14 +148,15 @@ function ttn(
160148
end
161149
@assert ortho_region vertices(is)
162150
is = insert_linkinds(is)
163-
ts = Dict{vertextype(is), ITensor}()
164-
for v in vertices(is)
151+
g = NamedGraph(underlying_graph(is))
152+
ts = Dict{vertextype(g), ITensor}()
153+
for v in vertices(g)
165154
site_inds = get(is, v, Index[])
166155
edges_v = [edgetype(is)(v, nv) for nv in neighbors(is, v)]
167156
link_inds = reduce(vcat, (is[e] for e in edges_v); init = Index[])
168157
ts[v] = ITensor(site_inds..., link_inds...)
169158
end
170-
tn = ITensorNetwork(ts)
159+
tn = ITensorNetwork(ts, g)
171160
ortho_center = first(ortho_region)
172161
for e in post_order_dfs_edges(tn, ortho_center)
173162
left_inds = setdiff(inds(a), inds(tn[dst(e)]))

0 commit comments

Comments
 (0)