1 // Copyright (C) 2007-2022 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (EDF R&D)
21 #ifndef __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__
22 #define __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__
24 #include "MEDCouplingMemArray.hxx"
25 #include "NormalizedUnstructuredMesh.hxx"
26 #include "InterpKernelException.hxx"
27 #include "InterpolationUtils.hxx"
28 #include "MEDCouplingPartDefinition.hxx"
29 #include "InterpKernelAutoPtr.hxx"
31 #include "MEDCouplingMap.txx"
41 void MEDCouplingPointer<T>::setInternal(T *pointer)
48 void MEDCouplingPointer<T>::setExternal(const T *pointer)
55 MemArray<T>::MemArray(const MemArray<T>& other):_nb_of_elem(0),_nb_of_elem_alloc(0),_ownership(false),_dealloc(0),_param_for_deallocator(0)
57 if(!other._pointer.isNull())
59 _nb_of_elem_alloc=other._nb_of_elem;
60 T *pointer=(T*)malloc(_nb_of_elem_alloc*sizeof(T));
61 std::copy(other._pointer.getConstPointer(),other._pointer.getConstPointer()+other._nb_of_elem,pointer);
62 useArray(pointer,true,DeallocType::C_DEALLOC,other._nb_of_elem);
67 void MemArray<T>::useArray(const T *array, bool ownership, DeallocType type, std::size_t nbOfElem)
71 _nb_of_elem_alloc=nbOfElem;
73 _pointer.setInternal(const_cast<T *>(array));
75 _pointer.setExternal(array);
77 _dealloc=BuildFromType(type);
81 void MemArray<T>::useExternalArrayWithRWAccess(const T *array, std::size_t nbOfElem)
85 _nb_of_elem_alloc=nbOfElem;
86 _pointer.setInternal(const_cast<T *>(array));
88 _dealloc=CPPDeallocator;
92 void MemArray<T>::writeOnPlace(std::size_t id, T element0, const T *others, std::size_t sizeOfOthers)
94 if(id+sizeOfOthers>=_nb_of_elem_alloc)
95 reserve(2*_nb_of_elem+sizeOfOthers+1);
96 T *pointer=_pointer.getPointer();
98 std::copy(others,others+sizeOfOthers,pointer+id+1);
99 _nb_of_elem=std::max<std::size_t>(_nb_of_elem,id+sizeOfOthers+1);
103 void MemArray<T>::pushBack(T elem)
105 if(_nb_of_elem>=_nb_of_elem_alloc)
106 reserve(_nb_of_elem_alloc>0?2*_nb_of_elem_alloc:1);
108 pt[_nb_of_elem++]=elem;
112 T MemArray<T>::popBack()
116 const T *pt=getConstPointer();
117 return pt[--_nb_of_elem];
119 throw INTERP_KERNEL::Exception("MemArray::popBack : nothing to pop in array !");
123 void MemArray<T>::pack() const
125 (const_cast<MemArray<T> * >(this))->reserve(_nb_of_elem);
129 bool MemArray<T>::isEqual(const MemArray<T>& other, T prec, std::string& reason) const
131 std::ostringstream oss; oss.precision(15);
132 if(_nb_of_elem!=other._nb_of_elem)
134 oss << "Number of elements in coarse data of DataArray mismatch : this=" << _nb_of_elem << " other=" << other._nb_of_elem;
138 const T *pt1=_pointer.getConstPointer();
139 const T *pt2=other._pointer.getConstPointer();
144 oss << "coarse data pointer is defined for only one DataArray instance !";
150 for(std::size_t i=0;i<_nb_of_elem;i++)
151 if(pt1[i]-pt2[i]<-prec || (pt1[i]-pt2[i])>prec)
153 oss << "The content of data differs at pos #" << i << " of coarse data ! this[i]=" << pt1[i] << " other[i]=" << pt2[i];
161 * \param [in] sl is typically the number of components
162 * \return True if a not null pointer is present, False if not.
165 bool MemArray<T>::reprHeader(mcIdType sl, std::ostream& stream) const
167 stream << "Number of tuples : ";
168 if(!_pointer.isNull())
171 stream << _nb_of_elem/sl << std::endl << "Internal memory facts : " << _nb_of_elem << "/" << _nb_of_elem_alloc;
173 stream << "Empty Data";
178 stream << "Data content :\n";
179 bool ret=!_pointer.isNull();
181 stream << "No data !\n";
186 * \param [in] sl is typically the number of components
189 void MemArray<T>::repr(mcIdType sl, std::ostream& stream) const
191 if(reprHeader(sl,stream))
193 const T *data=getConstPointer();
194 if(_nb_of_elem!=0 && sl!=0)
196 std::size_t nbOfTuples=_nb_of_elem/std::abs(sl);
197 for(std::size_t i=0;i<nbOfTuples;i++)
199 stream << "Tuple #" << i << " : ";
200 std::copy(data,data+sl,std::ostream_iterator<T>(stream," "));
206 stream << "Empty Data\n";
211 * \param [in] sl is typically the number of components
214 void MemArray<T>::reprZip(mcIdType sl, std::ostream& stream) const
216 stream << "Number of tuples : ";
217 if(!_pointer.isNull())
220 stream << _nb_of_elem/sl;
222 stream << "Empty Data";
227 stream << "Data content : ";
228 const T *data=getConstPointer();
229 if(!_pointer.isNull())
231 if(_nb_of_elem!=0 && sl!=0)
233 std::size_t nbOfTuples=_nb_of_elem/std::abs(sl);
234 for(std::size_t i=0;i<nbOfTuples;i++)
237 std::copy(data,data+sl,std::ostream_iterator<T>(stream," "));
244 stream << "Empty Data\n";
247 stream << "No data !\n";
251 * \param [in] sl is typically the number of components
254 void MemArray<T>::reprNotTooLong(mcIdType sl, std::ostream& stream) const
256 if(reprHeader(sl,stream))
258 const T *data=getConstPointer();
259 if(_nb_of_elem!=0 && sl!=0)
261 std::size_t nbOfTuples=_nb_of_elem/std::abs(sl);
264 for(std::size_t i=0;i<nbOfTuples;i++)
266 stream << "Tuple #" << i << " : ";
267 std::copy(data,data+sl,std::ostream_iterator<T>(stream," "));
273 {// too much tuples -> print the 3 first tuples and 3 last.
274 stream << "Tuple #0 : ";
275 std::copy(data,data+sl,std::ostream_iterator<T>(stream," ")); stream << "\n";
276 stream << "Tuple #1 : ";
277 std::copy(data+sl,data+2*sl,std::ostream_iterator<T>(stream," ")); stream << "\n";
278 stream << "Tuple #2 : ";
279 std::copy(data+2*sl,data+3*sl,std::ostream_iterator<T>(stream," ")); stream << "\n";
281 stream << "Tuple #" << nbOfTuples-3 << " : ";
282 std::copy(data+(nbOfTuples-3)*sl,data+(nbOfTuples-2)*sl,std::ostream_iterator<T>(stream," ")); stream << "\n";
283 stream << "Tuple #" << nbOfTuples-2 << " : ";
284 std::copy(data+(nbOfTuples-2)*sl,data+(nbOfTuples-1)*sl,std::ostream_iterator<T>(stream," ")); stream << "\n";
285 stream << "Tuple #" << nbOfTuples-1 << " : ";
286 std::copy(data+(nbOfTuples-1)*sl,data+nbOfTuples*sl,std::ostream_iterator<T>(stream," ")); stream << "\n";
290 stream << "Empty Data\n";
295 void MemArray<T>::fillWithValue(const T& val)
297 T *pt=_pointer.getPointer();
298 std::fill(pt,pt+_nb_of_elem,val);
302 T *MemArray<T>::fromNoInterlace(std::size_t nbOfComp) const
305 throw INTERP_KERNEL::Exception("MemArray<T>::fromNoInterlace : number of components must be > 0 !");
306 const T *pt=_pointer.getConstPointer();
307 std::size_t nbOfTuples=_nb_of_elem/nbOfComp;
308 T *ret=(T*)malloc(_nb_of_elem*sizeof(T));
310 for(std::size_t i=0;i<nbOfTuples;i++)
311 for(std::size_t j=0;j<nbOfComp;j++,w++)
312 *w=pt[j*nbOfTuples+i];
317 T *MemArray<T>::toNoInterlace(std::size_t nbOfComp) const
320 throw INTERP_KERNEL::Exception("MemArray<T>::toNoInterlace : number of components must be > 0 !");
321 const T *pt=_pointer.getConstPointer();
322 std::size_t nbOfTuples=_nb_of_elem/nbOfComp;
323 T *ret=(T*)malloc(_nb_of_elem*sizeof(T));
325 for(std::size_t i=0;i<nbOfComp;i++)
326 for(std::size_t j=0;j<nbOfTuples;j++,w++)
332 void MemArray<T>::sort(bool asc)
334 T *pt=_pointer.getPointer();
336 std::sort(pt,pt+_nb_of_elem);
339 typename std::reverse_iterator<T *> it1(pt+_nb_of_elem);
340 typename std::reverse_iterator<T *> it2(pt);
346 void MemArray<T>::reverse(std::size_t nbOfComp)
349 throw INTERP_KERNEL::Exception("MemArray<T>::reverse : only supported with 'this' array with ONE or more than ONE component !");
350 T *pt=_pointer.getPointer();
353 std::reverse(pt,pt+_nb_of_elem);
358 T *pt2=pt+_nb_of_elem-nbOfComp;
359 std::size_t nbOfTuples=_nb_of_elem/nbOfComp;
360 for(std::size_t i=0;i<nbOfTuples/2;i++,pt+=nbOfComp,pt2-=nbOfComp)
362 for(std::size_t j=0;j<nbOfComp;j++)
363 std::swap(pt[j],pt2[j]);
369 void MemArray<T>::alloc(std::size_t nbOfElements)
372 _nb_of_elem=nbOfElements;
373 _nb_of_elem_alloc=nbOfElements;
374 _pointer.setInternal((T*)malloc(_nb_of_elem_alloc*sizeof(T)));
376 _dealloc=CDeallocator;
380 * This method performs systematically an allocation of \a newNbOfElements elements in \a this.
381 * \a _nb_of_elem and \a _nb_of_elem_alloc will \b NOT be systematically equal (contrary to MemArray<T>::reAlloc method.
382 * 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
383 * \a newNbOfElements. This method is typically used to perform a pushBack to avoid systematic allocations-copy-deallocation.
384 * So after the call of this method the accessible content is perfectly set.
386 * So this method should not be confused with MemArray<T>::reserve that is close to MemArray<T>::reAlloc but not same.
389 void MemArray<T>::reserve(std::size_t newNbOfElements)
391 if(_nb_of_elem_alloc==newNbOfElements)
393 T *pointer=(T*)malloc(newNbOfElements*sizeof(T));
394 std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min<std::size_t>(_nb_of_elem,newNbOfElements),pointer);
396 DestroyPointer(const_cast<T *>(_pointer.getConstPointer()),_dealloc,_param_for_deallocator);//Do not use getPointer because in case of _external
397 _pointer.setInternal(pointer);
398 _nb_of_elem=std::min<std::size_t>(_nb_of_elem,newNbOfElements);
399 _nb_of_elem_alloc=newNbOfElements;
401 _dealloc=CDeallocator;
402 _param_for_deallocator=0;
406 * This method performs systematically an allocation of \a newNbOfElements elements in \a this.
407 * \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 .
408 * The remaining part of the new allocated chunk are available but not set previously !
410 * So this method should not be confused with MemArray<T>::reserve that is close to MemArray<T>::reAlloc but not same.
413 void MemArray<T>::reAlloc(std::size_t newNbOfElements)
415 if(_nb_of_elem==newNbOfElements)
417 T *pointer=(T*)malloc(newNbOfElements*sizeof(T));
418 std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min<std::size_t>(_nb_of_elem,newNbOfElements),pointer);
420 DestroyPointer(const_cast<T *>(_pointer.getConstPointer()),_dealloc,_param_for_deallocator);//Do not use getPointer because in case of _external
421 _pointer.setInternal(pointer);
422 _nb_of_elem=newNbOfElements;
423 _nb_of_elem_alloc=newNbOfElements;
425 _dealloc=CDeallocator;
426 _param_for_deallocator=0;
430 void MemArray<T>::CPPDeallocator(void *pt, void *param)
432 delete [] reinterpret_cast<T*>(pt);
436 void MemArray<T>::CDeallocator(void *pt, void *param)
442 void MemArray<T>::COffsetDeallocator(void *pt, void *param)
444 int64_t *offset(reinterpret_cast<int64_t *>(param));
445 char *ptcast(reinterpret_cast<char *>(pt));
446 free(ptcast+*offset);
450 typename MemArray<T>::Deallocator MemArray<T>::BuildFromType(DeallocType type)
454 case DeallocType::CPP_DEALLOC:
455 return CPPDeallocator;
456 case DeallocType::C_DEALLOC:
458 case DeallocType::C_DEALLOC_WITH_OFFSET:
459 return COffsetDeallocator;
461 throw INTERP_KERNEL::Exception("Invalid deallocation requested ! Unrecognized enum DeallocType !");
466 void MemArray<T>::DestroyPointer(T *pt, typename MemArray<T>::Deallocator dealloc, void *param)
473 void MemArray<T>::destroy()
476 DestroyPointer(const_cast<T *>(_pointer.getConstPointer()),_dealloc,_param_for_deallocator);//Do not use getPointer because in case of _external
480 _param_for_deallocator=NULL;
486 MemArray<T> &MemArray<T>::operator=(const MemArray<T>& other)
488 alloc(other._nb_of_elem);
489 std::copy(other._pointer.getConstPointer(),other._pointer.getConstPointer()+_nb_of_elem,_pointer.getPointer());
493 //////////////////////////////////
496 DataArrayIterator<T>::DataArrayIterator(typename Traits<T>::ArrayType *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
501 if(_da->isAllocated())
503 _nb_comp=da->getNumberOfComponents();
504 _nb_tuple=da->getNumberOfTuples();
505 _pt=da->getPointer();
511 DataArrayIterator<T>::~DataArrayIterator()
518 typename Traits<T>::ArrayTuple *DataArrayIterator<T>::nextt()
520 if(_tuple_id<_nb_tuple)
523 typename Traits<T>::ArrayTuple *ret=new typename Traits<T>::ArrayTuple(_pt,_nb_comp);
531 //////////////////////////////////
534 DataArrayTuple<T>::DataArrayTuple(T *pt, std::size_t nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
539 T DataArrayTuple<T>::zeValue() const
543 throw INTERP_KERNEL::Exception("DataArrayTuple<T>::zeValue : DataArrayTuple instance has not exactly 1 component -> Not possible to convert it into a single value !");
547 typename Traits<T>::ArrayType *DataArrayTuple<T>::buildDA(std::size_t nbOfTuples, std::size_t nbOfCompo) const
549 if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
551 typename Traits<T>::ArrayType *ret=Traits<T>::ArrayType::New();
552 ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
557 std::ostringstream oss; oss << "DataArrayTuple<T>::buildDA : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
558 oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
559 throw INTERP_KERNEL::Exception(oss.str().c_str());
563 //////////////////////////////////
566 * This method is useful to slice work among a pool of threads or processes. \a begin, \a end \a step is the input whole slice of work to perform,
567 * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
569 * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
571 * \param [in] start - the start of the input slice of the whole work to perform split into slices.
572 * \param [in] stop - the stop of the input slice of the whole work to perform split into slices.
573 * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform split into slices.
574 * \param [in] sliceId - the slice id considered
575 * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
576 * \param [out] startSlice - the start of the slice considered
577 * \param [out] stopSlice - the stop of the slice consided
579 * \throw If \a step == 0
580 * \throw If \a nbOfSlices not > 0
581 * \throw If \a sliceId not in [0,nbOfSlices)
584 void DataArrayTools<T>::GetSlice(T start, T stop, T step, mcIdType sliceId, mcIdType nbOfSlices, T& startSlice, T& stopSlice)
588 std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
589 throw INTERP_KERNEL::Exception(oss.str().c_str());
591 if(sliceId<0 || sliceId>=nbOfSlices)
593 std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
594 throw INTERP_KERNEL::Exception(oss.str().c_str());
596 mcIdType nbElems=DataArrayTools<T>::GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
597 mcIdType minNbOfElemsPerSlice=nbElems/nbOfSlices;
598 startSlice=start+minNbOfElemsPerSlice*step*sliceId;
599 if(sliceId<nbOfSlices-1)
600 stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
606 mcIdType DataArrayTools<T>::GetNumberOfItemGivenBES(T begin, T end, T step, const std::string& msg)
610 std::ostringstream oss; oss << msg << " : end before begin !";
611 throw INTERP_KERNEL::Exception(oss.str().c_str());
617 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
618 throw INTERP_KERNEL::Exception(oss.str().c_str());
620 return ToIdType((end-1-begin)/step+1);
624 mcIdType DataArrayTools<T>::GetNumberOfItemGivenBESRelative(T begin, T end, T step, const std::string& msg)
627 throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
628 if(end<begin && step>0)
630 std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
631 throw INTERP_KERNEL::Exception(oss.str().c_str());
633 if(begin<end && step<0)
635 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
636 throw INTERP_KERNEL::Exception(oss.str().c_str());
639 return ToIdType((std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1);
645 mcIdType DataArrayTools<T>::GetPosOfItemGivenBESRelativeNoThrow(T value, T begin, T end, T step)
650 if((step>0 && begin<=value && value<end) ||
651 (step<0 && begin>=value && value>end))
653 mcIdType id = ToIdType((value-begin)/step);
654 if (begin + step * id == value)
663 //////////////////////////////////
666 MCAuto< typename Traits<T>::ArrayTypeCh > DataArrayTemplate<T>::NewFromStdVector(const typename std::vector<T>& v)
668 std::size_t sz(v.size());
669 MCAuto< typename Traits<T>::ArrayTypeCh > ret(Traits<T>::ArrayTypeCh::New());
671 T *pt(ret->getPointer());
672 std::copy(v.begin(),v.end(),pt);
677 * Returns a newly created array containing a copy of the input array defined by [ \a arrBegin, \a arrEnd )
680 MCAuto< typename Traits<T>::ArrayTypeCh > DataArrayTemplate<T>::NewFromArray(const T *arrBegin, const T *arrEnd)
682 using DataArrayT = typename Traits<T>::ArrayTypeCh;
683 MCAuto< DataArrayT > ret(DataArrayT::New());
684 std::size_t nbElts(std::distance(arrBegin,arrEnd));
685 ret->alloc(nbElts,1);
686 std::copy(arrBegin,arrEnd,ret->getPointer());
691 std::vector< MCAuto< typename Traits<T>::ArrayTypeCh > > DataArrayTemplate<T>::explodeComponents() const
694 std::size_t sz(getNumberOfComponents());
695 mcIdType nbTuples(getNumberOfTuples());
696 std::string name(getName());
697 std::vector<std::string> compNames(getInfoOnComponents());
698 std::vector< MCAuto< typename Traits<T>::ArrayTypeCh > > ret(sz);
699 const T *thisPt(begin());
700 for(std::size_t i=0;i<sz;i++)
702 MCAuto< typename Traits<T>::ArrayTypeCh > part(Traits<T>::ArrayTypeCh::New());
703 part->alloc(nbTuples,1);
705 part->setInfoOnComponent(0,compNames[i]);
706 T *otherPt(part->getPointer());
707 for(mcIdType j=0;j<nbTuples;j++)
708 otherPt[j]=thisPt[sz*j+i];
715 std::size_t DataArrayTemplate<T>::getHeapMemorySizeWithoutChildren() const
717 std::size_t sz(_mem.getNbOfElemAllocated());
719 return DataArray::getHeapMemorySizeWithoutChildren()+sz;
723 * Allocates the raw data in memory. If the memory was already allocated, then it is
724 * freed and re-allocated. See an example of this method use
725 * \ref MEDCouplingArraySteps1WC "here".
726 * \param [in] nbOfTuple - number of tuples of data to allocate.
727 * \param [in] nbOfCompo - number of components of data to allocate.
728 * \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
731 void DataArrayTemplate<T>::alloc(std::size_t nbOfTuple, std::size_t nbOfCompo)
733 _info_on_compo.resize(nbOfCompo);
734 _mem.alloc(nbOfCompo*nbOfTuple);
739 * Sets a C array to be used as raw data of \a this. The previously set info
740 * of components is retained and re-sized.
741 * For more info see \ref MEDCouplingArraySteps1.
742 * \param [in] array - the C array to be used as raw data of \a this.
743 * \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
744 * \param [in] type - specifies how to deallocate \a array. If \a type == MEDCoupling::CPP_DEALLOC,
745 * \c delete [] \c array; will be called. If \a type == MEDCoupling::C_DEALLOC,
746 * \c free(\c array ) will be called.
747 * \param [in] nbOfTuple - new number of tuples in \a this.
748 * \param [in] nbOfCompo - new number of components in \a this.
751 void DataArrayTemplate<T>::useArray(const T *array, bool ownership, DeallocType type, std::size_t nbOfTuple, std::size_t nbOfCompo)
753 _info_on_compo.resize(nbOfCompo);
754 _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
759 void DataArrayTemplate<T>::useExternalArrayWithRWAccess(const T *array, std::size_t nbOfTuple, std::size_t nbOfCompo)
761 _info_on_compo.resize(nbOfCompo);
762 _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
767 * Returns a value located at specified tuple and component.
768 * This method is equivalent to DataArrayTemplate<T>::getIJ() except that validity of
769 * parameters is checked. So this method is safe but expensive if used to go through
770 * all values of \a this.
771 * \param [in] tupleId - index of tuple of interest.
772 * \param [in] compoId - index of component of interest.
773 * \return double - value located by \a tupleId and \a compoId.
774 * \throw If \a this is not allocated.
775 * \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
776 * \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
779 T DataArrayTemplate<T>::getIJSafe(std::size_t tupleId, std::size_t compoId) const
782 if(ToIdType(tupleId)>=getNumberOfTuples())
784 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
785 throw INTERP_KERNEL::Exception(oss.str().c_str());
787 if(compoId>=getNumberOfComponents())
789 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
790 throw INTERP_KERNEL::Exception(oss.str().c_str());
792 return _mem[tupleId*_info_on_compo.size()+compoId];
796 * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store.
798 * \sa DataArray::getHeapMemorySizeWithoutChildren, DataArrayTemplate<T>::reserve
801 void DataArrayTemplate<T>::pack() const
807 * Checks if raw data is allocated. Read more on the raw data
808 * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
809 * \return bool - \a true if the raw data is allocated, \a false else.
812 bool DataArrayTemplate<T>::isAllocated() const
814 return getConstPointer()!=0;
818 * Checks if raw data is allocated and throws an exception if it is not the case.
819 * \throw If the raw data is not allocated.
822 void DataArrayTemplate<T>::checkAllocated() const
826 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !";
827 throw INTERP_KERNEL::Exception(oss.str().c_str());
832 * This method deallocated \a this without modification of information relative to the components.
833 * After call of this method, DataArrayDouble::isAllocated will return false.
834 * If \a this is already not allocated, \a this is let unchanged.
837 void DataArrayTemplate<T>::desallocate()
843 * This method reserve nbOfElems elements in memory ( nbOfElems*sizeof(T) ) \b without impacting the number of tuples in \a this.
844 * 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.
845 * If \a this has not already been allocated, number of components is set to one.
846 * This method allows to reduce number of reallocations on invocation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
848 * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
851 void DataArrayTemplate<T>::reserve(std::size_t nbOfElems)
853 std::size_t nbCompo(getNumberOfComponents());
856 _mem.reserve(nbOfElems);
860 _mem.reserve(nbOfElems);
861 _info_on_compo.resize(1);
865 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::reserve : not available for DataArrayDouble with number of components different than 1 !";
866 throw INTERP_KERNEL::Exception(oss.str().c_str());
871 * 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
872 * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
874 * \param [in] val the value to be added in \a this
875 * \throw If \a this has already been allocated with number of components different from one.
876 * \sa DataArrayDouble::pushBackValsSilent
879 void DataArrayTemplate<T>::pushBackSilent(T val)
881 std::size_t nbCompo(getNumberOfComponents());
886 _info_on_compo.resize(1);
891 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !";
892 throw INTERP_KERNEL::Exception(oss.str().c_str());
897 * 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
898 * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
900 * \param [in] valsBg - an array of values to push at the end of \c this.
901 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
902 * the last value of \a valsBg is \a valsEnd[ -1 ].
903 * \throw If \a this has already been allocated with number of components different from one.
904 * \sa DataArrayDouble::pushBackSilent
907 void DataArrayTemplate<T>::pushBackValsSilent(const T *valsBg, const T *valsEnd)
909 std::size_t nbCompo(getNumberOfComponents());
911 _mem.insertAtTheEnd(valsBg,valsEnd);
914 _info_on_compo.resize(1);
915 _mem.insertAtTheEnd(valsBg,valsEnd);
919 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !";
920 throw INTERP_KERNEL::Exception(oss.str().c_str());
925 * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
926 * \throw If \a this is already empty.
927 * \throw If \a this has number of components different from one.
930 T DataArrayTemplate<T>::popBackSilent()
932 if(getNumberOfComponents()==1)
933 return _mem.popBack();
936 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::popBackSilent : not available for DataArrayDouble with number of components different than 1 !";
937 throw INTERP_KERNEL::Exception(oss.str().c_str());
942 * Allocates the raw data in memory. If exactly same memory as needed already
943 * allocated, it is not re-allocated.
944 * \param [in] nbOfTuple - number of tuples of data to allocate.
945 * \param [in] nbOfCompo - number of components of data to allocate.
946 * \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
949 void DataArrayTemplate<T>::allocIfNecessary(std::size_t nbOfTuple, std::size_t nbOfCompo)
953 if(ToIdType(nbOfTuple)!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
954 alloc(nbOfTuple,nbOfCompo);
957 alloc(nbOfTuple,nbOfCompo);
961 * Checks the number of tuples.
962 * \return bool - \a true if getNumberOfTuples() == 0, \a false else.
963 * \throw If \a this is not allocated.
966 bool DataArrayTemplate<T>::empty() const
969 return getNumberOfTuples()==0;
973 * Copies all the data from another DataArrayDouble. For more info see
974 * \ref MEDCouplingArrayBasicsCopyDeepAssign.
975 * \param [in] other - another instance of DataArrayDouble to copy data from.
976 * \throw If the \a other is not allocated.
979 void DataArrayTemplate<T>::deepCopyFrom(const DataArrayTemplate<T>& other)
981 other.checkAllocated();
982 mcIdType nbOfTuples(other.getNumberOfTuples());
983 std::size_t nbOfComp(other.getNumberOfComponents());
984 allocIfNecessary(nbOfTuples,nbOfComp);
985 std::size_t nbOfElems(nbOfTuples*nbOfComp);
987 const T *ptI(other.begin());
988 for(std::size_t i=0;i<nbOfElems;i++)
990 copyStringInfoFrom(other);
994 * Reverse the array values.
995 * \throw If \a this->getNumberOfComponents() < 1.
996 * \throw If \a this is not allocated.
999 void DataArrayTemplate<T>::reverse()
1002 _mem.reverse(getNumberOfComponents());
1007 * Assign \a val to all values in \a this array. To know more on filling arrays see
1008 * \ref MEDCouplingArrayFill.
1009 * \param [in] val - the value to fill with.
1010 * \throw If \a this is not allocated.
1013 void DataArrayTemplate<T>::fillWithValue(T val)
1016 _mem.fillWithValue(val);
1021 * Changes number of tuples in the array. If the new number of tuples is smaller
1022 * than the current number the array is truncated, otherwise the array is extended.
1023 * \param [in] nbOfTuples - new number of tuples.
1024 * \throw If \a this is not allocated.
1025 * \throw If \a nbOfTuples is negative.
1028 void DataArrayTemplate<T>::reAlloc(std::size_t nbOfTuples)
1031 _mem.reAlloc(getNumberOfComponents()*nbOfTuples);
1036 * Permutes values of \a this array as required by \a old2New array. The values are
1037 * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1038 * the same as in \c this one.
1039 * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
1040 * For more info on renumbering see \ref numbering.
1041 * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1042 * giving a new position for i-th old value.
1045 void DataArrayTemplate<T>::renumberInPlace(const mcIdType *old2New)
1048 mcIdType nbTuples(getNumberOfTuples());
1049 std::size_t nbOfCompo(getNumberOfComponents());
1050 T *tmp(new T[nbTuples*nbOfCompo]);
1051 const T *iptr(begin());
1052 for(mcIdType i=0;i<nbTuples;i++)
1054 mcIdType v=old2New[i];
1055 if(v>=0 && v<nbTuples)
1056 std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1059 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1060 throw INTERP_KERNEL::Exception(oss.str().c_str());
1063 std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1070 * Permutes values of \a this array as required by \a new2Old array. The values are
1071 * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1072 * the same as in \c this one.
1073 * For more info on renumbering see \ref numbering.
1074 * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1075 * giving a previous position of i-th new value.
1078 void DataArrayTemplate<T>::renumberInPlaceR(const mcIdType *new2Old)
1081 mcIdType nbTuples(getNumberOfTuples());
1082 std::size_t nbOfCompo(getNumberOfComponents());
1083 T *tmp(new T[nbTuples*nbOfCompo]);
1084 const T *iptr(begin());
1085 for(mcIdType i=0;i<nbTuples;i++)
1087 mcIdType v=new2Old[i];
1088 if(v>=0 && v<nbTuples)
1089 std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1092 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1093 throw INTERP_KERNEL::Exception(oss.str().c_str());
1096 std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1102 * Sorts values of the array. \b Warning, this method is not const, it alterates \a this content.
1104 * \param [in] asc - \a true means ascending order, \a false, descending.
1105 * \throw If \a this is not allocated.
1106 * \throw If \a this->getNumberOfComponents() != 1.
1110 void DataArrayTemplate<T>::sort(bool asc)
1113 if(getNumberOfComponents()!=1)
1115 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::sort : only supported with 'this' array with ONE component !";
1116 throw INTERP_KERNEL::Exception(oss.str().c_str());
1123 * Sorts values of the array and put the result in a newly allocated returned array.
1124 * This method does not alterate \a this content.
1126 * \param [in] asc - \a true means ascending order, \a false, descending.
1127 * \throw If \a this is not allocated.
1128 * \throw If \a this->getNumberOfComponents() != 1.
1132 typename Traits<T>::ArrayTypeCh *DataArrayTemplate<T>::copySortedImpl(bool asc) const
1134 MCAuto<typename Traits<T>::ArrayTypeCh> ret(static_cast<typename Traits<T>::ArrayTypeCh *>(this->deepCopy()));
1140 * Returns a copy of \a this array with values permuted as required by \a old2New array.
1141 * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ].
1142 * Number of tuples in the result array remains the same as in \c this one.
1143 * If a permutation reduction is needed, renumberAndReduce() should be used.
1144 * For more info on renumbering see \ref numbering.
1145 * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1146 * giving a new position for i-th old value.
1147 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1148 * is to delete using decrRef() as it is no more needed.
1149 * \throw If \a this is not allocated.
1152 typename Traits<T>::ArrayType *DataArrayTemplate<T>::renumber(const mcIdType *old2New) const
1155 mcIdType nbTuples(getNumberOfTuples());
1156 std::size_t nbOfCompo(getNumberOfComponents());
1157 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1158 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1159 ret->alloc(nbTuples,nbOfCompo);
1160 ret->copyStringInfoFrom(*this);
1161 const T *iptr(begin());
1162 T *optr(ret->getPointer());
1163 for(mcIdType i=0;i<nbTuples;i++)
1164 std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1165 ret->copyStringInfoFrom(*this);
1170 * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1171 * The values are permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1172 * tuples in the result array remains the same as in \c this one.
1173 * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
1174 * For more info on renumbering see \ref numbering.
1175 * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1176 * giving a previous position of i-th new value.
1177 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1178 * is to delete using decrRef() as it is no more needed.
1181 typename Traits<T>::ArrayType *DataArrayTemplate<T>::renumberR(const mcIdType *new2Old) const
1184 mcIdType nbTuples(getNumberOfTuples());
1185 std::size_t nbOfCompo(getNumberOfComponents());
1186 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1187 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1188 ret->alloc(nbTuples,nbOfCompo);
1189 ret->copyStringInfoFrom(*this);
1190 const T *iptr(getConstPointer());
1191 T *optr(ret->getPointer());
1192 for(mcIdType i=0;i<nbTuples;i++)
1193 std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1194 ret->copyStringInfoFrom(*this);
1199 * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1200 * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1201 * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ] for all
1202 * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which
1203 * \a old2New[ i ] is negative, is missing from the result array.
1204 * For more info on renumbering see \ref numbering.
1205 * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1206 * giving a new position for i-th old tuple and giving negative position for
1207 * for i-th old tuple that should be omitted.
1208 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1209 * is to delete using decrRef() as it is no more needed.
1212 typename Traits<T>::ArrayType *DataArrayTemplate<T>::renumberAndReduce(const mcIdType *old2New, mcIdType newNbOfTuple) const
1215 mcIdType nbTuples(getNumberOfTuples());
1216 std::size_t nbOfCompo(getNumberOfComponents());
1217 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1218 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1219 ret->alloc(newNbOfTuple,nbOfCompo);
1220 const T *iptr=getConstPointer();
1221 T *optr=ret->getPointer();
1222 for(mcIdType i=0;i<nbTuples;i++)
1224 mcIdType w=old2New[i];
1226 std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1228 ret->copyStringInfoFrom(*this);
1233 * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1234 * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1235 * \a new2OldBg array.
1236 * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1237 * This method is equivalent to renumberAndReduce() except that convention in input is
1238 * \c new2old and \b not \c old2new.
1239 * For more info on renumbering see \ref numbering.
1240 * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1241 * tuple index in \a this array to fill the i-th tuple in the new array.
1242 * \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1243 * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1244 * \a new2OldBg <= \a pi < \a new2OldEnd.
1245 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1246 * is to delete using decrRef() as it is no more needed.
1249 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleId(const mcIdType *new2OldBg, const mcIdType *new2OldEnd) const
1252 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1253 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1254 std::size_t nbComp(getNumberOfComponents());
1255 ret->alloc(std::distance(new2OldBg,new2OldEnd),nbComp);
1256 ret->copyStringInfoFrom(*this);
1257 T *pt(ret->getPointer());
1258 const T *srcPt(getConstPointer());
1260 for(const mcIdType *w=new2OldBg;w!=new2OldEnd;w++,i++)
1261 std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1262 ret->copyStringInfoFrom(*this);
1267 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleId(const DataArrayIdType& di) const
1269 return this->mySelectByTupleId(di.begin(),di.end());
1273 MCAuto<typename Traits<T>::ArrayTypeCh> DataArrayTemplate<T>::selectPartDef(const PartDefinition *pd) const
1276 throw INTERP_KERNEL::Exception("DataArrayTemplate<T>::selectPartDef : null input pointer !");
1277 MCAuto<typename Traits<T>::ArrayTypeCh> ret(Traits<T>::ArrayTypeCh::New());
1278 const SlicePartDefinition *spd(dynamic_cast<const SlicePartDefinition *>(pd));
1282 spd->getSlice(a,b,c);
1283 if(a==0 && b==getNumberOfTuples() && c==1)
1285 DataArrayTemplate<T> *directRet(const_cast<DataArrayTemplate<T> *>(this));
1286 directRet->incrRef();
1287 MCAuto<DataArrayTemplate<T> > ret2(directRet);
1288 return DynamicCastSafe<DataArrayTemplate<T>,typename Traits<T>::ArrayTypeCh>(ret2);
1292 MCAuto<DataArray> ret2(selectByTupleIdSafeSlice(a,b,c));
1293 return DynamicCastSafe<DataArray,typename Traits<T>::ArrayTypeCh>(ret2);
1296 const DataArrayPartDefinition *dpd(dynamic_cast<const DataArrayPartDefinition *>(pd));
1299 MCAuto<DataArrayIdType> arr(dpd->toDAI());
1300 MCAuto<DataArray> ret2(selectByTupleIdSafe(arr->begin(),arr->end()));
1301 return DynamicCastSafe<DataArray,typename Traits<T>::ArrayTypeCh>(ret2);
1304 throw INTERP_KERNEL::Exception("DataArrayTemplate<T>::selectPartDef : unrecognized part def !");
1308 * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1309 * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1310 * \a new2OldBg array.
1311 * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1312 * This method is equivalent to renumberAndReduce() except that convention in input is
1313 * \c new2old and \b not \c old2new.
1314 * This method is equivalent to selectByTupleId() except that it prevents coping data
1315 * from behind the end of \a this array.
1316 * For more info on renumbering see \ref numbering.
1317 * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1318 * tuple index in \a this array to fill the i-th tuple in the new array.
1319 * \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1320 * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1321 * \a new2OldBg <= \a pi < \a new2OldEnd.
1322 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1323 * is to delete using decrRef() as it is no more needed.
1324 * \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1327 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleIdSafe(const mcIdType *new2OldBg, const mcIdType *new2OldEnd) const
1330 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1331 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1332 std::size_t nbComp(getNumberOfComponents());
1333 mcIdType oldNbOfTuples(getNumberOfTuples());
1334 ret->alloc(std::distance(new2OldBg,new2OldEnd),nbComp);
1335 ret->copyStringInfoFrom(*this);
1336 T *pt(ret->getPointer());
1337 const T *srcPt(getConstPointer());
1339 for(const mcIdType *w=new2OldBg;w!=new2OldEnd;w++,i++)
1340 if(*w>=0 && *w<oldNbOfTuples)
1341 std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1344 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !";
1345 throw INTERP_KERNEL::Exception(oss.str().c_str());
1347 ret->copyStringInfoFrom(*this);
1352 * Changes the number of components within \a this array so that its raw data **does
1353 * not** change, instead splitting this data into tuples changes.
1354 * \warning This method erases all (name and unit) component info set before!
1355 * \param [in] newNbOfCompo - number of components for \a this array to have.
1356 * \throw If \a this is not allocated
1357 * \throw If getNbOfElems() % \a newNbOfCompo != 0.
1358 * \throw If \a newNbOfCompo is lower than 1.
1359 * \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1360 * \warning This method erases all (name and unit) component info set before!
1363 void DataArrayTemplate<T>::rearrange(std::size_t newNbOfCompo)
1368 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::rearrange : input newNbOfCompo must be > 0 !";
1369 throw INTERP_KERNEL::Exception(oss.str().c_str());
1371 std::size_t nbOfElems=getNbOfElems();
1372 if(nbOfElems%newNbOfCompo!=0)
1374 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::rearrange : nbOfElems%newNbOfCompo!=0 !";
1375 throw INTERP_KERNEL::Exception(oss.str().c_str());
1377 if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<mcIdType>::max())
1379 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !";
1380 throw INTERP_KERNEL::Exception(oss.str().c_str());
1382 _info_on_compo.clear();
1383 _info_on_compo.resize(newNbOfCompo);
1388 * Changes the number of components within \a this array to be equal to its number
1389 * of tuples, and inversely its number of tuples to become equal to its number of
1390 * components. So that its raw data **does not** change, instead splitting this
1391 * data into tuples changes.
1392 * \warning This method erases all (name and unit) component info set before!
1393 * \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1394 * \throw If \a this is not allocated.
1398 void DataArrayTemplate<T>::transpose()
1401 rearrange(getNumberOfTuples());
1405 * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1406 * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1407 * is truncated to have \a newNbOfComp components, keeping first components. If \a
1408 * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1409 * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1411 * \param [in] newNbOfComp - number of components for the new array to have.
1412 * \param [in] dftValue - value assigned to new values added to the new array.
1413 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1414 * is to delete using decrRef() as it is no more needed.
1415 * \throw If \a this is not allocated.
1418 typename Traits<T>::ArrayType *DataArrayTemplate<T>::changeNbOfComponents(std::size_t newNbOfComp, T dftValue) const
1421 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1422 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1423 ret->alloc(getNumberOfTuples(),newNbOfComp);
1424 const T *oldc(getConstPointer());
1425 T *nc(ret->getPointer());
1426 mcIdType nbOfTuples=getNumberOfTuples();
1427 std::size_t oldNbOfComp=getNumberOfComponents();
1428 std::size_t dim(std::min(oldNbOfComp,newNbOfComp));
1429 for(mcIdType i=0;i<nbOfTuples;i++)
1433 nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1434 for(;j<newNbOfComp;j++)
1435 nc[newNbOfComp*i+j]=dftValue;
1437 ret->setName(getName());
1438 for(std::size_t i=0;i<dim;i++)
1439 ret->setInfoOnComponent(i,getInfoOnComponent(i));
1440 ret->setName(getName());
1445 * Returns a copy of \a this array composed of selected components.
1446 * The new DataArrayDouble has the same number of tuples but includes components
1447 * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1448 * can be either less, same or more than \a this->getNbOfElems().
1449 * \param [in] compoIds - sequence of zero based indices of components to include
1450 * into the new array.
1451 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1452 * is to delete using decrRef() as it is no more needed.
1453 * \throw If \a this is not allocated.
1454 * \throw If a component index (\a i) is not valid:
1455 * \a i < 0 || \a i >= \a this->getNumberOfComponents().
1457 * \if ENABLE_EXAMPLES
1458 * \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1462 typename Traits<T>::ArrayType *DataArrayTemplate<T>::myKeepSelectedComponents(const std::vector<std::size_t>& compoIds) const
1465 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1466 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1467 std::size_t newNbOfCompo=compoIds.size();
1468 std::size_t oldNbOfCompo=getNumberOfComponents();
1469 for(std::vector<std::size_t>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1470 if((*it)>=oldNbOfCompo) // (*it) >= 0 (it is a size_t)
1472 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1473 throw INTERP_KERNEL::Exception(oss.str().c_str());
1475 mcIdType nbOfTuples(getNumberOfTuples());
1476 ret->alloc(nbOfTuples,newNbOfCompo);
1477 ret->copyPartOfStringInfoFrom(*this,compoIds);
1478 const T *oldc(getConstPointer());
1479 T *nc(ret->getPointer());
1480 for(mcIdType i=0;i<nbOfTuples;i++)
1481 for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1482 *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1487 * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1488 * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1489 * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1490 * This method is a specialization of selectByTupleIdSafeSlice().
1491 * \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1492 * \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1493 * If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1494 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1495 * is to delete using decrRef() as it is no more needed.
1496 * \throw If \a tupleIdBg < 0.
1497 * \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1498 * \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1499 * \sa DataArrayDouble::selectByTupleIdSafeSlice
1502 typename Traits<T>::ArrayType *DataArrayTemplate<T>::subArray(mcIdType tupleIdBg, mcIdType tupleIdEnd) const
1505 mcIdType nbt=getNumberOfTuples();
1508 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::subArray : The tupleIdBg parameter must be greater than 0 !";
1509 throw INTERP_KERNEL::Exception(oss.str().c_str());
1513 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << ":subArray : The tupleIdBg parameter is greater than number of tuples !";
1514 throw INTERP_KERNEL::Exception(oss.str().c_str());
1516 mcIdType trueEnd=tupleIdEnd;
1521 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << ":subArray : The tupleIdBg parameter is greater than number of tuples !";
1522 throw INTERP_KERNEL::Exception(oss.str().c_str());
1527 std::size_t nbComp=getNumberOfComponents();
1528 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1529 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1530 ret->alloc(trueEnd-tupleIdBg,nbComp);
1531 ret->copyStringInfoFrom(*this);
1532 std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1537 * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1538 * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1539 * tuple. Indices of the selected tuples are the same as ones returned by the Python
1540 * command \c range( \a bg, \a end2, \a step ).
1541 * This method is equivalent to selectByTupleIdSafe() except that the input array is
1542 * not constructed explicitly.
1543 * For more info on renumbering see \ref numbering.
1544 * \param [in] bg - index of the first tuple to copy from \a this array.
1545 * \param [in] end2 - index of the tuple before which the tuples to copy are located.
1546 * \param [in] step - index increment to get index of the next tuple to copy.
1547 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1548 * is to delete using decrRef() as it is no more needed.
1549 * \sa DataArrayDouble::subArray.
1552 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleIdSafeSlice(mcIdType bg, mcIdType end2, mcIdType step) const
1555 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1556 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1557 std::size_t nbComp(getNumberOfComponents());
1558 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::selectByTupleIdSafeSlice : ";
1559 mcIdType newNbOfTuples(GetNumberOfItemGivenBESRelative(bg,end2,step,oss.str()));
1560 ret->alloc(newNbOfTuples,nbComp);
1561 T *pt(ret->getPointer());
1562 const T *srcPt(getConstPointer()+bg*nbComp);
1563 for(mcIdType i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1564 std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1565 ret->copyStringInfoFrom(*this);
1570 * Copy all values from another DataArrayDouble into specified tuples and components
1571 * of \a this array. Textual data is not copied.
1572 * The tree parameters defining set of indices of tuples and components are similar to
1573 * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
1574 * \param [in] a - the array to copy values from.
1575 * \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
1576 * \param [in] endTuples - index of the tuple before which the tuples to assign to
1578 * \param [in] stepTuples - index increment to get index of the next tuple to assign to.
1579 * \param [in] bgComp - index of the first component of \a this array to assign values to.
1580 * \param [in] endComp - index of the component before which the components to assign
1582 * \param [in] stepComp - index increment to get index of the next component to assign to.
1583 * \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents()
1584 * must be equal to the number of columns to assign to, else an
1585 * exception is thrown; if \a false, then it is only required that \a
1586 * a->getNbOfElems() equals to number of values to assign to (this condition
1587 * must be respected even if \a strictCompoCompare is \a true). The number of
1588 * values to assign to is given by following Python expression:
1589 * \a nbTargetValues =
1590 * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
1591 * \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1592 * \throw If \a a is NULL.
1593 * \throw If \a a is not allocated.
1594 * \throw If \a this is not allocated.
1595 * \throw If parameters specifying tuples and components to assign to do not give a
1596 * non-empty range of increasing indices.
1597 * \throw If \a a->getNbOfElems() != \a nbTargetValues.
1598 * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
1599 * \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1601 * \if ENABLE_EXAMPLES
1602 * \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
1606 void DataArrayTemplate<T>::setPartOfValues1(const typename Traits<T>::ArrayType *a, mcIdType bgTuples, mcIdType endTuples, mcIdType stepTuples, mcIdType bgComp, mcIdType endComp, mcIdType stepComp, bool strictCompoCompare)
1610 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::setPartOfValues1 : input DataArrayDouble is NULL !";
1611 throw INTERP_KERNEL::Exception(oss.str().c_str());
1613 const char msg[]="DataArrayTemplate::setPartOfValues1";
1615 a->checkAllocated();
1616 mcIdType newNbOfTuples(DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg));
1617 mcIdType newNbOfComp(DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg));
1618 std::size_t nbComp(getNumberOfComponents());
1619 mcIdType nbOfTuples(getNumberOfTuples());
1620 DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
1621 DataArray::CheckValueInRangeEx(ToIdType(nbComp),bgComp,endComp,"invalid component value");
1622 bool assignTech(true);
1623 if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
1625 if(strictCompoCompare)
1626 a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1630 a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
1633 const T *srcPt(a->getConstPointer());
1634 T *pt(getPointer()+bgTuples*nbComp+bgComp);
1637 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1638 for(mcIdType j=0;j<newNbOfComp;j++,srcPt++)
1639 pt[j*stepComp]=*srcPt;
1643 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1645 const T*srcPt2=srcPt;
1646 for(mcIdType j=0;j<newNbOfComp;j++,srcPt2++)
1647 pt[j*stepComp]=*srcPt2;
1653 * Assign a given value to values at specified tuples and components of \a this array.
1654 * The tree parameters defining set of indices of tuples and components are similar to
1655 * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
1656 * \param [in] a - the value to assign.
1657 * \param [in] bgTuples - index of the first tuple of \a this array to assign to.
1658 * \param [in] endTuples - index of the tuple before which the tuples to assign to
1660 * \param [in] stepTuples - index increment to get index of the next tuple to assign to.
1661 * \param [in] bgComp - index of the first component of \a this array to assign to.
1662 * \param [in] endComp - index of the component before which the components to assign
1664 * \param [in] stepComp - index increment to get index of the next component to assign to.
1665 * \throw If \a this is not allocated.
1666 * \throw If parameters specifying tuples and components to assign to, do not give a
1667 * non-empty range of increasing indices or indices are out of a valid range
1668 * for \c this array.
1670 * \if ENABLE_EXAMPLES
1671 * \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
1675 void DataArrayTemplate<T>::setPartOfValuesSimple1(T a, mcIdType bgTuples, mcIdType endTuples, mcIdType stepTuples, mcIdType bgComp, mcIdType endComp, mcIdType stepComp)
1677 const char msg[]="DataArrayTemplate::setPartOfValuesSimple1";
1679 mcIdType newNbOfTuples(DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg));
1680 mcIdType newNbOfComp(DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg));
1681 std::size_t nbComp(getNumberOfComponents());
1682 mcIdType nbOfTuples(getNumberOfTuples());
1683 DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
1684 DataArray::CheckValueInRangeEx(ToIdType(nbComp),bgComp,endComp,"invalid component value");
1685 T *pt=getPointer()+bgTuples*nbComp+bgComp;
1686 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1687 for(mcIdType j=0;j<newNbOfComp;j++)
1692 * Copy all values from another DataArrayDouble (\a a) into specified tuples and
1693 * components of \a this array. Textual data is not copied.
1694 * The tuples and components to assign to are defined by C arrays of indices.
1695 * There are two *modes of usage*:
1696 * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
1697 * of \a a is assigned to its own location within \a this array.
1698 * - If \a a includes one tuple, then all values of \a a are assigned to the specified
1699 * components of every specified tuple of \a this array. In this mode it is required
1700 * that \a a->getNumberOfComponents() equals to the number of specified components.
1702 * \param [in] a - the array to copy values from.
1703 * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
1704 * assign values of \a a to.
1705 * \param [in] endTuples - specifies the end of the array \a bgTuples, so that
1706 * pointer to a tuple index <em>(pi)</em> varies as this:
1707 * \a bgTuples <= \a pi < \a endTuples.
1708 * \param [in] bgComp - pointer to an array of component indices of \a this array to
1709 * assign values of \a a to.
1710 * \param [in] endComp - specifies the end of the array \a bgTuples, so that
1711 * pointer to a component index <em>(pi)</em> varies as this:
1712 * \a bgComp <= \a pi < \a endComp.
1713 * \param [in] strictCompoCompare - this parameter is checked only if the
1714 * *mode of usage* is the first; if it is \a true (default),
1715 * then \a a->getNumberOfComponents() must be equal
1716 * to the number of specified columns, else this is not required.
1717 * \throw If \a a is NULL.
1718 * \throw If \a a is not allocated.
1719 * \throw If \a this is not allocated.
1720 * \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
1721 * out of a valid range for \a this array.
1722 * \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
1723 * if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
1724 * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
1725 * <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
1727 * \if ENABLE_EXAMPLES
1728 * \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
1732 void DataArrayTemplate<T>::setPartOfValues2(const typename Traits<T>::ArrayType *a, const mcIdType *bgTuples, const mcIdType *endTuples, const mcIdType *bgComp, const mcIdType *endComp, bool strictCompoCompare)
1735 throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
1736 const char msg[]="DataArrayTemplate::setPartOfValues2";
1738 a->checkAllocated();
1739 std::size_t nbComp(getNumberOfComponents());
1740 mcIdType nbOfTuples(getNumberOfTuples());
1741 for(const mcIdType *z=bgComp;z!=endComp;z++)
1742 DataArray::CheckValueInRange(ToIdType(nbComp),*z,"invalid component id");
1743 mcIdType newNbOfTuples(ToIdType(std::distance(bgTuples,endTuples)));
1744 mcIdType newNbOfComp(ToIdType(std::distance(bgComp,endComp)));
1745 bool assignTech(true);
1746 if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
1748 if(strictCompoCompare)
1749 a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1753 a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
1756 T *pt(getPointer());
1757 const T *srcPt(a->getConstPointer());
1760 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1762 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1763 for(const mcIdType *z=bgComp;z!=endComp;z++,srcPt++)
1765 pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
1771 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1773 const T *srcPt2=srcPt;
1774 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1775 for(const mcIdType *z=bgComp;z!=endComp;z++,srcPt2++)
1777 pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
1784 * Assign a given value to values at specified tuples and components of \a this array.
1785 * The tuples and components to assign to are defined by C arrays of indices.
1786 * \param [in] a - the value to assign.
1787 * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
1789 * \param [in] endTuples - specifies the end of the array \a bgTuples, so that
1790 * pointer to a tuple index (\a pi) varies as this:
1791 * \a bgTuples <= \a pi < \a endTuples.
1792 * \param [in] bgComp - pointer to an array of component indices of \a this array to
1794 * \param [in] endComp - specifies the end of the array \a bgTuples, so that
1795 * pointer to a component index (\a pi) varies as this:
1796 * \a bgComp <= \a pi < \a endComp.
1797 * \throw If \a this is not allocated.
1798 * \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
1799 * out of a valid range for \a this array.
1801 * \if ENABLE_EXAMPLES
1802 * \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
1806 void DataArrayTemplate<T>::setPartOfValuesSimple2(T a, const mcIdType *bgTuples, const mcIdType *endTuples, const mcIdType *bgComp, const mcIdType *endComp)
1809 std::size_t nbComp=getNumberOfComponents();
1810 mcIdType nbOfTuples=getNumberOfTuples();
1811 for(const mcIdType *z=bgComp;z!=endComp;z++)
1812 DataArray::CheckValueInRange(ToIdType(nbComp),*z,"invalid component id");
1813 T *pt(getPointer());
1814 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1815 for(const mcIdType *z=bgComp;z!=endComp;z++)
1817 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1818 pt[(std::size_t)(*w)*nbComp+(*z)]=a;
1823 * Copy all values from another DataArrayDouble (\a a) into specified tuples and
1824 * components of \a this array. Textual data is not copied.
1825 * The tuples to assign to are defined by a C array of indices.
1826 * The components to assign to are defined by three values similar to parameters of
1827 * the Python function \c range(\c start,\c stop,\c step).
1828 * There are two *modes of usage*:
1829 * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
1830 * of \a a is assigned to its own location within \a this array.
1831 * - If \a a includes one tuple, then all values of \a a are assigned to the specified
1832 * components of every specified tuple of \a this array. In this mode it is required
1833 * that \a a->getNumberOfComponents() equals to the number of specified components.
1835 * \param [in] a - the array to copy values from.
1836 * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
1837 * assign values of \a a to.
1838 * \param [in] endTuples - specifies the end of the array \a bgTuples, so that
1839 * pointer to a tuple index <em>(pi)</em> varies as this:
1840 * \a bgTuples <= \a pi < \a endTuples.
1841 * \param [in] bgComp - index of the first component of \a this array to assign to.
1842 * \param [in] endComp - index of the component before which the components to assign
1844 * \param [in] stepComp - index increment to get index of the next component to assign to.
1845 * \param [in] strictCompoCompare - this parameter is checked only in the first
1846 * *mode of usage*; if \a strictCompoCompare is \a true (default),
1847 * then \a a->getNumberOfComponents() must be equal
1848 * to the number of specified columns, else this is not required.
1849 * \throw If \a a is NULL.
1850 * \throw If \a a is not allocated.
1851 * \throw If \a this is not allocated.
1852 * \throw If any index of tuple given by \a bgTuples is out of a valid range for
1854 * \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
1855 * if <em> a->getNumberOfComponents()</em> is unequal to the number of components
1856 * defined by <em>(bgComp,endComp,stepComp)</em>.
1857 * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
1858 * <em> a->getNumberOfComponents()</em> is unequal to the number of components
1859 * defined by <em>(bgComp,endComp,stepComp)</em>.
1860 * \throw If parameters specifying components to assign to, do not give a
1861 * non-empty range of increasing indices or indices are out of a valid range
1862 * for \c this array.
1864 * \if ENABLE_EXAMPLES
1865 * \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
1869 void DataArrayTemplate<T>::setPartOfValues3(const typename Traits<T>::ArrayType *a, const mcIdType *bgTuples, const mcIdType *endTuples, mcIdType bgComp, mcIdType endComp, mcIdType stepComp, bool strictCompoCompare)
1872 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValues3 : input DataArrayDouble is NULL !");
1873 const char msg[]="DataArrayTemplate::setPartOfValues3";
1875 a->checkAllocated();
1876 mcIdType newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
1877 std::size_t nbComp(getNumberOfComponents());
1878 mcIdType nbOfTuples(getNumberOfTuples());
1879 DataArray::CheckValueInRangeEx(ToIdType(nbComp),bgComp,endComp,"invalid component value");
1880 mcIdType newNbOfTuples=ToIdType(std::distance(bgTuples,endTuples));
1881 bool assignTech=true;
1882 if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
1884 if(strictCompoCompare)
1885 a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1889 a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
1892 T *pt(getPointer()+bgComp);
1893 const T *srcPt(a->getConstPointer());
1896 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1897 for(mcIdType j=0;j<newNbOfComp;j++,srcPt++)
1899 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1900 pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
1905 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1907 const T *srcPt2=srcPt;
1908 for(mcIdType j=0;j<newNbOfComp;j++,srcPt2++)
1910 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1911 pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
1918 * Assign a given value to values at specified tuples and components of \a this array.
1919 * The tuples to assign to are defined by a C array of indices.
1920 * The components to assign to are defined by three values similar to parameters of
1921 * the Python function \c range(\c start,\c stop,\c step).
1922 * \param [in] a - the value to assign.
1923 * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
1925 * \param [in] endTuples - specifies the end of the array \a bgTuples, so that
1926 * pointer to a tuple index <em>(pi)</em> varies as this:
1927 * \a bgTuples <= \a pi < \a endTuples.
1928 * \param [in] bgComp - index of the first component of \a this array to assign to.
1929 * \param [in] endComp - index of the component before which the components to assign
1931 * \param [in] stepComp - index increment to get index of the next component to assign to.
1932 * \throw If \a this is not allocated.
1933 * \throw If any index of tuple given by \a bgTuples is out of a valid range for
1935 * \throw If parameters specifying components to assign to, do not give a
1936 * non-empty range of increasing indices or indices are out of a valid range
1937 * for \c this array.
1939 * \if ENABLE_EXAMPLES
1940 * \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
1944 void DataArrayTemplate<T>::setPartOfValuesSimple3(T a, const mcIdType *bgTuples, const mcIdType *endTuples, mcIdType bgComp, mcIdType endComp, mcIdType stepComp)
1946 const char msg[]="DataArrayTemplate::setPartOfValuesSimple3";
1948 std::size_t newNbOfComp(DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg));
1949 std::size_t nbComp(getNumberOfComponents());
1950 mcIdType nbOfTuples(getNumberOfTuples());
1951 DataArray::CheckValueInRangeEx(ToIdType(nbComp),bgComp,endComp,"invalid component value");
1952 T *pt(getPointer()+bgComp);
1953 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1954 for(std::size_t j=0;j<newNbOfComp;j++)
1956 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1957 pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
1962 * Copy all values from another DataArrayDouble into specified tuples and components
1963 * of \a this array. Textual data is not copied.
1964 * The tree parameters defining set of indices of tuples and components are similar to
1965 * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
1966 * \param [in] a - the array to copy values from.
1967 * \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
1968 * \param [in] endTuples - index of the tuple before which the tuples to assign to
1970 * \param [in] stepTuples - index increment to get index of the next tuple to assign to.
1971 * \param [in] bgComp - pointer to an array of component indices of \a this array to
1973 * \param [in] endComp - specifies the end of the array \a bgTuples, so that
1974 * pointer to a component index (\a pi) varies as this:
1975 * \a bgComp <= \a pi < \a endComp.
1976 * \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents()
1977 * must be equal to the number of columns to assign to, else an
1978 * exception is thrown; if \a false, then it is only required that \a
1979 * a->getNbOfElems() equals to number of values to assign to (this condition
1980 * must be respected even if \a strictCompoCompare is \a true). The number of
1981 * values to assign to is given by following Python expression:
1982 * \a nbTargetValues =
1983 * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
1984 * \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1985 * \throw If \a a is NULL.
1986 * \throw If \a a is not allocated.
1987 * \throw If \a this is not allocated.
1988 * \throw If parameters specifying tuples and components to assign to do not give a
1989 * non-empty range of increasing indices.
1990 * \throw If \a a->getNbOfElems() != \a nbTargetValues.
1991 * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
1992 * \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1996 void DataArrayTemplate<T>::setPartOfValues4(const typename Traits<T>::ArrayType *a, mcIdType bgTuples, mcIdType endTuples, mcIdType stepTuples, const mcIdType *bgComp, const mcIdType *endComp, bool strictCompoCompare)
1998 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValues4 : input DataArrayTemplate is NULL !");
1999 const char msg[]="DataArrayTemplate::setPartOfValues4";
2001 a->checkAllocated();
2002 mcIdType newNbOfTuples(DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg));
2003 std::size_t newNbOfComp(std::distance(bgComp,endComp));
2004 std::size_t nbComp(getNumberOfComponents());
2005 for(const mcIdType *z=bgComp;z!=endComp;z++)
2006 DataArray::CheckValueInRange(ToIdType(nbComp),*z,"invalid component id");
2007 mcIdType nbOfTuples(getNumberOfTuples());
2008 DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2009 bool assignTech(true);
2010 if(a->getNbOfElems()==ToIdType(newNbOfTuples*newNbOfComp))
2012 if(strictCompoCompare)
2013 a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2017 a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2020 const T *srcPt(a->getConstPointer());
2021 T *pt(getPointer()+bgTuples*nbComp);
2024 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2025 for(const mcIdType *z=bgComp;z!=endComp;z++,srcPt++)
2030 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2032 const T *srcPt2(srcPt);
2033 for(const mcIdType *z=bgComp;z!=endComp;z++,srcPt2++)
2040 void DataArrayTemplate<T>::setPartOfValuesSimple4(T a, mcIdType bgTuples, mcIdType endTuples, mcIdType stepTuples, const mcIdType *bgComp, const mcIdType *endComp)
2042 const char msg[]="DataArrayTemplate::setPartOfValuesSimple4";
2044 mcIdType newNbOfTuples(DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg));
2045 std::size_t nbComp(getNumberOfComponents());
2046 for(const mcIdType *z=bgComp;z!=endComp;z++)
2047 DataArray::CheckValueInRange(ToIdType(nbComp),*z,"invalid component id");
2048 mcIdType nbOfTuples(getNumberOfTuples());
2049 DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2050 T *pt=getPointer()+bgTuples*nbComp;
2051 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2052 for(const mcIdType *z=bgComp;z!=endComp;z++)
2057 * Copy some tuples from another DataArrayDouble into specified tuples
2058 * of \a this array. Textual data is not copied. Both arrays must have equal number of
2060 * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2061 * All components of selected tuples are copied.
2062 * \param [in] a - the array to copy values from.
2063 * \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2064 * target tuples of \a this. \a tuplesSelec has two components, and the
2065 * first component specifies index of the source tuple and the second
2066 * one specifies index of the target tuple.
2067 * \throw If \a this is not allocated.
2068 * \throw If \a a is NULL.
2069 * \throw If \a a is not allocated.
2070 * \throw If \a tuplesSelec is NULL.
2071 * \throw If \a tuplesSelec is not allocated.
2072 * \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2073 * \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2074 * \throw If any tuple index given by \a tuplesSelec is out of a valid range for
2075 * the corresponding (\a this or \a a) array.
2078 void DataArrayTemplate<T>::setPartOfValuesAdv(const typename Traits<T>::ArrayType *a, const DataArrayIdType *tuplesSelec)
2080 if(!a || !tuplesSelec)
2081 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValuesAdv : input DataArrayTemplate is NULL !");
2083 a->checkAllocated();
2084 tuplesSelec->checkAllocated();
2085 std::size_t nbOfComp(getNumberOfComponents());
2086 if(nbOfComp!=a->getNumberOfComponents())
2087 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValuesAdv : This and a do not have the same number of components !");
2088 if(tuplesSelec->getNumberOfComponents()!=2)
2089 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2090 mcIdType thisNt(getNumberOfTuples());
2091 mcIdType aNt(a->getNumberOfTuples());
2092 T *valsToSet(getPointer());
2093 const T *valsSrc(a->getConstPointer());
2094 for(const mcIdType *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2096 if(tuple[1]>=0 && tuple[1]<aNt)
2098 if(tuple[0]>=0 && tuple[0]<thisNt)
2099 std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2102 std::ostringstream oss; oss << "DataArrayTemplate::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2103 oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2104 throw INTERP_KERNEL::Exception(oss.str().c_str());
2109 std::ostringstream oss; oss << "DataArrayTemplate::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2110 oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2111 throw INTERP_KERNEL::Exception(oss.str().c_str());
2117 * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2118 * of \a this array. Textual data is not copied. Both arrays must have equal number of
2120 * The tuples to assign to are defined by index of the first tuple, and
2121 * their number is defined by \a tuplesSelec->getNumberOfTuples().
2122 * The tuples to copy are defined by values of a DataArrayInt.
2123 * All components of selected tuples are copied.
2124 * \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2126 * \param [in] aBase - the array to copy values from.
2127 * \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2128 * \throw If \a this is not allocated.
2129 * \throw If \a aBase is NULL.
2130 * \throw If \a aBase is not allocated.
2131 * \throw If \a tuplesSelec is NULL.
2132 * \throw If \a tuplesSelec is not allocated.
2133 * \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2134 * \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2135 * \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2136 * \throw If any tuple index given by \a tuplesSelec is out of a valid range for
2140 void DataArrayTemplate<T>::setContigPartOfSelectedValues(mcIdType tupleIdStart, const DataArray *aBase, const DataArrayIdType *tuplesSelec)
2142 if(!aBase || !tuplesSelec)
2143 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : input DataArray is NULL !");
2144 const typename Traits<T>::ArrayType *a(dynamic_cast<const typename Traits<T>::ArrayType *>(aBase));
2146 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2148 a->checkAllocated();
2149 tuplesSelec->checkAllocated();
2150 std::size_t nbOfComp(getNumberOfComponents());
2151 if(nbOfComp!=a->getNumberOfComponents())
2152 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2153 if(tuplesSelec->getNumberOfComponents()!=1)
2154 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2155 mcIdType thisNt(getNumberOfTuples());
2156 mcIdType aNt(a->getNumberOfTuples());
2157 mcIdType nbOfTupleToWrite(tuplesSelec->getNumberOfTuples());
2158 T *valsToSet(getPointer()+tupleIdStart*nbOfComp);
2159 if(tupleIdStart+nbOfTupleToWrite>thisNt)
2160 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : invalid number range of values to write !");
2161 const T *valsSrc=a->getConstPointer();
2162 for(const mcIdType *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2164 if(*tuple>=0 && *tuple<aNt)
2166 std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2170 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2171 oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2172 throw INTERP_KERNEL::Exception(oss.str().c_str());
2178 * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2179 * of \a this array. Textual data is not copied. Both arrays must have equal number of
2181 * The tuples to copy are defined by three values similar to parameters of
2182 * the Python function \c range(\c start,\c stop,\c step).
2183 * The tuples to assign to are defined by index of the first tuple, and
2184 * their number is defined by number of tuples to copy.
2185 * All components of selected tuples are copied.
2186 * \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2188 * \param [in] aBase - the array to copy values from.
2189 * \param [in] bg - index of the first tuple to copy of the array \a aBase.
2190 * \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2192 * \param [in] step - index increment to get index of the next tuple to copy.
2193 * \throw If \a this is not allocated.
2194 * \throw If \a aBase is NULL.
2195 * \throw If \a aBase is not allocated.
2196 * \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2197 * \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2198 * \throw If parameters specifying tuples to copy, do not give a
2199 * non-empty range of increasing indices or indices are out of a valid range
2200 * for the array \a aBase.
2203 void DataArrayTemplate<T>::setContigPartOfSelectedValuesSlice(mcIdType tupleIdStart, const DataArray *aBase, mcIdType bg, mcIdType end2, mcIdType step)
2207 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::setContigPartOfSelectedValuesSlice : input DataArray is NULL !";
2208 throw INTERP_KERNEL::Exception(oss.str().c_str());
2210 const typename Traits<T>::ArrayType *a(dynamic_cast<const typename Traits<T>::ArrayType *>(aBase));
2212 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValuesSlice : input DataArray aBase is not a DataArrayDouble !");
2214 a->checkAllocated();
2215 std::size_t nbOfComp(getNumberOfComponents());
2216 const char msg[]="DataArrayDouble::setContigPartOfSelectedValuesSlice";
2217 mcIdType nbOfTupleToWrite(DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg));
2218 if(nbOfComp!=a->getNumberOfComponents())
2219 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValuesSlice : This and a do not have the same number of components !");
2220 mcIdType thisNt(getNumberOfTuples());
2221 mcIdType aNt(a->getNumberOfTuples());
2222 T *valsToSet(getPointer()+tupleIdStart*nbOfComp);
2223 if(tupleIdStart+nbOfTupleToWrite>thisNt)
2224 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValuesSlice : invalid number range of values to write !");
2226 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValuesSlice : invalid range of values to read !");
2227 const T *valsSrc(a->getConstPointer()+bg*nbOfComp);
2228 for(mcIdType i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2230 std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2235 * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
2236 * of tuples specified by \a ranges parameter.
2237 * For more info on renumbering see \ref numbering.
2238 * \param [in] ranges - std::vector of std::pair's each of which defines a range
2239 * of tuples in [\c begin,\c end) format.
2240 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2241 * is to delete using decrRef() as it is no more needed.
2242 * \throw If \a end < \a begin.
2243 * \throw If \a end > \a this->getNumberOfTuples().
2244 * \throw If \a this is not allocated.
2247 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleRanges(const std::vector<std::pair<mcIdType,mcIdType> >& ranges) const
2250 std::size_t nbOfComp(getNumberOfComponents());
2251 mcIdType nbOfTuplesThis(getNumberOfTuples());
2254 MCAuto<DataArray> ret0(buildNewEmptyInstance());
2255 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
2256 ret->alloc(0,nbOfComp);
2257 ret->copyStringInfoFrom(*this);
2260 mcIdType ref(ranges.front().first),nbOfTuples(0);
2261 bool isIncreasing(true);
2262 for(std::vector<std::pair<mcIdType,mcIdType> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
2264 if((*it).first<=(*it).second)
2266 if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
2268 nbOfTuples+=(*it).second-(*it).first;
2270 isIncreasing=ref<=(*it).first;
2275 std::ostringstream oss; oss << "DataArrayTemplate::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
2276 oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
2277 throw INTERP_KERNEL::Exception(oss.str().c_str());
2282 std::ostringstream oss; oss << "DataArrayTemplate::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
2283 oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
2284 throw INTERP_KERNEL::Exception(oss.str().c_str());
2287 if(isIncreasing && nbOfTuplesThis==nbOfTuples)
2288 return static_cast<typename Traits<T>::ArrayType *>(deepCopy());
2289 MCAuto<DataArray> ret0(buildNewEmptyInstance());
2290 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
2291 ret->alloc(nbOfTuples,nbOfComp);
2292 ret->copyStringInfoFrom(*this);
2293 const T *src(getConstPointer());
2294 T *work(ret->getPointer());
2295 for(std::vector<std::pair<mcIdType,mcIdType> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
2296 work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
2301 * Returns the first value of \a this.
2302 * \return double - the last value of \a this array.
2303 * \throw If \a this is not allocated.
2304 * \throw If \a this->getNumberOfComponents() != 1.
2305 * \throw If \a this->getNumberOfTuples() < 1.
2308 T DataArrayTemplate<T>::front() const
2311 if(getNumberOfComponents()!=1)
2312 throw INTERP_KERNEL::Exception("DataArrayTemplate::front : number of components not equal to one !");
2313 mcIdType nbOfTuples=getNumberOfTuples();
2315 throw INTERP_KERNEL::Exception("DataArrayTemplate::front : number of tuples must be >= 1 !");
2316 return *(getConstPointer());
2320 * Returns the last value of \a this.
2321 * \return double - the last value of \a this array.
2322 * \throw If \a this is not allocated.
2323 * \throw If \a this->getNumberOfComponents() != 1.
2324 * \throw If \a this->getNumberOfTuples() < 1.
2327 T DataArrayTemplate<T>::back() const
2330 if(getNumberOfComponents()!=1)
2331 throw INTERP_KERNEL::Exception("DataArrayTemplate::back : number of components not equal to one !");
2332 mcIdType nbOfTuples=getNumberOfTuples();
2334 throw INTERP_KERNEL::Exception("DataArrayTemplate::back : number of tuples must be >= 1 !");
2335 return *(getConstPointer()+nbOfTuples-1);
2339 * Returns the maximal value and its location within \a this one-dimensional array.
2340 * \param [out] tupleId - index of the tuple holding the maximal value.
2341 * \return double - the maximal value among all values of \a this array.
2342 * \throw If \a this->getNumberOfComponents() != 1
2343 * \throw If \a this->getNumberOfTuples() < 1
2344 * \sa getMaxAbsValue, getMinValue
2347 T DataArrayTemplate<T>::getMaxValue(mcIdType& tupleId) const
2350 if(getNumberOfComponents()!=1)
2351 throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before or call 'getMaxValueInArray' method !");
2352 mcIdType nbOfTuples=getNumberOfTuples();
2354 throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
2355 const T *vals(getConstPointer());
2356 const T *loc(std::max_element(vals,vals+nbOfTuples));
2357 tupleId=ToIdType(std::distance(vals,loc));
2362 * Returns the maximal value within \a this array that is allowed to have more than
2364 * \return double - the maximal value among all values of \a this array.
2365 * \throw If \a this is not allocated.
2366 * \sa getMaxAbsValueInArray, getMinValueInArray
2369 T DataArrayTemplate<T>::getMaxValueInArray() const
2372 const T *loc(std::max_element(begin(),end()));
2377 * Returns the maximal absolute value in \a this and the first occurrence location associated to it.
2378 * \return the element in this (positive or negative) having the max abs value in \a this.
2379 * \throw If \a this is not allocated.
2380 * \throw If \a this is non one component array.
2381 * \throw If \a this is empty.
2384 T DataArrayTemplate<T>::getMaxAbsValue(std::size_t& tupleId) const
2387 if(getNumberOfComponents()!=1)
2388 throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxAbsValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before or call 'getMaxValueInArray' method !");
2389 mcIdType nbTuples(this->getNumberOfTuples());
2391 throw INTERP_KERNEL::Exception("DataArrayTemplate<T>::getMaxAbsValue : empty array !");
2394 const T *pt(begin());
2395 for(mcIdType i=0;i<nbTuples;i++,pt++)
2397 T cand((T)std::abs(*pt));
2404 return this->getIJ(ToIdType(tupleId),0);
2408 * Returns the maximal absolute value in \a this.
2409 * \throw If \a this is not allocated.
2410 * \throw If \a this is non one component array.
2411 * \throw If \a this is empty.
2414 T DataArrayTemplate<T>::getMaxAbsValueInArray() const
2417 return getMaxAbsValue(dummy);
2421 * Returns the minimal value and its location within \a this one-dimensional array.
2422 * \param [out] tupleId - index of the tuple holding the minimal value.
2423 * \return double - the minimal value among all values of \a this array.
2424 * \throw If \a this->getNumberOfComponents() != 1
2425 * \throw If \a this->getNumberOfTuples() < 1
2428 T DataArrayTemplate<T>::getMinValue(mcIdType& tupleId) const
2431 if(getNumberOfComponents()!=1)
2432 throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
2433 mcIdType nbOfTuples=getNumberOfTuples();
2435 throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
2436 const T *vals(getConstPointer());
2437 const T *loc(std::min_element(vals,vals+nbOfTuples));
2438 tupleId=ToIdType(std::distance(vals,loc));
2443 * Returns the minimal value within \a this array that is allowed to have more than
2445 * \return double - the minimal value among all values of \a this array.
2446 * \throw If \a this is not allocated.
2449 T DataArrayTemplate<T>::getMinValueInArray() const
2452 const T *loc=std::min_element(begin(),end());
2457 void DataArrayTemplate<T>::circularPermutation(mcIdType nbOfShift)
2460 std::size_t nbOfCompo(getNumberOfComponents());
2461 mcIdType nbTuples(getNumberOfTuples());
2462 mcIdType effNbSh(EffectiveCircPerm(nbOfShift,nbTuples));
2465 T *work(getPointer());
2466 if(effNbSh<nbTuples-effNbSh)
2468 typename INTERP_KERNEL::AutoPtr<T> buf(new T[effNbSh*nbOfCompo]);
2469 std::copy(work,work+effNbSh*nbOfCompo,(T *)buf);
2470 std::copy(work+effNbSh*nbOfCompo,work+nbTuples*nbOfCompo,work);// ze big shift
2471 std::copy((T *)buf,(T *)buf+effNbSh*nbOfCompo,work+(nbTuples-effNbSh)*nbOfCompo);
2475 typename INTERP_KERNEL::AutoPtr<T> buf(new T[(nbTuples-effNbSh)*nbOfCompo]);
2476 std::copy(work+effNbSh*nbOfCompo,work+nbTuples*nbOfCompo,(T *)buf);
2477 std::copy(work,work+effNbSh*nbOfCompo,work+(nbTuples-effNbSh)*nbOfCompo);// ze big shift
2478 std::copy((T*)buf,(T *)buf+(nbTuples-effNbSh)*nbOfCompo,work);
2483 void DataArrayTemplate<T>::circularPermutationPerTuple(mcIdType nbOfShift)
2486 std::size_t nbOfCompo(getNumberOfComponents());
2487 mcIdType nbTuples(getNumberOfTuples());
2488 mcIdType effNbSh(EffectiveCircPerm(nbOfShift,ToIdType(nbOfCompo)));
2491 T *work(getPointer());
2492 if(effNbSh<ToIdType(nbOfCompo)-effNbSh)
2494 typename INTERP_KERNEL::AutoPtr<T> buf(new T[effNbSh]);
2495 for(mcIdType i=0;i<nbTuples;i++,work+=nbOfCompo)
2497 std::copy(work,work+effNbSh,(T *)buf);
2498 std::copy(work+effNbSh,work+nbOfCompo,work);// ze big shift
2499 std::copy((T *)buf,(T *)buf+effNbSh,work+(nbOfCompo-effNbSh));
2504 typename INTERP_KERNEL::AutoPtr<T> buf(new T[nbOfCompo-effNbSh]);
2505 for(mcIdType i=0;i<nbTuples;i++,work+=nbOfCompo)
2507 std::copy(work+effNbSh,work+nbOfCompo,(T *)buf);
2508 std::copy(work,work+effNbSh,work+(nbOfCompo-effNbSh));// ze big shift
2509 std::copy((T*)buf,(T *)buf+(nbOfCompo-effNbSh),work);
2512 std::vector<std::string> sts(nbOfCompo);
2513 for(std::size_t i=0;i<nbOfCompo;i++)
2514 sts[i]=_info_on_compo[(i+effNbSh)%nbOfCompo];
2515 setInfoOnComponents(sts);
2519 void DataArrayTemplate<T>::reversePerTuple()
2522 std::size_t nbOfCompo(getNumberOfComponents());
2523 mcIdType nbTuples(getNumberOfTuples());
2526 T *work(getPointer());
2527 for(mcIdType i=0;i<nbTuples;i++,work+=nbOfCompo)
2528 std::reverse(work,work+nbOfCompo);
2529 std::reverse(_info_on_compo.begin(),_info_on_compo.end());
2533 * Assign pointer to one array to a pointer to another appay. Reference counter of
2534 * \a arrayToSet is incremented / decremented.
2535 * \param [in] newArray - the pointer to array to assign to \a arrayToSet.
2536 * \param [in,out] arrayToSet - the pointer to array to assign to.
2539 void DataArrayTemplate<T>::SetArrayIn(typename Traits<T>::ArrayType *newArray, typename Traits<T>::ArrayType* &arrayToSet)
2541 if(newArray!=arrayToSet)
2544 arrayToSet->decrRef();
2545 arrayToSet=newArray;
2547 arrayToSet->incrRef();
2552 * Assign zero to all values in \a this array. To know more on filling arrays see
2553 * \ref MEDCouplingArrayFill.
2554 * \throw If \a this is not allocated.
2557 void DataArrayTemplate<T>::fillWithZero()
2559 fillWithValue((T)0);
2562 //////////////////////////////
2566 // local static function to copy arrays without warnings
2567 template <class TIn, class TOut>
2568 static void copyCast (const TIn *begin, const TIn *end, TOut* dest)
2570 for (const TIn *src = begin; src != end; ++src, ++dest)
2571 *dest=static_cast<TOut>(*src);
2577 MCAuto< typename Traits<U>::ArrayType > DataArrayTemplateClassic<T>::convertToOtherTypeOfArr() const
2579 this->checkAllocated();
2580 MCAuto<typename Traits<U>::ArrayType> ret(Traits<U>::ArrayType::New());
2581 ret->alloc(this->getNumberOfTuples(),this->getNumberOfComponents());
2582 std::size_t nbOfVals(this->getNbOfElems());
2583 const T *src(this->begin());
2584 U *dest(ret->getPointer());
2585 // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
2586 copyCast(src, src+nbOfVals, dest);
2587 //std::copy(src,src+nbOfVals,dest);
2588 ret->copyStringInfoFrom(*this);
2593 * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
2594 * array to the new one.
2595 * \return DataArrayDouble * - the new instance of DataArrayInt.
2598 MCAuto<DataArrayDouble> DataArrayTemplateClassic<T>::convertToDblArr() const
2600 return convertToOtherTypeOfArr<double>();
2604 * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
2605 * array to the new one.
2606 * \return DataArrayInt * - the new instance of DataArrayInt.
2609 MCAuto<DataArrayInt> DataArrayTemplateClassic<T>::convertToIntArr() const
2611 return convertToOtherTypeOfArr<int>();
2615 * Creates a new DataArrayInt64 and assigns all (textual and numerical) data of \a this
2616 * array to the new one.
2617 * \return DataArrayInt * - the new instance of DataArrayInt64.
2620 MCAuto<DataArrayInt64> DataArrayTemplateClassic<T>::convertToInt64Arr() const
2622 return convertToOtherTypeOfArr<Int64>();
2625 * Creates a new DataArrayFloat and assigns all (textual and numerical) data of \a this
2626 * array to the new one.
2627 * \return DataArrayFloat * - the new instance of DataArrayInt.
2630 MCAuto<DataArrayFloat> DataArrayTemplateClassic<T>::convertToFloatArr() const
2632 return convertToOtherTypeOfArr<float>();
2636 * Apply a linear function to a given component of \a this array, so that
2637 * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
2638 * \param [in] a - the first coefficient of the function.
2639 * \param [in] b - the second coefficient of the function.
2640 * \param [in] compoId - the index of component to modify.
2641 * \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
2644 void DataArrayTemplateClassic<T>::applyLin(T a, T b, std::size_t compoId)
2646 this->checkAllocated();
2647 std::size_t nbOfComp=this->getNumberOfComponents();
2648 if(compoId>=nbOfComp)
2650 std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
2651 throw INTERP_KERNEL::Exception(oss.str().c_str());
2653 T *ptr(this->getPointer()+compoId);
2654 mcIdType nbOfTuple=this->getNumberOfTuples();
2655 for(mcIdType i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
2657 this->declareAsNew();
2661 * Apply a linear function to all elements of \a this array, so that
2662 * an element _x_ becomes \f$ a * x + b \f$.
2663 * \param [in] a - the first coefficient of the function.
2664 * \param [in] b - the second coefficient of the function.
2665 * \throw If \a this is not allocated.
2668 void DataArrayTemplateClassic<T>::applyLin(T a, T b)
2670 this->checkAllocated();
2671 T *ptr(this->getPointer());
2672 std::size_t nbOfElems(this->getNbOfElems());
2673 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2675 this->declareAsNew();
2679 * Returns a full copy of \a this array except that sign of all elements is reversed.
2680 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2681 * same number of tuples and component as \a this array.
2682 * The caller is to delete this result array using decrRef() as it is no more
2684 * \throw If \a this is not allocated.
2687 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::negate() const
2689 this->checkAllocated();
2690 MCAuto<typename Traits<T>::ArrayType> newArr(Traits<T>::ArrayType::New());
2691 mcIdType nbOfTuples(this->getNumberOfTuples());
2692 std::size_t nbOfComp(this->getNumberOfComponents());
2693 newArr->alloc(nbOfTuples,nbOfComp);
2694 const T *cptr(this->begin());
2695 std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<T>());
2696 newArr->copyStringInfoFrom(*this);
2697 return newArr.retn();
2702 void DataArrayTemplateClassic<T>::somethingEqual(const typename Traits<T>::ArrayType *other)
2705 throw INTERP_KERNEL::Exception("DataArray<T>::SomethingEqual : input DataArray<T> instance is NULL !");
2706 const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
2707 this->checkAllocated();
2708 other->checkAllocated();
2709 mcIdType nbOfTuple(this->getNumberOfTuples());
2710 mcIdType nbOfTuple2(other->getNumberOfTuples());
2711 std::size_t nbOfComp(this->getNumberOfComponents());
2712 std::size_t nbOfComp2(other->getNumberOfComponents());
2713 if(nbOfTuple==nbOfTuple2)
2715 if(nbOfComp==nbOfComp2)
2717 std::transform(this->begin(),this->end(),other->begin(),this->getPointer(),FCT());
2719 else if(nbOfComp2==1)
2721 T *ptr(this->getPointer());
2722 const T *ptrc(other->begin());
2723 for(mcIdType i=0;i<nbOfTuple;i++)
2724 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind(FCT(),std::placeholders::_1,*ptrc++));
2727 throw INTERP_KERNEL::Exception(msg);
2729 else if(nbOfTuple2==1)
2731 if(nbOfComp2==nbOfComp)
2733 T *ptr(this->getPointer());
2734 const T *ptrc(other->begin());
2735 for(mcIdType i=0;i<nbOfTuple;i++)
2736 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,FCT());
2739 throw INTERP_KERNEL::Exception(msg);
2742 throw INTERP_KERNEL::Exception(msg);
2743 this->declareAsNew();
2747 * Adds values of another DataArrayDouble to values of \a this one. There are 3
2749 * 1. The arrays have same number of tuples and components. Then each value of
2750 * \a other array is added to the corresponding value of \a this array, i.e.:
2751 * _a_ [ i, j ] += _other_ [ i, j ].
2752 * 2. The arrays have same number of tuples and \a other array has one component. Then
2753 * _a_ [ i, j ] += _other_ [ i, 0 ].
2754 * 3. The arrays have same number of components and \a other array has one tuple. Then
2755 * _a_ [ i, j ] += _a2_ [ 0, j ].
2757 * \param [in] other - an array to add to \a this one.
2758 * \throw If \a other is NULL.
2759 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
2760 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
2761 * \a other has number of both tuples and components not equal to 1.
2764 void DataArrayTemplateClassic<T>::addEqual(const typename Traits<T>::ArrayType *other)
2766 this->somethingEqual< std::plus<T> >(other);
2770 * Subtract values of another DataArrayDouble from values of \a this one. There are 3
2772 * 1. The arrays have same number of tuples and components. Then each value of
2773 * \a other array is subtracted from the corresponding value of \a this array, i.e.:
2774 * _a_ [ i, j ] -= _other_ [ i, j ].
2775 * 2. The arrays have same number of tuples and \a other array has one component. Then
2776 * _a_ [ i, j ] -= _other_ [ i, 0 ].
2777 * 3. The arrays have same number of components and \a other array has one tuple. Then
2778 * _a_ [ i, j ] -= _a2_ [ 0, j ].
2780 * \param [in] other - an array to subtract from \a this one.
2781 * \throw If \a other is NULL.
2782 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
2783 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
2784 * \a other has number of both tuples and components not equal to 1.
2787 void DataArrayTemplateClassic<T>::substractEqual(const typename Traits<T>::ArrayType *other)
2789 this->somethingEqual< std::minus<T> >(other);
2793 * Multiply values of another DataArrayDouble to values of \a this one. There are 3
2795 * 1. The arrays have same number of tuples and components. Then each value of
2796 * \a other array is multiplied to the corresponding value of \a this array, i.e.
2797 * _this_ [ i, j ] *= _other_ [ i, j ].
2798 * 2. The arrays have same number of tuples and \a other array has one component. Then
2799 * _this_ [ i, j ] *= _other_ [ i, 0 ].
2800 * 3. The arrays have same number of components and \a other array has one tuple. Then
2801 * _this_ [ i, j ] *= _a2_ [ 0, j ].
2803 * \param [in] other - an array to multiply to \a this one.
2804 * \throw If \a other is NULL.
2805 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
2806 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
2807 * \a other has number of both tuples and components not equal to 1.
2810 void DataArrayTemplateClassic<T>::multiplyEqual(const typename Traits<T>::ArrayType *other)
2812 this->somethingEqual< std::multiplies<T> >(other);
2816 * Divide values of \a this array by values of another DataArrayDouble. There are 3
2818 * 1. The arrays have same number of tuples and components. Then each value of
2819 * \a this array is divided by the corresponding value of \a other one, i.e.:
2820 * _a_ [ i, j ] /= _other_ [ i, j ].
2821 * 2. The arrays have same number of tuples and \a other array has one component. Then
2822 * _a_ [ i, j ] /= _other_ [ i, 0 ].
2823 * 3. The arrays have same number of components and \a other array has one tuple. Then
2824 * _a_ [ i, j ] /= _a2_ [ 0, j ].
2826 * \warning No check of division by zero is performed!
2827 * \param [in] other - an array to divide \a this one by.
2828 * \throw If \a other is NULL.
2829 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
2830 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
2831 * \a other has number of both tuples and components not equal to 1.
2834 void DataArrayTemplateClassic<T>::divideEqual(const typename Traits<T>::ArrayType *other)
2836 this->somethingEqual< std::divides<T> >(other);
2839 template<class T, class FCT>
2840 typename Traits<T>::ArrayType *DivSub(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
2843 throw INTERP_KERNEL::Exception("DivSub : input DataArrayDouble instance is NULL !");
2844 mcIdType nbOfTuple1(a1->getNumberOfTuples());
2845 mcIdType nbOfTuple2(a2->getNumberOfTuples());
2846 std::size_t nbOfComp1(a1->getNumberOfComponents());
2847 std::size_t nbOfComp2(a2->getNumberOfComponents());
2848 if(nbOfTuple2==nbOfTuple1)
2850 if(nbOfComp1==nbOfComp2)
2852 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
2853 ret->alloc(nbOfTuple2,nbOfComp1);
2854 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),FCT());
2855 ret->copyStringInfoFrom(*a1);
2858 else if(nbOfComp2==1)
2860 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
2861 ret->alloc(nbOfTuple1,nbOfComp1);
2862 const T *a2Ptr(a2->begin()),*a1Ptr(a1->begin());
2863 T *res(ret->getPointer());
2864 for(mcIdType i=0;i<nbOfTuple1;i++)
2865 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind(FCT(),std::placeholders::_1,a2Ptr[i]));
2866 ret->copyStringInfoFrom(*a1);
2871 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
2875 else if(nbOfTuple2==1)
2877 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
2878 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
2879 ret->alloc(nbOfTuple1,nbOfComp1);
2880 const T *a1ptr=a1->begin(),*a2ptr(a2->begin());
2881 T *pt(ret->getPointer());
2882 for(mcIdType i=0;i<nbOfTuple1;i++)
2883 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,FCT());
2884 ret->copyStringInfoFrom(*a1);
2889 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
2895 * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
2897 * 1. The arrays have same number of tuples and components. Then each value of
2898 * the result array (_a_) is a subtraction of the corresponding values of \a a1 and
2899 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
2900 * 2. The arrays have same number of tuples and one array, say _a2_, has one
2902 * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
2903 * 3. The arrays have same number of components and one array, say _a2_, has one
2905 * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
2907 * Info on components is copied either from the first array (in the first case) or from
2908 * the array with maximal number of elements (getNbOfElems()).
2909 * \param [in] a1 - an array to subtract from.
2910 * \param [in] a2 - an array to subtract.
2911 * \return DataArrayDouble * - the new instance of DataArrayDouble.
2912 * The caller is to delete this result array using decrRef() as it is no more
2914 * \throw If either \a a1 or \a a2 is NULL.
2915 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
2916 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
2917 * none of them has number of tuples or components equal to 1.
2920 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Substract(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
2922 return DivSub< T,std::minus<T> >(a1,a2);
2926 * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
2928 * 1. The arrays have same number of tuples and components. Then each value of
2929 * the result array (_a_) is a division of the corresponding values of \a a1 and
2930 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
2931 * 2. The arrays have same number of tuples and one array, say _a2_, has one
2933 * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
2934 * 3. The arrays have same number of components and one array, say _a2_, has one
2936 * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
2938 * Info on components is copied either from the first array (in the first case) or from
2939 * the array with maximal number of elements (getNbOfElems()).
2940 * \warning No check of division by zero is performed!
2941 * \param [in] a1 - a numerator array.
2942 * \param [in] a2 - a denominator array.
2943 * \return DataArrayDouble * - the new instance of DataArrayDouble.
2944 * The caller is to delete this result array using decrRef() as it is no more
2946 * \throw If either \a a1 or \a a2 is NULL.
2947 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
2948 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
2949 * none of them has number of tuples or components equal to 1.
2952 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Divide(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
2954 return DivSub< T,std::divides<T> >(a1,a2);
2957 template<class T, class FCT>
2958 typename Traits<T>::ArrayType *MulAdd(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
2961 throw INTERP_KERNEL::Exception("DataArrayDouble::MulAdd : input DataArrayDouble instance is NULL !");
2962 mcIdType nbOfTuple(a1->getNumberOfTuples());
2963 mcIdType nbOfTuple2(a2->getNumberOfTuples());
2964 std::size_t nbOfComp(a1->getNumberOfComponents());
2965 std::size_t nbOfComp2(a2->getNumberOfComponents());
2966 MCAuto<typename Traits<T>::ArrayType> ret=0;
2967 if(nbOfTuple==nbOfTuple2)
2969 if(nbOfComp==nbOfComp2)
2971 ret=Traits<T>::ArrayType::New();
2972 ret->alloc(nbOfTuple,nbOfComp);
2973 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),FCT());
2974 ret->copyStringInfoFrom(*a1);
2978 std::size_t nbOfCompMin,nbOfCompMax;
2979 const typename Traits<T>::ArrayType *aMin, *aMax;
2980 if(nbOfComp>nbOfComp2)
2982 nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
2987 nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
2992 ret=Traits<T>::ArrayType::New();
2993 ret->alloc(nbOfTuple,nbOfCompMax);
2994 const T *aMinPtr(aMin->begin());
2995 const T *aMaxPtr(aMax->begin());
2996 T *res=ret->getPointer();
2997 for(mcIdType i=0;i<nbOfTuple;i++)
2998 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind(FCT(),std::placeholders::_1,aMinPtr[i]));
2999 ret->copyStringInfoFrom(*aMax);
3002 throw INTERP_KERNEL::Exception("Nb of components mismatch for array MulAdd !");
3005 else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
3007 if(nbOfComp==nbOfComp2)
3009 mcIdType nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
3010 const typename Traits<T>::ArrayType *aMin(nbOfTuple>nbOfTuple2?a2:a1);
3011 const typename Traits<T>::ArrayType *aMax(nbOfTuple>nbOfTuple2?a1:a2);
3012 const T *aMinPtr(aMin->begin()),*aMaxPtr(aMax->begin());
3013 ret=Traits<T>::ArrayType::New();
3014 ret->alloc(nbOfTupleMax,nbOfComp);
3015 T *res(ret->getPointer());
3016 for(mcIdType i=0;i<nbOfTupleMax;i++)
3017 res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,FCT());
3018 ret->copyStringInfoFrom(*aMax);
3021 throw INTERP_KERNEL::Exception("Nb of components mismatch for array MulAdd !");
3024 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array MulAdd !");
3029 * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
3031 * 1. The arrays have same number of tuples and components. Then each value of
3032 * the result array (_a_) is a product of the corresponding values of \a a1 and
3033 * \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
3034 * 2. The arrays have same number of tuples and one array, say _a2_, has one
3036 * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
3037 * 3. The arrays have same number of components and one array, say _a2_, has one
3039 * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
3041 * Info on components is copied either from the first array (in the first case) or from
3042 * the array with maximal number of elements (getNbOfElems()).
3043 * \param [in] a1 - a factor array.
3044 * \param [in] a2 - another factor array.
3045 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3046 * The caller is to delete this result array using decrRef() as it is no more
3048 * \throw If either \a a1 or \a a2 is NULL.
3049 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3050 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3051 * none of them has number of tuples or components equal to 1.
3054 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Multiply(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
3056 return MulAdd< T , std::multiplies<T> >(a1,a2);
3060 * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
3062 * 1. The arrays have same number of tuples and components. Then each value of
3063 * the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
3064 * i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
3065 * 2. The arrays have same number of tuples and one array, say _a2_, has one
3067 * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
3068 * 3. The arrays have same number of components and one array, say _a2_, has one
3070 * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
3072 * Info on components is copied either from the first array (in the first case) or from
3073 * the array with maximal number of elements (getNbOfElems()).
3074 * \param [in] a1 - an array to sum up.
3075 * \param [in] a2 - another array to sum up.
3076 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3077 * The caller is to delete this result array using decrRef() as it is no more
3079 * \throw If either \a a1 or \a a2 is NULL.
3080 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3081 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3082 * none of them has number of tuples or components equal to 1.
3085 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Add(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
3087 return MulAdd< T , std::plus<T> >(a1,a2);
3091 * Returns either a \a deep or \a shallow copy of this array. For more info see
3092 * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
3093 * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
3094 * \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
3095 * == \a true) or \a this instance (if \a dCpy == \a false).
3098 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::PerformCopyOrIncrRef(bool dCpy, const typename Traits<T>::ArrayType& self)
3101 return self.deepCopy();
3105 return const_cast<typename Traits<T>::ArrayType *>(&self);
3112 GreatEqual(T v):_v(v) { }
3113 bool operator()(T v) const { return v>=_v; }
3120 GreaterThan(T v):_v(v) { }
3121 bool operator()(T v) const { return v>_v; }
3128 LowerEqual(T v):_v(v) { }
3129 bool operator()(T v) const { return v<=_v; }
3136 LowerThan(T v):_v(v) { }
3137 bool operator()(T v) const { return v<_v; }
3144 InRange(T a, T b):_a(a),_b(b) { }
3145 bool operator()(T v) const { return v>=_a && v<_b; }
3152 NotInRange(T a, T b):_a(a),_b(b) { }
3153 bool operator()(T v) const { return v<_a || v>=_b; }
3158 * This method works only on data array with one component. This method returns a newly allocated array storing stored ascendantly of tuple ids in \a this so that this[id]<0.
3160 * \return a newly allocated data array that the caller should deal with.
3161 * \sa DataArrayInt::findIdsInRange
3164 DataArrayIdType *DataArrayTemplateClassic<T>::findIdsStrictlyNegative() const
3166 LowerThan<T> lt((T)0);
3167 MCAuto<DataArrayIdType> ret(findIdsAdv(lt));
3172 MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsGreaterOrEqualTo(T val) const
3174 GreatEqual<T> ge(val);
3175 return findIdsAdv(ge);
3179 MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsGreaterThan(T val) const
3181 GreaterThan<T> gt(val);
3182 return findIdsAdv(gt);
3186 MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsLowerOrEqualTo(T val) const
3188 LowerEqual<T> le(val);
3189 return findIdsAdv(le);
3193 MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsLowerThan(T val) const
3195 LowerThan<T> lt(val);
3196 return findIdsAdv(lt);
3200 * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
3201 * of components in the result array is a sum of the number of components of given arrays
3202 * and (2) the number of tuples in the result array is same as that of each of given
3203 * arrays. In other words the i-th tuple of result array includes all components of
3204 * i-th tuples of all given arrays.
3205 * Number of tuples in the given arrays must be the same.
3206 * \param [in] a1 - an array to include in the result array.
3207 * \param [in] a2 - another array to include in the result array.
3208 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3209 * The caller is to delete this result array using decrRef() as it is no more
3211 * \throw If both \a a1 and \a a2 are NULL.
3212 * \throw If any given array is not allocated.
3213 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3216 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Meld(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
3218 std::vector<const typename Traits<T>::ArrayType *> arr(2);
3219 arr[0]=a1; arr[1]=a2;
3224 * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
3225 * of components in the result array is a sum of the number of components of given arrays
3226 * and (2) the number of tuples in the result array is same as that of each of given
3227 * arrays. In other words the i-th tuple of result array includes all components of
3228 * i-th tuples of all given arrays.
3229 * Number of tuples in the given arrays must be the same.
3230 * \param [in] arr - a sequence of arrays to include in the result array.
3231 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3232 * The caller is to delete this result array using decrRef() as it is no more
3234 * \throw If all arrays within \a arr are NULL.
3235 * \throw If any given array is not allocated.
3236 * \throw If getNumberOfTuples() of arrays within \a arr is different.
3239 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Meld(const std::vector<const typename Traits<T>::ArrayType *>& arr)
3241 std::vector<const typename Traits<T>::ArrayType *> a;
3242 for(typename std::vector<const typename Traits<T>::ArrayType *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3246 throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
3247 typename std::vector<const typename Traits<T>::ArrayType *>::const_iterator it;
3248 for(it=a.begin();it!=a.end();it++)
3249 (*it)->checkAllocated();
3251 mcIdType nbOfTuples((*it)->getNumberOfTuples());
3252 std::vector<std::size_t> nbc(a.size());
3253 std::vector<const T *> pts(a.size());
3254 nbc[0]=(*it)->getNumberOfComponents();
3255 pts[0]=(*it++)->getConstPointer();
3256 for(mcIdType i=1;it!=a.end();it++,i++)
3258 if(nbOfTuples!=(*it)->getNumberOfTuples())
3259 throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
3260 nbc[i]=(*it)->getNumberOfComponents();
3261 pts[i]=(*it)->getConstPointer();
3263 std::size_t totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),(std::size_t)0);
3264 typename Traits<T>::ArrayType *ret(Traits<T>::ArrayType::New());
3265 ret->alloc(nbOfTuples,totalNbOfComp);
3266 T *retPtr(ret->getPointer());
3267 for(mcIdType i=0;i<nbOfTuples;i++)
3268 for(std::size_t j=0;j<a.size();j++)
3270 retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
3274 for(std::size_t i=0;i<a.size();i++)
3275 for(std::size_t j=0;j<nbc[i];j++,k++)
3276 ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
3281 * Returns a new DataArrayDouble holding the same values as \a this array but differently
3282 * arranged in memory. If \a this array holds 2 components of 3 values:
3283 * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
3284 * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
3285 * \warning Do not confuse this method with transpose()!
3286 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
3287 * is to delete using decrRef() as it is no more needed.
3288 * \throw If \a this is not allocated.
3291 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::fromNoInterlace() const
3293 if(this->_mem.isNull())
3294 throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
3295 T *tab(this->_mem.fromNoInterlace(this->getNumberOfComponents()));
3296 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
3297 ret->useArray(tab,true,DeallocType::C_DEALLOC,this->getNumberOfTuples(),this->getNumberOfComponents());
3302 * Returns a new DataArrayDouble holding the same values as \a this array but differently
3303 * arranged in memory. If \a this array holds 2 components of 3 values:
3304 * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
3305 * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
3306 * \warning Do not confuse this method with transpose()!
3307 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
3308 * is to delete using decrRef() as it is no more needed.
3309 * \throw If \a this is not allocated.
3312 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::toNoInterlace() const
3314 if(this->_mem.isNull())
3315 throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
3316 T *tab(this->_mem.toNoInterlace(this->getNumberOfComponents()));
3317 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
3318 ret->useArray(tab,true,DeallocType::C_DEALLOC,this->getNumberOfTuples(),this->getNumberOfComponents());
3323 * Appends components of another array to components of \a this one, tuple by tuple.
3324 * So that the number of tuples of \a this array remains the same and the number of
3325 * components increases.
3326 * \param [in] other - the DataArrayDouble to append to \a this one.
3327 * \throw If \a this is not allocated.
3328 * \throw If \a this and \a other arrays have different number of tuples.
3330 * \if ENABLE_EXAMPLES
3331 * \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
3333 * \ref py_mcdataarraydouble_meldwith "Here is a Python example".
3337 void DataArrayTemplateClassic<T>::meldWith(const typename Traits<T>::ArrayType *other)
3339 this->checkAllocated();
3340 other->checkAllocated();
3341 mcIdType nbOfTuples(this->getNumberOfTuples());
3342 if(nbOfTuples!=other->getNumberOfTuples())
3343 throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
3344 std::size_t nbOfComp1=this->getNumberOfComponents();
3345 std::size_t nbOfComp2=other->getNumberOfComponents();
3346 T *newArr=(T *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(T));
3348 const T *inp1(this->begin()),*inp2(other->begin());
3349 for(mcIdType i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
3351 w=std::copy(inp1,inp1+nbOfComp1,w);
3352 w=std::copy(inp2,inp2+nbOfComp2,w);
3354 this->useArray(newArr,true,DeallocType::C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
3355 std::vector<std::size_t> compIds(nbOfComp2);
3356 for(std::size_t i=0;i<nbOfComp2;i++)
3357 compIds[i]=nbOfComp1+i;
3358 this->copyPartOfStringInfoFrom2(compIds,*other);
3363 * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
3364 * \a nbTimes should be at least equal to 1.
3365 * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
3366 * \throw if \a this is not allocated or if \a this has not number of components set to one or if \a nbTimes is lower than 1.
3369 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::duplicateEachTupleNTimes(mcIdType nbTimes) const
3371 this->checkAllocated();
3372 if(this->getNumberOfComponents()!=1)
3373 throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
3375 throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
3376 mcIdType nbTuples=this->getNumberOfTuples();
3377 const T *inPtr(this->begin());
3378 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New()); ret->alloc(nbTimes*nbTuples,1);
3379 T *retPtr(ret->getPointer());
3380 for(mcIdType i=0;i<nbTuples;i++,inPtr++)
3383 for(mcIdType j=0;j<nbTimes;j++,retPtr++)
3386 ret->copyStringInfoFrom(*this);
3391 void DataArrayTemplateClassic<T>::aggregate(const typename Traits<T>::ArrayType *other)
3394 throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !");
3395 if(this->getNumberOfComponents()!=other->getNumberOfComponents())
3396 throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !");
3397 this->_mem.insertAtTheEnd(other->begin(),other->end());
3401 * Converts every value of \a this array to its absolute value.
3402 * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
3403 * should be called instead.
3405 * \throw If \a this is not allocated.
3406 * \sa DataArrayDouble::computeAbs
3409 void DataArrayTemplateClassic<T>::abs()
3411 this->checkAllocated();
3412 T *ptr(this->getPointer());
3413 std::size_t nbOfElems(this->getNbOfElems());
3414 std::transform(ptr,ptr+nbOfElems,ptr,[](T c){return std::abs(c);});
3415 this->declareAsNew();
3419 * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
3420 * This method is a const method (that do not change any values in \a this) contrary to DataArrayDouble::abs method.
3422 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3423 * same number of tuples and component as \a this array.
3424 * The caller is to delete this result array using decrRef() as it is no more
3426 * \throw If \a this is not allocated.
3427 * \sa DataArrayDouble::abs
3430 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::computeAbs() const
3432 this->checkAllocated();
3433 MCAuto<typename Traits<T>::ArrayType> newArr(Traits<T>::ArrayType::New());
3434 mcIdType nbOfTuples(this->getNumberOfTuples());
3435 std::size_t nbOfComp(this->getNumberOfComponents());
3436 newArr->alloc(nbOfTuples,nbOfComp);
3437 std::transform(this->begin(),this->end(),newArr->getPointer(),[](T c){return std::abs(c);});
3438 newArr->copyStringInfoFrom(*this);
3439 return newArr.retn();
3443 * Returns either a \a deep or \a shallow copy of this array. For more info see
3444 * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
3445 * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
3446 * \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
3447 * == \a true) or \a this instance (if \a dCpy == \a false).
3450 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::performCopyOrIncrRef(bool dCpy) const
3452 const typename Traits<T>::ArrayType *thisC(static_cast<const typename Traits<T>::ArrayType *>(this));
3453 return DataArrayTemplateClassic<T>::PerformCopyOrIncrRef(dCpy,*thisC);
3457 * Computes for each tuple the sum of number of components values in the tuple and return it.
3459 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3460 * same number of tuples as \a this array and one component.
3461 * The caller is to delete this result array using decrRef() as it is no more
3463 * \throw If \a this is not allocated.
3466 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::sumPerTuple() const
3468 this->checkAllocated();
3469 std::size_t nbOfComp(this->getNumberOfComponents());
3470 mcIdType nbOfTuple(this->getNumberOfTuples());
3471 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
3472 ret->alloc(nbOfTuple,1);
3473 const T *src(this->begin());
3474 T *dest(ret->getPointer());
3475 for(mcIdType i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3476 *dest=std::accumulate(src,src+nbOfComp,(T)0);
3481 * Set all values in \a this array so that the i-th element equals to \a init + i
3482 * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
3483 * \param [in] init - value to assign to the first element of array.
3484 * \throw If \a this->getNumberOfComponents() != 1
3485 * \throw If \a this is not allocated.
3488 void DataArrayTemplateClassic<T>::iota(T init)
3490 this->checkAllocated();
3491 if(this->getNumberOfComponents()!=1)
3492 throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
3493 T *ptr(this->getPointer());
3494 mcIdType ntuples(this->getNumberOfTuples());
3495 for(mcIdType i=0;i<ntuples;i++)
3497 this->declareAsNew();
3501 struct ImplReprTraits { static void SetPrecision(std::ostream& oss) { } };
3504 struct ImplReprTraits<double> { static void SetPrecision(std::ostream& oss) { oss.precision(17); } };
3507 struct ImplReprTraits<float> { static void SetPrecision(std::ostream& oss) { oss.precision(7); } };
3510 void DataArrayTemplateClassic<T>::reprStream(std::ostream& stream) const
3512 stream << "Name of " << Traits<T>::ReprStr << " array : \"" << this->_name << "\"\n";
3513 reprWithoutNameStream(stream);
3517 void DataArrayTemplateClassic<T>::reprZipStream(std::ostream& stream) const
3519 stream << "Name of " << Traits<T>::ReprStr << " array : \"" << this->_name << "\"\n";
3520 reprZipWithoutNameStream(stream);
3524 void DataArrayTemplateClassic<T>::reprNotTooLongStream(std::ostream& stream) const
3526 stream << "Name of "<< Traits<T>::ReprStr << " array : \"" << this->_name << "\"\n";
3527 reprNotTooLongWithoutNameStream(stream);
3531 void DataArrayTemplateClassic<T>::reprWithoutNameStream(std::ostream& stream) const
3533 DataArray::reprWithoutNameStream(stream);
3534 ImplReprTraits<T>::SetPrecision(stream);
3535 this->_mem.repr(ToIdType(this->getNumberOfComponents()),stream);
3539 void DataArrayTemplateClassic<T>::reprZipWithoutNameStream(std::ostream& stream) const
3541 DataArray::reprWithoutNameStream(stream);
3542 ImplReprTraits<T>::SetPrecision(stream);
3543 this->_mem.reprZip(ToIdType(this->getNumberOfComponents()),stream);
3547 void DataArrayTemplateClassic<T>::reprNotTooLongWithoutNameStream(std::ostream& stream) const
3549 DataArray::reprWithoutNameStream(stream);
3550 ImplReprTraits<T>::SetPrecision(stream);
3551 this->_mem.reprNotTooLong(ToIdType(this->getNumberOfComponents()),stream);
3555 * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
3556 * printed out to avoid to consume too much space in interpretor.
3560 std::string DataArrayTemplateClassic<T>::reprNotTooLong() const
3562 std::ostringstream ret;
3563 reprNotTooLongStream(ret);
3568 * Returns a textual and human readable representation of \a this instance of
3569 * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
3570 * \return std::string - text describing \a this DataArrayInt.
3572 * \sa reprNotTooLong, reprZip
3575 std::string DataArrayTemplateClassic<T>::repr() const
3577 std::ostringstream ret;
3578 DataArrayTemplateClassic<T>::reprStream(ret);
3583 std::string DataArrayTemplateClassic<T>::reprZip() const
3585 std::ostringstream ret;
3586 DataArrayTemplateClassic<T>::reprZipStream(ret);
3590 /////////////////////////////////
3593 * Checks if all values in \a this array are equal to \a val at precision \a eps.
3594 * \param [in] val - value to check equality of array values to.
3595 * \param [in] eps - precision to check the equality.
3596 * \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
3598 * \throw If \a this->getNumberOfComponents() != 1
3599 * \throw If \a this is not allocated.
3602 bool DataArrayTemplateFP<T>::isUniform(T val, T eps) const
3604 this->checkAllocated();
3605 if(this->getNumberOfComponents()!=1)
3606 throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3607 const T *w(this->begin()),*end2(this->end());
3608 const T vmin(val-eps),vmax(val+eps);
3610 if(*w<vmin || *w>vmax)
3615 /////////////////////////////////
3618 * Returns the only one value in \a this, if and only if number of elements
3619 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3620 * \return double - the sole value stored in \a this array.
3621 * \throw If at least one of conditions stated above is not fulfilled.
3624 T DataArrayDiscrete<T>::intValue() const
3626 if(this->isAllocated())
3628 if(this->getNbOfElems()==1)
3630 return *this->getConstPointer();
3633 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3636 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3640 * Equivalent to DataArrayInt::isEqual except that if false the reason of
3641 * mismatch is given.
3643 * \param [in] other the instance to be compared with \a this
3644 * \param [out] reason In case of inequality returns the reason.
3645 * \sa DataArrayInt::isEqual
3648 bool DataArrayDiscrete<T>::isEqualIfNotWhy(const DataArrayDiscrete<T>& other, std::string& reason) const
3650 if(!this->areInfoEqualsIfNotWhy(other,reason))
3652 return this->_mem.isEqual(other._mem,0,reason);
3656 * Checks if \a this and another DataArrayInt are fully equal. For more info see
3657 * \ref MEDCouplingArrayBasicsCompare.
3658 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
3659 * \return bool - \a true if the two arrays are equal, \a false else.
3662 bool DataArrayDiscrete<T>::isEqual(const DataArrayDiscrete<T>& other) const
3665 return isEqualIfNotWhy(other,tmp);
3669 * Returns a new instance of DataArrayInt. The caller is to delete this array
3670 * using decrRef() as it is no more needed.
3673 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::New()
3675 return new typename Traits<T>::ArrayType;
3679 * Checks if values of \a this and another DataArrayInt are equal. For more info see
3680 * \ref MEDCouplingArrayBasicsCompare.
3681 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
3682 * \return bool - \a true if the values of two arrays are equal, \a false else.
3685 bool DataArrayDiscrete<T>::isEqualWithoutConsideringStr(const DataArrayDiscrete<T>& other) const
3688 return this->_mem.isEqual(other._mem,0,tmp);
3692 * Checks if values of \a this and another DataArrayInt are equal. Comparison is
3693 * performed on sorted value sequences.
3694 * For more info see\ref MEDCouplingArrayBasicsCompare.
3695 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
3696 * \return bool - \a true if the sorted values of two arrays are equal, \a false else.
3699 bool DataArrayDiscrete<T>::isEqualWithoutConsideringStrAndOrder(const typename Traits<T>::ArrayType& other) const
3701 MCAuto<typename Traits<T>::ArrayType> a((static_cast<const typename Traits<T>::ArrayType *>(this))->deepCopy());
3702 MCAuto<typename Traits<T>::ArrayType> b((static_cast<const typename Traits<T>::ArrayType *>(&other))->deepCopy());
3705 return a->isEqualWithoutConsideringStr(*b);
3710 void DataArrayDiscrete<T>::switchOnTupleAlg(T val, std::vector<bool>& vec, ALG algo) const
3712 this->checkAllocated();
3713 if(this->getNumberOfComponents()!=1)
3714 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
3715 mcIdType nbOfTuples(this->getNumberOfTuples());
3716 if(nbOfTuples!=ToIdType(vec.size()))
3717 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
3718 const T *pt(this->begin());
3719 for(mcIdType i=0;i<nbOfTuples;i++)
3725 * 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
3726 * put True to the corresponding entry in \a vec.
3727 * \a vec is expected to be with the same size than the number of tuples of \a this.
3729 * \sa DataArrayInt::switchOnTupleNotEqualTo.
3732 void DataArrayDiscrete<T>::switchOnTupleEqualTo(T val, std::vector<bool>& vec) const
3734 switchOnTupleAlg(val,vec,std::equal_to<T>());
3738 * 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
3739 * put True to the corresponding entry in \a vec.
3740 * \a vec is expected to be with the same size than the number of tuples of \a this.
3742 * \sa DataArrayInt::switchOnTupleEqualTo.
3745 void DataArrayDiscrete<T>::switchOnTupleNotEqualTo(T val, std::vector<bool>& vec) const
3747 switchOnTupleAlg(val,vec,std::not_equal_to<T>());
3751 * 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
3752 * appearing several times. If each element in \a this appears once an 1 component array containing only 0 will be returned.
3755 * - \a this : [5, 3, 2, 1, 4, 5, 2, 1, 0, 11, 5, 4]
3756 * - \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.
3758 * \return DataArrayInt * - a new instance of DataArrayInt with same number of tuples than \a this. The caller is to delete this
3759 * array using decrRef() as it is no more needed.
3760 * \throw If either this not allocated or not with one component.
3762 * \sa DataArrayInt::FindPermutationFromFirstToSecond
3765 DataArrayIdType *DataArrayDiscrete<T>::occurenceRankInThis() const
3767 constexpr char MSG0[] = "occurenceRankInThis :";
3768 this->checkAllocated();
3769 this->checkNbOfComps(1,MSG0);
3770 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
3771 ret->alloc(this->getNumberOfTuples(),1);
3772 mcIdType *retPtr(ret->getPointer());
3773 std::map<T,mcIdType> m;
3774 for(const T *pt = this->begin() ; pt != this->end() ; ++pt, ++retPtr )
3776 auto it = m.find(*pt);
3784 *retPtr = (*it).second++;
3791 * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
3792 * one-dimensional arrays that must be of the same length. The result array describes
3793 * correspondence between \a this and \a other arrays, so that
3794 * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
3795 * not possible because some element in \a other is not in \a this, an exception is thrown.
3796 * \param [in] other - an array to compute permutation to.
3797 * \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
3798 * from \a this to \a other. The caller is to delete this array using decrRef() as it is
3800 * \throw If \a this->getNumberOfComponents() != 1.
3801 * \throw If \a other->getNumberOfComponents() != 1.
3802 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
3803 * \throw If \a other includes a value which is not in \a this array.
3805 * \if ENABLE_EXAMPLES
3806 * \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
3808 * \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
3812 DataArrayIdType *DataArrayDiscrete<T>::buildPermutationArr(const DataArrayDiscrete<T>& other) const
3814 this->checkAllocated();
3815 if(this->getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
3816 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
3817 mcIdType nbTuple(this->getNumberOfTuples());
3818 other.checkAllocated();
3819 if(nbTuple!=other.getNumberOfTuples())
3820 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
3821 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
3822 ret->alloc(nbTuple,1);
3823 ret->fillWithValue(-1);
3824 const T *pt(this->begin());
3825 std::map<mcIdType,mcIdType> mm;
3826 for(mcIdType i=0;i<nbTuple;i++)
3827 mm[ToIdType(pt[i])]=i;
3829 mcIdType *retToFill(ret->getPointer());
3830 for(mcIdType i=0;i<nbTuple;i++)
3832 std::map<mcIdType,mcIdType>::const_iterator it=mm.find(ToIdType(pt[i]));
3835 std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
3836 throw INTERP_KERNEL::Exception(oss.str().c_str());
3838 retToFill[i]=(*it).second;
3844 * Elements of \a partOfThis are expected to be included in \a this.
3845 * The returned array \a ret is so that this[ret]==partOfThis
3847 * For example, if \a this array contents are [9,10,0,6,4,11,3,8] and if \a partOfThis contains [6,0,11,8]
3848 * the return array will contain [3,2,5,7].
3850 * \a this is expected to be a 1 compo allocated array.
3851 * \param [in] partOfThis - A 1 compo allocated array
3852 * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis.
3853 * \throw if two same element is present twice in \a this
3854 * \throw if an element in \a partOfThis is \b NOT in \a this.
3857 DataArrayIdType *DataArrayDiscrete<T>::indicesOfSubPart(const DataArrayDiscrete<T>& partOfThis) const
3859 if(this->getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1)
3860 throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !");
3861 this->checkAllocated(); partOfThis.checkAllocated();
3862 mcIdType thisNbTuples(this->getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples());
3863 const T *thisPt(this->begin()),*pt(partOfThis.begin());
3864 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
3865 ret->alloc(nbTuples,1);
3866 mcIdType *retPt(ret->getPointer());
3867 std::map<mcIdType,mcIdType> m;
3868 for(mcIdType i=0;i<thisNbTuples;i++,thisPt++)
3869 m[ToIdType(*thisPt)]=i;
3870 if(ToIdType(m.size())!=thisNbTuples)
3871 throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : some elements appears more than once !");
3872 for(mcIdType i=0;i<nbTuples;i++,retPt++,pt++)
3874 std::map<mcIdType,mcIdType>::const_iterator it(m.find(ToIdType(*pt)));
3876 *retPt=(*it).second;
3879 std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !";
3880 throw INTERP_KERNEL::Exception(oss.str());
3887 * Checks that \a this array is consistently **increasing** or **decreasing** in value.
3888 * If not an exception is thrown.
3889 * \param [in] increasing - if \a true, the array values should be increasing.
3890 * \throw If sequence of values is not strictly monotonic in agreement with \a
3892 * \throw If \a this->getNumberOfComponents() != 1.
3893 * \throw If \a this is not allocated.
3896 void DataArrayDiscrete<T>::checkMonotonic(bool increasing) const
3898 if(!isMonotonic(increasing))
3901 throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
3903 throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
3908 * Checks that \a this array is consistently **increasing** or **decreasing** in value.
3909 * \param [in] increasing - if \a true, array values should be increasing.
3910 * \return bool - \a true if values change in accordance with \a increasing arg.
3911 * \throw If \a this->getNumberOfComponents() != 1.
3912 * \throw If \a this is not allocated.
3915 bool DataArrayDiscrete<T>::isMonotonic(bool increasing) const
3917 this->checkAllocated();
3918 if(this->getNumberOfComponents()!=1)
3919 throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
3920 std::size_t nbOfElements(this->getNumberOfTuples());
3921 const T *ptr(this->begin());
3927 for(std::size_t i=1;i<nbOfElements;i++)
3937 for(std::size_t i=1;i<nbOfElements;i++)
3949 * This method check that array consistently INCREASING or DECREASING in value.
3952 bool DataArrayDiscrete<T>::isStrictlyMonotonic(bool increasing) const
3954 this->checkAllocated();
3955 if(this->getNumberOfComponents()!=1)
3956 throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
3957 std::size_t nbOfElements(this->getNumberOfTuples());
3958 const T *ptr(this->begin());
3964 for(std::size_t i=1;i<nbOfElements;i++)
3974 for(std::size_t i=1;i<nbOfElements;i++)
3986 * This method check that array consistently INCREASING or DECREASING in value.
3989 void DataArrayDiscrete<T>::checkStrictlyMonotonic(bool increasing) const
3991 if(!isStrictlyMonotonic(increasing))
3994 throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
3996 throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
4001 * Returns an integer value characterizing \a this array, which is useful for a quick
4002 * comparison of many instances of DataArrayInt.
4003 * \return mcIdType - the hash value.
4004 * \throw If \a this is not allocated.
4007 mcIdType DataArrayDiscrete<T>::getHashCode() const
4009 this->checkAllocated();
4010 mcIdType nbOfElems=ToIdType(this->getNbOfElems());
4011 mcIdType ret=nbOfElems*65536;
4016 const T *pt(this->begin());
4017 for(mcIdType i=0;i<nbOfElems;i+=delta)
4018 ret0+=pt[i] & 0x1FFF;
4019 return ToIdType(ret+ret0);
4023 void DataArrayDiscrete<T>::reprCppStream(const std::string& varName, std::ostream& stream) const
4025 mcIdType nbTuples(this->getNumberOfTuples());
4026 std::size_t nbComp(this->getNumberOfComponents());
4027 const T *data(this->getConstPointer());
4028 stream << Traits<T>::ArrayTypeName << " *" << varName << "=" << Traits<T>::ArrayTypeName << "::New();" << std::endl;
4029 if(nbTuples*nbComp>=1)
4031 stream << "const mcIdType " << varName << "Data[" << nbTuples*nbComp << "]={";
4032 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<T>(stream,","));
4033 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
4034 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
4037 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
4038 stream << varName << "->setName(\"" << this->getName() << "\");" << std::endl;
4042 * Method that gives a quick overvien of \a this for python.
4045 void DataArrayDiscrete<T>::reprQuickOverview(std::ostream& stream) const
4047 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
4048 stream << Traits<T>::ArrayTypeName << " C++ instance at " << this << ". ";
4049 if(this->isAllocated())
4051 std::size_t nbOfCompo(this->getNumberOfComponents());
4054 mcIdType nbOfTuples(this->getNumberOfTuples());
4055 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
4056 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
4059 stream << "Number of components : 0.";
4062 stream << "*** No data allocated ****";
4066 void DataArrayDiscrete<T>::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
4068 const T *data(this->begin());
4069 mcIdType nbOfTuples(this->getNumberOfTuples());
4070 std::size_t nbOfCompo(this->getNumberOfComponents());
4071 std::ostringstream oss2; oss2 << "[";
4072 std::string oss2Str(oss2.str());
4073 bool isFinished=true;
4074 for(mcIdType i=0;i<nbOfTuples && isFinished;i++)
4079 for(std::size_t j=0;j<nbOfCompo;j++,data++)
4082 if(j!=nbOfCompo-1) oss2 << ", ";
4088 if(i!=nbOfTuples-1) oss2 << ", ";
4089 std::string oss3Str(oss2.str());
4090 if(oss3Str.length()<maxNbOfByteInRepr)
4102 void DataArrayDiscrete<T>::writeVTK(std::ostream& ofs, mcIdType indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
4104 static const char SPACE[4]={' ',' ',' ',' '};
4105 this->checkAllocated();
4106 std::string idt(indent,' ');
4107 ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << this->getNumberOfComponents() << "\"";
4110 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
4111 if(std::string(type)==Traits<T>::VTKReprStr)
4113 const char *data(reinterpret_cast<const char *>(this->begin()));
4114 std::size_t sz(this->getNbOfElems()*sizeof(T));
4115 byteArr->insertAtTheEnd(data,data+sz);
4116 byteArr->insertAtTheEnd(SPACE,SPACE+4);
4118 else if(std::string(type)=="Int8")
4120 INTERP_KERNEL::AutoPtr<char> tmp(new char[this->getNbOfElems()]);
4121 copyCast(this->begin(),this->end(),(char *)tmp);
4122 byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+this->getNbOfElems());
4123 byteArr->insertAtTheEnd(SPACE,SPACE+4);
4125 else if(std::string(type)=="UInt8")
4127 INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[this->getNbOfElems()]);
4128 copyCast(this->begin(),this->end(),(unsigned char *)tmp);
4129 byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+this->getNbOfElems());
4130 byteArr->insertAtTheEnd(SPACE,SPACE+4);
4134 std::ostringstream oss;
4135 oss << Traits<T>::ArrayTypeName << "::writeVTK : Only " << Traits<T>::VTKReprStr << ", Int8 and UInt8 supported !";
4136 throw INTERP_KERNEL::Exception(oss.str());
4141 ofs << " RangeMin=\"" << this->getMinValueInArray() << "\" RangeMax=\"" << this->getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
4142 std::copy(this->begin(),this->end(),std::ostream_iterator<T>(ofs," "));
4144 ofs << std::endl << idt << "</DataArray>\n";
4148 * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4149 * i.e. a current value is used as in index to get a new value from \a indArrBg.
4150 * \param [in] indArrBg - pointer to the first element of array of new values to assign
4152 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4153 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4154 * \throw If \a this->getNumberOfComponents() != 1
4155 * \throw If any value of \a this can't be used as a valid index for
4156 * [\a indArrBg, \a indArrEnd).
4158 * \sa changeValue, findIdForEach
4161 void DataArrayDiscrete<T>::transformWithIndArr(const T *indArrBg, const T *indArrEnd)
4163 this->checkAllocated();
4164 if(this->getNumberOfComponents()!=1)
4165 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4166 mcIdType nbElemsIn=ToIdType(std::distance(indArrBg,indArrEnd));
4167 mcIdType nbOfTuples(this->getNumberOfTuples());
4168 T *pt(this->getPointer());
4169 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
4171 if(*pt>=0 && *pt<nbElemsIn)
4175 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4176 throw INTERP_KERNEL::Exception(oss.str());
4179 this->declareAsNew();
4183 void DataArrayDiscrete<T>::transformWithIndArr(const MapKeyVal<T, T>& m)
4185 this->checkAllocated();
4186 if(this->getNumberOfComponents()!=1)
4187 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4188 const typename std::map<T,T>& dat(m.data());
4189 mcIdType nbOfTuples(this->getNumberOfTuples());
4190 T *pt(this->getPointer());
4191 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
4193 typename std::map<T,T>::const_iterator it(dat.find(*pt));
4198 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !";
4199 throw INTERP_KERNEL::Exception(oss.str());
4202 this->declareAsNew();
4206 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
4207 * given one. The ids are sorted in the ascending order.
4208 * \param [in] val - the value to find within \a this.
4209 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4210 * array using decrRef() as it is no more needed.
4211 * \throw If \a this is not allocated.
4212 * \throw If \a this->getNumberOfComponents() != 1.
4213 * \sa DataArrayInt::findIdsEqualTuple
4216 DataArrayIdType *DataArrayDiscrete<T>::findIdsEqual(T val) const
4218 this->checkAllocated();
4219 if(this->getNumberOfComponents()!=1)
4220 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
4221 const T *cptr(this->getConstPointer());
4222 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(0,1);
4223 mcIdType nbOfTuples(this->getNumberOfTuples());
4224 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
4226 ret->pushBackSilent(ToIdType(i));
4231 * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from
4232 * values of \a this (\a a) and the given (\a indArr) arrays as follows:
4233 * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
4234 * new value in place \a indArr[ \a v ] is i.
4235 * \param [in] indArrBg - the array holding indices within the result array to assign
4236 * indices of values of \a this array pointing to values of \a indArrBg.
4237 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4238 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4239 * \return DataArrayInt * - the new instance of DataArrayInt.
4240 * The caller is to delete this result array using decrRef() as it is no more
4242 * \throw If \a this->getNumberOfComponents() != 1.
4243 * \throw If any value of \a this array is not a valid index for \a indArrBg array.
4244 * \throw If any value of \a indArrBg is not a valid index for \a this array.
4247 DataArrayIdType *DataArrayDiscrete<T>::transformWithIndArrR(const T *indArrBg, const T *indArrEnd) const
4249 this->checkAllocated();
4250 if(this->getNumberOfComponents()!=1)
4251 throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4252 mcIdType nbElemsIn=ToIdType(std::distance(indArrBg,indArrEnd));
4253 mcIdType nbOfTuples(this->getNumberOfTuples());
4254 const T *pt=this->getConstPointer();
4255 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
4256 ret->alloc(nbOfTuples,1);
4257 ret->fillWithValue(-1);
4258 mcIdType *tmp=ret->getPointer();
4259 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
4261 if(*pt>=0 && *pt<nbElemsIn)
4263 T pos=indArrBg[*pt];
4264 if(pos>=0 && pos<nbOfTuples)
4265 tmp[ToIdType(pos)]=i;
4268 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
4269 throw INTERP_KERNEL::Exception(oss.str().c_str());
4274 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
4275 throw INTERP_KERNEL::Exception(oss.str().c_str());
4282 * Computes distribution of values of \a this one-dimensional array between given value
4283 * ranges (casts). This method is typically useful for entity number splitting by types,
4285 * \warning The values contained in \a arrBg should be sorted ascendently. No
4286 * check of this is be done. If not, the result is not warranted.
4287 * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
4288 * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
4289 * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
4290 * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
4291 * should be more than every value in \a this array.
4292 * \param [in] arrEnd - specifies the end of the array \a arrBg, so that
4293 * the last value of \a arrBg is \a arrEnd[ -1 ].
4294 * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
4295 * (same number of tuples and components), the caller is to delete
4296 * using decrRef() as it is no more needed.
4297 * This array contains indices of ranges for every value of \a this array. I.e.
4298 * the i-th value of \a castArr gives the index of range the i-th value of \a this
4299 * belongs to. Or, in other words, this parameter contains for each tuple in \a
4300 * this in which cast it holds.
4301 * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
4302 * array, the caller is to delete using decrRef() as it is no more needed.
4303 * This array contains ranks of values of \a this array within ranges
4304 * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
4305 * the i-th value of \a this array within the \a castArr[ i ]-th range, to which
4306 * the i-th value of \a this belongs to. Or, in other words, this param contains
4307 * for each tuple its rank inside its cast. The rank is computed as difference
4308 * between the value and the lowest value of range.
4309 * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
4310 * ranges (casts) to which at least one value of \a this array belongs.
4311 * Or, in other words, this param contains the casts that \a this contains.
4312 * The caller is to delete this array using decrRef() as it is no more needed.
4314 * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
4315 * the output of this method will be :
4316 * - \a castArr : [1,1,0,0,0,1,1,0,1]
4317 * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
4318 * - \a castsPresent : [0,1]
4320 * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
4321 * range #1 and its rank within this range is 2; etc.
4323 * \throw If \a this->getNumberOfComponents() != 1.
4324 * \throw If \a arrEnd - arrBg < 2.
4325 * \throw If any value of \a this is not less than \a arrEnd[-1].
4328 void DataArrayDiscrete<T>::splitByValueRange(const T *arrBg, const T *arrEnd,
4329 DataArrayType *& castArr, DataArrayType *& rankInsideCast, DataArrayType *& castsPresent) const
4331 this->checkAllocated();
4332 if(this->getNumberOfComponents()!=1)
4333 throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4334 mcIdType nbOfTuples=this->getNumberOfTuples();
4335 std::size_t nbOfCast=std::distance(arrBg,arrEnd);
4337 throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
4339 const T *work=this->getConstPointer();
4340 typedef std::reverse_iterator<const T *> rintstart;
4341 rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
4342 rintstart end2(arrBg);
4343 MCAuto<DataArrayType> ret1=DataArrayType::New();
4344 MCAuto<DataArrayType> ret2=DataArrayType::New();
4345 MCAuto<DataArrayType> ret3=DataArrayType::New();
4346 ret1->alloc(nbOfTuples,1);
4347 ret2->alloc(nbOfTuples,1);
4348 T *ret1Ptr=ret1->getPointer();
4349 T *ret2Ptr=ret2->getPointer();
4350 std::set<T> castsDetected;
4351 for(mcIdType i=0;i<nbOfTuples;i++)
4353 rintstart res=std::find_if(bg,end2,std::bind(std::less_equal<T>(),std::placeholders::_1,work[i]));
4354 std::size_t pos=std::distance(bg,res);
4355 std::size_t pos2=nbOfCast-pos;
4358 ret1Ptr[i]=static_cast<T>(pos2);
4359 ret2Ptr[i]=work[i]-arrBg[pos2];
4360 castsDetected.insert(ret1Ptr[i]);
4364 std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
4365 throw INTERP_KERNEL::Exception(oss.str().c_str());
4368 ret3->alloc(castsDetected.size(),1);
4369 std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
4370 castArr=ret1.retn();
4371 rankInsideCast=ret2.retn();
4372 castsPresent=ret3.retn();
4376 * This method look at \a this if it can be considered as a range defined by the 3-tuple ( \a strt , \a sttoopp , \a stteepp ).
4377 * If false is returned the tuple must be ignored. If true is returned \a this can be considered by a range( \a strt , \a sttoopp , \a stteepp ).
4378 * This method works only if \a this is allocated and single component. If not an exception will be thrown.
4380 * \param [out] strt - the start of the range (included) if true is returned.
4381 * \param [out] sttoopp - the end of the range (not included) if true is returned.
4382 * \param [out] stteepp - the step of the range if true is returned.
4383 * \return the verdict of the check.
4385 * \sa DataArray::GetNumberOfItemGivenBES
4388 bool DataArrayDiscrete<T>::isRange(T& strt, T& sttoopp, T& stteepp) const
4390 this->checkAllocated();
4391 if(this->getNumberOfComponents()!=1)
4392 throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
4393 mcIdType nbTuples(this->getNumberOfTuples());
4395 { strt=0; sttoopp=0; stteepp=1; return true; }
4396 const T *pt(this->begin());
4399 { sttoopp=strt+1; stteepp=1; return true; }
4400 strt=*pt; sttoopp=pt[nbTuples-1];
4406 T a(sttoopp-1-strt),tmp(strt);
4407 if(a%(nbTuples-1)!=0)
4409 stteepp=a/(FromIdType<T>(nbTuples)-1);
4410 for(mcIdType i=0;i<nbTuples;i++,tmp+=stteepp)
4418 T a(strt-sttoopp-1),tmp(strt);
4419 if(a%(nbTuples-1)!=0)
4421 stteepp=-(a/(FromIdType<T>(nbTuples)-1));
4422 for(mcIdType i=0;i<nbTuples;i++,tmp+=stteepp)
4430 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4431 * from values of \a this array, which is supposed to contain a renumbering map in
4432 * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
4433 * To know how to use the renumbering maps see \ref numbering.
4434 * \param [in] newNbOfElem - the number of tuples in the result array.
4435 * \return DataArrayInt * - the new instance of DataArrayInt.
4436 * The caller is to delete this result array using decrRef() as it is no more
4439 * \if ENABLE_EXAMPLES
4440 * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
4441 * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
4445 DataArrayIdType * DataArrayDiscrete<T>::invertArrayO2N2N2O(mcIdType newNbOfElem) const
4447 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
4448 ret->alloc(newNbOfElem,1);
4449 mcIdType nbOfOldNodes(this->getNumberOfTuples());
4450 const T *old2New(this->begin());
4451 mcIdType *pt(ret->getPointer());
4452 for(mcIdType i=0;i!=nbOfOldNodes;i++)
4457 if(newp>=0 && newp<newNbOfElem)
4461 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4462 throw INTERP_KERNEL::Exception(oss.str().c_str());
4470 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4471 * from values of \a this array, which is supposed to contain a renumbering map in
4472 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4473 * To know how to use the renumbering maps see \ref numbering.
4474 * \param [in] oldNbOfElem - the number of tuples in the result array.
4475 * \return DataArrayInt * - the new instance of DataArrayInt.
4476 * The caller is to delete this result array using decrRef() as it is no more
4479 * \if ENABLE_EXAMPLES
4480 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4482 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4483 * \sa invertArrayN2O2O2NOptimized
4487 DataArrayIdType *DataArrayDiscrete<T>::invertArrayN2O2O2N(mcIdType oldNbOfElem) const
4489 this->checkAllocated();
4490 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
4491 ret->alloc(oldNbOfElem,1);
4492 const T *new2Old=this->getConstPointer();
4493 mcIdType *pt=ret->getPointer();
4494 std::fill(pt,pt+oldNbOfElem,-1);
4495 mcIdType nbOfNewElems(this->getNumberOfTuples());
4496 for(mcIdType i=0;i<nbOfNewElems;i++)
4499 if(v>=0 && v<oldNbOfElem)
4503 std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
4504 throw INTERP_KERNEL::Exception(oss.str().c_str());
4511 * This method is similar to DataArrayInt::invertArrayO2N2N2O except that
4512 * Example : If \a this contains [0,1,2,0,3,4,5,4,6,4] this method will return [0,1,2,4,5,6,8] whereas DataArrayInt::invertArrayO2N2N2O returns [3,1,2,4,9,6,8]
4515 DataArrayIdType *DataArrayDiscrete<T>::invertArrayO2N2N2OBis(mcIdType newNbOfElem) const
4517 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
4518 ret->alloc(newNbOfElem,1);
4519 mcIdType nbOfOldNodes(this->getNumberOfTuples());
4520 const T *old2New=this->getConstPointer();
4521 mcIdType *pt=ret->getPointer();
4522 for(mcIdType i=nbOfOldNodes-1;i>=0;i--)
4527 if(newp>=0 && newp<newNbOfElem)
4531 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4532 throw INTERP_KERNEL::Exception(oss.str().c_str());
4540 * Creates a map, whose contents are computed
4541 * from values of \a this array, which is supposed to contain a renumbering map in
4542 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4543 * To know how to use the renumbering maps see \ref numbering.
4544 * \return MapII - the new instance of Map.
4546 * \if ENABLE_EXAMPLES
4547 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4549 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4550 * \sa invertArrayN2O2O2N, giveN2OOptimized, MEDCouplingPointSet::renumberNodesInConn
4554 MCAuto< MapKeyVal<T, mcIdType> > DataArrayDiscrete<T>::invertArrayN2O2O2NOptimized() const
4556 this->checkAllocated();
4557 if(this->getNumberOfComponents()!=1)
4558 throw INTERP_KERNEL::Exception("DataArrayInt::invertArrayN2O2O2NOptimized : single component expected !");
4559 MCAuto< MapKeyVal<T, mcIdType> > ret(MapKeyVal<T, mcIdType>::New());
4560 std::map<T, mcIdType>& m(ret->data());
4561 const T *new2Old(this->begin());
4562 mcIdType nbOfNewElems(this->getNumberOfTuples());
4563 for(mcIdType i=0;i<nbOfNewElems;i++)
4572 * Creates a map, whose contents are computed
4573 * from values of \a this array, which is supposed to contain a renumbering map in
4574 * "New to Old" mode. The result array contains a renumbering map in "New to Old" mode as C++ map for performance reasons.
4576 * \sa invertArrayN2O2O2NOptimized, MEDCouplingPointSet::renumberNodesInConn
4579 MCAuto< MapKeyVal<mcIdType, T> > DataArrayDiscrete<T>::giveN2OOptimized() const
4581 this->checkAllocated();
4582 if(this->getNumberOfComponents()!=1)
4583 throw INTERP_KERNEL::Exception("DataArrayInt::giveN2OOptimized : single component expected !");
4584 MCAuto< MapKeyVal<mcIdType, T> > ret(MapKeyVal<mcIdType, T>::New());
4585 std::map<mcIdType,T>& m(ret->data());
4586 const T *new2Old(this->begin());
4587 mcIdType nbOfNewElems(this->getNumberOfTuples());
4588 for(mcIdType i=0;i<nbOfNewElems;i++)
4597 * This method finds for each element \a ELT in [valsBg,valsEnd) elements in \a this equal to it. Associated to ELT
4598 * this method will return the tuple id of last element found. If there is no element in \a this equal to ELT
4599 * an exception will be thrown.
4601 * In case of success this[ret]==vals. Samely ret->transformWithIndArr(this->begin(),this->end())==vals.
4602 * Where \a vals is the [valsBg,valsEnd) array and \a ret the array returned by this method.
4603 * This method can be seen as an extension of FindPermutationFromFirstToSecond.
4606 * - \a this: [17,27,2,10,-4,3,12,27,16]
4607 * - \a val : [3,16,-4,27,17]
4608 * - result: [5,8,4,7,0]
4610 * \return - An array of size std::distance(valsBg,valsEnd)
4612 * \sa DataArrayInt::FindPermutationFromFirstToSecond , DataArrayInt::FindPermutationFromFirstToSecondDuplicate
4615 MCAuto<DataArrayIdType> DataArrayDiscrete<T>::findIdForEach(const T *valsBg, const T *valsEnd) const
4617 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
4618 std::size_t nbOfTuplesOut(std::distance(valsBg,valsEnd));
4619 ret->alloc(nbOfTuplesOut,1);
4620 MCAuto< MapKeyVal<T, mcIdType> > zeMap(this->invertArrayN2O2O2NOptimized());
4621 const std::map<T, mcIdType>& dat(zeMap->data());
4622 mcIdType *ptToFeed(ret->getPointer());
4623 for(const T *pt=valsBg;pt!=valsEnd;pt++)
4625 typename std::map<T,mcIdType>::const_iterator it(dat.find(*pt));
4627 *ptToFeed++=(*it).second;
4630 std::ostringstream oss; oss << "DataArrayInt::findIdForEach : error for element at place " << std::distance(valsBg,pt);
4631 oss << " of input array value is " << *pt << " which is not in this !";
4632 throw INTERP_KERNEL::Exception(oss.str());
4639 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4640 * This map, if applied to \a this array, would make it sorted. For example, if
4641 * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4642 * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4643 * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4644 * This method is useful for renumbering (in MED file for example). For more info
4645 * on renumbering see \ref numbering.
4646 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4647 * array using decrRef() as it is no more needed.
4648 * \throw If \a this is not allocated.
4649 * \throw If \a this->getNumberOfComponents() != 1.
4650 * \throw If there are equal values in \a this array.
4653 DataArrayIdType *DataArrayDiscrete<T>::checkAndPreparePermutation() const
4655 this->checkAllocated();
4656 if(this->getNumberOfComponents()!=1)
4657 throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4658 mcIdType nbTuples(this->getNumberOfTuples());
4659 const T *pt=this->getConstPointer();
4660 mcIdType *pt2=this->CheckAndPreparePermutation(pt,pt+nbTuples);
4661 DataArrayIdType *ret=DataArrayIdType::New();
4662 ret->useArray(pt2,true,DeallocType::C_DEALLOC,nbTuples,1);
4667 * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4668 * onto a set of values of size \a targetNb (\a B). The surjective function is
4669 * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4670 * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4671 * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4672 * The first of out arrays returns indices of elements of \a this array, grouped by their
4673 * place in the set \a B. The second out array is the index of the first one; it shows how
4674 * many elements of \a A are mapped into each element of \a B. <br>
4676 * mapping and its usage in renumbering see \ref numbering. <br>
4678 * - \a this: [0,3,2,3,2,2,1,2]
4680 * - \a arr: [0, 6, 2,4,5,7, 1,3]
4681 * - \a arrI: [0,1,2,6,8]
4683 * This result means: <br>
4684 * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4685 * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4686 * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4687 * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] :
4688 * \a arrI[ 2+1 ]]); <br> etc.
4689 * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4690 * than the maximal value of \a A.
4691 * \param [out] arr - a new instance of DataArrayInt returning indices of
4692 * elements of \a this, grouped by their place in the set \a B. The caller is to delete
4693 * this array using decrRef() as it is no more needed.
4694 * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4695 * elements of \a this. The caller is to delete this array using decrRef() as it
4696 * is no more needed.
4697 * \throw If \a this is not allocated.
4698 * \throw If \a this->getNumberOfComponents() != 1.
4699 * \throw If any value in \a this is more or equal to \a targetNb.
4702 void DataArrayDiscrete<T>::changeSurjectiveFormat(T targetNb, DataArrayIdType *&arr, DataArrayIdType *&arrI) const
4704 this->checkAllocated();
4705 if(this->getNumberOfComponents()!=1)
4706 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4707 mcIdType nbOfTuples(this->getNumberOfTuples());
4708 const T *input=this->getConstPointer();
4709 std::vector< std::vector<mcIdType> > tmp(targetNb);
4710 for(mcIdType i=0;i<nbOfTuples;i++)
4713 if(tmp2>=0 && tmp2<targetNb)
4714 tmp[tmp2].push_back(i);
4717 std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4718 throw INTERP_KERNEL::Exception(oss.str().c_str());
4722 MCAuto<DataArrayIdType> retI(DataArrayIdType::New());
4723 retI->alloc(targetNb+1,1);
4724 mcIdType *retIPtr=retI->getPointer();
4726 for(std::vector< std::vector<mcIdType> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4727 retIPtr[1]=retIPtr[0]+ToIdType((*it1).size());
4728 if(nbOfTuples!=retI->getIJ(ToIdType(targetNb),0))
4729 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4730 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
4731 ret->alloc(nbOfTuples,1);
4732 mcIdType *retPtr=ret->getPointer();
4733 for(std::vector< std::vector<mcIdType> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4734 retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4740 * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4741 * which if applied to \a this array would make it sorted ascendingly.
4742 * For more info on renumbering see \ref numbering. <br>
4744 * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4745 * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4746 * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2]
4748 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4749 * array using decrRef() as it is no more needed.
4750 * \throw If \a this is not allocated.
4751 * \throw If \a this->getNumberOfComponents() != 1.
4754 DataArrayIdType *DataArrayDiscrete<T>::buildPermArrPerLevel() const
4756 this->checkAllocated();
4757 if(this->getNumberOfComponents()!=1)
4758 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4759 mcIdType nbOfTuples=this->getNumberOfTuples();
4760 const T *pt=this->getConstPointer();
4761 std::map<T,mcIdType> m;
4762 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
4763 ret->alloc(nbOfTuples,1);
4764 mcIdType *opt=ret->getPointer();
4765 for(mcIdType i=0;i<nbOfTuples;i++,pt++,opt++)
4768 typename std::map<T,mcIdType>::iterator it=m.find(val);
4777 m.insert(std::pair<T,mcIdType>(val,1));
4781 for(typename std::map<T,mcIdType>::iterator it=m.begin();it!=m.end();it++)
4783 mcIdType vt=(*it).second;
4787 pt=this->getConstPointer();
4788 opt=ret->getPointer();
4789 for(mcIdType i=0;i<nbOfTuples;i++,pt++,opt++)
4796 * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4797 * iota(). This method is particularly useful for DataArrayInt instances that represent
4798 * a renumbering array, to check if there is a real need in renumbering.
4799 * This method checks than \a this can be considered as an identity mapping
4800 * of a set having \a sizeExpected elements into itself.
4802 * \param [in] sizeExpected - The number of elements expected.
4803 * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4804 * \throw If \a this is not allocated.
4805 * \throw If \a this->getNumberOfComponents() != 1.
4808 bool DataArrayDiscrete<T>::isIota(mcIdType sizeExpected) const
4810 this->checkAllocated();
4811 if(this->getNumberOfComponents()!=1)
4813 mcIdType nbOfTuples(this->getNumberOfTuples());
4814 if(nbOfTuples!=sizeExpected)
4816 const T *pt=this->getConstPointer();
4817 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
4824 * Checks if all values in \a this array are equal to \a val.
4825 * \param [in] val - value to check equality of array values to.
4826 * \return bool - \a true if all values are \a val.
4827 * \throw If \a this is not allocated.
4828 * \throw If \a this->getNumberOfComponents() != 1
4829 * \sa DataArrayInt::checkUniformAndGuess
4832 bool DataArrayDiscrete<T>::isUniform(T val) const
4834 this->checkAllocated();
4835 if(this->getNumberOfComponents()!=1)
4836 throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4837 const T *w(this->begin()),*end2(this->end());
4845 * This method checks that \a this is uniform. If not and exception will be thrown.
4846 * In case of uniformity the corresponding value is returned.
4848 * \return mcIdType - the unique value contained in this
4849 * \throw If \a this is not allocated.
4850 * \throw If \a this->getNumberOfComponents() != 1
4851 * \throw If \a this is not uniform.
4852 * \sa DataArrayInt::isUniform
4855 T DataArrayDiscrete<T>::checkUniformAndGuess() const
4857 this->checkAllocated();
4858 if(this->getNumberOfComponents()!=1)
4859 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4861 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
4862 const T *w(this->begin()),*end2(this->end());
4866 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
4871 * Checks if all values in \a this array are unique.
4872 * \return bool - \a true if condition above is true
4873 * \throw If \a this is not allocated.
4874 * \throw If \a this->getNumberOfComponents() != 1
4877 bool DataArrayDiscrete<T>::hasUniqueValues() const
4879 this->checkAllocated();
4880 if(this->getNumberOfComponents()!=1)
4881 throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4882 std::size_t nbOfElements(this->getNumberOfTuples());
4883 std::set<T> s(this->begin(),this->end()); // in C++11, should use unordered_set (O(1) complexity)
4884 if (s.size() != nbOfElements)
4890 * Copy all components in a specified order from another DataArrayInt.
4891 * The specified components become the first ones in \a this array.
4892 * Both numerical and textual data is copied. The number of tuples in \a this and
4893 * the other array can be different.
4894 * \param [in] a - the array to copy data from.
4895 * \param [in] compoIds - sequence of zero based indices of components, data of which is
4897 * \throw If \a a is NULL.
4898 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
4899 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
4901 * \if ENABLE_EXAMPLES
4902 * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
4906 void DataArrayDiscrete<T>::setSelectedComponents(const DataArrayType *a, const std::vector<std::size_t>& compoIds)
4909 throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
4910 this->checkAllocated();
4911 a->checkAllocated();
4912 this->copyPartOfStringInfoFrom2(compoIds,*a);
4913 std::size_t partOfCompoSz=compoIds.size();
4914 std::size_t nbOfCompo = this->getNumberOfComponents();
4915 mcIdType nbOfTuples=std::min(this->getNumberOfTuples(),a->getNumberOfTuples());
4916 const T *ac=a->getConstPointer();
4917 T *nc=this->getPointer();
4918 for(mcIdType i=0;i<nbOfTuples;i++)
4919 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
4920 nc[nbOfCompo*i+compoIds[j]]=*ac;
4924 * This method searches each value in \a valToSearchIntoTuples among values in \a this given the corresponding tuple to find into.
4925 * If the value at the corresponding tuple is not found in the tuple an exception will be thrown.
4926 * If the value is found the corresponding component id is returned.
4928 * \param [in] valToSearchIntoTuples - a one component array containing the values to find in \a this
4929 * \param [in] tupleIdHint - a one component array having same size than \a valToSearchIntoTuples giving for each value the tuple to find into
4930 * \return DataArrayInt * - A newly allocated array having same size than \a valToSearchIntoTuples with one component
4933 * - \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)]
4934 * - \a valToSearchIntoTuples: [1, 4, 6, 8, 10, 12, 14, 16, 17]
4935 * - \a tupleIdHint: [0, 1, 2, 3, 4, 5, 6, 7, 7]
4936 * - result array: [1, 1, 0, 1, 2, 1, 0, 1, 2] == <br>
4939 DataArrayIdType *DataArrayDiscrete<T>::locateComponentId(const DataArrayType *valToSearchIntoTuples, const DataArrayIdType *tupleIdHint) const
4941 if(!valToSearchIntoTuples || !tupleIdHint)
4942 THROW_IK_EXCEPTION("DataArrayInt::locateComponentId : valToSearchIntoTuples and tupleIdHint must be not nullptr !");
4943 valToSearchIntoTuples->checkAllocated(); tupleIdHint->checkAllocated();
4944 this->checkAllocated();
4945 constexpr char MSG1[] = "DataArrayInt::locateComponentId : single component array expected";
4946 valToSearchIntoTuples->checkNbOfComps(1,MSG1); tupleIdHint->checkNbOfComps(1,MSG1);
4947 std::size_t nbOfCompo( this->getNumberOfComponents() );
4948 mcIdType thisNbTuples( this->getNumberOfTuples() );
4949 mcIdType nbOfTuples( valToSearchIntoTuples->getNumberOfTuples() );
4950 tupleIdHint->checkNbOfTuples(nbOfTuples,"Number of tuples of input arrays must be the same.");
4951 const T *cPtr(this->begin()),*valSearchPt(valToSearchIntoTuples->begin());
4952 const mcIdType *tHintPtr(tupleIdHint->begin());
4953 MCAuto<DataArrayIdType> ret = DataArrayIdType::New();
4954 ret->alloc(nbOfTuples,1);
4955 mcIdType *retPtr(ret->getPointer());
4956 for(auto i = 0 ; i < nbOfTuples ; ++i)
4958 if( tHintPtr[i] >=0 && tHintPtr[i] < thisNbTuples )
4960 auto strtSearch(cPtr+nbOfCompo*tHintPtr[i]),endSearch(cPtr+nbOfCompo*(tHintPtr[i]+1));
4961 auto pos = std::find(strtSearch,endSearch,valSearchPt[i]);
4962 if(pos != endSearch)
4963 *retPtr++ = ToIdType( std::distance(strtSearch,pos) );
4965 THROW_IK_EXCEPTION("At pos " << i << " value " << valSearchPt[i] << " is not present at tuple " << tHintPtr[i]);
4968 THROW_IK_EXCEPTION("At pos " << i << " hint tuple is " << tHintPtr[i] << " not in [0," << thisNbTuples << ")");
4974 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
4975 * equal to a given one.
4976 * \param [in] val - the value to ignore within \a this.
4977 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4978 * array using decrRef() as it is no more needed.
4979 * \throw If \a this is not allocated.
4980 * \throw If \a this->getNumberOfComponents() != 1.
4983 DataArrayIdType *DataArrayDiscrete<T>::findIdsNotEqual(T val) const
4985 this->checkAllocated();
4986 if(this->getNumberOfComponents()!=1)
4987 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
4988 const T *cptr(this->getConstPointer());
4989 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
4991 mcIdType nbOfTuples(this->getNumberOfTuples());
4992 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
4994 ret->pushBackSilent(i);
4999 * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
5000 * This method is an extension of DataArrayInt::findIdsEqual method.
5002 * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
5003 * \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
5004 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5005 * array using decrRef() as it is no more needed.
5006 * \throw If \a this is not allocated.
5007 * \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
5008 * \throw If \a this->getNumberOfComponents() is equal to 0.
5009 * \sa DataArrayInt::findIdsEqual
5012 DataArrayIdType *DataArrayDiscrete<T>::findIdsEqualTuple(const T *tupleBg, const T *tupleEnd) const
5014 std::size_t nbOfCompoExp=std::distance(tupleBg,tupleEnd);
5015 this->checkAllocated();
5016 if(this->getNumberOfComponents()!=nbOfCompoExp)
5018 std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << this->getNumberOfComponents() << " components !";
5019 throw INTERP_KERNEL::Exception(oss.str().c_str());
5022 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
5023 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
5025 const T *bg(this->begin()),*end2(this->end()),*work(this->begin());
5028 work=std::search(work,end2,tupleBg,tupleEnd);
5031 std::ptrdiff_t pos=std::distance(bg,work);
5032 if(pos%nbOfCompoExp==0)
5033 ret->pushBackSilent(ToIdType(pos/nbOfCompoExp));
5041 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
5042 * one of given values.
5043 * \param [in] valsBg - an array of values to find within \a this array.
5044 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5045 * the last value of \a valsBg is \a valsEnd[ -1 ].
5046 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5047 * array using decrRef() as it is no more needed.
5048 * \throw If \a this->getNumberOfComponents() != 1.
5051 DataArrayIdType *DataArrayDiscrete<T>::findIdsEqualList(const T *valsBg, const T *valsEnd) const
5053 if(this->getNumberOfComponents()!=1)
5054 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
5055 std::set<T> vals2(valsBg,valsEnd);
5056 const T *cptr(this->getConstPointer());
5057 mcIdType nbOfTuples(this->getNumberOfTuples());
5058 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(0,1);
5059 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
5060 if(vals2.find(*cptr)!=vals2.end())
5061 ret->pushBackSilent(i);
5066 * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
5067 * equal to any of given values.
5068 * \param [in] valsBg - an array of values to ignore within \a this array.
5069 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5070 * the last value of \a valsBg is \a valsEnd[ -1 ].
5071 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5072 * array using decrRef() as it is no more needed.
5073 * \throw If \a this->getNumberOfComponents() != 1.
5076 DataArrayIdType *DataArrayDiscrete<T>::findIdsNotEqualList(const T *valsBg, const T *valsEnd) const
5078 if(this->getNumberOfComponents()!=1)
5079 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
5080 std::set<T> vals2(valsBg,valsEnd);
5081 const T *cptr=this->getConstPointer();
5082 mcIdType nbOfTuples(this->getNumberOfTuples());
5083 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(0,1);
5084 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
5085 if(vals2.find(*cptr)==vals2.end())
5086 ret->pushBackSilent(i);
5091 * This method expects to be called when number of components of this is equal to one.
5092 * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
5093 * If not any tuple contains \b value -1 is returned.
5094 * \sa DataArrayInt::presenceOfValue
5097 mcIdType DataArrayDiscrete<T>::findIdFirstEqual(T value) const
5099 this->checkAllocated();
5100 if(this->getNumberOfComponents()!=1)
5101 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
5102 const T *cptr=this->getConstPointer();
5103 mcIdType nbOfTuples(this->getNumberOfTuples());
5104 const T *ret=std::find(cptr,cptr+nbOfTuples,value);
5105 if(ret!=cptr+nbOfTuples)
5106 return ToIdType(std::distance(cptr,ret));
5111 * This method expects to be called when number of components of this is equal to one.
5112 * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
5113 * If not any tuple contains one of the values contained in 'vals' -1 is returned.
5114 * \sa DataArrayInt::presenceOfValue
5117 mcIdType DataArrayDiscrete<T>::findIdFirstEqual(const std::vector<T>& vals) const
5119 this->checkAllocated();
5120 if(this->getNumberOfComponents()!=1)
5121 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
5122 std::set<T> vals2(vals.begin(),vals.end());
5123 const T *cptr=this->getConstPointer();
5124 mcIdType nbOfTuples(this->getNumberOfTuples());
5125 for(const T *w=cptr;w!=cptr+nbOfTuples;w++)
5126 if(vals2.find(*w)!=vals2.end())
5127 return ToIdType(std::distance(cptr,w));
5132 * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
5133 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5134 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5135 * If any the tuple id is returned. If not -1 is returned.
5137 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5138 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5140 * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
5141 * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
5144 mcIdType DataArrayDiscrete<T>::findIdFirstEqualTuple(const std::vector<T>& tupl) const
5146 this->checkAllocated();
5147 std::size_t nbOfCompo(this->getNumberOfComponents());
5149 throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
5150 if(nbOfCompo!=tupl.size())
5152 std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
5153 throw INTERP_KERNEL::Exception(oss.str().c_str());
5155 const T *cptr=this->getConstPointer();
5156 std::size_t nbOfVals=this->getNbOfElems();
5157 for(const T *work=cptr;work!=cptr+nbOfVals;)
5159 work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
5160 if(work!=cptr+nbOfVals)
5162 if(std::distance(cptr,work)%nbOfCompo!=0)
5165 return ToIdType (std::distance(cptr,work)/nbOfCompo);
5172 * This method searches the sequence specified in input parameter \b vals in \b this.
5173 * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
5174 * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
5175 * \sa DataArrayInt::findIdFirstEqualTuple
5178 mcIdType DataArrayDiscrete<T>::findIdSequence(const std::vector<T>& vals) const
5180 this->checkAllocated();
5181 std::size_t nbOfCompo=this->getNumberOfComponents();
5183 throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
5184 const T *cptr=this->getConstPointer();
5185 std::size_t nbOfVals=this->getNbOfElems();
5186 const T *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
5187 if(loc!=cptr+nbOfVals)
5188 return ToIdType(std::distance(cptr,loc));
5193 * Assigns \a newValue to all elements holding \a oldValue within \a this
5194 * one-dimensional array.
5195 * \param [in] oldValue - the value to replace.
5196 * \param [in] newValue - the value to assign.
5197 * \return mcIdType - number of replacements performed.
5198 * \throw If \a this is not allocated.
5199 * \throw If \a this->getNumberOfComponents() != 1.
5202 mcIdType DataArrayDiscrete<T>::changeValue(T oldValue, T newValue)
5204 this->checkAllocated();
5205 if(this->getNumberOfComponents()!=1)
5206 throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
5207 if(oldValue==newValue)
5209 T *start(this->getPointer()),*end2(start+this->getNbOfElems());
5211 for(T *val=start;val!=end2;val++)
5220 this->declareAsNew();
5225 * This method returns the number of values in \a this that are equals to input parameter \a value.
5226 * This method only works for single component array.
5228 * \return a value in [ 0, \c this->getNumberOfTuples() )
5230 * \throw If \a this is not allocated
5234 mcIdType DataArrayDiscrete<T>::count(T value) const
5237 this->checkAllocated();
5238 if(this->getNumberOfComponents()!=1)
5239 throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5240 const T *vals=this->begin();
5241 std::size_t nbOfElements=this->getNumberOfTuples();
5242 for(std::size_t i=0;i<nbOfElements;i++,vals++)
5249 * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
5250 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5251 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5252 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5253 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5254 * \sa DataArrayInt::findIdFirstEqualTuple
5257 bool DataArrayDiscrete<T>::presenceOfTuple(const std::vector<T>& tupl) const
5259 return this->findIdFirstEqualTuple(tupl)!=-1;
5264 * Returns \a true if a given value is present within \a this one-dimensional array.
5265 * \param [in] value - the value to find within \a this array.
5266 * \return bool - \a true in case if \a value is present within \a this array.
5267 * \throw If \a this is not allocated.
5268 * \throw If \a this->getNumberOfComponents() != 1.
5269 * \sa findIdFirstEqual()
5272 bool DataArrayDiscrete<T>::presenceOfValue(T value) const
5274 return this->findIdFirstEqual(value)!=-1;
5278 * This method expects to be called when number of components of this is equal to one.
5279 * This method returns true if it exists a tuple so that the value is contained in \b vals.
5280 * If not any tuple contains one of the values contained in 'vals' false is returned.
5281 * \sa DataArrayInt::findIdFirstEqual
5284 bool DataArrayDiscrete<T>::presenceOfValue(const std::vector<T>& vals) const
5286 return this->findIdFirstEqual(vals)!=-1;
5290 * Accumulates values of each component of \a this array.
5291 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
5292 * by the caller, that is filled by this method with sum value for each
5294 * \throw If \a this is not allocated.
5297 void DataArrayDiscrete<T>::accumulate(T *res) const
5299 this->checkAllocated();
5300 const T *ptr=this->getConstPointer();
5301 mcIdType nbTuple(this->getNumberOfTuples());
5302 std::size_t nbComps(this->getNumberOfComponents());
5303 std::fill(res,res+nbComps,0);
5304 for(mcIdType i=0;i<nbTuple;i++)
5305 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<T>());
5309 T DataArrayDiscrete<T>::accumulate(std::size_t compId) const
5311 this->checkAllocated();
5312 const T *ptr=this->getConstPointer();
5313 mcIdType nbTuple(this->getNumberOfTuples());
5314 std::size_t nbComps(this->getNumberOfComponents());
5315 if(compId>=nbComps) // compId >= 0 (it is a size_t)
5316 throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
5318 for(mcIdType i=0;i<nbTuple;i++)
5319 ret+=ptr[i*nbComps+compId];
5324 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
5325 * The returned array will have same number of components than \a this and number of tuples equal to
5326 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
5328 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
5330 * \param [in] bgOfIndex - begin (included) of the input index array.
5331 * \param [in] endOfIndex - end (excluded) of the input index array.
5332 * \return DataArrayInt * - the new instance having the same number of components than \a this.
5334 * \throw If bgOfIndex or end is NULL.
5335 * \throw If input index array is not ascendingly sorted.
5336 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
5337 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
5340 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::accumulatePerChunck(const mcIdType *bgOfIndex, const mcIdType *endOfIndex) const
5342 if(!bgOfIndex || !endOfIndex)
5343 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
5344 this->checkAllocated();
5345 std::size_t nbCompo(this->getNumberOfComponents());
5346 mcIdType nbOfTuples(this->getNumberOfTuples());
5347 mcIdType sz=ToIdType(std::distance(bgOfIndex,endOfIndex));
5349 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
5351 MCAuto<DataArrayType> ret=DataArrayType::New(); ret->alloc(sz,nbCompo);
5352 const mcIdType *w=bgOfIndex;
5353 if(*w<0 || *w>=nbOfTuples)
5354 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
5355 const T *srcPt=this->begin()+(*w)*nbCompo;
5356 T *tmp=ret->getPointer();
5357 for(mcIdType i=0;i<sz;i++,tmp+=nbCompo,w++)
5359 std::fill(tmp,tmp+nbCompo,0);
5362 for(mcIdType j=w[0];j<w[1];j++,srcPt+=nbCompo)
5364 if(j>=0 && j<nbOfTuples)
5365 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<T>());
5368 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
5369 throw INTERP_KERNEL::Exception(oss.str().c_str());
5375 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
5376 throw INTERP_KERNEL::Exception(oss.str().c_str());
5379 ret->copyStringInfoFrom(*this);
5384 * Returns in a single walk in \a this the min value and the max value in \a this.
5385 * \a this is expected to be single component array.
5387 * \param [out] minValue - the min value in \a this.
5388 * \param [out] maxValue - the max value in \a this.
5390 * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5393 void DataArrayDiscrete<T>::getMinMaxValues(T& minValue, T& maxValue) const
5395 this->checkAllocated();
5396 if(this->getNumberOfComponents()!=1)
5397 throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5398 std::size_t nbElements(this->getNumberOfTuples());
5399 const T *pt(this->begin());
5400 minValue=std::numeric_limits<T>::max(); maxValue=-std::numeric_limits<T>::max();
5401 for(std::size_t i=0;i<nbElements;i++,pt++)
5411 * Modify all elements of \a this array, so that
5412 * an element _x_ becomes \f$ numerator / x \f$.
5413 * \warning If an exception is thrown because of presence of 0 element in \a this
5414 * array, all elements processed before detection of the zero element remain
5416 * \param [in] numerator - the numerator used to modify array elements.
5417 * \throw If \a this is not allocated.
5418 * \throw If there is an element equal to 0 in \a this array.
5421 void DataArrayDiscrete<T>::applyInv(T numerator)
5423 this->checkAllocated();
5424 T *ptr=this->getPointer();
5425 std::size_t nbOfElems=this->getNbOfElems();
5426 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5430 *ptr=numerator/(*ptr);
5434 std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/(this->getNumberOfComponents()) << " component #" << i%(this->getNumberOfComponents());
5436 throw INTERP_KERNEL::Exception(oss.str().c_str());
5439 this->declareAsNew();
5443 * Modify all elements of \a this array, so that
5444 * an element _x_ becomes \f$ x / val \f$.
5445 * \param [in] val - the denominator used to modify array elements.
5446 * \throw If \a this is not allocated.
5447 * \throw If \a val == 0.
5450 void DataArrayDiscrete<T>::applyDivideBy(T val)
5453 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5454 this->checkAllocated();
5455 T *ptr=this->getPointer();
5456 std::size_t nbOfElems=this->getNbOfElems();
5457 std::transform(ptr,ptr+nbOfElems,ptr,std::bind(std::divides<T>(),std::placeholders::_1,val));
5458 this->declareAsNew();
5462 * Modify all elements of \a this array, so that
5463 * an element _x_ becomes <em> x % val </em>.
5464 * \param [in] val - the divisor used to modify array elements.
5465 * \throw If \a this is not allocated.
5466 * \throw If \a val <= 0.
5469 void DataArrayDiscrete<T>::applyModulus(T val)
5472 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5473 this->checkAllocated();
5474 T *ptr=this->getPointer();
5475 std::size_t nbOfElems=this->getNbOfElems();
5476 std::transform(ptr,ptr+nbOfElems,ptr,std::bind(std::modulus<T>(),std::placeholders::_1,val));
5477 this->declareAsNew();
5481 * Modify all elements of \a this array, so that
5482 * an element _x_ becomes <em> val % x </em>.
5483 * \warning If an exception is thrown because of presence of an element <= 0 in \a this
5484 * array, all elements processed before detection of the zero element remain
5486 * \param [in] val - the divident used to modify array elements.
5487 * \throw If \a this is not allocated.
5488 * \throw If there is an element equal to or less than 0 in \a this array.
5491 void DataArrayDiscrete<T>::applyRModulus(T val)
5493 this->checkAllocated();
5494 T *ptr=this->getPointer();
5495 std::size_t nbOfElems=this->getNbOfElems();
5496 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5504 std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/(this->getNumberOfComponents()) << " component #" << i%(this->getNumberOfComponents());
5506 throw INTERP_KERNEL::Exception(oss.str().c_str());
5509 this->declareAsNew();
5513 * Modify all elements of \a this array, so that
5514 * an element _x_ becomes <em> val ^ x </em>.
5515 * \param [in] val - the value used to apply pow on all array elements.
5516 * \throw If \a this is not allocated.
5517 * \throw If \a val < 0.
5520 void DataArrayDiscrete<T>::applyPow(T val)
5522 this->checkAllocated();
5524 throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5525 T *ptr=this->getPointer();
5526 std::size_t nbOfElems=this->getNbOfElems();
5529 std::fill(ptr,ptr+nbOfElems,1);
5532 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5535 for(T j=0;j<val;j++)
5539 this->declareAsNew();
5543 * Modify all elements of \a this array, so that
5544 * an element _x_ becomes \f$ val ^ x \f$.
5545 * \param [in] val - the value used to apply pow on all array elements.
5546 * \throw If \a this is not allocated.
5547 * \throw If there is an element < 0 in \a this array.
5548 * \warning If an exception is thrown because of presence of 0 element in \a this
5549 * array, all elements processed before detection of the zero element remain
5553 void DataArrayDiscrete<T>::applyRPow(T val)
5555 this->checkAllocated();
5556 T *ptr=this->getPointer();
5557 std::size_t nbOfElems=this->getNbOfElems();
5558 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5563 for(T j=0;j<*ptr;j++)
5569 std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/(this->getNumberOfComponents()) << " component #" << i%(this->getNumberOfComponents());
5571 throw INTERP_KERNEL::Exception(oss.str().c_str());
5574 this->declareAsNew();
5578 * This method works only on data array with one component.
5579 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5580 * this[*id] in [\b vmin,\b vmax)
5582 * \param [in] vmin begin of range. This value is included in range (included).
5583 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5584 * \return a newly allocated data array that the caller should deal with.
5586 * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5589 DataArrayIdType *DataArrayDiscrete<T>::findIdsInRange(T vmin, T vmax) const
5591 InRange<T> ir(vmin,vmax);
5592 MCAuto<DataArrayIdType> ret(this->findIdsAdv(ir));
5597 * This method works only on data array with one component.
5598 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5599 * this[*id] \b not in [\b vmin,\b vmax)
5601 * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5602 * \param [in] vmax end of range. This value is included in range (included).
5603 * \return a newly allocated data array that the caller should deal with.
5605 * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5608 DataArrayIdType *DataArrayDiscrete<T>::findIdsNotInRange(T vmin, T vmax) const
5610 NotInRange<T> nir(vmin,vmax);
5611 MCAuto<DataArrayIdType> ret(this->findIdsAdv(nir));
5616 * This method works only on data array with one component.
5617 * This method checks that all ids in \b this are in [ \b vmin, \b vmax ). If there is at least one element in \a this not in [ \b vmin, \b vmax ) an exception will be thrown.
5619 * \param [in] vmin begin of range. This value is included in range (included).
5620 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5621 * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5623 bool DataArrayDiscrete<T>::checkAllIdsInRange(T vmin, T vmax) const
5625 this->checkAllocated();
5626 if(this->getNumberOfComponents()!=1)
5627 throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5628 mcIdType nbOfTuples(this->getNumberOfTuples());
5630 const T *cptr=this->getConstPointer();
5631 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
5633 if(*cptr>=vmin && *cptr<vmax)
5634 { ret=ret && *cptr==i; }
5637 std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5638 throw INTERP_KERNEL::Exception(oss.str().c_str());
5645 * Returns a new DataArrayInt which contains a complement of elements of \a this
5646 * one-dimensional array. I.e. the result array contains all elements from the range [0,
5647 * \a nbOfElement) not present in \a this array.
5648 * \param [in] nbOfElement - maximal size of the result array.
5649 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5650 * array using decrRef() as it is no more needed.
5651 * \throw If \a this is not allocated.
5652 * \throw If \a this->getNumberOfComponents() != 1.
5653 * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
5657 DataArrayIdType *DataArrayDiscrete<T>::buildComplement(mcIdType nbOfElement) const
5659 this->checkAllocated();
5660 if(this->getNumberOfComponents()!=1)
5661 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
5662 std::vector<bool> tmp(nbOfElement);
5663 const T *pt=this->getConstPointer();
5664 std::size_t nbOfElements=this->getNumberOfTuples();
5665 for(const T *w=pt;w!=pt+nbOfElements;w++)
5666 if(*w>=0 && *w<nbOfElement)
5669 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
5670 std::size_t nbOfRetVal=std::count(tmp.begin(),tmp.end(),false);
5671 DataArrayIdType *ret=DataArrayIdType::New();
5672 ret->alloc(nbOfRetVal,1);
5674 mcIdType *retPtr=ret->getPointer();
5675 for(mcIdType i=0;i<nbOfElement;i++)
5682 * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
5683 * from an \a other one-dimensional array.
5684 * \param [in] other - a DataArrayInt containing elements not to include in the result array.
5685 * \return DataArrayInt * - a new instance of DataArrayInt with one component. The
5686 * caller is to delete this array using decrRef() as it is no more needed.
5687 * \throw If \a other is NULL.
5688 * \throw If \a other is not allocated.
5689 * \throw If \a other->getNumberOfComponents() != 1.
5690 * \throw If \a this is not allocated.
5691 * \throw If \a this->getNumberOfComponents() != 1.
5692 * \sa DataArrayInt::buildSubstractionOptimized()
5695 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildSubstraction(const DataArrayType *other) const
5698 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
5699 this->checkAllocated();
5700 other->checkAllocated();
5701 if(this->getNumberOfComponents()!=1)
5702 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
5703 if(other->getNumberOfComponents()!=1)
5704 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
5705 const T *pt=this->getConstPointer();
5706 std::size_t nbOfElements=this->getNumberOfTuples();
5707 std::set<T> s1(pt,pt+nbOfElements);
5708 pt=other->getConstPointer();
5709 nbOfElements=other->getNumberOfTuples();
5710 std::set<T> s2(pt,pt+nbOfElements);
5712 std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<T> >(r));
5713 DataArrayType *ret=DataArrayType::New();
5714 ret->alloc(r.size(),1);
5715 std::copy(r.begin(),r.end(),ret->getPointer());
5720 * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
5721 * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
5723 * \param [in] other an array with one component and expected to be sorted ascendingly.
5724 * \ret list of ids in \a this but not in \a other.
5725 * \sa DataArrayInt::buildSubstraction
5728 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildSubstractionOptimized(const DataArrayType *other) const
5730 static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
5731 if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
5732 this->checkAllocated(); other->checkAllocated();
5733 if(this->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5734 if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5735 const T *pt1Bg(this->begin()),*pt1End(this->end()),*pt2Bg(other->begin()),*pt2End(other->end());
5736 const T *work1(pt1Bg),*work2(pt2Bg);
5737 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(0,1);
5738 for(;work1!=pt1End;work1++)
5740 if(work2!=pt2End && *work1==*work2)
5743 ret->pushBackSilent(*work1);
5749 * Returns a new DataArrayInt which contains all elements of \a this and a given
5750 * one-dimensional arrays. The result array does not contain any duplicates
5751 * and its values are sorted in ascending order.
5752 * \param [in] other - an array to unite with \a this one.
5753 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5754 * array using decrRef() as it is no more needed.
5755 * \throw If \a this or \a other is not allocated.
5756 * \throw If \a this->getNumberOfComponents() != 1.
5757 * \throw If \a other->getNumberOfComponents() != 1.
5760 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildUnion(const DataArrayType *other) const
5762 std::vector<const DataArrayType *>arrs(2);
5763 arrs[0]=dynamic_cast<const DataArrayType *>(this); arrs[1]=other;
5764 return DataArrayDiscrete<T>::BuildUnion(arrs);
5768 * Returns a new DataArrayInt which contains elements present in both \a this and a given
5769 * one-dimensional arrays. The result array does not contain any duplicates
5770 * and its values are sorted in ascending order.
5771 * \param [in] other - an array to intersect with \a this one.
5772 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5773 * array using decrRef() as it is no more needed.
5774 * \throw If \a this or \a other is not allocated.
5775 * \throw If \a this->getNumberOfComponents() != 1.
5776 * \throw If \a other->getNumberOfComponents() != 1.
5779 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildIntersection(const DataArrayType *other) const
5781 std::vector<const DataArrayType *>arrs(2);
5782 arrs[0]=dynamic_cast<const DataArrayType *>(this); arrs[1]=other;
5783 return DataArrayDiscrete<T>::BuildIntersection(arrs);
5786 * This method can be applied on allocated with one component DataArrayInt instance.
5787 * 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.
5788 * Number of tuples of returned array is equal to size of \a this->buildUnique() + 1.
5789 * Last value of returned array is equal to \a this->getNumberOfTuples()
5792 * - \a this : [0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 5, 11]
5793 * - \a return is : [0, 1, 3, 5, 6, 8, 11, 12]
5795 * \return a newly allocated array containing the indexed array format of groups by same consecutive value.
5796 * \throw if \a this is not allocated or if \a this has not exactly one component.
5797 * \sa DataArrayInt::buildUnique, MEDCouplingSkyLineArray::groupPacks
5800 DataArrayIdType *DataArrayDiscrete<T>::indexOfSameConsecutiveValueGroups() const
5802 this->checkAllocated();
5803 if(this->getNumberOfComponents()!=1)
5804 throw INTERP_KERNEL::Exception("DataArrayInt::indexOfSameConsecutiveValueGroups : only single component allowed !");
5805 const T *pt(this->begin());
5806 const T *const ptEnd(this->end()) , * const ptBg(this->begin());
5807 // first find nb of different values in this
5808 std::size_t nbOfTuplesOut(0);
5809 while( pt != ptEnd )
5812 const T *endOfPack(std::find_if(pt+1,ptEnd,[val](T elt){ return val!=elt; }));
5816 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(nbOfTuplesOut+1,1);
5817 mcIdType *retPtr(ret->getPointer()); *retPtr++ = 0;
5819 while( pt != ptEnd )
5822 const T *endOfPack(std::find_if(pt+1,ptEnd,[val](T elt){ return val!=elt; }));
5823 *retPtr++ = ToIdType( std::distance(ptBg,endOfPack) );
5831 * This method can be applied on allocated with one component DataArrayInt instance.
5832 * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
5833 * Example : if \a this contains [1,2,2,3,3,3,3,4,5,5,7,7,7,19] the returned array will contain [1,2,3,4,5,7,19]
5835 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5836 * \throw if \a this is not allocated or if \a this has not exactly one component.
5837 * \sa DataArrayInt::buildUniqueNotSorted, DataArrayInt::indexOfSameConsecutiveValueGroups
5840 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildUnique() const
5842 this->checkAllocated();
5843 if(this->getNumberOfComponents()!=1)
5844 throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
5845 std::size_t nbOfElements(this->getNumberOfTuples());
5846 MCAuto<DataArrayType> tmp(DataArrayType::New());
5847 tmp->deepCopyFrom(*this);
5848 T *data(tmp->getPointer());
5849 T *last(std::unique(data,data+nbOfElements));
5850 MCAuto<DataArrayType> ret(DataArrayType::New());
5851 ret->alloc(std::distance(data,last),1);
5852 std::copy(data,last,ret->getPointer());
5857 * This method can be applied on allocated with one component DataArrayInt instance.
5858 * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
5860 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5862 * \throw if \a this is not allocated or if \a this has not exactly one component.
5864 * \sa DataArrayInt::buildUnique
5867 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildUniqueNotSorted() const
5869 this->checkAllocated();
5870 if(this->getNumberOfComponents()!=1)
5871 throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
5873 this->getMinMaxValues(minVal,maxVal);
5874 std::vector<bool> b(maxVal-minVal+1,false);
5875 const T *ptBg(this->begin()),*endBg(this->end());
5876 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(0,1);
5877 for(const T *pt=ptBg;pt!=endBg;pt++)
5881 ret->pushBackSilent(*pt);
5885 ret->copyStringInfoFrom(*this);
5890 * Returns a new DataArrayInt which contains size of every of groups described by \a this
5891 * "index" array. Such "index" array is returned for example by
5892 * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
5893 * "MEDCouplingUMesh::buildDescendingConnectivity" and
5894 * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
5895 * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
5896 * This method performs the reverse operation of DataArrayInt::computeOffsetsFull.
5897 * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
5898 * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
5899 * The caller is to delete this array using decrRef() as it is no more needed.
5900 * \throw If \a this is not allocated.
5901 * \throw If \a this->getNumberOfComponents() != 1.
5902 * \throw If \a this->getNumberOfTuples() < 2.
5905 * - this contains [1,3,6,7,7,9,15]
5906 * - result array contains [2,3,1,0,2,6],
5907 * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
5909 * \sa DataArrayInt::computeOffsetsFull
5912 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::deltaShiftIndex() const
5914 this->checkAllocated();
5915 if(this->getNumberOfComponents()!=1)
5916 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
5917 std::size_t nbOfElements=this->getNumberOfTuples();
5919 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 2 tuples at least must be present in 'this' !");
5920 const T *ptr=this->getConstPointer();
5921 DataArrayType *ret=DataArrayType::New();
5922 ret->alloc(nbOfElements-1,1);
5923 T *out=ret->getPointer();
5924 std::transform(ptr+1,ptr+nbOfElements,ptr,out,std::minus<T>());
5929 * Modifies \a this one-dimensional array so that value of each element \a x
5930 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5931 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
5932 * and components remains the same.<br>
5933 * This method is useful for allToAllV in MPI with contiguous policy. This method
5934 * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
5936 * \throw If \a this is not allocated.
5937 * \throw If \a this->getNumberOfComponents() != 1.
5940 * - Before \a this contains [3,5,1,2,0,8]
5941 * - After \a this contains [0,3,8,9,11,11]<br>
5942 * Note that the last element 19 = 11 + 8 is missing because size of \a this
5943 * array is retained and thus there is no space to store the last element.
5946 void DataArrayDiscrete<T>::computeOffsets()
5948 this->checkAllocated();
5949 if(this->getNumberOfComponents()!=1)
5950 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
5951 std::size_t nbOfElements=this->getNumberOfTuples();
5954 T *work=this->getPointer();
5957 for(std::size_t i=1;i<nbOfElements;i++)
5960 work[i]=work[i-1]+tmp;
5963 this->declareAsNew();
5967 * Modifies \a this one-dimensional array so that value of each element \a x
5968 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5969 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
5970 * components remains the same and number of tuples is inceamented by one.<br>
5971 * This method is useful for allToAllV in MPI with contiguous policy. This method
5972 * differs from computeOffsets() in that the number of tuples is changed by this one.
5973 * This method performs the reverse operation of DataArrayInt::deltaShiftIndex.
5974 * \throw If \a this is not allocated.
5975 * \throw If \a this->getNumberOfComponents() != 1.
5978 * - Before \a this contains [3,5,1,2,0,8]
5979 * - After \a this contains [0,3,8,9,11,11,19]<br>
5980 * \sa DataArrayInt::deltaShiftIndex
5983 void DataArrayDiscrete<T>::computeOffsetsFull()
5985 this->checkAllocated();
5986 if(this->getNumberOfComponents()!=1)
5987 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
5988 std::size_t nbOfElements=this->getNumberOfTuples();
5989 T *ret=(T *)malloc((nbOfElements+1)*sizeof(T));
5990 const T *work=this->getConstPointer();
5992 for(std::size_t i=0;i<nbOfElements;i++)
5993 ret[i+1]=work[i]+ret[i];
5994 this->useArray(ret,true,DeallocType::C_DEALLOC,nbOfElements+1,1);
5995 this->declareAsNew();
5999 * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
6000 * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
6001 * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
6002 * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
6003 * filling completely one of the ranges in \a this.
6005 * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
6006 * \param [out] rangeIdsFetched the range ids fetched
6007 * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
6008 * \a idsInInputListThatFetch is a part of input \a listOfIds.
6010 * \sa DataArrayInt::computeOffsetsFull
6013 * - \a this : [0,3,7,9,15,18]
6014 * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
6015 * - \a rangeIdsFetched result array: [0,2,4]
6016 * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
6017 * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
6021 void DataArrayDiscrete<T>::findIdsRangesInListOfIds(const DataArrayType *listOfIds, DataArrayIdType *& rangeIdsFetched, DataArrayType *& idsInInputListThatFetch) const
6024 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
6025 listOfIds->checkAllocated(); this->checkAllocated();
6026 if(listOfIds->getNumberOfComponents()!=1)
6027 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
6028 if(this->getNumberOfComponents()!=1)
6029 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
6030 MCAuto<DataArrayIdType> ret0=DataArrayIdType::New(); ret0->alloc(0,1);
6031 MCAuto<DataArrayType> ret1=DataArrayType::New(); ret1->alloc(0,1);
6032 const T *tupPtr(listOfIds->begin()), *tupEnd(listOfIds->end());
6033 const T *offBg(this->begin()),*offEnd(this->end()-1);
6034 const T *offPtr(offBg);
6035 while(tupPtr!=tupEnd && offPtr!=offEnd)
6037 if(*tupPtr==*offPtr)
6040 while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
6043 ret0->pushBackSilent(ToIdType(std::distance(offBg,offPtr)));
6044 ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
6049 { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
6051 rangeIdsFetched=ret0.retn();
6052 idsInInputListThatFetch=ret1.retn();
6056 * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
6057 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6058 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6059 * beginning within the "iota" array. And \a this is a one-dimensional array
6060 * considered as a selector of groups described by \a offsets to include into the result array.
6061 * \throw If \a offsets is NULL.
6062 * \throw If \a offsets is not allocated.
6063 * \throw If \a offsets->getNumberOfComponents() != 1.
6064 * \throw If \a offsets is not monotonically increasing.
6065 * \throw If \a this is not allocated.
6066 * \throw If \a this->getNumberOfComponents() != 1.
6067 * \throw If any element of \a this is not a valid index for \a offsets array.
6070 * - \a this: [0,2,3]
6071 * - \a offsets: [0,3,6,10,14,20]
6072 * - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
6073 * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
6074 * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) +
6075 * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) +
6076 * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
6079 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildExplicitArrByRanges(const DataArrayType *offsets) const
6082 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
6083 this->checkAllocated();
6084 if(this->getNumberOfComponents()!=1)
6085 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
6086 offsets->checkAllocated();
6087 if(offsets->getNumberOfComponents()!=1)
6088 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
6089 mcIdType othNbTuples=offsets->getNumberOfTuples()-1;
6090 mcIdType nbOfTuples=this->getNumberOfTuples();
6092 const T *work=this->getConstPointer();
6093 const T *offPtr=offsets->getConstPointer();
6094 for(mcIdType i=0;i<nbOfTuples;i++)
6097 if(val>=0 && val<othNbTuples)
6099 T delta=offPtr[val+1]-offPtr[val];
6101 retNbOftuples+=delta;
6104 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
6105 throw INTERP_KERNEL::Exception(oss.str().c_str());
6110 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
6111 oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
6112 throw INTERP_KERNEL::Exception(oss.str().c_str());
6115 MCAuto<DataArrayType> ret=DataArrayType::New();
6116 ret->alloc(retNbOftuples,1);
6117 T *retPtr=ret->getPointer();
6118 for(mcIdType i=0;i<nbOfTuples;i++)
6121 T start=offPtr[val];
6122 T off=offPtr[val+1]-start;
6123 for(T j=0;j<off;j++,retPtr++)
6130 * Returns a new DataArrayInt whose contents is computed using \a this that must be a
6131 * scaled array (monotonically increasing).
6132 from that of \a this and \a
6133 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6134 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6135 * beginning within the "iota" array. And \a this is a one-dimensional array
6136 * considered as a selector of groups described by \a offsets to include into the result array.
6137 * \throw If \a is NULL.
6138 * \throw If \a this is not allocated.
6139 * \throw If \a this->getNumberOfComponents() != 1.
6140 * \throw If \a this->getNumberOfTuples() == 0.
6141 * \throw If \a this is not monotonically increasing.
6142 * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
6145 * - \a bg , \a stop and \a step : (0,5,2)
6146 * - \a this: [0,3,6,10,14,20]
6147 * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
6150 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildExplicitArrOfSliceOnScaledArr(T bg, T stop, T step) const
6152 if(!this->isAllocated())
6153 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
6154 if(this->getNumberOfComponents()!=1)
6155 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
6156 mcIdType nbOfTuples(this->getNumberOfTuples());
6158 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
6159 const T *ids(this->begin());
6160 mcIdType nbOfEltsInSlc=DataArrayTools<T>::GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr");
6162 for(mcIdType i=0;i<nbOfEltsInSlc;i++,pos+=step)
6164 if(pos>=0 && pos<nbOfTuples-1)
6166 T delta(ids[pos+1]-ids[pos]);
6170 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
6171 throw INTERP_KERNEL::Exception(oss.str().c_str());
6176 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";
6177 throw INTERP_KERNEL::Exception(oss.str().c_str());
6180 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(sz,1);
6181 T *retPtr(ret->getPointer());
6183 for(mcIdType i=0;i<nbOfEltsInSlc;i++,pos+=step)
6185 T delta(ids[pos+1]-ids[pos]);
6186 for(T j=0;j<delta;j++,retPtr++)
6193 * Given in input ranges \a ranges, it returns a newly allocated DataArrayInt instance having one component and the same number of tuples than \a this.
6194 * For each tuple at place **i** in \a this it tells which is the first range in \a ranges that contains value \c this->getIJ(i,0) and put the result
6195 * in tuple **i** of returned DataArrayInt.
6196 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6198 * For example if \a this contains : [1,24,7,8,10,17] and \a ranges contains [(0,3),(3,8),(8,15),(15,22),(22,30)]
6199 * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6201 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6202 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6203 * \throw If offsets is a null pointer or does not have 2 components or if \a this is not allocated or \a this do not have exactly one component. To finish an exception
6204 * is thrown if no ranges in \a ranges contains value in \a this.
6206 * \sa DataArrayInt::findIdInRangeForEachTuple
6209 DataArrayIdType *DataArrayDiscrete<T>::findRangeIdForEachTuple(const DataArrayType *ranges) const
6212 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6213 if(ranges->getNumberOfComponents()!=2)
6214 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6215 this->checkAllocated();
6216 if(this->getNumberOfComponents()!=1)
6217 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6218 mcIdType nbTuples(this->getNumberOfTuples());
6219 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(nbTuples,1);
6220 mcIdType nbOfRanges(ranges->getNumberOfTuples());
6221 const T *rangesPtr=ranges->getConstPointer();
6222 mcIdType *retPtr=ret->getPointer();
6223 const T *inPtr=this->getConstPointer();
6224 for(mcIdType i=0;i<nbTuples;i++,retPtr++)
6228 for(mcIdType j=0;j<nbOfRanges && !found;j++)
6229 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6230 { *retPtr=j; found=true; }
6235 std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6236 throw INTERP_KERNEL::Exception(oss.str().c_str());
6243 * Given in input ranges \a ranges, it returns a newly allocated DataArrayInt instance having one component and the same number of tuples than \a this.
6244 * For each tuple at place **i** in \a this it tells which is the sub position of the first range in \a ranges that contains value \c this->getIJ(i,0) and put the result
6245 * in tuple **i** of returned DataArrayInt.
6246 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6248 * For example if \a this contains : [1,24,7,8,10,17] and \a ranges contains [(0,3),(3,8),(8,15),(15,22),(22,30)]
6249 * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6250 * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6252 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6253 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6254 * \throw If offsets is a null pointer or does not have 2 components or if \a this is not allocated or \a this do not have exactly one component. To finish an exception
6255 * is thrown if no ranges in \a ranges contains value in \a this.
6256 * \sa DataArrayInt::findRangeIdForEachTuple
6259 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::findIdInRangeForEachTuple(const DataArrayType *ranges) const
6262 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6263 if(ranges->getNumberOfComponents()!=2)
6264 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6265 this->checkAllocated();
6266 if(this->getNumberOfComponents()!=1)
6267 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6268 mcIdType nbTuples=this->getNumberOfTuples();
6269 MCAuto<DataArrayType> ret=DataArrayType::New(); ret->alloc(nbTuples,1);
6270 mcIdType nbOfRanges=ranges->getNumberOfTuples();
6271 const T *rangesPtr=ranges->getConstPointer();
6272 T *retPtr=ret->getPointer();
6273 const T *inPtr=this->getConstPointer();
6274 for(mcIdType i=0;i<nbTuples;i++,retPtr++)
6278 for(mcIdType j=0;j<nbOfRanges && !found;j++)
6279 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6280 { *retPtr=val-rangesPtr[2*j]; found=true; }
6285 std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6286 throw INTERP_KERNEL::Exception(oss.str().c_str());
6293 * \b WARNING this method is a \b non \a const \b method. This method works tuple by tuple. Each tuple is expected to be pairs (number of components must be equal to 2).
6294 * This method rearrange each pair in \a this so that, tuple with id \b tid will be after the call \c this->getIJ(tid,0)==this->getIJ(tid-1,1) and \c this->getIJ(tid,1)==this->getIJ(tid+1,0).
6295 * If it is impossible to reach such condition an exception will be thrown ! \b WARNING In case of throw \a this can be partially modified !
6296 * If this method has correctly worked, \a this will be able to be considered as a linked list.
6297 * This method does nothing if number of tuples is lower of equal to 1.
6299 * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internally the connectivity without any coordinates consideration.
6301 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::sortToHaveConsecutivePairs(), DataArrayInt::fromLinkedListOfPairToList
6304 void DataArrayDiscrete<T>::sortEachPairToMakeALinkedList()
6306 this->checkAllocated();
6307 if(this->getNumberOfComponents()!=2)
6308 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6309 mcIdType nbOfTuples(this->getNumberOfTuples());
6312 T *conn(this->getPointer());
6313 for(mcIdType i=1;i<nbOfTuples;i++,conn+=2)
6317 if(conn[2]==conn[3])
6319 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6320 throw INTERP_KERNEL::Exception(oss.str().c_str());
6322 if(conn[2]!=conn[1] && conn[3]!=conn[1])
6324 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : There is no common noeud between the tuple #" << i << " and the tuple #" << i + 1 << ". Need call DataArrayInt::sortToHaveConsecutivePairs() ";
6325 throw INTERP_KERNEL::Exception(oss.str().c_str());
6327 if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6328 std::swap(conn[2],conn[3]);
6329 //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6330 if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6332 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6333 throw INTERP_KERNEL::Exception(oss.str().c_str());
6338 if(conn[0]==conn[1] || conn[2]==conn[3])
6339 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6342 s.insert(conn,conn+4);
6344 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6345 if(std::count(conn,conn+4,conn[0])==2)
6350 if(conn[2]==conn[0])
6354 std::copy(tmp,tmp+4,conn);
6357 {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6358 if(conn[1]==conn[3])
6359 std::swap(conn[2],conn[3]);
6366 * This method is the improvement from the method sortEachPairToMakeALinkedList().
6368 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::sortEachPairToMakeALinkedList(), DataArrayInt::fromLinkedListOfPairToList
6371 void DataArrayDiscrete<T>::sortToHaveConsecutivePairs()
6373 this->checkAllocated();
6374 if(this->getNumberOfComponents()!=2)
6375 throw INTERP_KERNEL::Exception("DataArrayInt::sortToHaveConsecutivePairs : Only works on DataArrayInt instance with nb of components equal to 2 !");
6376 mcIdType nbOfTuples(this->getNumberOfTuples());
6377 T *thisPtr(this->getPointer());
6378 mcIdType idOfLastTuple = 0;
6379 std::pair<T*,T*> tmp;
6380 if(thisPtr[0]==thisPtr[1])
6382 THROW_IK_EXCEPTION("DataArrayInt::sortToHaveConsecutivePairs : In the first tuple presence of a pair filled with same ids !");
6384 while(idOfLastTuple < nbOfTuples-1)
6386 mcIdType i = idOfLastTuple+1;
6387 tmp.first = &thisPtr[2*i];
6388 tmp.second = &thisPtr[2*i+1];
6389 if(std::get<0>(tmp)[0] == std::get<1>(tmp)[0])
6391 THROW_IK_EXCEPTION("DataArrayInt::sortToHaveConsecutivePairs : In the tuple #" << i << " presence of a pair filled with same ids !");
6393 while((this->getIJ(idOfLastTuple,1) != std::get<0>(tmp)[0] &&
6394 this->getIJ(idOfLastTuple,1) != std::get<1>(tmp)[0]) &&
6397 std::swap(std::get<0>(tmp)[0],thisPtr[2*(i+1)]);
6398 std::swap(std::get<1>(tmp)[0],thisPtr[2*(i+1)+1]);
6401 if(i < nbOfTuples-1 ||
6402 this->getIJ(idOfLastTuple,1) == std::get<0>(tmp)[0] ||
6403 this->getIJ(idOfLastTuple,1) == std::get<1>(tmp)[0])
6405 if(this->getIJ(idOfLastTuple,1) != std::get<0>(tmp)[0])
6406 std::swap(std::get<0>(tmp)[0],std::get<1>(tmp)[0]);
6411 THROW_IK_EXCEPTION("DataArrayInt::sortToHaveConsecutivePairs : not found the tuple which have the common noeud = " << this->getIJ(idOfLastTuple,1));
6417 * \a this is expected to be a correctly linked list of pairs.
6419 * \sa DataArrayInt::sortEachPairToMakeALinkedList
6422 MCAuto<typename Traits<T>::ArrayType> DataArrayDiscrete<T>::fromLinkedListOfPairToList() const
6424 this->checkAllocated();
6425 this->checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6426 mcIdType nbTuples(this->getNumberOfTuples());
6428 throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6429 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(nbTuples+1,1);
6430 const T *thisPtr(this->begin());
6431 T *retPtr(ret->getPointer());
6432 retPtr[0]=thisPtr[0];
6433 for(mcIdType i=0;i<nbTuples;i++)
6435 retPtr[i+1]=thisPtr[2*i+1];
6437 if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6439 std::ostringstream oss; oss << "DataArrayInt::fromLinkedListOfPairToList : this is not a proper linked list of pair. The link is broken between tuple #" << i << " and tuple #" << i+1 << " ! Call sortEachPairToMakeALinkedList ?";
6440 throw INTERP_KERNEL::Exception(oss.str());
6447 * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6448 * But the number of components can be different from one.
6449 * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6452 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::getDifferentValues() const
6454 this->checkAllocated();
6456 ret.insert(this->begin(),this->end());
6457 MCAuto<DataArrayType> ret2=DataArrayType::New();
6458 ret2->alloc(ret.size(),1);
6459 std::copy(ret.begin(),ret.end(),ret2->getPointer());
6464 * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6465 * them it tells which tuple id have this id.
6466 * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6467 * This method returns two arrays having same size.
6468 * 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.
6469 * 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]]
6472 std::vector<DataArrayIdType *> DataArrayDiscrete<T>::partitionByDifferentValues(std::vector<T>& differentIds) const
6474 this->checkAllocated();
6475 if(this->getNumberOfComponents()!=1)
6476 throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6478 std::map<T,mcIdType> m,m2,m3;
6479 for(const T *w=this->begin();w!=this->end();w++)
6481 differentIds.resize(m.size());
6482 std::vector<DataArrayIdType *> ret(m.size());
6483 std::vector<mcIdType *> retPtr(m.size());
6484 for(typename std::map<T,mcIdType>::const_iterator it=m.begin();it!=m.end();it++,id++)
6487 ret[id]=DataArrayIdType::New();
6488 ret[id]->alloc((*it).second,1);
6489 retPtr[id]=ret[id]->getPointer();
6490 differentIds[id]=(*it).first;
6493 for(const T *w=this->begin();w!=this->end();w++,id++)
6495 retPtr[m2[*w]][m3[*w]++]=id;
6501 * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6502 * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6504 * \param [in] nbOfSlices - number of slices expected.
6505 * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6507 * \sa DataArray::GetSlice
6508 * \throw If \a this is not allocated or not with exactly one component.
6509 * \throw If an element in \a this if < 0.
6512 std::vector< std::pair<mcIdType,mcIdType> > DataArrayDiscrete<T>::splitInBalancedSlices(mcIdType nbOfSlices) const
6514 if(!this->isAllocated() || this->getNumberOfComponents()!=1)
6515 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6517 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6518 T sum(this->accumulate((std::size_t)0));
6519 mcIdType nbOfTuples(this->getNumberOfTuples());
6520 T sumPerSlc(sum/FromIdType<T>(nbOfSlices));
6522 const T *w(this->begin());
6523 std::vector< std::pair<mcIdType,mcIdType> > ret(nbOfSlices);
6524 for(mcIdType i=0;i<nbOfSlices;i++)
6526 std::pair<mcIdType, mcIdType> p(pos,-1);
6528 while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6532 p.second=nbOfTuples;
6539 * Modify \a this array so that each value becomes a modulus of division of this value by
6540 * a value of another DataArrayInt. There are 3 valid cases.
6541 * 1. The arrays have same number of tuples and components. Then each value of
6542 * \a this array is divided by the corresponding value of \a other one, i.e.:
6543 * _a_ [ i, j ] %= _other_ [ i, j ].
6544 * 2. The arrays have same number of tuples and \a other array has one component. Then
6545 * _a_ [ i, j ] %= _other_ [ i, 0 ].
6546 * 3. The arrays have same number of components and \a other array has one tuple. Then
6547 * _a_ [ i, j ] %= _a2_ [ 0, j ].
6549 * \warning No check of division by zero is performed!
6550 * \param [in] other - a divisor array.
6551 * \throw If \a other is NULL.
6552 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
6553 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
6554 * \a other has number of both tuples and components not equal to 1.
6557 void DataArrayDiscrete<T>::modulusEqual(const DataArrayType *other)
6560 throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
6561 const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
6562 this->checkAllocated(); other->checkAllocated();
6563 mcIdType nbOfTuple(this->getNumberOfTuples());
6564 mcIdType nbOfTuple2(other->getNumberOfTuples());
6565 std::size_t nbOfComp(this->getNumberOfComponents());
6566 std::size_t nbOfComp2(other->getNumberOfComponents());
6567 if(nbOfTuple==nbOfTuple2)
6569 if(nbOfComp==nbOfComp2)
6571 std::transform(this->begin(),this->end(),other->begin(),this->getPointer(),std::modulus<T>());
6573 else if(nbOfComp2==1)
6575 if(nbOfComp2==nbOfComp)
6577 T *ptr=this->getPointer();
6578 const T *ptrc=other->getConstPointer();
6579 for(mcIdType i=0;i<nbOfTuple;i++)
6580 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind(std::modulus<T>(),std::placeholders::_1,*ptrc++));
6583 throw INTERP_KERNEL::Exception(msg);
6586 throw INTERP_KERNEL::Exception(msg);
6588 else if(nbOfTuple2==1)
6590 T *ptr=this->getPointer();
6591 const T *ptrc=other->getConstPointer();
6592 for(mcIdType i=0;i<nbOfTuple;i++)
6593 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<T>());
6596 throw INTERP_KERNEL::Exception(msg);
6597 this->declareAsNew();
6601 * Apply pow on values of another DataArrayInt to values of \a this one.
6603 * \param [in] other - an array to pow to \a this one.
6604 * \throw If \a other is NULL.
6605 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
6606 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
6607 * \throw If there is a negative value in \a other.
6610 void DataArrayDiscrete<T>::powEqual(const DataArrayType *other)
6613 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
6614 mcIdType nbOfTuple=this->getNumberOfTuples();
6615 mcIdType nbOfTuple2=other->getNumberOfTuples();
6616 std::size_t nbOfComp=this->getNumberOfComponents();
6617 std::size_t nbOfComp2=other->getNumberOfComponents();
6618 if(nbOfTuple!=nbOfTuple2)
6619 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
6620 if(nbOfComp!=1 || nbOfComp2!=1)
6621 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
6622 T *ptr=this->getPointer();
6623 const T *ptrc=other->begin();
6624 for(mcIdType i=0;i<nbOfTuple;i++,ptrc++,ptr++)
6629 for(T j=0;j<*ptrc;j++)
6635 std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
6636 throw INTERP_KERNEL::Exception(oss.str().c_str());
6639 this->declareAsNew();
6642 ////////////////////////////////////
6644 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6648 void DataArrayDiscrete<T>::getTinySerializationIntInformation(std::vector<mcIdType>& tinyInfo) const
6651 if(this->isAllocated())
6653 tinyInfo[0]=this->getNumberOfTuples();
6654 tinyInfo[1]=ToIdType(this->getNumberOfComponents());
6664 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6668 void DataArrayDiscrete<T>::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
6670 if(this->isAllocated())
6672 std::size_t nbOfCompo(this->getNumberOfComponents());
6673 tinyInfo.resize(nbOfCompo+1);
6674 tinyInfo[0]=this->getName();
6675 for(std::size_t i=0;i<nbOfCompo;i++)
6676 tinyInfo[i+1]=this->getInfoOnComponent(i);
6681 tinyInfo[0]=this->getName();
6686 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6687 * This method returns if a feeding is needed.
6690 bool DataArrayDiscrete<T>::resizeForUnserialization(const std::vector<mcIdType>& tinyInfoI)
6692 mcIdType nbOfTuple=tinyInfoI[0];
6693 mcIdType nbOfComp=tinyInfoI[1];
6694 if(nbOfTuple!=-1 || nbOfComp!=-1)
6696 this->alloc(nbOfTuple,nbOfComp);
6703 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6704 * This method returns if a feeding is needed.
6707 void DataArrayDiscrete<T>::finishUnserialization(const std::vector<mcIdType>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
6709 this->setName(tinyInfoS[0]);
6710 if(this->isAllocated())
6712 mcIdType nbOfCompo=tinyInfoI[1];
6713 for(mcIdType i=0;i<nbOfCompo;i++)
6714 this->setInfoOnComponent(i,tinyInfoS[i+1]);
6718 ////////////////////////////////////
6721 * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
6724 * \param [in] a1 - an array to pow up.
6725 * \param [in] a2 - another array to sum up.
6726 * \return DataArrayInt * - the new instance of DataArrayInt.
6727 * The caller is to delete this result array using decrRef() as it is no more
6729 * \throw If either \a a1 or \a a2 is NULL.
6730 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6731 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
6732 * \throw If there is a negative value in \a a2.
6735 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Pow(const DataArrayType *a1, const DataArrayType *a2)
6738 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
6739 mcIdType nbOfTuple=a1->getNumberOfTuples();
6740 mcIdType nbOfTuple2=a2->getNumberOfTuples();
6741 std::size_t nbOfComp=a1->getNumberOfComponents();
6742 std::size_t nbOfComp2=a2->getNumberOfComponents();
6743 if(nbOfTuple!=nbOfTuple2)
6744 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
6745 if(nbOfComp!=1 || nbOfComp2!=1)
6746 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
6747 MCAuto<DataArrayType> ret=DataArrayType::New(); ret->alloc(nbOfTuple,1);
6748 const T *ptr1(a1->begin()),*ptr2(a2->begin());
6749 T *ptr=ret->getPointer();
6750 for(mcIdType i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
6755 for(T j=0;j<*ptr2;j++)
6761 std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
6762 throw INTERP_KERNEL::Exception(oss.str().c_str());
6769 * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6771 * 1. The arrays have same number of tuples and components. Then each value of
6772 * the result array (_a_) is a division of the corresponding values of \a a1 and
6773 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6774 * 2. The arrays have same number of tuples and one array, say _a2_, has one
6776 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6777 * 3. The arrays have same number of components and one array, say _a2_, has one
6779 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6781 * Info on components is copied either from the first array (in the first case) or from
6782 * the array with maximal number of elements (getNbOfElems()).
6783 * \warning No check of division by zero is performed!
6784 * \param [in] a1 - a dividend array.
6785 * \param [in] a2 - a divisor array.
6786 * \return DataArrayInt * - the new instance of DataArrayInt.
6787 * The caller is to delete this result array using decrRef() as it is no more
6789 * \throw If either \a a1 or \a a2 is NULL.
6790 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6791 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6792 * none of them has number of tuples or components equal to 1.
6795 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Modulus(const DataArrayType *a1, const DataArrayType *a2)
6798 throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6799 mcIdType nbOfTuple1(a1->getNumberOfTuples());
6800 mcIdType nbOfTuple2(a2->getNumberOfTuples());
6801 std::size_t nbOfComp1(a1->getNumberOfComponents());
6802 std::size_t nbOfComp2(a2->getNumberOfComponents());
6803 if(nbOfTuple2==nbOfTuple1)
6805 if(nbOfComp1==nbOfComp2)
6807 MCAuto<DataArrayType> ret=DataArrayType::New();
6808 ret->alloc(nbOfTuple2,nbOfComp1);
6809 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<T>());
6810 ret->copyStringInfoFrom(*a1);
6813 else if(nbOfComp2==1)
6815 MCAuto<DataArrayType> ret=DataArrayType::New();
6816 ret->alloc(nbOfTuple1,nbOfComp1);
6817 const T *a2Ptr=a2->getConstPointer();
6818 const T *a1Ptr=a1->getConstPointer();
6819 T *res=ret->getPointer();
6820 for(mcIdType i=0;i<nbOfTuple1;i++)
6821 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind(std::modulus<T>(),std::placeholders::_1,a2Ptr[i]));
6822 ret->copyStringInfoFrom(*a1);
6827 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6831 else if(nbOfTuple2==1)
6833 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6834 MCAuto<DataArrayType> ret=DataArrayType::New();
6835 ret->alloc(nbOfTuple1,nbOfComp1);
6836 const T *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6837 T *pt=ret->getPointer();
6838 for(mcIdType i=0;i<nbOfTuple1;i++)
6839 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<T>());
6840 ret->copyStringInfoFrom(*a1);
6845 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
6851 * 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
6852 * input array \a ids2.
6853 * \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.
6854 * 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
6856 * In case of success both assertion will be true (no throw) :
6857 * \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
6858 * \c ret->transformWithIndArr(ids2)->isEqual(ids1)
6861 * - \a ids1 : [3,1,103,4,6,10,-7,205]
6862 * - \a ids2 : [-7,1,205,10,6,3,103,4]
6863 * - \a return is : [5,1,6,7,4,3,0,2] because ids2[5]==ids1[0], ids2[1]==ids1[1], ids2[6]==ids1[2]...
6865 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6866 * array using decrRef() as it is no more needed.
6867 * \throw If either ids1 or ids2 is null not allocated or not with one components.
6869 * \sa DataArrayInt::findIdForEach, DataArrayInt::FindPermutationFromFirstToSecondDuplicate, DataArrayInt::rankOfElementInThis
6872 DataArrayIdType *DataArrayDiscrete<T>::FindPermutationFromFirstToSecond(const DataArrayType *ids1, const DataArrayType *ids2)
6875 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
6876 if(!ids1->isAllocated() || !ids2->isAllocated())
6877 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
6878 if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
6879 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
6880 if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
6882 std::ostringstream oss; oss << "DataArrayInt::FindPermutationFromFirstToSecond : first array has " << ids1->getNumberOfTuples() << " tuples and the second one " << ids2->getNumberOfTuples() << " tuples ! No chance to find a permutation between the 2 arrays !";
6883 throw INTERP_KERNEL::Exception(oss.str().c_str());
6885 MCAuto<DataArrayType> c1(ids1->deepCopy());
6886 MCAuto<DataArrayType> c2(ids2->deepCopy());
6887 c1->sort(true); c2->sort(true);
6888 if(!c1->isEqualWithoutConsideringStr(*c2))
6889 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
6890 MCAuto<DataArrayIdType> p1=ids1->checkAndPreparePermutation();
6891 MCAuto<DataArrayIdType> p2=ids2->checkAndPreparePermutation();
6892 p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
6893 p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
6898 * 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
6899 * input array \a ids2.
6900 * \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.
6901 * 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
6903 * The difference with DataArrayInt::FindPermutationFromFirstToSecond is that this method supports multiple same values in \a ids1 and \a ids2 whereas
6904 * DataArrayInt::FindPermutationFromFirstToSecond doesn't. It implies that this method my be slower than the DataArrayInt::FindPermutationFromFirstToSecond one.
6906 * In case of success both assertion will be true (no throw) :
6907 * \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
6908 * \c ret->transformWithIndArr(ids2)->isEqual(ids1)
6911 * - \a ids1 : [5, 3, 2, 1, 4, 5, 2, 1, 0, 11, 5, 4]
6912 * - \a ids2 : [0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 5, 11]
6913 * - \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]...
6915 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6916 * array using decrRef() as it is no more needed.
6917 * \throw If either ids1 or ids2 is null not allocated or not with one components.
6919 * \sa DataArrayInt::findIdForEach, DataArrayInt::FindPermutationFromFirstToSecond, DataArrayInt::occurenceRankInThis
6922 DataArrayIdType *DataArrayDiscrete<T>::FindPermutationFromFirstToSecondDuplicate(const DataArrayType *ids1, const DataArrayType *ids2)
6925 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecondDuplicate : the two input arrays must be not null !");
6926 constexpr char MSG0[] = "DataArrayInt::FindPermutationFromFirstToSecondDuplicate :";
6927 ids1->checkAllocated(); ids2->checkAllocated();
6928 ids1->checkNbOfComps(1,MSG0); ids2->checkNbOfComps(1,MSG0);
6929 mcIdType nbTuples(ids1->getNumberOfTuples());
6930 if(nbTuples != ids2->getNumberOfTuples())
6932 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 !";
6933 throw INTERP_KERNEL::Exception(oss.str().c_str());
6935 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(nbTuples,1);
6936 MCAuto<DataArrayIdType> oids2(ids2->occurenceRankInThis());
6937 std::map< std::pair<T,mcIdType>, mcIdType> m;
6939 const mcIdType *oids2Ptr(oids2->begin());
6940 for(const T * it2 = ids2->begin() ; it2 != ids2->end() ; ++it2, ++oids2Ptr, ++pos)
6941 m[{*it2,*oids2Ptr}] = pos;
6942 mcIdType *retPtr(ret->getPointer());
6944 std::map<T,mcIdType> mOccurence1; // see DataArrayInt::occurenceRankInThis : avoid to compute additionnal temporary array
6946 for(const T * it1 = ids1->begin() ; it1 != ids1->end() ; ++it1, ++retPtr)
6948 auto it = mOccurence1.find(*it1);
6950 if( it == mOccurence1.end() )
6953 mOccurence1[*it1] = 1;
6957 occRk1 = (*it).second++;
6960 auto it2 = m.find({*it1,occRk1});
6963 *retPtr = (*it2).second;
6967 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 !";
6968 throw INTERP_KERNEL::Exception(oss.str());
6976 * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
6977 * This map, if applied to \a start array, would make it sorted. For example, if
6978 * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
6979 * [5,6,0,3,2,7,1,4].
6980 * \param [in] start - pointer to the first element of the array for which the
6981 * permutation map is computed.
6982 * \param [in] end - pointer specifying the end of the array \a start, so that
6983 * the last value of \a start is \a end[ -1 ].
6984 * \return mcIdType * - the result permutation array that the caller is to delete as it is no
6986 * \throw If there are equal values in the input array.
6989 mcIdType *DataArrayDiscrete<T>::CheckAndPreparePermutation(const T *start, const T *end)
6991 std::size_t sz=std::distance(start,end);
6992 mcIdType *ret=(mcIdType *)malloc(sz*sizeof(mcIdType));
6994 std::copy(start,end,work);
6995 std::sort(work,work+sz);
6996 if(std::unique(work,work+sz)!=work+sz)
7000 throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
7002 std::map<T,mcIdType> m;
7003 for(T *workPt=work;workPt!=work+sz;workPt++)
7004 m[*workPt]=ToIdType(std::distance(work,workPt));
7005 mcIdType *iter2=ret;
7006 for(const T *iter=start;iter!=end;iter++,iter2++)
7013 * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
7014 * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
7015 * offsetA2</em> and (2)
7016 * the number of component in the result array is same as that of each of given arrays.
7017 * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
7018 * Info on components is copied from the first of the given arrays. Number of components
7019 * in the given arrays must be the same.
7020 * \param [in] a1 - an array to include in the result array.
7021 * \param [in] a2 - another array to include in the result array.
7022 * \param [in] offsetA2 - number of tuples of \a a2 to skip.
7023 * \return DataArrayInt * - the new instance of DataArrayInt.
7024 * The caller is to delete this result array using decrRef() as it is no more
7026 * \throw If either \a a1 or \a a2 is NULL.
7027 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
7030 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Aggregate(const DataArrayType *a1, const DataArrayType *a2, T offsetA2)
7033 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
7034 std::size_t nbOfComp(a1->getNumberOfComponents());
7035 if(nbOfComp!=a2->getNumberOfComponents())
7036 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
7037 mcIdType nbOfTuple1(a1->getNumberOfTuples()),nbOfTuple2(a2->getNumberOfTuples());
7038 MCAuto<DataArrayType> ret(DataArrayType::New());
7039 ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
7040 T *pt=std::copy(a1->begin(),a1->end(),ret->getPointer());
7041 std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
7042 ret->copyStringInfoFrom(*a1);
7047 * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
7048 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
7049 * the number of component in the result array is same as that of each of given arrays.
7050 * Info on components is copied from the first of the given arrays. Number of components
7051 * in the given arrays must be the same.
7052 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
7053 * not the object itself.
7054 * \param [in] arr - a sequence of arrays to include in the result array.
7055 * \return DataArrayInt * - the new instance of DataArrayInt.
7056 * The caller is to delete this result array using decrRef() as it is no more
7058 * \throw If all arrays within \a arr are NULL.
7059 * \throw If getNumberOfComponents() of arrays within \a arr.
7062 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Aggregate(const std::vector<const DataArrayType *>& arr)
7064 std::vector<const DataArrayType *> a;
7065 for(typename std::vector<const DataArrayType *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7069 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
7070 typename std::vector<const DataArrayType *>::const_iterator it=a.begin();
7071 std::size_t nbOfComp((*it)->getNumberOfComponents());
7072 mcIdType nbt((*it++)->getNumberOfTuples());
7073 for(;it!=a.end();it++)
7075 if((*it)->getNumberOfComponents()!=nbOfComp)
7076 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
7077 nbt+=(*it)->getNumberOfTuples();
7079 MCAuto<DataArrayType> ret=DataArrayType::New();
7080 ret->alloc(nbt,nbOfComp);
7081 T *pt=ret->getPointer();
7082 for(it=a.begin();it!=a.end();it++)
7083 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
7084 ret->copyStringInfoFrom(*(a[0]));
7089 * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
7090 * A packed index array is an allocated array with one component, and at least one tuple. The first element
7091 * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
7092 * This method is useful for users that want to aggregate a pair of DataArrayInt representing an indexed data (typically nodal connectivity index in unstructured meshes.
7094 * \return DataArrayInt * - a new object to be managed by the caller.
7097 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::AggregateIndexes(const std::vector<const DataArrayType *>& arrs)
7100 for(typename std::vector<const DataArrayType *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
7104 (*it4)->checkAllocated();
7105 if((*it4)->getNumberOfComponents()!=1)
7107 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
7108 throw INTERP_KERNEL::Exception(oss.str().c_str());
7110 mcIdType nbTupl((*it4)->getNumberOfTuples());
7113 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
7114 throw INTERP_KERNEL::Exception(oss.str().c_str());
7116 if((*it4)->front()!=0)
7118 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
7119 throw INTERP_KERNEL::Exception(oss.str().c_str());
7125 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
7126 throw INTERP_KERNEL::Exception(oss.str().c_str());
7130 throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
7131 MCAuto<DataArrayType> ret=DataArrayType::New();
7132 ret->alloc(retSz,1);
7133 T *pt=ret->getPointer(); *pt++=0;
7134 for(typename std::vector<const DataArrayType *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
7135 pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind(std::plus<T>(),std::placeholders::_1,pt[-1]));
7136 ret->copyStringInfoFrom(*(arrs[0]));
7141 * Returns a new DataArrayInt which contains all elements of given one-dimensional
7142 * arrays. The result array does not contain any duplicates and its values
7143 * are sorted in ascending order.
7144 * \param [in] arr - sequence of DataArrayInt's to unite.
7145 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7146 * array using decrRef() as it is no more needed.
7147 * \throw If any \a arr[i] is not allocated.
7148 * \throw If \a arr[i]->getNumberOfComponents() != 1.
7151 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::BuildUnion(const std::vector<const DataArrayType *>& arr)
7153 std::vector<const DataArrayType *> a;
7154 for(typename std::vector<const DataArrayType *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7157 for(typename std::vector<const DataArrayType *>::const_iterator it=a.begin();it!=a.end();it++)
7159 (*it)->checkAllocated();
7160 if((*it)->getNumberOfComponents()!=1)
7161 throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
7165 for(typename std::vector<const DataArrayType *>::const_iterator it=a.begin();it!=a.end();it++)
7167 const T *pt=(*it)->getConstPointer();
7168 mcIdType nbOfTuples((*it)->getNumberOfTuples());
7169 r.insert(pt,pt+nbOfTuples);
7171 DataArrayType *ret=DataArrayType::New();
7172 ret->alloc(r.size(),1);
7173 std::copy(r.begin(),r.end(),ret->getPointer());
7178 * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
7179 * arrays. The result array does not contain any duplicates and its values
7180 * are sorted in ascending order.
7181 * \param [in] arr - sequence of DataArrayInt's to intersect.
7182 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7183 * array using decrRef() as it is no more needed.
7184 * \throw If any \a arr[i] is not allocated.
7185 * \throw If \a arr[i]->getNumberOfComponents() != 1.
7188 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::BuildIntersection(const std::vector<const DataArrayType *>& arr)
7190 std::vector<const DataArrayType *> a;
7191 for(typename std::vector<const DataArrayType *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7194 for(typename std::vector<const DataArrayType *>::const_iterator it=a.begin();it!=a.end();it++)
7196 (*it)->checkAllocated();
7197 if((*it)->getNumberOfComponents()!=1)
7198 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
7202 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single not null element in array ! For safety reasons exception is raised !");
7205 for(typename std::vector<const DataArrayType *>::const_iterator it=a.begin();it!=a.end();it++)
7207 const T *pt=(*it)->getConstPointer();
7208 mcIdType nbOfTuples((*it)->getNumberOfTuples());
7209 std::set<T> s1(pt,pt+nbOfTuples);
7213 std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
7219 DataArrayType *ret(DataArrayType::New());
7220 ret->alloc(r.size(),1);
7221 std::copy(r.begin(),r.end(),ret->getPointer());
7226 * This method allows to put a vector of vector of integer into a more compact data structure (skyline).
7227 * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<mcIdType> >.
7229 * \param [in] v the input data structure to be translate into skyline format.
7230 * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
7231 * \param [out] dataIndex the second element of the skyline format.
7234 void DataArrayDiscrete<T>::PutIntoToSkylineFrmt(const std::vector< std::vector<T> >& v, DataArrayType *& data, DataArrayIdType *& dataIndex)
7236 std::size_t sz(v.size());
7237 MCAuto<DataArrayType> retDat(DataArrayType::New());
7238 MCAuto<DataArrayIdType> retIdx(DataArrayIdType::New());
7239 retIdx->alloc(sz+1,1);
7240 mcIdType *ptid(retIdx->getPointer()); *ptid=0;
7241 for(std::size_t i=0;i<sz;i++,ptid++)
7242 ptid[1]=ptid[0]+ToIdType(v[i].size());
7243 retDat->alloc(retIdx->back(),1);
7244 T *pt=retDat->getPointer();
7245 for(std::size_t i=0;i<sz;i++)
7246 pt=std::copy(v[i].begin(),v[i].end(),pt);
7247 data=retDat.retn(); dataIndex=retIdx.retn();
7251 * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn
7252 * (\ref numbering-indirect).
7253 * This method returns the result of the extraction ( specified by a set of ids in [\b idsOfSelectBg , \b idsOfSelectEnd ) ).
7254 * The selection of extraction is done standardly in new2old format.
7255 * This method returns indexed arrays (\ref numbering-indirect) using 2 arrays (arrOut,arrIndexOut).
7257 * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
7258 * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
7259 * \param [in] arrIn arr origin array from which the extraction will be done.
7260 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7261 * \param [out] arrOut the resulting array
7262 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
7263 * \sa DataArrayInt::ExtractFromIndexedArraysSlice
7266 void DataArrayDiscrete<T>::ExtractFromIndexedArrays(const mcIdType *idsOfSelectBg, const mcIdType *idsOfSelectEnd,
7267 const DataArrayType *arrIn, const DataArrayIdType *arrIndxIn,
7268 DataArrayType* &arrOut, DataArrayIdType* &arrIndexOut)
7270 if(!arrIn || !arrIndxIn)
7271 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArrays : input pointer is NULL !");
7272 arrIn->checkAllocated(); arrIndxIn->checkAllocated();
7273 if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1)
7274 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArrays : input arrays must have exactly one component !");
7275 std::size_t sz=std::distance(idsOfSelectBg,idsOfSelectEnd);
7276 const T *arrInPtr=arrIn->begin();
7277 const mcIdType *arrIndxPtr=arrIndxIn->begin();
7278 mcIdType nbOfGrps=arrIndxIn->getNumberOfTuples()-1;
7280 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArrays : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !");
7281 mcIdType maxSizeOfArr(arrIn->getNumberOfTuples());
7282 MCAuto<DataArrayType> arro=DataArrayType::New();
7283 MCAuto<DataArrayIdType> arrIo=DataArrayIdType::New();
7284 arrIo->alloc(sz+1,1);
7285 const mcIdType *idsIt=idsOfSelectBg;
7286 mcIdType *work=arrIo->getPointer();
7289 for(std::size_t i=0;i<sz;i++,work++,idsIt++)
7291 if(*idsIt>=0 && *idsIt<nbOfGrps)
7292 lgth+=arrIndxPtr[*idsIt+1]-arrIndxPtr[*idsIt];
7295 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " ! Must be in [0," << nbOfGrps << ") !";
7296 throw INTERP_KERNEL::Exception(oss.str());
7302 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " and at this pos arrIndxIn[" << *idsIt;
7303 oss << "+1]-arrIndxIn[" << *idsIt << "] < 0 ! The input index array is bugged !";
7304 throw INTERP_KERNEL::Exception(oss.str());
7307 arro->alloc(lgth,1);
7308 T *data=arro->getPointer();
7309 idsIt=idsOfSelectBg;
7310 for(std::size_t i=0;i<sz;i++,idsIt++)
7312 if(arrIndxPtr[*idsIt]>=0 && arrIndxPtr[*idsIt+1]<=maxSizeOfArr)
7313 data=std::copy(arrInPtr+arrIndxPtr[*idsIt],arrInPtr+arrIndxPtr[*idsIt+1],data);
7316 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " arrIndx[" << *idsIt << "] must be >= 0 and arrIndx[";
7317 oss << *idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!";
7318 throw INTERP_KERNEL::Exception(oss.str());
7322 arrIndexOut=arrIo.retn();
7326 * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn
7327 * (\ref numbering-indirect).
7328 * This method returns the result of the extraction ( specified by a set of ids with a slice given by \a idsOfSelectStart, \a idsOfSelectStop and \a idsOfSelectStep ).
7329 * The selection of extraction is done standardly in new2old format.
7330 * This method returns indexed arrays (\ref numbering-indirect) using 2 arrays (arrOut,arrIndexOut).
7332 * \param [in] idsOfSelectStart begin of set of ids of the input extraction (included)
7333 * \param [in] idsOfSelectStop end of set of ids of the input extraction (excluded)
7334 * \param [in] idsOfSelectStep step of set of ids of the input extraction
7335 * \param [in] arrIn arr origin array from which the extraction will be done.
7336 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7337 * \param [out] arrOut the resulting array
7338 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
7339 * \sa DataArrayInt::ExtractFromIndexedArrays
7342 void DataArrayDiscrete<T>::ExtractFromIndexedArraysSlice(mcIdType idsOfSelectStart, mcIdType idsOfSelectStop, mcIdType idsOfSelectStep,
7343 const DataArrayType *arrIn, const DataArrayIdType *arrIndxIn,
7344 DataArrayType* &arrOut, DataArrayIdType* &arrIndexOut)
7346 if(!arrIn || !arrIndxIn)
7347 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArraysSlice : input pointer is NULL !");
7348 arrIn->checkAllocated(); arrIndxIn->checkAllocated();
7349 if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1)
7350 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArraysSlice : input arrays must have exactly one component !");
7351 mcIdType sz=DataArray::GetNumberOfItemGivenBESRelative(idsOfSelectStart,idsOfSelectStop,idsOfSelectStep,"MEDCouplingUMesh::ExtractFromIndexedArraysSlice : Input slice ");
7352 const T *arrInPtr=arrIn->begin();
7353 const mcIdType *arrIndxPtr=arrIndxIn->begin();
7354 mcIdType nbOfGrps=arrIndxIn->getNumberOfTuples()-1;
7356 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArraysSlice : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !");
7357 mcIdType maxSizeOfArr(arrIn->getNumberOfTuples());
7358 MCAuto<DataArrayType> arro=DataArrayType::New();
7359 MCAuto<DataArrayIdType> arrIo=DataArrayIdType::New();
7360 arrIo->alloc(sz+1,1);
7361 mcIdType idsIt=idsOfSelectStart;
7362 mcIdType *work=arrIo->getPointer();
7365 for(mcIdType i=0;i<sz;i++,work++,idsIt+=idsOfSelectStep)
7367 if(idsIt>=0 && idsIt<nbOfGrps)
7368 lgth+=arrIndxPtr[idsIt+1]-arrIndxPtr[idsIt];
7371 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArraysSlice : id located on pos #" << i << " value is " << idsIt << " ! Must be in [0," << nbOfGrps << ") !";
7372 throw INTERP_KERNEL::Exception(oss.str());
7378 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArraysSlice : id located on pos #" << i << " value is " << idsIt << " and at this pos arrIndxIn[" << idsIt;
7379 oss << "+1]-arrIndxIn[" << idsIt << "] < 0 ! The input index array is bugged !";
7380 throw INTERP_KERNEL::Exception(oss.str());
7383 arro->alloc(lgth,1);
7384 T *data=arro->getPointer();
7385 idsIt=idsOfSelectStart;
7386 for(mcIdType i=0;i<sz;i++,idsIt+=idsOfSelectStep)
7388 if(arrIndxPtr[idsIt]>=0 && arrIndxPtr[idsIt+1]<=maxSizeOfArr)
7389 data=std::copy(arrInPtr+arrIndxPtr[idsIt],arrInPtr+arrIndxPtr[idsIt+1],data);
7392 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArraysSlice : id located on pos #" << i << " value is " << idsIt << " arrIndx[" << idsIt << "] must be >= 0 and arrIndx[";
7393 oss << idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!";
7394 throw INTERP_KERNEL::Exception(oss.str());
7398 arrIndexOut=arrIo.retn();
7402 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
7403 * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) and for
7404 * cellIds \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex).
7405 * This method is an generalization of MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitly a result output arrays.
7407 * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
7408 * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
7409 * \param [in] arrIn arr origin array from which the extraction will be done.
7410 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7411 * \param [in] srcArr input array that will be used as source of copy for ids in [ \b idsOfSelectBg, \b idsOfSelectEnd )
7412 * \param [in] srcArrIndex index array of \b srcArr
7413 * \param [out] arrOut the resulting array
7414 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
7416 * \sa DataArrayInt::SetPartOfIndexedArraysSameIdx
7419 void DataArrayDiscrete<T>::SetPartOfIndexedArrays(const mcIdType *idsOfSelectBg, const mcIdType *idsOfSelectEnd,
7420 const DataArrayType *arrIn, const DataArrayIdType *arrIndxIn,
7421 const DataArrayType *srcArr, const DataArrayIdType *srcArrIndex,
7422 DataArrayType* &arrOut, DataArrayIdType* &arrIndexOut)
7424 if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
7425 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArrays : presence of null pointer in input parameter !");
7426 MCAuto<DataArrayType> arro=DataArrayType::New();
7427 MCAuto<DataArrayIdType> arrIo=DataArrayIdType::New();
7428 mcIdType nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
7429 std::vector<bool> v(nbOfTuples,true);
7431 const mcIdType *arrIndxInPtr=arrIndxIn->begin();
7432 const mcIdType *srcArrIndexPtr=srcArrIndex->begin();
7433 for(const mcIdType *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++)
7435 if(*it>=0 && *it<nbOfTuples)
7438 offset+=(srcArrIndexPtr[1]-srcArrIndexPtr[0])-(arrIndxInPtr[*it+1]-arrIndxInPtr[*it]);
7442 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArrays : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !";
7443 throw INTERP_KERNEL::Exception(oss.str());
7446 srcArrIndexPtr=srcArrIndex->begin();
7447 arrIo->alloc(nbOfTuples+1,1);
7448 arro->alloc(arrIn->getNumberOfTuples()+offset,1);
7449 const T *arrInPtr=arrIn->begin();
7450 const T *srcArrPtr=srcArr->begin();
7451 mcIdType *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0;
7452 T *arroPtr=arro->getPointer();
7453 for(mcIdType ii=0;ii<nbOfTuples;ii++,arrIoPtr++)
7457 arroPtr=std::copy(arrInPtr+arrIndxInPtr[ii],arrInPtr+arrIndxInPtr[ii+1],arroPtr);
7458 *arrIoPtr=arrIoPtr[-1]+(arrIndxInPtr[ii+1]-arrIndxInPtr[ii]);
7462 std::size_t pos=std::distance(idsOfSelectBg,std::find(idsOfSelectBg,idsOfSelectEnd,ii));
7463 arroPtr=std::copy(srcArrPtr+srcArrIndexPtr[pos],srcArrPtr+srcArrIndexPtr[pos+1],arroPtr);
7464 *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]);
7468 arrIndexOut=arrIo.retn();
7472 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
7473 * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) and for
7474 * cellIds \b in [\b idsOfSelectBg, \b idsOfSelectEnd) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex).
7475 * This method is an generalization of DataArrayInt::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitly a result output arrays.
7477 * \param [in] start begin of set of ids of the input extraction (included)
7478 * \param [in] end end of set of ids of the input extraction (excluded)
7479 * \param [in] step step of the set of ids in range mode.
7480 * \param [in] arrIn arr origin array from which the extraction will be done.
7481 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7482 * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd)
7483 * \param [in] srcArrIndex index array of \b srcArr
7484 * \param [out] arrOut the resulting array
7485 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
7487 * \sa DataArrayInt::SetPartOfIndexedArraysSameIdx DataArrayInt::SetPartOfIndexedArrays
7490 void DataArrayDiscrete<T>::SetPartOfIndexedArraysSlice(mcIdType start, mcIdType end, mcIdType step,
7491 const DataArrayType *arrIn, const DataArrayIdType *arrIndxIn,
7492 const DataArrayType *srcArr, const DataArrayIdType *srcArrIndex,
7493 DataArrayType* &arrOut, DataArrayIdType* &arrIndexOut)
7495 if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
7496 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArraysSlice : presence of null pointer in input parameter !");
7497 MCAuto<DataArrayType> arro=DataArrayType::New();
7498 MCAuto<DataArrayIdType> arrIo=DataArrayIdType::New();
7499 mcIdType nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
7501 const mcIdType *arrIndxInPtr=arrIndxIn->begin();
7502 const mcIdType *srcArrIndexPtr=srcArrIndex->begin();
7503 mcIdType nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"DataArrayInt::SetPartOfIndexedArraysSlice : ");
7505 for(mcIdType i=0;i<nbOfElemsToSet;i++,srcArrIndexPtr++,it+=step)
7507 if(it>=0 && it<nbOfTuples)
7508 offset+=(srcArrIndexPtr[1]-srcArrIndexPtr[0])-(arrIndxInPtr[it+1]-arrIndxInPtr[it]);
7511 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSlice : On pos #" << i << " value is " << it << " not in [0," << nbOfTuples << ") !";
7512 throw INTERP_KERNEL::Exception(oss.str());
7515 srcArrIndexPtr=srcArrIndex->begin();
7516 arrIo->alloc(nbOfTuples+1,1);
7517 arro->alloc(arrIn->getNumberOfTuples()+offset,1);
7518 const T *arrInPtr=arrIn->begin();
7519 const T *srcArrPtr=srcArr->begin();
7520 mcIdType *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0;
7521 T *arroPtr=arro->getPointer();
7522 for(mcIdType ii=0;ii<nbOfTuples;ii++,arrIoPtr++)
7524 mcIdType pos=DataArray::GetPosOfItemGivenBESRelativeNoThrow(ii,start,end,step);
7527 arroPtr=std::copy(arrInPtr+arrIndxInPtr[ii],arrInPtr+arrIndxInPtr[ii+1],arroPtr);
7528 *arrIoPtr=arrIoPtr[-1]+(arrIndxInPtr[ii+1]-arrIndxInPtr[ii]);
7532 arroPtr=std::copy(srcArrPtr+srcArrIndexPtr[pos],srcArrPtr+srcArrIndexPtr[pos+1],arroPtr);
7533 *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]);
7537 arrIndexOut=arrIo.retn();
7541 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
7542 * This method is an specialization of MEDCouplingUMesh::SetPartOfIndexedArrays in the case of assignment do not modify the index in \b arrIndxIn.
7544 * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
7545 * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
7546 * \param [in,out] arrInOut arr origin array from which the extraction will be done.
7547 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7548 * \param [in] srcArr input array that will be used as source of copy for ids in [ \b idsOfSelectBg , \b idsOfSelectEnd )
7549 * \param [in] srcArrIndex index array of \b srcArr
7551 * \sa DataArrayInt::SetPartOfIndexedArrays
7554 void DataArrayDiscrete<T>::SetPartOfIndexedArraysSameIdx(const mcIdType *idsOfSelectBg, const mcIdType *idsOfSelectEnd,
7555 DataArrayType *arrInOut, const DataArrayIdType *arrIndxIn,
7556 const DataArrayType *srcArr, const DataArrayIdType *srcArrIndex)
7558 if(arrInOut==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
7559 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArraysSameIdx : presence of null pointer in input parameter !");
7560 mcIdType nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
7561 const mcIdType *arrIndxInPtr=arrIndxIn->begin();
7562 const mcIdType *srcArrIndexPtr=srcArrIndex->begin();
7563 T *arrInOutPtr=arrInOut->getPointer();
7564 const T *srcArrPtr=srcArr->begin();
7565 for(const mcIdType *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++)
7567 if(*it>=0 && *it<nbOfTuples)
7569 if(srcArrIndexPtr[1]-srcArrIndexPtr[0]==arrIndxInPtr[*it+1]-arrIndxInPtr[*it])
7570 std::copy(srcArrPtr+srcArrIndexPtr[0],srcArrPtr+srcArrIndexPtr[1],arrInOutPtr+arrIndxInPtr[*it]);
7573 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSameIdx : On pos #" << std::distance(idsOfSelectBg,it) << " id (idsOfSelectBg[" << std::distance(idsOfSelectBg,it)<< "]) is " << *it << " arrIndxIn[id+1]-arrIndxIn[id]!=srcArrIndex[pos+1]-srcArrIndex[pos] !";
7574 throw INTERP_KERNEL::Exception(oss.str());
7579 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSameIdx : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !";
7580 throw INTERP_KERNEL::Exception(oss.str());
7586 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
7587 * This method is an specialization of MEDCouplingUMesh::SetPartOfIndexedArrays in the case of assignment do not modify the index in \b arrIndxIn.
7589 * \param [in] start begin of set of ids of the input extraction (included)
7590 * \param [in] end end of set of ids of the input extraction (excluded)
7591 * \param [in] step step of the set of ids in range mode.
7592 * \param [in,out] arrInOut arr origin array from which the extraction will be done.
7593 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7594 * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd)
7595 * \param [in] srcArrIndex index array of \b srcArr
7597 * \sa DataArrayInt::SetPartOfIndexedArraysSlice DataArrayInt::SetPartOfIndexedArraysSameIdx
7600 void DataArrayDiscrete<T>::SetPartOfIndexedArraysSameIdxSlice(mcIdType start, mcIdType end, mcIdType step,
7601 DataArrayType *arrInOut, const DataArrayIdType *arrIndxIn,
7602 const DataArrayType *srcArr, const DataArrayIdType *srcArrIndex)
7604 if(arrInOut==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
7605 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : presence of null pointer in input parameter !");
7606 mcIdType nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
7607 const mcIdType *arrIndxInPtr=arrIndxIn->begin();
7608 const mcIdType *srcArrIndexPtr=srcArrIndex->begin();
7609 T *arrInOutPtr=arrInOut->getPointer();
7610 const T *srcArrPtr=srcArr->begin();
7611 mcIdType nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : ");
7613 for(mcIdType i=0;i<nbOfElemsToSet;i++,srcArrIndexPtr++,it+=step)
7615 if(it>=0 && it<nbOfTuples)
7617 if(srcArrIndexPtr[1]-srcArrIndexPtr[0]==arrIndxInPtr[it+1]-arrIndxInPtr[it])
7618 std::copy(srcArrPtr+srcArrIndexPtr[0],srcArrPtr+srcArrIndexPtr[1],arrInOutPtr+arrIndxInPtr[it]);
7621 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : On pos #" << i << " id (idsOfSelectBg[" << i << "]) is " << it << " arrIndxIn[id+1]-arrIndxIn[id]!=srcArrIndex[pos+1]-srcArrIndex[pos] !";
7622 throw INTERP_KERNEL::Exception(oss.str());
7627 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : On pos #" << i << " value is " << it << " not in [0," << nbOfTuples << ") !";
7628 throw INTERP_KERNEL::Exception(oss.str());
7634 * This method works on an input pair (\b arr, \b arrIndx) where \b arr indexes is in \b arrIndx.
7635 * This method will not impact the size of inout parameter \b arrIndx but the size of \b arr will be modified in case of suppression.
7637 * \param [in] idsToRemoveBg begin of set of ids to remove in \b arr (included)
7638 * \param [in] idsToRemoveEnd end of set of ids to remove in \b arr (excluded)
7639 * \param [in,out] arr array in which the remove operation will be done.
7640 * \param [in,out] arrIndx array in the remove operation will modify
7641 * \param [in] offsetForRemoval (by default 0) offset so that for each i in [0,arrIndx->getNumberOfTuples()-1) removal process will be performed in the following range [arr+arrIndx[i]+offsetForRemoval,arr+arr[i+1])
7642 * \return true if \b arr and \b arrIndx have been modified, false if not.
7645 bool DataArrayDiscrete<T>::RemoveIdsFromIndexedArrays(const T *idsToRemoveBg, const T *idsToRemoveEnd,
7646 DataArrayType *arr, DataArrayIdType *arrIndx, mcIdType offsetForRemoval)
7648 if(!arrIndx || !arr)
7649 throw INTERP_KERNEL::Exception("DataArrayInt::RemoveIdsFromIndexedArrays : some input arrays are empty !");
7650 if(offsetForRemoval<0)
7651 throw INTERP_KERNEL::Exception("DataArrayInt::RemoveIdsFromIndexedArrays : offsetForRemoval should be >=0 !");
7652 std::set<T> s(idsToRemoveBg,idsToRemoveEnd);
7653 mcIdType nbOfGrps=arrIndx->getNumberOfTuples()-1;
7654 mcIdType *arrIPtr=arrIndx->getPointer();
7656 mcIdType previousArrI=0;
7657 const T *arrPtr=arr->begin();
7658 std::vector<T> arrOut;//no utility to switch to DataArrayInt because copy always needed
7659 for(mcIdType i=0;i<nbOfGrps;i++,arrIPtr++)
7661 if(*arrIPtr-previousArrI>offsetForRemoval)
7663 for(const T *work=arrPtr+previousArrI+offsetForRemoval;work!=arrPtr+*arrIPtr;work++)
7665 if(s.find(*work)==s.end())
7666 arrOut.push_back(*work);
7669 previousArrI=*arrIPtr;
7670 *arrIPtr=ToIdType(arrOut.size());
7672 if(arr->getNumberOfTuples()==ToIdType(arrOut.size()))
7674 arr->alloc(arrOut.size(),1);
7675 std::copy(arrOut.begin(),arrOut.end(),arr->getPointer());
7680 * Returns a new DataArrayInt containing an arithmetic progression
7681 * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step )
7683 * \param [in] begin - the start value of the result sequence.
7684 * \param [in] end - limiting value, so that every value of the result array is less than
7686 * \param [in] step - specifies the increment or decrement.
7687 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7688 * array using decrRef() as it is no more needed.
7689 * \throw If \a step == 0.
7690 * \throw If \a end < \a begin && \a step > 0.
7691 * \throw If \a end > \a begin && \a step < 0.
7694 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Range(T begin, T end, T step)
7696 mcIdType nbOfTuples=DataArrayTools<T>::GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
7697 MCAuto<DataArrayType> ret=DataArrayType::New();
7698 ret->alloc(nbOfTuples,1);
7699 T *ptr=ret->getPointer();
7702 for(T i=begin;i<end;i+=step,ptr++)
7707 for(T i=begin;i>end;i+=step,ptr++)
7714 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7715 * from a zip representation of a surjective format (returned e.g. by
7716 * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7717 * for example). The result array minimizes the permutation. <br>
7718 * For more info on renumbering see \ref numbering. <br>
7720 * - \a nbOfOldTuples: 10
7721 * - \a arr : [0,3, 5,7,9]
7722 * - \a arrIBg : [0,2,5]
7723 * - \a newNbOfTuples: 7
7724 * - result array : [0,1,2,0,3,4,5,4,6,4]
7726 * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7727 * \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7728 * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7729 * (indices of) equal values. Its every element (except the last one) points to
7730 * the first element of a group of equal values.
7731 * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7732 * arrIBg is \a arrIEnd[ -1 ].
7733 * \param [out] newNbOfTuples - number of tuples after surjection application.
7734 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7735 * array using decrRef() as it is no more needed.
7736 * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7739 DataArrayIdType *DataArrayDiscrete<T>::ConvertIndexArrayToO2N(mcIdType nbOfOldTuples, const mcIdType *arr, const mcIdType *arrIBg, const mcIdType *arrIEnd, mcIdType &newNbOfTuples)
7741 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
7742 ret->alloc(nbOfOldTuples,1);
7743 mcIdType *pt=ret->getPointer();
7744 std::fill(pt,pt+nbOfOldTuples,-1);
7745 mcIdType nbOfGrps=ToIdType(std::distance(arrIBg,arrIEnd))-1;
7746 const mcIdType *cIPtr=arrIBg;
7747 for(mcIdType i=0;i<nbOfGrps;i++)
7748 pt[arr[cIPtr[i]]]=-(i+2);
7750 for(mcIdType iNode=0;iNode<nbOfOldTuples;iNode++)
7758 mcIdType grpId=-(pt[iNode]+2);
7759 for(mcIdType j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7761 if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7765 std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7766 throw INTERP_KERNEL::Exception(oss.str().c_str());
7773 newNbOfTuples=newNb;
7778 * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
7779 * The i-th item of the result array is an ID of a set of elements belonging to a
7780 * unique set of groups, which the i-th element is a part of. This set of elements
7781 * belonging to a unique set of groups is called \a family, so the result array contains
7782 * IDs of families each element belongs to.
7784 * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
7785 * then there are 3 families:
7786 * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
7787 * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
7788 * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
7789 * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
7790 * stands for the element #3 which is in none of groups.
7792 * \param [in] groups - sequence of groups of element IDs.
7793 * \param [in] newNb - total number of elements; it must be more than max ID of element
7795 * \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
7796 * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
7797 * each element with ID from range [0, \a newNb ) belongs to. The caller is to
7798 * delete this array using decrRef() as it is no more needed.
7799 * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
7802 DataArrayIdType *DataArrayDiscrete<T>::MakePartition(const std::vector<const DataArrayType *>& groups, mcIdType newNb, std::vector< std::vector<mcIdType> >& fidsOfGroups)
7804 std::vector<const DataArrayType *> groups2;
7805 for(typename std::vector<const DataArrayType *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
7807 groups2.push_back(*it4);
7808 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
7809 ret->alloc(newNb,1);
7810 mcIdType *retPtr=ret->getPointer();
7811 std::fill(retPtr,retPtr+newNb,0);
7813 for(typename std::vector<const DataArrayType *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
7815 const T *ptr=(*iter)->getConstPointer();
7816 std::size_t nbOfElem=(*iter)->getNbOfElems();
7818 for(mcIdType j=0;j<sfid;j++)
7821 for(std::size_t i=0;i<nbOfElem;i++)
7823 if(ptr[i]>=0 && ptr[i]<newNb)
7825 if(retPtr[ptr[i]]==j)
7833 std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
7835 throw INTERP_KERNEL::Exception(oss.str().c_str());
7842 fidsOfGroups.clear();
7843 fidsOfGroups.resize(groups2.size());
7845 for(typename std::vector<const DataArrayType *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
7847 std::set<mcIdType> tmp;
7848 const T *ptr=(*iter)->getConstPointer();
7849 std::size_t nbOfElem=(*iter)->getNbOfElems();
7850 for(const T *p=ptr;p!=ptr+nbOfElem;p++)
7851 tmp.insert(retPtr[*p]);
7852 fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
7860 namespace MEDCouplingImpl
7866 OpSwitchedOn(T *pt):_pt(pt),_cnt(0) { }
7867 void operator()(const bool& b) { if(b) *_pt++=FromIdType<T>(_cnt); _cnt++; }
7870 MEDCoupling::mcIdType _cnt;
7877 OpSwitchedOff(T *pt):_pt(pt),_cnt(0) { }
7878 void operator()(const bool& b) { if(!b) *_pt++=FromIdType<T>(_cnt); _cnt++; }
7881 MEDCoupling::mcIdType _cnt;
7886 namespace MEDCoupling
7889 * This method returns the list of ids in ascending mode so that v[id]==true.
7892 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::BuildListOfSwitchedOn(const std::vector<bool>& v)
7894 std::size_t sz(std::count(v.begin(),v.end(),true));
7895 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(sz,1);
7896 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn<T>(ret->getPointer()));
7901 * This method returns the list of ids in ascending mode so that v[id]==false.
7904 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::BuildListOfSwitchedOff(const std::vector<bool>& v)
7906 std::size_t sz(std::count(v.begin(),v.end(),false));
7907 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(sz,1);
7908 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff<T>(ret->getPointer()));
7913 namespace MEDCoupling
7916 * This method compares content of input vector \a v and \a this.
7917 * If for each id in \a this v[id]==True and for all other ids id2 not in \a this v[id2]==False, true is returned.
7918 * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
7920 * \param [in] v - the vector of 'flags' to be compared with \a this.
7922 * \throw If \a this is not sorted ascendingly.
7923 * \throw If \a this has not exactly one component.
7924 * \throw If \a this is not allocated.
7927 bool DataArrayDiscreteSigned<T>::isFittingWith(const std::vector<bool>& v) const
7929 this->checkAllocated();
7930 if(this->getNumberOfComponents()!=1)
7931 throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
7932 const T *w(this->begin()),*end2(this->end());
7933 T refVal=-std::numeric_limits<T>::max();
7935 std::vector<bool>::const_iterator it(v.begin());
7936 for(;it!=v.end();it++,i++)
7948 std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(this->begin(),w-1) << " this is not sorted ascendingly !";
7949 throw INTERP_KERNEL::Exception(oss.str().c_str());