# Contracting ITensors

Tensor contraction is often the most costly step of tensor algorithms. Code for contracting tensors can be fragile and error-prone when the tensor interface depends on the index ordering.

ITensor gets around these issues by using "intelligent" indices which recognize each other and automatically contract, regardless of the order they are in. ITensor works behind the scenes to make sure this is done as efficiently as possible.

To contract two ITensors, use
the `*`

operator, which *contracts all matching indices*.
Some pairs of indices may match, yet you do not want them to be
contracted. To prevent this from happening, change the prime
level of such indices on one or both tensors as in the
second example below.

### A Simple Example

Given three distinct Index objects i,j, and k, say we make the following ITensors:

```
auto A = ITensor(i,j);
auto B = ITensor(k,j);
```

Then the following code contracts over the index j

```
auto C = A * B;
```

In traditional notation this means performing the sum

If there had been other matching indices
between A and B other than j, the `*`

operator would have contracted
them too. Indices i and k did not match (they could be copies of the
same Index but we are assuming this is not the case) so they remain
uncontracted and become the indices of C.

Interestingly, because of the way ITensor contraction is defined,
`B*A`

gives the same result as `A*B`

.
ITensor contraction is a commutative operation.

### A More Complex Example

Of course, the real usefulness of a tensor library is handling cases where tensors have three or more indices.

Say we have an ITensor with indices i,s, and j

```
auto W = ITensor(i,s,j);
```

and want to contract W with itself, summing over indices i and j, but leaving s uncontracted.

In traditional tensor notation, we want to compute

But this notation can become cumbersome for more complicated contractions.

A nicer way to notate a tensor contraction is by using a diagram

In diagram notation a tensor is a blob and each line denotes an index. Connecting two lines implies those indices are summed over. The remaining unpaired lines are the indices of the resulting tensor.

Both notations indicate our contraction strategy should be to
prime the Index s on one copy of W. Calling `prime(W,s)`

returns
a copy of W with s replaced by s'. Then multiplying

```
auto D = W * prime(W,s);
```

automatically contracts i and j, but not s and s' since these no longer compare equal. Printing the result D confirms that it has only s and s' as indices.

ITensor Basics Factorizing ITensors

Back to Book

Back to Main