449
common/Array.h
449
common/Array.h
@@ -27,13 +27,10 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
/*!
|
||||
* Class Array is a multi-dimensional array class written by Mark Berrill
|
||||
*/
|
||||
template<class TYPE, class FUN, class Allocator>
|
||||
class Array final
|
||||
{
|
||||
template <class TYPE, class FUN, class Allocator> class Array final {
|
||||
public: // Constructors / assignment operators
|
||||
/*!
|
||||
* Create a new empty Array
|
||||
@@ -44,20 +41,20 @@ public: // Constructors / assignment operators
|
||||
* Create an Array with the given size
|
||||
* @param N Size of the array
|
||||
*/
|
||||
explicit Array( const ArraySize &N );
|
||||
explicit Array(const ArraySize &N);
|
||||
|
||||
/*!
|
||||
* Create a new 1D Array with the given number of elements
|
||||
* @param N Number of elements in the array
|
||||
*/
|
||||
explicit Array( size_t N );
|
||||
explicit Array(size_t N);
|
||||
|
||||
/*!
|
||||
* Create a new 2D Array with the given number of rows and columns
|
||||
* @param N_rows Number of rows
|
||||
* @param N_columns Number of columns
|
||||
*/
|
||||
explicit Array( size_t N_rows, size_t N_columns );
|
||||
explicit Array(size_t N_rows, size_t N_columns);
|
||||
|
||||
/*!
|
||||
* Create a new 3D Array with the given number of rows and columns
|
||||
@@ -65,7 +62,7 @@ public: // Constructors / assignment operators
|
||||
* @param N2 Number of columns
|
||||
* @param N3 Number of elements in the third dimension
|
||||
*/
|
||||
explicit Array( size_t N1, size_t N2, size_t N3 );
|
||||
explicit Array(size_t N1, size_t N2, size_t N3);
|
||||
|
||||
/*!
|
||||
* Create a new 4D Array with the given number of rows and columns
|
||||
@@ -74,7 +71,7 @@ public: // Constructors / assignment operators
|
||||
* @param N3 Number of elements in the third dimension
|
||||
* @param N4 Number of elements in the fourth dimension
|
||||
*/
|
||||
explicit Array( size_t N1, size_t N2, size_t N3, size_t N4 );
|
||||
explicit Array(size_t N1, size_t N2, size_t N3, size_t N4);
|
||||
|
||||
/*!
|
||||
* Create a new 4D Array with the given number of rows and columns
|
||||
@@ -84,76 +81,74 @@ public: // Constructors / assignment operators
|
||||
* @param N4 Number of elements in the fourth dimension
|
||||
* @param N5 Number of elements in the fifth dimension
|
||||
*/
|
||||
explicit Array( size_t N1, size_t N2, size_t N3, size_t N4, size_t N5 );
|
||||
explicit Array(size_t N1, size_t N2, size_t N3, size_t N4, size_t N5);
|
||||
|
||||
/*!
|
||||
* Create a multi-dimensional Array with the given number of elements
|
||||
* @param N Number of elements in each dimension
|
||||
* @param data Optional raw array to copy the src data
|
||||
*/
|
||||
explicit Array( const std::vector<size_t> &N, const TYPE *data = nullptr );
|
||||
explicit Array(const std::vector<size_t> &N, const TYPE *data = nullptr);
|
||||
|
||||
/*!
|
||||
* Create a 1D Array using a string that mimic's MATLAB
|
||||
* @param range Range of the data
|
||||
*/
|
||||
explicit Array( std::string range );
|
||||
explicit Array(std::string range);
|
||||
|
||||
/*!
|
||||
* Create a 1D Array with the given initializer list
|
||||
* @param data Input data
|
||||
*/
|
||||
Array( std::initializer_list<TYPE> data );
|
||||
Array(std::initializer_list<TYPE> data);
|
||||
|
||||
/*!
|
||||
* Create a 2D Array with the given initializer lists
|
||||
* @param data Input data
|
||||
*/
|
||||
Array( std::initializer_list<std::initializer_list<TYPE>> data );
|
||||
|
||||
Array(std::initializer_list<std::initializer_list<TYPE>> data);
|
||||
|
||||
/*!
|
||||
* Copy constructor
|
||||
* @param rhs Array to copy
|
||||
*/
|
||||
Array( const Array &rhs );
|
||||
Array(const Array &rhs);
|
||||
|
||||
/*!
|
||||
* Move constructor
|
||||
* @param rhs Array to copy
|
||||
*/
|
||||
Array( Array &&rhs );
|
||||
Array(Array &&rhs);
|
||||
|
||||
/*!
|
||||
* Assignment operator
|
||||
* @param rhs Array to copy
|
||||
*/
|
||||
Array &operator=( const Array &rhs );
|
||||
Array &operator=(const Array &rhs);
|
||||
|
||||
/*!
|
||||
* Move assignment operator
|
||||
* @param rhs Array to copy
|
||||
*/
|
||||
Array &operator=( Array &&rhs );
|
||||
Array &operator=(Array &&rhs);
|
||||
|
||||
/*!
|
||||
* Assignment operator
|
||||
* @param rhs std::vector to copy
|
||||
*/
|
||||
Array &operator=( const std::vector<TYPE> &rhs );
|
||||
Array &operator=(const std::vector<TYPE> &rhs);
|
||||
|
||||
//! Is copyable?
|
||||
inline bool isCopyable() const { return d_isCopyable; }
|
||||
|
||||
//! Set is copyable
|
||||
inline void setCopyable( bool flag ) { d_isCopyable = flag; }
|
||||
inline void setCopyable(bool flag) { d_isCopyable = flag; }
|
||||
|
||||
//! Is fixed size?
|
||||
inline bool isFixedSize() const { return d_isFixedSize; }
|
||||
|
||||
//! Set is copyable
|
||||
inline void setFixedSize( bool flag ) { d_isFixedSize = flag; }
|
||||
|
||||
inline void setFixedSize(bool flag) { d_isFixedSize = flag; }
|
||||
|
||||
public: // Views/copies/subset
|
||||
/*!
|
||||
@@ -161,30 +156,29 @@ public: // Views/copies/subset
|
||||
* @param N Number of elements in each dimension
|
||||
* @param data Pointer to the data
|
||||
*/
|
||||
static std::unique_ptr<Array> view( const ArraySize &N, std::shared_ptr<TYPE> data );
|
||||
|
||||
static std::unique_ptr<Array> view(const ArraySize &N,
|
||||
std::shared_ptr<TYPE> data);
|
||||
|
||||
/*!
|
||||
* Create a multi-dimensional Array view to a raw block of data
|
||||
* @param N Number of elements in each dimension
|
||||
* @param data Pointer to the data
|
||||
*/
|
||||
static std::unique_ptr<const Array> constView( const ArraySize &N,
|
||||
std::shared_ptr<const TYPE> const &data );
|
||||
|
||||
static std::unique_ptr<const Array>
|
||||
constView(const ArraySize &N, std::shared_ptr<const TYPE> const &data);
|
||||
|
||||
/*!
|
||||
* Make this object a view of the src
|
||||
* @param src Source vector to take the view of
|
||||
*/
|
||||
void view2( Array &src );
|
||||
void view2(Array &src);
|
||||
|
||||
/*!
|
||||
* Make this object a view of the data
|
||||
* @param N Number of elements in each dimension
|
||||
* @param data Pointer to the data
|
||||
*/
|
||||
void view2( const ArraySize &N, std::shared_ptr<TYPE> data );
|
||||
void view2(const ArraySize &N, std::shared_ptr<TYPE> data);
|
||||
|
||||
/*!
|
||||
* Make this object a view of the raw data (expert use only).
|
||||
@@ -199,10 +193,9 @@ public: // Views/copies/subset
|
||||
* @param isCopyable Once the view is created, can the array be copied
|
||||
* @param isFixedSize Once the view is created, is the array size fixed
|
||||
*/
|
||||
inline void viewRaw(
|
||||
int ndim, const size_t *dims, TYPE *data, bool isCopyable = true, bool isFixedSize = true )
|
||||
{
|
||||
viewRaw( ArraySize( ndim, dims ), data, isCopyable, isFixedSize );
|
||||
inline void viewRaw(int ndim, const size_t *dims, TYPE *data,
|
||||
bool isCopyable = true, bool isFixedSize = true) {
|
||||
viewRaw(ArraySize(ndim, dims), data, isCopyable, isFixedSize);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -217,7 +210,8 @@ public: // Views/copies/subset
|
||||
* @param isCopyable Once the view is created, can the array be copied
|
||||
* @param isFixedSize Once the view is created, is the array size fixed
|
||||
*/
|
||||
void viewRaw( const ArraySize &N, TYPE *data, bool isCopyable = true, bool isFixedSize = true );
|
||||
void viewRaw(const ArraySize &N, TYPE *data, bool isCopyable = true,
|
||||
bool isFixedSize = true);
|
||||
|
||||
/*!
|
||||
* Create an array view of the given data (expert use only).
|
||||
@@ -229,10 +223,9 @@ public: // Views/copies/subset
|
||||
* @param N Number of elements in each dimension
|
||||
* @param data Pointer to the data
|
||||
*/
|
||||
static inline Array staticView( const ArraySize &N, TYPE *data )
|
||||
{
|
||||
static inline Array staticView(const ArraySize &N, TYPE *data) {
|
||||
Array x;
|
||||
x.viewRaw( N, data, true, true );
|
||||
x.viewRaw(N, data, true, true);
|
||||
return x;
|
||||
}
|
||||
|
||||
@@ -240,39 +233,34 @@ public: // Views/copies/subset
|
||||
* Convert an array of one type to another. This may or may not allocate new memory.
|
||||
* @param array Input array
|
||||
*/
|
||||
template<class TYPE2>
|
||||
template <class TYPE2>
|
||||
static inline std::unique_ptr<Array<TYPE2, FUN, Allocator>>
|
||||
convert( std::shared_ptr<Array<TYPE, FUN, Allocator>> array )
|
||||
{
|
||||
auto array2 = std::make_unique<Array<TYPE2>>( array->size() );
|
||||
array2.copy( *array );
|
||||
convert(std::shared_ptr<Array<TYPE, FUN, Allocator>> array) {
|
||||
auto array2 = std::make_unique<Array<TYPE2>>(array->size());
|
||||
array2.copy(*array);
|
||||
return array2;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* Convert an array of one type to another. This may or may not allocate new memory.
|
||||
* @param array Input array
|
||||
*/
|
||||
template<class TYPE2>
|
||||
template <class TYPE2>
|
||||
static inline std::unique_ptr<const Array<TYPE2, FUN, Allocator>>
|
||||
convert( std::shared_ptr<const Array<TYPE, FUN, Allocator>> array )
|
||||
{
|
||||
auto array2 = std::make_unique<Array<TYPE2>>( array->size() );
|
||||
array2.copy( *array );
|
||||
convert(std::shared_ptr<const Array<TYPE, FUN, Allocator>> array) {
|
||||
auto array2 = std::make_unique<Array<TYPE2>>(array->size());
|
||||
array2.copy(*array);
|
||||
return array2;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* Copy and convert data from another array to this array
|
||||
* @param array Source array
|
||||
*/
|
||||
template<class TYPE2, class FUN2, class Allocator2>
|
||||
void inline copy( const Array<TYPE2, FUN2, Allocator2> &array )
|
||||
{
|
||||
resize( array.size() );
|
||||
copy( array.data() );
|
||||
template <class TYPE2, class FUN2, class Allocator2>
|
||||
void inline copy(const Array<TYPE2, FUN2, Allocator2> &array) {
|
||||
resize(array.size());
|
||||
copy(array.data());
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -280,39 +268,33 @@ public: // Views/copies/subset
|
||||
* Note: The current array must be allocated to the proper size first.
|
||||
* @param data Source data
|
||||
*/
|
||||
template<class TYPE2>
|
||||
inline void copy( const TYPE2 *data );
|
||||
template <class TYPE2> inline void copy(const TYPE2 *data);
|
||||
|
||||
/*!
|
||||
* Copy and convert data from this array to a raw vector.
|
||||
* @param data Source data
|
||||
*/
|
||||
template<class TYPE2>
|
||||
inline void copyTo( TYPE2 *data ) const;
|
||||
template <class TYPE2> inline void copyTo(TYPE2 *data) const;
|
||||
|
||||
/*!
|
||||
* Copy and convert data from this array to a new array
|
||||
*/
|
||||
template<class TYPE2>
|
||||
Array<TYPE2, FUN, std::allocator<TYPE2>> inline cloneTo() const
|
||||
{
|
||||
Array<TYPE2, FUN, std::allocator<TYPE2>> dst( this->size() );
|
||||
copyTo( dst.data() );
|
||||
template <class TYPE2>
|
||||
Array<TYPE2, FUN, std::allocator<TYPE2>> inline cloneTo() const {
|
||||
Array<TYPE2, FUN, std::allocator<TYPE2>> dst(this->size());
|
||||
copyTo(dst.data());
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
/*! swap the raw data pointers for the Arrays after checking for compatibility */
|
||||
void swap( Array &other );
|
||||
|
||||
void swap(Array &other);
|
||||
|
||||
/*!
|
||||
* Fill the array with the given value
|
||||
* @param y Value to fill
|
||||
*/
|
||||
inline void fill( const TYPE &y )
|
||||
{
|
||||
for ( auto &x : *this )
|
||||
inline void fill(const TYPE &y) {
|
||||
for (auto &x : *this)
|
||||
x = y;
|
||||
}
|
||||
|
||||
@@ -320,67 +302,56 @@ public: // Views/copies/subset
|
||||
* Scale the array by the given value
|
||||
* @param y Value to scale by
|
||||
*/
|
||||
template<class TYPE2>
|
||||
inline void scale( const TYPE2 &y )
|
||||
{
|
||||
for ( auto &x : *this )
|
||||
template <class TYPE2> inline void scale(const TYPE2 &y) {
|
||||
for (auto &x : *this)
|
||||
x *= y;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* Set the values of this array to pow(base, exp)
|
||||
* @param base Base array
|
||||
* @param exp Exponent value
|
||||
*/
|
||||
void pow( const Array &base, const TYPE &exp );
|
||||
|
||||
void pow(const Array &base, const TYPE &exp);
|
||||
|
||||
//! Destructor
|
||||
~Array();
|
||||
|
||||
|
||||
//! Clear the data in the array
|
||||
void clear();
|
||||
|
||||
|
||||
//! Return the size of the Array
|
||||
inline int ndim() const { return d_size.ndim(); }
|
||||
|
||||
|
||||
//! Return the size of the Array
|
||||
inline const ArraySize &size() const { return d_size; }
|
||||
|
||||
|
||||
//! Return the size of the Array
|
||||
inline size_t size( int d ) const { return d_size[d]; }
|
||||
|
||||
inline size_t size(int d) const { return d_size[d]; }
|
||||
|
||||
//! Return the size of the Array
|
||||
inline size_t length() const { return d_size.length(); }
|
||||
|
||||
|
||||
//! Return true if the Array is empty
|
||||
inline bool empty() const { return d_size.length() == 0; }
|
||||
|
||||
|
||||
//! Return true if the Array is not empty
|
||||
inline operator bool() const { return d_size.length() != 0; }
|
||||
|
||||
|
||||
/*!
|
||||
* Resize the Array
|
||||
* @param N NUmber of elements
|
||||
*/
|
||||
inline void resize( size_t N ) { resize( ArraySize( N ) ); }
|
||||
|
||||
inline void resize(size_t N) { resize(ArraySize(N)); }
|
||||
|
||||
/*!
|
||||
* Resize the Array
|
||||
* @param N_row Number of rows
|
||||
* @param N_col Number of columns
|
||||
*/
|
||||
inline void resize( size_t N_row, size_t N_col ) { resize( ArraySize( N_row, N_col ) ); }
|
||||
inline void resize(size_t N_row, size_t N_col) {
|
||||
resize(ArraySize(N_row, N_col));
|
||||
}
|
||||
|
||||
/*!
|
||||
* Resize the Array
|
||||
@@ -388,14 +359,15 @@ public: // Views/copies/subset
|
||||
* @param N2 Number of columns
|
||||
* @param N3 Number of elements in the third dimension
|
||||
*/
|
||||
inline void resize( size_t N1, size_t N2, size_t N3 ) { resize( ArraySize( N1, N2, N3 ) ); }
|
||||
inline void resize(size_t N1, size_t N2, size_t N3) {
|
||||
resize(ArraySize(N1, N2, N3));
|
||||
}
|
||||
|
||||
/*!
|
||||
* Resize the Array
|
||||
* @param N Number of elements in each dimension
|
||||
*/
|
||||
void resize( const ArraySize &N );
|
||||
|
||||
void resize(const ArraySize &N);
|
||||
|
||||
/*!
|
||||
* Resize the given dimension of the array
|
||||
@@ -403,87 +375,83 @@ public: // Views/copies/subset
|
||||
* @param N Number of elements for the given dimension
|
||||
* @param value Value to initialize new elements
|
||||
*/
|
||||
void resizeDim( int dim, size_t N, const TYPE &value );
|
||||
|
||||
void resizeDim(int dim, size_t N, const TYPE &value);
|
||||
|
||||
/*!
|
||||
* Reshape the Array (total size of array will not change)
|
||||
* @param N Number of elements in each dimension
|
||||
*/
|
||||
void reshape( const ArraySize &N );
|
||||
|
||||
void reshape(const ArraySize &N);
|
||||
|
||||
/*!
|
||||
* Remove singleton dimensions.
|
||||
*/
|
||||
void squeeze();
|
||||
|
||||
|
||||
/*!
|
||||
* Reshape the Array so that the number of dimensions is the
|
||||
* max of ndim and the largest dim>1.
|
||||
* @param ndim Desired number of dimensions
|
||||
*/
|
||||
inline void setNdim( int ndim ) { d_size.setNdim( ndim ); }
|
||||
|
||||
inline void setNdim(int ndim) { d_size.setNdim(ndim); }
|
||||
|
||||
/*!
|
||||
* Subset the Array
|
||||
* @param index Index to subset (imin,imax,jmin,jmax,kmin,kmax,...)
|
||||
*/
|
||||
Array subset( const std::vector<size_t> &index ) const;
|
||||
|
||||
Array subset(const std::vector<size_t> &index) const;
|
||||
|
||||
/*!
|
||||
* Subset the Array
|
||||
* @param index Index to subset (ix:kx:jx,iy:ky:jy,...)
|
||||
*/
|
||||
Array subset( const std::vector<Range<size_t>> &index ) const;
|
||||
|
||||
Array subset(const std::vector<Range<size_t>> &index) const;
|
||||
|
||||
/*!
|
||||
* Copy data from an array into a subset of this array
|
||||
* @param index Index of the subset (imin,imax,jmin,jmax,kmin,kmax,...)
|
||||
* @param subset The subset array to copy from
|
||||
*/
|
||||
void copySubset( const std::vector<size_t> &index, const Array &subset );
|
||||
void copySubset(const std::vector<size_t> &index, const Array &subset);
|
||||
|
||||
/*!
|
||||
* Copy data from an array into a subset of this array
|
||||
* @param index Index of the subset
|
||||
* @param subset The subset array to copy from
|
||||
*/
|
||||
void copySubset( const std::vector<Range<size_t>> &index, const Array &subset );
|
||||
void copySubset(const std::vector<Range<size_t>> &index,
|
||||
const Array &subset);
|
||||
|
||||
/*!
|
||||
* Add data from an array into a subset of this array
|
||||
* @param index Index of the subset (imin,imax,jmin,jmax,kmin,kmax,...)
|
||||
* @param subset The subset array to add from
|
||||
*/
|
||||
void addSubset( const std::vector<size_t> &index, const Array &subset );
|
||||
void addSubset(const std::vector<size_t> &index, const Array &subset);
|
||||
|
||||
/*!
|
||||
* Add data from an array into a subset of this array
|
||||
* @param index Index of the subset
|
||||
* @param subset The subset array to add from
|
||||
*/
|
||||
void addSubset( const std::vector<Range<size_t>> &index, const Array &subset );
|
||||
|
||||
void addSubset(const std::vector<Range<size_t>> &index,
|
||||
const Array &subset);
|
||||
|
||||
public: // Accessors
|
||||
/*!
|
||||
* Access the desired element
|
||||
* @param i The row index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()( size_t i ) { return d_data[d_size.index( i )]; }
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()(size_t i) {
|
||||
return d_data[d_size.index(i)];
|
||||
}
|
||||
|
||||
/*!
|
||||
* Access the desired element
|
||||
* @param i The row index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline const TYPE &operator()( size_t i ) const
|
||||
{
|
||||
return d_data[d_size.index( i )];
|
||||
ARRAY_ATTRIBUTE inline const TYPE &operator()(size_t i) const {
|
||||
return d_data[d_size.index(i)];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -491,9 +459,8 @@ public: // Accessors
|
||||
* @param i The row index
|
||||
* @param j The column index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()( size_t i, size_t j )
|
||||
{
|
||||
return d_data[d_size.index( i, j )];
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()(size_t i, size_t j) {
|
||||
return d_data[d_size.index(i, j)];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -501,9 +468,8 @@ public: // Accessors
|
||||
* @param i The row index
|
||||
* @param j The column index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline const TYPE &operator()( size_t i, size_t j ) const
|
||||
{
|
||||
return d_data[d_size.index( i, j )];
|
||||
ARRAY_ATTRIBUTE inline const TYPE &operator()(size_t i, size_t j) const {
|
||||
return d_data[d_size.index(i, j)];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -512,9 +478,8 @@ public: // Accessors
|
||||
* @param j The column index
|
||||
* @param k The third index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()( size_t i, size_t j, size_t k )
|
||||
{
|
||||
return d_data[d_size.index( i, j, k )];
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()(size_t i, size_t j, size_t k) {
|
||||
return d_data[d_size.index(i, j, k)];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -523,9 +488,9 @@ public: // Accessors
|
||||
* @param j The column index
|
||||
* @param k The third index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline const TYPE &operator()( size_t i, size_t j, size_t k ) const
|
||||
{
|
||||
return d_data[d_size.index( i, j, k )];
|
||||
ARRAY_ATTRIBUTE inline const TYPE &operator()(size_t i, size_t j,
|
||||
size_t k) const {
|
||||
return d_data[d_size.index(i, j, k)];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -535,9 +500,9 @@ public: // Accessors
|
||||
* @param i3 The third index
|
||||
* @param i4 The fourth index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()( size_t i1, size_t i2, size_t i3, size_t i4 )
|
||||
{
|
||||
return d_data[d_size.index( i1, i2, i3, i4 )];
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()(size_t i1, size_t i2, size_t i3,
|
||||
size_t i4) {
|
||||
return d_data[d_size.index(i1, i2, i3, i4)];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -547,10 +512,9 @@ public: // Accessors
|
||||
* @param i3 The third index
|
||||
* @param i4 The fourth index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline const TYPE &
|
||||
operator()( size_t i1, size_t i2, size_t i3, size_t i4 ) const
|
||||
{
|
||||
return d_data[d_size.index( i1, i2, i3, i4 )];
|
||||
ARRAY_ATTRIBUTE inline const TYPE &operator()(size_t i1, size_t i2,
|
||||
size_t i3, size_t i4) const {
|
||||
return d_data[d_size.index(i1, i2, i3, i4)];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -561,9 +525,9 @@ public: // Accessors
|
||||
* @param i4 The fourth index
|
||||
* @param i5 The fifth index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()( size_t i1, size_t i2, size_t i3, size_t i4, size_t i5 )
|
||||
{
|
||||
return d_data[d_size.index( i1, i2, i3, i4, i5 )];
|
||||
ARRAY_ATTRIBUTE inline TYPE &operator()(size_t i1, size_t i2, size_t i3,
|
||||
size_t i4, size_t i5) {
|
||||
return d_data[d_size.index(i1, i2, i3, i4, i5)];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -575,17 +539,15 @@ public: // Accessors
|
||||
* @param i5 The fifth index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline const TYPE &
|
||||
operator()( size_t i1, size_t i2, size_t i3, size_t i4, size_t i5 ) const
|
||||
{
|
||||
return d_data[d_size.index( i1, i2, i3, i4, i5 )];
|
||||
operator()(size_t i1, size_t i2, size_t i3, size_t i4, size_t i5) const {
|
||||
return d_data[d_size.index(i1, i2, i3, i4, i5)];
|
||||
}
|
||||
|
||||
/*!
|
||||
* Access the desired element as a raw pointer
|
||||
* @param i The global index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline TYPE *ptr( size_t i )
|
||||
{
|
||||
ARRAY_ATTRIBUTE inline TYPE *ptr(size_t i) {
|
||||
return i >= d_size.length() ? nullptr : &d_data[i];
|
||||
}
|
||||
|
||||
@@ -593,8 +555,7 @@ public: // Accessors
|
||||
* Access the desired element as a raw pointer
|
||||
* @param i The global index
|
||||
*/
|
||||
ARRAY_ATTRIBUTE inline const TYPE *ptr( size_t i ) const
|
||||
{
|
||||
ARRAY_ATTRIBUTE inline const TYPE *ptr(size_t i) const {
|
||||
return i >= d_size.length() ? nullptr : &d_data[i];
|
||||
}
|
||||
|
||||
@@ -622,40 +583,40 @@ public: // Accessors
|
||||
//! Return the pointer to the raw data
|
||||
ARRAY_ATTRIBUTE inline const TYPE *data() const { return d_data; }
|
||||
|
||||
|
||||
public: // Operator overloading
|
||||
//! Check if two matrices are equal
|
||||
// Equality means the dimensions and data have to be identical
|
||||
bool operator==( const Array &rhs ) const;
|
||||
bool operator==(const Array &rhs) const;
|
||||
|
||||
//! Check if two matrices are not equal
|
||||
inline bool operator!=( const Array &rhs ) const { return !this->operator==( rhs ); }
|
||||
inline bool operator!=(const Array &rhs) const {
|
||||
return !this->operator==(rhs);
|
||||
}
|
||||
|
||||
//! Add another array
|
||||
Array &operator+=( const Array &rhs );
|
||||
Array &operator+=(const Array &rhs);
|
||||
|
||||
//! Subtract another array
|
||||
Array &operator-=( const Array &rhs );
|
||||
Array &operator-=(const Array &rhs);
|
||||
|
||||
//! Add a scalar
|
||||
Array &operator+=( const TYPE &rhs );
|
||||
Array &operator+=(const TYPE &rhs);
|
||||
|
||||
//! Subtract a scalar
|
||||
Array &operator-=( const TYPE &rhs );
|
||||
|
||||
Array &operator-=(const TYPE &rhs);
|
||||
|
||||
public: // Math operations
|
||||
//! Concatenates the arrays along the dimension dim.
|
||||
static Array cat( const std::vector<Array> &x, int dim = 0 );
|
||||
static Array cat(const std::vector<Array> &x, int dim = 0);
|
||||
|
||||
//! Concatenates the arrays along the dimension dim.
|
||||
static Array cat( const std::initializer_list<Array> &x, int dim = 0 );
|
||||
static Array cat(const std::initializer_list<Array> &x, int dim = 0);
|
||||
|
||||
//! Concatenates the arrays along the dimension dim.
|
||||
static Array cat( size_t N_array, const Array *x, int dim );
|
||||
static Array cat(size_t N_array, const Array *x, int dim);
|
||||
|
||||
//! Concatenates a given array with the current array
|
||||
void cat( const Array &x, int dim = 0 );
|
||||
void cat(const Array &x, int dim = 0);
|
||||
|
||||
//! Initialize the array with random values (defined from the function table)
|
||||
//void rand();
|
||||
@@ -676,46 +637,46 @@ public: // Math operations
|
||||
TYPE mean() const;
|
||||
|
||||
//! Return the min of all elements in a given direction
|
||||
Array min( int dir ) const;
|
||||
Array min(int dir) const;
|
||||
|
||||
//! Return the max of all elements in a given direction
|
||||
Array max( int dir ) const;
|
||||
Array max(int dir) const;
|
||||
|
||||
//! Return the sum of all elements in a given direction
|
||||
Array sum( int dir ) const;
|
||||
Array sum(int dir) const;
|
||||
|
||||
//! Return the smallest value
|
||||
TYPE min( const std::vector<size_t> &index ) const;
|
||||
TYPE min(const std::vector<size_t> &index) const;
|
||||
|
||||
//! Return the largest value
|
||||
TYPE max( const std::vector<size_t> &index ) const;
|
||||
TYPE max(const std::vector<size_t> &index) const;
|
||||
|
||||
//! Return the sum of all elements
|
||||
TYPE sum( const std::vector<size_t> &index ) const;
|
||||
TYPE sum(const std::vector<size_t> &index) const;
|
||||
|
||||
//! Return the mean of all elements
|
||||
TYPE mean( const std::vector<size_t> &index ) const;
|
||||
TYPE mean(const std::vector<size_t> &index) const;
|
||||
|
||||
//! Return the smallest value
|
||||
TYPE min( const std::vector<Range<size_t>> &index ) const;
|
||||
TYPE min(const std::vector<Range<size_t>> &index) const;
|
||||
|
||||
//! Return the largest value
|
||||
TYPE max( const std::vector<Range<size_t>> &index ) const;
|
||||
TYPE max(const std::vector<Range<size_t>> &index) const;
|
||||
|
||||
//! Return the sum of all elements
|
||||
TYPE sum( const std::vector<Range<size_t>> &index ) const;
|
||||
TYPE sum(const std::vector<Range<size_t>> &index) const;
|
||||
|
||||
//! Return the mean of all elements
|
||||
TYPE mean( const std::vector<Range<size_t>> &index ) const;
|
||||
TYPE mean(const std::vector<Range<size_t>> &index) const;
|
||||
|
||||
//! Find all elements that match the operator
|
||||
std::vector<size_t> find( const TYPE &value,
|
||||
std::function<bool( const TYPE &, const TYPE & )> compare ) const;
|
||||
|
||||
std::vector<size_t>
|
||||
find(const TYPE &value,
|
||||
std::function<bool(const TYPE &, const TYPE &)> compare) const;
|
||||
|
||||
//! Print an array
|
||||
void
|
||||
print( std::ostream &os, const std::string &name = "A", const std::string &prefix = "" ) const;
|
||||
void print(std::ostream &os, const std::string &name = "A",
|
||||
const std::string &prefix = "") const;
|
||||
|
||||
//! Transpose an array
|
||||
Array reverseDim() const;
|
||||
@@ -728,7 +689,7 @@ public: // Math operations
|
||||
* shiftDim shifts the dimensions to the right and pads with singletons.
|
||||
* @param N Desired shift
|
||||
*/
|
||||
Array shiftDim( int N ) const;
|
||||
Array shiftDim(int N) const;
|
||||
|
||||
/*!
|
||||
* @brief Permute array dimensions
|
||||
@@ -738,24 +699,25 @@ public: // Math operations
|
||||
* needed to access any particular element are rearranged as specified.
|
||||
* @param index Desired order of the subscripts
|
||||
*/
|
||||
Array permute( const std::vector<uint8_t> &index ) const;
|
||||
Array permute(const std::vector<uint8_t> &index) const;
|
||||
|
||||
//! Replicate an array a given number of times in each direction
|
||||
Array repmat( const std::vector<size_t> &N ) const;
|
||||
Array repmat(const std::vector<size_t> &N) const;
|
||||
|
||||
//! Coarsen an array using the given filter
|
||||
Array coarsen( const Array &filter ) const;
|
||||
Array coarsen(const Array &filter) const;
|
||||
|
||||
//! Coarsen an array using the given filter
|
||||
Array coarsen( const std::vector<size_t> &ratio,
|
||||
std::function<TYPE( const Array & )> filter ) const;
|
||||
Array coarsen(const std::vector<size_t> &ratio,
|
||||
std::function<TYPE(const Array &)> filter) const;
|
||||
|
||||
/*!
|
||||
* Perform a element-wise operation y = f(x)
|
||||
* @param[in] fun The function operation
|
||||
* @param[in] x The input array
|
||||
*/
|
||||
static Array transform( std::function<TYPE( const TYPE & )> fun, const Array &x );
|
||||
static Array transform(std::function<TYPE(const TYPE &)> fun,
|
||||
const Array &x);
|
||||
|
||||
/*!
|
||||
* Perform a element-wise operation z = f(x,y)
|
||||
@@ -763,9 +725,8 @@ public: // Math operations
|
||||
* @param[in] x The first array
|
||||
* @param[in] y The second array
|
||||
*/
|
||||
static Array transform( std::function<TYPE( const TYPE &, const TYPE & )> fun,
|
||||
const Array &x,
|
||||
const Array &y );
|
||||
static Array transform(std::function<TYPE(const TYPE &, const TYPE &)> fun,
|
||||
const Array &x, const Array &y);
|
||||
|
||||
/*!
|
||||
* axpby operation: this = alpha*x + beta*this
|
||||
@@ -773,19 +734,21 @@ public: // Math operations
|
||||
* @param[in] x x
|
||||
* @param[in] beta beta
|
||||
*/
|
||||
void axpby( const TYPE &alpha, const Array &x, const TYPE &beta );
|
||||
void axpby(const TYPE &alpha, const Array &x, const TYPE &beta);
|
||||
|
||||
/*!
|
||||
* Linear interpolation
|
||||
* @param[in] x Position as a decimal index
|
||||
*/
|
||||
inline TYPE interp( const std::vector<double> &x ) const { return interp( x.data() ); }
|
||||
inline TYPE interp(const std::vector<double> &x) const {
|
||||
return interp(x.data());
|
||||
}
|
||||
|
||||
/*!
|
||||
* Linear interpolation
|
||||
* @param[in] x Position as a decimal index
|
||||
*/
|
||||
TYPE interp( const double *x ) const;
|
||||
TYPE interp(const double *x) const;
|
||||
|
||||
/**
|
||||
* \fn equals (Array & const rhs, TYPE tol )
|
||||
@@ -794,7 +757,7 @@ public: // Math operations
|
||||
* \param[in] tol Tolerance of comparison
|
||||
* \return True iff \f$||\mathit{rhs} - x||_\infty < \mathit{tol}\f$
|
||||
*/
|
||||
bool equals( const Array &rhs, TYPE tol = 0.000001 ) const;
|
||||
bool equals(const Array &rhs, TYPE tol = 0.000001) const;
|
||||
|
||||
private:
|
||||
bool d_isCopyable; // Can the array be copied
|
||||
@@ -802,115 +765,106 @@ private:
|
||||
ArraySize d_size; // Size of each dimension
|
||||
TYPE *d_data; // Raw pointer to data in array
|
||||
std::shared_ptr<TYPE> d_ptr; // Shared pointer to data in array
|
||||
void allocate( const ArraySize &N );
|
||||
void allocate(const ArraySize &N);
|
||||
|
||||
private:
|
||||
inline void checkSubsetIndex( const std::vector<Range<size_t>> &range ) const;
|
||||
inline std::vector<Range<size_t>> convert( const std::vector<size_t> &index ) const;
|
||||
static inline void getSubsetArrays( const std::vector<Range<size_t>> &range,
|
||||
std::array<size_t, 5> &first,
|
||||
std::array<size_t, 5> &last,
|
||||
std::array<size_t, 5> &inc,
|
||||
std::array<size_t, 5> &N );
|
||||
inline void checkSubsetIndex(const std::vector<Range<size_t>> &range) const;
|
||||
inline std::vector<Range<size_t>>
|
||||
convert(const std::vector<size_t> &index) const;
|
||||
static inline void getSubsetArrays(const std::vector<Range<size_t>> &range,
|
||||
std::array<size_t, 5> &first,
|
||||
std::array<size_t, 5> &last,
|
||||
std::array<size_t, 5> &inc,
|
||||
std::array<size_t, 5> &N);
|
||||
};
|
||||
|
||||
|
||||
/********************************************************
|
||||
* ostream operator *
|
||||
********************************************************/
|
||||
inline std::ostream &operator<<( std::ostream &out, const ArraySize &s )
|
||||
{
|
||||
inline std::ostream &operator<<(std::ostream &out, const ArraySize &s) {
|
||||
out << "[" << s[0];
|
||||
for ( size_t i = 1; i < s.ndim(); i++ )
|
||||
for (size_t i = 1; i < s.ndim(); i++)
|
||||
out << "," << s[i];
|
||||
out << "]";
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Math operations *
|
||||
********************************************************/
|
||||
template<class TYPE, class FUN, class Allocator>
|
||||
inline Array<TYPE, FUN, Allocator> operator+(
|
||||
const Array<TYPE, FUN, Allocator> &a, const Array<TYPE, FUN, Allocator> &b )
|
||||
{
|
||||
template <class TYPE, class FUN, class Allocator>
|
||||
inline Array<TYPE, FUN, Allocator>
|
||||
operator+(const Array<TYPE, FUN, Allocator> &a,
|
||||
const Array<TYPE, FUN, Allocator> &b) {
|
||||
Array<TYPE, FUN, Allocator> c;
|
||||
const auto &op = []( const TYPE &a, const TYPE &b ) { return a + b; };
|
||||
FUN::transform( op, a, b, c );
|
||||
const auto &op = [](const TYPE &a, const TYPE &b) { return a + b; };
|
||||
FUN::transform(op, a, b, c);
|
||||
return c;
|
||||
}
|
||||
template<class TYPE, class FUN, class Allocator>
|
||||
inline Array<TYPE, FUN, Allocator> operator-(
|
||||
const Array<TYPE, FUN, Allocator> &a, const Array<TYPE, FUN, Allocator> &b )
|
||||
{
|
||||
template <class TYPE, class FUN, class Allocator>
|
||||
inline Array<TYPE, FUN, Allocator>
|
||||
operator-(const Array<TYPE, FUN, Allocator> &a,
|
||||
const Array<TYPE, FUN, Allocator> &b) {
|
||||
Array<TYPE, FUN, Allocator> c;
|
||||
const auto &op = []( const TYPE &a, const TYPE &b ) { return a - b; };
|
||||
FUN::transform( op, a, b, c );
|
||||
const auto &op = [](const TYPE &a, const TYPE &b) { return a - b; };
|
||||
FUN::transform(op, a, b, c);
|
||||
return c;
|
||||
}
|
||||
template<class TYPE, class FUN, class Allocator>
|
||||
inline Array<TYPE, FUN, Allocator> operator*(
|
||||
const Array<TYPE, FUN, Allocator> &a, const Array<TYPE, FUN, Allocator> &b )
|
||||
{
|
||||
template <class TYPE, class FUN, class Allocator>
|
||||
inline Array<TYPE, FUN, Allocator>
|
||||
operator*(const Array<TYPE, FUN, Allocator> &a,
|
||||
const Array<TYPE, FUN, Allocator> &b) {
|
||||
Array<TYPE, FUN, Allocator> c;
|
||||
FUN::multiply( a, b, c );
|
||||
FUN::multiply(a, b, c);
|
||||
return c;
|
||||
}
|
||||
template<class TYPE, class FUN, class Allocator>
|
||||
inline Array<TYPE, FUN, Allocator> operator*(
|
||||
const Array<TYPE, FUN, Allocator> &a, const std::vector<TYPE> &b )
|
||||
{
|
||||
template <class TYPE, class FUN, class Allocator>
|
||||
inline Array<TYPE, FUN, Allocator>
|
||||
operator*(const Array<TYPE, FUN, Allocator> &a, const std::vector<TYPE> &b) {
|
||||
Array<TYPE, FUN, Allocator> b2, c;
|
||||
b2.viewRaw( { b.size() }, const_cast<TYPE *>( b.data() ) );
|
||||
FUN::multiply( a, b2, c );
|
||||
b2.viewRaw({b.size()}, const_cast<TYPE *>(b.data()));
|
||||
FUN::multiply(a, b2, c);
|
||||
return c;
|
||||
}
|
||||
template<class TYPE, class FUN, class Allocator>
|
||||
inline Array<TYPE, FUN, Allocator> operator*( const TYPE &a,
|
||||
const Array<TYPE, FUN, Allocator> &b )
|
||||
{
|
||||
template <class TYPE, class FUN, class Allocator>
|
||||
inline Array<TYPE, FUN, Allocator>
|
||||
operator*(const TYPE &a, const Array<TYPE, FUN, Allocator> &b) {
|
||||
auto c = b;
|
||||
c.scale( a );
|
||||
c.scale(a);
|
||||
return c;
|
||||
}
|
||||
template<class TYPE, class FUN, class Allocator>
|
||||
inline Array<TYPE, FUN, Allocator> operator*( const Array<TYPE, FUN, Allocator> &a,
|
||||
const TYPE &b )
|
||||
{
|
||||
template <class TYPE, class FUN, class Allocator>
|
||||
inline Array<TYPE, FUN, Allocator>
|
||||
operator*(const Array<TYPE, FUN, Allocator> &a, const TYPE &b) {
|
||||
auto c = a;
|
||||
c.scale( b );
|
||||
c.scale(b);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Copy array *
|
||||
********************************************************/
|
||||
template<class TYPE, class FUN, class Allocator>
|
||||
template<class TYPE2>
|
||||
inline void Array<TYPE, FUN, Allocator>::copy( const TYPE2 *data )
|
||||
{
|
||||
if ( std::is_same<TYPE, TYPE2>::value ) {
|
||||
std::copy( data, data + d_size.length(), d_data );
|
||||
template <class TYPE, class FUN, class Allocator>
|
||||
template <class TYPE2>
|
||||
inline void Array<TYPE, FUN, Allocator>::copy(const TYPE2 *data) {
|
||||
if (std::is_same<TYPE, TYPE2>::value) {
|
||||
std::copy(data, data + d_size.length(), d_data);
|
||||
} else {
|
||||
for ( size_t i = 0; i < d_size.length(); i++ )
|
||||
d_data[i] = static_cast<TYPE>( data[i] );
|
||||
for (size_t i = 0; i < d_size.length(); i++)
|
||||
d_data[i] = static_cast<TYPE>(data[i]);
|
||||
}
|
||||
}
|
||||
template<class TYPE, class FUN, class Allocator>
|
||||
template<class TYPE2>
|
||||
inline void Array<TYPE, FUN, Allocator>::copyTo( TYPE2 *data ) const
|
||||
{
|
||||
if ( std::is_same<TYPE, TYPE2>::value ) {
|
||||
std::copy( d_data, d_data + d_size.length(), data );
|
||||
template <class TYPE, class FUN, class Allocator>
|
||||
template <class TYPE2>
|
||||
inline void Array<TYPE, FUN, Allocator>::copyTo(TYPE2 *data) const {
|
||||
if (std::is_same<TYPE, TYPE2>::value) {
|
||||
std::copy(d_data, d_data + d_size.length(), data);
|
||||
} else {
|
||||
for ( size_t i = 0; i < d_size.length(); i++ )
|
||||
data[i] = static_cast<TYPE2>( d_data[i] );
|
||||
for (size_t i = 0; i < d_size.length(); i++)
|
||||
data[i] = static_cast<TYPE2>(d_data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Convience typedefs *
|
||||
* Copy array *
|
||||
@@ -918,5 +872,4 @@ inline void Array<TYPE, FUN, Allocator>::copyTo( TYPE2 *data ) const
|
||||
typedef Array<double> DoubleArray;
|
||||
typedef Array<int> IntArray;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user