# Indices

## Definition

There are two types of indices: array indices and flat indices. Consider this example (stored in row-major):

```#include <xtensor/xtensor.hpp>
#include <xtensor/xarray.hpp>
#include <xtensor/xio.hpp>

int main()
{
xt::xarray<size_t> a = xt::arange<size_t>(3 * 4);

a.reshape({3,4});

std::cout << a << std::endl;
}
```

Which prints

```{{ 0,  1,  2,  3},
{ 4,  5,  6,  7},
{ 8,  9, 10, 11}}
```

The array index `{1, 2}` corresponds to the flat index `6`.

## Operators: array index

An array index can be specified to an operators by a sequence of numbers. To this end the following operators are at your disposal:

### `operator()(args...)`

Returns a (constant) reference to the element, specified by an array index given by a number of unsigned integers.

• If the number of indices is less that the dimension of the array, the indices are pre-padded with zeros until the dimension is matched (example: `a(2) == a(0, 2) == 2`).

• If the number of indices is greater than the dimension of the array, the first `#indices - dimension` indices are ignored.

• To post-pad an arbitrary number of zeros use `xt::missing` (example `a(2, xt::missing) == a(2, 0) == 8`.

### `at(args...)`

Same as `operator()()`: Returns a (constant) reference to the element, specified by an array index given by a number of unsigned integers.

### `unchecked(args...)`

Returns a (constant) reference to the element, specified by an array index given by a number of unsigned integers. Different than `operator()()` there are no bounds checks (even when assertions) are turned on, and the number of indices is assumed to match the dimension of the array. `unchecked()` is thus aimed at performance.

Note

If you assume responsibility for bounds-checking, this operator can be used to virtually post-pad zeros if you specify less indices than the rank of the array. Example: `a.unchecked(1) == a(1, 0)`.

### `periodic(args...)`

Returns a (constant) reference to the element, specified by an array index given by a number of signed integers. Negative and ‘overflowing’ indices are changed by assuming periodicity along that axis. For example, for the first axis: `-1 -> a.shape(0) - 1 = 2`, likewise for example `3 -> 3 - a.shape(0) = 0`. Of course this comes as the cost of some extra complexity.

### `in_bounds(args...)`

• Example: `a.in_bounds(1, 2) == true`.

• See also: `xt::xcontainer::in_bounds()`.

Check if the array index is ‘in bounds’, return `false` otherwise.

### `operator[]({...})`

• Example: `a[{1, 2}] == 6`.

• See also: `xt::xcontainer::operator[]()`.

Returns a (constant) reference to the element, specified by an array index given by a list of unsigned integers.

## Operators: flat index

### `flat(i)`

Returns a (constant) reference to the element specified by a flat index, given an unsigned integer.

Note

If the layout would not have been the default row major, but column major, then `a.flat(6) == 2`.

Note

In many cases `a.flat(i) == a.data()[i]`.

## Array indices

Functions like `xt::argwhere(a < 5)` return a `std::vector` of array indices. Using the same matrix as above, we can do

```int main()
{
xt::xarray<size_t> a = xt::arange<size_t>(3 * 4);

a.reshape({3,4});

auto idx = xt::from_indices(xt::argwhere(a >= 6));

std::cout << idx << std::endl;
}
```

which prints

```{{1, 2},
{1, 3},
{2, 0},
{2, 1},
{2, 2},
{2, 3}}
```

To print the `std::vector`, it is converted to a `xt::xtensor<size_t, 2>` array, which is done using `xt::from_indices()`.

## From array indices to flat indices

To convert the array indices to a `xt::xtensor<size_t, 1>` of flat indices, `xt::ravel_indices()` can be used. For the same example:

```#include <xtensor/xtensor.hpp>
#include <xtensor/xarray.hpp>
#include <xtensor/xio.hpp>

int main()
{
xt::xarray<size_t> a = xt::arange<size_t>(3 * 4);

a.reshape({3,4});

auto idx = xt::ravel_indices(xt::argwhere(a >= 6), a.shape());

std::cout << idx << std::endl;
}
```

which prints

```{ 6,  7,  8,  9, 10, 11}
```

Note

To convert to a `std::vector` use

```auto idx = xt::ravel_indices<xt::ravel_vector_tag>(xt::argwhere(a >= 6), a.shape());
```

## 1-D arrays: array indices == flat indices

For 1-D arrays the array indices and flat indices coincide. One can use the generic functions `xt::flatten_indices()` to get a `xt::xtensor<size_t, 1>` of (array/flat) indices. For example:

```#include <xtensor/xtensor.hpp>
#include <xtensor/xview.hpp>
#include <xtensor/xio.hpp>

int main()
{
xt::xtensor<size_t, 1> a = xt::arange<size_t>(16);

auto idx = xt::flatten_indices(xt::argwhere(a >= 6));

std::cout << idx << std::endl;

std::cout << xt::view(a, xt::keep(idx)) << std::endl;
}
```

which prints the indices and the selection (which are in this case identical):

```{ 6,  7,  8,  9, 10, 11, 12, 13, 14, 15}
{ 6,  7,  8,  9, 10, 11, 12, 13, 14, 15}
```

## From flat indices to array indices

To convert flat indices to array_indices the function `xt::unravel_indices()` can be used. For example

```#include <xtensor/xarray.hpp>
#include <xtensor/xtensor.hpp>
#include <xtensor/xstrides.hpp>
#include <xtensor/xio.hpp>

int main()
{
xt::xarray<size_t> a = xt::arange<size_t>(3 * 4);

a.reshape({3,4});

auto flat_indices = xt::ravel_indices(xt::argwhere(a >= 6), a.shape());

auto array_indices = xt::from_indices(xt::unravel_indices(flat_indices, a.shape()));

std::cout << "flat_indices = " << std::endl << flat_indices << std::endl;
std::cout << "array_indices = " << std::endl << array_indices << std::endl;
}
```

which prints

```flat_indices =
{ 6,  7,  8,  9, 10, 11}
array_indices =
{{1, 2},
{1, 3},
{2, 0},
{2, 1},
{2, 2},
{2, 3}}
```

Notice that once again the function `xt::from_indices()` has been used to convert a `std::vector` of indices to a `xt::xtensor` array for printing.