Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
4 changes: 1 addition & 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.0"
version = "0.22.0"
Comment thread
mtfishman marked this conversation as resolved.
Outdated
authors = ["Matthew Fishman <mfishman@flatironinstitute.org>, Joseph Tindall <jtindall@flatironinstitute.org> and contributors"]

[workspace]
Expand All @@ -15,7 +15,6 @@ Compat = "34da2185-b29b-5c13-b0c7-acf172513d20"
ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9"
DataGraphs = "b5a273c3-7e6c-41f6-98bd-8d7f1525a36a"
Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
ITensors = "9136182c-28ba-11e9-034c-db9fb085ebd5"
Expand Down Expand Up @@ -56,7 +55,6 @@ Compat = "3, 4"
ConstructionBase = "1.6"
DataGraphs = "0.4"
Dictionaries = "0.4"
Distributions = "0.25.86"
DocStringExtensions = "0.9"
Graphs = "1.8"
ITensors = "0.7, 0.8, 0.9"
Expand Down
2 changes: 1 addition & 1 deletion docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ 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"
Expand Down
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ DocMeta.setdocmeta!(
using Graphs: dst, edges, src, vertices
using ITensorNetworks
using ITensorNetworks:
TreeTensorNetwork, expect, loginner, mps, orthogonalize, siteinds, truncate, ttn
TreeTensorNetwork, expect, loginner, orthogonalize, siteinds, truncate
using ITensors: inner
using LinearAlgebra: norm, normalize
using OMEinsumContractionOrders
Expand Down
11 changes: 6 additions & 5 deletions docs/src/computing_properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

```@setup main
using Graphs: edges, vertices
using ITensorNetworks: ITensorNetwork, expect, inner, loginner, normalize, siteinds, ttn
using ITensorNetworks:
ITensorNetwork, TreeTensorNetwork, expect, inner, loginner, normalize, siteinds
using ITensors: Index, random_itensor
using LinearAlgebra: norm
using NamedGraphs.GraphsExtensions: incident_edges
Expand All @@ -20,10 +21,10 @@ end

g = named_grid((4,))
s = siteinds("S=1/2", g)
phi = normalize(ttn(random_state(g, s; link_space = 2)))
psi = normalize(ttn(random_state(g, s; link_space = 2)))
x = normalize(ttn(random_state(g, s; link_space = 2)))
y = normalize(ttn(random_state(g, s; link_space = 2)))
phi = normalize(TreeTensorNetwork(random_state(g, s; link_space = 2)))
psi = normalize(TreeTensorNetwork(random_state(g, s; link_space = 2)))
x = normalize(TreeTensorNetwork(random_state(g, s; link_space = 2)))
y = normalize(TreeTensorNetwork(random_state(g, s; link_space = 2)))
v = first(vertices(psi))
```

Expand Down
37 changes: 0 additions & 37 deletions docs/src/deprecated_methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,6 @@

Suggestions of methods which could be deleted.

## ITensorNetwork Methods

#### ITensorNetwork Constructors

* From a named graph, forwards to construction from `IndsNetwork` (`itensornetwork.jl`):
```julia
ITensorNetwork{V}(g::NamedGraph)
ITensorNetwork(eltype::Type, undef::UndefInitializer, graph::AbstractNamedGraph; kws...)
ITensorNetwork(f, graph::AbstractNamedGraph; kwargs...)
ITensorNetwork(graph::AbstractNamedGraph; kwargs...)
```

* From a simple graph, forwards to construction from `IndsNetwork` (`itensornetwork.jl`):
```julia
ITensorNetwork(eltype::Type, undef::UndefInitializer, graph::AbstractSimpleGraph; kws...)
ITensorNetwork(f, graph::AbstractSimpleGraph; kwargs...)
ITensorNetwork(graph::AbstractSimpleGraph; kwargs...)
```

* From a function over vertices or from a "value" (e.g. a string like `"Up"`,
an `Op`, an array, or a per-vertex dict/array) that is converted to a callable and used
to initialize each vertex tensor (`itensornetwork.jl`):
```julia
ITensorNetwork(value, is::IndsNetwork; kwargs...)
ITensorNetwork(elt::Type, f, is::IndsNetwork; link_space = trivial_space(is), kws...)
ITensorNetwork(itensor_constructor::Function, is::IndsNetwork; link_space = trivial_space(is), kwargs...)
```

* Construct an `ITensorNetwork` from an `IndsNetwork`. Initializes ITensors with `undef` storage on each vertex
of the `IndsNetwork` with the corresponding indices (`itensornetwork.jl`):
```julia
ITensorNetwork(eltype::Type, undef::UndefInitializer, is::IndsNetwork; kwargs...)
ITensorNetwork(eltype::Type, is::IndsNetwork; kwargs...)
ITensorNetwork(undef::UndefInitializer, is::IndsNetwork; kwargs...)
ITensorNetwork(is::IndsNetwork; kwargs...)
```

## Global Operations on ITensorNetworks


Expand Down
2 changes: 1 addition & 1 deletion docs/src/experimental_methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Methods which still need to be discussed, modified, or deprecated.

* From an `OpSum`, using `opsum_to_ttn.jl` code:
```julia
ttn(os::OpSum, sites::IndsNetwork; kws...)
TreeTensorNetwork(os::OpSum, sites::IndsNetwork; kws...)
```

* From `OpSum`, assuming path graph (`opsum_to_ttn.jl`):
Expand Down
14 changes: 7 additions & 7 deletions docs/src/interface_methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ Recommended methods for building applications on top of ITensorNetworks.

These ITensorNetwork constructor interfaces are foundational to other constructors:

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

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


Expand Down
63 changes: 36 additions & 27 deletions docs/src/itensor_networks.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,49 +11,58 @@ Key facts:
- The underlying graph is a [`NamedGraph`](https://github.com/ITensor/NamedGraphs.jl), 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 `Index` objects (when constructing
from a collection of `ITensor`s) or inserted automatically (when constructing from an
`IndsNetwork`).
- Edges are either inferred from shared `Index` objects (when constructing from a
collection of `ITensor`s) or taken from a graph passed explicitly alongside the tensors.

## Construction

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:
When you already have `ITensor`s in hand, edges are inferred automatically from shared
indices:

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

# 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)
i, j, k = Index(2, "i"), Index(2, "j"), Index(2, "k")
A, B, C = ITensor(i, j), ITensor(j, k), ITensor(k)

# Staggered initialization with a vertex-dependent function
ψ = ITensorNetwork(v -> isodd(sum(v)) ? "Up" : "Dn", s)
tn = ITensorNetwork([A, B, C]) # integer vertices 1, 2, 3
tn = ITensorNetwork(Dict("A" => A, "B" => B, "C" => C)) # named vertices via a Dict
```

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

```@example main
i, j, k = Index(2, "i"), Index(2, "j"), Index(2, "k")
A, B, C = ITensor(i, j), ITensor(j, k), ITensor(k)
using ITensors: random_itensor
using NamedGraphs: NamedGraph
using NamedGraphs.GraphsExtensions: edgetype, incident_edges

tn = ITensorNetwork([A, B, C]) # integer vertices 1, 2, 3
tn = ITensorNetwork(Dict("A" => A, "B" => B, "C" => C)) # named vertices via a Dict
g = NamedGraph(named_grid((3, 3)))
s = siteinds("S=1/2", g) # one spin-½ site Index per vertex

# One shared link Index per edge; bond dimension χ
χ = 2
links = Dict(e => Index(χ, "Link") for e in edges(g))

# Per-vertex tensor: the site Index plus the link Index of every incident edge
tensors = Dict(map(collect(vertices(g))) do v
site_v = s[v]
link_v = [haskey(links, e) ? links[e] : links[reverse(e)] for e in incident_edges(g, v)]
return v => random_itensor(site_v..., link_v...)
end)

ψ = ITensorNetwork(tensors, g)
```

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

```@docs; canonical=false
ITensorNetworks.ITensorNetwork
```
Expand All @@ -77,7 +86,7 @@ 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
For `TreeTensorNetwork`, the no-argument form `truncate(tn; kwargs...)` sweeps and
recompresses all bonds at once.

```@example main
Expand All @@ -101,7 +110,7 @@ edge = (1, 2) => (1, 3)
```

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

Expand Down
9 changes: 5 additions & 4 deletions docs/src/solvers.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ variational sweep algorithm.

```@example main
using Graphs: vertices
using ITensorNetworks: ITensorNetwork, dmrg, dst, edges, normalize, siteinds, src, ttn
using ITensorNetworks:
ITensorNetwork, TreeTensorNetwork, dmrg, dst, edges, normalize, siteinds, src
using ITensors: Index, OpSum, random_itensor
using NamedGraphs.GraphsExtensions: incident_edges
using NamedGraphs.NamedGraphGenerators: named_comb_tree
Expand All @@ -29,7 +30,7 @@ function random_state(g, s; link_space)
v => random_itensor(only(s[v]), (l[e] for e in incident_edges(g, v))...)
for v in vertices(g)
)
return ITensorNetwork(ts)
return ITensorNetwork(ts, g)
end

# Build a Heisenberg Hamiltonian on a comb tree
Expand All @@ -41,11 +42,11 @@ H = let h = OpSum()
h += 0.5, "S-", src(e), "S+", dst(e)
h += "Sz", src(e), "Sz", dst(e)
end
ttn(h, s)
TreeTensorNetwork(h, s)
end

# Random initial state (normalise first!)
psi0 = normalize(ttn(random_state(g, s; link_space = 2)))
psi0 = normalize(TreeTensorNetwork(random_state(g, s; link_space = 2)))

# Run DMRG
energy, psi = dmrg(H, psi0;
Expand Down
74 changes: 42 additions & 32 deletions docs/src/tree_tensor_networks.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,48 +11,56 @@ records which vertices currently form the orthogonality center of the network. A
update this field as the gauge changes.

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

## Construction

### From an `IndsNetwork` or graph
### From an `OpSum` (Hamiltonian)

```@example main
using Graphs: vertices
using ITensorNetworks: ITensorNetwork, TreeTensorNetwork, mps, ortho_region, orthogonalize,
siteinds, ttn
using ITensors: ITensors
using LinearAlgebra: norm
using NamedGraphs.NamedGraphGenerators: named_comb_tree

# Comb-tree TTN (a popular tree topology for 2D-like systems)
g = named_comb_tree((3, 2))
sites = siteinds("S=1/2", g)

psi = ttn(sites) # zero-initialised
psi = ttn(v -> "Up", sites) # product state

# 1D MPS
s1d = siteinds("S=1/2", 6)
mps_state = mps(v -> "Up", s1d) # product MPS
```
A common way to obtain a Hamiltonian-shaped TTN is to convert an `OpSum` over an
`IndsNetwork` of site indices.

```@docs; canonical=false
ITensorNetworks.ttn
ITensorNetworks.mps
ITensorNetworks.TreeTensorNetwork(::ITensors.Ops.OpSum, ::ITensorNetworks.IndsNetwork)
```

### The `TreeTensorNetwork` type and conversion
### From an existing `ITensorNetwork`

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

```@example main
itn = ITensorNetwork(psi) # TTN → ITensorNetwork
psi = TreeTensorNetwork(itn) # ITensorNetwork → TTN
using Graphs: edges, vertices
using ITensorNetworks: ITensorNetwork, TreeTensorNetwork, ortho_region, orthogonalize,
siteinds
using ITensors: ITensors, Index, random_itensor
using LinearAlgebra: norm
using NamedGraphs: NamedGraph
using NamedGraphs.GraphsExtensions: incident_edges
using NamedGraphs.NamedGraphGenerators: named_comb_tree

# Comb-tree TTN (a popular tree topology for 2D-like systems)
g = NamedGraph(named_comb_tree((3, 2)))
sites = siteinds("S=1/2", g)

# Build a structured `ITensorNetwork` with shared link indices on each edge
χ = 2
links = Dict(e => Index(χ, "Link") for e in edges(g))
tensors = Dict(map(collect(vertices(g))) do v
site_v = sites[v]
link_v = [haskey(links, e) ? links[e] : links[reverse(e)] for e in incident_edges(g, v)]
return v => random_itensor(site_v..., link_v...)
end)
itn = ITensorNetwork(tensors, g)
psi = TreeTensorNetwork(itn)
```

To strip the gauge metadata back to a plain `ITensorNetwork`:

```@example main
itn_again = ITensorNetwork(psi) # TTN → ITensorNetwork
```

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

```@example main
g = named_comb_tree((3, 1))
sites = siteinds("S=1/2", g)
A = ITensors.random_itensor(only(sites[(1, 1)]), only(sites[(2, 1)]), only(sites[(3, 1)]))
ttn_A = ttn(A, sites)
g_small = named_comb_tree((3, 1))
sites_small = siteinds("S=1/2", g_small)
A = ITensors.random_itensor(
only(sites_small[(1, 1)]), only(sites_small[(2, 1)]), only(sites_small[(3, 1)])
)
ttn_A = TreeTensorNetwork(A, sites_small)
```

```@docs; canonical=false
ITensorNetworks.ttn(::ITensors.ITensor, ::ITensorNetworks.IndsNetwork)
ITensorNetworks.TreeTensorNetwork(::ITensors.ITensor, ::ITensorNetworks.IndsNetwork)
```

## Orthogonal Gauge
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"
Loading
Loading