]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
WIP
authorAnthony Geay <anthony.geay@edf.fr>
Sun, 19 Apr 2020 16:06:11 +0000 (18:06 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Sun, 19 Apr 2020 16:06:11 +0000 (18:06 +0200)
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling/MEDCouplingMemArray.txx
src/MEDCoupling/MEDCouplingSkyLineArray.cxx
src/MEDCoupling/MEDCouplingSkyLineArray.hxx
src/MEDCoupling_Swig/DataArrayInt.i
src/MEDCoupling_Swig/MEDCouplingBasicsTest7.py
src/MEDCoupling_Swig/MEDCouplingCommon.i
src/MEDCoupling_Swig/MEDCouplingMemArray.i
src/ParaMEDMEM/ParaSkyLineArray.cxx
src/ParaMEDMEM/ParaSkyLineArray.hxx

index f0382270741997b5e3d5595baa434dea174455f7..a06cfefdd9fa1b9c1940a82d4036a1f898879a87 100755 (executable)
@@ -569,7 +569,7 @@ namespace MEDCoupling
     DataArrayIdType *findIdsEqual(T val) const;
     DataArrayIdType *transformWithIndArrR(const T *indArr2Bg, const T *indArrEnd) const;
     void splitByValueRange(const T *arrBg, const T *arrEnd,
-                                              DataArrayType *& castArr, DataArrayType *& rankInsideCast, DataArrayType *& castsPresent) const;
+                           DataArrayType *& castArr, DataArrayType *& rankInsideCast, DataArrayType *& castsPresent) const;
     bool isRange(T& strt, T& sttoopp, T& stteepp) const;
     DataArrayIdType *invertArrayO2N2N2O(mcIdType newNbOfElem) const;
     DataArrayIdType *invertArrayN2O2O2N(mcIdType oldNbOfElem) const;
@@ -622,6 +622,7 @@ namespace MEDCoupling
     DataArrayType *buildSubstractionOptimized(const DataArrayType *other) const;
     DataArrayType *buildUnion(const DataArrayType *other) const;
     DataArrayType *buildIntersection(const DataArrayType *other) const;
+    DataArrayIdType *indexOfSameConsecutiveValueGroups() const;
     DataArrayType *buildUnique() const;
     DataArrayType *buildUniqueNotSorted() const;
     DataArrayType *deltaShiftIndex() const;
index e4ff8dd764bb6abbb8ef68fac63bba1bd6f4ef6a..a52d83f2abbe15003ea03a75adf3c13e2dc57a8c 100755 (executable)
@@ -5705,6 +5705,53 @@ struct NotInRange
     arrs[0]=dynamic_cast<const DataArrayType *>(this); arrs[1]=other;
     return DataArrayDiscrete<T>::BuildIntersection(arrs);
   }
+  /*!
+   * This method can be applied on allocated with one component DataArrayInt instance.
+   * Locate groups of all consecutive same values in \a this and return them into an indexed array of positions pointing to \a this starting with 0.
+   * Number of tuples of returned array is equal to size of \a this->buildUnique() + 1.
+   * Last value of returned array is equal to \a this->getNumberOfTuples()
+   * 
+   * \b Example:
+   * - \a this : [0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 5, 11]
+   * - \a return is : [0, 1, 3, 5, 6, 8, 11, 12]
+   *
+   * \return a newly allocated array containing the indexed array of
+   * \throw if \a this is not allocated or if \a this has not exactly one component or if number of tuples is equal to 0.
+   * \sa DataArrayInt::buildUnique, MEDCouplingSkyLineArray::groupPacks
+   */
+  template <class T>
+  DataArrayIdType *DataArrayDiscrete<T>::indexOfSameConsecutiveValueGroups() const
+  {
+    this->checkAllocated();
+    if(this->getNumberOfComponents()!=1)
+      throw INTERP_KERNEL::Exception("DataArrayInt::indexOfSameConsecutiveValueGroups : only single component allowed !");
+    if(this->getNumberOfTuples()==0)
+      throw INTERP_KERNEL::Exception("DataArrayInt::indexOfSameConsecutiveValueGroups : number of tuples must be > 0 !");
+    const T *pt(this->begin());
+    const T *const ptEnd(this->end()) , * const ptBg(this->begin());
+    const T *oldPt(pt);
+    // first find nb of different values in this
+    std::size_t nbOfTuplesOut(0);
+    while( pt != ptEnd )
+    {
+      T val(*pt);
+      const T *endOfPack(std::find_if(pt+1,ptEnd,[val](T elt){ return val!=elt; }));
+      pt = endOfPack;
+      ++nbOfTuplesOut;
+    }
+    MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(nbOfTuplesOut+1,1);
+    mcIdType *retPtr(ret->getPointer()); *retPtr++ = 0;
+    pt = this->begin();
+    while( pt != ptEnd )
+    {
+      T val(*pt);
+      const T *endOfPack(std::find_if(pt+1,ptEnd,[val](T elt){ return val!=elt; }));
+      *retPtr++ = ToIdType( std::distance(ptBg,endOfPack) );
+      pt = endOfPack;
+      ++nbOfTuplesOut;
+    }
+    return ret.retn();
+  }
 
   /*!
    * This method can be applied on allocated with one component DataArrayInt instance.
@@ -5713,7 +5760,7 @@ struct NotInRange
    *
    * \return a newly allocated array that contain the result of the unique operation applied on \a this.
    * \throw if \a this is not allocated or if \a this has not exactly one component.
-   * \sa DataArrayInt::buildUniqueNotSorted
+   * \sa DataArrayInt::buildUniqueNotSorted, DataArrayInt::indexOfSameConsecutiveValueGroups
    */
   template <class T>
   typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildUnique() const
@@ -5721,12 +5768,12 @@ struct NotInRange
     this->checkAllocated();
     if(this->getNumberOfComponents()!=1)
       throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
-    std::size_t nbOfElements=this->getNumberOfTuples();
-    MCAuto<DataArrayType> tmp=DataArrayType::New();
-    tmp->deepCopyFrom (*this);
-    T *data=tmp->getPointer();
-    T *last=std::unique(data,data+nbOfElements);
-    MCAuto<DataArrayType> ret=DataArrayType::New();
+    std::size_t nbOfElements(this->getNumberOfTuples());
+    MCAuto<DataArrayType> tmp(DataArrayType::New());
+    tmp->deepCopyFrom(*this);
+    T *data(tmp->getPointer());
+    T *last(std::unique(data,data+nbOfElements));
+    MCAuto<DataArrayType> ret(DataArrayType::New());
     ret->alloc(std::distance(data,last),1);
     std::copy(data,last,ret->getPointer());
     return ret.retn();
index dcbb24a4cc819b777a79f0bd44c3869b7309674e..bc216096ae7aef9616064e80457449365ed922cd 100755 (executable)
@@ -312,6 +312,20 @@ std::string MEDCouplingSkyLineArray::simpleRepr() const
   return oss.str();
 }
 
+MEDCouplingSkyLineArray *MEDCouplingSkyLineArray::groupPacks(const DataArrayIdType *indexedPacks) const
+{
+  indexedPacks->checkAllocated();
+  if( indexedPacks->getNumberOfComponents() != 1 )
+    throw INTERP_KERNEL::Exception("MEDCouplingSkyLineArray::groupPacks : number of components must be 1 !");
+  std::size_t nbTuples(indexedPacks->getNumberOfTuples());
+  if( nbTuples == 0 )
+    throw INTERP_KERNEL::Exception("MEDCouplingSkyLineArray::groupPacks : number of tuples must be > 0 !");
+  const DataArrayIdType *index(this->getIndexArray());
+  MCAuto<DataArrayIdType> partIndex(index->selectByTupleIdSafe(indexedPacks->begin(),indexedPacks->end()));
+  MCAuto<MEDCouplingSkyLineArray> ret(MEDCouplingSkyLineArray::New(partIndex,this->getValuesArray()));
+  return ret.retn();
+}
+
 /**
  * For a 2- or 3-level SkyLine array, return a copy of the absolute pack with given identifier.
  */
index f7280c1bee13cc0653dfb6e76815f342c37273aa..21fba35eb08dd262aa4c650d74f97a4718d39ea4 100644 (file)
@@ -107,6 +107,8 @@ namespace MEDCoupling
 
     std::string simpleRepr() const;
 
+    MEDCouplingSkyLineArray *groupPacks(const DataArrayIdType *indexedPacks) const;
+
     void getSimplePackSafe(const mcIdType absolutePackId, std::vector<mcIdType> & pack) const;
     const mcIdType * getSimplePackSafePtr(const mcIdType absolutePackId, mcIdType & packSize) const;
     void findPackIds(const std::vector<mcIdType> & superPackIndices, const mcIdType *packBg, const mcIdType *packEnd,
index 15484e476772aad3af3a071d071a08a73d7183a9..2d1d07e1e425eb32a25a23f4b3cadbee6899acbe 100644 (file)
     ARRAY *buildSubstractionOptimized(const ARRAY *other) const;
     ARRAY *buildUnion(const ARRAY *other) const;
     ARRAY *buildIntersection(const ARRAY *other) const;
+    DataArrayIdType *indexOfSameConsecutiveValueGroups() const;
     ARRAY *buildUnique() const;
     ARRAY *buildUniqueNotSorted() const;
     ARRAY *deltaShiftIndex() const;
index f73300fa4a1224d13d47059831199e0ecc2cae00..953d7292735fc03e1ce778e04ee494c6d8012645 100644 (file)
@@ -759,6 +759,24 @@ class MEDCouplingBasicsTest7(unittest.TestCase):
         arr=DataArrayInt([5,3,2,1,4,5,2,1,0,11,5,4])
         self.assertTrue(arr.occurenceRankInThis().isEqual(DataArrayInt([0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 2, 1])))
 
+    def testDAIFindPermutationFromFirstToSecondDuplicate(self):
+        arr0 = DataArrayInt([5,3,2,1,4,5,2,1,0,11,5,4])
+        arr1 = DataArrayInt([0,1,1,2,2,3,4,4,5,5,5,11])
+        self.assertTrue(DataArrayInt.FindPermutationFromFirstToSecondDuplicate(arr0,arr1).isEqual(DataArrayInt([8,5,3,1,6,9,4,2,0,11,10,7])))
+        self.assertTrue(DataArrayInt.FindPermutationFromFirstToSecondDuplicate(arr1,arr0).isEqual(DataArrayInt([8,3,7,2,6,1,4,11,0,5,10,9])))
+        
+    def testDAIIndexOfSameConsecutiveValueGroups(self):
+        arr = DataArrayInt([0,1,1,2,2,3,4,4,5,5,5,11])
+        self.assertTrue(arr.indexOfSameConsecutiveValueGroups().isEqual(DataArrayInt([0, 1, 3, 5, 6, 8, 11, 12])))
+
+    def testSkyLineGroupPacks(self):
+        arr = DataArrayInt([1,4,5,0,2,4,5,6,1,3,5,6,7,2,6,7,0,1,5,8,9,0,1,2,4,6,8,9,10,1,2,3,5,7,9,10,11,2,3,6,10,11,4,5,9,12,13,4,5,6,8,10,12,13,14,5,6,7,9,11,13,14,15,6,7,10,14,15,8,9,13,8,9,10,12,14,9,10,11,13,15,10,11,14])
+        arrI = DataArrayInt([0,3,8,13,16,21,29,37,42,47,55,63,68,71,76,81,84])
+        sk = MEDCouplingSkyLineArray(arrI,arr)
+        part = DataArrayInt([0,3,4,7,16])
+        sk2 = sk.groupPacks(part)
+        self.assertTrue(sk2.getValuesArray().isEqual(arr))
+        self.assertTrue(sk2.getIndexArray().isEqual(DataArrayInt([0,13,16,37,84])))
     pass
 
 if __name__ == '__main__':
index d90474d782fd55bd05bacac4c200b4c12f59720e..b3b8069957d4bb5f4f7ae8a1dec117195e924e00 100644 (file)
@@ -466,6 +466,7 @@ typedef long int mcIdType;
 %newobject MEDCoupling::MEDCouplingSkyLineArray::getSuperIndexArray;
 %newobject MEDCoupling::MEDCouplingSkyLineArray::getIndexArray;
 %newobject MEDCoupling::MEDCouplingSkyLineArray::getValuesArray;
+%newobject MEDCoupling::MEDCouplingSkyLineArray::groupPacks;
 
 %feature("unref") MEDCouplingPointSet "$this->decrRef();"
 %feature("unref") MEDCouplingMesh "$this->decrRef();"
@@ -1296,6 +1297,8 @@ namespace MEDCoupling
     
     void deleteSimplePack(const int i);
     void deleteSimplePacks(const DataArrayIdType* idx);
+
+    MEDCouplingSkyLineArray *groupPacks(const DataArrayIdType *indexedPacks) const;
     
     %extend 
     {
index aa591ba51146db869432ffa1b3d056920e785a08..2152f9a1f95d5deb043e3374e320d570cabbd02d 100644 (file)
 %newobject MEDCoupling::DataArrayInt32::buildSubstraction;
 %newobject MEDCoupling::DataArrayInt32::buildSubstractionOptimized;
 %newobject MEDCoupling::DataArrayInt32::buildIntersection;
+%newobject MEDCoupling::DataArrayInt32::indexOfSameConsecutiveValueGroups;
 %newobject MEDCoupling::DataArrayInt32::buildUnique;
 %newobject MEDCoupling::DataArrayInt32::buildUniqueNotSorted;
 %newobject MEDCoupling::DataArrayInt32::deltaShiftIndex;
 %newobject MEDCoupling::DataArrayInt64::buildSubstraction;
 %newobject MEDCoupling::DataArrayInt64::buildSubstractionOptimized;
 %newobject MEDCoupling::DataArrayInt64::buildIntersection;
+%newobject MEDCoupling::DataArrayInt64::indexOfSameConsecutiveValueGroups;
 %newobject MEDCoupling::DataArrayInt64::buildUnique;
 %newobject MEDCoupling::DataArrayInt64::buildUniqueNotSorted;
 %newobject MEDCoupling::DataArrayInt64::deltaShiftIndex;
index a7f0d22b9d9e6e099aeb11a351fb9a4ad9ebf784..e75283a4a2d84d2fac3574be9ad7d8f8e37898f9 100644 (file)
 
 using namespace MEDCoupling;
 
+ParaSkyLineArray *ParaSkyLineArray::New(MEDCouplingSkyLineArray *ska, DataArrayIdType *globalIds)
+{
+  return new ParaSkyLineArray(ska,globalIds);
+}
+
 ParaSkyLineArray::ParaSkyLineArray(MEDCouplingSkyLineArray *ska, DataArrayIdType *globalIds)
 {
   _ska.takeRef(ska);
@@ -95,4 +100,20 @@ MCAuto<ParaSkyLineArray> ParaSkyLineArray::equiRedistribute(mcIdType nbOfEntitie
     ci.allToAllArrays(comm,valuesToBeSent,myRkSkValues);
     values = DataArrayIdType::Aggregate(FromVecAutoToVecOfConst<DataArrayIdType>(myRkSkValues));
   }
+  // Reorder results coming from other procs
+  MCAuto<DataArrayIdType> aggregatedIdsSort(aggregatedIds->deepCopy()); aggregatedIds->sort();
+  MCAuto<DataArrayIdType> idsIntoAggregatedIds(DataArrayIdType::FindPermutationFromFirstToSecondDuplicate(aggregatedIdsSort,aggregatedIds));
+  MCAuto<DataArrayIdType> indicesSorted,valuesSorted;
+  {
+    DataArrayIdType *indicesSortedTmp(nullptr),*valuesSortedTmp(nullptr);
+    DataArrayIdType::ExtractFromIndexedArrays(idsIntoAggregatedIds->begin(),idsIntoAggregatedIds->end(),values,indices,valuesSortedTmp,indicesSortedTmp);
+    indicesSorted = indicesSortedTmp; valuesSorted=valuesSortedTmp;
+  }
+  MCAuto<DataArrayIdType> idxOfSameIds(aggregatedIdsSort->indexOfSameConsecutiveValueGroups());
+  //
+  MCAuto<DataArrayIdType> globalIdsOut(aggregatedIds->buildUnique());
+  MCAuto<MEDCouplingSkyLineArray> skOut(MEDCouplingSkyLineArray::New(valuesSorted,indicesSorted));
+  skOut = skOut->groupPacks(idxOfSameIds);
+  MCAuto<ParaSkyLineArray> ret(ParaSkyLineArray::New(skOut,globalIdsOut));
+  return ret.retn();
 }
\ No newline at end of file
index e012f96095b172594746f5ede32c23430f5a83fc..19dad005a5b96340816074e07014b54459998bf2 100644 (file)
@@ -37,10 +37,13 @@ namespace MEDCoupling
   class ParaSkyLineArray : public RefCountObject
   {
   public:
-    ParaSkyLineArray(MEDCouplingSkyLineArray *ska, DataArrayIdType *globalIds);
+    static ParaSkyLineArray *New(MEDCouplingSkyLineArray *ska, DataArrayIdType *globalIds);
     MCAuto<ParaSkyLineArray> equiRedistribute(mcIdType nbOfEntities) const;
     virtual ~ParaSkyLineArray() { }
+  private:
+    ParaSkyLineArray(MEDCouplingSkyLineArray *ska, DataArrayIdType *globalIds);
   protected:
+    std::string getClassName() const override { return "ParaSkyLineArray"; }
     std::size_t getHeapMemorySizeWithoutChildren() const override;
     std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const override;
   private: