From 05e2e1b74944fd4f488c9ab8bc7a8b95a21f3ee5 Mon Sep 17 00:00:00 2001 From: ageay Date: Mon, 25 Mar 2013 16:25:56 +0000 Subject: [PATCH] pow on DataArrayInt and reverse with multi component --- src/MEDCoupling/MEDCouplingMemArray.cxx | 167 +++++++++++++++++++- src/MEDCoupling/MEDCouplingMemArray.hxx | 7 +- src/MEDCoupling/MEDCouplingMemArray.txx | 20 ++- src/MEDCoupling/MEDCouplingMemArrayChar.cxx | 12 ++ 4 files changed, 195 insertions(+), 11 deletions(-) diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 235a81e38..d2a322a0d 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -909,19 +909,19 @@ void DataArrayDouble::sort(bool asc) throw(INTERP_KERNEL::Exception) if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !"); _mem.sort(asc); + declareAsNew(); } /*! * Reverse the array values. - * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this->getNumberOfComponents() < 1. * \throw If \a this is not allocated. */ void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception) { checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::reverse : only supported with 'this' array with ONE component !"); - _mem.reverse(); + _mem.reverse(getNumberOfComponents()); + declareAsNew(); } /*! @@ -5698,19 +5698,19 @@ void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception) if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !"); _mem.sort(asc); + declareAsNew(); } /*! * Reverse the array values. - * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this->getNumberOfComponents() < 1. * \throw If \a this is not allocated. */ void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception) { checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::reverse : only supported with 'this' array with ONE component !"); - _mem.reverse(); + _mem.reverse(getNumberOfComponents()); + declareAsNew(); } /*! @@ -8043,6 +8043,69 @@ void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception) declareAsNew(); } +/*! + * Modify all elements of \a this array, so that + * an element _x_ becomes val ^ x . + * \param [in] val - the value used to apply pow on all array elements. + * \throw If \a this is not allocated. + * \throw If \a val < 0. + */ +void DataArrayInt::applyPow(int val) throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(val<0) + throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !"); + int *ptr=getPointer(); + std::size_t nbOfElems=getNbOfElems(); + if(val==0) + { + std::fill(ptr,ptr+nbOfElems,1.); + return ; + } + for(std::size_t i=0;i=0) + { + int tmp=1; + for(int j=0;j<*ptr;j++) + tmp*=val; + *ptr=val; + } + else + { + std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents(); + oss << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + declareAsNew(); +} + /*! * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number * of components in the result array is a sum of the number of components of given arrays @@ -9597,6 +9660,94 @@ void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL:: declareAsNew(); } +/*! + * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3 + * valid cases. + * + * \param [in] a1 - an array to pow up. + * \param [in] a2 - another array to sum up. + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() + * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1. + * \throw If there is a negative value in \a a2. + */ +DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !"); + int nbOfTuple=a1->getNumberOfTuples(); + int nbOfTuple2=a2->getNumberOfTuples(); + int nbOfComp=a1->getNumberOfComponents(); + int nbOfComp2=a2->getNumberOfComponents(); + if(nbOfTuple!=nbOfTuple2) + throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !"); + if(nbOfComp!=1 || nbOfComp2!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !"); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1); + const int *ptr1(a1->begin()),*ptr2(a2->begin()); + int *ptr=ret->getPointer(); + for(int i=0;i=0) + { + int tmp=1; + for(int j=0;j<*ptr2;j++) + tmp*=*ptr1; + *ptr=tmp; + } + else + { + std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret.retn(); +} + +/*! + * Apply pow on values of another DataArrayInt to values of \a this one. + * + * \param [in] other - an array to pow to \a this one. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() + * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1 + * \throw If there is a negative value in \a other. + */ +void DataArrayInt::powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception) +{ + if(!other) + throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !"); + int nbOfTuple=getNumberOfTuples(); + int nbOfTuple2=other->getNumberOfTuples(); + int nbOfComp=getNumberOfComponents(); + int nbOfComp2=other->getNumberOfComponents(); + if(nbOfTuple!=nbOfTuple2) + throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !"); + if(nbOfComp!=1 || nbOfComp2!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !"); + int *ptr=getPointer(); + const int *ptrc=other->begin(); + for(int i=0;i=0) + { + int tmp=1; + for(int j=0;j<*ptrc;j++) + tmp*=*ptr; + *ptr=tmp; + } + else + { + std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + declareAsNew(); +} + /*! * Returns a C array which is a renumbering map in "Old to New" mode for the input array. * This map, if applied to \a start array, would make it sorted. For example, if diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index e48cde8a3..6bb2c48ee 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -74,7 +74,7 @@ namespace ParaMEDMEM T *fromNoInterlace(int nbOfComp) const; T *toNoInterlace(int nbOfComp) const; void sort(bool asc); - void reverse(); + void reverse(int nbOfComp); void alloc(std::size_t nbOfElements) throw(INTERP_KERNEL::Exception); void reserve(std::size_t newNbOfElements) throw(INTERP_KERNEL::Exception); void reAlloc(std::size_t newNbOfElements) throw(INTERP_KERNEL::Exception); @@ -494,6 +494,8 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void applyDivideBy(int val) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void applyModulus(int val) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void applyRModulus(int val) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void applyPow(int val) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void applyRPow(int val) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayInt *Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2); MEDCOUPLING_EXPORT static DataArrayInt *Aggregate(const std::vector& arr) throw(INTERP_KERNEL::Exception); @@ -533,6 +535,8 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT static DataArrayInt *Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayInt *Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void updateTime() const { } public: MEDCOUPLING_EXPORT static int *CheckAndPreparePermutation(const int *start, const int *end); @@ -604,6 +608,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT bool isEqual(const DataArrayChar& other) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT virtual bool isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayChar& other) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void reverse() throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void fillWithZero() throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void fillWithValue(char val) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT std::string repr() const throw(INTERP_KERNEL::Exception); diff --git a/src/MEDCoupling/MEDCouplingMemArray.txx b/src/MEDCoupling/MEDCouplingMemArray.txx index f891dd9c8..be73b6dbd 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.txx +++ b/src/MEDCoupling/MEDCouplingMemArray.txx @@ -310,10 +310,26 @@ namespace ParaMEDMEM } template - void MemArray::reverse() + void MemArray::reverse(int nbOfComp) { + if(nbOfComp<1) + throw INTERP_KERNEL::Exception("MemArray::reverse : only supported with 'this' array with ONE or more than ONE component !"); T *pt=_pointer.getPointer(); - std::reverse(pt,pt+_nb_of_elem); + if(nbOfComp==1) + { + std::reverse(pt,pt+_nb_of_elem); + return ; + } + else + { + T *pt2=pt+_nb_of_elem-nbOfComp; + std::size_t nbOfTuples=_nb_of_elem/nbOfComp; + for(std::size_t i=0;i diff --git a/src/MEDCoupling/MEDCouplingMemArrayChar.cxx b/src/MEDCoupling/MEDCouplingMemArrayChar.cxx index e0d8a59fb..7663146f9 100644 --- a/src/MEDCoupling/MEDCouplingMemArrayChar.cxx +++ b/src/MEDCoupling/MEDCouplingMemArrayChar.cxx @@ -301,6 +301,18 @@ bool DataArrayChar::isEqualWithoutConsideringStr(const DataArrayChar& other) con return _mem.isEqual(other._mem,0,tmp); } +/*! + * Reverse the array values. + * \throw If \a this->getNumberOfComponents() < 1. + * \throw If \a this is not allocated. + */ +void DataArrayChar::reverse() throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + _mem.reverse(getNumberOfComponents()); + declareAsNew(); +} + /*! * Assign zero to all values in \a this array. To know more on filling arrays see * \ref MEDCouplingArrayFill. -- 2.39.2