An ITensorNetwork is the central data structure of this package. It represents a
collection of ITensors arranged on a
graph, where each edge encodes a shared (contracted) index between the neighboring tensors.
Key facts:
- The underlying graph is a
NamedGraph, so vertices can be any hashable Julia value: integers, tuples, strings, etc. - Each vertex holds exactly one
ITensor. - Edges and link indices are either inferred from shared
Indexobjects (when constructing from a collection ofITensors) or inserted automatically (when constructing from anIndsNetwork).
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:
using NamedGraphs.NamedGraphGenerators: named_grid
using ITensorNetworks: ITensorNetwork, siteinds, linkinds, add
using ITensors: ITensor, Index
using Graphs: vertices, edges, neighbors, nv, ne
# 3×3 square-lattice tensor network
g = named_grid((3, 3))
s = siteinds("S=1/2", g) # one spin-½ Index per vertex
# Zero-initialized, bond dimension 2
ψ = ITensorNetwork(s; link_space = 2)
# Product state — every site in the |↑⟩ state
ψ = ITensorNetwork("Up", s)
# Staggered initialization with a vertex-dependent function
ψ = ITensorNetwork(v -> isodd(sum(v)) ? "Up" : "Dn", s)
When you already have ITensors in hand, edges are inferred automatically from shared
indices:
i, j, k = Index(2,"i"), Index(2,"j"), Index(2,"k")
A, B, C = ITensor(i,j), ITensor(j,k), ITensor(k)
tn = ITensorNetwork([A, B, C]) # integer vertices 1, 2, 3
tn = ITensorNetwork(["A","B","C"], [A, B, C]) # named vertices
tn = ITensorNetwork(["A"=>A, "B"=>B, "C"=>C]) # from pairs
ITensorNetworks.ITensorNetwork
v = (1, 2)
T = ψ[v] # ITensor at vertex (1,2)
ψ[v] = T # replace tensor at a vertex
vertices(ψ) # all vertex labels
edges(ψ) # all edges
neighbors(ψ, v) # neighbouring vertices of v
nv(ψ), ne(ψ) # vertex / edge counts
siteinds(ψ) # IndsNetwork of site (physical) indices
linkinds(ψ) # IndsNetwork of bond (virtual) indices
Two networks with the same graph and site indices can be added. The result represents the
tensor network ψ₁ + ψ₂ and has bond dimension equal to the sum of the two input bond
dimensions. Individual bonds of the result can be recompressed with truncate(tn, edge).
For TreeTensorNetwork, the no-argument form truncate(ttn; kwargs...) sweeps and
recompresses all bonds at once.
ψ1, ψ2 = ψ, ψ
ψ12 = add(ψ1, ψ2)
ψ12 = ψ1 + ψ2
ITensorNetworks.add(::ITensorNetworks.AbstractITensorNetwork, ::ITensorNetworks.AbstractITensorNetwork)
A single bond (edge) of any ITensorNetwork can be truncated by SVD:
edge = (1,2) => (1,3)
ψ12 = truncate(ψ12, (1,2) => (1,3)) # truncate the bond between vertices (1,2) and (1,3)
ψ12 = truncate(ψ12, edge) # or pass an AbstractEdge directly
Truncation parameters (cutoff, maxdim, mindim, …) are forwarded to ITensors.svd.
For a TreeTensorNetwork, the sweep-based truncate(ttn; kwargs...) is usually more
convenient because it recompresses the entire network at once with controlled errors;
see the Tree Tensor Networks page.
Base.truncate(::ITensorNetworks.AbstractITensorNetwork, ::Graphs.AbstractEdge)