From 58234982f7246d2782567c00ef25d8f02ff2857d Mon Sep 17 00:00:00 2001 From: ageay Date: Thu, 8 Nov 2012 08:42:03 +0000 Subject: [PATCH] Some code factorization --- .../MEDCouplingFieldDiscretization.cxx | 25 +---------- src/MEDCoupling/MEDCouplingMemArray.cxx | 41 ++++++++++++++++++- src/MEDCoupling/MEDCouplingMemArray.hxx | 1 + src/MEDCoupling_Swig/MEDCouplingBasicsTest.py | 9 ++++ src/MEDCoupling_Swig/MEDCouplingCommon.i | 19 +++++++++ 5 files changed, 69 insertions(+), 26 deletions(-) diff --git a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx b/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx index 474fcc4b0..7296ec923 100644 --- a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx @@ -1419,30 +1419,7 @@ std::vector MEDCouplingFieldDiscretizationGauss::splitIntoSingle { if(!_discr_per_cell) throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::splitIntoSingleGaussDicrPerCellType : no descretization set !"); - locIds.clear(); - std::set df=_discr_per_cell->getDifferentValues(); - df.erase(-1); - std::map m; - int nid=0; - std::vector > ret2(df.size()); locIds.resize(df.size()); - for(std::set::iterator it=df.begin();it!=df.end();it++,nid++) - { m[*it]=nid; locIds[nid]=*it; } - nid=0; - for(const int *discrPerCell=_discr_per_cell->begin();discrPerCell!=_discr_per_cell->end();discrPerCell++,nid++) - { - if(*discrPerCell!=-1) - ret2[m[*discrPerCell]].push_back(nid); - } - nid=0; - std::vector ret(df.size()); - for(std::set::iterator it=df.begin();it!=df.end();it++,nid++) - { - DataArrayInt *part=DataArrayInt::New(); - part->alloc(ret2[nid].size(),1); - std::copy(ret2[nid].begin(),ret2[nid].end(),part->getPointer()); - ret[nid]=part; - } - return ret; + return _discr_per_cell->partitionByDifferentValues(locIds); } MEDCouplingFieldDiscretizationGaussNE::MEDCouplingFieldDiscretizationGaussNE() diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index d765f7ab4..73c5d58d7 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -5796,13 +5796,50 @@ DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(IN } /*! - * This method returns all different values found in 'this'. + * This method returns all different values found in \a this. This method throws if \a this has not been allocated. + * But the number of components can be different from one. */ std::set DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception) { checkAllocated(); std::set ret; - ret.insert(getConstPointer(),getConstPointer()+getNbOfElems()); + ret.insert(begin(),end()); + return ret; +} + +/*! + * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of + * them it tells which tuple id have this id. + * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ). + * This method returns two arrays having same size. + * The instances of DataArrayInt in the returned vector have be specially allocated and computed by this method. Each of them should be dealt by the caller of this method. + * Example : if this is equal to [1,0,1,2,0,2,2,-3,2] -> differentIds=[-3,0,1,2] and returned array will be equal to [[7],[1,4],[0,2],[3,5,6,8]] + */ +std::vector DataArrayInt::partitionByDifferentValues(std::vector& differentIds) const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !"); + int id=0; + std::map m,m2,m3; + for(const int *w=begin();w!=end();w++) + m[*w]++; + differentIds.resize(m.size()); + std::vector ret(m.size()); + std::vector retPtr(m.size()); + for(std::map::const_iterator it=m.begin();it!=m.end();it++,id++) + { + m2[(*it).first]=id; + ret[id]=DataArrayInt::New(); + ret[id]->alloc((*it).second,1); + retPtr[id]=ret[id]->getPointer(); + differentIds[id]=(*it).first; + } + id=0; + for(const int *w=begin();w!=end();w++,id++) + { + retPtr[m2[*w]][m3[*w]++]=id; + } return ret; } diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index 8b009d047..a6c922fbb 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -468,6 +468,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayInt *findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT std::set getDifferentValues() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT std::vector partitionByDifferentValues(std::vector& differentIds) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo); MEDCOUPLING_EXPORT void writeOnPlace(int id, int element0, const int *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); } diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index 0d4461be3..6be7ec04e 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -10271,6 +10271,15 @@ class MEDCouplingBasicsTest(unittest.TestCase): self.assertTrue(e.isEqual(DataArrayInt([1,2,3,4,5,7,19]))) pass + def testDAIPartitionByDifferentValues1(self): + d=DataArrayInt([1,0,1,2,0,2,2,-3,2]) + expected=[[-3,[7]],[0,[1,4]],[1,[0,2]],[2,[3,5,6,8]]] + for i,elt in enumerate(zip(*d.partitionByDifferentValues())): + self.assertEqual(expected[i][0],elt[1]) + self.assertEqual(expected[i][1],elt[0].getValues()) + pass + pass + def setUp(self): pass pass diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index d7ab7e4a1..d9acfef63 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -847,10 +847,29 @@ namespace ParaMEDMEM std::set ret=self->getDifferentValues(); return convertIntArrToPyList3(ret); } + + PyObject *partitionByDifferentValues() const throw(INTERP_KERNEL::Exception) + { + std::vector ret1; + std::vector ret0=self->partitionByDifferentValues(ret1); + std::size_t sz=ret0.size(); + PyObject *pyRet=PyTuple_New(2); + PyObject *pyRet0=PyList_New((int)sz); + PyObject *pyRet1=PyList_New((int)sz); + for(std::size_t i=0;i