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
.
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.