|
| 1 | +# ITensor Networks |
| 2 | + |
| 3 | +## The `ITensorNetwork` Type |
| 4 | + |
| 5 | +An `ITensorNetwork` is the central data structure of this package. It represents a |
| 6 | +collection of [`ITensor`](https://itensor.github.io/ITensors.jl/stable/)s arranged on a |
| 7 | +graph, where each edge encodes a shared (contracted) index between the neighboring tensors. |
| 8 | + |
| 9 | +Key facts: |
| 10 | + |
| 11 | +- The underlying graph is a [`NamedGraph`](https://github.com/ITensor/NamedGraphs.jl), so |
| 12 | + vertices can be any hashable Julia value: integers, tuples, strings, etc. |
| 13 | +- 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`). |
| 17 | + |
| 18 | +## Construction |
| 19 | + |
| 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: |
| 25 | + |
| 26 | +```@example main |
| 27 | +using Graphs: edges, ne, neighbors, nv, vertices |
| 28 | +using ITensorNetworks: ITensorNetwork, add, linkinds, siteinds |
| 29 | +using ITensors: Index, ITensor |
| 30 | +using NamedGraphs.NamedGraphGenerators: named_grid |
| 31 | +
|
| 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) |
| 41 | +
|
| 42 | +# Staggered initialization with a vertex-dependent function |
| 43 | +ψ = ITensorNetwork(v -> isodd(sum(v)) ? "Up" : "Dn", s) |
| 44 | +``` |
| 45 | + |
| 46 | +When you already have `ITensor`s in hand, edges are inferred automatically from shared |
| 47 | +indices: |
| 48 | + |
| 49 | +```@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) |
| 52 | +
|
| 53 | +tn = ITensorNetwork([A, B, C]) # integer vertices 1, 2, 3 |
| 54 | +tn = ITensorNetwork(["A", "B", "C"], [A, B, C]) # named vertices |
| 55 | +tn = ITensorNetwork(["A" => A, "B" => B, "C" => C]) # from pairs |
| 56 | +``` |
| 57 | + |
| 58 | +```@docs; canonical=false |
| 59 | +ITensorNetworks.ITensorNetwork |
| 60 | +``` |
| 61 | + |
| 62 | +## Accessing Data |
| 63 | + |
| 64 | +```@example main |
| 65 | +v = (1, 2) |
| 66 | +T = ψ[v] # ITensor at vertex (1,2) |
| 67 | +ψ[v] = T # replace tensor at a vertex |
| 68 | +vertices(ψ) # all vertex labels |
| 69 | +edges(ψ) # all edges |
| 70 | +neighbors(ψ, v) # neighbouring vertices of v |
| 71 | +nv(ψ), ne(ψ) # vertex / edge counts |
| 72 | +siteinds(ψ) # IndsNetwork of site (physical) indices |
| 73 | +linkinds(ψ) # IndsNetwork of bond (virtual) indices |
| 74 | +``` |
| 75 | + |
| 76 | +## Adding Two `ITensorNetwork`s |
| 77 | + |
| 78 | +Two networks with the same graph and site indices can be added. The result represents the |
| 79 | +tensor network `ψ₁ + ψ₂` and has bond dimension equal to the **sum** of the two input bond |
| 80 | +dimensions. Individual bonds of the result can be recompressed with `truncate(tn, edge)`. |
| 81 | +For `TreeTensorNetwork`, the no-argument form `truncate(ttn; kwargs...)` sweeps and |
| 82 | +recompresses all bonds at once. |
| 83 | + |
| 84 | +```@example main |
| 85 | +ψ1, ψ2 = ψ, ψ |
| 86 | +ψ12 = add(ψ1, ψ2) |
| 87 | +ψ12 = ψ1 + ψ2 |
| 88 | +``` |
| 89 | + |
| 90 | +```@docs; canonical=false |
| 91 | +ITensorNetworks.add(::ITensorNetworks.AbstractITensorNetwork, ::ITensorNetworks.AbstractITensorNetwork) |
| 92 | +``` |
| 93 | + |
| 94 | +## Bond Truncation |
| 95 | + |
| 96 | +A single bond (edge) of any `ITensorNetwork` can be truncated by SVD: |
| 97 | + |
| 98 | +```@example main |
| 99 | +edge = (1, 2) => (1, 3) |
| 100 | +ψ12 = truncate(ψ12, (1, 2) => (1, 3)) # truncate the bond between vertices (1,2) and (1,3) |
| 101 | +ψ12 = truncate(ψ12, edge) # or pass an AbstractEdge directly |
| 102 | +``` |
| 103 | + |
| 104 | +Truncation parameters (`cutoff`, `maxdim`, `mindim`, …) are forwarded to `ITensors.svd`. |
| 105 | +For a `TreeTensorNetwork`, the sweep-based `truncate(ttn; kwargs...)` is usually more |
| 106 | +convenient because it recompresses the entire network at once with controlled errors; |
| 107 | +see the [Tree Tensor Networks](@ref) page. |
| 108 | + |
| 109 | +```@docs; canonical=false |
| 110 | +Base.truncate(::ITensorNetworks.AbstractITensorNetwork, ::Graphs.AbstractEdge) |
| 111 | +``` |
0 commit comments