From e047259d4379db94f72d88eb21596f08f4ca6613 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Wed, 21 Dec 2022 17:23:47 +0100 Subject: [PATCH] Implementation of new DataArrayInt.locateComponentId method --- src/MEDCoupling/MEDCouplingMemArray.hxx | 1 + src/MEDCoupling/MEDCouplingMemArray.txx | 49 +++++++++++++++++++ src/MEDCoupling_Swig/DataArrayInt.i | 5 ++ .../MEDCouplingBasicsTest7.py | 8 +++ src/MEDCoupling_Swig/MEDCouplingMemArray.i | 2 + 5 files changed, 65 insertions(+) diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index ea18707e3..d70be4d27 100755 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -603,6 +603,7 @@ namespace MEDCoupling T checkUniformAndGuess() const; bool hasUniqueValues() const; void setSelectedComponents(const DataArrayType *a, const std::vector& compoIds); + DataArrayIdType *locateComponentId(const DataArrayType *valToSearchIntoTuples, const DataArrayIdType *tupleIdHint) const; DataArrayIdType *findIdsNotEqual(T val) const; DataArrayIdType *findIdsEqualTuple(const T *tupleBg, const T *tupleEnd) const; DataArrayIdType *findIdsEqualList(const T *valsBg, const T *valsEnd) const; diff --git a/src/MEDCoupling/MEDCouplingMemArray.txx b/src/MEDCoupling/MEDCouplingMemArray.txx index 16a07683f..01863c854 100755 --- a/src/MEDCoupling/MEDCouplingMemArray.txx +++ b/src/MEDCoupling/MEDCouplingMemArray.txx @@ -4920,6 +4920,55 @@ struct NotInRange nc[nbOfCompo*i+compoIds[j]]=*ac; } + /*! + * This method searches each value in \a valToSearchIntoTuples among values in \a this given the corresponding tuple to find into. + * If the value at the corresponding tuple is not found in the tuple an exception will be thrown. + * If the value is found the corresponding component id is returned. + * + * \param [in] valToSearchIntoTuples - a one component array containing the values to find in \a this + * \param [in] tupleIdHint - a one component array having same size than \a valToSearchIntoTuples giving for each value the tuple to find into + * \return DataArrayInt * - A newly allocated array having same size than \a valToSearchIntoTuples with one component + * + * \b Example:
+ * - \a this: [(0, 1, 2), (3, 4, 5), (6, 2, 3), (7, 8, 9), (9, 0, 10), (11, 12, 13), (14, 5, 11), (15, 16, 17)] + * - \a valToSearchIntoTuples: [1, 4, 6, 8, 10, 12, 14, 16, 17] + * - \a tupleIdHint: [0, 1, 2, 3, 4, 5, 6, 7, 7] + * - result array: [1, 1, 0, 1, 2, 1, 0, 1, 2] ==
+ */ + template + DataArrayIdType *DataArrayDiscrete::locateComponentId(const DataArrayType *valToSearchIntoTuples, const DataArrayIdType *tupleIdHint) const + { + if(!valToSearchIntoTuples || !tupleIdHint) + THROW_IK_EXCEPTION("DataArrayInt::locateComponentId : valToSearchIntoTuples and tupleIdHint must be not nullptr !"); + valToSearchIntoTuples->checkAllocated(); tupleIdHint->checkAllocated(); + this->checkAllocated(); + constexpr char MSG1[] = "DataArrayInt::locateComponentId : single component array expected"; + valToSearchIntoTuples->checkNbOfComps(1,MSG1); tupleIdHint->checkNbOfComps(1,MSG1); + auto nbOfCompo( this->getNumberOfComponents() ),thisNbTuples( this->getNumberOfTuples() ); + auto nbOfTuples( valToSearchIntoTuples->getNumberOfTuples() ); + tupleIdHint->checkNbOfTuples(nbOfTuples,"Number of tuples of input arrays must be the same."); + const T *cPtr(this->begin()),*valSearchPt(valToSearchIntoTuples->begin()); + const mcIdType *tHintPtr(tupleIdHint->begin()); + MCAuto ret = DataArrayIdType::New(); + ret->alloc(nbOfTuples,1); + mcIdType *retPtr(ret->getPointer()); + for(auto i = 0 ; i < nbOfTuples ; ++i) + { + if( tHintPtr[i] >=0 && tHintPtr[i] < thisNbTuples ) + { + auto strtSearch(cPtr+nbOfCompo*tHintPtr[i]),endSearch(cPtr+nbOfCompo*(tHintPtr[i]+1)); + auto pos = std::find(strtSearch,endSearch,valSearchPt[i]); + if(pos != endSearch) + *retPtr++ = ToIdType( std::distance(strtSearch,pos) ); + else + THROW_IK_EXCEPTION("At pos " << i << " value " << valSearchPt[i] << " is not present at tuple " << tHintPtr[i]); + } + else + THROW_IK_EXCEPTION("At pos " << i << " hint tuple is " << tHintPtr[i] << " not in [0," << thisNbTuples << ")"); + } + return ret.retn(); + } + /*! * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not * equal to a given one. diff --git a/src/MEDCoupling_Swig/DataArrayInt.i b/src/MEDCoupling_Swig/DataArrayInt.i index dbfaf63ae..ea8996cb9 100644 --- a/src/MEDCoupling_Swig/DataArrayInt.i +++ b/src/MEDCoupling_Swig/DataArrayInt.i @@ -2019,6 +2019,11 @@ return pyRet; } + DataArrayIdType *locateComponentId(const ARRAY *valToSearchIntoTuples, const DataArrayIdType *tupleIdHint) const + { + return self->locateComponentId(valToSearchIntoTuples,tupleIdHint); + } + PyObject *findIdsRangesInListOfIds(const ARRAY *listOfIds) const { DataArrayIdType *ret0=0; diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest7.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest7.py index a9a0c6006..ecdc04954 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest7.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest7.py @@ -1132,6 +1132,14 @@ class MEDCouplingBasicsTest7(unittest.TestCase): expected2 = DataArrayDouble([sqrt(2)/2.0, sqrt(2)/2.0]) self.assertTrue( res2.minPerTuple().isEqual(expected2,1e-12) ) + def testDAILocateComponentId0(self): + arr = DataArrayInt( [(0, 1, 2), (3, 4, 5), (6, 2, 3), (7, 8, 9), (9, 0, 10), (11, 12, 13), (14, 5, 11), (15, 16, 17)] ) + valToSearchIntoTuples = DataArrayInt( [1, 4, 6, 8, 10, 12, 14, 16, 17] ) + tupleIdHint = DataArrayInt( [0, 1, 2, 3, 4, 5, 6, 7, 7] ) + ret = arr.locateComponentId( valToSearchIntoTuples, tupleIdHint ) + self.assertTrue( ret.isEqual(DataArrayInt([1, 1, 0, 1, 2, 1, 0, 1, 2]) ) ) + pass + pass if __name__ == '__main__': diff --git a/src/MEDCoupling_Swig/MEDCouplingMemArray.i b/src/MEDCoupling_Swig/MEDCouplingMemArray.i index f9ba14216..0d2a5358f 100644 --- a/src/MEDCoupling_Swig/MEDCouplingMemArray.i +++ b/src/MEDCoupling_Swig/MEDCouplingMemArray.i @@ -142,6 +142,7 @@ %newobject MEDCoupling::DataArrayInt32::occurenceRankInThis; %newobject MEDCoupling::DataArrayInt32::buildPermutationArr; %newobject MEDCoupling::DataArrayInt32::buildPermArrPerLevel; +%newobject MEDCoupling::DataArrayInt32::locateComponentId; %newobject MEDCoupling::DataArrayInt32::getDifferentValues; %newobject MEDCoupling::DataArrayInt32::FindPermutationFromFirstToSecond; %newobject MEDCoupling::DataArrayInt32::FindPermutationFromFirstToSecondDuplicate; @@ -218,6 +219,7 @@ %newobject MEDCoupling::DataArrayInt64::occurenceRankInThis; %newobject MEDCoupling::DataArrayInt64::buildPermutationArr; %newobject MEDCoupling::DataArrayInt64::buildPermArrPerLevel; +%newobject MEDCoupling::DataArrayInt64::locateComponentId; %newobject MEDCoupling::DataArrayInt64::getDifferentValues; %newobject MEDCoupling::DataArrayInt64::FindPermutationFromFirstToSecond; %newobject MEDCoupling::DataArrayInt64::FindPermutationFromFirstToSecondDuplicate; -- 2.39.2