-// Copyright (C) 2007-2020 CEA/DEN, EDF R&D
+// Copyright (C) 2007-2024 CEA, EDF
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
return const_cast<MEDCouplingSkyLineArray*>(this)->_values;
}
+MEDCouplingSkyLineArray *MEDCouplingSkyLineArray::deepCopy() const
+{
+ MCAuto<DataArrayIdType> indexCpy(this->_index->deepCopy());
+ MCAuto<DataArrayIdType> valuesCpy(this->_values->deepCopy());
+ MCAuto<MEDCouplingSkyLineArray> ret(MEDCouplingSkyLineArray::New(indexCpy,valuesCpy));
+ if(_super_index.isNotNull())
+ {
+ MCAuto<DataArrayIdType> superIndexCpy(this->_super_index->deepCopy());
+ ret->_super_index = superIndexCpy;
+ }
+ return ret.retn();
+}
+
void MEDCouplingSkyLineArray::checkSuperIndex(const std::string& func) const
{
if (!_super_index->getNbOfElems())
return oss.str();
}
+/*!
+ * Returns 2 SkyLineArrays with same number of packs than \a this.
+ * Each pack in \a this is split in 2 parts using \a threshold parameter as cut point.
+ * \a left part contains ids in \a this pack strictly lower than \a threshold
+ * \a right part contains ids in \a this pack greater or equal to \a threshold
+ */
+void MEDCouplingSkyLineArray::thresholdPerPack(mcIdType threshold, MCAuto<MEDCouplingSkyLineArray>& left, MCAuto<MEDCouplingSkyLineArray>& right) const
+{
+ mcIdType nbPacks(this->getNumberOf());
+ MCAuto<DataArrayIdType> lCount(DataArrayIdType::New()); lCount->alloc(nbPacks,1); lCount->fillWithZero();
+ mcIdType *lCountPtr(lCount->getPointerSilent());
+ const mcIdType *valuesPtr(this->_values->begin()),*indexPtr(this->_index->begin());
+ for(mcIdType i = 0 ; i < nbPacks ; ++i, ++lCountPtr)
+ {
+ *lCountPtr = ToIdType(std::count_if(valuesPtr+indexPtr[i],valuesPtr+indexPtr[i+1],[threshold](mcIdType elt) { return elt<threshold; }));
+ }
+ MCAuto<DataArrayIdType> sizeOfPacks(this->_index->deltaShiftIndex());
+ sizeOfPacks->substractEqual(lCount);
+ mcIdType leftNbOfVal(lCount->accumulate(std::size_t(0))),rightNbOfVal(sizeOfPacks->accumulate(std::size_t(0)));
+ lCount->computeOffsetsFull(); sizeOfPacks->computeOffsetsFull();
+ MCAuto<DataArrayIdType> leftValues(DataArrayIdType::New()); leftValues->alloc(leftNbOfVal,1);
+ MCAuto<DataArrayIdType> rightValues(DataArrayIdType::New()); rightValues->alloc(rightNbOfVal,1);
+ mcIdType *rvPtr(rightValues->getPointerSilent()),*lvPtr(leftValues->getPointerSilent());
+ for(mcIdType i = 0 ; i < nbPacks ; ++i)
+ {
+ std::for_each(valuesPtr+indexPtr[i],valuesPtr+indexPtr[i+1],[threshold,&rvPtr,&lvPtr](mcIdType elt) { if(elt<threshold) { *lvPtr++ = elt; } else { *rvPtr++ = elt; } });
+ }
+ left = MEDCouplingSkyLineArray::New(lCount,leftValues); right = MEDCouplingSkyLineArray::New(sizeOfPacks,rightValues);
+}
+
+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();
+}
+
+MEDCouplingSkyLineArray *MEDCouplingSkyLineArray::uniqueNotSortedByPack() const
+{
+ mcIdType nbPacks(this->getNumberOf());
+ MCAuto<DataArrayIdType> retIndex(DataArrayIdType::New()); retIndex->alloc(nbPacks+1,1);
+ const mcIdType *valuesPtr(this->_values->begin()),*indexPtr(this->_index->begin());
+ mcIdType *retIndexPtr(retIndex->getPointer()); *retIndexPtr = 0;
+ for(mcIdType i = 0 ; i < nbPacks ; ++i, ++retIndexPtr)
+ {
+ std::set<mcIdType> s(valuesPtr+indexPtr[i],valuesPtr+indexPtr[i+1]);
+ retIndexPtr[1] = retIndexPtr[0] + ToIdType(s.size());
+ }
+ MCAuto<DataArrayIdType> retValues(DataArrayIdType::New()); retValues->alloc(retIndex->back(),1);
+ mcIdType *retValuesPtr(retValues->getPointer());
+ for(mcIdType i = 0 ; i < nbPacks ; ++i)
+ {
+ std::set<mcIdType> s(valuesPtr+indexPtr[i],valuesPtr+indexPtr[i+1]);
+ retValuesPtr = std::copy(s.begin(),s.end(),retValuesPtr);
+ }
+ MCAuto<MEDCouplingSkyLineArray> ret(MEDCouplingSkyLineArray::New(retIndex,retValues));
+ return ret.retn();
+}
+/*!
+ * Take as input skylinearrays containing the same number of packs ( \a this->getNumberOf ).
+ * For each packs, this method aggregates corresponding pack in \a sks.
+ *
+ * \throw if either a lenght of not nullptr instances in \a sks is zero or if number of packs of not nullptr instances in \a sks is not the same.
+ * \return a newly allocated skyline array that is the aggregated packs of inputs
+ */
+MEDCouplingSkyLineArray *MEDCouplingSkyLineArray::AggregatePacks(const std::vector<const MEDCouplingSkyLineArray *>& sks)
+{
+ std::vector<const MEDCouplingSkyLineArray *>sksEff;
+ mcIdType nbOfPacks(std::numeric_limits<mcIdType>::max());
+ constexpr char MSG[]="MEDCouplingSkyLineArray::AggregatePacks : ";
+ for(auto sk : sks)
+ {
+ if(sk)
+ {
+ mcIdType curNbPacks(sk->getNumberOf());
+ if(sksEff.empty())
+ nbOfPacks = curNbPacks;
+ if(nbOfPacks != curNbPacks)
+ {
+ std::ostringstream oss; oss << MSG << "first not null input ska has " << nbOfPacks << " whereas there is presence of ska with " << curNbPacks << " !";
+ throw INTERP_KERNEL::Exception(oss.str());
+ }
+ sksEff.push_back(sk);
+ }
+ }
+ if(sksEff.empty())
+ {
+ std::ostringstream oss; oss << MSG << "input vector contains no not nullptr elements !";
+ throw INTERP_KERNEL::Exception(oss.str());
+ }
+ //
+ MCAuto<DataArrayIdType> index(DataArrayIdType::New()); index->alloc(nbOfPacks+1,1);
+ mcIdType *indexPtr(index->getPointer()); *indexPtr=0;
+ std::vector<const mcIdType *> indicesIn(SkyLineArrayIndexIterator(0,&sksEff),SkyLineArrayIndexIterator(sksEff.size(),&sksEff));
+ for( mcIdType packId = 0 ; packId < nbOfPacks ; ++packId, ++indexPtr )
+ {
+ mcIdType nbOfAggPacks(0);
+ std::for_each(indicesIn.begin(),indicesIn.end(),[packId,&nbOfAggPacks](const mcIdType *elt) { nbOfAggPacks+=elt[packId+1]-elt[packId]; });
+ indexPtr[1] = indexPtr[0] + nbOfAggPacks;
+ }
+ mcIdType nbOfTuplesOut(index->back());
+ MCAuto<DataArrayIdType> values(DataArrayIdType::New()); values->alloc(nbOfTuplesOut,1);
+ mcIdType *valuesPtr(values->getPointer());
+ // let's go to populate values array
+ std::vector<const mcIdType *> valuesIn(SkyLineArrayValuesIterator(0,&sksEff),SkyLineArrayValuesIterator(sksEff.size(),&sksEff));
+ for( mcIdType packId = 0 ; packId < nbOfPacks ; ++packId )
+ {
+ std::size_t pos(0);
+ std::for_each(valuesIn.begin(),valuesIn.end(),[packId,&indicesIn,&valuesPtr,&pos](const mcIdType *elt)
+ { valuesPtr=std::copy(elt+indicesIn[pos][packId],elt+indicesIn[pos][packId+1],valuesPtr); ++pos; }
+ );
+ }
+ //
+ MCAuto<MEDCouplingSkyLineArray> ret(MEDCouplingSkyLineArray::New(index,values));
+ return ret.retn();
+}
+
/**
* For a 2- or 3-level SkyLine array, return a copy of the absolute pack with given identifier.
*/
* \param[in] superPackIndices the list of super-packs that should be inspected
* \param[in] packBg the pack that the function is looking for in each of the provided super-pack
* \param[in] packEnd the pack that the function is looking for in each of the provided super-pack
- * \param[out] a vector of mcIdType, having the same size as superPackIndices and containing for each inspected super-pack
+ * \param[out] out a vector of mcIdType, having the same size as superPackIndices and containing for each inspected super-pack
* the index of the first matching pack, or -1 if none found.
*/
void MEDCouplingSkyLineArray::findPackIds(const std::vector<mcIdType> & superPackIndices,