SyDEVS  v0.6.5
Multiscale Simulation and Systems Modeling Library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
sydevs::arraynd< T, ndims > Class Template Reference

A class template for a multidimensional array with elements of type T arranged in a lattice of ndims dimensions. More...

#include <arraynd.h>

Inherits sydevs::arraynd_base< T, ndims >.

Public Member Functions

 arraynd ()
 Constructs an arraynd object with dimensions of length zero. More...
 
 arraynd (const std::array< int64, ndims > &dims, const T &value)
 Constructs an arraynd object with the specified dimensions dims and all elements initialized to value. More...
 
 arraynd (const std::array< int64, ndims > &dims, const std::vector< T > &data)
 Constructs an arraynd object with the specified dimensions dims and elements initialized with the supplied data. More...
 
 arraynd (const std::array< int64, ndims > &dims, std::function< T(const std::array< int64, ndims > &indices)> func)
 Constructs an arraynd object with the specified dimensions dims and elements initialized using the function object func. More...
 
 arraynd (const arraynd< T, ndims > &)=default
 Copy constructor (if rhs.is_view(), data is shared; otherwise data is copied) More...
 
arraynd< T, ndims > & operator= (const arraynd< T, ndims > &)=default
 Copy assignment (if !is_view() && rhs.is_view(), data is shared; otherwise data is copied) More...
 
 arraynd (arraynd< T, ndims > &&)=default
 Move constructor (data is shared) More...
 
arraynd< T, ndims > & operator= (arraynd< T, ndims > &&)=default
 Move assignment (data is shared) More...
 
 ~arraynd ()=default
 Destructor. More...
 
const arraynd< T, ndims-1 > operator[] (int64 index) const
 Create a const slice with one dimension replaced by referencing elements at the specified index (data is shared). More...
 
arraynd< T, ndims-1 > operator[] (int64 index)
 Create a slice with one dimension replaced by referencing elements at the specified index (data is shared). More...
 
const arraynd< T, ndims > operator[] (range r) const
 Create a const slice with one dimension filtered by referencing elements in the specified range r (data is shared). More...
 
arraynd< T, ndims > operator[] (range r)
 Create a slice with one dimension filtered by referencing elements in the specified range r (data is shared). More...
 
const arraynd< T, ndims > view () const
 Create a const view of the multidimensional array (data is shared). More...
 
arraynd< T, ndims > view ()
 Create a view of the multidimensional array (data is shared). More...
 
arraynd< T, ndims > copy () const
 Create a deep copy of the multidimensional array (data is copied). More...
 
const arraynd< T, ndims > view_transposed () const
 Create a const transposed view of the multidimensional array (data is shared). More...
 
arraynd< T, ndims > view_transposed ()
 Create a transposed view of the multidimensional array (data is shared). More...
 
arraynd< T, ndims > copy_transposed () const
 Create a transposed deep copy of the multidimensional array (data is copied). More...
 
const arraynd< T, ndims > view_swapped_axes (int64 idim0, int64 idim1) const
 Create a const view with dimensions idim0 and idim1 swapped (data is shared). More...
 
arraynd< T, ndims > view_swapped_axes (int64 idim0, int64 idim1)
 Create a view with dimensions idim0 and idim1 swapped (data is shared). More...
 
arraynd< T, ndims > copy_swapped_axes (int64 idim0, int64 idim1) const
 Create a deep copy with dimensions idim0 and idim1 swapped (data is copied). More...
 
const arraynd< T, ndims+1 > view_subdivided_axis (int64 idim, const std::array< int64, 2 > &dims) const
 Create a const view with dimension idim split into two dimensions with lengths given by dims (data is shared). More...
 
arraynd< T, ndims+1 > view_subdivided_axis (int64 idim, const std::array< int64, 2 > &dims)
 Create a view with dimension idim split into two dimensions with lengths given by dims (data is shared). More...
 
arraynd< T, ndims+1 > copy_subdivided_axis (int64 idim, const std::array< int64, 2 > &dims) const
 Create a deep copy with dimension idim split into two dimensions with lengths given by dims (data is copied). More...
 
const arraynd< T, ndims-1 > view_absorbed_axis (int64 idim) const
 Create a const view with dimension idim absorbed into dimension idim - 1 (data is shared). More...
 
arraynd< T, ndims-1 > view_absorbed_axis (int64 idim)
 Create a view with dimension idim absorbed into dimension idim - 1 (data is shared). More...
 
arraynd< T, ndims-1 > copy_absorbed_axis (int64 idim) const
 Create a deep copy with dimension idim absorbed into dimension idim - 1 (data is copied). More...
 
- Public Member Functions inherited from sydevs::arraynd_base< T, ndims >
 ~arraynd_base ()=default
 Destructor. More...
 
std::array< int64, ndims > dims () const
 Returns the lengths of each dimension. More...
 
std::array< int64, ndims > strides () const
 Returns the number of element-size steps in memory between successive elements for each dimension. More...
 
bool empty () const
 Returns true if there is at least one element. More...
 
int64 size () const
 Returns the total number of elements. More...
 
int64 offset () const
 Returns the number of element-size steps in memory before the first element. More...
 
const T * data () const
 Returns a pointer to the element data (const). More...
 
T * data ()
 Returns a pointer to the element data. More...
 
bool is_contiguous () const
 Returns true if a row-major traversal of the multidimensional array accesses each element of data in sequence. More...
 
bool is_view () const
 Returns true if this multidimensional array is a view of another, meaning that data is shared. More...
 
bool is_readonly () const
 Returns true if the data is readonly, in which case attempts to modify it raise a std::logic_error. More...
 
const T & operator() (const std::array< int64, ndims > &indices) const
 Returns a reference to an element (const). More...
 
T & operator() (const std::array< int64, ndims > &indices)
 Returns a reference to an element. More...
 
const T & operator() (const arraynd_base< int64, 1 > &indices) const
 Returns a reference to an element (const). More...
 
T & operator() (const arraynd_base< int64, 1 > &indices)
 Returns a reference to an element. More...
 
template<typename... Indices>
const T & operator() (Indices...indices) const
 Returns a reference to an element (const). More...
 
template<typename... Indices>
T & operator() (Indices...indices)
 Returns a reference to an element. More...
 
void fill (const T &value)
 Replaces every element with value. More...
 
void assign (const arraynd_base< T, ndims > &rhs)
 Replaces every element with the corresponding value in rhs. More...
 
void assign_from_function (std::function< T(const std::array< int64, ndims > &indices)> func)
 Replaces every element with the result of func evaluated at the cooresponding indices. More...
 
bool traverse (std::function< bool(const std::array< int64, ndims > &indices, const T &value)> func) const
 Traverses the multidimensional array in row-major order, calling func at every element. More...
 

Friends

class arraynd< T, ndims+1 >
 

Additional Inherited Members

- Protected Member Functions inherited from sydevs::arraynd_base< T, ndims >
 arraynd_base ()
 
 arraynd_base (const std::array< int64, ndims > &dims, const T &value)
 
 arraynd_base (const std::array< int64, ndims > &dims, const std::vector< T > &data)
 
 arraynd_base (const std::array< int64, ndims > &dims, std::function< T(const std::array< int64, ndims > &indices)> func)
 
 arraynd_base (const arraynd_base< T, ndims+1 > &rhs, int64 index, bool is_readonly)
 
 arraynd_base (const arraynd_base< T, ndims > &rhs, range r, bool is_readonly)
 
 arraynd_base (const arraynd_base< T, ndims > &rhs, bool is_view, bool is_readonly)
 
 arraynd_base (const arraynd_base< T, ndims > &rhs)
 
arraynd_base< T, ndims > & operator= (const arraynd_base< T, ndims > &rhs)
 
 arraynd_base (arraynd_base< T, ndims > &&)=default
 
arraynd_base< T, ndims > & operator= (arraynd_base< T, ndims > &&)=default
 
- Static Protected Member Functions inherited from sydevs::arraynd_base< T, ndims >
static void transpose (arraynd_base< T, ndims > &arr)
 
static void swap_axes (arraynd_base< T, ndims > &arr, int64 idim0, int64 idim1)
 
static void subdivide_axis (const arraynd_base< T, ndims > &arr0, arraynd_base< T, ndims+1 > &arr, int64 idim, const std::array< int64, 2 > &dims)
 
static void absorb_axis (const arraynd_base< T, ndims > &arr0, arraynd_base< T, ndims-1 > &arr, int64 idim)
 

Detailed Description

template<typename T, int64 ndims>
class sydevs::arraynd< T, ndims >

A class template for a multidimensional array with elements of type T arranged in a lattice of ndims dimensions.

An arraynd object represents a multidimensional array of elements of type T arranged in a rectangular lattice of ndims dimensions. Although the element type and number of dimensions are determined at compile-time, the lengths the dimensions (dims), the total number of elements (size), and the value of each element can be changed dynamically.

Multidimensional arrays can be constructed using a set of 9 type aliases named arraynd, but with n replaced by 1, 2, 3, ..., 9. The instruction below constructs a 3D multidimensional array with dimensions 2, 4, and 5, with all 40 floating-point elements initialized to zero.

auto arr = array3d<float64>({2, 4, 5}, 0.0);

Multidimensional array elements are stored in row-major order. When an array is constructed with data supplied in the form of a std::vector, the vector elements are copied into the array in row-major order. The following example illustrates the construction and printing of a 2-by-3 array populated with data from a length-6 vector.

auto arr = array2d<int64>({2, 3}, {0, 1, 2, 3, 4, 5});
std::cout << arr; // Prints "{{0, 1, 2}, {3, 4, 5}}".

Arrays can also be constructed by mapping indices to values.

auto arr = array3d<int64>({2, 3, 4}, [](const std::array<int64, 3>& indices) {
return 100*indices[0] + 10*indices[1] + indices[2];
});
std::cout << arr; // Prints "{{{0, 1, 2, 3},
// {10, 11, 12, 13},
// {20, 21, 22, 23}},
// {{100, 101, 102, 103},
// {110, 111, 112, 113},
// {120, 121, 122, 123}}}"
//
// (without line breaks).

The most efficient way to access individual multidimensional array elements is using operator().

auto arr = array3d<int64>({2, 3, 4}, [](const std::array<int64, 3>& indices) {
return 100*indices[0] + 10*indices[1] + indices[2];
});
arr(1, 0, 3) = 7;
std::cout << arr(1, 0, 3); // Prints "7".

1D arrays and std::array instances can also be used to access elements.

Elements can also be accessed by chaining ndims invocations of operator[]. However, this is less efficient than operator() because it involves constructing ndims - 1 new multidimensional arrays that share memory with the original.

auto arr = array3d<int64>({2, 3, 4}, [](const std::array<int64, 3>& indices) {
return 100*indices[0] + 10*indices[1] + indices[2];
});
arr[1][0][3] = 7; // Sets one element equal to 7 (inefficient).
std::cout << arr[1][0][3]; // Prints "7" (inefficient).

One should use operator[] in conjunction with the range class to construct slices that share data with the original array.

auto arr = array3d<int64>({2, 3, 4}, [](const std::array<int64, 3>& indices) {
return 100*indices[0] + 10*indices[1] + indices[2];
});
std::cout << arr[range().stride_by(2)][1][range().start_at(4).stride_by(-3)]
// Takes every 2nd element from the first dimension.
// Replaces the second dimension with contents associated with index 1.
// Takes every 3rd element from the third dimension going backwards from index 4.
// Prints "{{14, 11}, {214, 211}}".
arr[range().stride_by(2)][1][range().start_at(4).stride_by(-3)].fill(7);
// Replaces a 2-by-2 slice of the original array with the value 7.
arr[range().stride_by(2)][1][range().start_at(4).stride_by(-3)].assign(other);
// Replaces a 2-by-2 slice of the original array with the values in the
// multidimensional array `other`.

Copying a multidimensional array shares the internal data by default. The result of operator[] also shares data, and so does the view member function. The copy member function performs a deep copy of a multidimensional array so that no data is shared.

auto arr = array2d<int64>({2, 3}, {0, 1, 2, 3, 4, 5});
auto arr2 = arr; // Shares data.
auto arr3 = arr[range()][range()]; // Shares data.
auto arr4 = arr.view(); // Shares data.
auto arr5 = arr.copy(); // Copies data.

There are also several transformation functions that either share or copy the data. For example, view_transposed creates a new array that reverses the order of the dimensions while sharing data with the original. By contrast, copy_transposed creates a new transposed array with its own copy of the data.

If data is shared with a constant multidimensional array, then neither array can be modified. In the following example, arr is const and arr2 shares data with it.

try {
const auto arr = array2d<std::string>({2, 2}, {"A", "B", "C", "D"});
auto arr2 = arr.view();
arr2(0, 0) = "E";
}
catch (const std::exception& e) {
std::cout << "ERROR: " << e.what() << std::endl;
}

Since replacing element (0, 0) of arr2 would also replace an element of arr, and since arr is const, the error below is produced.

ERROR: Attempt to obtain a non-const reference to readonly multidimensional array data

Various mathematical operations are available for multidimensional arrays and scalars, and for pairs of multidimensional arrays with the same dimensions.

auto a = array2d<int64>({2, 3}, {0, 1, 2, 3, 4, 5});
auto b = array2d<int64>({2, 3}, {2, 1, 0, 2, 4, 6});
std::cout << a + b; // Prints "{{2, 2, 2}, {5, 8, 11}}".
std::cout << a + 5; // Prints "{{5, 6, 7}, {8, 9, 10}}".
std::cout << 5 - a; // Prints "{{5, 4, 3}, {2, 1, 0}}".
std::cout << a/5; // Prints "{{0, 0, 1}, {1, 2, 2}}".
std::cout << (a < b); // Prints "{{1, 0, 0}, {0, 0, 1}}".
std::cout << (a == b); // Prints "{{0, 1, 0}, {0, 1, 0}}".
std::cout << (a >= 1 && a <= 4); // Prints "{{0, 1, 1}, {1, 1, 0}}".
std::cout << all(a >= 0); // Prints "1".
std::cout << any(a == 7); // Prints "0".

There is also an element type conversion function to and an element replacement function replace, demonstrated below.

auto arr = array2d<float64>({2, 2}, {0.5, 1.5, -0.5, -1.5});
std::cout << to<int64>(arr); // Prints "{{0, 1}, {0, -1}}"
std::cout << replace(arr, arr < 0, 0); // Prints "{{0.5, 1.5}, {0, 0}}"
std::cout << replace(arr, arr < 0, -arr); // Prints "{{0.5, 1.5}, {0.5, 1.5}}"

Constructor & Destructor Documentation

template<typename T , int64 ndims>
sydevs::arraynd< T, ndims >::arraynd ( )

Constructs an arraynd object with dimensions of length zero.

Template Parameters
TThe type of all elements of the multidimensional array.
ndimsThe number of dimensions of the multidimensional array.
template<typename T , int64 ndims>
sydevs::arraynd< T, ndims >::arraynd ( const std::array< int64, ndims > &  dims,
const T &  value 
)

Constructs an arraynd object with the specified dimensions dims and all elements initialized to value.

Parameters
dimsThe dimensions.
valueA value to be assigned to all elements of the multidimensional array.
Template Parameters
TThe type of all elements of the multidimensional array.
ndimsThe number of dimensions of the multidimensional array.
template<typename T , int64 ndims>
sydevs::arraynd< T, ndims >::arraynd ( const std::array< int64, ndims > &  dims,
const std::vector< T > &  data 
)

Constructs an arraynd object with the specified dimensions dims and elements initialized with the supplied data.

The supplied data vector must have a length equal to the product of the dimensions so that the multidimensional array can be filled. Otherwise, a std::domain_error exception is thrown. The elements of data` are copied into the multidimensional array in row-major order.

Parameters
dimsThe dimensions.
dataA vector of values to be copied into the multidimensional array.
Template Parameters
TThe type of all elements of the multidimensional array.
ndimsThe number of dimensions of the multidimensional array.
template<typename T , int64 ndims>
sydevs::arraynd< T, ndims >::arraynd ( const std::array< int64, ndims > &  dims,
std::function< T(const std::array< int64, ndims > &indices)>  func 
)

Constructs an arraynd object with the specified dimensions dims and elements initialized using the function object func.

The function object func maps a set of indices to the value that will be assigned to the corresponding location in the multidimensional array.

Parameters
dimsThe dimensions.
funcThe function object invoked to initialize each element.
Template Parameters
TThe type of all elements of the multidimensional array.
ndimsThe number of dimensions of the multidimensional array.
template<typename T, int64 ndims>
sydevs::arraynd< T, ndims >::arraynd ( const arraynd< T, ndims > &  )
default

Copy constructor (if rhs.is_view(), data is shared; otherwise data is copied)

template<typename T, int64 ndims>
sydevs::arraynd< T, ndims >::arraynd ( arraynd< T, ndims > &&  )
default

Move constructor (data is shared)

template<typename T, int64 ndims>
sydevs::arraynd< T, ndims >::~arraynd ( )
default

Destructor.

Member Function Documentation

template<typename T , int64 ndims>
arraynd< T, ndims > sydevs::arraynd< T, ndims >::copy ( ) const

Create a deep copy of the multidimensional array (data is copied).

template<typename T , int64 ndims>
arraynd< T, ndims-1 > sydevs::arraynd< T, ndims >::copy_absorbed_axis ( int64  idim) const

Create a deep copy with dimension idim absorbed into dimension idim - 1 (data is copied).

template<typename T , int64 ndims>
arraynd< T, ndims+1 > sydevs::arraynd< T, ndims >::copy_subdivided_axis ( int64  idim,
const std::array< int64, 2 > &  dims 
) const

Create a deep copy with dimension idim split into two dimensions with lengths given by dims (data is copied).

template<typename T , int64 ndims>
arraynd< T, ndims > sydevs::arraynd< T, ndims >::copy_swapped_axes ( int64  idim0,
int64  idim1 
) const

Create a deep copy with dimensions idim0 and idim1 swapped (data is copied).

template<typename T , int64 ndims>
arraynd< T, ndims > sydevs::arraynd< T, ndims >::copy_transposed ( ) const

Create a transposed deep copy of the multidimensional array (data is copied).

template<typename T, int64 ndims>
arraynd<T, ndims>& sydevs::arraynd< T, ndims >::operator= ( const arraynd< T, ndims > &  )
default

Copy assignment (if !is_view() && rhs.is_view(), data is shared; otherwise data is copied)

template<typename T, int64 ndims>
arraynd<T, ndims>& sydevs::arraynd< T, ndims >::operator= ( arraynd< T, ndims > &&  )
default

Move assignment (data is shared)

template<typename T , int64 ndims>
const arraynd< T, ndims-1 > sydevs::arraynd< T, ndims >::operator[] ( int64  index) const

Create a const slice with one dimension replaced by referencing elements at the specified index (data is shared).

template<typename T , int64 ndims>
arraynd< T, ndims-1 > sydevs::arraynd< T, ndims >::operator[] ( int64  index)

Create a slice with one dimension replaced by referencing elements at the specified index (data is shared).

template<typename T , int64 ndims>
const arraynd< T, ndims > sydevs::arraynd< T, ndims >::operator[] ( range  r) const

Create a const slice with one dimension filtered by referencing elements in the specified range r (data is shared).

template<typename T , int64 ndims>
arraynd< T, ndims > sydevs::arraynd< T, ndims >::operator[] ( range  r)

Create a slice with one dimension filtered by referencing elements in the specified range r (data is shared).

template<typename T , int64 ndims>
const arraynd< T, ndims > sydevs::arraynd< T, ndims >::view ( ) const

Create a const view of the multidimensional array (data is shared).

template<typename T , int64 ndims>
arraynd< T, ndims > sydevs::arraynd< T, ndims >::view ( )

Create a view of the multidimensional array (data is shared).

template<typename T , int64 ndims>
const arraynd< T, ndims-1 > sydevs::arraynd< T, ndims >::view_absorbed_axis ( int64  idim) const

Create a const view with dimension idim absorbed into dimension idim - 1 (data is shared).

template<typename T , int64 ndims>
arraynd< T, ndims-1 > sydevs::arraynd< T, ndims >::view_absorbed_axis ( int64  idim)

Create a view with dimension idim absorbed into dimension idim - 1 (data is shared).

template<typename T , int64 ndims>
const arraynd< T, ndims+1 > sydevs::arraynd< T, ndims >::view_subdivided_axis ( int64  idim,
const std::array< int64, 2 > &  dims 
) const

Create a const view with dimension idim split into two dimensions with lengths given by dims (data is shared).

template<typename T , int64 ndims>
arraynd< T, ndims+1 > sydevs::arraynd< T, ndims >::view_subdivided_axis ( int64  idim,
const std::array< int64, 2 > &  dims 
)

Create a view with dimension idim split into two dimensions with lengths given by dims (data is shared).

template<typename T , int64 ndims>
const arraynd< T, ndims > sydevs::arraynd< T, ndims >::view_swapped_axes ( int64  idim0,
int64  idim1 
) const

Create a const view with dimensions idim0 and idim1 swapped (data is shared).

template<typename T , int64 ndims>
arraynd< T, ndims > sydevs::arraynd< T, ndims >::view_swapped_axes ( int64  idim0,
int64  idim1 
)

Create a view with dimensions idim0 and idim1 swapped (data is shared).

template<typename T , int64 ndims>
const arraynd< T, ndims > sydevs::arraynd< T, ndims >::view_transposed ( ) const

Create a const transposed view of the multidimensional array (data is shared).

template<typename T , int64 ndims>
arraynd< T, ndims > sydevs::arraynd< T, ndims >::view_transposed ( )

Create a transposed view of the multidimensional array (data is shared).

Friends And Related Function Documentation

template<typename T, int64 ndims>
friend class arraynd< T, ndims+1 >
friend

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