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;
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;
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.
*
* \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
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();
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.
*/
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,
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;
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__':
%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();"
void deleteSimplePack(const int i);
void deleteSimplePacks(const DataArrayIdType* idx);
+
+ MEDCouplingSkyLineArray *groupPacks(const DataArrayIdType *indexedPacks) const;
%extend
{
%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;
using namespace MEDCoupling;
+ParaSkyLineArray *ParaSkyLineArray::New(MEDCouplingSkyLineArray *ska, DataArrayIdType *globalIds)
+{
+ return new ParaSkyLineArray(ska,globalIds);
+}
+
ParaSkyLineArray::ParaSkyLineArray(MEDCouplingSkyLineArray *ska, DataArrayIdType *globalIds)
{
_ska.takeRef(ska);
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
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: