Wolfram Language Paclet Repository

Community-contributed installable additions to the Wolfram Language

Primary Navigation

    • Cloud & Deployment
    • Core Language & Structure
    • Data Manipulation & Analysis
    • Engineering Data & Computation
    • External Interfaces & Connections
    • Financial Data & Computation
    • Geographic Data & Computation
    • Geometry
    • Graphs & Networks
    • Higher Mathematical Computation
    • Images
    • Knowledge Representation & Natural Language
    • Machine Learning
    • Notebook Documents & Presentation
    • Scientific and Medical Data & Computation
    • Social, Cultural & Linguistic Data
    • Strings & Text
    • Symbolic & Numeric Computation
    • System Operation & Setup
    • Time-Related Computation
    • User Interface Construction
    • Visualization & Graphics
    • Random Paclet
    • Alphabetical List
  • Using Paclets
    • Get Started
    • Download Definition Notebook
  • Learn More about Wolfram Language

TensorNetworks

Guides

  • TensorNetworks

Tech Notes

  • Building Tensor Networks
  • Contraction Paths and Execution
  • Matrix Product States
  • Tensor Networks Overview
  • Young Tableaux and Tensor Symmetries

Symbols

  • ActivateTensors
  • BinaryTensorNetwork
  • BinaryTensorNetworkQ
  • CanonicalPath
  • CanonicalPathQ
  • ContractIndices
  • ContractionTree
  • EinsteinSummation
  • GreedyContractionPath
  • HookFactor
  • HookLength
  • HookLengths
  • IndexedMultiply
  • InitializeTensorNetwork
  • MetricTensor
  • MetricTensorQ
  • MPSCanonicalForm
  • MPSCanonicalQ
  • MPSEntanglementEntropy
  • MPSNormalize
  • MPSNorm
  • MPSOverlap
  • MPSSchmidtValues
  • MPSTruncate
  • OptimalContractionPath
  • PartitionQ
  • PathIndexContractions
  • PathQ
  • PathToTreePath
  • RandomTensorNetwork
  • SparseTensorNetwork
  • TableauColumns
  • TableauDimension
  • TableauRows
  • TableauShape
  • TableauSize
  • TensorNetworkAdd
  • TensorNetworkContraction
  • TensorNetworkContractions
  • TensorNetworkContract
  • TensorNetworkData
  • TensorNetworkDelete
  • TensorNetworkFreeIndices
  • TensorNetworkGraphData
  • TensorNetworkGraphQ
  • TensorNetworkIndexDimensions
  • TensorNetworkIndexGraph
  • TensorNetworkIndices
  • TensorNetwork
  • TensorNetworkQ
  • TensorNetworkRemoveCycles
  • TensorNetworkReplaceIndices
  • TensorNetworkSize
  • TensorNetworkTensors
  • TensorNetworkToNetGraph
  • ToTensorNetworkGraph
  • TransposePartition
  • TreePathQ
  • TreePathToPath
  • YoungProject
  • YoungSymmetrize
  • YoungTableau
  • YoungTableauQ
Building Tensor Networks
This tutorial covers the basics of building tensor networks in the Wolfram Language. It begins with the TensorNetwork object itself — what it bundles, how to interrogate it, and what makes the head a distinct value rather than an opaque tagged list. It then walks through the four constructor patterns: tensors plus hyperedges, einsum-style rules with an explicit output specification, conversion from an Inactive
TensorContract
expression, and a symbolic-skeleton constructor that builds
ArraySymbol
placeholders from a hypergraph and dimension association alone. The named-topology section uses
RandomTensorNetwork
to generate instances of the standard families — matrix product states and operators, tensor trains, PEPS on a 2D grid, tree tensor networks, and MERA — including the boundary and field options shared by the chain families. Property dispatch covers the
tn["..."]
interface and the underlying
TensorNetworkData
association. Hyperedges and binarization explains the
SymbolicDeltaProductArray
spider trick that lets pairwise contraction-path algorithms consume otherwise non-binary networks. Edits and transformations cover
TensorNetworkAdd
,
TensorNetworkDelete
,
TensorNetworkReplaceIndices
on the graph form,
SparseTensorNetwork
, and
ToTensorNetworkGraph
.
In[59]:=
Needs["Wolfram`TensorNetworks`"]
1. The TensorNetwork object
A tensor network is a collection of tensors wired together by named legs. The fundamental Wolfram-Language container for one is
TensorNetwork
, with the canonical signature TensorNetwork[tensors, hyperedges, output]. The three pieces of state are a flat list of numeric (or symbolic) tensors, a list of hyperedges — each itself a list of integer leg labels naming the indices that the corresponding tensor exposes — and an output specification controlling which legs survive as free indices after the network is contracted. The output argument is optional; it defaults to Automatic, which keeps exactly the indices that appear in only one tensor (the network's open legs). Any index that appears more than once is treated as contracted.
Conceptually the hyperedges play the role of a hypergraph: each integer label is a vertex of the hypergraph; each inner list is an edge naming the legs of one tensor. The network does not commit to a contraction order. Path search, binarization, and evaluation are all deferred to downstream functions that consume the object — see
TensorNetworkContract
and
OptimalContractionPath
.
Prepare two example tensors.
In[4]:=
A=RandomReal[1,{2,3}];​​B=RandomReal[1,{3,4}];
Wrap them in a
TensorNetwork
by passing the tensor list and a hyperedge list. The matrices A and B each have rank 2, so each inner hyperedge list has length 2. The shared label 2 names the joining bond — it appears in both hyperedges and will be contracted away. Labels 1 and 3 each appear exactly once and remain free.
In[12]:=
tn=
TensorNetwork
[{A,B},{{1,2},{2,3}}]
Out[12]=
TensorNetwork
Tensors: 2
Binary: Yes
Free indices: 2
Sparse: No
Output dimension: 8
​

The head of the resulting expressions is the symbol
TensorNetwork
itself. The paclet installs a custom summary box, so the object renders as a single compact glyph in the front end rather than unfolding into a screen-filling list of numeric entries. This matters when you start composing operations — the object can be passed around, stored, and combined without ever spilling its tensor data into the output history.
In[16]:=
tn["Hypergraph"]
Out[16]=
Use
TensorNetworkQ
to test whether an expression is a valid network. It checks both the head and the structural invariants (lengths agree, every hyperedge length equals the rank of its tensor, every output leg is a label that actually appears). Predicates of this form are useful as guards inside
PatternTest
constructions.
In[63]:=
TensorNetworkQ
[tn]
Out[63]=
True
The free indices are the ones that appear in exactly one hyperedge — the network's open legs. When the output specification is Automatic, the free-index list is computed automatically by counting label occurrences. The next section shows how to override that to expose contracted legs or to scalar-out.
In[64]:=
tn["FreeIndices"]
Out[64]=
{1,3}
2. Constructor forms
There are four idiomatic ways to construct a network. The first three start from existing tensors — either fully numeric or carrying symbolic entries — and differ only in the syntax used to attach them to a hypergraph. The fourth bypasses tensors entirely: you describe the shape of the network with a hypergraph and a dimension association, and the constructor populates each slot with an
ArraySymbol
placeholder of the correct rank and dimensions. The symbolic form is useful for planning a contraction before the numerics exist, for index-only analyses, and for testing path search under specific shape regimes.

2.1. Tensors plus a hyperedge list

Form 1: tensors plus a hyperedge list. Each inner list is one hyperedge, naming the legs it joins. The constructor matches the leg names to tensor ranks in order — the kth label inside the ith hyperedge corresponds to the kth axis of the ith tensor. Shapes must match: if the same label appears twice, the two corresponding tensor axes must have the same dimension.
In[17]:=
tn1=
TensorNetwork
[{A,B},{{1,2},{2,3}}]
Out[17]=
TensorNetwork
Tensors: 2
Binary: Yes
Free indices: 2
Sparse: No
Output dimension: 8
​

In[18]:=
tn1["Hypergraph"]
Out[18]=
In[19]:=
{tn1["Hyperedges"],tn1["FreeIndices"]}
Out[19]=
{{{1,2},{2,3}},{1,3}}

2.2. Einsum-style with explicit output

Form 2: einsum-style with an explicit hyperedges -> output rule. The right-hand side lists which indices survive as free legs after contraction. Setting it equal to the indices that appear once recovers Automatic behavior; setting it to {} contracts the network to a scalar (a tensor trace); setting it to a permutation of the auto-free list reorders the output axes. This is the form most directly cognate with einsum strings in NumPy or with ITensor's index-naming conventions.
In[20]:=
tn2=
TensorNetwork
[{A,B},{{1,2},{2,3}}{1,3}]
Out[20]=
TensorNetwork
Tensors: 2
Binary: Yes
Free indices: 2
Sparse: No
Output dimension: 8
​


2.3. Inactive TensorContract expression

Form 3: lift an unevaluated
TensorContract
expression. The contraction is written in the native
TensorProduct
/
TensorContract
notation Wolfram Language uses for higher-rank tensor algebra; the
Inactive
wrapper keeps it from evaluating eagerly. This is the natural bridge from a mathematical description of a contraction into network form — the inactive expression carries enough information to recover both the tensors and the contracted axis pairs, and the constructor reads it directly.
In[69]:=
tn3=
TensorNetwork
[Inactive[TensorContract][Inactive[TensorProduct][A,B],{{2,3}}]]
Out[69]=
TensorNetwork
Tensors: 2
Binary: Yes
Free indices: 2
Sparse: No
Output dimension: 8
​


2.4. Symbolic skeleton from hypergraph

Form 4: build a symbolic skeleton from the hypergraph alone. The first argument is the hyperedge list (optionally with an output spec); the second is an association mapping each leg label to its dimension. Tensors are filled in with
ArraySymbol
of the correct shape, all bearing the same formal symbol so they are clearly placeholders. Use this when the hypergraph topology is fixed but the entries are not — for symbolic manipulations, scaling analyses, or as a template that
InitializeTensorNetwork
can later populate with real values.
Symbolic tensor networks with global contractions slots and final output:
In[70]:=
tn4=
TensorNetwork
[{{1,2},{2,3}}{3,1}]
Out[70]=
TensorNetwork
Tensors: 2
Binary: Yes
Free indices: 2
Sparse: No
Output dimension:
2
d.
​

Corresponding tensors:
In[71]:=
tn4["Tensors"]
Out[71]=

2
T.
,
2
T.

Corresponding index dimensions (symbolic only):
In[72]:=
tn4["Dimensions"]
Out[72]=
d.,d.,d.,d.
Symbolic tensor networks with contractions slots, final output and a specific glorbal-index dimensions:
In[73]:=
tn5=
TensorNetwork
[{{1,2},{2,3}}{1,3},12,25,34]
Out[73]=
TensorNetwork
Tensors: 2
Binary: Yes
Free indices: 2
Sparse: No
Output dimension: 8
​

Show tensor dimensions:
In[74]:=
tn5["Dimensions"]
Out[74]=
{{2,5},{5,4}}

2.5. Dimension list instead of association

When indices have not yet been bound to arrays, the hypergraph constructor also accepts a positional _List of dimensions in place of an Association. The dimensions are paired with the union of integer index labels in sorted order: the first dimension is assigned to the smallest index, the second to the next, and so on. This is the most compact way to specify a symbolic skeleton when you do not care about index names.
In[75]:=
TensorNetwork
[{{1,2},{2,3}}{1,3},{2,3,4}]
Out[75]=
TensorNetwork
Tensors: 2
Binary: Yes
Free indices: 2
Sparse: No
Output dimension: 8
​

Verify the dimension mapping via ["Dimensions"]: indices 1, 2, 3 receive dimensions 2, 3, 4 respectively.
In[76]:=
TensorNetwork
[{{1,2},{2,3}}{1,3},{2,3,4}]["Dimensions"]
Out[76]=
{{2,3},{3,4}}

2.6. Output permutation via Cycles

The third argument of
TensorNetwork
accepts either an explicit list of free indices, or a
Cycles
permutation that is applied to the auto-derived free-index order. The Cycles form is convenient when you want to keep the default selection of free indices but reorder them — for instance, when downstream code expects rows before columns rather than the order in which they happened to appear in the hyperedge list.
In[77]:=
A=RandomReal[1,{2,3}];​​B=RandomReal[1,{3,4}];
In[79]:=
tnPerm=
TensorNetwork
[{A,B},{{1,2},{2,3}},Cycles[{{1,2}}]]
Out[79]=
TensorNetwork
Tensors: 2
Binary: Yes
Free indices: 2
Sparse: No
Output dimension: 8
​

The default free-index order would have been {1, 3}. Applying the cycle (1 2) swaps the two positions, giving {3, 1}.
In[80]:=
tnPerm["FreeIndices"]
Out[80]=
{3,1}

2.7. Round-trip from an annotated graph

The constructor also accepts an annotated
Graph
whose vertices carry tensors and indices as annotations — in other words, anything satisfying
TensorNetworkGraphQ
. This is the inverse of
ToTensorNetworkGraph
: starting from a flat TensorNetwork[…], round-tripping through the graph form and back recovers a flat object with the same tensors and the same contraction pattern. The integer index labels are replaced by structured Superscript/Subscript labels that record edge direction, but the underlying bond pattern is unchanged.
In[81]:=
base=
TensorNetwork
[{A,B},{{1,2},{2,3}}]
Out[81]=
TensorNetwork
Tensors: 2
Binary: Yes
Free indices: 2
Sparse: No
Output dimension: 8
​

In[82]:=
TensorNetworkData
@base
Out[82]=
Tensors{{{0.92579,0.327791,0.458629},{0.267579,0.411054,0.0854018}},{{0.726854,0.043862,0.724771,0.73795},{0.765395,0.572407,0.445793,0.61895},{0.768739,0.726334,0.683203,0.764582}}},Dimensions{{2,3},{3,4}},Hyperedges{{1,2},{2,3}},Indices{{
1
1
,
2
1
},{
2
2
,
3
2
}},Vertices{1,2},Bonds{{
2
1
,
2
2
}3},Contractions{{
1
1
,{
2
1
,
2
2
}},{{
2
1
,
2
2
},
3
2
}},ContractionIndices{{1,2},{2,3}},FreeIndices{1,3}
3. Named topologies

3.1. Matrix product states

Inspect the hyperedge structure. Each contracted bond appears as a shared label between neighboring sites — labels 1, 2, and 3 link successive pairs. The physical legs (labels 5 through 8) appear only once each and remain free.

3.2. Tensor trains

A tensor train ("TT") is structurally an MPS without a physical dimension — useful for compressing arbitrary high-rank tensors as a chain of low-rank cores. The chain shape is the same (left bond, right bond per interior core) but every tensor lacks the physical leg. Compare the hyperedges: a 4-site tensor train has only the bond indices and no site labels.

3.3. Matrix product operators

A matrix product operator ("MPO") doubles the physical legs — one ket-side and one bra-side per site, so that the object represents an operator rather than a state. Each interior tensor has rank 4 (two bond legs plus two physical legs); each boundary tensor has rank 3. The free-index list interleaves the ket and bra indices in pairs.

3.4. PEPS on a 2D grid

PEPS — projected entangled pair states — lives on a 2D grid. The first argument is {rows, cols}. Each site has up to four bond legs (one to each grid neighbor) plus a single physical leg; boundary and corner sites have correspondingly fewer bonds. The labeling encodes the (row, column) coordinates and the physical-leg range in separate integer bands (hundreds for rows, thousands for physical legs in this example) so the resulting hyperedge list stays readable.

3.5. Tree tensor networks

Tree tensor networks ("TTN") build hierarchical topologies — bonds branch outward from a single root through successive layers, with no horizontal connections between siblings. They naturally represent states with a coarse-graining structure and are common in chemistry-oriented TN methods. Specify depth (number of layers from root to leaves), bond dimension, and branching (number of children per node).

3.6. MERA

The multi-scale entanglement renormalization ansatz ("MERA") adds horizontal disentanglers between layers of a tree, giving the network a characteristic causal-cone structure that captures critical scaling well. Specify width (number of physical sites), bond dimension, and layers (renormalization depth).

3.7. Boundary and field options

Chain families accept the boundary option "Boundary" -> "Open" (default — the leftmost and rightmost sites have rank 2) or "Periodic" — the latter wraps the last site back to the first, adding one extra hyperedge and making every site interior-shaped. All families accept Method -> "Complex" to populate tensors with complex Gaussian entries instead of real ones; the underlying distribution becomes the standard complex normal, and downstream contractions remain complex throughout.

3.8. Random networks on arbitrary graphs

Three forms are available:
• RandomTensorNetwork[g, maxDim] — each index gets an independent random dimension in {2, maxDim}.
• RandomTensorNetwork[g, {fixedDim}] — every index has the same dimension fixedDim.
• RandomTensorNetwork[g, dimSpec, additionalRank] — each vertex's rank is sampled from {VertexDegree[v], VertexDegree[v] + additionalRank}, and the extra legs become free indices.
A 5-vertex, 8-edge random graph with dimensions up to 3:
Fixed dimension 2 on every index:
Adding additionalRank -> 2 gives each vertex between VertexDegree[v] and VertexDegree[v] + 2 legs; the surplus become free indices, useful when generating networks with prescribed free-leg counts:
4. Property dispatch
"Tensors" returns the raw tensor list — three elements for this 3-site MPS. The list is the same object that was passed to the constructor (or that the random generator produced); it round-trips exactly. "Hyperedges" returns the integer labelling of the bonds in the same order.
"FreeIndices" names the open legs — the indices that survive the contraction. "Dimensions" returns one list per tensor giving the size of each of its legs, parallel to the hyperedge list. Together these are enough to predict the shape of the contracted result without actually running the contraction.
"Bonds" enumerates the contracted edges and the dimension each one carries. Each bond is reported as a rule from a pair of typed indices to a dimension, which makes it easy to scan a network and sanity-check that adjacent tensors agree on the dimensions of shared legs before contraction. A mismatch in this output is always the cause of a downstream evaluation error.
Enumerate every property the dispatch knows about with tn["Properties"]. The list includes both the raw fields and several derived views ("Hypergraph", "Vertices", "Ranks"). Use this as a discoverability handle when exploring a new network.

4.1. Function form vs property form

For every key dispatched through tn["Key"] there is a standalone function with the same name. Both forms return identical results and share an implementation — the property form just forwards to the function. Pick whichever reads cleaner at the call site: the property form is concise when the network is already in hand; the function form composes naturally with Map, @*, and other higher-order operators.
The two pairings agree on the values they return:
5. Hyperedges and binarization
A hyperedge is an index that joins three or more tensors at once. In ordinary tensor diagrams every edge connects exactly two tensors, but the underlying mathematics — sums over a shared dummy index — is happy to admit any arity. Hyperedges express copy and broadcast structure that two-end edges cannot draw, and they appear naturally in symmetry-restricted networks, in tensor decompositions like CP, and whenever a delta-function constraint couples more than two tensors.
Build three tensors sharing index 2 — a genuine hyperedge.
The arrow notation 1 -> 2 in the new hyperedge list denotes the rewritten leg name: it reads as "the copy of the old index 2 that hangs off tensor 1." Each original tensor keeps one of these distinguished names instead of the shared label, and the new delta tensor connects them all. The naming is a record of where the spider came from.
6. Edits and transformations

6.1. Adding and deleting tensors

6.2. Renaming indices on the graph form

6.3. Sparse storage

6.4. The annotated graph form

7. Cycles and visualizations
Two transformations that operate on the annotated graph form fall outside the basic edit-and-rename workflow of section 6: cycle breaking and index-connectivity extraction. Cycle breaking is required whenever a network contains a closed loop — for instance, a chain with periodic boundary conditions — because sequential pairwise contraction cannot reduce a cycle without first opening it. Index-connectivity extraction collapses the network down to its bond structure alone, useful for inspecting how indices share tensors without the data getting in the way.

7.1. Breaking cycles with TensorNetworkRemoveCycles

The graph reports a non-trivial cycle:
After cycle removal the graph is acyclic and FindCycle returns the empty list. Two extra vertices (the cup and the cap) have been inserted:

7.2. Index-connectivity graph

Pull the index graph off an MPS:

© 2026 Wolfram. All rights reserved.

  • Legal & Privacy Policy
  • Contact Us
  • WolframAlpha.com
  • WolframCloud.com