/*************************************************************************** * GNdarray.hpp - N-dimensional array class * * ----------------------------------------------------------------------- * * copyright (C) 2016 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * ***************************************************************************/ /** * @file GNdarray.hpp * @brief N-dimensional array class interface definition * @author Juergen Knoedlseder */ #ifndef GNDARRAY_HPP #define GNDARRAY_HPP /* __ Includes ___________________________________________________________ */ #include #include #include "GBase.hpp" /***********************************************************************//** * @class GNdarray * * @brief N-dimensional array class * * This class implements a n-dimensional double precision floating point * array. ***************************************************************************/ class GNdarray : public GBase { // Friend functions friend double min(const GNdarray& array); friend double max(const GNdarray& array); friend double sum(const GNdarray& array); friend GNdarray acos(const GNdarray& array); friend GNdarray acosh(const GNdarray& array); friend GNdarray asin(const GNdarray& array); friend GNdarray asinh(const GNdarray& array); friend GNdarray atan(const GNdarray& array); friend GNdarray atanh(const GNdarray& array); friend GNdarray cos(const GNdarray& array); friend GNdarray cosh(const GNdarray& array); friend GNdarray exp(const GNdarray& array); friend GNdarray abs(const GNdarray& array); friend GNdarray log(const GNdarray& array); friend GNdarray log10(const GNdarray& array); friend GNdarray sin(const GNdarray& array); friend GNdarray sinh(const GNdarray& array); friend GNdarray sqrt(const GNdarray& array); friend GNdarray tan(const GNdarray& array); friend GNdarray tanh(const GNdarray& array); friend GNdarray pow(const GNdarray& array, const double& power); public: // Constructors and destructors GNdarray(void); explicit GNdarray(const int& nx); GNdarray(const int& nx, const int& ny); GNdarray(const int& nx, const int& ny, const int& nz); GNdarray(const std::vector& n); GNdarray(const GNdarray& array); virtual ~GNdarray(void); // Element access operators double& operator()(const int& ix); double& operator()(const int& ix, const int& iy); double& operator()(const int& ix, const int& iy, const int& iz); double& operator()(const std::vector& i); const double& operator()(const int& ix) const; const double& operator()(const int& ix, const int& iy) const; const double& operator()(const int& ix, const int& iy, const int& iz) const; const double& operator()(const std::vector& i) const; // Operators GNdarray& operator=(const GNdarray& array); bool operator==(const GNdarray& array) const; bool operator!=(const GNdarray& array) const; GNdarray& operator+=(const GNdarray& array); GNdarray& operator-=(const GNdarray& array); GNdarray& operator+=(const double& value); GNdarray& operator-=(const double& value); GNdarray& operator*=(const double& value); GNdarray& operator/=(const double& value); GNdarray operator-(void) const; // Methods void clear(void); GNdarray* clone(void) const; std::string classname(void) const; int dim(void) const; int size(void) const; const std::vector& shape(void) const; const std::vector& strides(void) const; double& at(const int& ix); double& at(const int& ix, const int& iy); double& at(const int& ix, const int& iy, const int& iz); double& at(const std::vector& i); const double& at(const int& ix) const; const double& at(const int& ix, const int& iy) const; const double& at(const int& ix, const int& iy, const int& iz) const; const double& at(const std::vector& i) const; std::string print(const GChatter& chatter = NORMAL) const; protected: // Protected methods void init_members(void); void copy_members(const GNdarray& array); void free_members(void); int index(const std::vector& i) const; bool has_same_shape(const GNdarray& array) const; void require_same_shape(const std::string& method, const GNdarray& array) const; // Protected members std::vector m_shape; //!< Array dimensions std::vector m_strides; //!< Steps in each dimension when traversing array std::vector m_data; //!< Array data }; /***********************************************************************//** * @brief Return class name * * @return String containing the class name ("GNdarray"). ***************************************************************************/ inline std::string GNdarray::classname(void) const { return ("GNdarray"); } /***********************************************************************//** * @brief 1-dimensional array element access operator * * @param[in] ix Element index [0,...,shape(0)-1]. * @return Reference to array element. ***************************************************************************/ inline double& GNdarray::operator()(const int& ix) { // Return array element return m_data[ix]; } /***********************************************************************//** * @brief 2-dimensional array element access operator * * @param[in] ix Index in first dimension [0,...,shape(0)-1]. * @param[in] iy Index in second dimension [0,...,shape(1)-1]. * @return Reference to array element. ***************************************************************************/ inline double& GNdarray::operator()(const int& ix, const int& iy) { // Return array element return m_data[ix+m_strides[1]*iy]; } /***********************************************************************//** * @brief 3-dimensional array element access operator * * @param[in] ix Index in first dimension [0,...,shape(0)-1]. * @param[in] iy Index in second dimension [0,...,shape(1)-1]. * @param[in] iz Index in third dimension [0,...,shape(2)-1]. * @return Reference to array element. ***************************************************************************/ inline double& GNdarray::operator()(const int& ix, const int& iy, const int& iz) { // Return array element return m_data[ix+m_strides[1]*iy+m_strides[2]*iz]; } /***********************************************************************//** * @brief n-dimensional array element access operator * * @param[in] i Index vector. * @return Reference to array element. ***************************************************************************/ inline double& GNdarray::operator()(const std::vector& i) { // Return array element return m_data[index(i)]; } /***********************************************************************//** * @brief 1-dimensional array element access operator (const variant) * * @param[in] ix Element index [0,...,shape(0)-1]. * @return Const reference to array element. ***************************************************************************/ inline const double& GNdarray::operator()(const int& ix) const { // Return array element return m_data[ix]; } /***********************************************************************//** * @brief 2-dimensional array element access operator (const variant) * * @param[in] ix Index in first dimension [0,...,shape(0)-1]. * @param[in] iy Index in second dimension [0,...,shape(1)-1]. * @return Const reference to array element. ***************************************************************************/ inline const double& GNdarray::operator()(const int& ix, const int& iy) const { // Return array element return m_data[ix+m_strides[1]*iy]; } /***********************************************************************//** * @brief 3-dimensional array element access operator (const variant) * * @param[in] ix Index in first dimension [0,...,shape(0)-1]. * @param[in] iy Index in second dimension [0,...,shape(1)-1]. * @param[in] iz Index in third dimension [0,...,shape(2)-1]. * @return Const reference to array element. ***************************************************************************/ inline const double& GNdarray::operator()(const int& ix, const int& iy, const int& iz) const { // Return array element return m_data[ix+m_strides[1]*iy+m_strides[2]*iz]; } /***********************************************************************//** * @brief n-dimensional array element access operator (const variant) * * @param[in] i Index vector. * @return Const reference to array element. ***************************************************************************/ inline const double& GNdarray::operator()(const std::vector& i) const { // Return array element return m_data[index(i)]; } /***********************************************************************//** * @brief Return dimension of array * * @return Dimension of array * * Returns the dimension of the array. ***************************************************************************/ inline int GNdarray::dim(void) const { return m_shape.size(); } /***********************************************************************//** * @brief Return number of elements in array * * @return Number of elements in array * * Returns the number of elements in the array. ***************************************************************************/ inline int GNdarray::size(void) const { return m_data.size(); } /***********************************************************************//** * @brief Return shape of array * * @return Shape of array * * Returns the shape of the array. ***************************************************************************/ inline const std::vector& GNdarray::shape(void) const { return m_shape; } /***********************************************************************//** * @brief Return strides of array * * @return Strides of array * * Returns the strides of the array. ***************************************************************************/ inline const std::vector& GNdarray::strides(void) const { return m_strides; } /***********************************************************************//** * @brief 1-dimensional array element access with range checking * * @param[in] ix Element index [0,...,shape(0)-1]. * @return Reference to array element. ***************************************************************************/ inline double& GNdarray::at(const int& ix) { return const_cast(static_cast(*this).at(ix)); } /***********************************************************************//** * @brief 2-dimensional array element access with range checking * * @param[in] ix Index in first dimension [0,...,shape(0)-1]. * @param[in] iy Index in second dimension [0,...,shape(1)-1]. * @return Reference to array element. ***************************************************************************/ inline double& GNdarray::at(const int& ix, const int& iy) { return const_cast(static_cast(*this).at(ix,iy)); } /***********************************************************************//** * @brief 3-dimensional array element access with range checking * * @param[in] ix Index in first dimension [0,...,shape(0)-1]. * @param[in] iy Index in second dimension [0,...,shape(1)-1]. * @param[in] iz Index in third dimension [0,...,shape(2)-1]. * @return Reference to array element. ***************************************************************************/ inline double& GNdarray::at(const int& ix, const int& iy, const int& iz) { return const_cast(static_cast(*this).at(ix,iy,iz)); } /***********************************************************************//** * @brief n-dimensional array element access with range checking * * @param[in] i Index vector. * @return Reference to array element. ***************************************************************************/ inline double& GNdarray::at(const std::vector& i) { return const_cast(static_cast(*this).at(i)); } /***********************************************************************//** * @brief Return sum of two arrays * * @param[in] a First array. * @param[in] b Second array. * @return Sum of arrays @p a and @p b. * * Returns the sum of arrays @p a and @p b. ***************************************************************************/ inline GNdarray operator+(const GNdarray& a, const GNdarray& b) { GNdarray result = a; result += b; return result; } /***********************************************************************//** * @brief Add value to array (right addition) * * @param[in] array Array. * @param[in] value Value. * @return Array with @p value added to all elements. * * Returns an array for which the @p value has been added to all elements. ***************************************************************************/ inline GNdarray operator+(const GNdarray& array, const double& value) { GNdarray result = array; result += value; return result; } /***********************************************************************//** * @brief Add value to array (left addition) * * @param[in] value Value. * @param[in] array Array. * @return Array with @p value added to all elements. * * Returns an array for which the @p value has been added to all elements. ***************************************************************************/ inline GNdarray operator+(const double& value, const GNdarray& array) { GNdarray result = array; result += value; return result; } /***********************************************************************//** * @brief Return difference of arrays * * @param[in] a First array. * @param[in] b Second array. * @return Difference between array @p a and @p b. * * Returns the difference between array @p a and @p b. ***************************************************************************/ inline GNdarray operator-(const GNdarray& a, const GNdarray& b) { GNdarray result = a; result -= b; return result; } /***********************************************************************//** * @brief Subtract value from array * * @param[in] array Array. * @param[in] value Value. * @return Array with @p value subtracted from all elements. * * Returns an array for which the @p value has been subtracted from all * elements. For example * * double value = 5.0; * GNdarray result = array - value; ***************************************************************************/ inline GNdarray operator-(const GNdarray& array, const double& value) { GNdarray result = array; result -= value; return result; } /***********************************************************************//** * @brief Subtract array from value * * @param[in] value Value. * @param[in] array Array. * @return Array with @p value subtracted from all elements. * * Returns an array for which all elements have been subtracted from * @p value. For example * * double value = 5.0; * GNdarray result = value - array; ***************************************************************************/ inline GNdarray operator-(const double& value, const GNdarray& array) { GNdarray result = -array; result += value; return result; } /***********************************************************************//** * @brief Multiply array by value (right multiplication) * * @param[in] array Array. * @param[in] value Value. * @return Array for which all elements have be multiplied by @p value. * * Returns an array for which all elements have be multiplied by @p value. ***************************************************************************/ inline GNdarray operator*(const GNdarray& array, const double& value) { GNdarray result = array; result *= value; return result; } /***********************************************************************//** * @brief Multiply array by value (left multiplication) * * @param[in] value Value. * @param[in] array Array. * @return Array for which all elements have be multiplied by @p value. * * Returns an array for which all elements have be multiplied by @p value. ***************************************************************************/ inline GNdarray operator*(const double& value, const GNdarray& array) { GNdarray result = array; result *= value; return result; } /***********************************************************************//** * @brief Divide array by value * * @param[in] array Array. * @param[in] value Value. * @return Array for which all elements have be divided by @p value. * * Returns an array for which all elements have be divided by @p value. ***************************************************************************/ inline GNdarray operator/(const GNdarray& array, const double& value) { GNdarray result = array; result /= value; return result; } #endif /* GNDARRAY_HPP */