hexed 0.3.0
 
Loading...
Searching...
No Matches
hexed::Array< T > Class Template Reference

Represents a dynamic-sized multidimensional array. More...

#include <Array.hpp>

Public Types

typedef T * iterator
 Iterator type to allow Array to function like a * standard container. *
 
typedef const T * constiterator
 Iterator type to allow Array to function like a * standard container. *
 

Public Member Functions

 Array (std::vector< int > shape_arg, T *data_arg)
 Creates an array from scratch.
 
 Array (std::vector< int > shape_arg)
 Creates an array from scratch.
 
template<typename input_it >
 Array (std::vector< int > shape_arg, input_it first, input_it last)
 
 Array (std::vector< int > shape_arg, std::function< T(std::size_t)> func)
 
template<int sz>
 Array (Eigen::Vector< T, sz > vec)
 Constructs an array from an Eigen::Vector.
 
 Array (Array< T > &other)
 Creates an array which is a reference to other's data.
 
 Array (Array< T > &&other)
 Steals whatever assets other had.
 
Array< T > & operator= (const Array< T > &other)
 Assigns the values in other to this.
 
Array< T > & operator= (const T &value)
 Sets all entries to the specified value.
 
Array< T > & operator= (T *ptr)
 Sets the entries to the first size() objects pointed to by ptr.
 
template<typename U = T>
Array< U > copy () const
 Creates a new array that owns its data, which is a copy of this's data (i.e. new data is allocated).
 
int order () const
 Returns the number of dimensions of the Array.
 
std::vector< int > shape () const
 Fetches the shape (size of each dimension) of the Array.
 
int size () const
 Returns the total size of the array.
 
bool same_shape (const Array< T > &other)
 true iff this and other have the same shape().
 
int stride (int i_dim) const
 The stride for indexing along demension i_dim.
 
T * data ()
 fetches pointer to data
 
T & operator[] (int i)
 Accesses elements by flat indexing. *.
 
Array< T > operator() ()
 Creates an array as a reference to this's data.
 
Array< T > operator() (int i)
 Creates an array which is a view of the ith "row" of this. *.
 
Array operator() (int start, int stop)
 Creates an array which is a view of rows [start, stop) of this. *.
 
Array reshaped (std::vector< int > new_shape)
 Returns an array referencing the same data as this but with a different shape. *.
 
iterator begin ()
 Iterator to beginning of (flat) data.
 
iterator end ()
 Iterator 1 word past the end of (flat) data.
 
Eigen::Map< Eigen::Matrix< T, dyn, 1 > > vector ()
 view of data as an Eigen vector object
 
const T * data () const
 fetches pointer to data
 
const T & operator[] (int i) const
 Accesses elements by flat indexing. *.
 
const Array< T > operator() () const
 Creates an array as a reference to this's data.
 
const Array< T > operator() (int i) const
 Creates an array which is a view of the ith "row" of this. *.
 
const Array operator() (int start, int stop) const
 Creates an array which is a view of rows [start, stop) of this. *.
 
const Array reshaped (std::vector< int > new_shape) const
 Returns an array referencing the same data as this but with a different shape. *.
 
constiterator begin () const
 Iterator to beginning of (flat) data.
 
constiterator end () const
 Iterator 1 word past the end of (flat) data.
 
const Eigen::Map< Eigen::Matrix< T, dyn, 1 > > vector () const
 view of data as an Eigen vector object
 
Array< T > & operator-= (const Array< T > &that)
 
template<typename Scalar >
Array< T > & operator-= (Scalar s)
 
Array< T > & operator+= (const Array< T > &that)
 
template<typename Scalar >
Array< T > & operator+= (Scalar s)
 
Array< T > & operator/= (const Array< T > &that)
 
template<typename Scalar >
Array< T > & operator/= (Scalar s)
 
Array< T > & operator*= (const Array< T > &that)
 
template<typename Scalar >
Array< T > & operator*= (Scalar s)
 
Array< T > & operator%= (const Array< T > &that)
 
template<typename Scalar >
Array< T > & operator%= (Scalar s)
 

Static Public Member Functions

template<typename... U>
static Array< T > make (U... args)
 Constructs a 1D array whose elements are args.
 

Detailed Description

template<typename T>
class hexed::Array< T >

Represents a dynamic-sized multidimensional array.

This is an array-style container designed to meet the following objectives:

  • Data is contiguous in memory.
  • Supports an arbitrary number of dimensions.
  • Can own its own data or be a reference to separately-allocated data.
  • A subset of an Array can be accessed with another Array, so that a single function can accept a whole array or a slice without requiring overloads for different types.

Neither the standard library nor Eigen appear to supply a container that meets these criteria. This is a mid-performance class. For absolutely optimum performance, you can use data() and work with the raw pointer. Data is stored in row-major order. Also, here is an overview of how to manage ownership with this class, although this information is also scattered through the member documentation.

  • To create a new array that owns its data, use Array(std::vector<int>).
  • To create a new array that references data in another array, use Array(other).
  • To create a new array that references existing data that is not in an array, use Array(std::vector<int>, T*)
  • To create a new array that is a copy of an existing array (allocating new data), use Array(other.copy())
  • To copy data from an existing array to another (of the same size) without allocating or creating references, use the = operator.

If you want to pass an Array as a function argument, you should be able to pass it by value without thinking about it. Due to the way the copy and move constructors are set up, this should not cause any significant additional allocations unless you explicitly call copy(), and if you're passing a temporary object, it should be preserved as long as it needs to be with the move constructor.

By default, if DEBUG is defined, then dynamic bounds checking is performed and out-of-bounds access will result in an exception. Otherwise, no bounds checking is performed and out-of-bounds access is undefined behavior. This can be overridden by explicitly defining the HEXED_ARRAY_BOUNDS_CHECK macro to be true or false.

Arrays support the unary arithmetic operators - and + as well as the binary operators -, +, /, *, %, &&, and ||. Binary operators can operate on two arrays or on an array and a scalar. All operators perform their operations elementwise. They always create a copy, so for truly optimal performance you might consider a loop instead. For binary operators, both operands (arrays or scalars) must have the same data type. To perform operations on arrays that have different, but compatible, types, you can cast them to the same type with Array::copy<U>().

Note
Implementing a feature-complete array container is a large task, and I have not yet implemented all of the features that I ultimately plan to. If there is a feature you want and feel that an array class ought to have, feel free to let me know and I may be able to move it up in the queue.

Member Typedef Documentation

◆ constiterator

template<typename T >
typedef const T* hexed::Array< T >::constiterator

Iterator type to allow Array to function like a * standard container. *

Iterators remain valid throughout the lifetime of the array, * since there is no mechanism that changes the address of its underlying data.

◆ iterator

template<typename T >
typedef T* hexed::Array< T >::iterator

Iterator type to allow Array to function like a * standard container. *

Iterators remain valid throughout the lifetime of the array, * since there is no mechanism that changes the address of its underlying data.

Constructor & Destructor Documentation

◆ Array() [1/5]

template<typename T >
hexed::Array< T >::Array ( std::vector< int > shape_arg,
T * data_arg )
inline

Creates an array from scratch.

Array will have dimensions specified by shape_arg. This array will be a reference to the data starting at data_arg and will not own that data.

◆ Array() [2/5]

template<typename T >
hexed::Array< T >::Array ( std::vector< int > shape_arg)
inline

Creates an array from scratch.

Array will have dimensions specified by shape_arg. This array will allocate new data, which it will now own. Data values are uninitialized.

◆ Array() [3/5]

template<typename T >
template<int sz>
hexed::Array< T >::Array ( Eigen::Vector< T, sz > vec)
inline

Constructs an array from an Eigen::Vector.

Elements are copied.

◆ Array() [4/5]

template<typename T >
hexed::Array< T >::Array ( Array< T > & other)
inline

Creates an array which is a reference to other's data.

Note that this array does not own the data, and if other is deleted it will now contain a dangling pointer.

◆ Array() [5/5]

template<typename T >
hexed::Array< T >::Array ( Array< T > && other)
inline

Steals whatever assets other had.

If other owned its data, this will steal that data. If other had a reference to existing data, this will also be a reference to that data. Leaves other in an unspecified but valid state.

Member Function Documentation

◆ copy()

template<typename T >
template<typename U = T>
Array< U > hexed::Array< T >::copy ( ) const
inline

Creates a new array that owns its data, which is a copy of this's data (i.e. new data is allocated).

If the template argument is specified to be something other than T, the array will be cast to a different type. The old type must by copy-assignable to the new type.

◆ operator()() [1/4]

template<typename T >
Array< T > hexed::Array< T >::operator() ( int i)
inline

Creates an array which is a view of the ith "row" of this. *.

Resulting array will have 1 less order() * and shape equal to the shape of this but with the first element removed. * You can think of it as equivalent to the operator [] of multidimensional builtin arrays * or NumPy arays. * For example, if you have an order 3 array a with shape {10, 4, 5}, you can access the element at (5, 2, 3) * with either a[113] (5*4*5 + 2*5 + 3 = 113) or a(5)(2)[3].

◆ operator()() [2/4]

template<typename T >
const Array< T > hexed::Array< T >::operator() ( int i) const
inline

Creates an array which is a view of the ith "row" of this. *.

Resulting array will have 1 less order() * and shape equal to the shape of this but with the first element removed. * You can think of it as equivalent to the operator [] of multidimensional builtin arrays * or NumPy arays. * For example, if you have an order 3 array a with shape {10, 4, 5}, you can access the element at (5, 2, 3) * with either a[113] (5*4*5 + 2*5 + 3 = 113) or a(5)(2)[3].

◆ operator()() [3/4]

template<typename T >
Array hexed::Array< T >::operator() ( int start,
int stop )
inline

Creates an array which is a view of rows [start, stop) of this. *.

As indicated by the interval notation, includes start but not stop. * If stop is less than start or not less than size()[0], * this results in an array with 0 as the first entry of its shape (and consequently size 0). * This will not result in an exception nor undefined behavior, * unless of course you attempt to access data from this empty array. * Equivalent to array[start:stop] for * NumPy arays. * The resulting array will have the same order as this. * The first entry of shape() will be stop - start and the rest will be the same as this * (granted the above caveat about empty results).

◆ operator()() [4/4]

template<typename T >
const Array hexed::Array< T >::operator() ( int start,
int stop ) const
inline

Creates an array which is a view of rows [start, stop) of this. *.

As indicated by the interval notation, includes start but not stop. * If stop is less than start or not less than size()[0], * this results in an array with 0 as the first entry of its shape (and consequently size 0). * This will not result in an exception nor undefined behavior, * unless of course you attempt to access data from this empty array. * Equivalent to array[start:stop] for * NumPy arays. * The resulting array will have the same order as this. * The first entry of shape() will be stop - start and the rest will be the same as this * (granted the above caveat about empty results).

◆ operator=()

template<typename T >
Array< T > & hexed::Array< T >::operator= ( const Array< T > & other)
inline

Assigns the values in other to this.

other and this must have the same shape. Not allocations are performed and no new references are created. You are simply assigning values to existing data.

◆ operator[]() [1/2]

template<typename T >
T & hexed::Array< T >::operator[] ( int i)
inline

Accesses elements by flat indexing. *.

Equivalent to data()[i], give or take bounds checking

◆ operator[]() [2/2]

template<typename T >
const T & hexed::Array< T >::operator[] ( int i) const
inline

Accesses elements by flat indexing. *.

Equivalent to data()[i], give or take bounds checking

◆ order()

template<typename T >
int hexed::Array< T >::order ( ) const
inline

Returns the number of dimensions of the Array.

If you think of the array as a tensor, then this is the order of the tensor.

◆ reshaped() [1/2]

template<typename T >
Array hexed::Array< T >::reshaped ( std::vector< int > new_shape)
inline

Returns an array referencing the same data as this but with a different shape. *.

The new size must be less than or equal to the old size, or else behavior is undefined. * If any entries of new_shape are hexed::same, * then they will be converted to the entry of the current shape at the same index. * E.g., if shape() is {2, 3, 4} and you call reshape({1, same, 4}), * the resulting shape will be {1, 3, 4}. * Of course, the index of any same arguments must be less than order(). * If exactly one of the entries of new_shape is whatever, * it will be converted to whatever value is necessary to keep the size the same. * Making more than 1 entry whatever is not allowed. * Note that reshaping maintains the underlying (row-major) storage order of the values * (unlike Eigen's [conservativeResize] * (https://eigen.tuxfamily.org/dox/classEigen_1_1PlainObjectBase.html#a712c25be1652e5a64a00f28c8ed11462)), * so it can't generally be used to select a block of an Array. * It is more useful for adding or removing dimensions. * E.g., array.reshaped({whatever}) flattens array.

◆ reshaped() [2/2]

template<typename T >
const Array hexed::Array< T >::reshaped ( std::vector< int > new_shape) const
inline

Returns an array referencing the same data as this but with a different shape. *.

The new size must be less than or equal to the old size, or else behavior is undefined. * If any entries of new_shape are hexed::same, * then they will be converted to the entry of the current shape at the same index. * E.g., if shape() is {2, 3, 4} and you call reshape({1, same, 4}), * the resulting shape will be {1, 3, 4}. * Of course, the index of any same arguments must be less than order(). * If exactly one of the entries of new_shape is whatever, * it will be converted to whatever value is necessary to keep the size the same. * Making more than 1 entry whatever is not allowed. * Note that reshaping maintains the underlying (row-major) storage order of the values * (unlike Eigen's [conservativeResize] * (https://eigen.tuxfamily.org/dox/classEigen_1_1PlainObjectBase.html#a712c25be1652e5a64a00f28c8ed11462)), * so it can't generally be used to select a block of an Array. * It is more useful for adding or removing dimensions. * E.g., array.reshaped({whatever}) flattens array.

◆ same_shape()

template<typename T >
bool hexed::Array< T >::same_shape ( const Array< T > & other)
inline

true iff this and other have the same shape().

It's okay to call this on arrays of different order(); naturally it will return false.

◆ size()

template<typename T >
int hexed::Array< T >::size ( ) const
inline

Returns the total size of the array.

This is the number of values you can access with the [] operator, or equivalently the product of the entries of shape().

◆ stride()

template<typename T >
int hexed::Array< T >::stride ( int i_dim) const
inline

The stride for indexing along demension i_dim.

E.g.,

  • arr(1).data() == arr.data() + arr.stride(0)
  • arr(0)(1).data() == arr.data() + arr.stride(1)

The documentation for this class was generated from the following file: