ndarray
NumPy-friendly multidimensional arrays in C++
|
ndarray is a template library that provides multidimensional array objects in C++, with an interface and features designed to mimic the Python 'numpy' package as much as possible.
A tutorial can be found here.
A number of other public C++ multidimensional array libraries already exist, such as boost.MultiArray, Blitz++, and xtensor. Much of the architecture and some of the interface of the ndarray templates is built on ideas from both of these, particularly boost.MultiArray. ndarray supports shared ownership of data, lazy evaluation of mathematical operations using expression templates, and the ability to use externally allocated memory. It also supports optimized, natural, nested iteration and preserve const-correctness (albeit with different semantics).
While ndarray can perform numerical operations with broadcasting, it makes no attempt to perform explicit vectorization, and libraries that focus more on computational performance will be better at it in almost every context. ndarray's goal is to provide lightweight, flexible data structures with a more Python-friendly ownership model, while maintaining enough static typing to allow optimized libraries (such as Eigen) to work effectively on ndarray-managed arrays.
The memory used by ndarray objects is reference counted, and can be allocated using any STL-compatible allocator. Arrays can also be constructed from external memory buffers, with full reference counting for any external memory owned by an object that participates in any reference-counting scheme (most notably memory belonging to Python Numpy arrays in C++ Python extensions). Reference counting can also be disabled for individual arrays that reference external memory that is not reference-counted.
Array objects in ndarray preserve constness in the same way as most C++ smart pointers: there is a distinction between an array with const elements (Array<T const,N>) and a const array value or reference (Array<T,N> const). An array with const elements does not support operations that change element values ("deep" operations), while a const array object or reference does not allow the array's data pointer, shape, or strides to be changed ("shallow" operations). As a result, functions should generally use const references for both input and output array arguments (with const and non-const elements, respectively). Arrays with non-const elements are implicitly (and efficiently) convertible to arrays with const elements, while an array with const elements can be cast to one with non-const elements using the const_array_cast function.
In addition to being templated on its element type and total number of dimensions, Array is parameterized by the number of guaranteed row-major contiguous (RMC) dimensions, starting from the end. This parameter defaults to zero. For example:
An Array with M RMC dimensions can be implicitly converted to an Array with N<=M RMC dimensions. The static_dimension_cast
and dynamic_dimension_cast
functions can be used to create arrays with M<N RMC dimensions (dynamic_dimension_cast returns an empty Array if the strides are not appropriately RMC, while static_dimension_cast does no checking).
An Array with dimension N>1 behaves like largely like an STL container of Array of dimension N-1. An Array with dimension 1 behaves like a simple container of elements. Iterators over an Array with N>1 thus dereference to Arrays with dimension N-1, and standard [] indexing also yields the expected lower-dimensional array.
Arbitrary views can be retrieved by passing a view definition to an Array's bracket indexing operators. These view definitions are temporaries created by the view() function:
Supplying a single integer indexes a dimension by a scalar (which reduces the dimension of output), supplying a pair of integers indicates a contiguous range, and supplying three integers indicates a slice. Specifying no arguments for a dimension includes the entire dimension. Not indexing all dimensions is equivalent to including empty parentheses for the remaining dimensions.
https://github.com/ndarray/ndarray/releases
ndarray is distributed under a simple BSD-like license: https://github.com/ndarray/ndarray/blob/master/LICENSE