1 // Copyright (C) 2007-2020 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=DataArrayTemplate<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*8 bytes ) \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.
1076 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1077 * is to delete using decrRef() as it is no more needed.
1080 void DataArrayTemplate<T>::renumberInPlaceR(const mcIdType *new2Old)
1083 mcIdType nbTuples(getNumberOfTuples());
1084 std::size_t nbOfCompo(getNumberOfComponents());
1085 T *tmp(new T[nbTuples*nbOfCompo]);
1086 const T *iptr(begin());
1087 for(mcIdType i=0;i<nbTuples;i++)
1089 mcIdType v=new2Old[i];
1090 if(v>=0 && v<nbTuples)
1091 std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1094 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1095 throw INTERP_KERNEL::Exception(oss.str().c_str());
1098 std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1104 * Sorts values of the array. \b Warning, this method is not const, it alterates \a this content.
1106 * \param [in] asc - \a true means ascending order, \a false, descending.
1107 * \throw If \a this is not allocated.
1108 * \throw If \a this->getNumberOfComponents() != 1.
1112 void DataArrayTemplate<T>::sort(bool asc)
1115 if(getNumberOfComponents()!=1)
1117 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::sort : only supported with 'this' array with ONE component !";
1118 throw INTERP_KERNEL::Exception(oss.str().c_str());
1125 * Sorts values of the array and put the result in a newly allocated returned array.
1126 * This method does not alterate \a this content.
1128 * \param [in] asc - \a true means ascending order, \a false, descending.
1129 * \throw If \a this is not allocated.
1130 * \throw If \a this->getNumberOfComponents() != 1.
1134 typename Traits<T>::ArrayTypeCh *DataArrayTemplate<T>::copySortedImpl(bool asc) const
1136 MCAuto<typename Traits<T>::ArrayTypeCh> ret(static_cast<typename Traits<T>::ArrayTypeCh *>(this->deepCopy()));
1142 * Returns a copy of \a this array with values permuted as required by \a old2New array.
1143 * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ].
1144 * Number of tuples in the result array remains the same as in \c this one.
1145 * If a permutation reduction is needed, renumberAndReduce() should be used.
1146 * For more info on renumbering see \ref numbering.
1147 * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1148 * giving a new position for i-th old value.
1149 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1150 * is to delete using decrRef() as it is no more needed.
1151 * \throw If \a this is not allocated.
1154 typename Traits<T>::ArrayType *DataArrayTemplate<T>::renumber(const mcIdType *old2New) const
1157 mcIdType nbTuples(getNumberOfTuples());
1158 std::size_t nbOfCompo(getNumberOfComponents());
1159 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1160 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1161 ret->alloc(nbTuples,nbOfCompo);
1162 ret->copyStringInfoFrom(*this);
1163 const T *iptr(begin());
1164 T *optr(ret->getPointer());
1165 for(mcIdType i=0;i<nbTuples;i++)
1166 std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1167 ret->copyStringInfoFrom(*this);
1172 * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1173 * The values are permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1174 * tuples in the result array remains the same as in \c this one.
1175 * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
1176 * For more info on renumbering see \ref numbering.
1177 * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1178 * giving a previous position of i-th new value.
1179 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1180 * is to delete using decrRef() as it is no more needed.
1183 typename Traits<T>::ArrayType *DataArrayTemplate<T>::renumberR(const mcIdType *new2Old) const
1186 mcIdType nbTuples(getNumberOfTuples());
1187 std::size_t nbOfCompo(getNumberOfComponents());
1188 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1189 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1190 ret->alloc(nbTuples,nbOfCompo);
1191 ret->copyStringInfoFrom(*this);
1192 const T *iptr(getConstPointer());
1193 T *optr(ret->getPointer());
1194 for(mcIdType i=0;i<nbTuples;i++)
1195 std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1196 ret->copyStringInfoFrom(*this);
1201 * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1202 * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1203 * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ] for all
1204 * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which
1205 * \a old2New[ i ] is negative, is missing from the result array.
1206 * For more info on renumbering see \ref numbering.
1207 * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1208 * giving a new position for i-th old tuple and giving negative position for
1209 * for i-th old tuple that should be omitted.
1210 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1211 * is to delete using decrRef() as it is no more needed.
1214 typename Traits<T>::ArrayType *DataArrayTemplate<T>::renumberAndReduce(const mcIdType *old2New, mcIdType newNbOfTuple) const
1217 mcIdType nbTuples(getNumberOfTuples());
1218 std::size_t nbOfCompo(getNumberOfComponents());
1219 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1220 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1221 ret->alloc(newNbOfTuple,nbOfCompo);
1222 const T *iptr=getConstPointer();
1223 T *optr=ret->getPointer();
1224 for(mcIdType i=0;i<nbTuples;i++)
1226 mcIdType w=old2New[i];
1228 std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1230 ret->copyStringInfoFrom(*this);
1235 * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1236 * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1237 * \a new2OldBg array.
1238 * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1239 * This method is equivalent to renumberAndReduce() except that convention in input is
1240 * \c new2old and \b not \c old2new.
1241 * For more info on renumbering see \ref numbering.
1242 * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1243 * tuple index in \a this array to fill the i-th tuple in the new array.
1244 * \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1245 * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1246 * \a new2OldBg <= \a pi < \a new2OldEnd.
1247 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1248 * is to delete using decrRef() as it is no more needed.
1251 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleId(const mcIdType *new2OldBg, const mcIdType *new2OldEnd) const
1254 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1255 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1256 std::size_t nbComp(getNumberOfComponents());
1257 ret->alloc(std::distance(new2OldBg,new2OldEnd),nbComp);
1258 ret->copyStringInfoFrom(*this);
1259 T *pt(ret->getPointer());
1260 const T *srcPt(getConstPointer());
1262 for(const mcIdType *w=new2OldBg;w!=new2OldEnd;w++,i++)
1263 std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1264 ret->copyStringInfoFrom(*this);
1269 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleId(const DataArrayIdType& di) const
1271 return this->mySelectByTupleId(di.begin(),di.end());
1275 MCAuto<typename Traits<T>::ArrayTypeCh> DataArrayTemplate<T>::selectPartDef(const PartDefinition *pd) const
1278 throw INTERP_KERNEL::Exception("DataArrayTemplate<T>::selectPartDef : null input pointer !");
1279 MCAuto<typename Traits<T>::ArrayTypeCh> ret(Traits<T>::ArrayTypeCh::New());
1280 const SlicePartDefinition *spd(dynamic_cast<const SlicePartDefinition *>(pd));
1284 spd->getSlice(a,b,c);
1285 if(a==0 && b==getNumberOfTuples() && c==1)
1287 DataArrayTemplate<T> *directRet(const_cast<DataArrayTemplate<T> *>(this));
1288 directRet->incrRef();
1289 MCAuto<DataArrayTemplate<T> > ret2(directRet);
1290 return DynamicCastSafe<DataArrayTemplate<T>,typename Traits<T>::ArrayTypeCh>(ret2);
1294 MCAuto<DataArray> ret2(selectByTupleIdSafeSlice(a,b,c));
1295 return DynamicCastSafe<DataArray,typename Traits<T>::ArrayTypeCh>(ret2);
1298 const DataArrayPartDefinition *dpd(dynamic_cast<const DataArrayPartDefinition *>(pd));
1301 MCAuto<DataArrayIdType> arr(dpd->toDAI());
1302 MCAuto<DataArray> ret2(selectByTupleIdSafe(arr->begin(),arr->end()));
1303 return DynamicCastSafe<DataArray,typename Traits<T>::ArrayTypeCh>(ret2);
1306 throw INTERP_KERNEL::Exception("DataArrayTemplate<T>::selectPartDef : unrecognized part def !");
1310 * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1311 * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1312 * \a new2OldBg array.
1313 * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1314 * This method is equivalent to renumberAndReduce() except that convention in input is
1315 * \c new2old and \b not \c old2new.
1316 * This method is equivalent to selectByTupleId() except that it prevents coping data
1317 * from behind the end of \a this array.
1318 * For more info on renumbering see \ref numbering.
1319 * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1320 * tuple index in \a this array to fill the i-th tuple in the new array.
1321 * \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1322 * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1323 * \a new2OldBg <= \a pi < \a new2OldEnd.
1324 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1325 * is to delete using decrRef() as it is no more needed.
1326 * \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1329 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleIdSafe(const mcIdType *new2OldBg, const mcIdType *new2OldEnd) const
1332 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1333 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1334 std::size_t nbComp(getNumberOfComponents());
1335 mcIdType oldNbOfTuples(getNumberOfTuples());
1336 ret->alloc(std::distance(new2OldBg,new2OldEnd),nbComp);
1337 ret->copyStringInfoFrom(*this);
1338 T *pt(ret->getPointer());
1339 const T *srcPt(getConstPointer());
1341 for(const mcIdType *w=new2OldBg;w!=new2OldEnd;w++,i++)
1342 if(*w>=0 && *w<oldNbOfTuples)
1343 std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1346 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !";
1347 throw INTERP_KERNEL::Exception(oss.str().c_str());
1349 ret->copyStringInfoFrom(*this);
1354 * Changes the number of components within \a this array so that its raw data **does
1355 * not** change, instead splitting this data into tuples changes.
1356 * \warning This method erases all (name and unit) component info set before!
1357 * \param [in] newNbOfComp - number of components for \a this array to have.
1358 * \throw If \a this is not allocated
1359 * \throw If getNbOfElems() % \a newNbOfCompo != 0.
1360 * \throw If \a newNbOfCompo is lower than 1.
1361 * \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1362 * \warning This method erases all (name and unit) component info set before!
1365 void DataArrayTemplate<T>::rearrange(std::size_t newNbOfCompo)
1370 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::rearrange : input newNbOfCompo must be > 0 !";
1371 throw INTERP_KERNEL::Exception(oss.str().c_str());
1373 std::size_t nbOfElems=getNbOfElems();
1374 if(nbOfElems%newNbOfCompo!=0)
1376 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::rearrange : nbOfElems%newNbOfCompo!=0 !";
1377 throw INTERP_KERNEL::Exception(oss.str().c_str());
1379 if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<mcIdType>::max())
1381 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !";
1382 throw INTERP_KERNEL::Exception(oss.str().c_str());
1384 _info_on_compo.clear();
1385 _info_on_compo.resize(newNbOfCompo);
1390 * Changes the number of components within \a this array to be equal to its number
1391 * of tuples, and inversely its number of tuples to become equal to its number of
1392 * components. So that its raw data **does not** change, instead splitting this
1393 * data into tuples changes.
1394 * \warning This method erases all (name and unit) component info set before!
1395 * \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1396 * \throw If \a this is not allocated.
1400 void DataArrayTemplate<T>::transpose()
1403 rearrange(getNumberOfTuples());
1407 * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1408 * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1409 * is truncated to have \a newNbOfComp components, keeping first components. If \a
1410 * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1411 * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1413 * \param [in] newNbOfComp - number of components for the new array to have.
1414 * \param [in] dftValue - value assigned to new values added to the new array.
1415 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1416 * is to delete using decrRef() as it is no more needed.
1417 * \throw If \a this is not allocated.
1420 typename Traits<T>::ArrayType *DataArrayTemplate<T>::changeNbOfComponents(std::size_t newNbOfComp, T dftValue) const
1423 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1424 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1425 ret->alloc(getNumberOfTuples(),newNbOfComp);
1426 const T *oldc(getConstPointer());
1427 T *nc(ret->getPointer());
1428 mcIdType nbOfTuples=getNumberOfTuples();
1429 std::size_t oldNbOfComp=getNumberOfComponents();
1430 std::size_t dim(std::min(oldNbOfComp,newNbOfComp));
1431 for(mcIdType i=0;i<nbOfTuples;i++)
1435 nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1436 for(;j<newNbOfComp;j++)
1437 nc[newNbOfComp*i+j]=dftValue;
1439 ret->setName(getName());
1440 for(std::size_t i=0;i<dim;i++)
1441 ret->setInfoOnComponent(i,getInfoOnComponent(i));
1442 ret->setName(getName());
1447 * Returns a copy of \a this array composed of selected components.
1448 * The new DataArrayDouble has the same number of tuples but includes components
1449 * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1450 * can be either less, same or more than \a this->getNbOfElems().
1451 * \param [in] compoIds - sequence of zero based indices of components to include
1452 * into the new array.
1453 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1454 * is to delete using decrRef() as it is no more needed.
1455 * \throw If \a this is not allocated.
1456 * \throw If a component index (\a i) is not valid:
1457 * \a i < 0 || \a i >= \a this->getNumberOfComponents().
1459 * \if ENABLE_EXAMPLES
1460 * \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1464 typename Traits<T>::ArrayType *DataArrayTemplate<T>::myKeepSelectedComponents(const std::vector<std::size_t>& compoIds) const
1467 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1468 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1469 std::size_t newNbOfCompo=compoIds.size();
1470 std::size_t oldNbOfCompo=getNumberOfComponents();
1471 for(std::vector<std::size_t>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1472 if((*it)<0 || (*it)>=oldNbOfCompo)
1474 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1475 throw INTERP_KERNEL::Exception(oss.str().c_str());
1477 mcIdType nbOfTuples(getNumberOfTuples());
1478 ret->alloc(nbOfTuples,newNbOfCompo);
1479 ret->copyPartOfStringInfoFrom(*this,compoIds);
1480 const T *oldc(getConstPointer());
1481 T *nc(ret->getPointer());
1482 for(mcIdType i=0;i<nbOfTuples;i++)
1483 for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1484 *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1489 * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1490 * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1491 * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1492 * This method is a specialization of selectByTupleIdSafeSlice().
1493 * \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1494 * \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1495 * If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1496 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1497 * is to delete using decrRef() as it is no more needed.
1498 * \throw If \a tupleIdBg < 0.
1499 * \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1500 * \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1501 * \sa DataArrayDouble::selectByTupleIdSafeSlice
1504 typename Traits<T>::ArrayType *DataArrayTemplate<T>::subArray(mcIdType tupleIdBg, mcIdType tupleIdEnd) const
1507 mcIdType nbt=getNumberOfTuples();
1510 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::subArray : The tupleIdBg parameter must be greater than 0 !";
1511 throw INTERP_KERNEL::Exception(oss.str().c_str());
1515 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << ":subArray : The tupleIdBg parameter is greater than number of tuples !";
1516 throw INTERP_KERNEL::Exception(oss.str().c_str());
1518 mcIdType trueEnd=tupleIdEnd;
1523 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << ":subArray : The tupleIdBg parameter is greater than number of tuples !";
1524 throw INTERP_KERNEL::Exception(oss.str().c_str());
1529 std::size_t nbComp=getNumberOfComponents();
1530 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1531 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1532 ret->alloc(trueEnd-tupleIdBg,nbComp);
1533 ret->copyStringInfoFrom(*this);
1534 std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1539 * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1540 * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1541 * tuple. Indices of the selected tuples are the same as ones returned by the Python
1542 * command \c range( \a bg, \a end2, \a step ).
1543 * This method is equivalent to selectByTupleIdSafe() except that the input array is
1544 * not constructed explicitly.
1545 * For more info on renumbering see \ref numbering.
1546 * \param [in] bg - index of the first tuple to copy from \a this array.
1547 * \param [in] end2 - index of the tuple before which the tuples to copy are located.
1548 * \param [in] step - index increment to get index of the next tuple to copy.
1549 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1550 * is to delete using decrRef() as it is no more needed.
1551 * \sa DataArrayDouble::subArray.
1554 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleIdSafeSlice(mcIdType bg, mcIdType end2, mcIdType step) const
1557 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1558 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1559 std::size_t nbComp(getNumberOfComponents());
1560 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::selectByTupleIdSafeSlice : ";
1561 mcIdType newNbOfTuples(GetNumberOfItemGivenBESRelative(bg,end2,step,oss.str()));
1562 ret->alloc(newNbOfTuples,nbComp);
1563 T *pt(ret->getPointer());
1564 const T *srcPt(getConstPointer()+bg*nbComp);
1565 for(mcIdType i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1566 std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1567 ret->copyStringInfoFrom(*this);
1572 * Copy all values from another DataArrayDouble into specified tuples and components
1573 * of \a this array. Textual data is not copied.
1574 * The tree parameters defining set of indices of tuples and components are similar to
1575 * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
1576 * \param [in] a - the array to copy values from.
1577 * \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
1578 * \param [in] endTuples - index of the tuple before which the tuples to assign to
1580 * \param [in] stepTuples - index increment to get index of the next tuple to assign to.
1581 * \param [in] bgComp - index of the first component of \a this array to assign values to.
1582 * \param [in] endComp - index of the component before which the components to assign
1584 * \param [in] stepComp - index increment to get index of the next component to assign to.
1585 * \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents()
1586 * must be equal to the number of columns to assign to, else an
1587 * exception is thrown; if \a false, then it is only required that \a
1588 * a->getNbOfElems() equals to number of values to assign to (this condition
1589 * must be respected even if \a strictCompoCompare is \a true). The number of
1590 * values to assign to is given by following Python expression:
1591 * \a nbTargetValues =
1592 * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
1593 * \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1594 * \throw If \a a is NULL.
1595 * \throw If \a a is not allocated.
1596 * \throw If \a this is not allocated.
1597 * \throw If parameters specifying tuples and components to assign to do not give a
1598 * non-empty range of increasing indices.
1599 * \throw If \a a->getNbOfElems() != \a nbTargetValues.
1600 * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
1601 * \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1603 * \if ENABLE_EXAMPLES
1604 * \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
1608 void DataArrayTemplate<T>::setPartOfValues1(const typename Traits<T>::ArrayType *a, mcIdType bgTuples, mcIdType endTuples, mcIdType stepTuples, mcIdType bgComp, mcIdType endComp, mcIdType stepComp, bool strictCompoCompare)
1612 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::setPartOfValues1 : input DataArrayDouble is NULL !";
1613 throw INTERP_KERNEL::Exception(oss.str().c_str());
1615 const char msg[]="DataArrayTemplate::setPartOfValues1";
1617 a->checkAllocated();
1618 mcIdType newNbOfTuples(DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg));
1619 mcIdType newNbOfComp(DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg));
1620 std::size_t nbComp(getNumberOfComponents());
1621 mcIdType nbOfTuples(getNumberOfTuples());
1622 DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
1623 DataArray::CheckValueInRangeEx(ToIdType(nbComp),bgComp,endComp,"invalid component value");
1624 bool assignTech(true);
1625 if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
1627 if(strictCompoCompare)
1628 a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1632 a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
1635 const T *srcPt(a->getConstPointer());
1636 T *pt(getPointer()+bgTuples*nbComp+bgComp);
1639 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1640 for(mcIdType j=0;j<newNbOfComp;j++,srcPt++)
1641 pt[j*stepComp]=*srcPt;
1645 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1647 const T*srcPt2=srcPt;
1648 for(mcIdType j=0;j<newNbOfComp;j++,srcPt2++)
1649 pt[j*stepComp]=*srcPt2;
1655 * Assign a given value to values at specified tuples and components of \a this array.
1656 * The tree parameters defining set of indices of tuples and components are similar to
1657 * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
1658 * \param [in] a - the value to assign.
1659 * \param [in] bgTuples - index of the first tuple of \a this array to assign to.
1660 * \param [in] endTuples - index of the tuple before which the tuples to assign to
1662 * \param [in] stepTuples - index increment to get index of the next tuple to assign to.
1663 * \param [in] bgComp - index of the first component of \a this array to assign to.
1664 * \param [in] endComp - index of the component before which the components to assign
1666 * \param [in] stepComp - index increment to get index of the next component to assign to.
1667 * \throw If \a this is not allocated.
1668 * \throw If parameters specifying tuples and components to assign to, do not give a
1669 * non-empty range of increasing indices or indices are out of a valid range
1670 * for \c this array.
1672 * \if ENABLE_EXAMPLES
1673 * \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
1677 void DataArrayTemplate<T>::setPartOfValuesSimple1(T a, mcIdType bgTuples, mcIdType endTuples, mcIdType stepTuples, mcIdType bgComp, mcIdType endComp, mcIdType stepComp)
1679 const char msg[]="DataArrayTemplate::setPartOfValuesSimple1";
1681 mcIdType newNbOfTuples(DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg));
1682 mcIdType newNbOfComp(DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg));
1683 std::size_t nbComp(getNumberOfComponents());
1684 mcIdType nbOfTuples(getNumberOfTuples());
1685 DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
1686 DataArray::CheckValueInRangeEx(ToIdType(nbComp),bgComp,endComp,"invalid component value");
1687 T *pt=getPointer()+bgTuples*nbComp+bgComp;
1688 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1689 for(mcIdType j=0;j<newNbOfComp;j++)
1694 * Copy all values from another DataArrayDouble (\a a) into specified tuples and
1695 * components of \a this array. Textual data is not copied.
1696 * The tuples and components to assign to are defined by C arrays of indices.
1697 * There are two *modes of usage*:
1698 * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
1699 * of \a a is assigned to its own location within \a this array.
1700 * - If \a a includes one tuple, then all values of \a a are assigned to the specified
1701 * components of every specified tuple of \a this array. In this mode it is required
1702 * that \a a->getNumberOfComponents() equals to the number of specified components.
1704 * \param [in] a - the array to copy values from.
1705 * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
1706 * assign values of \a a to.
1707 * \param [in] endTuples - specifies the end of the array \a bgTuples, so that
1708 * pointer to a tuple index <em>(pi)</em> varies as this:
1709 * \a bgTuples <= \a pi < \a endTuples.
1710 * \param [in] bgComp - pointer to an array of component indices of \a this array to
1711 * assign values of \a a to.
1712 * \param [in] endComp - specifies the end of the array \a bgTuples, so that
1713 * pointer to a component index <em>(pi)</em> varies as this:
1714 * \a bgComp <= \a pi < \a endComp.
1715 * \param [in] strictCompoCompare - this parameter is checked only if the
1716 * *mode of usage* is the first; if it is \a true (default),
1717 * then \a a->getNumberOfComponents() must be equal
1718 * to the number of specified columns, else this is not required.
1719 * \throw If \a a is NULL.
1720 * \throw If \a a is not allocated.
1721 * \throw If \a this is not allocated.
1722 * \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
1723 * out of a valid range for \a this array.
1724 * \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
1725 * if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
1726 * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
1727 * <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
1729 * \if ENABLE_EXAMPLES
1730 * \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
1734 void DataArrayTemplate<T>::setPartOfValues2(const typename Traits<T>::ArrayType *a, const mcIdType *bgTuples, const mcIdType *endTuples, const mcIdType *bgComp, const mcIdType *endComp, bool strictCompoCompare)
1737 throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
1738 const char msg[]="DataArrayTemplate::setPartOfValues2";
1740 a->checkAllocated();
1741 std::size_t nbComp(getNumberOfComponents());
1742 mcIdType nbOfTuples(getNumberOfTuples());
1743 for(const mcIdType *z=bgComp;z!=endComp;z++)
1744 DataArray::CheckValueInRange(ToIdType(nbComp),*z,"invalid component id");
1745 mcIdType newNbOfTuples(ToIdType(std::distance(bgTuples,endTuples)));
1746 mcIdType newNbOfComp(ToIdType(std::distance(bgComp,endComp)));
1747 bool assignTech(true);
1748 if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
1750 if(strictCompoCompare)
1751 a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1755 a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
1758 T *pt(getPointer());
1759 const T *srcPt(a->getConstPointer());
1762 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1764 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1765 for(const mcIdType *z=bgComp;z!=endComp;z++,srcPt++)
1767 pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
1773 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1775 const T *srcPt2=srcPt;
1776 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1777 for(const mcIdType *z=bgComp;z!=endComp;z++,srcPt2++)
1779 pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
1786 * Assign a given value to values at specified tuples and components of \a this array.
1787 * The tuples and components to assign to are defined by C arrays of indices.
1788 * \param [in] a - the value to assign.
1789 * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
1791 * \param [in] endTuples - specifies the end of the array \a bgTuples, so that
1792 * pointer to a tuple index (\a pi) varies as this:
1793 * \a bgTuples <= \a pi < \a endTuples.
1794 * \param [in] bgComp - pointer to an array of component indices of \a this array to
1796 * \param [in] endComp - specifies the end of the array \a bgTuples, so that
1797 * pointer to a component index (\a pi) varies as this:
1798 * \a bgComp <= \a pi < \a endComp.
1799 * \throw If \a this is not allocated.
1800 * \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
1801 * out of a valid range for \a this array.
1803 * \if ENABLE_EXAMPLES
1804 * \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
1808 void DataArrayTemplate<T>::setPartOfValuesSimple2(T a, const mcIdType *bgTuples, const mcIdType *endTuples, const mcIdType *bgComp, const mcIdType *endComp)
1811 std::size_t nbComp=getNumberOfComponents();
1812 mcIdType nbOfTuples=getNumberOfTuples();
1813 for(const mcIdType *z=bgComp;z!=endComp;z++)
1814 DataArray::CheckValueInRange(ToIdType(nbComp),*z,"invalid component id");
1815 T *pt(getPointer());
1816 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1817 for(const mcIdType *z=bgComp;z!=endComp;z++)
1819 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1820 pt[(std::size_t)(*w)*nbComp+(*z)]=a;
1825 * Copy all values from another DataArrayDouble (\a a) into specified tuples and
1826 * components of \a this array. Textual data is not copied.
1827 * The tuples to assign to are defined by a C array of indices.
1828 * The components to assign to are defined by three values similar to parameters of
1829 * the Python function \c range(\c start,\c stop,\c step).
1830 * There are two *modes of usage*:
1831 * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
1832 * of \a a is assigned to its own location within \a this array.
1833 * - If \a a includes one tuple, then all values of \a a are assigned to the specified
1834 * components of every specified tuple of \a this array. In this mode it is required
1835 * that \a a->getNumberOfComponents() equals to the number of specified components.
1837 * \param [in] a - the array to copy values from.
1838 * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
1839 * assign values of \a a to.
1840 * \param [in] endTuples - specifies the end of the array \a bgTuples, so that
1841 * pointer to a tuple index <em>(pi)</em> varies as this:
1842 * \a bgTuples <= \a pi < \a endTuples.
1843 * \param [in] bgComp - index of the first component of \a this array to assign to.
1844 * \param [in] endComp - index of the component before which the components to assign
1846 * \param [in] stepComp - index increment to get index of the next component to assign to.
1847 * \param [in] strictCompoCompare - this parameter is checked only in the first
1848 * *mode of usage*; if \a strictCompoCompare is \a true (default),
1849 * then \a a->getNumberOfComponents() must be equal
1850 * to the number of specified columns, else this is not required.
1851 * \throw If \a a is NULL.
1852 * \throw If \a a is not allocated.
1853 * \throw If \a this is not allocated.
1854 * \throw If any index of tuple given by \a bgTuples is out of a valid range for
1856 * \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
1857 * if <em> a->getNumberOfComponents()</em> is unequal to the number of components
1858 * defined by <em>(bgComp,endComp,stepComp)</em>.
1859 * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
1860 * <em> a->getNumberOfComponents()</em> is unequal to the number of components
1861 * defined by <em>(bgComp,endComp,stepComp)</em>.
1862 * \throw If parameters specifying components to assign to, do not give a
1863 * non-empty range of increasing indices or indices are out of a valid range
1864 * for \c this array.
1866 * \if ENABLE_EXAMPLES
1867 * \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
1871 void DataArrayTemplate<T>::setPartOfValues3(const typename Traits<T>::ArrayType *a, const mcIdType *bgTuples, const mcIdType *endTuples, mcIdType bgComp, mcIdType endComp, mcIdType stepComp, bool strictCompoCompare)
1874 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValues3 : input DataArrayDouble is NULL !");
1875 const char msg[]="DataArrayTemplate::setPartOfValues3";
1877 a->checkAllocated();
1878 mcIdType newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
1879 std::size_t nbComp(getNumberOfComponents());
1880 mcIdType nbOfTuples(getNumberOfTuples());
1881 DataArray::CheckValueInRangeEx(ToIdType(nbComp),bgComp,endComp,"invalid component value");
1882 mcIdType newNbOfTuples=ToIdType(std::distance(bgTuples,endTuples));
1883 bool assignTech=true;
1884 if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
1886 if(strictCompoCompare)
1887 a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1891 a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
1894 T *pt(getPointer()+bgComp);
1895 const T *srcPt(a->getConstPointer());
1898 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1899 for(mcIdType j=0;j<newNbOfComp;j++,srcPt++)
1901 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1902 pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
1907 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1909 const T *srcPt2=srcPt;
1910 for(mcIdType j=0;j<newNbOfComp;j++,srcPt2++)
1912 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1913 pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
1920 * Assign a given value to values at specified tuples and components of \a this array.
1921 * The tuples to assign to are defined by a C array of indices.
1922 * The components to assign to are defined by three values similar to parameters of
1923 * the Python function \c range(\c start,\c stop,\c step).
1924 * \param [in] a - the value to assign.
1925 * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
1927 * \param [in] endTuples - specifies the end of the array \a bgTuples, so that
1928 * pointer to a tuple index <em>(pi)</em> varies as this:
1929 * \a bgTuples <= \a pi < \a endTuples.
1930 * \param [in] bgComp - index of the first component of \a this array to assign to.
1931 * \param [in] endComp - index of the component before which the components to assign
1933 * \param [in] stepComp - index increment to get index of the next component to assign to.
1934 * \throw If \a this is not allocated.
1935 * \throw If any index of tuple given by \a bgTuples is out of a valid range for
1937 * \throw If parameters specifying components to assign to, do not give a
1938 * non-empty range of increasing indices or indices are out of a valid range
1939 * for \c this array.
1941 * \if ENABLE_EXAMPLES
1942 * \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
1946 void DataArrayTemplate<T>::setPartOfValuesSimple3(T a, const mcIdType *bgTuples, const mcIdType *endTuples, mcIdType bgComp, mcIdType endComp, mcIdType stepComp)
1948 const char msg[]="DataArrayTemplate::setPartOfValuesSimple3";
1950 std::size_t newNbOfComp(DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg));
1951 std::size_t nbComp(getNumberOfComponents());
1952 mcIdType nbOfTuples(getNumberOfTuples());
1953 DataArray::CheckValueInRangeEx(ToIdType(nbComp),bgComp,endComp,"invalid component value");
1954 T *pt(getPointer()+bgComp);
1955 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1956 for(std::size_t j=0;j<newNbOfComp;j++)
1958 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1959 pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
1964 * Copy all values from another DataArrayDouble into specified tuples and components
1965 * of \a this array. Textual data is not copied.
1966 * The tree parameters defining set of indices of tuples and components are similar to
1967 * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
1968 * \param [in] a - the array to copy values from.
1969 * \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
1970 * \param [in] endTuples - index of the tuple before which the tuples to assign to
1972 * \param [in] stepTuples - index increment to get index of the next tuple to assign to.
1973 * \param [in] bgComp - pointer to an array of component indices of \a this array to
1975 * \param [in] endComp - specifies the end of the array \a bgTuples, so that
1976 * pointer to a component index (\a pi) varies as this:
1977 * \a bgComp <= \a pi < \a endComp.
1978 * \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents()
1979 * must be equal to the number of columns to assign to, else an
1980 * exception is thrown; if \a false, then it is only required that \a
1981 * a->getNbOfElems() equals to number of values to assign to (this condition
1982 * must be respected even if \a strictCompoCompare is \a true). The number of
1983 * values to assign to is given by following Python expression:
1984 * \a nbTargetValues =
1985 * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
1986 * \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1987 * \throw If \a a is NULL.
1988 * \throw If \a a is not allocated.
1989 * \throw If \a this is not allocated.
1990 * \throw If parameters specifying tuples and components to assign to do not give a
1991 * non-empty range of increasing indices.
1992 * \throw If \a a->getNbOfElems() != \a nbTargetValues.
1993 * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
1994 * \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1998 void DataArrayTemplate<T>::setPartOfValues4(const typename Traits<T>::ArrayType *a, mcIdType bgTuples, mcIdType endTuples, mcIdType stepTuples, const mcIdType *bgComp, const mcIdType *endComp, bool strictCompoCompare)
2000 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValues4 : input DataArrayTemplate is NULL !");
2001 const char msg[]="DataArrayTemplate::setPartOfValues4";
2003 a->checkAllocated();
2004 mcIdType newNbOfTuples(DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg));
2005 std::size_t newNbOfComp(std::distance(bgComp,endComp));
2006 std::size_t nbComp(getNumberOfComponents());
2007 for(const mcIdType *z=bgComp;z!=endComp;z++)
2008 DataArray::CheckValueInRange(ToIdType(nbComp),*z,"invalid component id");
2009 mcIdType nbOfTuples(getNumberOfTuples());
2010 DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2011 bool assignTech(true);
2012 if(a->getNbOfElems()==ToIdType(newNbOfTuples*newNbOfComp))
2014 if(strictCompoCompare)
2015 a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2019 a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2022 const T *srcPt(a->getConstPointer());
2023 T *pt(getPointer()+bgTuples*nbComp);
2026 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2027 for(const mcIdType *z=bgComp;z!=endComp;z++,srcPt++)
2032 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2034 const T *srcPt2(srcPt);
2035 for(const mcIdType *z=bgComp;z!=endComp;z++,srcPt2++)
2042 void DataArrayTemplate<T>::setPartOfValuesSimple4(T a, mcIdType bgTuples, mcIdType endTuples, mcIdType stepTuples, const mcIdType *bgComp, const mcIdType *endComp)
2044 const char msg[]="DataArrayTemplate::setPartOfValuesSimple4";
2046 mcIdType newNbOfTuples(DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg));
2047 std::size_t nbComp(getNumberOfComponents());
2048 for(const mcIdType *z=bgComp;z!=endComp;z++)
2049 DataArray::CheckValueInRange(ToIdType(nbComp),*z,"invalid component id");
2050 mcIdType nbOfTuples(getNumberOfTuples());
2051 DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2052 T *pt=getPointer()+bgTuples*nbComp;
2053 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2054 for(const mcIdType *z=bgComp;z!=endComp;z++)
2059 * Copy some tuples from another DataArrayDouble into specified tuples
2060 * of \a this array. Textual data is not copied. Both arrays must have equal number of
2062 * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2063 * All components of selected tuples are copied.
2064 * \param [in] a - the array to copy values from.
2065 * \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2066 * target tuples of \a this. \a tuplesSelec has two components, and the
2067 * first component specifies index of the source tuple and the second
2068 * one specifies index of the target tuple.
2069 * \throw If \a this is not allocated.
2070 * \throw If \a a is NULL.
2071 * \throw If \a a is not allocated.
2072 * \throw If \a tuplesSelec is NULL.
2073 * \throw If \a tuplesSelec is not allocated.
2074 * \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2075 * \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2076 * \throw If any tuple index given by \a tuplesSelec is out of a valid range for
2077 * the corresponding (\a this or \a a) array.
2080 void DataArrayTemplate<T>::setPartOfValuesAdv(const typename Traits<T>::ArrayType *a, const DataArrayIdType *tuplesSelec)
2082 if(!a || !tuplesSelec)
2083 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValuesAdv : input DataArrayTemplate is NULL !");
2085 a->checkAllocated();
2086 tuplesSelec->checkAllocated();
2087 std::size_t nbOfComp(getNumberOfComponents());
2088 if(nbOfComp!=a->getNumberOfComponents())
2089 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValuesAdv : This and a do not have the same number of components !");
2090 if(tuplesSelec->getNumberOfComponents()!=2)
2091 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2092 mcIdType thisNt(getNumberOfTuples());
2093 mcIdType aNt(a->getNumberOfTuples());
2094 T *valsToSet(getPointer());
2095 const T *valsSrc(a->getConstPointer());
2096 for(const mcIdType *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2098 if(tuple[1]>=0 && tuple[1]<aNt)
2100 if(tuple[0]>=0 && tuple[0]<thisNt)
2101 std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2104 std::ostringstream oss; oss << "DataArrayTemplate::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2105 oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2106 throw INTERP_KERNEL::Exception(oss.str().c_str());
2111 std::ostringstream oss; oss << "DataArrayTemplate::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2112 oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2113 throw INTERP_KERNEL::Exception(oss.str().c_str());
2119 * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2120 * of \a this array. Textual data is not copied. Both arrays must have equal number of
2122 * The tuples to assign to are defined by index of the first tuple, and
2123 * their number is defined by \a tuplesSelec->getNumberOfTuples().
2124 * The tuples to copy are defined by values of a DataArrayInt.
2125 * All components of selected tuples are copied.
2126 * \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2128 * \param [in] aBase - the array to copy values from.
2129 * \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2130 * \throw If \a this is not allocated.
2131 * \throw If \a aBase is NULL.
2132 * \throw If \a aBase is not allocated.
2133 * \throw If \a tuplesSelec is NULL.
2134 * \throw If \a tuplesSelec is not allocated.
2135 * \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2136 * \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2137 * \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2138 * \throw If any tuple index given by \a tuplesSelec is out of a valid range for
2142 void DataArrayTemplate<T>::setContigPartOfSelectedValues(mcIdType tupleIdStart, const DataArray *aBase, const DataArrayIdType *tuplesSelec)
2144 if(!aBase || !tuplesSelec)
2145 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : input DataArray is NULL !");
2146 const typename Traits<T>::ArrayType *a(dynamic_cast<const typename Traits<T>::ArrayType *>(aBase));
2148 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2150 a->checkAllocated();
2151 tuplesSelec->checkAllocated();
2152 std::size_t nbOfComp(getNumberOfComponents());
2153 if(nbOfComp!=a->getNumberOfComponents())
2154 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2155 if(tuplesSelec->getNumberOfComponents()!=1)
2156 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2157 mcIdType thisNt(getNumberOfTuples());
2158 mcIdType aNt(a->getNumberOfTuples());
2159 mcIdType nbOfTupleToWrite(tuplesSelec->getNumberOfTuples());
2160 T *valsToSet(getPointer()+tupleIdStart*nbOfComp);
2161 if(tupleIdStart+nbOfTupleToWrite>thisNt)
2162 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : invalid number range of values to write !");
2163 const T *valsSrc=a->getConstPointer();
2164 for(const mcIdType *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2166 if(*tuple>=0 && *tuple<aNt)
2168 std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2172 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2173 oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2174 throw INTERP_KERNEL::Exception(oss.str().c_str());
2180 * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2181 * of \a this array. Textual data is not copied. Both arrays must have equal number of
2183 * The tuples to copy are defined by three values similar to parameters of
2184 * the Python function \c range(\c start,\c stop,\c step).
2185 * The tuples to assign to are defined by index of the first tuple, and
2186 * their number is defined by number of tuples to copy.
2187 * All components of selected tuples are copied.
2188 * \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2190 * \param [in] aBase - the array to copy values from.
2191 * \param [in] bg - index of the first tuple to copy of the array \a aBase.
2192 * \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2194 * \param [in] step - index increment to get index of the next tuple to copy.
2195 * \throw If \a this is not allocated.
2196 * \throw If \a aBase is NULL.
2197 * \throw If \a aBase is not allocated.
2198 * \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2199 * \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2200 * \throw If parameters specifying tuples to copy, do not give a
2201 * non-empty range of increasing indices or indices are out of a valid range
2202 * for the array \a aBase.
2205 void DataArrayTemplate<T>::setContigPartOfSelectedValuesSlice(mcIdType tupleIdStart, const DataArray *aBase, mcIdType bg, mcIdType end2, mcIdType step)
2209 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::setContigPartOfSelectedValuesSlice : input DataArray is NULL !";
2210 throw INTERP_KERNEL::Exception(oss.str().c_str());
2212 const typename Traits<T>::ArrayType *a(dynamic_cast<const typename Traits<T>::ArrayType *>(aBase));
2214 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValuesSlice : input DataArray aBase is not a DataArrayDouble !");
2216 a->checkAllocated();
2217 std::size_t nbOfComp(getNumberOfComponents());
2218 const char msg[]="DataArrayDouble::setContigPartOfSelectedValuesSlice";
2219 mcIdType nbOfTupleToWrite(DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg));
2220 if(nbOfComp!=a->getNumberOfComponents())
2221 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValuesSlice : This and a do not have the same number of components !");
2222 mcIdType thisNt(getNumberOfTuples());
2223 mcIdType aNt(a->getNumberOfTuples());
2224 T *valsToSet(getPointer()+tupleIdStart*nbOfComp);
2225 if(tupleIdStart+nbOfTupleToWrite>thisNt)
2226 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValuesSlice : invalid number range of values to write !");
2228 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValuesSlice : invalid range of values to read !");
2229 const T *valsSrc(a->getConstPointer()+bg*nbOfComp);
2230 for(mcIdType i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2232 std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2237 * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
2238 * of tuples specified by \a ranges parameter.
2239 * For more info on renumbering see \ref numbering.
2240 * \param [in] ranges - std::vector of std::pair's each of which defines a range
2241 * of tuples in [\c begin,\c end) format.
2242 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2243 * is to delete using decrRef() as it is no more needed.
2244 * \throw If \a end < \a begin.
2245 * \throw If \a end > \a this->getNumberOfTuples().
2246 * \throw If \a this is not allocated.
2249 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleRanges(const std::vector<std::pair<mcIdType,mcIdType> >& ranges) const
2252 std::size_t nbOfComp(getNumberOfComponents());
2253 mcIdType nbOfTuplesThis(getNumberOfTuples());
2256 MCAuto<DataArray> ret0(buildNewEmptyInstance());
2257 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
2258 ret->alloc(0,nbOfComp);
2259 ret->copyStringInfoFrom(*this);
2262 mcIdType ref(ranges.front().first),nbOfTuples(0);
2263 bool isIncreasing(true);
2264 for(std::vector<std::pair<mcIdType,mcIdType> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
2266 if((*it).first<=(*it).second)
2268 if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
2270 nbOfTuples+=(*it).second-(*it).first;
2272 isIncreasing=ref<=(*it).first;
2277 std::ostringstream oss; oss << "DataArrayTemplate::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
2278 oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
2279 throw INTERP_KERNEL::Exception(oss.str().c_str());
2284 std::ostringstream oss; oss << "DataArrayTemplate::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
2285 oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
2286 throw INTERP_KERNEL::Exception(oss.str().c_str());
2289 if(isIncreasing && nbOfTuplesThis==nbOfTuples)
2290 return static_cast<typename Traits<T>::ArrayType *>(deepCopy());
2291 MCAuto<DataArray> ret0(buildNewEmptyInstance());
2292 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
2293 ret->alloc(nbOfTuples,nbOfComp);
2294 ret->copyStringInfoFrom(*this);
2295 const T *src(getConstPointer());
2296 T *work(ret->getPointer());
2297 for(std::vector<std::pair<mcIdType,mcIdType> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
2298 work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
2303 * Returns the first value of \a this.
2304 * \return double - the last value of \a this array.
2305 * \throw If \a this is not allocated.
2306 * \throw If \a this->getNumberOfComponents() != 1.
2307 * \throw If \a this->getNumberOfTuples() < 1.
2310 T DataArrayTemplate<T>::front() const
2313 if(getNumberOfComponents()!=1)
2314 throw INTERP_KERNEL::Exception("DataArrayTemplate::front : number of components not equal to one !");
2315 mcIdType nbOfTuples=getNumberOfTuples();
2317 throw INTERP_KERNEL::Exception("DataArrayTemplate::front : number of tuples must be >= 1 !");
2318 return *(getConstPointer());
2322 * Returns the last value of \a this.
2323 * \return double - the last value of \a this array.
2324 * \throw If \a this is not allocated.
2325 * \throw If \a this->getNumberOfComponents() != 1.
2326 * \throw If \a this->getNumberOfTuples() < 1.
2329 T DataArrayTemplate<T>::back() const
2332 if(getNumberOfComponents()!=1)
2333 throw INTERP_KERNEL::Exception("DataArrayTemplate::back : number of components not equal to one !");
2334 mcIdType nbOfTuples=getNumberOfTuples();
2336 throw INTERP_KERNEL::Exception("DataArrayTemplate::back : number of tuples must be >= 1 !");
2337 return *(getConstPointer()+nbOfTuples-1);
2341 * Returns the maximal value and its location within \a this one-dimensional array.
2342 * \param [out] tupleId - index of the tuple holding the maximal value.
2343 * \return double - the maximal value among all values of \a this array.
2344 * \throw If \a this->getNumberOfComponents() != 1
2345 * \throw If \a this->getNumberOfTuples() < 1
2346 * \sa getMaxAbsValue, getMinValue
2349 T DataArrayTemplate<T>::getMaxValue(mcIdType& tupleId) const
2352 if(getNumberOfComponents()!=1)
2353 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 !");
2354 mcIdType nbOfTuples=getNumberOfTuples();
2356 throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
2357 const T *vals(getConstPointer());
2358 const T *loc(std::max_element(vals,vals+nbOfTuples));
2359 tupleId=ToIdType(std::distance(vals,loc));
2364 * Returns the maximal value within \a this array that is allowed to have more than
2366 * \return double - the maximal value among all values of \a this array.
2367 * \throw If \a this is not allocated.
2368 * \sa getMaxAbsValueInArray, getMinValueInArray
2371 T DataArrayTemplate<T>::getMaxValueInArray() const
2374 const T *loc(std::max_element(begin(),end()));
2379 * Returns the maximal absolute value in \a this and the first occurrence location associated to it.
2380 * \return the element in this (positive or negative) having the max abs value in \a this.
2381 * \throw If \a this is not allocated.
2382 * \throw If \a this is non one component array.
2383 * \throw If \a this is empty.
2386 T DataArrayTemplate<T>::getMaxAbsValue(std::size_t& tupleId) const
2389 if(getNumberOfComponents()!=1)
2390 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 !");
2391 mcIdType nbTuples(this->getNumberOfTuples());
2393 throw INTERP_KERNEL::Exception("DataArrayTemplate<T>::getMaxAbsValue : empty array !");
2396 const T *pt(begin());
2397 for(mcIdType i=0;i<nbTuples;i++,pt++)
2399 T cand((T)std::abs(*pt));
2406 return this->getIJ(ToIdType(tupleId),0);
2410 * Returns the maximal absolute value in \a this.
2411 * \throw If \a this is not allocated.
2412 * \throw If \a this is non one component array.
2413 * \throw If \a this is empty.
2416 T DataArrayTemplate<T>::getMaxAbsValueInArray() const
2419 return getMaxAbsValue(dummy);
2423 * Returns the minimal value and its location within \a this one-dimensional array.
2424 * \param [out] tupleId - index of the tuple holding the minimal value.
2425 * \return double - the minimal value among all values of \a this array.
2426 * \throw If \a this->getNumberOfComponents() != 1
2427 * \throw If \a this->getNumberOfTuples() < 1
2430 T DataArrayTemplate<T>::getMinValue(mcIdType& tupleId) const
2433 if(getNumberOfComponents()!=1)
2434 throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
2435 mcIdType nbOfTuples=getNumberOfTuples();
2437 throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
2438 const T *vals(getConstPointer());
2439 const T *loc(std::min_element(vals,vals+nbOfTuples));
2440 tupleId=ToIdType(std::distance(vals,loc));
2445 * Returns the minimal value within \a this array that is allowed to have more than
2447 * \return double - the minimal value among all values of \a this array.
2448 * \throw If \a this is not allocated.
2451 T DataArrayTemplate<T>::getMinValueInArray() const
2454 const T *loc=std::min_element(begin(),end());
2459 void DataArrayTemplate<T>::circularPermutation(mcIdType nbOfShift)
2462 std::size_t nbOfCompo(getNumberOfComponents());
2463 mcIdType nbTuples(getNumberOfTuples());
2464 mcIdType effNbSh(EffectiveCircPerm(nbOfShift,nbTuples));
2467 T *work(getPointer());
2468 if(effNbSh<nbTuples-effNbSh)
2470 typename INTERP_KERNEL::AutoPtr<T> buf(new T[effNbSh*nbOfCompo]);
2471 std::copy(work,work+effNbSh*nbOfCompo,(T *)buf);
2472 std::copy(work+effNbSh*nbOfCompo,work+nbTuples*nbOfCompo,work);// ze big shift
2473 std::copy((T *)buf,(T *)buf+effNbSh*nbOfCompo,work+(nbTuples-effNbSh)*nbOfCompo);
2477 typename INTERP_KERNEL::AutoPtr<T> buf(new T[(nbTuples-effNbSh)*nbOfCompo]);
2478 std::copy(work+effNbSh*nbOfCompo,work+nbTuples*nbOfCompo,(T *)buf);
2479 std::copy(work,work+effNbSh*nbOfCompo,work+(nbTuples-effNbSh)*nbOfCompo);// ze big shift
2480 std::copy((T*)buf,(T *)buf+(nbTuples-effNbSh)*nbOfCompo,work);
2485 void DataArrayTemplate<T>::circularPermutationPerTuple(mcIdType nbOfShift)
2488 std::size_t nbOfCompo(getNumberOfComponents());
2489 mcIdType nbTuples(getNumberOfTuples());
2490 mcIdType effNbSh(EffectiveCircPerm(nbOfShift,ToIdType(nbOfCompo)));
2493 T *work(getPointer());
2494 if(effNbSh<ToIdType(nbOfCompo)-effNbSh)
2496 typename INTERP_KERNEL::AutoPtr<T> buf(new T[effNbSh]);
2497 for(mcIdType i=0;i<nbTuples;i++,work+=nbOfCompo)
2499 std::copy(work,work+effNbSh,(T *)buf);
2500 std::copy(work+effNbSh,work+nbOfCompo,work);// ze big shift
2501 std::copy((T *)buf,(T *)buf+effNbSh,work+(nbOfCompo-effNbSh));
2506 typename INTERP_KERNEL::AutoPtr<T> buf(new T[nbOfCompo-effNbSh]);
2507 for(mcIdType i=0;i<nbTuples;i++,work+=nbOfCompo)
2509 std::copy(work+effNbSh,work+nbOfCompo,(T *)buf);
2510 std::copy(work,work+effNbSh,work+(nbOfCompo-effNbSh));// ze big shift
2511 std::copy((T*)buf,(T *)buf+(nbOfCompo-effNbSh),work);
2514 std::vector<std::string> sts(nbOfCompo);
2515 for(std::size_t i=0;i<nbOfCompo;i++)
2516 sts[i]=_info_on_compo[(i+effNbSh)%nbOfCompo];
2517 setInfoOnComponents(sts);
2521 void DataArrayTemplate<T>::reversePerTuple()
2524 std::size_t nbOfCompo(getNumberOfComponents());
2525 mcIdType nbTuples(getNumberOfTuples());
2528 T *work(getPointer());
2529 for(mcIdType i=0;i<nbTuples;i++,work+=nbOfCompo)
2530 std::reverse(work,work+nbOfCompo);
2531 std::reverse(_info_on_compo.begin(),_info_on_compo.end());
2535 * Assign pointer to one array to a pointer to another appay. Reference counter of
2536 * \a arrayToSet is incremented / decremented.
2537 * \param [in] newArray - the pointer to array to assign to \a arrayToSet.
2538 * \param [in,out] arrayToSet - the pointer to array to assign to.
2541 void DataArrayTemplate<T>::SetArrayIn(typename Traits<T>::ArrayType *newArray, typename Traits<T>::ArrayType* &arrayToSet)
2543 if(newArray!=arrayToSet)
2546 arrayToSet->decrRef();
2547 arrayToSet=newArray;
2549 arrayToSet->incrRef();
2554 * Assign zero to all values in \a this array. To know more on filling arrays see
2555 * \ref MEDCouplingArrayFill.
2556 * \throw If \a this is not allocated.
2559 void DataArrayTemplate<T>::fillWithZero()
2561 fillWithValue((T)0);
2564 //////////////////////////////
2568 // local static function to copy arrays without warnings
2569 template <class TIn, class TOut>
2570 static void copyCast (const TIn *begin, const TIn *end, TOut* dest)
2572 for (const TIn *src = begin; src != end; ++src, ++dest)
2573 *dest=static_cast<TOut>(*src);
2579 MCAuto< typename Traits<U>::ArrayType > DataArrayTemplateClassic<T>::convertToOtherTypeOfArr() const
2581 this->checkAllocated();
2582 MCAuto<typename Traits<U>::ArrayType> ret(Traits<U>::ArrayType::New());
2583 ret->alloc(this->getNumberOfTuples(),this->getNumberOfComponents());
2584 std::size_t nbOfVals(this->getNbOfElems());
2585 const T *src(this->begin());
2586 U *dest(ret->getPointer());
2587 // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
2588 copyCast(src, src+nbOfVals, dest);
2589 //std::copy(src,src+nbOfVals,dest);
2590 ret->copyStringInfoFrom(*this);
2595 * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
2596 * array to the new one.
2597 * \return DataArrayDouble * - the new instance of DataArrayInt.
2600 MCAuto<DataArrayDouble> DataArrayTemplateClassic<T>::convertToDblArr() const
2602 return convertToOtherTypeOfArr<double>();
2606 * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
2607 * array to the new one.
2608 * \return DataArrayInt * - the new instance of DataArrayInt.
2611 MCAuto<DataArrayInt> DataArrayTemplateClassic<T>::convertToIntArr() const
2613 return convertToOtherTypeOfArr<int>();
2617 * Creates a new DataArrayFloat and assigns all (textual and numerical) data of \a this
2618 * array to the new one.
2619 * \return DataArrayFloat * - the new instance of DataArrayInt.
2622 MCAuto<DataArrayFloat> DataArrayTemplateClassic<T>::convertToFloatArr() const
2624 return convertToOtherTypeOfArr<float>();
2628 * Apply a linear function to a given component of \a this array, so that
2629 * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
2630 * \param [in] a - the first coefficient of the function.
2631 * \param [in] b - the second coefficient of the function.
2632 * \param [in] compoId - the index of component to modify.
2633 * \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
2636 void DataArrayTemplateClassic<T>::applyLin(T a, T b, std::size_t compoId)
2638 this->checkAllocated();
2639 std::size_t nbOfComp=this->getNumberOfComponents();
2640 if(compoId>=nbOfComp)
2642 std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
2643 throw INTERP_KERNEL::Exception(oss.str().c_str());
2645 T *ptr(this->getPointer()+compoId);
2646 mcIdType nbOfTuple=this->getNumberOfTuples();
2647 for(mcIdType i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
2649 this->declareAsNew();
2653 * Apply a linear function to all elements of \a this array, so that
2654 * an element _x_ becomes \f$ a * x + b \f$.
2655 * \param [in] a - the first coefficient of the function.
2656 * \param [in] b - the second coefficient of the function.
2657 * \throw If \a this is not allocated.
2660 void DataArrayTemplateClassic<T>::applyLin(T a, T b)
2662 this->checkAllocated();
2663 T *ptr(this->getPointer());
2664 std::size_t nbOfElems(this->getNbOfElems());
2665 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2667 this->declareAsNew();
2671 * Returns a full copy of \a this array except that sign of all elements is reversed.
2672 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2673 * same number of tuples and component as \a this array.
2674 * The caller is to delete this result array using decrRef() as it is no more
2676 * \throw If \a this is not allocated.
2679 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::negate() const
2681 this->checkAllocated();
2682 MCAuto<typename Traits<T>::ArrayType> newArr(Traits<T>::ArrayType::New());
2683 mcIdType nbOfTuples(this->getNumberOfTuples());
2684 std::size_t nbOfComp(this->getNumberOfComponents());
2685 newArr->alloc(nbOfTuples,nbOfComp);
2686 const T *cptr(this->begin());
2687 std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<T>());
2688 newArr->copyStringInfoFrom(*this);
2689 return newArr.retn();
2694 void DataArrayTemplateClassic<T>::somethingEqual(const typename Traits<T>::ArrayType *other)
2697 throw INTERP_KERNEL::Exception("DataArray<T>::SomethingEqual : input DataArray<T> instance is NULL !");
2698 const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
2699 this->checkAllocated();
2700 other->checkAllocated();
2701 mcIdType nbOfTuple(this->getNumberOfTuples());
2702 mcIdType nbOfTuple2(other->getNumberOfTuples());
2703 std::size_t nbOfComp(this->getNumberOfComponents());
2704 std::size_t nbOfComp2(other->getNumberOfComponents());
2705 if(nbOfTuple==nbOfTuple2)
2707 if(nbOfComp==nbOfComp2)
2709 std::transform(this->begin(),this->end(),other->begin(),this->getPointer(),FCT());
2711 else if(nbOfComp2==1)
2713 T *ptr(this->getPointer());
2714 const T *ptrc(other->begin());
2715 for(mcIdType i=0;i<nbOfTuple;i++)
2716 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(FCT(),*ptrc++));
2719 throw INTERP_KERNEL::Exception(msg);
2721 else if(nbOfTuple2==1)
2723 if(nbOfComp2==nbOfComp)
2725 T *ptr(this->getPointer());
2726 const T *ptrc(other->begin());
2727 for(mcIdType i=0;i<nbOfTuple;i++)
2728 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,FCT());
2731 throw INTERP_KERNEL::Exception(msg);
2734 throw INTERP_KERNEL::Exception(msg);
2735 this->declareAsNew();
2739 * Adds values of another DataArrayDouble to values of \a this one. There are 3
2741 * 1. The arrays have same number of tuples and components. Then each value of
2742 * \a other array is added to the corresponding value of \a this array, i.e.:
2743 * _a_ [ i, j ] += _other_ [ i, j ].
2744 * 2. The arrays have same number of tuples and \a other array has one component. Then
2745 * _a_ [ i, j ] += _other_ [ i, 0 ].
2746 * 3. The arrays have same number of components and \a other array has one tuple. Then
2747 * _a_ [ i, j ] += _a2_ [ 0, j ].
2749 * \param [in] other - an array to add to \a this one.
2750 * \throw If \a other is NULL.
2751 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
2752 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
2753 * \a other has number of both tuples and components not equal to 1.
2756 void DataArrayTemplateClassic<T>::addEqual(const typename Traits<T>::ArrayType *other)
2758 this->somethingEqual< std::plus<T> >(other);
2762 * Subtract values of another DataArrayDouble from values of \a this one. There are 3
2764 * 1. The arrays have same number of tuples and components. Then each value of
2765 * \a other array is subtracted from the corresponding value of \a this array, i.e.:
2766 * _a_ [ i, j ] -= _other_ [ i, j ].
2767 * 2. The arrays have same number of tuples and \a other array has one component. Then
2768 * _a_ [ i, j ] -= _other_ [ i, 0 ].
2769 * 3. The arrays have same number of components and \a other array has one tuple. Then
2770 * _a_ [ i, j ] -= _a2_ [ 0, j ].
2772 * \param [in] other - an array to subtract from \a this one.
2773 * \throw If \a other is NULL.
2774 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
2775 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
2776 * \a other has number of both tuples and components not equal to 1.
2779 void DataArrayTemplateClassic<T>::substractEqual(const typename Traits<T>::ArrayType *other)
2781 this->somethingEqual< std::minus<T> >(other);
2785 * Multiply values of another DataArrayDouble to values of \a this one. There are 3
2787 * 1. The arrays have same number of tuples and components. Then each value of
2788 * \a other array is multiplied to the corresponding value of \a this array, i.e.
2789 * _this_ [ i, j ] *= _other_ [ i, j ].
2790 * 2. The arrays have same number of tuples and \a other array has one component. Then
2791 * _this_ [ i, j ] *= _other_ [ i, 0 ].
2792 * 3. The arrays have same number of components and \a other array has one tuple. Then
2793 * _this_ [ i, j ] *= _a2_ [ 0, j ].
2795 * \param [in] other - an array to multiply to \a this one.
2796 * \throw If \a other is NULL.
2797 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
2798 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
2799 * \a other has number of both tuples and components not equal to 1.
2802 void DataArrayTemplateClassic<T>::multiplyEqual(const typename Traits<T>::ArrayType *other)
2804 this->somethingEqual< std::multiplies<T> >(other);
2808 * Divide values of \a this array by values of another DataArrayDouble. There are 3
2810 * 1. The arrays have same number of tuples and components. Then each value of
2811 * \a this array is divided by the corresponding value of \a other one, i.e.:
2812 * _a_ [ i, j ] /= _other_ [ i, j ].
2813 * 2. The arrays have same number of tuples and \a other array has one component. Then
2814 * _a_ [ i, j ] /= _other_ [ i, 0 ].
2815 * 3. The arrays have same number of components and \a other array has one tuple. Then
2816 * _a_ [ i, j ] /= _a2_ [ 0, j ].
2818 * \warning No check of division by zero is performed!
2819 * \param [in] other - an array to divide \a this one by.
2820 * \throw If \a other is NULL.
2821 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
2822 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
2823 * \a other has number of both tuples and components not equal to 1.
2826 void DataArrayTemplateClassic<T>::divideEqual(const typename Traits<T>::ArrayType *other)
2828 this->somethingEqual< std::divides<T> >(other);
2831 template<class T, class FCT>
2832 typename Traits<T>::ArrayType *DivSub(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
2835 throw INTERP_KERNEL::Exception("DivSub : input DataArrayDouble instance is NULL !");
2836 mcIdType nbOfTuple1(a1->getNumberOfTuples());
2837 mcIdType nbOfTuple2(a2->getNumberOfTuples());
2838 std::size_t nbOfComp1(a1->getNumberOfComponents());
2839 std::size_t nbOfComp2(a2->getNumberOfComponents());
2840 if(nbOfTuple2==nbOfTuple1)
2842 if(nbOfComp1==nbOfComp2)
2844 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
2845 ret->alloc(nbOfTuple2,nbOfComp1);
2846 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),FCT());
2847 ret->copyStringInfoFrom(*a1);
2850 else if(nbOfComp2==1)
2852 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
2853 ret->alloc(nbOfTuple1,nbOfComp1);
2854 const T *a2Ptr(a2->begin()),*a1Ptr(a1->begin());
2855 T *res(ret->getPointer());
2856 for(mcIdType i=0;i<nbOfTuple1;i++)
2857 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(FCT(),a2Ptr[i]));
2858 ret->copyStringInfoFrom(*a1);
2863 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
2867 else if(nbOfTuple2==1)
2869 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
2870 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
2871 ret->alloc(nbOfTuple1,nbOfComp1);
2872 const T *a1ptr=a1->begin(),*a2ptr(a2->begin());
2873 T *pt(ret->getPointer());
2874 for(mcIdType i=0;i<nbOfTuple1;i++)
2875 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,FCT());
2876 ret->copyStringInfoFrom(*a1);
2881 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
2887 * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
2889 * 1. The arrays have same number of tuples and components. Then each value of
2890 * the result array (_a_) is a subtraction of the corresponding values of \a a1 and
2891 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
2892 * 2. The arrays have same number of tuples and one array, say _a2_, has one
2894 * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
2895 * 3. The arrays have same number of components and one array, say _a2_, has one
2897 * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
2899 * Info on components is copied either from the first array (in the first case) or from
2900 * the array with maximal number of elements (getNbOfElems()).
2901 * \param [in] a1 - an array to subtract from.
2902 * \param [in] a2 - an array to subtract.
2903 * \return DataArrayDouble * - the new instance of DataArrayDouble.
2904 * The caller is to delete this result array using decrRef() as it is no more
2906 * \throw If either \a a1 or \a a2 is NULL.
2907 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
2908 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
2909 * none of them has number of tuples or components equal to 1.
2912 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Substract(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
2914 return DivSub< T,std::minus<T> >(a1,a2);
2918 * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
2920 * 1. The arrays have same number of tuples and components. Then each value of
2921 * the result array (_a_) is a division of the corresponding values of \a a1 and
2922 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
2923 * 2. The arrays have same number of tuples and one array, say _a2_, has one
2925 * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
2926 * 3. The arrays have same number of components and one array, say _a2_, has one
2928 * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
2930 * Info on components is copied either from the first array (in the first case) or from
2931 * the array with maximal number of elements (getNbOfElems()).
2932 * \warning No check of division by zero is performed!
2933 * \param [in] a1 - a numerator array.
2934 * \param [in] a2 - a denominator array.
2935 * \return DataArrayDouble * - the new instance of DataArrayDouble.
2936 * The caller is to delete this result array using decrRef() as it is no more
2938 * \throw If either \a a1 or \a a2 is NULL.
2939 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
2940 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
2941 * none of them has number of tuples or components equal to 1.
2944 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Divide(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
2946 return DivSub< T,std::divides<T> >(a1,a2);
2949 template<class T, class FCT>
2950 typename Traits<T>::ArrayType *MulAdd(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
2953 throw INTERP_KERNEL::Exception("DataArrayDouble::MulAdd : input DataArrayDouble instance is NULL !");
2954 mcIdType nbOfTuple(a1->getNumberOfTuples());
2955 mcIdType nbOfTuple2(a2->getNumberOfTuples());
2956 std::size_t nbOfComp(a1->getNumberOfComponents());
2957 std::size_t nbOfComp2(a2->getNumberOfComponents());
2958 MCAuto<typename Traits<T>::ArrayType> ret=0;
2959 if(nbOfTuple==nbOfTuple2)
2961 if(nbOfComp==nbOfComp2)
2963 ret=Traits<T>::ArrayType::New();
2964 ret->alloc(nbOfTuple,nbOfComp);
2965 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),FCT());
2966 ret->copyStringInfoFrom(*a1);
2970 std::size_t nbOfCompMin,nbOfCompMax;
2971 const typename Traits<T>::ArrayType *aMin, *aMax;
2972 if(nbOfComp>nbOfComp2)
2974 nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
2979 nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
2984 ret=Traits<T>::ArrayType::New();
2985 ret->alloc(nbOfTuple,nbOfCompMax);
2986 const T *aMinPtr(aMin->begin());
2987 const T *aMaxPtr(aMax->begin());
2988 T *res=ret->getPointer();
2989 for(mcIdType i=0;i<nbOfTuple;i++)
2990 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(FCT(),aMinPtr[i]));
2991 ret->copyStringInfoFrom(*aMax);
2994 throw INTERP_KERNEL::Exception("Nb of components mismatch for array MulAdd !");
2997 else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
2999 if(nbOfComp==nbOfComp2)
3001 mcIdType nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
3002 const typename Traits<T>::ArrayType *aMin(nbOfTuple>nbOfTuple2?a2:a1);
3003 const typename Traits<T>::ArrayType *aMax(nbOfTuple>nbOfTuple2?a1:a2);
3004 const T *aMinPtr(aMin->begin()),*aMaxPtr(aMax->begin());
3005 ret=Traits<T>::ArrayType::New();
3006 ret->alloc(nbOfTupleMax,nbOfComp);
3007 T *res(ret->getPointer());
3008 for(mcIdType i=0;i<nbOfTupleMax;i++)
3009 res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,FCT());
3010 ret->copyStringInfoFrom(*aMax);
3013 throw INTERP_KERNEL::Exception("Nb of components mismatch for array MulAdd !");
3016 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array MulAdd !");
3021 * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
3023 * 1. The arrays have same number of tuples and components. Then each value of
3024 * the result array (_a_) is a product of the corresponding values of \a a1 and
3025 * \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
3026 * 2. The arrays have same number of tuples and one array, say _a2_, has one
3028 * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
3029 * 3. The arrays have same number of components and one array, say _a2_, has one
3031 * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
3033 * Info on components is copied either from the first array (in the first case) or from
3034 * the array with maximal number of elements (getNbOfElems()).
3035 * \param [in] a1 - a factor array.
3036 * \param [in] a2 - another factor array.
3037 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3038 * The caller is to delete this result array using decrRef() as it is no more
3040 * \throw If either \a a1 or \a a2 is NULL.
3041 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3042 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3043 * none of them has number of tuples or components equal to 1.
3046 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Multiply(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
3048 return MulAdd< T , std::multiplies<T> >(a1,a2);
3052 * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
3054 * 1. The arrays have same number of tuples and components. Then each value of
3055 * the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
3056 * i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
3057 * 2. The arrays have same number of tuples and one array, say _a2_, has one
3059 * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
3060 * 3. The arrays have same number of components and one array, say _a2_, has one
3062 * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
3064 * Info on components is copied either from the first array (in the first case) or from
3065 * the array with maximal number of elements (getNbOfElems()).
3066 * \param [in] a1 - an array to sum up.
3067 * \param [in] a2 - another array to sum up.
3068 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3069 * The caller is to delete this result array using decrRef() as it is no more
3071 * \throw If either \a a1 or \a a2 is NULL.
3072 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3073 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3074 * none of them has number of tuples or components equal to 1.
3077 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Add(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
3079 return MulAdd< T , std::plus<T> >(a1,a2);
3083 * Returns either a \a deep or \a shallow copy of this array. For more info see
3084 * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
3085 * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
3086 * \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
3087 * == \a true) or \a this instance (if \a dCpy == \a false).
3090 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::PerformCopyOrIncrRef(bool dCpy, const typename Traits<T>::ArrayType& self)
3093 return self.deepCopy();
3097 return const_cast<typename Traits<T>::ArrayType *>(&self);
3104 GreatEqual(T v):_v(v) { }
3105 bool operator()(T v) const { return v>=_v; }
3112 GreaterThan(T v):_v(v) { }
3113 bool operator()(T v) const { return v>_v; }
3120 LowerEqual(T v):_v(v) { }
3121 bool operator()(T v) const { return v<=_v; }
3128 LowerThan(T v):_v(v) { }
3129 bool operator()(T v) const { return v<_v; }
3136 InRange(T a, T b):_a(a),_b(b) { }
3137 bool operator()(T v) const { return v>=_a && v<_b; }
3144 NotInRange(T a, T b):_a(a),_b(b) { }
3145 bool operator()(T v) const { return v<_a || v>=_b; }
3150 * 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.
3152 * \return a newly allocated data array that the caller should deal with.
3153 * \sa DataArrayInt::findIdsInRange
3156 DataArrayIdType *DataArrayTemplateClassic<T>::findIdsStrictlyNegative() const
3158 LowerThan<T> lt((T)0);
3159 MCAuto<DataArrayIdType> ret(findIdsAdv(lt));
3164 MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsGreaterOrEqualTo(T val) const
3166 GreatEqual<T> ge(val);
3167 return findIdsAdv(ge);
3171 MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsGreaterThan(T val) const
3173 GreaterThan<T> gt(val);
3174 return findIdsAdv(gt);
3178 MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsLowerOrEqualTo(T val) const
3180 LowerEqual<T> le(val);
3181 return findIdsAdv(le);
3185 MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsLowerThan(T val) const
3187 LowerThan<T> lt(val);
3188 return findIdsAdv(lt);
3192 * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
3193 * of components in the result array is a sum of the number of components of given arrays
3194 * and (2) the number of tuples in the result array is same as that of each of given
3195 * arrays. In other words the i-th tuple of result array includes all components of
3196 * i-th tuples of all given arrays.
3197 * Number of tuples in the given arrays must be the same.
3198 * \param [in] a1 - an array to include in the result array.
3199 * \param [in] a2 - another array to include in the result array.
3200 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3201 * The caller is to delete this result array using decrRef() as it is no more
3203 * \throw If both \a a1 and \a a2 are NULL.
3204 * \throw If any given array is not allocated.
3205 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3208 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Meld(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
3210 std::vector<const typename Traits<T>::ArrayType *> arr(2);
3211 arr[0]=a1; arr[1]=a2;
3216 * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
3217 * of components in the result array is a sum of the number of components of given arrays
3218 * and (2) the number of tuples in the result array is same as that of each of given
3219 * arrays. In other words the i-th tuple of result array includes all components of
3220 * i-th tuples of all given arrays.
3221 * Number of tuples in the given arrays must be the same.
3222 * \param [in] arr - a sequence of arrays to include in the result array.
3223 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3224 * The caller is to delete this result array using decrRef() as it is no more
3226 * \throw If all arrays within \a arr are NULL.
3227 * \throw If any given array is not allocated.
3228 * \throw If getNumberOfTuples() of arrays within \a arr is different.
3231 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Meld(const std::vector<const typename Traits<T>::ArrayType *>& arr)
3233 std::vector<const typename Traits<T>::ArrayType *> a;
3234 for(typename std::vector<const typename Traits<T>::ArrayType *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3238 throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
3239 typename std::vector<const typename Traits<T>::ArrayType *>::const_iterator it;
3240 for(it=a.begin();it!=a.end();it++)
3241 (*it)->checkAllocated();
3243 mcIdType nbOfTuples((*it)->getNumberOfTuples());
3244 std::vector<std::size_t> nbc(a.size());
3245 std::vector<const T *> pts(a.size());
3246 nbc[0]=(*it)->getNumberOfComponents();
3247 pts[0]=(*it++)->getConstPointer();
3248 for(mcIdType i=1;it!=a.end();it++,i++)
3250 if(nbOfTuples!=(*it)->getNumberOfTuples())
3251 throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
3252 nbc[i]=(*it)->getNumberOfComponents();
3253 pts[i]=(*it)->getConstPointer();
3255 std::size_t totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),(std::size_t)0);
3256 typename Traits<T>::ArrayType *ret(Traits<T>::ArrayType::New());
3257 ret->alloc(nbOfTuples,totalNbOfComp);
3258 T *retPtr(ret->getPointer());
3259 for(mcIdType i=0;i<nbOfTuples;i++)
3260 for(std::size_t j=0;j<a.size();j++)
3262 retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
3266 for(std::size_t i=0;i<a.size();i++)
3267 for(std::size_t j=0;j<nbc[i];j++,k++)
3268 ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
3273 * Returns a new DataArrayDouble holding the same values as \a this array but differently
3274 * arranged in memory. If \a this array holds 2 components of 3 values:
3275 * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
3276 * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
3277 * \warning Do not confuse this method with transpose()!
3278 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
3279 * is to delete using decrRef() as it is no more needed.
3280 * \throw If \a this is not allocated.
3283 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::fromNoInterlace() const
3285 if(this->_mem.isNull())
3286 throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
3287 T *tab(this->_mem.fromNoInterlace(this->getNumberOfComponents()));
3288 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
3289 ret->useArray(tab,true,DeallocType::C_DEALLOC,this->getNumberOfTuples(),this->getNumberOfComponents());
3294 * Returns a new DataArrayDouble holding the same values as \a this array but differently
3295 * arranged in memory. If \a this array holds 2 components of 3 values:
3296 * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
3297 * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
3298 * \warning Do not confuse this method with transpose()!
3299 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
3300 * is to delete using decrRef() as it is no more needed.
3301 * \throw If \a this is not allocated.
3304 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::toNoInterlace() const
3306 if(this->_mem.isNull())
3307 throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
3308 T *tab(this->_mem.toNoInterlace(this->getNumberOfComponents()));
3309 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
3310 ret->useArray(tab,true,DeallocType::C_DEALLOC,this->getNumberOfTuples(),this->getNumberOfComponents());
3315 * Appends components of another array to components of \a this one, tuple by tuple.
3316 * So that the number of tuples of \a this array remains the same and the number of
3317 * components increases.
3318 * \param [in] other - the DataArrayDouble to append to \a this one.
3319 * \throw If \a this is not allocated.
3320 * \throw If \a this and \a other arrays have different number of tuples.
3322 * \if ENABLE_EXAMPLES
3323 * \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
3325 * \ref py_mcdataarraydouble_meldwith "Here is a Python example".
3329 void DataArrayTemplateClassic<T>::meldWith(const typename Traits<T>::ArrayType *other)
3331 this->checkAllocated();
3332 other->checkAllocated();
3333 mcIdType nbOfTuples(this->getNumberOfTuples());
3334 if(nbOfTuples!=other->getNumberOfTuples())
3335 throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
3336 std::size_t nbOfComp1=this->getNumberOfComponents();
3337 std::size_t nbOfComp2=other->getNumberOfComponents();
3338 T *newArr=(T *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(T));
3340 const T *inp1(this->begin()),*inp2(other->begin());
3341 for(mcIdType i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
3343 w=std::copy(inp1,inp1+nbOfComp1,w);
3344 w=std::copy(inp2,inp2+nbOfComp2,w);
3346 this->useArray(newArr,true,DeallocType::C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
3347 std::vector<std::size_t> compIds(nbOfComp2);
3348 for(std::size_t i=0;i<nbOfComp2;i++)
3349 compIds[i]=nbOfComp1+i;
3350 this->copyPartOfStringInfoFrom2(compIds,*other);
3355 * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
3356 * \a nbTimes should be at least equal to 1.
3357 * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
3358 * \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.
3361 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::duplicateEachTupleNTimes(mcIdType nbTimes) const
3363 this->checkAllocated();
3364 if(this->getNumberOfComponents()!=1)
3365 throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
3367 throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
3368 mcIdType nbTuples=this->getNumberOfTuples();
3369 const T *inPtr(this->begin());
3370 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New()); ret->alloc(nbTimes*nbTuples,1);
3371 T *retPtr(ret->getPointer());
3372 for(mcIdType i=0;i<nbTuples;i++,inPtr++)
3375 for(mcIdType j=0;j<nbTimes;j++,retPtr++)
3378 ret->copyStringInfoFrom(*this);
3383 void DataArrayTemplateClassic<T>::aggregate(const typename Traits<T>::ArrayType *other)
3386 throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !");
3387 if(this->getNumberOfComponents()!=other->getNumberOfComponents())
3388 throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !");
3389 this->_mem.insertAtTheEnd(other->begin(),other->end());
3393 * Converts every value of \a this array to its absolute value.
3394 * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
3395 * should be called instead.
3397 * \throw If \a this is not allocated.
3398 * \sa DataArrayDouble::computeAbs
3401 void DataArrayTemplateClassic<T>::abs()
3403 this->checkAllocated();
3404 T *ptr(this->getPointer());
3405 std::size_t nbOfElems(this->getNbOfElems());
3406 std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<T,T>(std::abs));
3407 this->declareAsNew();
3411 * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
3412 * This method is a const method (that do not change any values in \a this) contrary to DataArrayDouble::abs method.
3414 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3415 * same number of tuples and component as \a this array.
3416 * The caller is to delete this result array using decrRef() as it is no more
3418 * \throw If \a this is not allocated.
3419 * \sa DataArrayDouble::abs
3422 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::computeAbs() const
3424 this->checkAllocated();
3425 MCAuto<typename Traits<T>::ArrayType> newArr(Traits<T>::ArrayType::New());
3426 mcIdType nbOfTuples(this->getNumberOfTuples());
3427 std::size_t nbOfComp(this->getNumberOfComponents());
3428 newArr->alloc(nbOfTuples,nbOfComp);
3429 std::transform(this->begin(),this->end(),newArr->getPointer(),std::ptr_fun<T,T>(std::abs));
3430 newArr->copyStringInfoFrom(*this);
3431 return newArr.retn();
3435 * Returns either a \a deep or \a shallow copy of this array. For more info see
3436 * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
3437 * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
3438 * \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
3439 * == \a true) or \a this instance (if \a dCpy == \a false).
3442 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::performCopyOrIncrRef(bool dCpy) const
3444 const typename Traits<T>::ArrayType *thisC(static_cast<const typename Traits<T>::ArrayType *>(this));
3445 return DataArrayTemplateClassic<T>::PerformCopyOrIncrRef(dCpy,*thisC);
3449 * Computes for each tuple the sum of number of components values in the tuple and return it.
3451 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3452 * same number of tuples as \a this array and one component.
3453 * The caller is to delete this result array using decrRef() as it is no more
3455 * \throw If \a this is not allocated.
3458 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::sumPerTuple() const
3460 this->checkAllocated();
3461 std::size_t nbOfComp(this->getNumberOfComponents());
3462 mcIdType nbOfTuple(this->getNumberOfTuples());
3463 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
3464 ret->alloc(nbOfTuple,1);
3465 const T *src(this->begin());
3466 T *dest(ret->getPointer());
3467 for(mcIdType i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3468 *dest=std::accumulate(src,src+nbOfComp,(T)0);
3473 * Set all values in \a this array so that the i-th element equals to \a init + i
3474 * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
3475 * \param [in] init - value to assign to the first element of array.
3476 * \throw If \a this->getNumberOfComponents() != 1
3477 * \throw If \a this is not allocated.
3480 void DataArrayTemplateClassic<T>::iota(T init)
3482 this->checkAllocated();
3483 if(this->getNumberOfComponents()!=1)
3484 throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
3485 T *ptr(this->getPointer());
3486 mcIdType ntuples(this->getNumberOfTuples());
3487 for(mcIdType i=0;i<ntuples;i++)
3489 this->declareAsNew();
3493 struct ImplReprTraits { static void SetPrecision(std::ostream& oss) { } };
3496 struct ImplReprTraits<double> { static void SetPrecision(std::ostream& oss) { oss.precision(17); } };
3499 struct ImplReprTraits<float> { static void SetPrecision(std::ostream& oss) { oss.precision(7); } };
3502 void DataArrayTemplateClassic<T>::reprStream(std::ostream& stream) const
3504 stream << "Name of " << Traits<T>::ReprStr << " array : \"" << this->_name << "\"\n";
3505 reprWithoutNameStream(stream);
3509 void DataArrayTemplateClassic<T>::reprZipStream(std::ostream& stream) const
3511 stream << "Name of " << Traits<T>::ReprStr << " array : \"" << this->_name << "\"\n";
3512 reprZipWithoutNameStream(stream);
3516 void DataArrayTemplateClassic<T>::reprNotTooLongStream(std::ostream& stream) const
3518 stream << "Name of "<< Traits<T>::ReprStr << " array : \"" << this->_name << "\"\n";
3519 reprNotTooLongWithoutNameStream(stream);
3523 void DataArrayTemplateClassic<T>::reprWithoutNameStream(std::ostream& stream) const
3525 DataArray::reprWithoutNameStream(stream);
3526 ImplReprTraits<T>::SetPrecision(stream);
3527 this->_mem.repr(ToIdType(this->getNumberOfComponents()),stream);
3531 void DataArrayTemplateClassic<T>::reprZipWithoutNameStream(std::ostream& stream) const
3533 DataArray::reprWithoutNameStream(stream);
3534 ImplReprTraits<T>::SetPrecision(stream);
3535 this->_mem.reprZip(ToIdType(this->getNumberOfComponents()),stream);
3539 void DataArrayTemplateClassic<T>::reprNotTooLongWithoutNameStream(std::ostream& stream) const
3541 DataArray::reprWithoutNameStream(stream);
3542 ImplReprTraits<T>::SetPrecision(stream);
3543 this->_mem.reprNotTooLong(ToIdType(this->getNumberOfComponents()),stream);
3547 * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
3548 * printed out to avoid to consume too much space in interpretor.
3552 std::string DataArrayTemplateClassic<T>::reprNotTooLong() const
3554 std::ostringstream ret;
3555 reprNotTooLongStream(ret);
3560 * Returns a textual and human readable representation of \a this instance of
3561 * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
3562 * \return std::string - text describing \a this DataArrayInt.
3564 * \sa reprNotTooLong, reprZip
3567 std::string DataArrayTemplateClassic<T>::repr() const
3569 std::ostringstream ret;
3570 DataArrayTemplateClassic<T>::reprStream(ret);
3575 std::string DataArrayTemplateClassic<T>::reprZip() const
3577 std::ostringstream ret;
3578 DataArrayTemplateClassic<T>::reprZipStream(ret);
3582 /////////////////////////////////
3585 * Checks if all values in \a this array are equal to \a val at precision \a eps.
3586 * \param [in] val - value to check equality of array values to.
3587 * \param [in] eps - precision to check the equality.
3588 * \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
3590 * \throw If \a this->getNumberOfComponents() != 1
3591 * \throw If \a this is not allocated.
3594 bool DataArrayTemplateFP<T>::isUniform(T val, T eps) const
3596 this->checkAllocated();
3597 if(this->getNumberOfComponents()!=1)
3598 throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3599 const T *w(this->begin()),*end2(this->end());
3600 const T vmin(val-eps),vmax(val+eps);
3602 if(*w<vmin || *w>vmax)
3607 /////////////////////////////////
3610 * Returns the only one value in \a this, if and only if number of elements
3611 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3612 * \return double - the sole value stored in \a this array.
3613 * \throw If at least one of conditions stated above is not fulfilled.
3616 T DataArrayDiscrete<T>::intValue() const
3618 if(this->isAllocated())
3620 if(this->getNbOfElems()==1)
3622 return *this->getConstPointer();
3625 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3628 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3632 * Equivalent to DataArrayInt::isEqual except that if false the reason of
3633 * mismatch is given.
3635 * \param [in] other the instance to be compared with \a this
3636 * \param [out] reason In case of inequality returns the reason.
3637 * \sa DataArrayInt::isEqual
3640 bool DataArrayDiscrete<T>::isEqualIfNotWhy(const DataArrayDiscrete<T>& other, std::string& reason) const
3642 if(!this->areInfoEqualsIfNotWhy(other,reason))
3644 return this->_mem.isEqual(other._mem,0,reason);
3648 * Checks if \a this and another DataArrayInt are fully equal. For more info see
3649 * \ref MEDCouplingArrayBasicsCompare.
3650 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
3651 * \return bool - \a true if the two arrays are equal, \a false else.
3654 bool DataArrayDiscrete<T>::isEqual(const DataArrayDiscrete<T>& other) const
3657 return isEqualIfNotWhy(other,tmp);
3661 * Returns a new instance of DataArrayInt. The caller is to delete this array
3662 * using decrRef() as it is no more needed.
3665 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::New()
3667 return new typename Traits<T>::ArrayType;
3671 * Checks if values of \a this and another DataArrayInt are equal. For more info see
3672 * \ref MEDCouplingArrayBasicsCompare.
3673 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
3674 * \return bool - \a true if the values of two arrays are equal, \a false else.
3677 bool DataArrayDiscrete<T>::isEqualWithoutConsideringStr(const DataArrayDiscrete<T>& other) const
3680 return this->_mem.isEqual(other._mem,0,tmp);
3684 * Checks if values of \a this and another DataArrayInt are equal. Comparison is
3685 * performed on sorted value sequences.
3686 * For more info see\ref MEDCouplingArrayBasicsCompare.
3687 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
3688 * \return bool - \a true if the sorted values of two arrays are equal, \a false else.
3691 bool DataArrayDiscrete<T>::isEqualWithoutConsideringStrAndOrder(const typename Traits<T>::ArrayType& other) const
3693 MCAuto<typename Traits<T>::ArrayType> a((static_cast<const typename Traits<T>::ArrayType *>(this))->deepCopy());
3694 MCAuto<typename Traits<T>::ArrayType> b((static_cast<const typename Traits<T>::ArrayType *>(&other))->deepCopy());
3697 return a->isEqualWithoutConsideringStr(*b);
3702 void DataArrayDiscrete<T>::switchOnTupleAlg(T val, std::vector<bool>& vec, ALG algo) const
3704 this->checkAllocated();
3705 if(this->getNumberOfComponents()!=1)
3706 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
3707 mcIdType nbOfTuples(this->getNumberOfTuples());
3708 if(nbOfTuples!=ToIdType(vec.size()))
3709 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
3710 const T *pt(this->begin());
3711 for(mcIdType i=0;i<nbOfTuples;i++)
3717 * 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
3718 * put True to the corresponding entry in \a vec.
3719 * \a vec is expected to be with the same size than the number of tuples of \a this.
3721 * \sa DataArrayInt::switchOnTupleNotEqualTo.
3724 void DataArrayDiscrete<T>::switchOnTupleEqualTo(T val, std::vector<bool>& vec) const
3726 switchOnTupleAlg(val,vec,std::equal_to<T>());
3730 * 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
3731 * put True to the corresponding entry in \a vec.
3732 * \a vec is expected to be with the same size than the number of tuples of \a this.
3734 * \sa DataArrayInt::switchOnTupleEqualTo.
3737 void DataArrayDiscrete<T>::switchOnTupleNotEqualTo(T val, std::vector<bool>& vec) const
3739 switchOnTupleAlg(val,vec,std::not_equal_to<T>());
3743 * 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
3744 * appearing several times. If each element in \a this appears once an 1 component array containing only 0 will be returned.
3747 * - \a this : [5, 3, 2, 1, 4, 5, 2, 1, 0, 11, 5, 4]
3748 * - \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.
3750 * \return DataArrayInt * - a new instance of DataArrayInt with same number of tuples than \a this. The caller is to delete this
3751 * array using decrRef() as it is no more needed.
3752 * \throw If either this not allocated or not with one component.
3754 * \sa DataArrayInt::FindPermutationFromFirstToSecond
3757 DataArrayIdType *DataArrayDiscrete<T>::occurenceRankInThis() const
3759 constexpr char MSG0[] = "occurenceRankInThis :";
3760 this->checkAllocated();
3761 this->checkNbOfComps(1,MSG0);
3762 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
3763 ret->alloc(this->getNumberOfTuples(),1);
3764 mcIdType *retPtr(ret->getPointer());
3765 std::map<T,mcIdType> m;
3766 for(const T *pt = this->begin() ; pt != this->end() ; ++pt, ++retPtr )
3768 auto it = m.find(*pt);
3776 *retPtr = (*it).second++;
3783 * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
3784 * one-dimensional arrays that must be of the same length. The result array describes
3785 * correspondence between \a this and \a other arrays, so that
3786 * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
3787 * not possible because some element in \a other is not in \a this, an exception is thrown.
3788 * \param [in] other - an array to compute permutation to.
3789 * \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
3790 * from \a this to \a other. The caller is to delete this array using decrRef() as it is
3792 * \throw If \a this->getNumberOfComponents() != 1.
3793 * \throw If \a other->getNumberOfComponents() != 1.
3794 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
3795 * \throw If \a other includes a value which is not in \a this array.
3797 * \if ENABLE_EXAMPLES
3798 * \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
3800 * \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
3804 DataArrayIdType *DataArrayDiscrete<T>::buildPermutationArr(const DataArrayDiscrete<T>& other) const
3806 this->checkAllocated();
3807 if(this->getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
3808 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
3809 mcIdType nbTuple(this->getNumberOfTuples());
3810 other.checkAllocated();
3811 if(nbTuple!=other.getNumberOfTuples())
3812 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
3813 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
3814 ret->alloc(nbTuple,1);
3815 ret->fillWithValue(-1);
3816 const T *pt(this->begin());
3817 std::map<mcIdType,mcIdType> mm;
3818 for(mcIdType i=0;i<nbTuple;i++)
3819 mm[ToIdType(pt[i])]=i;
3821 mcIdType *retToFill(ret->getPointer());
3822 for(mcIdType i=0;i<nbTuple;i++)
3824 std::map<mcIdType,mcIdType>::const_iterator it=mm.find(ToIdType(pt[i]));
3827 std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
3828 throw INTERP_KERNEL::Exception(oss.str().c_str());
3830 retToFill[i]=(*it).second;
3836 * Elements of \a partOfThis are expected to be included in \a this.
3837 * The returned array \a ret is so that this[ret]==partOfThis
3839 * 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]
3840 * the return array will contain [3,2,5,7].
3842 * \a this is expected to be a 1 compo allocated array.
3843 * \param [in] partOfThis - A 1 compo allocated array
3844 * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis.
3845 * \throw if two same element is present twice in \a this
3846 * \throw if an element in \a partOfThis is \b NOT in \a this.
3849 DataArrayIdType *DataArrayDiscrete<T>::indicesOfSubPart(const DataArrayDiscrete<T>& partOfThis) const
3851 if(this->getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1)
3852 throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !");
3853 this->checkAllocated(); partOfThis.checkAllocated();
3854 mcIdType thisNbTuples(this->getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples());
3855 const T *thisPt(this->begin()),*pt(partOfThis.begin());
3856 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
3857 ret->alloc(nbTuples,1);
3858 mcIdType *retPt(ret->getPointer());
3859 std::map<mcIdType,mcIdType> m;
3860 for(mcIdType i=0;i<thisNbTuples;i++,thisPt++)
3861 m[ToIdType(*thisPt)]=i;
3862 if(ToIdType(m.size())!=thisNbTuples)
3863 throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : some elements appears more than once !");
3864 for(mcIdType i=0;i<nbTuples;i++,retPt++,pt++)
3866 std::map<mcIdType,mcIdType>::const_iterator it(m.find(ToIdType(*pt)));
3868 *retPt=(*it).second;
3871 std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !";
3872 throw INTERP_KERNEL::Exception(oss.str());
3879 * Checks that \a this array is consistently **increasing** or **decreasing** in value.
3880 * If not an exception is thrown.
3881 * \param [in] increasing - if \a true, the array values should be increasing.
3882 * \throw If sequence of values is not strictly monotonic in agreement with \a
3884 * \throw If \a this->getNumberOfComponents() != 1.
3885 * \throw If \a this is not allocated.
3888 void DataArrayDiscrete<T>::checkMonotonic(bool increasing) const
3890 if(!isMonotonic(increasing))
3893 throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
3895 throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
3900 * Checks that \a this array is consistently **increasing** or **decreasing** in value.
3901 * \param [in] increasing - if \a true, array values should be increasing.
3902 * \return bool - \a true if values change in accordance with \a increasing arg.
3903 * \throw If \a this->getNumberOfComponents() != 1.
3904 * \throw If \a this is not allocated.
3907 bool DataArrayDiscrete<T>::isMonotonic(bool increasing) const
3909 this->checkAllocated();
3910 if(this->getNumberOfComponents()!=1)
3911 throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
3912 std::size_t nbOfElements(this->getNumberOfTuples());
3913 const T *ptr(this->begin());
3919 for(std::size_t i=1;i<nbOfElements;i++)
3929 for(std::size_t i=1;i<nbOfElements;i++)
3941 * This method check that array consistently INCREASING or DECREASING in value.
3944 bool DataArrayDiscrete<T>::isStrictlyMonotonic(bool increasing) const
3946 this->checkAllocated();
3947 if(this->getNumberOfComponents()!=1)
3948 throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
3949 std::size_t nbOfElements(this->getNumberOfTuples());
3950 const T *ptr(this->begin());
3956 for(std::size_t i=1;i<nbOfElements;i++)
3966 for(std::size_t i=1;i<nbOfElements;i++)
3978 * This method check that array consistently INCREASING or DECREASING in value.
3981 void DataArrayDiscrete<T>::checkStrictlyMonotonic(bool increasing) const
3983 if(!isStrictlyMonotonic(increasing))
3986 throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
3988 throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
3993 * Returns an integer value characterizing \a this array, which is useful for a quick
3994 * comparison of many instances of DataArrayInt.
3995 * \return mcIdType - the hash value.
3996 * \throw If \a this is not allocated.
3999 mcIdType DataArrayDiscrete<T>::getHashCode() const
4001 this->checkAllocated();
4002 mcIdType nbOfElems=ToIdType(this->getNbOfElems());
4003 mcIdType ret=nbOfElems*65536;
4008 const T *pt(this->begin());
4009 for(mcIdType i=0;i<nbOfElems;i+=delta)
4010 ret0+=pt[i] & 0x1FFF;
4011 return ToIdType(ret+ret0);
4015 void DataArrayDiscrete<T>::reprCppStream(const std::string& varName, std::ostream& stream) const
4017 mcIdType nbTuples(this->getNumberOfTuples());
4018 std::size_t nbComp(this->getNumberOfComponents());
4019 const T *data(this->getConstPointer());
4020 stream << Traits<T>::ArrayTypeName << " *" << varName << "=" << Traits<T>::ArrayTypeName << "::New();" << std::endl;
4021 if(nbTuples*nbComp>=1)
4023 stream << "const mcIdType " << varName << "Data[" << nbTuples*nbComp << "]={";
4024 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<T>(stream,","));
4025 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
4026 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
4029 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
4030 stream << varName << "->setName(\"" << this->getName() << "\");" << std::endl;
4034 * Method that gives a quick overvien of \a this for python.
4037 void DataArrayDiscrete<T>::reprQuickOverview(std::ostream& stream) const
4039 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
4040 stream << Traits<T>::ArrayTypeName << " C++ instance at " << this << ". ";
4041 if(this->isAllocated())
4043 std::size_t nbOfCompo(this->getNumberOfComponents());
4046 mcIdType nbOfTuples(this->getNumberOfTuples());
4047 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
4048 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
4051 stream << "Number of components : 0.";
4054 stream << "*** No data allocated ****";
4058 void DataArrayDiscrete<T>::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
4060 const T *data(this->begin());
4061 mcIdType nbOfTuples(this->getNumberOfTuples());
4062 std::size_t nbOfCompo(this->getNumberOfComponents());
4063 std::ostringstream oss2; oss2 << "[";
4064 std::string oss2Str(oss2.str());
4065 bool isFinished=true;
4066 for(mcIdType i=0;i<nbOfTuples && isFinished;i++)
4071 for(std::size_t j=0;j<nbOfCompo;j++,data++)
4074 if(j!=nbOfCompo-1) oss2 << ", ";
4080 if(i!=nbOfTuples-1) oss2 << ", ";
4081 std::string oss3Str(oss2.str());
4082 if(oss3Str.length()<maxNbOfByteInRepr)
4094 void DataArrayDiscrete<T>::writeVTK(std::ostream& ofs, mcIdType indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
4096 static const char SPACE[4]={' ',' ',' ',' '};
4097 this->checkAllocated();
4098 std::string idt(indent,' ');
4099 ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << this->getNumberOfComponents() << "\"";
4102 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
4103 if(std::string(type)==Traits<T>::VTKReprStr)
4105 const char *data(reinterpret_cast<const char *>(this->begin()));
4106 std::size_t sz(this->getNbOfElems()*sizeof(T));
4107 byteArr->insertAtTheEnd(data,data+sz);
4108 byteArr->insertAtTheEnd(SPACE,SPACE+4);
4110 else if(std::string(type)=="Int8")
4112 INTERP_KERNEL::AutoPtr<char> tmp(new char[this->getNbOfElems()]);
4113 copyCast(this->begin(),this->end(),(char *)tmp);
4114 byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+this->getNbOfElems());
4115 byteArr->insertAtTheEnd(SPACE,SPACE+4);
4117 else if(std::string(type)=="UInt8")
4119 INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[this->getNbOfElems()]);
4120 copyCast(this->begin(),this->end(),(unsigned char *)tmp);
4121 byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+this->getNbOfElems());
4122 byteArr->insertAtTheEnd(SPACE,SPACE+4);
4126 std::ostringstream oss;
4127 oss << Traits<T>::ArrayTypeName << "::writeVTK : Only " << Traits<T>::VTKReprStr << ", Int8 and UInt8 supported !";
4128 throw INTERP_KERNEL::Exception(oss.str());
4133 ofs << " RangeMin=\"" << this->getMinValueInArray() << "\" RangeMax=\"" << this->getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
4134 std::copy(this->begin(),this->end(),std::ostream_iterator<T>(ofs," "));
4136 ofs << std::endl << idt << "</DataArray>\n";
4140 * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4141 * i.e. a current value is used as in index to get a new value from \a indArrBg.
4142 * \param [in] indArrBg - pointer to the first element of array of new values to assign
4144 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4145 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4146 * \throw If \a this->getNumberOfComponents() != 1
4147 * \throw If any value of \a this can't be used as a valid index for
4148 * [\a indArrBg, \a indArrEnd).
4150 * \sa changeValue, findIdForEach
4153 void DataArrayDiscrete<T>::transformWithIndArr(const T *indArrBg, const T *indArrEnd)
4155 this->checkAllocated();
4156 if(this->getNumberOfComponents()!=1)
4157 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4158 mcIdType nbElemsIn=ToIdType(std::distance(indArrBg,indArrEnd));
4159 mcIdType nbOfTuples(this->getNumberOfTuples());
4160 T *pt(this->getPointer());
4161 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
4163 if(*pt>=0 && *pt<nbElemsIn)
4167 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4168 throw INTERP_KERNEL::Exception(oss.str());
4171 this->declareAsNew();
4175 void DataArrayDiscrete<T>::transformWithIndArr(const MapKeyVal<T, T>& m)
4177 this->checkAllocated();
4178 if(this->getNumberOfComponents()!=1)
4179 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4180 const typename std::map<T,T>& dat(m.data());
4181 mcIdType nbOfTuples(this->getNumberOfTuples());
4182 T *pt(this->getPointer());
4183 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
4185 typename std::map<T,T>::const_iterator it(dat.find(*pt));
4190 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !";
4191 throw INTERP_KERNEL::Exception(oss.str());
4194 this->declareAsNew();
4198 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
4199 * given one. The ids are sorted in the ascending order.
4200 * \param [in] val - the value to find within \a this.
4201 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4202 * array using decrRef() as it is no more needed.
4203 * \throw If \a this is not allocated.
4204 * \throw If \a this->getNumberOfComponents() != 1.
4205 * \sa DataArrayInt::findIdsEqualTuple
4208 DataArrayIdType *DataArrayDiscrete<T>::findIdsEqual(T val) const
4210 this->checkAllocated();
4211 if(this->getNumberOfComponents()!=1)
4212 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
4213 const T *cptr(this->getConstPointer());
4214 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(0,1);
4215 mcIdType nbOfTuples(this->getNumberOfTuples());
4216 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
4218 ret->pushBackSilent(ToIdType(i));
4223 * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from
4224 * values of \a this (\a a) and the given (\a indArr) arrays as follows:
4225 * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
4226 * new value in place \a indArr[ \a v ] is i.
4227 * \param [in] indArrBg - the array holding indices within the result array to assign
4228 * indices of values of \a this array pointing to values of \a indArrBg.
4229 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4230 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4231 * \return DataArrayInt * - the new instance of DataArrayInt.
4232 * The caller is to delete this result array using decrRef() as it is no more
4234 * \throw If \a this->getNumberOfComponents() != 1.
4235 * \throw If any value of \a this array is not a valid index for \a indArrBg array.
4236 * \throw If any value of \a indArrBg is not a valid index for \a this array.
4239 DataArrayIdType *DataArrayDiscrete<T>::transformWithIndArrR(const T *indArrBg, const T *indArrEnd) const
4241 this->checkAllocated();
4242 if(this->getNumberOfComponents()!=1)
4243 throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4244 mcIdType nbElemsIn=ToIdType(std::distance(indArrBg,indArrEnd));
4245 mcIdType nbOfTuples(this->getNumberOfTuples());
4246 const T *pt=this->getConstPointer();
4247 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
4248 ret->alloc(nbOfTuples,1);
4249 ret->fillWithValue(-1);
4250 mcIdType *tmp=ret->getPointer();
4251 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
4253 if(*pt>=0 && *pt<nbElemsIn)
4255 T pos=indArrBg[*pt];
4256 if(pos>=0 && pos<nbOfTuples)
4257 tmp[ToIdType(pos)]=i;
4260 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
4261 throw INTERP_KERNEL::Exception(oss.str().c_str());
4266 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
4267 throw INTERP_KERNEL::Exception(oss.str().c_str());
4274 * Computes distribution of values of \a this one-dimensional array between given value
4275 * ranges (casts). This method is typically useful for entity number splitting by types,
4277 * \warning The values contained in \a arrBg should be sorted ascendently. No
4278 * check of this is be done. If not, the result is not warranted.
4279 * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
4280 * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
4281 * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
4282 * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
4283 * should be more than every value in \a this array.
4284 * \param [in] arrEnd - specifies the end of the array \a arrBg, so that
4285 * the last value of \a arrBg is \a arrEnd[ -1 ].
4286 * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
4287 * (same number of tuples and components), the caller is to delete
4288 * using decrRef() as it is no more needed.
4289 * This array contains indices of ranges for every value of \a this array. I.e.
4290 * the i-th value of \a castArr gives the index of range the i-th value of \a this
4291 * belongs to. Or, in other words, this parameter contains for each tuple in \a
4292 * this in which cast it holds.
4293 * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
4294 * array, the caller is to delete using decrRef() as it is no more needed.
4295 * This array contains ranks of values of \a this array within ranges
4296 * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
4297 * the i-th value of \a this array within the \a castArr[ i ]-th range, to which
4298 * the i-th value of \a this belongs to. Or, in other words, this param contains
4299 * for each tuple its rank inside its cast. The rank is computed as difference
4300 * between the value and the lowest value of range.
4301 * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
4302 * ranges (casts) to which at least one value of \a this array belongs.
4303 * Or, in other words, this param contains the casts that \a this contains.
4304 * The caller is to delete this array using decrRef() as it is no more needed.
4306 * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
4307 * the output of this method will be :
4308 * - \a castArr : [1,1,0,0,0,1,1,0,1]
4309 * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
4310 * - \a castsPresent : [0,1]
4312 * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
4313 * range #1 and its rank within this range is 2; etc.
4315 * \throw If \a this->getNumberOfComponents() != 1.
4316 * \throw If \a arrEnd - arrBg < 2.
4317 * \throw If any value of \a this is not less than \a arrEnd[-1].
4320 void DataArrayDiscrete<T>::splitByValueRange(const T *arrBg, const T *arrEnd,
4321 DataArrayType *& castArr, DataArrayType *& rankInsideCast, DataArrayType *& castsPresent) const
4323 this->checkAllocated();
4324 if(this->getNumberOfComponents()!=1)
4325 throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4326 mcIdType nbOfTuples=this->getNumberOfTuples();
4327 std::size_t nbOfCast=std::distance(arrBg,arrEnd);
4329 throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
4331 const T *work=this->getConstPointer();
4332 typedef std::reverse_iterator<const T *> rintstart;
4333 rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
4334 rintstart end2(arrBg);
4335 MCAuto<DataArrayType> ret1=DataArrayType::New();
4336 MCAuto<DataArrayType> ret2=DataArrayType::New();
4337 MCAuto<DataArrayType> ret3=DataArrayType::New();
4338 ret1->alloc(nbOfTuples,1);
4339 ret2->alloc(nbOfTuples,1);
4340 T *ret1Ptr=ret1->getPointer();
4341 T *ret2Ptr=ret2->getPointer();
4342 std::set<T> castsDetected;
4343 for(mcIdType i=0;i<nbOfTuples;i++)
4345 rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<T>(), work[i]));
4346 std::size_t pos=std::distance(bg,res);
4347 std::size_t pos2=nbOfCast-pos;
4350 ret1Ptr[i]=static_cast<T>(pos2);
4351 ret2Ptr[i]=work[i]-arrBg[pos2];
4352 castsDetected.insert(ret1Ptr[i]);
4356 std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
4357 throw INTERP_KERNEL::Exception(oss.str().c_str());
4360 ret3->alloc(castsDetected.size(),1);
4361 std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
4362 castArr=ret1.retn();
4363 rankInsideCast=ret2.retn();
4364 castsPresent=ret3.retn();
4368 * 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 ).
4369 * 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 ).
4370 * This method works only if \a this is allocated and single component. If not an exception will be thrown.
4372 * \param [out] strt - the start of the range (included) if true is returned.
4373 * \param [out] sttoopp - the end of the range (not included) if true is returned.
4374 * \param [out] stteepp - the step of the range if true is returned.
4375 * \return the verdict of the check.
4377 * \sa DataArray::GetNumberOfItemGivenBES
4380 bool DataArrayDiscrete<T>::isRange(T& strt, T& sttoopp, T& stteepp) const
4382 this->checkAllocated();
4383 if(this->getNumberOfComponents()!=1)
4384 throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
4385 mcIdType nbTuples(this->getNumberOfTuples());
4387 { strt=0; sttoopp=0; stteepp=1; return true; }
4388 const T *pt(this->begin());
4391 { sttoopp=strt+1; stteepp=1; return true; }
4392 strt=*pt; sttoopp=pt[nbTuples-1];
4398 T a(sttoopp-1-strt),tmp(strt);
4399 if(a%(nbTuples-1)!=0)
4401 stteepp=a/(FromIdType<T>(nbTuples)-1);
4402 for(mcIdType i=0;i<nbTuples;i++,tmp+=stteepp)
4410 T a(strt-sttoopp-1),tmp(strt);
4411 if(a%(nbTuples-1)!=0)
4413 stteepp=-(a/(FromIdType<T>(nbTuples)-1));
4414 for(mcIdType i=0;i<nbTuples;i++,tmp+=stteepp)
4422 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4423 * from values of \a this array, which is supposed to contain a renumbering map in
4424 * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
4425 * To know how to use the renumbering maps see \ref numbering.
4426 * \param [in] newNbOfElem - the number of tuples in the result array.
4427 * \return DataArrayInt * - the new instance of DataArrayInt.
4428 * The caller is to delete this result array using decrRef() as it is no more
4431 * \if ENABLE_EXAMPLES
4432 * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
4433 * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
4437 DataArrayIdType * DataArrayDiscrete<T>::invertArrayO2N2N2O(mcIdType newNbOfElem) const
4439 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
4440 ret->alloc(newNbOfElem,1);
4441 mcIdType nbOfOldNodes(this->getNumberOfTuples());
4442 const T *old2New(this->begin());
4443 mcIdType *pt(ret->getPointer());
4444 for(mcIdType i=0;i!=nbOfOldNodes;i++)
4449 if(newp>=0 && newp<newNbOfElem)
4453 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4454 throw INTERP_KERNEL::Exception(oss.str().c_str());
4462 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4463 * from values of \a this array, which is supposed to contain a renumbering map in
4464 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4465 * To know how to use the renumbering maps see \ref numbering.
4466 * \param [in] newNbOfElem - the number of tuples in the result array.
4467 * \return DataArrayInt * - the new instance of DataArrayInt.
4468 * The caller is to delete this result array using decrRef() as it is no more
4471 * \if ENABLE_EXAMPLES
4472 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4474 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4475 * \sa invertArrayN2O2O2NOptimized
4479 DataArrayIdType *DataArrayDiscrete<T>::invertArrayN2O2O2N(mcIdType oldNbOfElem) const
4481 this->checkAllocated();
4482 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
4483 ret->alloc(oldNbOfElem,1);
4484 const T *new2Old=this->getConstPointer();
4485 mcIdType *pt=ret->getPointer();
4486 std::fill(pt,pt+oldNbOfElem,-1);
4487 mcIdType nbOfNewElems(this->getNumberOfTuples());
4488 for(mcIdType i=0;i<nbOfNewElems;i++)
4491 if(v>=0 && v<oldNbOfElem)
4495 std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
4496 throw INTERP_KERNEL::Exception(oss.str().c_str());
4503 * This method is similar to DataArrayInt::invertArrayO2N2N2O except that
4504 * 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]
4507 DataArrayIdType *DataArrayDiscrete<T>::invertArrayO2N2N2OBis(mcIdType newNbOfElem) const
4509 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
4510 ret->alloc(newNbOfElem,1);
4511 mcIdType nbOfOldNodes(this->getNumberOfTuples());
4512 const T *old2New=this->getConstPointer();
4513 mcIdType *pt=ret->getPointer();
4514 for(mcIdType i=nbOfOldNodes-1;i>=0;i--)
4519 if(newp>=0 && newp<newNbOfElem)
4523 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4524 throw INTERP_KERNEL::Exception(oss.str().c_str());
4532 * Creates a map, whose contents are computed
4533 * from values of \a this array, which is supposed to contain a renumbering map in
4534 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4535 * To know how to use the renumbering maps see \ref numbering.
4536 * \param [in] newNbOfElem - the number of tuples in the result array.
4537 * \return MapII - the new instance of Map.
4539 * \if ENABLE_EXAMPLES
4540 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4542 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4543 * \sa invertArrayN2O2O2N, giveN2OOptimized, MEDCouplingPointSet::renumberNodesInConn
4547 MCAuto< MapKeyVal<T, mcIdType> > DataArrayDiscrete<T>::invertArrayN2O2O2NOptimized() const
4549 this->checkAllocated();
4550 if(this->getNumberOfComponents()!=1)
4551 throw INTERP_KERNEL::Exception("DataArrayInt::invertArrayN2O2O2NOptimized : single component expected !");
4552 MCAuto< MapKeyVal<T, mcIdType> > ret(MapKeyVal<T, mcIdType>::New());
4553 std::map<T, mcIdType>& m(ret->data());
4554 const T *new2Old(this->begin());
4555 mcIdType nbOfNewElems(this->getNumberOfTuples());
4556 for(mcIdType i=0;i<nbOfNewElems;i++)
4565 * Creates a map, whose contents are computed
4566 * from values of \a this array, which is supposed to contain a renumbering map in
4567 * "New to Old" mode. The result array contains a renumbering map in "New to Old" mode as C++ map for performance reasons.
4569 * \sa invertArrayN2O2O2NOptimized, MEDCouplingPointSet::renumberNodesInConn
4572 MCAuto< MapKeyVal<mcIdType, T> > DataArrayDiscrete<T>::giveN2OOptimized() const
4574 this->checkAllocated();
4575 if(this->getNumberOfComponents()!=1)
4576 throw INTERP_KERNEL::Exception("DataArrayInt::giveN2OOptimized : single component expected !");
4577 MCAuto< MapKeyVal<mcIdType, T> > ret(MapKeyVal<mcIdType, T>::New());
4578 std::map<mcIdType,T>& m(ret->data());
4579 const T *new2Old(this->begin());
4580 mcIdType nbOfNewElems(this->getNumberOfTuples());
4581 for(mcIdType i=0;i<nbOfNewElems;i++)
4590 * This method finds for each element \a ELT in [valsBg,valsEnd) elements in \a this equal to it. Associated to ELT
4591 * this method will return the tuple id of last element found. If there is no element in \a this equal to ELT
4592 * an exception will be thrown.
4594 * In case of success this[ret]==vals. Samely ret->transformWithIndArr(this->begin(),this->end())==vals.
4595 * Where \a vals is the [valsBg,valsEnd) array and \a ret the array returned by this method.
4596 * This method can be seen as an extension of FindPermutationFromFirstToSecond.
4599 * - \a this: [17,27,2,10,-4,3,12,27,16]
4600 * - \a val : [3,16,-4,27,17]
4601 * - result: [5,8,4,7,0]
4603 * \return - An array of size std::distance(valsBg,valsEnd)
4605 * \sa DataArrayInt::FindPermutationFromFirstToSecond , DataArrayInt::FindPermutationFromFirstToSecondDuplicate
4608 MCAuto<DataArrayIdType> DataArrayDiscrete<T>::findIdForEach(const T *valsBg, const T *valsEnd) const
4610 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
4611 std::size_t nbOfTuplesOut(std::distance(valsBg,valsEnd));
4612 ret->alloc(nbOfTuplesOut,1);
4613 MCAuto< MapKeyVal<T, mcIdType> > zeMap(this->invertArrayN2O2O2NOptimized());
4614 const std::map<T, mcIdType>& dat(zeMap->data());
4615 mcIdType *ptToFeed(ret->getPointer());
4616 for(const T *pt=valsBg;pt!=valsEnd;pt++)
4618 typename std::map<T,mcIdType>::const_iterator it(dat.find(*pt));
4620 *ptToFeed++=(*it).second;
4623 std::ostringstream oss; oss << "DataArrayInt::findIdForEach : error for element at place " << std::distance(valsBg,pt);
4624 oss << " of input array value is " << *pt << " which is not in this !";
4625 throw INTERP_KERNEL::Exception(oss.str());
4632 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4633 * This map, if applied to \a this array, would make it sorted. For example, if
4634 * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4635 * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4636 * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4637 * This method is useful for renumbering (in MED file for example). For more info
4638 * on renumbering see \ref numbering.
4639 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4640 * array using decrRef() as it is no more needed.
4641 * \throw If \a this is not allocated.
4642 * \throw If \a this->getNumberOfComponents() != 1.
4643 * \throw If there are equal values in \a this array.
4646 DataArrayIdType *DataArrayDiscrete<T>::checkAndPreparePermutation() const
4648 this->checkAllocated();
4649 if(this->getNumberOfComponents()!=1)
4650 throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4651 mcIdType nbTuples(this->getNumberOfTuples());
4652 const T *pt=this->getConstPointer();
4653 mcIdType *pt2=this->CheckAndPreparePermutation(pt,pt+nbTuples);
4654 DataArrayIdType *ret=DataArrayIdType::New();
4655 ret->useArray(pt2,true,DeallocType::C_DEALLOC,nbTuples,1);
4660 * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4661 * onto a set of values of size \a targetNb (\a B). The surjective function is
4662 * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4663 * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4664 * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4665 * The first of out arrays returns indices of elements of \a this array, grouped by their
4666 * place in the set \a B. The second out array is the index of the first one; it shows how
4667 * many elements of \a A are mapped into each element of \a B. <br>
4669 * mapping and its usage in renumbering see \ref numbering. <br>
4671 * - \a this: [0,3,2,3,2,2,1,2]
4673 * - \a arr: [0, 6, 2,4,5,7, 1,3]
4674 * - \a arrI: [0,1,2,6,8]
4676 * This result means: <br>
4677 * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4678 * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4679 * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4680 * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] :
4681 * \a arrI[ 2+1 ]]); <br> etc.
4682 * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4683 * than the maximal value of \a A.
4684 * \param [out] arr - a new instance of DataArrayInt returning indices of
4685 * elements of \a this, grouped by their place in the set \a B. The caller is to delete
4686 * this array using decrRef() as it is no more needed.
4687 * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4688 * elements of \a this. The caller is to delete this array using decrRef() as it
4689 * is no more needed.
4690 * \throw If \a this is not allocated.
4691 * \throw If \a this->getNumberOfComponents() != 1.
4692 * \throw If any value in \a this is more or equal to \a targetNb.
4695 void DataArrayDiscrete<T>::changeSurjectiveFormat(T targetNb, DataArrayIdType *&arr, DataArrayIdType *&arrI) const
4697 this->checkAllocated();
4698 if(this->getNumberOfComponents()!=1)
4699 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4700 mcIdType nbOfTuples(this->getNumberOfTuples());
4701 const T *input=this->getConstPointer();
4702 std::vector< std::vector<mcIdType> > tmp(targetNb);
4703 for(mcIdType i=0;i<nbOfTuples;i++)
4706 if(tmp2>=0 && tmp2<targetNb)
4707 tmp[tmp2].push_back(i);
4710 std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4711 throw INTERP_KERNEL::Exception(oss.str().c_str());
4715 MCAuto<DataArrayIdType> retI(DataArrayIdType::New());
4716 retI->alloc(targetNb+1,1);
4717 mcIdType *retIPtr=retI->getPointer();
4719 for(std::vector< std::vector<mcIdType> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4720 retIPtr[1]=retIPtr[0]+ToIdType((*it1).size());
4721 if(nbOfTuples!=retI->getIJ(ToIdType(targetNb),0))
4722 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4723 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
4724 ret->alloc(nbOfTuples,1);
4725 mcIdType *retPtr=ret->getPointer();
4726 for(std::vector< std::vector<mcIdType> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4727 retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4733 * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4734 * which if applied to \a this array would make it sorted ascendingly.
4735 * For more info on renumbering see \ref numbering. <br>
4737 * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4738 * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4739 * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2]
4741 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4742 * array using decrRef() as it is no more needed.
4743 * \throw If \a this is not allocated.
4744 * \throw If \a this->getNumberOfComponents() != 1.
4747 DataArrayIdType *DataArrayDiscrete<T>::buildPermArrPerLevel() const
4749 this->checkAllocated();
4750 if(this->getNumberOfComponents()!=1)
4751 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4752 mcIdType nbOfTuples=this->getNumberOfTuples();
4753 const T *pt=this->getConstPointer();
4754 std::map<T,mcIdType> m;
4755 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
4756 ret->alloc(nbOfTuples,1);
4757 mcIdType *opt=ret->getPointer();
4758 for(mcIdType i=0;i<nbOfTuples;i++,pt++,opt++)
4761 typename std::map<T,mcIdType>::iterator it=m.find(val);
4770 m.insert(std::pair<T,mcIdType>(val,1));
4774 for(typename std::map<T,mcIdType>::iterator it=m.begin();it!=m.end();it++)
4776 mcIdType vt=(*it).second;
4780 pt=this->getConstPointer();
4781 opt=ret->getPointer();
4782 for(mcIdType i=0;i<nbOfTuples;i++,pt++,opt++)
4789 * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4790 * iota(). This method is particularly useful for DataArrayInt instances that represent
4791 * a renumbering array, to check if there is a real need in renumbering.
4792 * This method checks than \a this can be considered as an identity mapping
4793 * of a set having \a sizeExpected elements into itself.
4795 * \param [in] sizeExpected - The number of elements expected.
4796 * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4797 * \throw If \a this is not allocated.
4798 * \throw If \a this->getNumberOfComponents() != 1.
4801 bool DataArrayDiscrete<T>::isIota(mcIdType sizeExpected) const
4803 this->checkAllocated();
4804 if(this->getNumberOfComponents()!=1)
4806 mcIdType nbOfTuples(this->getNumberOfTuples());
4807 if(nbOfTuples!=sizeExpected)
4809 const T *pt=this->getConstPointer();
4810 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
4817 * Checks if all values in \a this array are equal to \a val.
4818 * \param [in] val - value to check equality of array values to.
4819 * \return bool - \a true if all values are \a val.
4820 * \throw If \a this is not allocated.
4821 * \throw If \a this->getNumberOfComponents() != 1
4822 * \sa DataArrayInt::checkUniformAndGuess
4825 bool DataArrayDiscrete<T>::isUniform(T val) const
4827 this->checkAllocated();
4828 if(this->getNumberOfComponents()!=1)
4829 throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4830 const T *w(this->begin()),*end2(this->end());
4838 * This method checks that \a this is uniform. If not and exception will be thrown.
4839 * In case of uniformity the corresponding value is returned.
4841 * \return mcIdType - the unique value contained in this
4842 * \throw If \a this is not allocated.
4843 * \throw If \a this->getNumberOfComponents() != 1
4844 * \throw If \a this is not uniform.
4845 * \sa DataArrayInt::isUniform
4848 T DataArrayDiscrete<T>::checkUniformAndGuess() const
4850 this->checkAllocated();
4851 if(this->getNumberOfComponents()!=1)
4852 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4854 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
4855 const T *w(this->begin()),*end2(this->end());
4859 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
4864 * Checks if all values in \a this array are unique.
4865 * \return bool - \a true if condition above is true
4866 * \throw If \a this is not allocated.
4867 * \throw If \a this->getNumberOfComponents() != 1
4870 bool DataArrayDiscrete<T>::hasUniqueValues() const
4872 this->checkAllocated();
4873 if(this->getNumberOfComponents()!=1)
4874 throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4875 std::size_t nbOfElements(this->getNumberOfTuples());
4876 std::set<T> s(this->begin(),this->end()); // in C++11, should use unordered_set (O(1) complexity)
4877 if (s.size() != nbOfElements)
4883 * Copy all components in a specified order from another DataArrayInt.
4884 * The specified components become the first ones in \a this array.
4885 * Both numerical and textual data is copied. The number of tuples in \a this and
4886 * the other array can be different.
4887 * \param [in] a - the array to copy data from.
4888 * \param [in] compoIds - sequence of zero based indices of components, data of which is
4890 * \throw If \a a is NULL.
4891 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
4892 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
4894 * \if ENABLE_EXAMPLES
4895 * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
4899 void DataArrayDiscrete<T>::setSelectedComponents(const DataArrayType *a, const std::vector<std::size_t>& compoIds)
4902 throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
4903 this->checkAllocated();
4904 a->checkAllocated();
4905 this->copyPartOfStringInfoFrom2(compoIds,*a);
4906 std::size_t partOfCompoSz=compoIds.size();
4907 std::size_t nbOfCompo = this->getNumberOfComponents();
4908 mcIdType nbOfTuples=std::min(this->getNumberOfTuples(),a->getNumberOfTuples());
4909 const T *ac=a->getConstPointer();
4910 T *nc=this->getPointer();
4911 for(mcIdType i=0;i<nbOfTuples;i++)
4912 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
4913 nc[nbOfCompo*i+compoIds[j]]=*ac;
4917 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
4918 * equal to a given one.
4919 * \param [in] val - the value to ignore within \a this.
4920 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4921 * array using decrRef() as it is no more needed.
4922 * \throw If \a this is not allocated.
4923 * \throw If \a this->getNumberOfComponents() != 1.
4926 DataArrayIdType *DataArrayDiscrete<T>::findIdsNotEqual(T val) const
4928 this->checkAllocated();
4929 if(this->getNumberOfComponents()!=1)
4930 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
4931 const T *cptr(this->getConstPointer());
4932 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
4934 mcIdType nbOfTuples(this->getNumberOfTuples());
4935 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
4937 ret->pushBackSilent(i);
4942 * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
4943 * This method is an extension of DataArrayInt::findIdsEqual method.
4945 * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
4946 * \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
4947 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4948 * array using decrRef() as it is no more needed.
4949 * \throw If \a this is not allocated.
4950 * \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
4951 * \throw If \a this->getNumberOfComponents() is equal to 0.
4952 * \sa DataArrayInt::findIdsEqual
4955 DataArrayIdType *DataArrayDiscrete<T>::findIdsEqualTuple(const T *tupleBg, const T *tupleEnd) const
4957 std::size_t nbOfCompoExp=std::distance(tupleBg,tupleEnd);
4958 this->checkAllocated();
4959 if(this->getNumberOfComponents()!=nbOfCompoExp)
4961 std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << this->getNumberOfComponents() << " components !";
4962 throw INTERP_KERNEL::Exception(oss.str().c_str());
4965 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
4966 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
4968 const T *bg(this->begin()),*end2(this->end()),*work(this->begin());
4971 work=std::search(work,end2,tupleBg,tupleEnd);
4974 std::ptrdiff_t pos=std::distance(bg,work);
4975 if(pos%nbOfCompoExp==0)
4976 ret->pushBackSilent(ToIdType(pos/nbOfCompoExp));
4984 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
4985 * one of given values.
4986 * \param [in] valsBg - an array of values to find within \a this array.
4987 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4988 * the last value of \a valsBg is \a valsEnd[ -1 ].
4989 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4990 * array using decrRef() as it is no more needed.
4991 * \throw If \a this->getNumberOfComponents() != 1.
4994 DataArrayIdType *DataArrayDiscrete<T>::findIdsEqualList(const T *valsBg, const T *valsEnd) const
4996 if(this->getNumberOfComponents()!=1)
4997 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
4998 std::set<T> vals2(valsBg,valsEnd);
4999 const T *cptr(this->getConstPointer());
5000 mcIdType nbOfTuples(this->getNumberOfTuples());
5001 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(0,1);
5002 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
5003 if(vals2.find(*cptr)!=vals2.end())
5004 ret->pushBackSilent(i);
5009 * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
5010 * equal to any of given values.
5011 * \param [in] valsBg - an array of values to ignore within \a this array.
5012 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5013 * the last value of \a valsBg is \a valsEnd[ -1 ].
5014 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5015 * array using decrRef() as it is no more needed.
5016 * \throw If \a this->getNumberOfComponents() != 1.
5019 DataArrayIdType *DataArrayDiscrete<T>::findIdsNotEqualList(const T *valsBg, const T *valsEnd) const
5021 if(this->getNumberOfComponents()!=1)
5022 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
5023 std::set<T> vals2(valsBg,valsEnd);
5024 const T *cptr=this->getConstPointer();
5025 mcIdType nbOfTuples(this->getNumberOfTuples());
5026 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(0,1);
5027 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
5028 if(vals2.find(*cptr)==vals2.end())
5029 ret->pushBackSilent(i);
5034 * This method expects to be called when number of components of this is equal to one.
5035 * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
5036 * If not any tuple contains \b value -1 is returned.
5037 * \sa DataArrayInt::presenceOfValue
5040 mcIdType DataArrayDiscrete<T>::findIdFirstEqual(T value) const
5042 this->checkAllocated();
5043 if(this->getNumberOfComponents()!=1)
5044 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
5045 const T *cptr=this->getConstPointer();
5046 mcIdType nbOfTuples(this->getNumberOfTuples());
5047 const T *ret=std::find(cptr,cptr+nbOfTuples,value);
5048 if(ret!=cptr+nbOfTuples)
5049 return ToIdType(std::distance(cptr,ret));
5054 * This method expects to be called when number of components of this is equal to one.
5055 * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
5056 * If not any tuple contains one of the values contained in 'vals' -1 is returned.
5057 * \sa DataArrayInt::presenceOfValue
5060 mcIdType DataArrayDiscrete<T>::findIdFirstEqual(const std::vector<T>& vals) const
5062 this->checkAllocated();
5063 if(this->getNumberOfComponents()!=1)
5064 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
5065 std::set<T> vals2(vals.begin(),vals.end());
5066 const T *cptr=this->getConstPointer();
5067 mcIdType nbOfTuples(this->getNumberOfTuples());
5068 for(const T *w=cptr;w!=cptr+nbOfTuples;w++)
5069 if(vals2.find(*w)!=vals2.end())
5070 return ToIdType(std::distance(cptr,w));
5075 * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
5076 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5077 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5078 * If any the tuple id is returned. If not -1 is returned.
5080 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5081 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5083 * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
5084 * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
5087 mcIdType DataArrayDiscrete<T>::findIdFirstEqualTuple(const std::vector<T>& tupl) const
5089 this->checkAllocated();
5090 std::size_t nbOfCompo(this->getNumberOfComponents());
5092 throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
5093 if(nbOfCompo!=tupl.size())
5095 std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
5096 throw INTERP_KERNEL::Exception(oss.str().c_str());
5098 const T *cptr=this->getConstPointer();
5099 std::size_t nbOfVals=this->getNbOfElems();
5100 for(const T *work=cptr;work!=cptr+nbOfVals;)
5102 work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
5103 if(work!=cptr+nbOfVals)
5105 if(std::distance(cptr,work)%nbOfCompo!=0)
5108 return ToIdType (std::distance(cptr,work)/nbOfCompo);
5115 * This method searches the sequence specified in input parameter \b vals in \b this.
5116 * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
5117 * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
5118 * \sa DataArrayInt::findIdFirstEqualTuple
5121 mcIdType DataArrayDiscrete<T>::findIdSequence(const std::vector<T>& vals) const
5123 this->checkAllocated();
5124 std::size_t nbOfCompo=this->getNumberOfComponents();
5126 throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
5127 const T *cptr=this->getConstPointer();
5128 std::size_t nbOfVals=this->getNbOfElems();
5129 const T *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
5130 if(loc!=cptr+nbOfVals)
5131 return ToIdType(std::distance(cptr,loc));
5136 * Assigns \a newValue to all elements holding \a oldValue within \a this
5137 * one-dimensional array.
5138 * \param [in] oldValue - the value to replace.
5139 * \param [in] newValue - the value to assign.
5140 * \return mcIdType - number of replacements performed.
5141 * \throw If \a this is not allocated.
5142 * \throw If \a this->getNumberOfComponents() != 1.
5145 mcIdType DataArrayDiscrete<T>::changeValue(T oldValue, T newValue)
5147 this->checkAllocated();
5148 if(this->getNumberOfComponents()!=1)
5149 throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
5150 if(oldValue==newValue)
5152 T *start(this->getPointer()),*end2(start+this->getNbOfElems());
5154 for(T *val=start;val!=end2;val++)
5163 this->declareAsNew();
5168 * This method returns the number of values in \a this that are equals to input parameter \a value.
5169 * This method only works for single component array.
5171 * \return a value in [ 0, \c this->getNumberOfTuples() )
5173 * \throw If \a this is not allocated
5177 mcIdType DataArrayDiscrete<T>::count(T value) const
5180 this->checkAllocated();
5181 if(this->getNumberOfComponents()!=1)
5182 throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5183 const T *vals=this->begin();
5184 std::size_t nbOfElements=this->getNumberOfTuples();
5185 for(std::size_t i=0;i<nbOfElements;i++,vals++)
5192 * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
5193 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5194 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5195 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5196 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5197 * \sa DataArrayInt::findIdFirstEqualTuple
5200 bool DataArrayDiscrete<T>::presenceOfTuple(const std::vector<T>& tupl) const
5202 return this->findIdFirstEqualTuple(tupl)!=-1;
5207 * Returns \a true if a given value is present within \a this one-dimensional array.
5208 * \param [in] value - the value to find within \a this array.
5209 * \return bool - \a true in case if \a value is present within \a this array.
5210 * \throw If \a this is not allocated.
5211 * \throw If \a this->getNumberOfComponents() != 1.
5212 * \sa findIdFirstEqual()
5215 bool DataArrayDiscrete<T>::presenceOfValue(T value) const
5217 return this->findIdFirstEqual(value)!=-1;
5221 * This method expects to be called when number of components of this is equal to one.
5222 * This method returns true if it exists a tuple so that the value is contained in \b vals.
5223 * If not any tuple contains one of the values contained in 'vals' false is returned.
5224 * \sa DataArrayInt::findIdFirstEqual
5227 bool DataArrayDiscrete<T>::presenceOfValue(const std::vector<T>& vals) const
5229 return this->findIdFirstEqual(vals)!=-1;
5233 * Accumulates values of each component of \a this array.
5234 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
5235 * by the caller, that is filled by this method with sum value for each
5237 * \throw If \a this is not allocated.
5240 void DataArrayDiscrete<T>::accumulate(T *res) const
5242 this->checkAllocated();
5243 const T *ptr=this->getConstPointer();
5244 mcIdType nbTuple(this->getNumberOfTuples());
5245 std::size_t nbComps(this->getNumberOfComponents());
5246 std::fill(res,res+nbComps,0);
5247 for(mcIdType i=0;i<nbTuple;i++)
5248 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<T>());
5252 T DataArrayDiscrete<T>::accumulate(std::size_t compId) const
5254 this->checkAllocated();
5255 const T *ptr=this->getConstPointer();
5256 mcIdType nbTuple(this->getNumberOfTuples());
5257 std::size_t nbComps(this->getNumberOfComponents());
5258 if(compId<0 || compId>=nbComps)
5259 throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
5261 for(mcIdType i=0;i<nbTuple;i++)
5262 ret+=ptr[i*nbComps+compId];
5267 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
5268 * The returned array will have same number of components than \a this and number of tuples equal to
5269 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
5271 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
5273 * \param [in] bgOfIndex - begin (included) of the input index array.
5274 * \param [in] endOfIndex - end (excluded) of the input index array.
5275 * \return DataArrayInt * - the new instance having the same number of components than \a this.
5277 * \throw If bgOfIndex or end is NULL.
5278 * \throw If input index array is not ascendingly sorted.
5279 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
5280 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
5283 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::accumulatePerChunck(const mcIdType *bgOfIndex, const mcIdType *endOfIndex) const
5285 if(!bgOfIndex || !endOfIndex)
5286 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
5287 this->checkAllocated();
5288 std::size_t nbCompo(this->getNumberOfComponents());
5289 mcIdType nbOfTuples(this->getNumberOfTuples());
5290 mcIdType sz=ToIdType(std::distance(bgOfIndex,endOfIndex));
5292 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
5294 MCAuto<DataArrayType> ret=DataArrayType::New(); ret->alloc(sz,nbCompo);
5295 const mcIdType *w=bgOfIndex;
5296 if(*w<0 || *w>=nbOfTuples)
5297 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
5298 const T *srcPt=this->begin()+(*w)*nbCompo;
5299 T *tmp=ret->getPointer();
5300 for(mcIdType i=0;i<sz;i++,tmp+=nbCompo,w++)
5302 std::fill(tmp,tmp+nbCompo,0);
5305 for(mcIdType j=w[0];j<w[1];j++,srcPt+=nbCompo)
5307 if(j>=0 && j<nbOfTuples)
5308 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<T>());
5311 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
5312 throw INTERP_KERNEL::Exception(oss.str().c_str());
5318 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
5319 throw INTERP_KERNEL::Exception(oss.str().c_str());
5322 ret->copyStringInfoFrom(*this);
5327 * Returns in a single walk in \a this the min value and the max value in \a this.
5328 * \a this is expected to be single component array.
5330 * \param [out] minValue - the min value in \a this.
5331 * \param [out] maxValue - the max value in \a this.
5333 * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5336 void DataArrayDiscrete<T>::getMinMaxValues(T& minValue, T& maxValue) const
5338 this->checkAllocated();
5339 if(this->getNumberOfComponents()!=1)
5340 throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5341 std::size_t nbElements(this->getNumberOfTuples());
5342 const T *pt(this->begin());
5343 minValue=std::numeric_limits<T>::max(); maxValue=-std::numeric_limits<T>::max();
5344 for(std::size_t i=0;i<nbElements;i++,pt++)
5354 * Modify all elements of \a this array, so that
5355 * an element _x_ becomes \f$ numerator / x \f$.
5356 * \warning If an exception is thrown because of presence of 0 element in \a this
5357 * array, all elements processed before detection of the zero element remain
5359 * \param [in] numerator - the numerator used to modify array elements.
5360 * \throw If \a this is not allocated.
5361 * \throw If there is an element equal to 0 in \a this array.
5364 void DataArrayDiscrete<T>::applyInv(T numerator)
5366 this->checkAllocated();
5367 T *ptr=this->getPointer();
5368 std::size_t nbOfElems=this->getNbOfElems();
5369 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5373 *ptr=numerator/(*ptr);
5377 std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/(this->getNumberOfComponents()) << " component #" << i%(this->getNumberOfComponents());
5379 throw INTERP_KERNEL::Exception(oss.str().c_str());
5382 this->declareAsNew();
5386 * Modify all elements of \a this array, so that
5387 * an element _x_ becomes \f$ x / val \f$.
5388 * \param [in] val - the denominator used to modify array elements.
5389 * \throw If \a this is not allocated.
5390 * \throw If \a val == 0.
5393 void DataArrayDiscrete<T>::applyDivideBy(T val)
5396 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5397 this->checkAllocated();
5398 T *ptr=this->getPointer();
5399 std::size_t nbOfElems=this->getNbOfElems();
5400 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<T>(),val));
5401 this->declareAsNew();
5405 * Modify all elements of \a this array, so that
5406 * an element _x_ becomes <em> x % val </em>.
5407 * \param [in] val - the divisor used to modify array elements.
5408 * \throw If \a this is not allocated.
5409 * \throw If \a val <= 0.
5412 void DataArrayDiscrete<T>::applyModulus(T val)
5415 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5416 this->checkAllocated();
5417 T *ptr=this->getPointer();
5418 std::size_t nbOfElems=this->getNbOfElems();
5419 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<T>(),val));
5420 this->declareAsNew();
5424 * Modify all elements of \a this array, so that
5425 * an element _x_ becomes <em> val % x </em>.
5426 * \warning If an exception is thrown because of presence of an element <= 0 in \a this
5427 * array, all elements processed before detection of the zero element remain
5429 * \param [in] val - the divident used to modify array elements.
5430 * \throw If \a this is not allocated.
5431 * \throw If there is an element equal to or less than 0 in \a this array.
5434 void DataArrayDiscrete<T>::applyRModulus(T val)
5436 this->checkAllocated();
5437 T *ptr=this->getPointer();
5438 std::size_t nbOfElems=this->getNbOfElems();
5439 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5447 std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/(this->getNumberOfComponents()) << " component #" << i%(this->getNumberOfComponents());
5449 throw INTERP_KERNEL::Exception(oss.str().c_str());
5452 this->declareAsNew();
5456 * Modify all elements of \a this array, so that
5457 * an element _x_ becomes <em> val ^ x </em>.
5458 * \param [in] val - the value used to apply pow on all array elements.
5459 * \throw If \a this is not allocated.
5460 * \throw If \a val < 0.
5463 void DataArrayDiscrete<T>::applyPow(T val)
5465 this->checkAllocated();
5467 throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5468 T *ptr=this->getPointer();
5469 std::size_t nbOfElems=this->getNbOfElems();
5472 std::fill(ptr,ptr+nbOfElems,1);
5475 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5478 for(T j=0;j<val;j++)
5482 this->declareAsNew();
5486 * Modify all elements of \a this array, so that
5487 * an element _x_ becomes \f$ val ^ x \f$.
5488 * \param [in] val - the value used to apply pow on all array elements.
5489 * \throw If \a this is not allocated.
5490 * \throw If there is an element < 0 in \a this array.
5491 * \warning If an exception is thrown because of presence of 0 element in \a this
5492 * array, all elements processed before detection of the zero element remain
5496 void DataArrayDiscrete<T>::applyRPow(T val)
5498 this->checkAllocated();
5499 T *ptr=this->getPointer();
5500 std::size_t nbOfElems=this->getNbOfElems();
5501 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5506 for(T j=0;j<*ptr;j++)
5512 std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/(this->getNumberOfComponents()) << " component #" << i%(this->getNumberOfComponents());
5514 throw INTERP_KERNEL::Exception(oss.str().c_str());
5517 this->declareAsNew();
5521 * This method works only on data array with one component.
5522 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5523 * this[*id] in [\b vmin,\b vmax)
5525 * \param [in] vmin begin of range. This value is included in range (included).
5526 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5527 * \return a newly allocated data array that the caller should deal with.
5529 * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5532 DataArrayIdType *DataArrayDiscrete<T>::findIdsInRange(T vmin, T vmax) const
5534 InRange<T> ir(vmin,vmax);
5535 MCAuto<DataArrayIdType> ret(this->findIdsAdv(ir));
5540 * This method works only on data array with one component.
5541 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5542 * this[*id] \b not in [\b vmin,\b vmax)
5544 * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5545 * \param [in] vmax end of range. This value is included in range (included).
5546 * \return a newly allocated data array that the caller should deal with.
5548 * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5551 DataArrayIdType *DataArrayDiscrete<T>::findIdsNotInRange(T vmin, T vmax) const
5553 NotInRange<T> nir(vmin,vmax);
5554 MCAuto<DataArrayIdType> ret(this->findIdsAdv(nir));
5559 * This method works only on data array with one component.
5560 * 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.
5562 * \param [in] vmin begin of range. This value is included in range (included).
5563 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5564 * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5566 bool DataArrayDiscrete<T>::checkAllIdsInRange(T vmin, T vmax) const
5568 this->checkAllocated();
5569 if(this->getNumberOfComponents()!=1)
5570 throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5571 mcIdType nbOfTuples(this->getNumberOfTuples());
5573 const T *cptr=this->getConstPointer();
5574 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
5576 if(*cptr>=vmin && *cptr<vmax)
5577 { ret=ret && *cptr==i; }
5580 std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5581 throw INTERP_KERNEL::Exception(oss.str().c_str());
5588 * Returns a new DataArrayInt which contains a complement of elements of \a this
5589 * one-dimensional array. I.e. the result array contains all elements from the range [0,
5590 * \a nbOfElement) not present in \a this array.
5591 * \param [in] nbOfElement - maximal size of the result array.
5592 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5593 * array using decrRef() as it is no more needed.
5594 * \throw If \a this is not allocated.
5595 * \throw If \a this->getNumberOfComponents() != 1.
5596 * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
5600 DataArrayIdType *DataArrayDiscrete<T>::buildComplement(mcIdType nbOfElement) const
5602 this->checkAllocated();
5603 if(this->getNumberOfComponents()!=1)
5604 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
5605 std::vector<bool> tmp(nbOfElement);
5606 const T *pt=this->getConstPointer();
5607 std::size_t nbOfElements=this->getNumberOfTuples();
5608 for(const T *w=pt;w!=pt+nbOfElements;w++)
5609 if(*w>=0 && *w<nbOfElement)
5612 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
5613 std::size_t nbOfRetVal=std::count(tmp.begin(),tmp.end(),false);
5614 DataArrayIdType *ret=DataArrayIdType::New();
5615 ret->alloc(nbOfRetVal,1);
5617 mcIdType *retPtr=ret->getPointer();
5618 for(mcIdType i=0;i<nbOfElement;i++)
5625 * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
5626 * from an \a other one-dimensional array.
5627 * \param [in] other - a DataArrayInt containing elements not to include in the result array.
5628 * \return DataArrayInt * - a new instance of DataArrayInt with one component. The
5629 * caller is to delete this array using decrRef() as it is no more needed.
5630 * \throw If \a other is NULL.
5631 * \throw If \a other is not allocated.
5632 * \throw If \a other->getNumberOfComponents() != 1.
5633 * \throw If \a this is not allocated.
5634 * \throw If \a this->getNumberOfComponents() != 1.
5635 * \sa DataArrayInt::buildSubstractionOptimized()
5638 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildSubstraction(const DataArrayType *other) const
5641 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
5642 this->checkAllocated();
5643 other->checkAllocated();
5644 if(this->getNumberOfComponents()!=1)
5645 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
5646 if(other->getNumberOfComponents()!=1)
5647 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
5648 const T *pt=this->getConstPointer();
5649 std::size_t nbOfElements=this->getNumberOfTuples();
5650 std::set<T> s1(pt,pt+nbOfElements);
5651 pt=other->getConstPointer();
5652 nbOfElements=other->getNumberOfTuples();
5653 std::set<T> s2(pt,pt+nbOfElements);
5655 std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<T> >(r));
5656 DataArrayType *ret=DataArrayType::New();
5657 ret->alloc(r.size(),1);
5658 std::copy(r.begin(),r.end(),ret->getPointer());
5663 * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
5664 * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
5666 * \param [in] other an array with one component and expected to be sorted ascendingly.
5667 * \ret list of ids in \a this but not in \a other.
5668 * \sa DataArrayInt::buildSubstraction
5671 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildSubstractionOptimized(const DataArrayType *other) const
5673 static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
5674 if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
5675 this->checkAllocated(); other->checkAllocated();
5676 if(this->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5677 if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5678 const T *pt1Bg(this->begin()),*pt1End(this->end()),*pt2Bg(other->begin()),*pt2End(other->end());
5679 const T *work1(pt1Bg),*work2(pt2Bg);
5680 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(0,1);
5681 for(;work1!=pt1End;work1++)
5683 if(work2!=pt2End && *work1==*work2)
5686 ret->pushBackSilent(*work1);
5692 * Returns a new DataArrayInt which contains all elements of \a this and a given
5693 * one-dimensional arrays. The result array does not contain any duplicates
5694 * and its values are sorted in ascending order.
5695 * \param [in] other - an array to unite with \a this one.
5696 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5697 * array using decrRef() as it is no more needed.
5698 * \throw If \a this or \a other is not allocated.
5699 * \throw If \a this->getNumberOfComponents() != 1.
5700 * \throw If \a other->getNumberOfComponents() != 1.
5703 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildUnion(const DataArrayType *other) const
5705 std::vector<const DataArrayType *>arrs(2);
5706 arrs[0]=dynamic_cast<const DataArrayType *>(this); arrs[1]=other;
5707 return DataArrayDiscrete<T>::BuildUnion(arrs);
5711 * Returns a new DataArrayInt which contains elements present in both \a this and a given
5712 * one-dimensional arrays. The result array does not contain any duplicates
5713 * and its values are sorted in ascending order.
5714 * \param [in] other - an array to intersect with \a this one.
5715 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5716 * array using decrRef() as it is no more needed.
5717 * \throw If \a this or \a other is not allocated.
5718 * \throw If \a this->getNumberOfComponents() != 1.
5719 * \throw If \a other->getNumberOfComponents() != 1.
5722 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildIntersection(const DataArrayType *other) const
5724 std::vector<const DataArrayType *>arrs(2);
5725 arrs[0]=dynamic_cast<const DataArrayType *>(this); arrs[1]=other;
5726 return DataArrayDiscrete<T>::BuildIntersection(arrs);
5729 * This method can be applied on allocated with one component DataArrayInt instance.
5730 * 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.
5731 * Number of tuples of returned array is equal to size of \a this->buildUnique() + 1.
5732 * Last value of returned array is equal to \a this->getNumberOfTuples()
5735 * - \a this : [0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 5, 11]
5736 * - \a return is : [0, 1, 3, 5, 6, 8, 11, 12]
5738 * \return a newly allocated array containing the indexed array format of groups by same consecutive value.
5739 * \throw if \a this is not allocated or if \a this has not exactly one component.
5740 * \sa DataArrayInt::buildUnique, MEDCouplingSkyLineArray::groupPacks
5743 DataArrayIdType *DataArrayDiscrete<T>::indexOfSameConsecutiveValueGroups() const
5745 this->checkAllocated();
5746 if(this->getNumberOfComponents()!=1)
5747 throw INTERP_KERNEL::Exception("DataArrayInt::indexOfSameConsecutiveValueGroups : only single component allowed !");
5748 const T *pt(this->begin());
5749 const T *const ptEnd(this->end()) , * const ptBg(this->begin());
5751 // first find nb of different values in this
5752 std::size_t nbOfTuplesOut(0);
5753 while( pt != ptEnd )
5756 const T *endOfPack(std::find_if(pt+1,ptEnd,[val](T elt){ return val!=elt; }));
5760 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(nbOfTuplesOut+1,1);
5761 mcIdType *retPtr(ret->getPointer()); *retPtr++ = 0;
5763 while( pt != ptEnd )
5766 const T *endOfPack(std::find_if(pt+1,ptEnd,[val](T elt){ return val!=elt; }));
5767 *retPtr++ = ToIdType( std::distance(ptBg,endOfPack) );
5775 * This method can be applied on allocated with one component DataArrayInt instance.
5776 * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
5777 * 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]
5779 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5780 * \throw if \a this is not allocated or if \a this has not exactly one component.
5781 * \sa DataArrayInt::buildUniqueNotSorted, DataArrayInt::indexOfSameConsecutiveValueGroups
5784 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildUnique() const
5786 this->checkAllocated();
5787 if(this->getNumberOfComponents()!=1)
5788 throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
5789 std::size_t nbOfElements(this->getNumberOfTuples());
5790 MCAuto<DataArrayType> tmp(DataArrayType::New());
5791 tmp->deepCopyFrom(*this);
5792 T *data(tmp->getPointer());
5793 T *last(std::unique(data,data+nbOfElements));
5794 MCAuto<DataArrayType> ret(DataArrayType::New());
5795 ret->alloc(std::distance(data,last),1);
5796 std::copy(data,last,ret->getPointer());
5801 * This method can be applied on allocated with one component DataArrayInt instance.
5802 * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
5804 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5806 * \throw if \a this is not allocated or if \a this has not exactly one component.
5808 * \sa DataArrayInt::buildUnique
5811 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildUniqueNotSorted() const
5813 this->checkAllocated();
5814 if(this->getNumberOfComponents()!=1)
5815 throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
5817 this->getMinMaxValues(minVal,maxVal);
5818 std::vector<bool> b(maxVal-minVal+1,false);
5819 const T *ptBg(this->begin()),*endBg(this->end());
5820 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(0,1);
5821 for(const T *pt=ptBg;pt!=endBg;pt++)
5825 ret->pushBackSilent(*pt);
5829 ret->copyStringInfoFrom(*this);
5834 * Returns a new DataArrayInt which contains size of every of groups described by \a this
5835 * "index" array. Such "index" array is returned for example by
5836 * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
5837 * "MEDCouplingUMesh::buildDescendingConnectivity" and
5838 * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
5839 * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
5840 * This method performs the reverse operation of DataArrayInt::computeOffsetsFull.
5841 * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
5842 * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
5843 * The caller is to delete this array using decrRef() as it is no more needed.
5844 * \throw If \a this is not allocated.
5845 * \throw If \a this->getNumberOfComponents() != 1.
5846 * \throw If \a this->getNumberOfTuples() < 2.
5849 * - this contains [1,3,6,7,7,9,15]
5850 * - result array contains [2,3,1,0,2,6],
5851 * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
5853 * \sa DataArrayInt::computeOffsetsFull
5856 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::deltaShiftIndex() const
5858 this->checkAllocated();
5859 if(this->getNumberOfComponents()!=1)
5860 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
5861 std::size_t nbOfElements=this->getNumberOfTuples();
5863 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
5864 const T *ptr=this->getConstPointer();
5865 DataArrayType *ret=DataArrayType::New();
5866 ret->alloc(nbOfElements-1,1);
5867 T *out=ret->getPointer();
5868 std::transform(ptr+1,ptr+nbOfElements,ptr,out,std::minus<T>());
5873 * Modifies \a this one-dimensional array so that value of each element \a x
5874 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5875 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
5876 * and components remains the same.<br>
5877 * This method is useful for allToAllV in MPI with contiguous policy. This method
5878 * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
5880 * \throw If \a this is not allocated.
5881 * \throw If \a this->getNumberOfComponents() != 1.
5884 * - Before \a this contains [3,5,1,2,0,8]
5885 * - After \a this contains [0,3,8,9,11,11]<br>
5886 * Note that the last element 19 = 11 + 8 is missing because size of \a this
5887 * array is retained and thus there is no space to store the last element.
5890 void DataArrayDiscrete<T>::computeOffsets()
5892 this->checkAllocated();
5893 if(this->getNumberOfComponents()!=1)
5894 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
5895 std::size_t nbOfElements=this->getNumberOfTuples();
5898 T *work=this->getPointer();
5901 for(std::size_t i=1;i<nbOfElements;i++)
5904 work[i]=work[i-1]+tmp;
5907 this->declareAsNew();
5911 * Modifies \a this one-dimensional array so that value of each element \a x
5912 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5913 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
5914 * components remains the same and number of tuples is inceamented by one.<br>
5915 * This method is useful for allToAllV in MPI with contiguous policy. This method
5916 * differs from computeOffsets() in that the number of tuples is changed by this one.
5917 * This method performs the reverse operation of DataArrayInt::deltaShiftIndex.
5918 * \throw If \a this is not allocated.
5919 * \throw If \a this->getNumberOfComponents() != 1.
5922 * - Before \a this contains [3,5,1,2,0,8]
5923 * - After \a this contains [0,3,8,9,11,11,19]<br>
5924 * \sa DataArrayInt::deltaShiftIndex
5927 void DataArrayDiscrete<T>::computeOffsetsFull()
5929 this->checkAllocated();
5930 if(this->getNumberOfComponents()!=1)
5931 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
5932 std::size_t nbOfElements=this->getNumberOfTuples();
5933 T *ret=(T *)malloc((nbOfElements+1)*sizeof(T));
5934 const T *work=this->getConstPointer();
5936 for(std::size_t i=0;i<nbOfElements;i++)
5937 ret[i+1]=work[i]+ret[i];
5938 this->useArray(ret,true,DeallocType::C_DEALLOC,nbOfElements+1,1);
5939 this->declareAsNew();
5943 * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
5944 * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
5945 * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
5946 * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
5947 * filling completely one of the ranges in \a this.
5949 * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
5950 * \param [out] rangeIdsFetched the range ids fetched
5951 * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
5952 * \a idsInInputListThatFetch is a part of input \a listOfIds.
5954 * \sa DataArrayInt::computeOffsetsFull
5957 * - \a this : [0,3,7,9,15,18]
5958 * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
5959 * - \a rangeIdsFetched result array: [0,2,4]
5960 * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
5961 * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
5965 void DataArrayDiscrete<T>::findIdsRangesInListOfIds(const DataArrayType *listOfIds, DataArrayIdType *& rangeIdsFetched, DataArrayType *& idsInInputListThatFetch) const
5968 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
5969 listOfIds->checkAllocated(); this->checkAllocated();
5970 if(listOfIds->getNumberOfComponents()!=1)
5971 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
5972 if(this->getNumberOfComponents()!=1)
5973 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
5974 MCAuto<DataArrayIdType> ret0=DataArrayIdType::New(); ret0->alloc(0,1);
5975 MCAuto<DataArrayType> ret1=DataArrayType::New(); ret1->alloc(0,1);
5976 const T *tupPtr(listOfIds->begin()), *tupEnd(listOfIds->end());
5977 const T *offBg(this->begin()),*offEnd(this->end()-1);
5978 const T *offPtr(offBg);
5979 while(tupPtr!=tupEnd && offPtr!=offEnd)
5981 if(*tupPtr==*offPtr)
5984 while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
5987 ret0->pushBackSilent(ToIdType(std::distance(offBg,offPtr)));
5988 ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
5993 { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
5995 rangeIdsFetched=ret0.retn();
5996 idsInInputListThatFetch=ret1.retn();
6000 * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
6001 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6002 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6003 * beginning within the "iota" array. And \a this is a one-dimensional array
6004 * considered as a selector of groups described by \a offsets to include into the result array.
6005 * \throw If \a offsets is NULL.
6006 * \throw If \a offsets is not allocated.
6007 * \throw If \a offsets->getNumberOfComponents() != 1.
6008 * \throw If \a offsets is not monotonically increasing.
6009 * \throw If \a this is not allocated.
6010 * \throw If \a this->getNumberOfComponents() != 1.
6011 * \throw If any element of \a this is not a valid index for \a offsets array.
6014 * - \a this: [0,2,3]
6015 * - \a offsets: [0,3,6,10,14,20]
6016 * - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
6017 * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
6018 * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) +
6019 * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) +
6020 * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
6023 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildExplicitArrByRanges(const DataArrayType *offsets) const
6026 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
6027 this->checkAllocated();
6028 if(this->getNumberOfComponents()!=1)
6029 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
6030 offsets->checkAllocated();
6031 if(offsets->getNumberOfComponents()!=1)
6032 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
6033 mcIdType othNbTuples=offsets->getNumberOfTuples()-1;
6034 mcIdType nbOfTuples=this->getNumberOfTuples();
6036 const T *work=this->getConstPointer();
6037 const T *offPtr=offsets->getConstPointer();
6038 for(mcIdType i=0;i<nbOfTuples;i++)
6041 if(val>=0 && val<othNbTuples)
6043 T delta=offPtr[val+1]-offPtr[val];
6045 retNbOftuples+=delta;
6048 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
6049 throw INTERP_KERNEL::Exception(oss.str().c_str());
6054 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
6055 oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
6056 throw INTERP_KERNEL::Exception(oss.str().c_str());
6059 MCAuto<DataArrayType> ret=DataArrayType::New();
6060 ret->alloc(retNbOftuples,1);
6061 T *retPtr=ret->getPointer();
6062 for(mcIdType i=0;i<nbOfTuples;i++)
6065 T start=offPtr[val];
6066 T off=offPtr[val+1]-start;
6067 for(T j=0;j<off;j++,retPtr++)
6074 * Returns a new DataArrayInt whose contents is computed using \a this that must be a
6075 * scaled array (monotonically increasing).
6076 from that of \a this and \a
6077 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6078 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6079 * beginning within the "iota" array. And \a this is a one-dimensional array
6080 * considered as a selector of groups described by \a offsets to include into the result array.
6081 * \throw If \a is NULL.
6082 * \throw If \a this is not allocated.
6083 * \throw If \a this->getNumberOfComponents() != 1.
6084 * \throw If \a this->getNumberOfTuples() == 0.
6085 * \throw If \a this is not monotonically increasing.
6086 * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
6089 * - \a bg , \a stop and \a step : (0,5,2)
6090 * - \a this: [0,3,6,10,14,20]
6091 * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
6094 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildExplicitArrOfSliceOnScaledArr(T bg, T stop, T step) const
6096 if(!this->isAllocated())
6097 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
6098 if(this->getNumberOfComponents()!=1)
6099 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
6100 mcIdType nbOfTuples(this->getNumberOfTuples());
6102 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
6103 const T *ids(this->begin());
6104 mcIdType nbOfEltsInSlc=DataArrayTools<T>::GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr");
6106 for(mcIdType i=0;i<nbOfEltsInSlc;i++,pos+=step)
6108 if(pos>=0 && pos<nbOfTuples-1)
6110 T delta(ids[pos+1]-ids[pos]);
6114 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
6115 throw INTERP_KERNEL::Exception(oss.str().c_str());
6120 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";
6121 throw INTERP_KERNEL::Exception(oss.str().c_str());
6124 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(sz,1);
6125 T *retPtr(ret->getPointer());
6127 for(mcIdType i=0;i<nbOfEltsInSlc;i++,pos+=step)
6129 T delta(ids[pos+1]-ids[pos]);
6130 for(T j=0;j<delta;j++,retPtr++)
6137 * 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.
6138 * 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
6139 * in tuple **i** of returned DataArrayInt.
6140 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6142 * 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)]
6143 * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6145 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6146 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6147 * \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
6148 * is thrown if no ranges in \a ranges contains value in \a this.
6150 * \sa DataArrayInt::findIdInRangeForEachTuple
6153 DataArrayIdType *DataArrayDiscrete<T>::findRangeIdForEachTuple(const DataArrayType *ranges) const
6156 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6157 if(ranges->getNumberOfComponents()!=2)
6158 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6159 this->checkAllocated();
6160 if(this->getNumberOfComponents()!=1)
6161 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6162 mcIdType nbTuples(this->getNumberOfTuples());
6163 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(nbTuples,1);
6164 mcIdType nbOfRanges(ranges->getNumberOfTuples());
6165 const T *rangesPtr=ranges->getConstPointer();
6166 mcIdType *retPtr=ret->getPointer();
6167 const T *inPtr=this->getConstPointer();
6168 for(mcIdType i=0;i<nbTuples;i++,retPtr++)
6172 for(mcIdType j=0;j<nbOfRanges && !found;j++)
6173 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6174 { *retPtr=j; found=true; }
6179 std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6180 throw INTERP_KERNEL::Exception(oss.str().c_str());
6187 * 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.
6188 * 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
6189 * in tuple **i** of returned DataArrayInt.
6190 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6192 * 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)]
6193 * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6194 * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6196 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6197 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6198 * \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
6199 * is thrown if no ranges in \a ranges contains value in \a this.
6200 * \sa DataArrayInt::findRangeIdForEachTuple
6203 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::findIdInRangeForEachTuple(const DataArrayType *ranges) const
6206 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6207 if(ranges->getNumberOfComponents()!=2)
6208 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6209 this->checkAllocated();
6210 if(this->getNumberOfComponents()!=1)
6211 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6212 mcIdType nbTuples=this->getNumberOfTuples();
6213 MCAuto<DataArrayType> ret=DataArrayType::New(); ret->alloc(nbTuples,1);
6214 mcIdType nbOfRanges=ranges->getNumberOfTuples();
6215 const T *rangesPtr=ranges->getConstPointer();
6216 T *retPtr=ret->getPointer();
6217 const T *inPtr=this->getConstPointer();
6218 for(mcIdType i=0;i<nbTuples;i++,retPtr++)
6222 for(mcIdType j=0;j<nbOfRanges && !found;j++)
6223 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6224 { *retPtr=val-rangesPtr[2*j]; found=true; }
6229 std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6230 throw INTERP_KERNEL::Exception(oss.str().c_str());
6237 * \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).
6238 * 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).
6239 * 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 !
6240 * If this method has correctly worked, \a this will be able to be considered as a linked list.
6241 * This method does nothing if number of tuples is lower of equal to 1.
6243 * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internally the connectivity without any coordinates consideration.
6245 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
6248 void DataArrayDiscrete<T>::sortEachPairToMakeALinkedList()
6250 this->checkAllocated();
6251 if(this->getNumberOfComponents()!=2)
6252 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6253 mcIdType nbOfTuples(this->getNumberOfTuples());
6256 T *conn(this->getPointer());
6257 for(mcIdType i=1;i<nbOfTuples;i++,conn+=2)
6261 if(conn[2]==conn[3])
6263 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6264 throw INTERP_KERNEL::Exception(oss.str().c_str());
6266 if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6267 std::swap(conn[2],conn[3]);
6268 //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6269 if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6271 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6272 throw INTERP_KERNEL::Exception(oss.str().c_str());
6277 if(conn[0]==conn[1] || conn[2]==conn[3])
6278 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6281 s.insert(conn,conn+4);
6283 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6284 if(std::count(conn,conn+4,conn[0])==2)
6289 if(conn[2]==conn[0])
6293 std::copy(tmp,tmp+4,conn);
6296 {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6297 if(conn[1]==conn[3])
6298 std::swap(conn[2],conn[3]);
6305 * \a this is expected to be a correctly linked list of pairs.
6307 * \sa DataArrayInt::sortEachPairToMakeALinkedList
6310 MCAuto<typename Traits<T>::ArrayType> DataArrayDiscrete<T>::fromLinkedListOfPairToList() const
6312 this->checkAllocated();
6313 this->checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6314 mcIdType nbTuples(this->getNumberOfTuples());
6316 throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6317 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(nbTuples+1,1);
6318 const T *thisPtr(this->begin());
6319 T *retPtr(ret->getPointer());
6320 retPtr[0]=thisPtr[0];
6321 for(mcIdType i=0;i<nbTuples;i++)
6323 retPtr[i+1]=thisPtr[2*i+1];
6325 if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6327 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 ?";
6328 throw INTERP_KERNEL::Exception(oss.str());
6335 * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6336 * But the number of components can be different from one.
6337 * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6340 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::getDifferentValues() const
6342 this->checkAllocated();
6344 ret.insert(this->begin(),this->end());
6345 MCAuto<DataArrayType> ret2=DataArrayType::New();
6346 ret2->alloc(ret.size(),1);
6347 std::copy(ret.begin(),ret.end(),ret2->getPointer());
6352 * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6353 * them it tells which tuple id have this id.
6354 * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6355 * This method returns two arrays having same size.
6356 * 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.
6357 * 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]]
6360 std::vector<DataArrayIdType *> DataArrayDiscrete<T>::partitionByDifferentValues(std::vector<T>& differentIds) const
6362 this->checkAllocated();
6363 if(this->getNumberOfComponents()!=1)
6364 throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6366 std::map<T,mcIdType> m,m2,m3;
6367 for(const T *w=this->begin();w!=this->end();w++)
6369 differentIds.resize(m.size());
6370 std::vector<DataArrayIdType *> ret(m.size());
6371 std::vector<mcIdType *> retPtr(m.size());
6372 for(typename std::map<T,mcIdType>::const_iterator it=m.begin();it!=m.end();it++,id++)
6375 ret[id]=DataArrayIdType::New();
6376 ret[id]->alloc((*it).second,1);
6377 retPtr[id]=ret[id]->getPointer();
6378 differentIds[id]=(*it).first;
6381 for(const T *w=this->begin();w!=this->end();w++,id++)
6383 retPtr[m2[*w]][m3[*w]++]=id;
6389 * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6390 * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6392 * \param [in] nbOfSlices - number of slices expected.
6393 * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6395 * \sa DataArray::GetSlice
6396 * \throw If \a this is not allocated or not with exactly one component.
6397 * \throw If an element in \a this if < 0.
6400 std::vector< std::pair<mcIdType,mcIdType> > DataArrayDiscrete<T>::splitInBalancedSlices(mcIdType nbOfSlices) const
6402 if(!this->isAllocated() || this->getNumberOfComponents()!=1)
6403 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6405 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6406 T sum(this->accumulate((std::size_t)0));
6407 mcIdType nbOfTuples(this->getNumberOfTuples());
6408 T sumPerSlc(sum/FromIdType<T>(nbOfSlices));
6410 const T *w(this->begin());
6411 std::vector< std::pair<mcIdType,mcIdType> > ret(nbOfSlices);
6412 for(mcIdType i=0;i<nbOfSlices;i++)
6414 std::pair<mcIdType, mcIdType> p(pos,-1);
6416 while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6420 p.second=nbOfTuples;
6427 * Modify \a this array so that each value becomes a modulus of division of this value by
6428 * a value of another DataArrayInt. There are 3 valid cases.
6429 * 1. The arrays have same number of tuples and components. Then each value of
6430 * \a this array is divided by the corresponding value of \a other one, i.e.:
6431 * _a_ [ i, j ] %= _other_ [ i, j ].
6432 * 2. The arrays have same number of tuples and \a other array has one component. Then
6433 * _a_ [ i, j ] %= _other_ [ i, 0 ].
6434 * 3. The arrays have same number of components and \a other array has one tuple. Then
6435 * _a_ [ i, j ] %= _a2_ [ 0, j ].
6437 * \warning No check of division by zero is performed!
6438 * \param [in] other - a divisor array.
6439 * \throw If \a other is NULL.
6440 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
6441 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
6442 * \a other has number of both tuples and components not equal to 1.
6445 void DataArrayDiscrete<T>::modulusEqual(const DataArrayType *other)
6448 throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
6449 const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
6450 this->checkAllocated(); other->checkAllocated();
6451 mcIdType nbOfTuple(this->getNumberOfTuples());
6452 mcIdType nbOfTuple2(other->getNumberOfTuples());
6453 std::size_t nbOfComp(this->getNumberOfComponents());
6454 std::size_t nbOfComp2(other->getNumberOfComponents());
6455 if(nbOfTuple==nbOfTuple2)
6457 if(nbOfComp==nbOfComp2)
6459 std::transform(this->begin(),this->end(),other->begin(),this->getPointer(),std::modulus<T>());
6461 else if(nbOfComp2==1)
6463 if(nbOfComp2==nbOfComp)
6465 T *ptr=this->getPointer();
6466 const T *ptrc=other->getConstPointer();
6467 for(mcIdType i=0;i<nbOfTuple;i++)
6468 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<T>(),*ptrc++));
6471 throw INTERP_KERNEL::Exception(msg);
6474 throw INTERP_KERNEL::Exception(msg);
6476 else if(nbOfTuple2==1)
6478 T *ptr=this->getPointer();
6479 const T *ptrc=other->getConstPointer();
6480 for(mcIdType i=0;i<nbOfTuple;i++)
6481 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<T>());
6484 throw INTERP_KERNEL::Exception(msg);
6485 this->declareAsNew();
6489 * Apply pow on values of another DataArrayInt to values of \a this one.
6491 * \param [in] other - an array to pow to \a this one.
6492 * \throw If \a other is NULL.
6493 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
6494 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
6495 * \throw If there is a negative value in \a other.
6498 void DataArrayDiscrete<T>::powEqual(const DataArrayType *other)
6501 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
6502 mcIdType nbOfTuple=this->getNumberOfTuples();
6503 mcIdType nbOfTuple2=other->getNumberOfTuples();
6504 std::size_t nbOfComp=this->getNumberOfComponents();
6505 std::size_t nbOfComp2=other->getNumberOfComponents();
6506 if(nbOfTuple!=nbOfTuple2)
6507 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
6508 if(nbOfComp!=1 || nbOfComp2!=1)
6509 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
6510 T *ptr=this->getPointer();
6511 const T *ptrc=other->begin();
6512 for(mcIdType i=0;i<nbOfTuple;i++,ptrc++,ptr++)
6517 for(T j=0;j<*ptrc;j++)
6523 std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
6524 throw INTERP_KERNEL::Exception(oss.str().c_str());
6527 this->declareAsNew();
6530 ////////////////////////////////////
6532 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6536 void DataArrayDiscrete<T>::getTinySerializationIntInformation(std::vector<mcIdType>& tinyInfo) const
6539 if(this->isAllocated())
6541 tinyInfo[0]=this->getNumberOfTuples();
6542 tinyInfo[1]=ToIdType(this->getNumberOfComponents());
6552 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6556 void DataArrayDiscrete<T>::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
6558 if(this->isAllocated())
6560 std::size_t nbOfCompo(this->getNumberOfComponents());
6561 tinyInfo.resize(nbOfCompo+1);
6562 tinyInfo[0]=this->getName();
6563 for(std::size_t i=0;i<nbOfCompo;i++)
6564 tinyInfo[i+1]=this->getInfoOnComponent(i);
6569 tinyInfo[0]=this->getName();
6574 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6575 * This method returns if a feeding is needed.
6578 bool DataArrayDiscrete<T>::resizeForUnserialization(const std::vector<mcIdType>& tinyInfoI)
6580 mcIdType nbOfTuple=tinyInfoI[0];
6581 mcIdType nbOfComp=tinyInfoI[1];
6582 if(nbOfTuple!=-1 || nbOfComp!=-1)
6584 this->alloc(nbOfTuple,nbOfComp);
6591 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6592 * This method returns if a feeding is needed.
6595 void DataArrayDiscrete<T>::finishUnserialization(const std::vector<mcIdType>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
6597 this->setName(tinyInfoS[0]);
6598 if(this->isAllocated())
6600 mcIdType nbOfCompo=tinyInfoI[1];
6601 for(mcIdType i=0;i<nbOfCompo;i++)
6602 this->setInfoOnComponent(i,tinyInfoS[i+1]);
6606 ////////////////////////////////////
6609 * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
6612 * \param [in] a1 - an array to pow up.
6613 * \param [in] a2 - another array to sum up.
6614 * \return DataArrayInt * - the new instance of DataArrayInt.
6615 * The caller is to delete this result array using decrRef() as it is no more
6617 * \throw If either \a a1 or \a a2 is NULL.
6618 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6619 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
6620 * \throw If there is a negative value in \a a2.
6623 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Pow(const DataArrayType *a1, const DataArrayType *a2)
6626 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
6627 mcIdType nbOfTuple=a1->getNumberOfTuples();
6628 mcIdType nbOfTuple2=a2->getNumberOfTuples();
6629 std::size_t nbOfComp=a1->getNumberOfComponents();
6630 std::size_t nbOfComp2=a2->getNumberOfComponents();
6631 if(nbOfTuple!=nbOfTuple2)
6632 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
6633 if(nbOfComp!=1 || nbOfComp2!=1)
6634 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
6635 MCAuto<DataArrayType> ret=DataArrayType::New(); ret->alloc(nbOfTuple,1);
6636 const T *ptr1(a1->begin()),*ptr2(a2->begin());
6637 T *ptr=ret->getPointer();
6638 for(mcIdType i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
6643 for(T j=0;j<*ptr2;j++)
6649 std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
6650 throw INTERP_KERNEL::Exception(oss.str().c_str());
6657 * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6659 * 1. The arrays have same number of tuples and components. Then each value of
6660 * the result array (_a_) is a division of the corresponding values of \a a1 and
6661 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6662 * 2. The arrays have same number of tuples and one array, say _a2_, has one
6664 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6665 * 3. The arrays have same number of components and one array, say _a2_, has one
6667 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6669 * Info on components is copied either from the first array (in the first case) or from
6670 * the array with maximal number of elements (getNbOfElems()).
6671 * \warning No check of division by zero is performed!
6672 * \param [in] a1 - a dividend array.
6673 * \param [in] a2 - a divisor array.
6674 * \return DataArrayInt * - the new instance of DataArrayInt.
6675 * The caller is to delete this result array using decrRef() as it is no more
6677 * \throw If either \a a1 or \a a2 is NULL.
6678 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6679 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6680 * none of them has number of tuples or components equal to 1.
6683 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Modulus(const DataArrayType *a1, const DataArrayType *a2)
6686 throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6687 mcIdType nbOfTuple1(a1->getNumberOfTuples());
6688 mcIdType nbOfTuple2(a2->getNumberOfTuples());
6689 std::size_t nbOfComp1(a1->getNumberOfComponents());
6690 std::size_t nbOfComp2(a2->getNumberOfComponents());
6691 if(nbOfTuple2==nbOfTuple1)
6693 if(nbOfComp1==nbOfComp2)
6695 MCAuto<DataArrayType> ret=DataArrayType::New();
6696 ret->alloc(nbOfTuple2,nbOfComp1);
6697 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<T>());
6698 ret->copyStringInfoFrom(*a1);
6701 else if(nbOfComp2==1)
6703 MCAuto<DataArrayType> ret=DataArrayType::New();
6704 ret->alloc(nbOfTuple1,nbOfComp1);
6705 const T *a2Ptr=a2->getConstPointer();
6706 const T *a1Ptr=a1->getConstPointer();
6707 T *res=ret->getPointer();
6708 for(mcIdType i=0;i<nbOfTuple1;i++)
6709 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<T>(),a2Ptr[i]));
6710 ret->copyStringInfoFrom(*a1);
6715 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6719 else if(nbOfTuple2==1)
6721 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6722 MCAuto<DataArrayType> ret=DataArrayType::New();
6723 ret->alloc(nbOfTuple1,nbOfComp1);
6724 const T *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6725 T *pt=ret->getPointer();
6726 for(mcIdType i=0;i<nbOfTuple1;i++)
6727 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<T>());
6728 ret->copyStringInfoFrom(*a1);
6733 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
6739 * 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
6740 * input array \a ids2.
6741 * \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.
6742 * 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
6744 * In case of success both assertion will be true (no throw) :
6745 * \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
6746 * \c ret->transformWithIndArr(ids2)->isEqual(ids1)
6749 * - \a ids1 : [3,1,103,4,6,10,-7,205]
6750 * - \a ids2 : [-7,1,205,10,6,3,103,4]
6751 * - \a return is : [5,1,6,7,4,3,0,2] because ids2[5]==ids1[0], ids2[1]==ids1[1], ids2[6]==ids1[2]...
6753 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6754 * array using decrRef() as it is no more needed.
6755 * \throw If either ids1 or ids2 is null not allocated or not with one components.
6757 * \sa DataArrayInt::findIdForEach, DataArrayInt::FindPermutationFromFirstToSecondDuplicate, DataArrayInt::rankOfElementInThis
6760 DataArrayIdType *DataArrayDiscrete<T>::FindPermutationFromFirstToSecond(const DataArrayType *ids1, const DataArrayType *ids2)
6763 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
6764 if(!ids1->isAllocated() || !ids2->isAllocated())
6765 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
6766 if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
6767 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
6768 if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
6770 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 !";
6771 throw INTERP_KERNEL::Exception(oss.str().c_str());
6773 MCAuto<DataArrayType> c1(ids1->deepCopy());
6774 MCAuto<DataArrayType> c2(ids2->deepCopy());
6775 c1->sort(true); c2->sort(true);
6776 if(!c1->isEqualWithoutConsideringStr(*c2))
6777 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
6778 MCAuto<DataArrayIdType> p1=ids1->checkAndPreparePermutation();
6779 MCAuto<DataArrayIdType> p2=ids2->checkAndPreparePermutation();
6780 p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
6781 p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
6786 * 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
6787 * input array \a ids2.
6788 * \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.
6789 * 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
6791 * The difference with DataArrayInt::FindPermutationFromFirstToSecond is that this method supports multiple same values in \a ids1 and \a ids2 whereas
6792 * DataArrayInt::FindPermutationFromFirstToSecond doesn't. It implies that this method my be slower than the DataArrayInt::FindPermutationFromFirstToSecond one.
6794 * In case of success both assertion will be true (no throw) :
6795 * \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
6796 * \c ret->transformWithIndArr(ids2)->isEqual(ids1)
6799 * - \a ids1 : [5, 3, 2, 1, 4, 5, 2, 1, 0, 11, 5, 4]
6800 * - \a ids2 : [0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 5, 11]
6801 * - \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]...
6803 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6804 * array using decrRef() as it is no more needed.
6805 * \throw If either ids1 or ids2 is null not allocated or not with one components.
6807 * \sa DataArrayInt::findIdForEach, DataArrayInt::FindPermutationFromFirstToSecond, DataArrayInt::occurenceRankInThis
6810 DataArrayIdType *DataArrayDiscrete<T>::FindPermutationFromFirstToSecondDuplicate(const DataArrayType *ids1, const DataArrayType *ids2)
6813 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecondDuplicate : the two input arrays must be not null !");
6814 constexpr char MSG0[] = "DataArrayInt::FindPermutationFromFirstToSecondDuplicate :";
6815 ids1->checkAllocated(); ids2->checkAllocated();
6816 ids1->checkNbOfComps(1,MSG0); ids2->checkNbOfComps(1,MSG0);
6817 mcIdType nbTuples(ids1->getNumberOfTuples());
6818 if(nbTuples != ids2->getNumberOfTuples())
6820 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 !";
6821 throw INTERP_KERNEL::Exception(oss.str().c_str());
6823 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(nbTuples,1);
6824 MCAuto<DataArrayIdType> oids2(ids2->occurenceRankInThis());
6825 std::map< std::pair<T,mcIdType>, mcIdType> m;
6827 const mcIdType *oids2Ptr(oids2->begin());
6828 for(const T * it2 = ids2->begin() ; it2 != ids2->end() ; ++it2, ++oids2Ptr, ++pos)
6829 m[{*it2,*oids2Ptr}] = pos;
6830 mcIdType *retPtr(ret->getPointer());
6832 std::map<T,mcIdType> mOccurence1; // see DataArrayInt::occurenceRankInThis : avoid to compute additionnal temporary array
6834 for(const T * it1 = ids1->begin() ; it1 != ids1->end() ; ++it1, ++retPtr)
6836 auto it = mOccurence1.find(*it1);
6838 if( it == mOccurence1.end() )
6841 mOccurence1[*it1] = 1;
6845 occRk1 = (*it).second++;
6848 auto it2 = m.find({*it1,occRk1});
6851 *retPtr = (*it2).second;
6855 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 !";
6856 throw INTERP_KERNEL::Exception(oss.str());
6864 * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
6865 * This map, if applied to \a start array, would make it sorted. For example, if
6866 * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
6867 * [5,6,0,3,2,7,1,4].
6868 * \param [in] start - pointer to the first element of the array for which the
6869 * permutation map is computed.
6870 * \param [in] end - pointer specifying the end of the array \a start, so that
6871 * the last value of \a start is \a end[ -1 ].
6872 * \return mcIdType * - the result permutation array that the caller is to delete as it is no
6874 * \throw If there are equal values in the input array.
6877 mcIdType *DataArrayDiscrete<T>::CheckAndPreparePermutation(const T *start, const T *end)
6879 std::size_t sz=std::distance(start,end);
6880 mcIdType *ret=(mcIdType *)malloc(sz*sizeof(mcIdType));
6882 std::copy(start,end,work);
6883 std::sort(work,work+sz);
6884 if(std::unique(work,work+sz)!=work+sz)
6888 throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
6890 std::map<T,mcIdType> m;
6891 for(T *workPt=work;workPt!=work+sz;workPt++)
6892 m[*workPt]=ToIdType(std::distance(work,workPt));
6893 mcIdType *iter2=ret;
6894 for(const T *iter=start;iter!=end;iter++,iter2++)
6901 * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
6902 * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
6903 * offsetA2</em> and (2)
6904 * the number of component in the result array is same as that of each of given arrays.
6905 * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
6906 * Info on components is copied from the first of the given arrays. Number of components
6907 * in the given arrays must be the same.
6908 * \param [in] a1 - an array to include in the result array.
6909 * \param [in] a2 - another array to include in the result array.
6910 * \param [in] offsetA2 - number of tuples of \a a2 to skip.
6911 * \return DataArrayInt * - the new instance of DataArrayInt.
6912 * The caller is to delete this result array using decrRef() as it is no more
6914 * \throw If either \a a1 or \a a2 is NULL.
6915 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
6918 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Aggregate(const DataArrayType *a1, const DataArrayType *a2, T offsetA2)
6921 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
6922 std::size_t nbOfComp(a1->getNumberOfComponents());
6923 if(nbOfComp!=a2->getNumberOfComponents())
6924 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
6925 mcIdType nbOfTuple1(a1->getNumberOfTuples()),nbOfTuple2(a2->getNumberOfTuples());
6926 MCAuto<DataArrayType> ret(DataArrayType::New());
6927 ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
6928 T *pt=std::copy(a1->begin(),a1->end(),ret->getPointer());
6929 std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
6930 ret->copyStringInfoFrom(*a1);
6935 * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
6936 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
6937 * the number of component in the result array is same as that of each of given arrays.
6938 * Info on components is copied from the first of the given arrays. Number of components
6939 * in the given arrays must be the same.
6940 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
6941 * not the object itself.
6942 * \param [in] arr - a sequence of arrays to include in the result array.
6943 * \return DataArrayInt * - the new instance of DataArrayInt.
6944 * The caller is to delete this result array using decrRef() as it is no more
6946 * \throw If all arrays within \a arr are NULL.
6947 * \throw If getNumberOfComponents() of arrays within \a arr.
6950 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Aggregate(const std::vector<const DataArrayType *>& arr)
6952 std::vector<const DataArrayType *> a;
6953 for(typename std::vector<const DataArrayType *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6957 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
6958 typename std::vector<const DataArrayType *>::const_iterator it=a.begin();
6959 std::size_t nbOfComp((*it)->getNumberOfComponents());
6960 mcIdType nbt((*it++)->getNumberOfTuples());
6961 for(;it!=a.end();it++)
6963 if((*it)->getNumberOfComponents()!=nbOfComp)
6964 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
6965 nbt+=(*it)->getNumberOfTuples();
6967 MCAuto<DataArrayType> ret=DataArrayType::New();
6968 ret->alloc(nbt,nbOfComp);
6969 T *pt=ret->getPointer();
6970 for(it=a.begin();it!=a.end();it++)
6971 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
6972 ret->copyStringInfoFrom(*(a[0]));
6977 * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
6978 * A packed index array is an allocated array with one component, and at least one tuple. The first element
6979 * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
6980 * 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.
6982 * \return DataArrayInt * - a new object to be managed by the caller.
6985 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::AggregateIndexes(const std::vector<const DataArrayType *>& arrs)
6988 for(typename std::vector<const DataArrayType *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
6992 (*it4)->checkAllocated();
6993 if((*it4)->getNumberOfComponents()!=1)
6995 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6996 throw INTERP_KERNEL::Exception(oss.str().c_str());
6998 mcIdType nbTupl((*it4)->getNumberOfTuples());
7001 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
7002 throw INTERP_KERNEL::Exception(oss.str().c_str());
7004 if((*it4)->front()!=0)
7006 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
7007 throw INTERP_KERNEL::Exception(oss.str().c_str());
7013 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
7014 throw INTERP_KERNEL::Exception(oss.str().c_str());
7018 throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
7019 MCAuto<DataArrayType> ret=DataArrayType::New();
7020 ret->alloc(retSz,1);
7021 T *pt=ret->getPointer(); *pt++=0;
7022 for(typename std::vector<const DataArrayType *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
7023 pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<T>(),pt[-1]));
7024 ret->copyStringInfoFrom(*(arrs[0]));
7029 * Returns a new DataArrayInt which contains all elements of given one-dimensional
7030 * arrays. The result array does not contain any duplicates and its values
7031 * are sorted in ascending order.
7032 * \param [in] arr - sequence of DataArrayInt's to unite.
7033 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7034 * array using decrRef() as it is no more needed.
7035 * \throw If any \a arr[i] is not allocated.
7036 * \throw If \a arr[i]->getNumberOfComponents() != 1.
7039 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::BuildUnion(const std::vector<const DataArrayType *>& arr)
7041 std::vector<const DataArrayType *> a;
7042 for(typename std::vector<const DataArrayType *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7045 for(typename std::vector<const DataArrayType *>::const_iterator it=a.begin();it!=a.end();it++)
7047 (*it)->checkAllocated();
7048 if((*it)->getNumberOfComponents()!=1)
7049 throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
7053 for(typename std::vector<const DataArrayType *>::const_iterator it=a.begin();it!=a.end();it++)
7055 const T *pt=(*it)->getConstPointer();
7056 mcIdType nbOfTuples((*it)->getNumberOfTuples());
7057 r.insert(pt,pt+nbOfTuples);
7059 DataArrayType *ret=DataArrayType::New();
7060 ret->alloc(r.size(),1);
7061 std::copy(r.begin(),r.end(),ret->getPointer());
7066 * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
7067 * arrays. The result array does not contain any duplicates and its values
7068 * are sorted in ascending order.
7069 * \param [in] arr - sequence of DataArrayInt's to intersect.
7070 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7071 * array using decrRef() as it is no more needed.
7072 * \throw If any \a arr[i] is not allocated.
7073 * \throw If \a arr[i]->getNumberOfComponents() != 1.
7076 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::BuildIntersection(const std::vector<const DataArrayType *>& arr)
7078 std::vector<const DataArrayType *> a;
7079 for(typename std::vector<const DataArrayType *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7082 for(typename std::vector<const DataArrayType *>::const_iterator it=a.begin();it!=a.end();it++)
7084 (*it)->checkAllocated();
7085 if((*it)->getNumberOfComponents()!=1)
7086 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
7090 for(typename std::vector<const DataArrayType *>::const_iterator it=a.begin();it!=a.end();it++)
7092 const T *pt=(*it)->getConstPointer();
7093 mcIdType nbOfTuples((*it)->getNumberOfTuples());
7094 std::set<T> s1(pt,pt+nbOfTuples);
7098 std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
7104 DataArrayType *ret(DataArrayType::New());
7105 ret->alloc(r.size(),1);
7106 std::copy(r.begin(),r.end(),ret->getPointer());
7111 * This method allows to put a vector of vector of integer into a more compact data structure (skyline).
7112 * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<mcIdType> >.
7114 * \param [in] v the input data structure to be translate into skyline format.
7115 * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
7116 * \param [out] dataIndex the second element of the skyline format.
7119 void DataArrayDiscrete<T>::PutIntoToSkylineFrmt(const std::vector< std::vector<T> >& v, DataArrayType *& data, DataArrayIdType *& dataIndex)
7121 std::size_t sz(v.size());
7122 MCAuto<DataArrayType> retDat(DataArrayType::New());
7123 MCAuto<DataArrayIdType> retIdx(DataArrayIdType::New());
7124 retIdx->alloc(sz+1,1);
7125 mcIdType *ptid(retIdx->getPointer()); *ptid=0;
7126 for(std::size_t i=0;i<sz;i++,ptid++)
7127 ptid[1]=ptid[0]+ToIdType(v[i].size());
7128 retDat->alloc(retIdx->back(),1);
7129 T *pt=retDat->getPointer();
7130 for(std::size_t i=0;i<sz;i++)
7131 pt=std::copy(v[i].begin(),v[i].end(),pt);
7132 data=retDat.retn(); dataIndex=retIdx.retn();
7136 * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn
7137 * (\ref numbering-indirect).
7138 * This method returns the result of the extraction ( specified by a set of ids in [\b idsOfSelectBg , \b idsOfSelectEnd ) ).
7139 * The selection of extraction is done standardly in new2old format.
7140 * This method returns indexed arrays (\ref numbering-indirect) using 2 arrays (arrOut,arrIndexOut).
7142 * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
7143 * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
7144 * \param [in] arrIn arr origin array from which the extraction will be done.
7145 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7146 * \param [out] arrOut the resulting array
7147 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
7148 * \sa DataArrayInt::ExtractFromIndexedArraysSlice
7151 void DataArrayDiscrete<T>::ExtractFromIndexedArrays(const mcIdType *idsOfSelectBg, const mcIdType *idsOfSelectEnd,
7152 const DataArrayType *arrIn, const DataArrayIdType *arrIndxIn,
7153 DataArrayType* &arrOut, DataArrayIdType* &arrIndexOut)
7155 if(!arrIn || !arrIndxIn)
7156 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArrays : input pointer is NULL !");
7157 arrIn->checkAllocated(); arrIndxIn->checkAllocated();
7158 if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1)
7159 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArrays : input arrays must have exactly one component !");
7160 std::size_t sz=std::distance(idsOfSelectBg,idsOfSelectEnd);
7161 const T *arrInPtr=arrIn->begin();
7162 const mcIdType *arrIndxPtr=arrIndxIn->begin();
7163 mcIdType nbOfGrps=arrIndxIn->getNumberOfTuples()-1;
7165 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArrays : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !");
7166 mcIdType maxSizeOfArr(arrIn->getNumberOfTuples());
7167 MCAuto<DataArrayType> arro=DataArrayType::New();
7168 MCAuto<DataArrayIdType> arrIo=DataArrayIdType::New();
7169 arrIo->alloc(sz+1,1);
7170 const mcIdType *idsIt=idsOfSelectBg;
7171 mcIdType *work=arrIo->getPointer();
7174 for(std::size_t i=0;i<sz;i++,work++,idsIt++)
7176 if(*idsIt>=0 && *idsIt<nbOfGrps)
7177 lgth+=arrIndxPtr[*idsIt+1]-arrIndxPtr[*idsIt];
7180 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " ! Must be in [0," << nbOfGrps << ") !";
7181 throw INTERP_KERNEL::Exception(oss.str());
7187 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " and at this pos arrIndxIn[" << *idsIt;
7188 oss << "+1]-arrIndxIn[" << *idsIt << "] < 0 ! The input index array is bugged !";
7189 throw INTERP_KERNEL::Exception(oss.str());
7192 arro->alloc(lgth,1);
7193 T *data=arro->getPointer();
7194 idsIt=idsOfSelectBg;
7195 for(std::size_t i=0;i<sz;i++,idsIt++)
7197 if(arrIndxPtr[*idsIt]>=0 && arrIndxPtr[*idsIt+1]<=maxSizeOfArr)
7198 data=std::copy(arrInPtr+arrIndxPtr[*idsIt],arrInPtr+arrIndxPtr[*idsIt+1],data);
7201 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " arrIndx[" << *idsIt << "] must be >= 0 and arrIndx[";
7202 oss << *idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!";
7203 throw INTERP_KERNEL::Exception(oss.str());
7207 arrIndexOut=arrIo.retn();
7211 * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn
7212 * (\ref numbering-indirect).
7213 * 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 ).
7214 * The selection of extraction is done standardly in new2old format.
7215 * This method returns indexed arrays (\ref numbering-indirect) using 2 arrays (arrOut,arrIndexOut).
7217 * \param [in] idsOfSelectStart begin of set of ids of the input extraction (included)
7218 * \param [in] idsOfSelectStop end of set of ids of the input extraction (excluded)
7219 * \param [in] idsOfSelectStep
7220 * \param [in] arrIn arr origin array from which the extraction will be done.
7221 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7222 * \param [out] arrOut the resulting array
7223 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
7224 * \sa DataArrayInt::ExtractFromIndexedArrays
7227 void DataArrayDiscrete<T>::ExtractFromIndexedArraysSlice(mcIdType idsOfSelectStart, mcIdType idsOfSelectStop, mcIdType idsOfSelectStep,
7228 const DataArrayType *arrIn, const DataArrayIdType *arrIndxIn,
7229 DataArrayType* &arrOut, DataArrayIdType* &arrIndexOut)
7231 if(!arrIn || !arrIndxIn)
7232 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArraysSlice : input pointer is NULL !");
7233 arrIn->checkAllocated(); arrIndxIn->checkAllocated();
7234 if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1)
7235 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArraysSlice : input arrays must have exactly one component !");
7236 mcIdType sz=DataArray::GetNumberOfItemGivenBESRelative(idsOfSelectStart,idsOfSelectStop,idsOfSelectStep,"MEDCouplingUMesh::ExtractFromIndexedArraysSlice : Input slice ");
7237 const T *arrInPtr=arrIn->begin();
7238 const mcIdType *arrIndxPtr=arrIndxIn->begin();
7239 mcIdType nbOfGrps=arrIndxIn->getNumberOfTuples()-1;
7241 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArraysSlice : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !");
7242 mcIdType maxSizeOfArr(arrIn->getNumberOfTuples());
7243 MCAuto<DataArrayType> arro=DataArrayType::New();
7244 MCAuto<DataArrayIdType> arrIo=DataArrayIdType::New();
7245 arrIo->alloc(sz+1,1);
7246 mcIdType idsIt=idsOfSelectStart;
7247 mcIdType *work=arrIo->getPointer();
7250 for(mcIdType i=0;i<sz;i++,work++,idsIt+=idsOfSelectStep)
7252 if(idsIt>=0 && idsIt<nbOfGrps)
7253 lgth+=arrIndxPtr[idsIt+1]-arrIndxPtr[idsIt];
7256 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArraysSlice : id located on pos #" << i << " value is " << idsIt << " ! Must be in [0," << nbOfGrps << ") !";
7257 throw INTERP_KERNEL::Exception(oss.str());
7263 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArraysSlice : id located on pos #" << i << " value is " << idsIt << " and at this pos arrIndxIn[" << idsIt;
7264 oss << "+1]-arrIndxIn[" << idsIt << "] < 0 ! The input index array is bugged !";
7265 throw INTERP_KERNEL::Exception(oss.str());
7268 arro->alloc(lgth,1);
7269 T *data=arro->getPointer();
7270 idsIt=idsOfSelectStart;
7271 for(mcIdType i=0;i<sz;i++,idsIt+=idsOfSelectStep)
7273 if(arrIndxPtr[idsIt]>=0 && arrIndxPtr[idsIt+1]<=maxSizeOfArr)
7274 data=std::copy(arrInPtr+arrIndxPtr[idsIt],arrInPtr+arrIndxPtr[idsIt+1],data);
7277 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArraysSlice : id located on pos #" << i << " value is " << idsIt << " arrIndx[" << idsIt << "] must be >= 0 and arrIndx[";
7278 oss << idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!";
7279 throw INTERP_KERNEL::Exception(oss.str());
7283 arrIndexOut=arrIo.retn();
7287 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
7288 * 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
7289 * cellIds \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex).
7290 * This method is an generalization of MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitly a result output arrays.
7292 * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
7293 * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
7294 * \param [in] arrIn arr origin array from which the extraction will be done.
7295 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7296 * \param [in] srcArr input array that will be used as source of copy for ids in [ \b idsOfSelectBg, \b idsOfSelectEnd )
7297 * \param [in] srcArrIndex index array of \b srcArr
7298 * \param [out] arrOut the resulting array
7299 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
7301 * \sa DataArrayInt::SetPartOfIndexedArraysSameIdx
7304 void DataArrayDiscrete<T>::SetPartOfIndexedArrays(const mcIdType *idsOfSelectBg, const mcIdType *idsOfSelectEnd,
7305 const DataArrayType *arrIn, const DataArrayIdType *arrIndxIn,
7306 const DataArrayType *srcArr, const DataArrayIdType *srcArrIndex,
7307 DataArrayType* &arrOut, DataArrayIdType* &arrIndexOut)
7309 if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
7310 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArrays : presence of null pointer in input parameter !");
7311 MCAuto<DataArrayType> arro=DataArrayType::New();
7312 MCAuto<DataArrayIdType> arrIo=DataArrayIdType::New();
7313 mcIdType nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
7314 std::vector<bool> v(nbOfTuples,true);
7316 const mcIdType *arrIndxInPtr=arrIndxIn->begin();
7317 const mcIdType *srcArrIndexPtr=srcArrIndex->begin();
7318 for(const mcIdType *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++)
7320 if(*it>=0 && *it<nbOfTuples)
7323 offset+=(srcArrIndexPtr[1]-srcArrIndexPtr[0])-(arrIndxInPtr[*it+1]-arrIndxInPtr[*it]);
7327 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArrays : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !";
7328 throw INTERP_KERNEL::Exception(oss.str());
7331 srcArrIndexPtr=srcArrIndex->begin();
7332 arrIo->alloc(nbOfTuples+1,1);
7333 arro->alloc(arrIn->getNumberOfTuples()+offset,1);
7334 const T *arrInPtr=arrIn->begin();
7335 const T *srcArrPtr=srcArr->begin();
7336 mcIdType *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0;
7337 T *arroPtr=arro->getPointer();
7338 for(mcIdType ii=0;ii<nbOfTuples;ii++,arrIoPtr++)
7342 arroPtr=std::copy(arrInPtr+arrIndxInPtr[ii],arrInPtr+arrIndxInPtr[ii+1],arroPtr);
7343 *arrIoPtr=arrIoPtr[-1]+(arrIndxInPtr[ii+1]-arrIndxInPtr[ii]);
7347 std::size_t pos=std::distance(idsOfSelectBg,std::find(idsOfSelectBg,idsOfSelectEnd,ii));
7348 arroPtr=std::copy(srcArrPtr+srcArrIndexPtr[pos],srcArrPtr+srcArrIndexPtr[pos+1],arroPtr);
7349 *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]);
7353 arrIndexOut=arrIo.retn();
7357 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
7358 * 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
7359 * cellIds \b in [\b idsOfSelectBg, \b idsOfSelectEnd) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex).
7360 * This method is an generalization of DataArrayInt::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitly a result output arrays.
7362 * \param [in] start begin of set of ids of the input extraction (included)
7363 * \param [in] end end of set of ids of the input extraction (excluded)
7364 * \param [in] step step of the set of ids in range mode.
7365 * \param [in] arrIn arr origin array from which the extraction will be done.
7366 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7367 * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd)
7368 * \param [in] srcArrIndex index array of \b srcArr
7369 * \param [out] arrOut the resulting array
7370 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
7372 * \sa DataArrayInt::SetPartOfIndexedArraysSameIdx DataArrayInt::SetPartOfIndexedArrays
7375 void DataArrayDiscrete<T>::SetPartOfIndexedArraysSlice(mcIdType start, mcIdType end, mcIdType step,
7376 const DataArrayType *arrIn, const DataArrayIdType *arrIndxIn,
7377 const DataArrayType *srcArr, const DataArrayIdType *srcArrIndex,
7378 DataArrayType* &arrOut, DataArrayIdType* &arrIndexOut)
7380 if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
7381 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArraysSlice : presence of null pointer in input parameter !");
7382 MCAuto<DataArrayType> arro=DataArrayType::New();
7383 MCAuto<DataArrayIdType> arrIo=DataArrayIdType::New();
7384 mcIdType nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
7386 const mcIdType *arrIndxInPtr=arrIndxIn->begin();
7387 const mcIdType *srcArrIndexPtr=srcArrIndex->begin();
7388 mcIdType nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"DataArrayInt::SetPartOfIndexedArraysSlice : ");
7390 for(mcIdType i=0;i<nbOfElemsToSet;i++,srcArrIndexPtr++,it+=step)
7392 if(it>=0 && it<nbOfTuples)
7393 offset+=(srcArrIndexPtr[1]-srcArrIndexPtr[0])-(arrIndxInPtr[it+1]-arrIndxInPtr[it]);
7396 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSlice : On pos #" << i << " value is " << it << " not in [0," << nbOfTuples << ") !";
7397 throw INTERP_KERNEL::Exception(oss.str());
7400 srcArrIndexPtr=srcArrIndex->begin();
7401 arrIo->alloc(nbOfTuples+1,1);
7402 arro->alloc(arrIn->getNumberOfTuples()+offset,1);
7403 const T *arrInPtr=arrIn->begin();
7404 const T *srcArrPtr=srcArr->begin();
7405 mcIdType *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0;
7406 T *arroPtr=arro->getPointer();
7407 for(mcIdType ii=0;ii<nbOfTuples;ii++,arrIoPtr++)
7409 mcIdType pos=DataArray::GetPosOfItemGivenBESRelativeNoThrow(ii,start,end,step);
7412 arroPtr=std::copy(arrInPtr+arrIndxInPtr[ii],arrInPtr+arrIndxInPtr[ii+1],arroPtr);
7413 *arrIoPtr=arrIoPtr[-1]+(arrIndxInPtr[ii+1]-arrIndxInPtr[ii]);
7417 arroPtr=std::copy(srcArrPtr+srcArrIndexPtr[pos],srcArrPtr+srcArrIndexPtr[pos+1],arroPtr);
7418 *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]);
7422 arrIndexOut=arrIo.retn();
7426 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
7427 * This method is an specialization of MEDCouplingUMesh::SetPartOfIndexedArrays in the case of assignment do not modify the index in \b arrIndxIn.
7429 * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
7430 * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
7431 * \param [in,out] arrInOut arr origin array from which the extraction will be done.
7432 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7433 * \param [in] srcArr input array that will be used as source of copy for ids in [ \b idsOfSelectBg , \b idsOfSelectEnd )
7434 * \param [in] srcArrIndex index array of \b srcArr
7436 * \sa DataArrayInt::SetPartOfIndexedArrays
7439 void DataArrayDiscrete<T>::SetPartOfIndexedArraysSameIdx(const mcIdType *idsOfSelectBg, const mcIdType *idsOfSelectEnd,
7440 DataArrayType *arrInOut, const DataArrayIdType *arrIndxIn,
7441 const DataArrayType *srcArr, const DataArrayIdType *srcArrIndex)
7443 if(arrInOut==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
7444 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArraysSameIdx : presence of null pointer in input parameter !");
7445 mcIdType nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
7446 const mcIdType *arrIndxInPtr=arrIndxIn->begin();
7447 const mcIdType *srcArrIndexPtr=srcArrIndex->begin();
7448 T *arrInOutPtr=arrInOut->getPointer();
7449 const T *srcArrPtr=srcArr->begin();
7450 for(const mcIdType *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++)
7452 if(*it>=0 && *it<nbOfTuples)
7454 if(srcArrIndexPtr[1]-srcArrIndexPtr[0]==arrIndxInPtr[*it+1]-arrIndxInPtr[*it])
7455 std::copy(srcArrPtr+srcArrIndexPtr[0],srcArrPtr+srcArrIndexPtr[1],arrInOutPtr+arrIndxInPtr[*it]);
7458 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] !";
7459 throw INTERP_KERNEL::Exception(oss.str());
7464 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSameIdx : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !";
7465 throw INTERP_KERNEL::Exception(oss.str());
7471 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
7472 * This method is an specialization of MEDCouplingUMesh::SetPartOfIndexedArrays in the case of assignment do not modify the index in \b arrIndxIn.
7474 * \param [in] start begin of set of ids of the input extraction (included)
7475 * \param [in] end end of set of ids of the input extraction (excluded)
7476 * \param [in] step step of the set of ids in range mode.
7477 * \param [in,out] arrInOut arr origin array from which the extraction will be done.
7478 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7479 * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd)
7480 * \param [in] srcArrIndex index array of \b srcArr
7482 * \sa DataArrayInt::SetPartOfIndexedArraysSlice DataArrayInt::SetPartOfIndexedArraysSameIdx
7485 void DataArrayDiscrete<T>::SetPartOfIndexedArraysSameIdxSlice(mcIdType start, mcIdType end, mcIdType step,
7486 DataArrayType *arrInOut, const DataArrayIdType *arrIndxIn,
7487 const DataArrayType *srcArr, const DataArrayIdType *srcArrIndex)
7489 if(arrInOut==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
7490 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : presence of null pointer in input parameter !");
7491 mcIdType nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
7492 const mcIdType *arrIndxInPtr=arrIndxIn->begin();
7493 const mcIdType *srcArrIndexPtr=srcArrIndex->begin();
7494 T *arrInOutPtr=arrInOut->getPointer();
7495 const T *srcArrPtr=srcArr->begin();
7496 mcIdType nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : ");
7498 for(mcIdType i=0;i<nbOfElemsToSet;i++,srcArrIndexPtr++,it+=step)
7500 if(it>=0 && it<nbOfTuples)
7502 if(srcArrIndexPtr[1]-srcArrIndexPtr[0]==arrIndxInPtr[it+1]-arrIndxInPtr[it])
7503 std::copy(srcArrPtr+srcArrIndexPtr[0],srcArrPtr+srcArrIndexPtr[1],arrInOutPtr+arrIndxInPtr[it]);
7506 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : On pos #" << i << " id (idsOfSelectBg[" << i << "]) is " << it << " arrIndxIn[id+1]-arrIndxIn[id]!=srcArrIndex[pos+1]-srcArrIndex[pos] !";
7507 throw INTERP_KERNEL::Exception(oss.str());
7512 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : On pos #" << i << " value is " << it << " not in [0," << nbOfTuples << ") !";
7513 throw INTERP_KERNEL::Exception(oss.str());
7519 * This method works on an input pair (\b arr, \b arrIndx) where \b arr indexes is in \b arrIndx.
7520 * 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.
7522 * \param [in] idsToRemoveBg begin of set of ids to remove in \b arr (included)
7523 * \param [in] idsToRemoveEnd end of set of ids to remove in \b arr (excluded)
7524 * \param [in,out] arr array in which the remove operation will be done.
7525 * \param [in,out] arrIndx array in the remove operation will modify
7526 * \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])
7527 * \return true if \b arr and \b arrIndx have been modified, false if not.
7530 bool DataArrayDiscrete<T>::RemoveIdsFromIndexedArrays(const T *idsToRemoveBg, const T *idsToRemoveEnd,
7531 DataArrayType *arr, DataArrayIdType *arrIndx, mcIdType offsetForRemoval)
7533 if(!arrIndx || !arr)
7534 throw INTERP_KERNEL::Exception("DataArrayInt::RemoveIdsFromIndexedArrays : some input arrays are empty !");
7535 if(offsetForRemoval<0)
7536 throw INTERP_KERNEL::Exception("DataArrayInt::RemoveIdsFromIndexedArrays : offsetForRemoval should be >=0 !");
7537 std::set<T> s(idsToRemoveBg,idsToRemoveEnd);
7538 mcIdType nbOfGrps=arrIndx->getNumberOfTuples()-1;
7539 mcIdType *arrIPtr=arrIndx->getPointer();
7541 mcIdType previousArrI=0;
7542 const T *arrPtr=arr->begin();
7543 std::vector<T> arrOut;//no utility to switch to DataArrayInt because copy always needed
7544 for(mcIdType i=0;i<nbOfGrps;i++,arrIPtr++)
7546 if(*arrIPtr-previousArrI>offsetForRemoval)
7548 for(const T *work=arrPtr+previousArrI+offsetForRemoval;work!=arrPtr+*arrIPtr;work++)
7550 if(s.find(*work)==s.end())
7551 arrOut.push_back(*work);
7554 previousArrI=*arrIPtr;
7555 *arrIPtr=ToIdType(arrOut.size());
7557 if(arr->getNumberOfTuples()==ToIdType(arrOut.size()))
7559 arr->alloc(arrOut.size(),1);
7560 std::copy(arrOut.begin(),arrOut.end(),arr->getPointer());
7565 * Returns a new DataArrayInt containing an arithmetic progression
7566 * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step )
7568 * \param [in] begin - the start value of the result sequence.
7569 * \param [in] end - limiting value, so that every value of the result array is less than
7571 * \param [in] step - specifies the increment or decrement.
7572 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7573 * array using decrRef() as it is no more needed.
7574 * \throw If \a step == 0.
7575 * \throw If \a end < \a begin && \a step > 0.
7576 * \throw If \a end > \a begin && \a step < 0.
7579 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Range(T begin, T end, T step)
7581 mcIdType nbOfTuples=DataArrayTools<T>::GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
7582 MCAuto<DataArrayType> ret=DataArrayType::New();
7583 ret->alloc(nbOfTuples,1);
7584 T *ptr=ret->getPointer();
7587 for(T i=begin;i<end;i+=step,ptr++)
7592 for(T i=begin;i>end;i+=step,ptr++)
7599 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7600 * from a zip representation of a surjective format (returned e.g. by
7601 * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7602 * for example). The result array minimizes the permutation. <br>
7603 * For more info on renumbering see \ref numbering. <br>
7605 * - \a nbOfOldTuples: 10
7606 * - \a arr : [0,3, 5,7,9]
7607 * - \a arrIBg : [0,2,5]
7608 * - \a newNbOfTuples: 7
7609 * - result array : [0,1,2,0,3,4,5,4,6,4]
7611 * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7612 * \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7613 * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7614 * (indices of) equal values. Its every element (except the last one) points to
7615 * the first element of a group of equal values.
7616 * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7617 * arrIBg is \a arrIEnd[ -1 ].
7618 * \param [out] newNbOfTuples - number of tuples after surjection application.
7619 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7620 * array using decrRef() as it is no more needed.
7621 * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7624 DataArrayIdType *DataArrayDiscrete<T>::ConvertIndexArrayToO2N(mcIdType nbOfOldTuples, const mcIdType *arr, const mcIdType *arrIBg, const mcIdType *arrIEnd, mcIdType &newNbOfTuples)
7626 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
7627 ret->alloc(nbOfOldTuples,1);
7628 mcIdType *pt=ret->getPointer();
7629 std::fill(pt,pt+nbOfOldTuples,-1);
7630 mcIdType nbOfGrps=ToIdType(std::distance(arrIBg,arrIEnd))-1;
7631 const mcIdType *cIPtr=arrIBg;
7632 for(mcIdType i=0;i<nbOfGrps;i++)
7633 pt[arr[cIPtr[i]]]=-(i+2);
7635 for(mcIdType iNode=0;iNode<nbOfOldTuples;iNode++)
7643 mcIdType grpId=-(pt[iNode]+2);
7644 for(mcIdType j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7646 if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7650 std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7651 throw INTERP_KERNEL::Exception(oss.str().c_str());
7658 newNbOfTuples=newNb;
7663 * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
7664 * The i-th item of the result array is an ID of a set of elements belonging to a
7665 * unique set of groups, which the i-th element is a part of. This set of elements
7666 * belonging to a unique set of groups is called \a family, so the result array contains
7667 * IDs of families each element belongs to.
7669 * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
7670 * then there are 3 families:
7671 * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
7672 * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
7673 * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
7674 * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
7675 * stands for the element #3 which is in none of groups.
7677 * \param [in] groups - sequence of groups of element IDs.
7678 * \param [in] newNb - total number of elements; it must be more than max ID of element
7680 * \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
7681 * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
7682 * each element with ID from range [0, \a newNb ) belongs to. The caller is to
7683 * delete this array using decrRef() as it is no more needed.
7684 * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
7687 DataArrayIdType *DataArrayDiscrete<T>::MakePartition(const std::vector<const DataArrayType *>& groups, mcIdType newNb, std::vector< std::vector<mcIdType> >& fidsOfGroups)
7689 std::vector<const DataArrayType *> groups2;
7690 for(typename std::vector<const DataArrayType *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
7692 groups2.push_back(*it4);
7693 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
7694 ret->alloc(newNb,1);
7695 mcIdType *retPtr=ret->getPointer();
7696 std::fill(retPtr,retPtr+newNb,0);
7698 for(typename std::vector<const DataArrayType *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
7700 const T *ptr=(*iter)->getConstPointer();
7701 std::size_t nbOfElem=(*iter)->getNbOfElems();
7703 for(mcIdType j=0;j<sfid;j++)
7706 for(std::size_t i=0;i<nbOfElem;i++)
7708 if(ptr[i]>=0 && ptr[i]<newNb)
7710 if(retPtr[ptr[i]]==j)
7718 std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
7720 throw INTERP_KERNEL::Exception(oss.str().c_str());
7727 fidsOfGroups.clear();
7728 fidsOfGroups.resize(groups2.size());
7730 for(typename std::vector<const DataArrayType *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
7732 std::set<mcIdType> tmp;
7733 const T *ptr=(*iter)->getConstPointer();
7734 std::size_t nbOfElem=(*iter)->getNbOfElems();
7735 for(const T *p=ptr;p!=ptr+nbOfElem;p++)
7736 tmp.insert(retPtr[*p]);
7737 fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
7745 namespace MEDCouplingImpl
7751 OpSwitchedOn(T *pt):_pt(pt),_cnt(0) { }
7752 void operator()(const bool& b) { if(b) *_pt++=FromIdType<T>(_cnt); _cnt++; }
7755 MEDCoupling::mcIdType _cnt;
7762 OpSwitchedOff(T *pt):_pt(pt),_cnt(0) { }
7763 void operator()(const bool& b) { if(!b) *_pt++=FromIdType<T>(_cnt); _cnt++; }
7766 MEDCoupling::mcIdType _cnt;
7771 namespace MEDCoupling
7774 * This method returns the list of ids in ascending mode so that v[id]==true.
7777 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::BuildListOfSwitchedOn(const std::vector<bool>& v)
7779 std::size_t sz(std::count(v.begin(),v.end(),true));
7780 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(sz,1);
7781 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn<T>(ret->getPointer()));
7786 * This method returns the list of ids in ascending mode so that v[id]==false.
7789 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::BuildListOfSwitchedOff(const std::vector<bool>& v)
7791 std::size_t sz(std::count(v.begin(),v.end(),false));
7792 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(sz,1);
7793 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff<T>(ret->getPointer()));
7798 namespace MEDCoupling
7801 * This method compares content of input vector \a v and \a this.
7802 * 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.
7803 * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
7805 * \param [in] v - the vector of 'flags' to be compared with \a this.
7807 * \throw If \a this is not sorted ascendingly.
7808 * \throw If \a this has not exactly one component.
7809 * \throw If \a this is not allocated.
7812 bool DataArrayDiscreteSigned<T>::isFittingWith(const std::vector<bool>& v) const
7814 this->checkAllocated();
7815 if(this->getNumberOfComponents()!=1)
7816 throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
7817 const T *w(this->begin()),*end2(this->end());
7818 T refVal=-std::numeric_limits<T>::max();
7820 std::vector<bool>::const_iterator it(v.begin());
7821 for(;it!=v.end();it++,i++)
7833 std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(this->begin(),w-1) << " this is not sorted ascendingly !";
7834 throw INTERP_KERNEL::Exception(oss.str().c_str());