Arrays¶
Important
#include "higra/structure/array.hpp
The preferred way to represent homogeneous tabular data in higra is through the use of xtensor multi-dimentional arrays. Xtensor aims at providing numpy like arrays in C++: take a look at the numpy->xtensor cheat sheet .
Higra defines some commodity types (aliases) that map to particular xtensor types. There are 3 categories of types:
points, ie. 1 dimensional arrays of fixed size: they do not require heap allocated memory and benefit from a lot of compile time optimization;
fixed dimension arrays of variable size: they require heap allocated memory but, thanks to their fixed dimension, they also benefit from compile time optimization;
variable dimension arrays of variable size: they require heap allocated memory.
Therefore, using the most specific type compatible with your needs will provide better performances.
Typename |
Template |
Description |
Base type |
---|---|---|---|
|
|
An n dimensional point |
|
|
A two dimentional point with real coordinates ( |
|
|
|
A two dimentional point with integral coordinates ( |
|
|
|
A three dimentional point with real coordinates ( |
|
|
|
A three dimentional point with integral coordinates ( |
|
|
|
A four dimentional point with real coordinates ( |
|
|
|
A four dimentional point with integral coordinates ( |
|
|
|
|
A one dimentional array |
|
|
|
A two dimentional array |
|
|
|
A three dimentional array |
|
|
|
A four dimentional array |
|
|
|
A n-dimentional array (n being defined at runtime) |
|
Quick start¶
Creating arrays¶
From scratch:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // explicit initialization array_2d<int> a1 {{1, 2, 3}, {4, 5, 6}}; // empty (non initialized) array of given shape array_2d<int> a2 = array_1d<int>::from_shape({2, 3}); // array of given shapes initialized with given value array_2d<int> a3({2, 3}, 5); // array of given shapes initialized with 0 array_2d<int> a4 = xt::zeros<int>({2, 3}); // array of given shapes initialized with 1 array_2d<int> a5 = xt::ones<int>({2, 3}); |
From an existing array:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | array_2d<int> a1 {{1, 2, 3}, {4, 5, 6}}; // same shape and value type, non-initialized auto a2 = xt::empty_like(a1); // same shape and value type, initialized to 0 auto a3 = xt::zeros_like(a1); // same shape and value type, initialized to 1 auto a4 = xt::ones_like(a1); // same shape and value type, initialized to given value auto a5 = xt::full_like(a1, 5); |
Properties¶
1 2 3 4 5 6 7 8 9 10 11 12 13 | array_2d<int> a1 {{1, 2, 3}, {4, 5, 6}}; // dimension auto d = a1.dimension(); // 2 // size auto s = a1.size(); // 6 // shape auto sh = a1.shape(); sh[0]; // 2 sh[1]; // 3 |
Element access¶
1 2 3 4 5 6 7 8 9 10 | array_2d<int> a1 {{1, 2, 3}, {4, 5, 6}}; // modify and read element at line 1, column 2 a1(1, 2) = 7; int v = a1(1, 2); // Same thing with the [] operator a1[{1, 2}] = 7; int v = a1[{1, 2}]; |
Display¶
1 2 3 4 5 6 7 8 | #include <iostream> #include <xtensor/xio.hpp> using namespace std; array_2d<int> a1 {{1, 2, 3}, {4, 5, 6}}; cout << a1 << "\n"; |
Lazy Evaluation¶
Most xtensor operations are lazily evaluated. In the following situation:
1 2 3 4 | array_1d<int> a1{1, 2, 3}; array_1d<int> a2{4, 5, 6}; auto r = a2 * (a1 + a2); |
r does only store the expression, i.e. the symbolic operation, but no actual results. The result will be computed when elements are accessed:
1 | auto v = r(1); // performs 5 * (2 + 5) |
If an expression is evaluated several times at the same position, the same result will be computed several times.
An expression can be fully evaluated by assigning it to an actual array or by using the eval function:
1 2 | array_1d<int> ar1 = r; // evaluates the expression r and assigns the result to ar1 auto ar2 = xt::eval(r); // evaluates r and assigns it to an array called ar2 |
Attention
Returning a non evaluated expression that refers to local variable will lead to undefined behaviors:
1 2 3 4 5 6 | auto function(){ array_1d<int> a1{1, 2, 3}; array_1d<int> a2{4, 5, 6}; //return a1 + a2; => ERROR depends of local variables that are destructed at the end of the function return xt::eval(a1 + a2); // OK } |