# ITensor Basics

The ITensor, or intelligent tensor, is the basic tensor of the ITensor library.

The simplest way to construct an ITensor is to provide its indices:

```
auto i = Index(2,"index i");
auto j = Index(3,"index j");
auto k = Index(4,"index k");
auto T = ITensor(i,j,k);
```

This creates an ITensor T with all elements set to zero.

To confirm this is an order 3 tensor (a tensor with 3 indices), call `order(T)`

:

```
println("The order of T is ",order(T));
//prints: The order of T is 3
```

```
#include "itensor/all.h"
using namespace itensor;
int main()
{
auto i = Index(2,"index i");
auto j = Index(3,"index j");
auto k = Index(4,"index k");
auto T = ITensor(i,j,k);
println("The order of T is ",order(T));
return 0;
}
```

### Accessing ITensor Elements

To set a particular element, or component, of an ITensor call its `.set`

method:

```
T.set(i=2,j=1,k=3, 4.56);
```

This sets the i=2,j=1,k=3 element of the tensor to the value 4.56.

In a more conventional tensor interface, the above operation might look something like

```
T[2,1,3] = 4.56; //not actual ITensor code!!
```

where the user would have to remember that the first entry corresponds to index i, the second to index j, and the third to index k.

For an ITensor, the reason the indices are passed to the `.set`

method along with their values
is that nothing about the ITensor interface requires knowing the index order.

If we gave the Index-value pairs such as `j=2`

in a different order,
the `.set`

method still accesses the correct element. A call such as

```
T.set(k=3,i=2,j=1, 4.56);
```

has exactly the same outcome as the call

```
T.set(i=2,j=1,k=3, 4.56);
```

We can retrieve an element by using the `elt`

function:

```
auto x = elt(T,k=3,i=2,j=1);
println("x = ",x);
//prints: x = 4.56
```

We can also set elements of ITensors to be complex numbers:

```
T.set(i=2,k=3,j=1, 7+8_i);
```

Now we must use the `eltC`

function to retrieve this element as a
complex data type; calling `elt`

would throw an exception:

```
auto z = eltC(T,i=2,k=3,j=1);
println("z = ",z);
//prints: z = (7,8)
```

The `eltC`

function always succeeds even if the tensor has only real elements.

### Printing ITensors

A convenient way to print an ITensor is to use the `Print`

macro:

```
Print(T);
//prints:
// T =
// ITensor ord = 3: (2|id=483|"index i") (3|id=97|"index j") (4|id=922|"index k")
```

Calling `Print(expr)`

essentially rewrites the code to be `println("expr = ",expr)`

,
which is why there is a "T = " at the beginning of the output.

The output shows information about the indices, but not the ITensor elements because this could lead to a very large output.

To see the non-zero elements resulting from our earlier calls to `.set`

,
we can use the `PrintData`

macro, which prints both
the indices and the non-zero elements:

```
PrintData(T);
//prints:
// T =
// ITensor ord = 3: (2|id=483|"index i") (3|id=97|"index j") (4|id=922|"index k")
// (2,2,1) 7.00+8.00i
// (1,2,3) 4.56+0.00i
```

### Basic Mathematical Operations

ITensors can be added, subtracted, and multiplied by scalars in the usual way:

```
auto Q = 2*T;
auto R = Q/3 + T*4_i;
auto S = R - T;
S *= 5;
//etc.
```

Two ITensors can be added and subtracted if they have the same set of indices, regardless of the index ordering. Internally, the tensor data will be permuted if the index ordering is different, guaranteeing the correct result.

The norm of an ITensor (square root of sum of squared elements) can be computed
using the `norm`

function

```
println("The norm of T is ",norm(T));
```

*For a complete listing of all of the methods of class ITensor, view the
detailed documentation.*

Index Objects Contracting ITensors

Back to Book

Back to Main