/*************************************************************************** * GNdarray.i - N-dimensional array class * * ----------------------------------------------------------------------- * * copyright (C) 2016-2017 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.i * @brief N-dimensional array class interface definition * @author Juergen Knoedlseder */ %{ /* Put headers and other declarations here that are needed for compilation */ #include "GNdarray.hpp" %} /***********************************************************************//** * @class GNdarray * * @brief N-dimensional array class * * This class implement a n-dimensional double precision floating point * array. ***************************************************************************/ class GNdarray : public GBase { 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); // Operators 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 GNdarray& array); GNdarray& operator/=(const GNdarray& array); 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() const; int size(void) const; const std::vector& shape(void) const; const std::vector& strides(void) const; void shape(const std::vector& shape); double* data(void); }; /***********************************************************************//** * @brief GNdarray class extension ***************************************************************************/ %extend GNdarray { double __getitem__(int GTuple[]) { // Handle first the special case of a single index. In Python we want // to support accessing a n-dimensional array with a single index so // that we can iterate over the array if (GTuple[0] == 1) { if (GTuple[1] >= 0 && GTuple[1] < self->size()) { return ((*self)(GTuple[1])); } else { throw GException::out_of_range("__getitem__(int)", "Array " "index", GTuple[1], self->size()); } } if (GTuple[0] != self->dim()) { throw GException::invalid_value("__getitem__(int)", "Invalid " "access of "+gammalib::str(self->dim())+"-dimensional " "array with "+gammalib::str(GTuple[0])+"-dimensional " "access operator."); } int index = 0; for (size_t i = 0; i < self->shape().size(); ++i) { if (GTuple[i+1] < 0 || GTuple[i+1] >= self->shape()[i]) { throw GException::out_of_range("__getitem__(int)", "Dimension "+ gammalib::str(i)+" index", GTuple[i+1], self->shape()[i]); } index += self->strides()[i] * GTuple[i+1]; } return ((*self)(index)); } void __setitem__(int GTuple[], const double& value) { if (GTuple[0] != self->dim()) { throw GException::invalid_value("__setitem__(int)", "Invalid " "access of "+gammalib::str(self->dim())+"-dimensional " "array with "+gammalib::str(GTuple[0])+"-dimensional " "access operator."); } int index = 0; for (size_t i = 0; i < self->shape().size(); ++i) { if (GTuple[i+1] < 0 || GTuple[i+1] >= self->shape()[i]) { throw GException::out_of_range("__setitem__(int)", "Dimension "+ gammalib::str(i)+" index", GTuple[i+1], self->shape()[i]); } index += self->strides()[i] * GTuple[i+1]; } (*self)(index) = value; } GNdarray __add__(const GNdarray &a) { return (*self) + a; } GNdarray __add__(const double &a) { return (*self) + a; } GNdarray __sub__(const GNdarray &a) { return (*self) - a; } GNdarray __sub__(const double &a) { return (*self) - a; } GNdarray __mul__(const double &a) { return (*self) * a; } // Python 2.x GNdarray __div__(const double &a) { return (*self) / a; } // Python 3.x GNdarray __truediv__(const double &a) { return (*self) / a; } // Python 2.x operator/= GNdarray __idiv__(const double& value) { self->operator/=(value); return (*self); } // Python 3.x operator/= GNdarray __itruediv__(const double& value) { self->operator/=(value); return (*self); } int __is__(const GNdarray &a) { return (*self) == a; } GNdarray copy() { return (*self); } double min() { return min(*self); } double max() { return max(*self); } double sum() { return sum(*self); } GNdarray acos() { return acos(*self); } GNdarray acosh() { return acosh(*self); } GNdarray asin() { return asin(*self); } GNdarray asinh() { return asinh(*self); } GNdarray atan() { return atan(*self); } GNdarray atanh() { return atanh(*self); } GNdarray cos() { return cos(*self); } GNdarray cosh() { return cosh(*self); } GNdarray exp() { return exp(*self); } GNdarray abs() { return abs(*self); } GNdarray log() { return log(*self); } GNdarray log10() { return log10(*self); } GNdarray sign() { return sign(*self); } GNdarray sin() { return sin(*self); } GNdarray sinh() { return sinh(*self); } GNdarray sqrt() { return sqrt(*self); } GNdarray tan() { return tan(*self); } GNdarray tanh() { return tanh(*self); } };