]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
pow on DataArrayInt and reverse with multi component
authorageay <ageay>
Mon, 25 Mar 2013 16:25:56 +0000 (16:25 +0000)
committerageay <ageay>
Mon, 25 Mar 2013 16:25:56 +0000 (16:25 +0000)
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling/MEDCouplingMemArray.txx
src/MEDCoupling/MEDCouplingMemArrayChar.cxx

index 235a81e380c9da2a849f7081a43853fce4448e8e..d2a322a0d538710ea830975f4767b292afbea62b 100644 (file)
@@ -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 <em> val ^ x </em>.
+ *  \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<nbOfElems;i++,ptr++)
+    {
+      int tmp=1;
+      for(int j=0;j<val;j++)
+        tmp*=*ptr;
+      *ptr=tmp;
+    }
+  declareAsNew();
+}
+
+/*!
+ * Modify all elements of \a this array, so that
+ * an element _x_ becomes \f$ val ^ x \f$.
+ *  \param [in] val - the value used to apply pow on all array elements.
+ *  \throw If \a this is not allocated.
+ *  \throw If there is an element < 0 in \a this array.
+ *  \warning If an exception is thrown because of presence of 0 element in \a this 
+ *           array, all elements processed before detection of the zero element remain
+ *           modified.
+ */
+void DataArrayInt::applyRPow(int val) throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  int *ptr=getPointer();
+  std::size_t nbOfElems=getNbOfElems();
+  for(std::size_t i=0;i<nbOfElems;i++,ptr++)
+    {
+      if(*ptr>=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<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
+  const int *ptr1(a1->begin()),*ptr2(a2->begin());
+  int *ptr=ret->getPointer();
+  for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
+    {
+      if(*ptr2>=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<nbOfTuple;i++,ptrc++,ptr++)
+    {
+      if(*ptrc>=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
index e48cde8a359608c9a79071df0b804e6df0e8844e..6bb2c48ee1d3f2398a149f8becba8d952d147e73 100644 (file)
@@ -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<const DataArrayInt *>& 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);
index f891dd9c8ca69cc9f25ec9ed7bafb365fd5bbac3..be73b6dbd8ba0e91833e0d59f876725070c71ef7 100644 (file)
@@ -310,10 +310,26 @@ namespace ParaMEDMEM
   }
 
   template<class T>
-  void MemArray<T>::reverse()
+  void MemArray<T>::reverse(int nbOfComp)
   {
+    if(nbOfComp<1)
+      throw INTERP_KERNEL::Exception("MemArray<T>::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<nbOfTuples/2;i++,pt+=nbOfComp,pt2-=nbOfComp)
+          {
+            for(int j=0;j<nbOfComp;j++)
+              std::swap(pt[j],pt2[j]);
+          }
+      }
   }
 
   template<class T>
index e0d8a59fb6743eb90ff58ccf7f9f22dfe73c092e..7663146f9f5b233b48344fda2a64b453f307c286 100644 (file)
@@ -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.