|q⟩ Bad Qubits

advanced · Programming · Tensor Networks & Simulation Methods

Contracting Tensor Networks

To contract a tensor network is to sum over its shared (internal) indices, collapsing many tensors into a single resulting tensor. Every quantity you read off a tensor network — an amplitude, an overlap, an expectation value, the unitary of a circuit — is the result of a contraction. This lesson develops the idea on the smallest possible networks.

Contraction is index summation

Two tensors connected by a shared index are contracted by summing over that index. For two matrices AA and BB sharing the middle index kk,

Cij=kAikBkj,C_{ij} = \sum_k A_{ik}\,B_{kj} ,

which is ordinary matrix multiplication. The free indices i,ji,j survive; the bond index kk is summed away. A tensor network is just a bookkeeping diagram for many such sums at once: a line joining two tensors is a contracted index, a dangling line is a free (physical) index.

For a quantum circuit on a single wire, each gate is a 2×22\times 2 tensor with one input index and one output index. Stacking gates connects each gate's output index to the next gate's input index. Contracting the whole chain — summing over all the internal wire indices — yields the circuit's overall 2×22 \times 2 unitary, applied in time order.

Contraction order matters for cost, not for the answer

The contracted result is unique, but the order in which you perform the pairwise sums can change the computational cost enormously. Contracting a long chain left-to-right is cheap; contracting it in a bad order can blow up the size of the intermediate tensors. Choosing a good contraction order is one of the central engineering problems of tensor-network simulation, and finding the optimal order is in general NP-hard. For the tiny networks here every order is cheap, so we focus on getting the answer right.

A worked single-wire contraction

Place three gates on one qubit in time order: HH, then ZZ, then HH. As matrices,

H=12(1111),Z=(1001).H = \frac{1}{\sqrt 2}\begin{pmatrix} 1 & 1 \\ 1 & -1 \end{pmatrix}, \qquad Z = \begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix}.

Contracting the chain means multiplying the matrices in reverse application order (the last gate sits leftmost when acting on a column vector):

U=HZH.U = H\,Z\,H .

Work it out. First ZHZ H:

ZH=12(1001)(1111)=12(1111).Z H = \frac{1}{\sqrt 2}\begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix} \begin{pmatrix} 1 & 1 \\ 1 & -1 \end{pmatrix} = \frac{1}{\sqrt 2}\begin{pmatrix} 1 & 1 \\ -1 & 1 \end{pmatrix}.

Then H(ZH)H(ZH):

U=12(1111)(1111)=12(0220)=(0110)=X.U = \frac{1}{2}\begin{pmatrix} 1 & 1 \\ 1 & -1 \end{pmatrix} \begin{pmatrix} 1 & 1 \\ -1 & 1 \end{pmatrix} = \frac{1}{2}\begin{pmatrix} 0 & 2 \\ 2 & 0 \end{pmatrix} = \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix} = X .

The contracted network is the bit-flip XX. This is the famous identity HZH=XH Z H = X: conjugating a ZZ by Hadamards rotates it into an XX.

Try it

Build a single-qubit circuit whose contracted unitary equals the Pauli-XX gate, using only Hadamard and ZZ gates — realise the identity HZH=XH Z H = X. The grader contracts your circuit into its 2×22 \times 2 unitary and compares it to the reference solution.

Run your code to see the quantum state.

After running, applying your circuit to 0|0\rangle should produce 1|1\rangle, confirming the contraction equals XX.

Sign in on the full site to ask questions and join the discussion.