-// Copyright (C) 2007-2019 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
/*!
* This method performs systematically an allocation of \a newNbOfElements elements in \a this.
* \a _nb_of_elem and \a _nb_of_elem_alloc will \b NOT be systematically equal (contrary to MemArray<T>::reAlloc method.
- * So after the call of this method \a _nb_of_elem will be equal tostd::min<std::size_t>(_nb_of_elem,newNbOfElements) and \a _nb_of_elem_alloc equal to
+ * So after the call of this method \a _nb_of_elem will be equal tostd::min<std::size_t>(_nb_of_elem,newNbOfElements) and \a _nb_of_elem_alloc equal to
* \a newNbOfElements. This method is typically used to perform a pushBack to avoid systematic allocations-copy-deallocation.
* So after the call of this method the accessible content is perfectly set.
- *
+ *
* So this method should not be confused with MemArray<T>::reserve that is close to MemArray<T>::reAlloc but not same.
*/
template<class T>
* This method performs systematically an allocation of \a newNbOfElements elements in \a this.
* \a _nb_of_elem and \a _nb_of_elem_alloc will be equal even if only std::min<std::size_t>(_nb_of_elem,newNbOfElements) come from the .
* The remaining part of the new allocated chunk are available but not set previously !
- *
+ *
* So this method should not be confused with MemArray<T>::reserve that is close to MemArray<T>::reAlloc but not same.
*/
template<class T>
}
}
}
-
+
template<class T>
DataArrayIterator<T>::~DataArrayIterator()
{
DataArrayTuple<T>::DataArrayTuple(T *pt, std::size_t nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
{
}
-
+
template<class T>
T DataArrayTuple<T>::zeValue() const
{
return *_pt;
throw INTERP_KERNEL::Exception("DataArrayTuple<T>::zeValue : DataArrayTuple instance has not exactly 1 component -> Not possible to convert it into a single value !");
}
-
+
template<class T>
typename Traits<T>::ArrayType *DataArrayTuple<T>::buildDA(std::size_t nbOfTuples, std::size_t nbOfCompo) const
{
throw INTERP_KERNEL::Exception(oss.str().c_str());
}
}
-
+
//////////////////////////////////
/*!
std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
throw INTERP_KERNEL::Exception(oss.str().c_str());
}
- mcIdType nbElems=DataArrayTemplate<T>::GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
+ mcIdType nbElems=DataArrayTools<T>::GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
mcIdType minNbOfElemsPerSlice=nbElems/nbOfSlices;
startSlice=start+minNbOfElemsPerSlice*step*sliceId;
if(sliceId<nbOfSlices-1)
std::copy(v.begin(),v.end(),pt);
return ret;
}
-
+
+ /*!
+ * Returns a newly created array containing a copy of the input array defined by [ \a arrBegin, \a arrEnd )
+ */
+ template<class T>
+ MCAuto< typename Traits<T>::ArrayTypeCh > DataArrayTemplate<T>::NewFromArray(const T *arrBegin, const T *arrEnd)
+ {
+ using DataArrayT = typename Traits<T>::ArrayTypeCh;
+ MCAuto< DataArrayT > ret(DataArrayT::New());
+ std::size_t nbElts(std::distance(arrBegin,arrEnd));
+ ret->alloc(nbElts,1);
+ std::copy(arrBegin,arrEnd,ret->getPointer());
+ return ret;
+ }
+
template<class T>
std::vector< MCAuto< typename Traits<T>::ArrayTypeCh > > DataArrayTemplate<T>::explodeComponents() const
{
}
return ret;
}
-
+
template<class T>
std::size_t DataArrayTemplate<T>::getHeapMemorySizeWithoutChildren() const
{
sz*=sizeof(T);
return DataArray::getHeapMemorySizeWithoutChildren()+sz;
}
-
+
/*!
* Allocates the raw data in memory. If the memory was already allocated, then it is
* freed and re-allocated. See an example of this method use
/*!
* Sets a C array to be used as raw data of \a this. The previously set info
- * of components is retained and re-sized.
+ * of components is retained and re-sized.
* For more info see \ref MEDCouplingArraySteps1.
* \param [in] array - the C array to be used as raw data of \a this.
* \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
_mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
declareAsNew();
}
-
+
template<class T>
void DataArrayTemplate<T>::useExternalArrayWithRWAccess(const T *array, std::size_t nbOfTuple, std::size_t nbOfCompo)
{
{
return getConstPointer()!=0;
}
-
+
/*!
* Checks if raw data is allocated and throws an exception if it is not the case.
* \throw If the raw data is not allocated.
throw INTERP_KERNEL::Exception(oss.str().c_str());
}
}
-
+
/*!
* This method deallocated \a this without modification of information relative to the components.
* After call of this method, DataArrayDouble::isAllocated will return false.
}
/*!
- * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
+ * This method reserve nbOfElems elements in memory ( nbOfElems*sizeof(T) ) \b without impacting the number of tuples in \a this.
* If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown.
* If \a this has not already been allocated, number of components is set to one.
* This method allows to reduce number of reallocations on invocation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
- *
+ *
* \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
*/
template<class T>
throw INTERP_KERNEL::Exception(oss.str().c_str());
}
}
-
+
/*!
* This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation
* of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
throw INTERP_KERNEL::Exception(oss.str().c_str());
}
}
-
+
/*!
* This method adds at the end of \a this a series of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation
* of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
throw INTERP_KERNEL::Exception(oss.str().c_str());
}
}
-
+
/*!
* This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
* \throw If \a this is already empty.
throw INTERP_KERNEL::Exception(oss.str().c_str());
}
}
-
+
/*!
* Allocates the raw data in memory. If exactly same memory as needed already
* allocated, it is not re-allocated.
/*!
* Changes number of tuples in the array. If the new number of tuples is smaller
* than the current number the array is truncated, otherwise the array is extended.
- * \param [in] nbOfTuples - new number of tuples.
+ * \param [in] nbOfTuples - new number of tuples.
* \throw If \a this is not allocated.
* \throw If \a nbOfTuples is negative.
*/
* For more info on renumbering see \ref numbering.
* \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
* giving a previous position of i-th new value.
- * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
- * is to delete using decrRef() as it is no more needed.
*/
template<class T>
void DataArrayTemplate<T>::renumberInPlaceR(const mcIdType *new2Old)
}
/*!
- * Sorts values of the array.
+ * Sorts values of the array. \b Warning, this method is not const, it alterates \a this content.
+ *
* \param [in] asc - \a true means ascending order, \a false, descending.
* \throw If \a this is not allocated.
* \throw If \a this->getNumberOfComponents() != 1.
+ * \sa copySorted
*/
template<class T>
void DataArrayTemplate<T>::sort(bool asc)
declareAsNew();
}
+ /*!
+ * Sorts values of the array and put the result in a newly allocated returned array.
+ * This method does not alterate \a this content.
+ *
+ * \param [in] asc - \a true means ascending order, \a false, descending.
+ * \throw If \a this is not allocated.
+ * \throw If \a this->getNumberOfComponents() != 1.
+ * \sa sort
+ */
+ template<class T>
+ typename Traits<T>::ArrayTypeCh *DataArrayTemplate<T>::copySortedImpl(bool asc) const
+ {
+ MCAuto<typename Traits<T>::ArrayTypeCh> ret(static_cast<typename Traits<T>::ArrayTypeCh *>(this->deepCopy()));
+ ret->sort(asc);
+ return ret.retn();
+ }
+
/*!
* Returns a copy of \a this array with values permuted as required by \a old2New array.
* The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ].
* Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
* of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
* The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ] for all
- * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which
+ * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which
* \a old2New[ i ] is negative, is missing from the result array.
* For more info on renumbering see \ref numbering.
* \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
MCAuto<DataArrayIdType> arr(dpd->toDAI());
MCAuto<DataArray> ret2(selectByTupleIdSafe(arr->begin(),arr->end()));
return DynamicCastSafe<DataArray,typename Traits<T>::ArrayTypeCh>(ret2);
-
+
}
throw INTERP_KERNEL::Exception("DataArrayTemplate<T>::selectPartDef : unrecognized part def !");
}
-
+
/*!
* Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
* of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
* Changes the number of components within \a this array so that its raw data **does
* not** change, instead splitting this data into tuples changes.
* \warning This method erases all (name and unit) component info set before!
- * \param [in] newNbOfComp - number of components for \a this array to have.
+ * \param [in] newNbOfCompo - number of components for \a this array to have.
* \throw If \a this is not allocated
* \throw If getNbOfElems() % \a newNbOfCompo != 0.
* \throw If \a newNbOfCompo is lower than 1.
/*!
* Changes the number of components within \a this array to be equal to its number
- * of tuples, and inversely its number of tuples to become equal to its number of
+ * of tuples, and inversely its number of tuples to become equal to its number of
* components. So that its raw data **does not** change, instead splitting this
* data into tuples changes.
* \warning This method erases all (name and unit) component info set before!
* is truncated to have \a newNbOfComp components, keeping first components. If \a
* newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
* expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
- * components.
+ * components.
* \param [in] newNbOfComp - number of components for the new array to have.
* \param [in] dftValue - value assigned to new values added to the new array.
* \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
* \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
* is to delete using decrRef() as it is no more needed.
* \throw If \a this is not allocated.
- * \throw If a component index (\a i) is not valid:
+ * \throw If a component index (\a i) is not valid:
* \a i < 0 || \a i >= \a this->getNumberOfComponents().
*
* \if ENABLE_EXAMPLES
std::size_t newNbOfCompo=compoIds.size();
std::size_t oldNbOfCompo=getNumberOfComponents();
for(std::vector<std::size_t>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
- if((*it)<0 || (*it)>=oldNbOfCompo)
+ if((*it)>=oldNbOfCompo) // (*it) >= 0 (it is a size_t)
{
std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
throw INTERP_KERNEL::Exception(oss.str().c_str());
ret->copyStringInfoFrom(*this);
return ret.retn();
}
-
+
/*!
* Copy all values from another DataArrayDouble into specified tuples and components
* of \a this array. Textual data is not copied.
* \param [in] endComp - index of the component before which the components to assign
* to are located.
* \param [in] stepComp - index increment to get index of the next component to assign to.
- * \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents()
+ * \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents()
* must be equal to the number of columns to assign to, else an
* exception is thrown; if \a false, then it is only required that \a
* a->getNbOfElems() equals to number of values to assign to (this condition
- * must be respected even if \a strictCompoCompare is \a true). The number of
+ * must be respected even if \a strictCompoCompare is \a true). The number of
* values to assign to is given by following Python expression:
- * \a nbTargetValues =
+ * \a nbTargetValues =
* \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
* \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
* \throw If \a a is NULL.
}
}
}
-
+
/*!
* Assign a given value to values at specified tuples and components of \a this array.
* The tree parameters defining set of indices of tuples and components are similar to
for(mcIdType j=0;j<newNbOfComp;j++)
pt[j*stepComp]=a;
}
-
+
/*!
- * Copy all values from another DataArrayDouble (\a a) into specified tuples and
+ * Copy all values from another DataArrayDouble (\a a) into specified tuples and
* components of \a this array. Textual data is not copied.
* The tuples and components to assign to are defined by C arrays of indices.
* There are two *modes of usage*:
* - If \a a->getNbOfElems() equals to number of values to assign to, then every value
- * of \a a is assigned to its own location within \a this array.
+ * of \a a is assigned to its own location within \a this array.
* - If \a a includes one tuple, then all values of \a a are assigned to the specified
* components of every specified tuple of \a this array. In this mode it is required
* that \a a->getNumberOfComponents() equals to the number of specified components.
* \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
* assign values of \a a to.
* \param [in] endTuples - specifies the end of the array \a bgTuples, so that
- * pointer to a tuple index <em>(pi)</em> varies as this:
+ * pointer to a tuple index <em>(pi)</em> varies as this:
* \a bgTuples <= \a pi < \a endTuples.
* \param [in] bgComp - pointer to an array of component indices of \a this array to
* assign values of \a a to.
* \param [in] endComp - specifies the end of the array \a bgTuples, so that
- * pointer to a component index <em>(pi)</em> varies as this:
+ * pointer to a component index <em>(pi)</em> varies as this:
* \a bgComp <= \a pi < \a endComp.
* \param [in] strictCompoCompare - this parameter is checked only if the
- * *mode of usage* is the first; if it is \a true (default),
- * then \a a->getNumberOfComponents() must be equal
+ * *mode of usage* is the first; if it is \a true (default),
+ * then \a a->getNumberOfComponents() must be equal
* to the number of specified columns, else this is not required.
* \throw If \a a is NULL.
* \throw If \a a is not allocated.
T *pt(getPointer());
const T *srcPt(a->getConstPointer());
if(assignTech)
- {
+ {
for(const mcIdType *w=bgTuples;w!=endTuples;w++)
{
DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
for(const mcIdType *z=bgComp;z!=endComp;z++,srcPt++)
- {
+ {
pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
}
}
const T *srcPt2=srcPt;
DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
for(const mcIdType *z=bgComp;z!=endComp;z++,srcPt2++)
- {
+ {
pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
}
}
}
}
-
+
/*!
* Assign a given value to values at specified tuples and components of \a this array.
* The tuples and components to assign to are defined by C arrays of indices.
* \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
* assign \a a to.
* \param [in] endTuples - specifies the end of the array \a bgTuples, so that
- * pointer to a tuple index (\a pi) varies as this:
+ * pointer to a tuple index (\a pi) varies as this:
* \a bgTuples <= \a pi < \a endTuples.
* \param [in] bgComp - pointer to an array of component indices of \a this array to
* assign \a a to.
* \param [in] endComp - specifies the end of the array \a bgTuples, so that
- * pointer to a component index (\a pi) varies as this:
+ * pointer to a component index (\a pi) varies as this:
* \a bgComp <= \a pi < \a endComp.
* \throw If \a this is not allocated.
* \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
pt[(std::size_t)(*w)*nbComp+(*z)]=a;
}
}
-
+
/*!
- * Copy all values from another DataArrayDouble (\a a) into specified tuples and
+ * Copy all values from another DataArrayDouble (\a a) into specified tuples and
* components of \a this array. Textual data is not copied.
* The tuples to assign to are defined by a C array of indices.
* The components to assign to are defined by three values similar to parameters of
* the Python function \c range(\c start,\c stop,\c step).
* There are two *modes of usage*:
* - If \a a->getNbOfElems() equals to number of values to assign to, then every value
- * of \a a is assigned to its own location within \a this array.
+ * of \a a is assigned to its own location within \a this array.
* - If \a a includes one tuple, then all values of \a a are assigned to the specified
* components of every specified tuple of \a this array. In this mode it is required
* that \a a->getNumberOfComponents() equals to the number of specified components.
* \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
* assign values of \a a to.
* \param [in] endTuples - specifies the end of the array \a bgTuples, so that
- * pointer to a tuple index <em>(pi)</em> varies as this:
+ * pointer to a tuple index <em>(pi)</em> varies as this:
* \a bgTuples <= \a pi < \a endTuples.
* \param [in] bgComp - index of the first component of \a this array to assign to.
* \param [in] endComp - index of the component before which the components to assign
* to are located.
* \param [in] stepComp - index increment to get index of the next component to assign to.
* \param [in] strictCompoCompare - this parameter is checked only in the first
- * *mode of usage*; if \a strictCompoCompare is \a true (default),
- * then \a a->getNumberOfComponents() must be equal
+ * *mode of usage*; if \a strictCompoCompare is \a true (default),
+ * then \a a->getNumberOfComponents() must be equal
* to the number of specified columns, else this is not required.
* \throw If \a a is NULL.
* \throw If \a a is not allocated.
* \throw If \a this is not allocated.
- * \throw If any index of tuple given by \a bgTuples is out of a valid range for
+ * \throw If any index of tuple given by \a bgTuples is out of a valid range for
* \a this array.
* \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
* if <em> a->getNumberOfComponents()</em> is unequal to the number of components
}
}
}
-
+
/*!
* Assign a given value to values at specified tuples and components of \a this array.
* The tuples to assign to are defined by a C array of indices.
* \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
* assign \a a to.
* \param [in] endTuples - specifies the end of the array \a bgTuples, so that
- * pointer to a tuple index <em>(pi)</em> varies as this:
+ * pointer to a tuple index <em>(pi)</em> varies as this:
* \a bgTuples <= \a pi < \a endTuples.
* \param [in] bgComp - index of the first component of \a this array to assign to.
* \param [in] endComp - index of the component before which the components to assign
* to are located.
* \param [in] stepComp - index increment to get index of the next component to assign to.
* \throw If \a this is not allocated.
- * \throw If any index of tuple given by \a bgTuples is out of a valid range for
+ * \throw If any index of tuple given by \a bgTuples is out of a valid range for
* \a this array.
* \throw If parameters specifying components to assign to, do not give a
* non-empty range of increasing indices or indices are out of a valid range
* \param [in] bgComp - pointer to an array of component indices of \a this array to
* assign \a a to.
* \param [in] endComp - specifies the end of the array \a bgTuples, so that
- * pointer to a component index (\a pi) varies as this:
+ * pointer to a component index (\a pi) varies as this:
* \a bgComp <= \a pi < \a endComp.
- * \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents()
+ * \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents()
* must be equal to the number of columns to assign to, else an
* exception is thrown; if \a false, then it is only required that \a
* a->getNbOfElems() equals to number of values to assign to (this condition
- * must be respected even if \a strictCompoCompare is \a true). The number of
+ * must be respected even if \a strictCompoCompare is \a true). The number of
* values to assign to is given by following Python expression:
- * \a nbTargetValues =
+ * \a nbTargetValues =
* \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
* \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
* \throw If \a a is NULL.
for(const mcIdType *z=bgComp;z!=endComp;z++)
pt[*z]=a;
}
-
+
/*!
* Copy some tuples from another DataArrayDouble into specified tuples
* of \a this array. Textual data is not copied. Both arrays must have equal number of
* \throw If \a tuplesSelec is not allocated.
* \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
* \throw If \a tuplesSelec->getNumberOfComponents() != 2.
- * \throw If any tuple index given by \a tuplesSelec is out of a valid range for
+ * \throw If any tuple index given by \a tuplesSelec is out of a valid range for
* the corresponding (\a this or \a a) array.
*/
template<class T>
}
}
}
-
+
/*!
* Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
* of \a this array. Textual data is not copied. Both arrays must have equal number of
* \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
* \throw If \a tuplesSelec->getNumberOfComponents() != 1.
* \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
- * \throw If any tuple index given by \a tuplesSelec is out of a valid range for
+ * \throw If any tuple index given by \a tuplesSelec is out of a valid range for
* \a aBase array.
*/
template<class T>
}
}
}
-
+
/*!
* Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
* of \a this array. Textual data is not copied. Both arrays must have equal number of
}
/*!
- * Returns the first value of \a this.
+ * Returns the first value of \a this.
* \return double - the last value of \a this array.
* \throw If \a this is not allocated.
* \throw If \a this->getNumberOfComponents() != 1.
throw INTERP_KERNEL::Exception("DataArrayTemplate::front : number of tuples must be >= 1 !");
return *(getConstPointer());
}
-
+
/*!
- * Returns the last value of \a this.
+ * Returns the last value of \a this.
* \return double - the last value of \a this array.
* \throw If \a this is not allocated.
* \throw If \a this->getNumberOfComponents() != 1.
throw INTERP_KERNEL::Exception("DataArrayTemplate::back : number of tuples must be >= 1 !");
return *(getConstPointer()+nbOfTuples-1);
}
-
+
/*!
* Returns the maximal value and its location within \a this one-dimensional array.
* \param [out] tupleId - index of the tuple holding the maximal value.
tupleId=ToIdType(std::distance(vals,loc));
return *loc;
}
-
+
/*!
* Returns the maximal value within \a this array that is allowed to have more than
* one component.
const T *loc(std::max_element(begin(),end()));
return *loc;
}
-
+
/*!
* Returns the maximal absolute value in \a this and the first occurrence location associated to it.
* \return the element in this (positive or negative) having the max abs value in \a this.
tupleId=ToIdType(std::distance(vals,loc));
return *loc;
}
-
+
/*!
* Returns the minimal value within \a this array that is allowed to have more than
* one component.
const T *loc=std::min_element(begin(),end());
return *loc;
}
-
+
template<class T>
void DataArrayTemplate<T>::circularPermutation(mcIdType nbOfShift)
{
std::copy((T*)buf,(T *)buf+(nbTuples-effNbSh)*nbOfCompo,work);
}
}
-
+
template<class T>
void DataArrayTemplate<T>::circularPermutationPerTuple(mcIdType nbOfShift)
{
sts[i]=_info_on_compo[(i+effNbSh)%nbOfCompo];
setInfoOnComponents(sts);
}
-
+
template<class T>
void DataArrayTemplate<T>::reversePerTuple()
{
ret->copyStringInfoFrom(*this);
return ret;
}
-
+
/*!
* Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
* array to the new one.
return convertToOtherTypeOfArr<int>();
}
+ /*!
+ * Creates a new DataArrayInt64 and assigns all (textual and numerical) data of \a this
+ * array to the new one.
+ * \return DataArrayInt * - the new instance of DataArrayInt64.
+ */
+ template<class T>
+ MCAuto<DataArrayInt64> DataArrayTemplateClassic<T>::convertToInt64Arr() const
+ {
+ return convertToOtherTypeOfArr<Int64>();
+ }
/*!
* Creates a new DataArrayFloat and assigns all (textual and numerical) data of \a this
* array to the new one.
*ptr=a*(*ptr)+b;
this->declareAsNew();
}
-
+
/*!
* Returns a full copy of \a this array except that sign of all elements is reversed.
* \return DataArrayDouble * - the new instance of DataArrayDouble containing the
T *ptr(this->getPointer());
const T *ptrc(other->begin());
for(mcIdType i=0;i<nbOfTuple;i++)
- std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(FCT(),*ptrc++));
+ std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind(FCT(),std::placeholders::_1,*ptrc++));
}
else
throw INTERP_KERNEL::Exception(msg);
throw INTERP_KERNEL::Exception(msg);
this->declareAsNew();
}
-
+
/*!
* Adds values of another DataArrayDouble to values of \a this one. There are 3
* valid cases.
{
this->somethingEqual< std::minus<T> >(other);
}
-
+
/*!
* Multiply values of another DataArrayDouble to values of \a this one. There are 3
* valid cases.
{
this->somethingEqual< std::divides<T> >(other);
}
-
+
template<class T, class FCT>
typename Traits<T>::ArrayType *DivSub(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
{
const T *a2Ptr(a2->begin()),*a1Ptr(a1->begin());
T *res(ret->getPointer());
for(mcIdType i=0;i<nbOfTuple1;i++)
- res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(FCT(),a2Ptr[i]));
+ res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind(FCT(),std::placeholders::_1,a2Ptr[i]));
ret->copyStringInfoFrom(*a1);
return ret.retn();
}
return 0;
}
}
-
+
/*!
* Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
* valid cases.
{
return DivSub< T,std::minus<T> >(a1,a2);
}
-
+
/*!
* Returns a new DataArrayDouble that is a division of two given arrays. There are 3
* valid cases.
const T *aMaxPtr(aMax->begin());
T *res=ret->getPointer();
for(mcIdType i=0;i<nbOfTuple;i++)
- res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(FCT(),aMinPtr[i]));
+ res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind(FCT(),std::placeholders::_1,aMinPtr[i]));
ret->copyStringInfoFrom(*aMax);
}
else
throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array MulAdd !");
return ret.retn();
}
-
+
/*!
* Returns a new DataArrayDouble that is a product of two given arrays. There are 3
* valid cases.
{
return MulAdd< T , std::multiplies<T> >(a1,a2);
}
-
+
/*!
* Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
* valid cases.
{
return MulAdd< T , std::plus<T> >(a1,a2);
}
-
+
/*!
* Returns either a \a deep or \a shallow copy of this array. For more info see
* \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
bool operator()(T v) const { return v>=_v; }
T _v;
};
-
+
template<class T>
struct GreaterThan
{
bool operator()(T v) const { return v>_v; }
T _v;
};
-
+
template<class T>
struct LowerEqual
{
bool operator()(T v) const { return v<=_v; }
T _v;
};
-
+
template<class T>
struct LowerThan
{
bool operator()(T v) const { return v<_v; }
T _v;
};
-
+
template<class T>
struct InRange
{
MCAuto<DataArrayIdType> ret(findIdsAdv(lt));
return ret.retn();
}
-
+
template<class T>
MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsGreaterOrEqualTo(T val) const
{
GreatEqual<T> ge(val);
return findIdsAdv(ge);
}
-
+
template<class T>
MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsGreaterThan(T val) const
{
GreaterThan<T> gt(val);
return findIdsAdv(gt);
}
-
+
template<class T>
MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsLowerOrEqualTo(T val) const
{
LowerEqual<T> le(val);
return findIdsAdv(le);
}
-
+
template<class T>
MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsLowerThan(T val) const
{
ret->useArray(tab,true,DeallocType::C_DEALLOC,this->getNumberOfTuples(),this->getNumberOfComponents());
return ret.retn();
}
-
+
/*!
* Appends components of another array to components of \a this one, tuple by tuple.
- * So that the number of tuples of \a this array remains the same and the number of
+ * So that the number of tuples of \a this array remains the same and the number of
* components increases.
* \param [in] other - the DataArrayDouble to append to \a this one.
* \throw If \a this is not allocated.
}
/*!
- *
+ *
* \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
* \a nbTimes should be at least equal to 1.
* \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
ret->copyStringInfoFrom(*this);
return ret.retn();
}
-
+
template<class T>
void DataArrayTemplateClassic<T>::aggregate(const typename Traits<T>::ArrayType *other)
{
this->checkAllocated();
T *ptr(this->getPointer());
std::size_t nbOfElems(this->getNbOfElems());
- std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<T,T>(std::abs));
+ std::transform(ptr,ptr+nbOfElems,ptr,[](T c){return std::abs(c);});
this->declareAsNew();
}
mcIdType nbOfTuples(this->getNumberOfTuples());
std::size_t nbOfComp(this->getNumberOfComponents());
newArr->alloc(nbOfTuples,nbOfComp);
- std::transform(this->begin(),this->end(),newArr->getPointer(),std::ptr_fun<T,T>(std::abs));
+ std::transform(this->begin(),this->end(),newArr->getPointer(),[](T c){return std::abs(c);});
newArr->copyStringInfoFrom(*this);
return newArr.retn();
}
/*!
* Computes for each tuple the sum of number of components values in the tuple and return it.
- *
+ *
* \return DataArrayDouble * - the new instance of DataArrayDouble containing the
* same number of tuples as \a this array and one component.
* The caller is to delete this result array using decrRef() as it is no more
template<>
struct ImplReprTraits<double> { static void SetPrecision(std::ostream& oss) { oss.precision(17); } };
-
+
template<>
struct ImplReprTraits<float> { static void SetPrecision(std::ostream& oss) { oss.precision(7); } };
-
+
template<class T>
void DataArrayTemplateClassic<T>::reprStream(std::ostream& stream) const
{
reprNotTooLongStream(ret);
return ret.str();
}
-
+
/*!
* Returns a textual and human readable representation of \a this instance of
* DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
DataArrayTemplateClassic<T>::reprStream(ret);
return ret.str();
}
-
+
template<class T>
std::string DataArrayTemplateClassic<T>::reprZip() const
{
DataArrayTemplateClassic<T>::reprZipStream(ret);
return ret.str();
}
-
+
/////////////////////////////////
-
+
/*!
* Checks if all values in \a this array are equal to \a val at precision \a eps.
* \param [in] val - value to check equality of array values to.
/*!
* Equivalent to DataArrayInt::isEqual except that if false the reason of
* mismatch is given.
- *
+ *
* \param [in] other the instance to be compared with \a this
* \param [out] reason In case of inequality returns the reason.
* \sa DataArrayInt::isEqual
std::string tmp;
return isEqualIfNotWhy(other,tmp);
}
-
+
/*!
* Returns a new instance of DataArrayInt. The caller is to delete this array
* using decrRef() as it is no more needed.
{
return new typename Traits<T>::ArrayType;
}
-
+
/*!
* Checks if values of \a this and another DataArrayInt are equal. For more info see
* \ref MEDCouplingArrayBasicsCompare.
b->sort();
return a->isEqualWithoutConsideringStr(*b);
}
-
+
template<class T>
template<class ALG>
void DataArrayDiscrete<T>::switchOnTupleAlg(T val, std::vector<bool>& vec, ALG algo) const
if(algo(pt[i],val))
vec[i]=true;
}
-
+
/*!
* This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple equal to \a val
* put True to the corresponding entry in \a vec.
* This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple different from \a val
* put True to the corresponding entry in \a vec.
* \a vec is expected to be with the same size than the number of tuples of \a this.
- *
+ *
* \sa DataArrayInt::switchOnTupleEqualTo.
*/
template<class T>
switchOnTupleAlg(val,vec,std::not_equal_to<T>());
}
+ /*!
+ * Compute for each element in \a this the occurence rank of that element. This method is typically useful of one-component array having a same element
+ * appearing several times. If each element in \a this appears once an 1 component array containing only 0 will be returned.
+ *
+ * \b Example:
+ * - \a this : [5, 3, 2, 1, 4, 5, 2, 1, 0, 11, 5, 4]
+ * - \a return is : [0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 2, 1] because at pos #0 of \a this (ie value 5) is the first occurrence ->0. At pos #10 of \a this (ie value 5 also) is the third occurrence of 5 -> 2.
+ *
+ * \return DataArrayInt * - a new instance of DataArrayInt with same number of tuples than \a this. The caller is to delete this
+ * array using decrRef() as it is no more needed.
+ * \throw If either this not allocated or not with one component.
+ *
+ * \sa DataArrayInt::FindPermutationFromFirstToSecond
+ */
+ template<class T>
+ DataArrayIdType *DataArrayDiscrete<T>::occurenceRankInThis() const
+ {
+ constexpr char MSG0[] = "occurenceRankInThis :";
+ this->checkAllocated();
+ this->checkNbOfComps(1,MSG0);
+ MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
+ ret->alloc(this->getNumberOfTuples(),1);
+ mcIdType *retPtr(ret->getPointer());
+ std::map<T,mcIdType> m;
+ for(const T *pt = this->begin() ; pt != this->end() ; ++pt, ++retPtr )
+ {
+ auto it = m.find(*pt);
+ if( it == m.end() )
+ {
+ *retPtr = 0;
+ m[*pt] = 1;
+ }
+ else
+ {
+ *retPtr = (*it).second++;
+ }
+ }
+ return ret.retn();
+ }
+
/*!
* Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
* one-dimensional arrays that must be of the same length. The result array describes
- * correspondence between \a this and \a other arrays, so that
+ * correspondence between \a this and \a other arrays, so that
* <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
* not possible because some element in \a other is not in \a this, an exception is thrown.
* \param [in] other - an array to compute permutation to.
* \throw If \a other->getNumberOfComponents() != 1.
* \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
* \throw If \a other includes a value which is not in \a this array.
- *
+ *
* \if ENABLE_EXAMPLES
* \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
*
/*!
* Computes distribution of values of \a this one-dimensional array between given value
* ranges (casts). This method is typically useful for entity number splitting by types,
- * for example.
+ * for example.
* \warning The values contained in \a arrBg should be sorted ascendently. No
- * check of this is be done. If not, the result is not warranted.
+ * check of this is be done. If not, the result is not warranted.
* \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
* value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
* and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
std::set<T> castsDetected;
for(mcIdType i=0;i<nbOfTuples;i++)
{
- rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<T>(), work[i]));
+ rintstart res=std::find_if(bg,end2,std::bind(std::less_equal<T>(),std::placeholders::_1,work[i]));
std::size_t pos=std::distance(bg,res);
std::size_t pos2=nbOfCast-pos;
if(pos2<nbOfCast)
* from values of \a this array, which is supposed to contain a renumbering map in
* "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
* To know how to use the renumbering maps see \ref numbering.
- * \param [in] newNbOfElem - the number of tuples in the result array.
+ * \param [in] oldNbOfElem - the number of tuples in the result array.
* \return DataArrayInt * - the new instance of DataArrayInt.
* The caller is to delete this result array using decrRef() as it is no more
* needed.
* from values of \a this array, which is supposed to contain a renumbering map in
* "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
* To know how to use the renumbering maps see \ref numbering.
- * \param [in] newNbOfElem - the number of tuples in the result array.
* \return MapII - the new instance of Map.
*
* \if ENABLE_EXAMPLES
/*!
* Creates a map, whose contents are computed
- * from values of \a this array, which is supposed to contain a renumbering map in
+ * from values of \a this array, which is supposed to contain a renumbering map in
* "New to Old" mode. The result array contains a renumbering map in "New to Old" mode as C++ map for performance reasons.
*
* \sa invertArrayN2O2O2NOptimized, MEDCouplingPointSet::renumberNodesInConn
*
* \return - An array of size std::distance(valsBg,valsEnd)
*
- * \sa DataArrayInt::FindPermutationFromFirstToSecond
+ * \sa DataArrayInt::FindPermutationFromFirstToSecond , DataArrayInt::FindPermutationFromFirstToSecondDuplicate
*/
template <class T>
MCAuto<DataArrayIdType> DataArrayDiscrete<T>::findIdForEach(const T *valsBg, const T *valsEnd) const
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: <br>
+ * - \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] == <br>
+ */
+ template <class T>
+ DataArrayIdType *DataArrayDiscrete<T>::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);
+ std::size_t nbOfCompo( this->getNumberOfComponents() );
+ mcIdType thisNbTuples( this->getNumberOfTuples() );
+ mcIdType 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<DataArrayIdType> 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.
ret->pushBackSilent(i);
return ret.retn();
}
-
+
/*!
* Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
* This method is an extension of DataArrayInt::findIdsEqual method.
ret->pushBackSilent(i);
return ret.retn();
}
-
+
/*!
* Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
* equal to any of given values.
return ToIdType(std::distance(cptr,ret));
return -1;
}
-
+
/*!
* This method expects to be called when number of components of this is equal to one.
* This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
{
return this->findIdFirstEqualTuple(tupl)!=-1;
}
-
-
+
+
/*!
* Returns \a true if a given value is present within \a this one-dimensional array.
* \param [in] value - the value to find within \a this array.
{
return this->findIdFirstEqual(value)!=-1;
}
-
+
/*!
* This method expects to be called when number of components of this is equal to one.
* This method returns true if it exists a tuple so that the value is contained in \b vals.
for(mcIdType i=0;i<nbTuple;i++)
std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<T>());
}
-
+
template <class T>
T DataArrayDiscrete<T>::accumulate(std::size_t compId) const
{
const T *ptr=this->getConstPointer();
mcIdType nbTuple(this->getNumberOfTuples());
std::size_t nbComps(this->getNumberOfComponents());
- if(compId<0 || compId>=nbComps)
+ if(compId>=nbComps) // compId >= 0 (it is a size_t)
throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
T ret=0;
for(mcIdType i=0;i<nbTuple;i++)
this->checkAllocated();
T *ptr=this->getPointer();
std::size_t nbOfElems=this->getNbOfElems();
- std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<T>(),val));
+ std::transform(ptr,ptr+nbOfElems,ptr,std::bind(std::divides<T>(),std::placeholders::_1,val));
this->declareAsNew();
}
this->checkAllocated();
T *ptr=this->getPointer();
std::size_t nbOfElems=this->getNbOfElems();
- std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<T>(),val));
+ std::transform(ptr,ptr+nbOfElems,ptr,std::bind(std::modulus<T>(),std::placeholders::_1,val));
this->declareAsNew();
}
}
this->declareAsNew();
}
-
+
/*!
* Modify all elements of \a this array, so that
* an element _x_ becomes \f$ val ^ x \f$.
MCAuto<DataArrayIdType> ret(this->findIdsAdv(ir));
return ret.retn();
}
-
+
/*!
* This method works only on data array with one component.
* This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
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 format of groups by same consecutive value.
+ * \throw if \a this is not allocated or if \a this has not exactly one component.
+ * \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 !");
+ const T *pt(this->begin());
+ const T *const ptEnd(this->end()) , * const ptBg(this->begin());
+ // 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();
throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
std::size_t nbOfElements=this->getNumberOfTuples();
if(nbOfElements<2)
- throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
+ throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 2 tuples at least must be present in 'this' !");
const T *ptr=this->getConstPointer();
DataArrayType *ret=DataArrayType::New();
ret->alloc(nbOfElements-1,1);
*
* This method is useful for users having an unstructured mesh having only SEG2 to rearrange internally the connectivity without any coordinates consideration.
*
- * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
+ * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::sortToHaveConsecutivePairs(), DataArrayInt::fromLinkedListOfPairToList
*/
template <class T>
void DataArrayDiscrete<T>::sortEachPairToMakeALinkedList()
std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
throw INTERP_KERNEL::Exception(oss.str().c_str());
}
+ if(conn[2]!=conn[1] && conn[3]!=conn[1])
+ {
+ std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : There is no common noeud between the tuple #" << i << " and the tuple #" << i + 1 << ". Need call DataArrayInt::sortToHaveConsecutivePairs() ";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
std::swap(conn[2],conn[3]);
//not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
}
}
+ /*!
+ * This method is the improvement from the method sortEachPairToMakeALinkedList().
+ *
+ * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::sortEachPairToMakeALinkedList(), DataArrayInt::fromLinkedListOfPairToList
+ */
+ template <class T>
+ void DataArrayDiscrete<T>::sortToHaveConsecutivePairs()
+ {
+ this->checkAllocated();
+ if(this->getNumberOfComponents()!=2)
+ throw INTERP_KERNEL::Exception("DataArrayInt::sortToHaveConsecutivePairs : Only works on DataArrayInt instance with nb of components equal to 2 !");
+ mcIdType nbOfTuples(this->getNumberOfTuples());
+ T *thisPtr(this->getPointer());
+ mcIdType idOfLastTuple = 0;
+ std::pair<T*,T*> tmp;
+ if(thisPtr[0]==thisPtr[1])
+ {
+ THROW_IK_EXCEPTION("DataArrayInt::sortToHaveConsecutivePairs : In the first tuple presence of a pair filled with same ids !");
+ }
+ while(idOfLastTuple < nbOfTuples-1)
+ {
+ mcIdType i = idOfLastTuple+1;
+ tmp.first = &thisPtr[2*i];
+ tmp.second = &thisPtr[2*i+1];
+ if(std::get<0>(tmp)[0] == std::get<1>(tmp)[0])
+ {
+ THROW_IK_EXCEPTION("DataArrayInt::sortToHaveConsecutivePairs : In the tuple #" << i << " presence of a pair filled with same ids !");
+ }
+ while((this->getIJ(idOfLastTuple,1) != std::get<0>(tmp)[0] &&
+ this->getIJ(idOfLastTuple,1) != std::get<1>(tmp)[0]) &&
+ i < nbOfTuples-1)
+ {
+ std::swap(std::get<0>(tmp)[0],thisPtr[2*(i+1)]);
+ std::swap(std::get<1>(tmp)[0],thisPtr[2*(i+1)+1]);
+ i++;
+ }
+ if(i < nbOfTuples-1 ||
+ this->getIJ(idOfLastTuple,1) == std::get<0>(tmp)[0] ||
+ this->getIJ(idOfLastTuple,1) == std::get<1>(tmp)[0])
+ {
+ if(this->getIJ(idOfLastTuple,1) != std::get<0>(tmp)[0])
+ std::swap(std::get<0>(tmp)[0],std::get<1>(tmp)[0]);
+ idOfLastTuple++;
+ }
+ else
+ {
+ THROW_IK_EXCEPTION("DataArrayInt::sortToHaveConsecutivePairs : not found the tuple which have the common noeud = " << this->getIJ(idOfLastTuple,1));
+ }
+ }
+ }
+
/*!
* \a this is expected to be a correctly linked list of pairs.
*
T *ptr=this->getPointer();
const T *ptrc=other->getConstPointer();
for(mcIdType i=0;i<nbOfTuple;i++)
- std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<T>(),*ptrc++));
+ std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind(std::modulus<T>(),std::placeholders::_1,*ptrc++));
}
else
throw INTERP_KERNEL::Exception(msg);
const T *a1Ptr=a1->getConstPointer();
T *res=ret->getPointer();
for(mcIdType i=0;i<nbOfTuple1;i++)
- res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<T>(),a2Ptr[i]));
+ res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind(std::modulus<T>(),std::placeholders::_1,a2Ptr[i]));
ret->copyStringInfoFrom(*a1);
return ret.retn();
}
* array using decrRef() as it is no more needed.
* \throw If either ids1 or ids2 is null not allocated or not with one components.
*
- * \sa DataArrayInt::findIdForEach
+ * \sa DataArrayInt::findIdForEach, DataArrayInt::FindPermutationFromFirstToSecondDuplicate, DataArrayInt::rankOfElementInThis
*/
template<class T>
DataArrayIdType *DataArrayDiscrete<T>::FindPermutationFromFirstToSecond(const DataArrayType *ids1, const DataArrayType *ids2)
return p2.retn();
}
+ /*!
+ * This method tries to find the permutation to apply to the first input \a ids1 to obtain the same array (without considering strings information) the second
+ * input array \a ids2.
+ * \a ids1 and \a ids2 are expected to be both a list of ids (both with number of components equal to one) not sorted and with values that can be negative.
+ * This method will throw an exception is no such permutation array can be obtained. It is typically the case if there is some ids in \a ids1 not in \a ids2 or
+ * inversely.
+ * The difference with DataArrayInt::FindPermutationFromFirstToSecond is that this method supports multiple same values in \a ids1 and \a ids2 whereas
+ * DataArrayInt::FindPermutationFromFirstToSecond doesn't. It implies that this method my be slower than the DataArrayInt::FindPermutationFromFirstToSecond one.
+ *
+ * In case of success both assertion will be true (no throw) :
+ * \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
+ * \c ret->transformWithIndArr(ids2)->isEqual(ids1)
+ *
+ * \b Example:
+ * - \a ids1 : [5, 3, 2, 1, 4, 5, 2, 1, 0, 11, 5, 4]
+ * - \a ids2 : [0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 5, 11]
+ * - \a return is : [8, 5, 3, 1, 6, 9, 4, 2, 0, 11, 10, 7] because ids2[8]==ids1[0], ids2[5]==ids1[1], ids2[3]==ids1[2], ids2[1]==ids1[3]...
+ *
+ * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
+ * array using decrRef() as it is no more needed.
+ * \throw If either ids1 or ids2 is null not allocated or not with one components.
+ *
+ * \sa DataArrayInt::findIdForEach, DataArrayInt::FindPermutationFromFirstToSecond, DataArrayInt::occurenceRankInThis
+ */
+ template<class T>
+ DataArrayIdType *DataArrayDiscrete<T>::FindPermutationFromFirstToSecondDuplicate(const DataArrayType *ids1, const DataArrayType *ids2)
+ {
+ if(!ids1 || !ids2)
+ throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecondDuplicate : the two input arrays must be not null !");
+ constexpr char MSG0[] = "DataArrayInt::FindPermutationFromFirstToSecondDuplicate :";
+ ids1->checkAllocated(); ids2->checkAllocated();
+ ids1->checkNbOfComps(1,MSG0); ids2->checkNbOfComps(1,MSG0);
+ mcIdType nbTuples(ids1->getNumberOfTuples());
+ if(nbTuples != ids2->getNumberOfTuples())
+ {
+ std::ostringstream oss; oss << "DataArrayInt::FindPermutationFromFirstToSecondDuplicate : first array has " << ids1->getNumberOfTuples() << " tuples and the second one " << ids2->getNumberOfTuples() << " tuples ! No chance to find a permutation between the 2 arrays !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(nbTuples,1);
+ MCAuto<DataArrayIdType> oids2(ids2->occurenceRankInThis());
+ std::map< std::pair<T,mcIdType>, mcIdType> m;
+ mcIdType pos(0);
+ const mcIdType *oids2Ptr(oids2->begin());
+ for(const T * it2 = ids2->begin() ; it2 != ids2->end() ; ++it2, ++oids2Ptr, ++pos)
+ m[{*it2,*oids2Ptr}] = pos;
+ mcIdType *retPtr(ret->getPointer());
+ //
+ std::map<T,mcIdType> mOccurence1; // see DataArrayInt::occurenceRankInThis : avoid to compute additionnal temporary array
+ //
+ for(const T * it1 = ids1->begin() ; it1 != ids1->end() ; ++it1, ++retPtr)
+ {
+ auto it = mOccurence1.find(*it1);
+ mcIdType occRk1;
+ if( it == mOccurence1.end() )
+ {
+ occRk1 = 0;
+ mOccurence1[*it1] = 1;
+ }
+ else
+ {
+ occRk1 = (*it).second++;
+ }
+ //
+ auto it2 = m.find({*it1,occRk1});
+ if(it2 != m.end())
+ {
+ *retPtr = (*it2).second;
+ }
+ else
+ {
+ std::ostringstream oss; oss << MSG0 << "At pos " << std::distance(ids1->begin(),it1) << " value is " << *it1 << " and occurence rank is " << occRk1 << ". No such item into second array !";
+ throw INTERP_KERNEL::Exception(oss.str());
+ }
+
+ }
+ return ret.retn();
+ }
+
/*!
* Returns a C array which is a renumbering map in "Old to New" mode for the input array.
* This map, if applied to \a start array, would make it sorted. For example, if
ret->alloc(retSz,1);
T *pt=ret->getPointer(); *pt++=0;
for(typename std::vector<const DataArrayType *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
- pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<T>(),pt[-1]));
+ pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind(std::plus<T>(),std::placeholders::_1,pt[-1]));
ret->copyStringInfoFrom(*(arrs[0]));
return ret.retn();
}
throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
}
//
+ if(a.size()==1)
+ throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single not null element in array ! For safety reasons exception is raised !");
+ //
std::set<T> r;
for(typename std::vector<const DataArrayType *>::const_iterator it=a.begin();it!=a.end();it++)
{
*
* \param [in] idsOfSelectStart begin of set of ids of the input extraction (included)
* \param [in] idsOfSelectStop end of set of ids of the input extraction (excluded)
- * \param [in] idsOfSelectStep
+ * \param [in] idsOfSelectStep step of set of ids of the input extraction
* \param [in] arrIn arr origin array from which the extraction will be done.
* \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
* \param [out] arrOut the resulting array