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 std::vector< MCAuto< typename Traits<T>::ArrayTypeCh > > DataArrayTemplate<T>::explodeComponents() const
680 std::size_t sz(getNumberOfComponents());
681 mcIdType nbTuples(getNumberOfTuples());
682 std::string name(getName());
683 std::vector<std::string> compNames(getInfoOnComponents());
684 std::vector< MCAuto< typename Traits<T>::ArrayTypeCh > > ret(sz);
685 const T *thisPt(begin());
686 for(std::size_t i=0;i<sz;i++)
688 MCAuto< typename Traits<T>::ArrayTypeCh > part(Traits<T>::ArrayTypeCh::New());
689 part->alloc(nbTuples,1);
691 part->setInfoOnComponent(0,compNames[i]);
692 T *otherPt(part->getPointer());
693 for(mcIdType j=0;j<nbTuples;j++)
694 otherPt[j]=thisPt[sz*j+i];
701 std::size_t DataArrayTemplate<T>::getHeapMemorySizeWithoutChildren() const
703 std::size_t sz(_mem.getNbOfElemAllocated());
705 return DataArray::getHeapMemorySizeWithoutChildren()+sz;
709 * Allocates the raw data in memory. If the memory was already allocated, then it is
710 * freed and re-allocated. See an example of this method use
711 * \ref MEDCouplingArraySteps1WC "here".
712 * \param [in] nbOfTuple - number of tuples of data to allocate.
713 * \param [in] nbOfCompo - number of components of data to allocate.
714 * \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
717 void DataArrayTemplate<T>::alloc(std::size_t nbOfTuple, std::size_t nbOfCompo)
719 _info_on_compo.resize(nbOfCompo);
720 _mem.alloc(nbOfCompo*nbOfTuple);
725 * Sets a C array to be used as raw data of \a this. The previously set info
726 * of components is retained and re-sized.
727 * For more info see \ref MEDCouplingArraySteps1.
728 * \param [in] array - the C array to be used as raw data of \a this.
729 * \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
730 * \param [in] type - specifies how to deallocate \a array. If \a type == MEDCoupling::CPP_DEALLOC,
731 * \c delete [] \c array; will be called. If \a type == MEDCoupling::C_DEALLOC,
732 * \c free(\c array ) will be called.
733 * \param [in] nbOfTuple - new number of tuples in \a this.
734 * \param [in] nbOfCompo - new number of components in \a this.
737 void DataArrayTemplate<T>::useArray(const T *array, bool ownership, DeallocType type, std::size_t nbOfTuple, std::size_t nbOfCompo)
739 _info_on_compo.resize(nbOfCompo);
740 _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
745 void DataArrayTemplate<T>::useExternalArrayWithRWAccess(const T *array, std::size_t nbOfTuple, std::size_t nbOfCompo)
747 _info_on_compo.resize(nbOfCompo);
748 _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
753 * Returns a value located at specified tuple and component.
754 * This method is equivalent to DataArrayTemplate<T>::getIJ() except that validity of
755 * parameters is checked. So this method is safe but expensive if used to go through
756 * all values of \a this.
757 * \param [in] tupleId - index of tuple of interest.
758 * \param [in] compoId - index of component of interest.
759 * \return double - value located by \a tupleId and \a compoId.
760 * \throw If \a this is not allocated.
761 * \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
762 * \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
765 T DataArrayTemplate<T>::getIJSafe(std::size_t tupleId, std::size_t compoId) const
768 if(ToIdType(tupleId)>=getNumberOfTuples())
770 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
771 throw INTERP_KERNEL::Exception(oss.str().c_str());
773 if(compoId>=getNumberOfComponents())
775 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
776 throw INTERP_KERNEL::Exception(oss.str().c_str());
778 return _mem[tupleId*_info_on_compo.size()+compoId];
782 * 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.
784 * \sa DataArray::getHeapMemorySizeWithoutChildren, DataArrayTemplate<T>::reserve
787 void DataArrayTemplate<T>::pack() const
793 * Checks if raw data is allocated. Read more on the raw data
794 * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
795 * \return bool - \a true if the raw data is allocated, \a false else.
798 bool DataArrayTemplate<T>::isAllocated() const
800 return getConstPointer()!=0;
804 * Checks if raw data is allocated and throws an exception if it is not the case.
805 * \throw If the raw data is not allocated.
808 void DataArrayTemplate<T>::checkAllocated() const
812 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !";
813 throw INTERP_KERNEL::Exception(oss.str().c_str());
818 * This method deallocated \a this without modification of information relative to the components.
819 * After call of this method, DataArrayDouble::isAllocated will return false.
820 * If \a this is already not allocated, \a this is let unchanged.
823 void DataArrayTemplate<T>::desallocate()
829 * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
830 * 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.
831 * If \a this has not already been allocated, number of components is set to one.
832 * This method allows to reduce number of reallocations on invocation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
834 * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
837 void DataArrayTemplate<T>::reserve(std::size_t nbOfElems)
839 std::size_t nbCompo(getNumberOfComponents());
842 _mem.reserve(nbOfElems);
846 _mem.reserve(nbOfElems);
847 _info_on_compo.resize(1);
851 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::reserve : not available for DataArrayDouble with number of components different than 1 !";
852 throw INTERP_KERNEL::Exception(oss.str().c_str());
857 * 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
858 * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
860 * \param [in] val the value to be added in \a this
861 * \throw If \a this has already been allocated with number of components different from one.
862 * \sa DataArrayDouble::pushBackValsSilent
865 void DataArrayTemplate<T>::pushBackSilent(T val)
867 std::size_t nbCompo(getNumberOfComponents());
872 _info_on_compo.resize(1);
877 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !";
878 throw INTERP_KERNEL::Exception(oss.str().c_str());
883 * 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
884 * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
886 * \param [in] valsBg - an array of values to push at the end of \c this.
887 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
888 * the last value of \a valsBg is \a valsEnd[ -1 ].
889 * \throw If \a this has already been allocated with number of components different from one.
890 * \sa DataArrayDouble::pushBackSilent
893 void DataArrayTemplate<T>::pushBackValsSilent(const T *valsBg, const T *valsEnd)
895 std::size_t nbCompo(getNumberOfComponents());
897 _mem.insertAtTheEnd(valsBg,valsEnd);
900 _info_on_compo.resize(1);
901 _mem.insertAtTheEnd(valsBg,valsEnd);
905 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !";
906 throw INTERP_KERNEL::Exception(oss.str().c_str());
911 * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
912 * \throw If \a this is already empty.
913 * \throw If \a this has number of components different from one.
916 T DataArrayTemplate<T>::popBackSilent()
918 if(getNumberOfComponents()==1)
919 return _mem.popBack();
922 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::popBackSilent : not available for DataArrayDouble with number of components different than 1 !";
923 throw INTERP_KERNEL::Exception(oss.str().c_str());
928 * Allocates the raw data in memory. If exactly same memory as needed already
929 * allocated, it is not re-allocated.
930 * \param [in] nbOfTuple - number of tuples of data to allocate.
931 * \param [in] nbOfCompo - number of components of data to allocate.
932 * \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
935 void DataArrayTemplate<T>::allocIfNecessary(std::size_t nbOfTuple, std::size_t nbOfCompo)
939 if(ToIdType(nbOfTuple)!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
940 alloc(nbOfTuple,nbOfCompo);
943 alloc(nbOfTuple,nbOfCompo);
947 * Checks the number of tuples.
948 * \return bool - \a true if getNumberOfTuples() == 0, \a false else.
949 * \throw If \a this is not allocated.
952 bool DataArrayTemplate<T>::empty() const
955 return getNumberOfTuples()==0;
959 * Copies all the data from another DataArrayDouble. For more info see
960 * \ref MEDCouplingArrayBasicsCopyDeepAssign.
961 * \param [in] other - another instance of DataArrayDouble to copy data from.
962 * \throw If the \a other is not allocated.
965 void DataArrayTemplate<T>::deepCopyFrom(const DataArrayTemplate<T>& other)
967 other.checkAllocated();
968 mcIdType nbOfTuples(other.getNumberOfTuples());
969 std::size_t nbOfComp(other.getNumberOfComponents());
970 allocIfNecessary(nbOfTuples,nbOfComp);
971 std::size_t nbOfElems(nbOfTuples*nbOfComp);
973 const T *ptI(other.begin());
974 for(std::size_t i=0;i<nbOfElems;i++)
976 copyStringInfoFrom(other);
980 * Reverse the array values.
981 * \throw If \a this->getNumberOfComponents() < 1.
982 * \throw If \a this is not allocated.
985 void DataArrayTemplate<T>::reverse()
988 _mem.reverse(getNumberOfComponents());
993 * Assign \a val to all values in \a this array. To know more on filling arrays see
994 * \ref MEDCouplingArrayFill.
995 * \param [in] val - the value to fill with.
996 * \throw If \a this is not allocated.
999 void DataArrayTemplate<T>::fillWithValue(T val)
1002 _mem.fillWithValue(val);
1007 * Changes number of tuples in the array. If the new number of tuples is smaller
1008 * than the current number the array is truncated, otherwise the array is extended.
1009 * \param [in] nbOfTuples - new number of tuples.
1010 * \throw If \a this is not allocated.
1011 * \throw If \a nbOfTuples is negative.
1014 void DataArrayTemplate<T>::reAlloc(std::size_t nbOfTuples)
1017 _mem.reAlloc(getNumberOfComponents()*nbOfTuples);
1022 * Permutes values of \a this array as required by \a old2New array. The values are
1023 * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1024 * the same as in \c this one.
1025 * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
1026 * For more info on renumbering see \ref numbering.
1027 * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1028 * giving a new position for i-th old value.
1031 void DataArrayTemplate<T>::renumberInPlace(const mcIdType *old2New)
1034 mcIdType nbTuples(getNumberOfTuples());
1035 std::size_t nbOfCompo(getNumberOfComponents());
1036 T *tmp(new T[nbTuples*nbOfCompo]);
1037 const T *iptr(begin());
1038 for(mcIdType i=0;i<nbTuples;i++)
1040 mcIdType v=old2New[i];
1041 if(v>=0 && v<nbTuples)
1042 std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1045 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1046 throw INTERP_KERNEL::Exception(oss.str().c_str());
1049 std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1056 * Permutes values of \a this array as required by \a new2Old array. The values are
1057 * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1058 * the same as in \c this one.
1059 * For more info on renumbering see \ref numbering.
1060 * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1061 * giving a previous position of i-th new value.
1062 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1063 * is to delete using decrRef() as it is no more needed.
1066 void DataArrayTemplate<T>::renumberInPlaceR(const mcIdType *new2Old)
1069 mcIdType nbTuples(getNumberOfTuples());
1070 std::size_t nbOfCompo(getNumberOfComponents());
1071 T *tmp(new T[nbTuples*nbOfCompo]);
1072 const T *iptr(begin());
1073 for(mcIdType i=0;i<nbTuples;i++)
1075 mcIdType v=new2Old[i];
1076 if(v>=0 && v<nbTuples)
1077 std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1080 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1081 throw INTERP_KERNEL::Exception(oss.str().c_str());
1084 std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1090 * Sorts values of the array.
1091 * \param [in] asc - \a true means ascending order, \a false, descending.
1092 * \throw If \a this is not allocated.
1093 * \throw If \a this->getNumberOfComponents() != 1.
1096 void DataArrayTemplate<T>::sort(bool asc)
1099 if(getNumberOfComponents()!=1)
1101 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::sort : only supported with 'this' array with ONE component !";
1102 throw INTERP_KERNEL::Exception(oss.str().c_str());
1109 * Returns a copy of \a this array with values permuted as required by \a old2New array.
1110 * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ].
1111 * Number of tuples in the result array remains the same as in \c this one.
1112 * If a permutation reduction is needed, renumberAndReduce() should be used.
1113 * For more info on renumbering see \ref numbering.
1114 * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1115 * giving a new position for i-th old value.
1116 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1117 * is to delete using decrRef() as it is no more needed.
1118 * \throw If \a this is not allocated.
1121 typename Traits<T>::ArrayType *DataArrayTemplate<T>::renumber(const mcIdType *old2New) const
1124 mcIdType nbTuples(getNumberOfTuples());
1125 std::size_t nbOfCompo(getNumberOfComponents());
1126 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1127 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1128 ret->alloc(nbTuples,nbOfCompo);
1129 ret->copyStringInfoFrom(*this);
1130 const T *iptr(begin());
1131 T *optr(ret->getPointer());
1132 for(mcIdType i=0;i<nbTuples;i++)
1133 std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1134 ret->copyStringInfoFrom(*this);
1139 * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1140 * The values are permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1141 * tuples in the result array remains the same as in \c this one.
1142 * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
1143 * For more info on renumbering see \ref numbering.
1144 * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1145 * giving a previous position of i-th new value.
1146 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1147 * is to delete using decrRef() as it is no more needed.
1150 typename Traits<T>::ArrayType *DataArrayTemplate<T>::renumberR(const mcIdType *new2Old) const
1153 mcIdType nbTuples(getNumberOfTuples());
1154 std::size_t nbOfCompo(getNumberOfComponents());
1155 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1156 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1157 ret->alloc(nbTuples,nbOfCompo);
1158 ret->copyStringInfoFrom(*this);
1159 const T *iptr(getConstPointer());
1160 T *optr(ret->getPointer());
1161 for(mcIdType i=0;i<nbTuples;i++)
1162 std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1163 ret->copyStringInfoFrom(*this);
1168 * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1169 * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1170 * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ] for all
1171 * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which
1172 * \a old2New[ i ] is negative, is missing from the result array.
1173 * For more info on renumbering see \ref numbering.
1174 * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1175 * giving a new position for i-th old tuple and giving negative position for
1176 * for i-th old tuple that should be omitted.
1177 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1178 * is to delete using decrRef() as it is no more needed.
1181 typename Traits<T>::ArrayType *DataArrayTemplate<T>::renumberAndReduce(const mcIdType *old2New, mcIdType newNbOfTuple) const
1184 mcIdType nbTuples(getNumberOfTuples());
1185 std::size_t nbOfCompo(getNumberOfComponents());
1186 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1187 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1188 ret->alloc(newNbOfTuple,nbOfCompo);
1189 const T *iptr=getConstPointer();
1190 T *optr=ret->getPointer();
1191 for(mcIdType i=0;i<nbTuples;i++)
1193 mcIdType w=old2New[i];
1195 std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1197 ret->copyStringInfoFrom(*this);
1202 * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1203 * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1204 * \a new2OldBg array.
1205 * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1206 * This method is equivalent to renumberAndReduce() except that convention in input is
1207 * \c new2old and \b not \c old2new.
1208 * For more info on renumbering see \ref numbering.
1209 * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1210 * tuple index in \a this array to fill the i-th tuple in the new array.
1211 * \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1212 * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1213 * \a new2OldBg <= \a pi < \a new2OldEnd.
1214 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1215 * is to delete using decrRef() as it is no more needed.
1218 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleId(const mcIdType *new2OldBg, const mcIdType *new2OldEnd) const
1221 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1222 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1223 std::size_t nbComp(getNumberOfComponents());
1224 ret->alloc(std::distance(new2OldBg,new2OldEnd),nbComp);
1225 ret->copyStringInfoFrom(*this);
1226 T *pt(ret->getPointer());
1227 const T *srcPt(getConstPointer());
1229 for(const mcIdType *w=new2OldBg;w!=new2OldEnd;w++,i++)
1230 std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1231 ret->copyStringInfoFrom(*this);
1236 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleId(const DataArrayIdType& di) const
1238 return this->mySelectByTupleId(di.begin(),di.end());
1242 MCAuto<typename Traits<T>::ArrayTypeCh> DataArrayTemplate<T>::selectPartDef(const PartDefinition *pd) const
1245 throw INTERP_KERNEL::Exception("DataArrayTemplate<T>::selectPartDef : null input pointer !");
1246 MCAuto<typename Traits<T>::ArrayTypeCh> ret(Traits<T>::ArrayTypeCh::New());
1247 const SlicePartDefinition *spd(dynamic_cast<const SlicePartDefinition *>(pd));
1251 spd->getSlice(a,b,c);
1252 if(a==0 && b==getNumberOfTuples() && c==1)
1254 DataArrayTemplate<T> *directRet(const_cast<DataArrayTemplate<T> *>(this));
1255 directRet->incrRef();
1256 MCAuto<DataArrayTemplate<T> > ret2(directRet);
1257 return DynamicCastSafe<DataArrayTemplate<T>,typename Traits<T>::ArrayTypeCh>(ret2);
1261 MCAuto<DataArray> ret2(selectByTupleIdSafeSlice(a,b,c));
1262 return DynamicCastSafe<DataArray,typename Traits<T>::ArrayTypeCh>(ret2);
1265 const DataArrayPartDefinition *dpd(dynamic_cast<const DataArrayPartDefinition *>(pd));
1268 MCAuto<DataArrayIdType> arr(dpd->toDAI());
1269 MCAuto<DataArray> ret2(selectByTupleIdSafe(arr->begin(),arr->end()));
1270 return DynamicCastSafe<DataArray,typename Traits<T>::ArrayTypeCh>(ret2);
1273 throw INTERP_KERNEL::Exception("DataArrayTemplate<T>::selectPartDef : unrecognized part def !");
1277 * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1278 * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1279 * \a new2OldBg array.
1280 * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1281 * This method is equivalent to renumberAndReduce() except that convention in input is
1282 * \c new2old and \b not \c old2new.
1283 * This method is equivalent to selectByTupleId() except that it prevents coping data
1284 * from behind the end of \a this array.
1285 * For more info on renumbering see \ref numbering.
1286 * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1287 * tuple index in \a this array to fill the i-th tuple in the new array.
1288 * \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1289 * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1290 * \a new2OldBg <= \a pi < \a new2OldEnd.
1291 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1292 * is to delete using decrRef() as it is no more needed.
1293 * \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1296 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleIdSafe(const mcIdType *new2OldBg, const mcIdType *new2OldEnd) const
1299 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1300 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1301 std::size_t nbComp(getNumberOfComponents());
1302 mcIdType oldNbOfTuples(getNumberOfTuples());
1303 ret->alloc(std::distance(new2OldBg,new2OldEnd),nbComp);
1304 ret->copyStringInfoFrom(*this);
1305 T *pt(ret->getPointer());
1306 const T *srcPt(getConstPointer());
1308 for(const mcIdType *w=new2OldBg;w!=new2OldEnd;w++,i++)
1309 if(*w>=0 && *w<oldNbOfTuples)
1310 std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1313 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !";
1314 throw INTERP_KERNEL::Exception(oss.str().c_str());
1316 ret->copyStringInfoFrom(*this);
1321 * Changes the number of components within \a this array so that its raw data **does
1322 * not** change, instead splitting this data into tuples changes.
1323 * \warning This method erases all (name and unit) component info set before!
1324 * \param [in] newNbOfComp - number of components for \a this array to have.
1325 * \throw If \a this is not allocated
1326 * \throw If getNbOfElems() % \a newNbOfCompo != 0.
1327 * \throw If \a newNbOfCompo is lower than 1.
1328 * \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1329 * \warning This method erases all (name and unit) component info set before!
1332 void DataArrayTemplate<T>::rearrange(std::size_t newNbOfCompo)
1337 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::rearrange : input newNbOfCompo must be > 0 !";
1338 throw INTERP_KERNEL::Exception(oss.str().c_str());
1340 std::size_t nbOfElems=getNbOfElems();
1341 if(nbOfElems%newNbOfCompo!=0)
1343 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::rearrange : nbOfElems%newNbOfCompo!=0 !";
1344 throw INTERP_KERNEL::Exception(oss.str().c_str());
1346 if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<mcIdType>::max())
1348 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !";
1349 throw INTERP_KERNEL::Exception(oss.str().c_str());
1351 _info_on_compo.clear();
1352 _info_on_compo.resize(newNbOfCompo);
1357 * Changes the number of components within \a this array to be equal to its number
1358 * of tuples, and inversely its number of tuples to become equal to its number of
1359 * components. So that its raw data **does not** change, instead splitting this
1360 * data into tuples changes.
1361 * \warning This method erases all (name and unit) component info set before!
1362 * \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1363 * \throw If \a this is not allocated.
1367 void DataArrayTemplate<T>::transpose()
1370 rearrange(getNumberOfTuples());
1374 * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1375 * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1376 * is truncated to have \a newNbOfComp components, keeping first components. If \a
1377 * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1378 * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1380 * \param [in] newNbOfComp - number of components for the new array to have.
1381 * \param [in] dftValue - value assigned to new values added to the new array.
1382 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1383 * is to delete using decrRef() as it is no more needed.
1384 * \throw If \a this is not allocated.
1387 typename Traits<T>::ArrayType *DataArrayTemplate<T>::changeNbOfComponents(std::size_t newNbOfComp, T dftValue) const
1390 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1391 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1392 ret->alloc(getNumberOfTuples(),newNbOfComp);
1393 const T *oldc(getConstPointer());
1394 T *nc(ret->getPointer());
1395 mcIdType nbOfTuples=getNumberOfTuples();
1396 std::size_t oldNbOfComp=getNumberOfComponents();
1397 std::size_t dim(std::min(oldNbOfComp,newNbOfComp));
1398 for(mcIdType i=0;i<nbOfTuples;i++)
1402 nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1403 for(;j<newNbOfComp;j++)
1404 nc[newNbOfComp*i+j]=dftValue;
1406 ret->setName(getName());
1407 for(std::size_t i=0;i<dim;i++)
1408 ret->setInfoOnComponent(i,getInfoOnComponent(i));
1409 ret->setName(getName());
1414 * Returns a copy of \a this array composed of selected components.
1415 * The new DataArrayDouble has the same number of tuples but includes components
1416 * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1417 * can be either less, same or more than \a this->getNbOfElems().
1418 * \param [in] compoIds - sequence of zero based indices of components to include
1419 * into the new array.
1420 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1421 * is to delete using decrRef() as it is no more needed.
1422 * \throw If \a this is not allocated.
1423 * \throw If a component index (\a i) is not valid:
1424 * \a i < 0 || \a i >= \a this->getNumberOfComponents().
1426 * \if ENABLE_EXAMPLES
1427 * \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1431 typename Traits<T>::ArrayType *DataArrayTemplate<T>::myKeepSelectedComponents(const std::vector<std::size_t>& compoIds) const
1434 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1435 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1436 std::size_t newNbOfCompo=compoIds.size();
1437 std::size_t oldNbOfCompo=getNumberOfComponents();
1438 for(std::vector<std::size_t>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1439 if((*it)<0 || (*it)>=oldNbOfCompo)
1441 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1442 throw INTERP_KERNEL::Exception(oss.str().c_str());
1444 mcIdType nbOfTuples(getNumberOfTuples());
1445 ret->alloc(nbOfTuples,newNbOfCompo);
1446 ret->copyPartOfStringInfoFrom(*this,compoIds);
1447 const T *oldc(getConstPointer());
1448 T *nc(ret->getPointer());
1449 for(mcIdType i=0;i<nbOfTuples;i++)
1450 for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1451 *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1456 * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1457 * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1458 * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1459 * This method is a specialization of selectByTupleIdSafeSlice().
1460 * \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1461 * \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1462 * If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1463 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1464 * is to delete using decrRef() as it is no more needed.
1465 * \throw If \a tupleIdBg < 0.
1466 * \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1467 * \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1468 * \sa DataArrayDouble::selectByTupleIdSafeSlice
1471 typename Traits<T>::ArrayType *DataArrayTemplate<T>::subArray(mcIdType tupleIdBg, mcIdType tupleIdEnd) const
1474 mcIdType nbt=getNumberOfTuples();
1477 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::subArray : The tupleIdBg parameter must be greater than 0 !";
1478 throw INTERP_KERNEL::Exception(oss.str().c_str());
1482 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << ":subArray : The tupleIdBg parameter is greater than number of tuples !";
1483 throw INTERP_KERNEL::Exception(oss.str().c_str());
1485 mcIdType trueEnd=tupleIdEnd;
1490 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << ":subArray : The tupleIdBg parameter is greater than number of tuples !";
1491 throw INTERP_KERNEL::Exception(oss.str().c_str());
1496 std::size_t nbComp=getNumberOfComponents();
1497 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1498 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1499 ret->alloc(trueEnd-tupleIdBg,nbComp);
1500 ret->copyStringInfoFrom(*this);
1501 std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1506 * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1507 * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1508 * tuple. Indices of the selected tuples are the same as ones returned by the Python
1509 * command \c range( \a bg, \a end2, \a step ).
1510 * This method is equivalent to selectByTupleIdSafe() except that the input array is
1511 * not constructed explicitly.
1512 * For more info on renumbering see \ref numbering.
1513 * \param [in] bg - index of the first tuple to copy from \a this array.
1514 * \param [in] end2 - index of the tuple before which the tuples to copy are located.
1515 * \param [in] step - index increment to get index of the next tuple to copy.
1516 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1517 * is to delete using decrRef() as it is no more needed.
1518 * \sa DataArrayDouble::subArray.
1521 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleIdSafeSlice(mcIdType bg, mcIdType end2, mcIdType step) const
1524 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1525 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1526 std::size_t nbComp(getNumberOfComponents());
1527 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::selectByTupleIdSafeSlice : ";
1528 mcIdType newNbOfTuples(GetNumberOfItemGivenBESRelative(bg,end2,step,oss.str()));
1529 ret->alloc(newNbOfTuples,nbComp);
1530 T *pt(ret->getPointer());
1531 const T *srcPt(getConstPointer()+bg*nbComp);
1532 for(mcIdType i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1533 std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1534 ret->copyStringInfoFrom(*this);
1539 * Copy all values from another DataArrayDouble into specified tuples and components
1540 * of \a this array. Textual data is not copied.
1541 * The tree parameters defining set of indices of tuples and components are similar to
1542 * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
1543 * \param [in] a - the array to copy values from.
1544 * \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
1545 * \param [in] endTuples - index of the tuple before which the tuples to assign to
1547 * \param [in] stepTuples - index increment to get index of the next tuple to assign to.
1548 * \param [in] bgComp - index of the first component of \a this array to assign values to.
1549 * \param [in] endComp - index of the component before which the components to assign
1551 * \param [in] stepComp - index increment to get index of the next component to assign to.
1552 * \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents()
1553 * must be equal to the number of columns to assign to, else an
1554 * exception is thrown; if \a false, then it is only required that \a
1555 * a->getNbOfElems() equals to number of values to assign to (this condition
1556 * must be respected even if \a strictCompoCompare is \a true). The number of
1557 * values to assign to is given by following Python expression:
1558 * \a nbTargetValues =
1559 * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
1560 * \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1561 * \throw If \a a is NULL.
1562 * \throw If \a a is not allocated.
1563 * \throw If \a this is not allocated.
1564 * \throw If parameters specifying tuples and components to assign to do not give a
1565 * non-empty range of increasing indices.
1566 * \throw If \a a->getNbOfElems() != \a nbTargetValues.
1567 * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
1568 * \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1570 * \if ENABLE_EXAMPLES
1571 * \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
1575 void DataArrayTemplate<T>::setPartOfValues1(const typename Traits<T>::ArrayType *a, mcIdType bgTuples, mcIdType endTuples, mcIdType stepTuples, mcIdType bgComp, mcIdType endComp, mcIdType stepComp, bool strictCompoCompare)
1579 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::setPartOfValues1 : input DataArrayDouble is NULL !";
1580 throw INTERP_KERNEL::Exception(oss.str().c_str());
1582 const char msg[]="DataArrayTemplate::setPartOfValues1";
1584 a->checkAllocated();
1585 mcIdType newNbOfTuples(DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg));
1586 mcIdType newNbOfComp(DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg));
1587 std::size_t nbComp(getNumberOfComponents());
1588 mcIdType nbOfTuples(getNumberOfTuples());
1589 DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
1590 DataArray::CheckValueInRangeEx(ToIdType(nbComp),bgComp,endComp,"invalid component value");
1591 bool assignTech(true);
1592 if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
1594 if(strictCompoCompare)
1595 a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1599 a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
1602 const T *srcPt(a->getConstPointer());
1603 T *pt(getPointer()+bgTuples*nbComp+bgComp);
1606 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1607 for(mcIdType j=0;j<newNbOfComp;j++,srcPt++)
1608 pt[j*stepComp]=*srcPt;
1612 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1614 const T*srcPt2=srcPt;
1615 for(mcIdType j=0;j<newNbOfComp;j++,srcPt2++)
1616 pt[j*stepComp]=*srcPt2;
1622 * Assign a given value to values at specified tuples and components of \a this array.
1623 * The tree parameters defining set of indices of tuples and components are similar to
1624 * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
1625 * \param [in] a - the value to assign.
1626 * \param [in] bgTuples - index of the first tuple of \a this array to assign to.
1627 * \param [in] endTuples - index of the tuple before which the tuples to assign to
1629 * \param [in] stepTuples - index increment to get index of the next tuple to assign to.
1630 * \param [in] bgComp - index of the first component of \a this array to assign to.
1631 * \param [in] endComp - index of the component before which the components to assign
1633 * \param [in] stepComp - index increment to get index of the next component to assign to.
1634 * \throw If \a this is not allocated.
1635 * \throw If parameters specifying tuples and components to assign to, do not give a
1636 * non-empty range of increasing indices or indices are out of a valid range
1637 * for \c this array.
1639 * \if ENABLE_EXAMPLES
1640 * \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
1644 void DataArrayTemplate<T>::setPartOfValuesSimple1(T a, mcIdType bgTuples, mcIdType endTuples, mcIdType stepTuples, mcIdType bgComp, mcIdType endComp, mcIdType stepComp)
1646 const char msg[]="DataArrayTemplate::setPartOfValuesSimple1";
1648 mcIdType newNbOfTuples(DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg));
1649 mcIdType newNbOfComp(DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg));
1650 std::size_t nbComp(getNumberOfComponents());
1651 mcIdType nbOfTuples(getNumberOfTuples());
1652 DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
1653 DataArray::CheckValueInRangeEx(ToIdType(nbComp),bgComp,endComp,"invalid component value");
1654 T *pt=getPointer()+bgTuples*nbComp+bgComp;
1655 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1656 for(mcIdType j=0;j<newNbOfComp;j++)
1661 * Copy all values from another DataArrayDouble (\a a) into specified tuples and
1662 * components of \a this array. Textual data is not copied.
1663 * The tuples and components to assign to are defined by C arrays of indices.
1664 * There are two *modes of usage*:
1665 * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
1666 * of \a a is assigned to its own location within \a this array.
1667 * - If \a a includes one tuple, then all values of \a a are assigned to the specified
1668 * components of every specified tuple of \a this array. In this mode it is required
1669 * that \a a->getNumberOfComponents() equals to the number of specified components.
1671 * \param [in] a - the array to copy values from.
1672 * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
1673 * assign values of \a a to.
1674 * \param [in] endTuples - specifies the end of the array \a bgTuples, so that
1675 * pointer to a tuple index <em>(pi)</em> varies as this:
1676 * \a bgTuples <= \a pi < \a endTuples.
1677 * \param [in] bgComp - pointer to an array of component indices of \a this array to
1678 * assign values of \a a to.
1679 * \param [in] endComp - specifies the end of the array \a bgTuples, so that
1680 * pointer to a component index <em>(pi)</em> varies as this:
1681 * \a bgComp <= \a pi < \a endComp.
1682 * \param [in] strictCompoCompare - this parameter is checked only if the
1683 * *mode of usage* is the first; if it is \a true (default),
1684 * then \a a->getNumberOfComponents() must be equal
1685 * to the number of specified columns, else this is not required.
1686 * \throw If \a a is NULL.
1687 * \throw If \a a is not allocated.
1688 * \throw If \a this is not allocated.
1689 * \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
1690 * out of a valid range for \a this array.
1691 * \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
1692 * if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
1693 * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
1694 * <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
1696 * \if ENABLE_EXAMPLES
1697 * \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
1701 void DataArrayTemplate<T>::setPartOfValues2(const typename Traits<T>::ArrayType *a, const mcIdType *bgTuples, const mcIdType *endTuples, const mcIdType *bgComp, const mcIdType *endComp, bool strictCompoCompare)
1704 throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
1705 const char msg[]="DataArrayTemplate::setPartOfValues2";
1707 a->checkAllocated();
1708 std::size_t nbComp(getNumberOfComponents());
1709 mcIdType nbOfTuples(getNumberOfTuples());
1710 for(const mcIdType *z=bgComp;z!=endComp;z++)
1711 DataArray::CheckValueInRange(ToIdType(nbComp),*z,"invalid component id");
1712 mcIdType newNbOfTuples(ToIdType(std::distance(bgTuples,endTuples)));
1713 mcIdType newNbOfComp(ToIdType(std::distance(bgComp,endComp)));
1714 bool assignTech(true);
1715 if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
1717 if(strictCompoCompare)
1718 a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1722 a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
1725 T *pt(getPointer());
1726 const T *srcPt(a->getConstPointer());
1729 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1731 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1732 for(const mcIdType *z=bgComp;z!=endComp;z++,srcPt++)
1734 pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
1740 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1742 const T *srcPt2=srcPt;
1743 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1744 for(const mcIdType *z=bgComp;z!=endComp;z++,srcPt2++)
1746 pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
1753 * Assign a given value to values at specified tuples and components of \a this array.
1754 * The tuples and components to assign to are defined by C arrays of indices.
1755 * \param [in] a - the value to assign.
1756 * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
1758 * \param [in] endTuples - specifies the end of the array \a bgTuples, so that
1759 * pointer to a tuple index (\a pi) varies as this:
1760 * \a bgTuples <= \a pi < \a endTuples.
1761 * \param [in] bgComp - pointer to an array of component indices of \a this array to
1763 * \param [in] endComp - specifies the end of the array \a bgTuples, so that
1764 * pointer to a component index (\a pi) varies as this:
1765 * \a bgComp <= \a pi < \a endComp.
1766 * \throw If \a this is not allocated.
1767 * \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
1768 * out of a valid range for \a this array.
1770 * \if ENABLE_EXAMPLES
1771 * \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
1775 void DataArrayTemplate<T>::setPartOfValuesSimple2(T a, const mcIdType *bgTuples, const mcIdType *endTuples, const mcIdType *bgComp, const mcIdType *endComp)
1778 std::size_t nbComp=getNumberOfComponents();
1779 mcIdType nbOfTuples=getNumberOfTuples();
1780 for(const mcIdType *z=bgComp;z!=endComp;z++)
1781 DataArray::CheckValueInRange(ToIdType(nbComp),*z,"invalid component id");
1782 T *pt(getPointer());
1783 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1784 for(const mcIdType *z=bgComp;z!=endComp;z++)
1786 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1787 pt[(std::size_t)(*w)*nbComp+(*z)]=a;
1792 * Copy all values from another DataArrayDouble (\a a) into specified tuples and
1793 * components of \a this array. Textual data is not copied.
1794 * The tuples to assign to are defined by a C array of indices.
1795 * The components to assign to are defined by three values similar to parameters of
1796 * the Python function \c range(\c start,\c stop,\c step).
1797 * There are two *modes of usage*:
1798 * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
1799 * of \a a is assigned to its own location within \a this array.
1800 * - If \a a includes one tuple, then all values of \a a are assigned to the specified
1801 * components of every specified tuple of \a this array. In this mode it is required
1802 * that \a a->getNumberOfComponents() equals to the number of specified components.
1804 * \param [in] a - the array to copy values from.
1805 * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
1806 * assign values of \a a to.
1807 * \param [in] endTuples - specifies the end of the array \a bgTuples, so that
1808 * pointer to a tuple index <em>(pi)</em> varies as this:
1809 * \a bgTuples <= \a pi < \a endTuples.
1810 * \param [in] bgComp - index of the first component of \a this array to assign to.
1811 * \param [in] endComp - index of the component before which the components to assign
1813 * \param [in] stepComp - index increment to get index of the next component to assign to.
1814 * \param [in] strictCompoCompare - this parameter is checked only in the first
1815 * *mode of usage*; if \a strictCompoCompare is \a true (default),
1816 * then \a a->getNumberOfComponents() must be equal
1817 * to the number of specified columns, else this is not required.
1818 * \throw If \a a is NULL.
1819 * \throw If \a a is not allocated.
1820 * \throw If \a this is not allocated.
1821 * \throw If any index of tuple given by \a bgTuples is out of a valid range for
1823 * \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
1824 * if <em> a->getNumberOfComponents()</em> is unequal to the number of components
1825 * defined by <em>(bgComp,endComp,stepComp)</em>.
1826 * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
1827 * <em> a->getNumberOfComponents()</em> is unequal to the number of components
1828 * defined by <em>(bgComp,endComp,stepComp)</em>.
1829 * \throw If parameters specifying components to assign to, do not give a
1830 * non-empty range of increasing indices or indices are out of a valid range
1831 * for \c this array.
1833 * \if ENABLE_EXAMPLES
1834 * \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
1838 void DataArrayTemplate<T>::setPartOfValues3(const typename Traits<T>::ArrayType *a, const mcIdType *bgTuples, const mcIdType *endTuples, mcIdType bgComp, mcIdType endComp, mcIdType stepComp, bool strictCompoCompare)
1841 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValues3 : input DataArrayDouble is NULL !");
1842 const char msg[]="DataArrayTemplate::setPartOfValues3";
1844 a->checkAllocated();
1845 mcIdType newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
1846 std::size_t nbComp(getNumberOfComponents());
1847 mcIdType nbOfTuples(getNumberOfTuples());
1848 DataArray::CheckValueInRangeEx(ToIdType(nbComp),bgComp,endComp,"invalid component value");
1849 mcIdType newNbOfTuples=ToIdType(std::distance(bgTuples,endTuples));
1850 bool assignTech=true;
1851 if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
1853 if(strictCompoCompare)
1854 a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1858 a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
1861 T *pt(getPointer()+bgComp);
1862 const T *srcPt(a->getConstPointer());
1865 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1866 for(mcIdType j=0;j<newNbOfComp;j++,srcPt++)
1868 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1869 pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
1874 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1876 const T *srcPt2=srcPt;
1877 for(mcIdType j=0;j<newNbOfComp;j++,srcPt2++)
1879 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1880 pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
1887 * Assign a given value to values at specified tuples and components of \a this array.
1888 * The tuples to assign to are defined by a C array of indices.
1889 * The components to assign to are defined by three values similar to parameters of
1890 * the Python function \c range(\c start,\c stop,\c step).
1891 * \param [in] a - the value to assign.
1892 * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
1894 * \param [in] endTuples - specifies the end of the array \a bgTuples, so that
1895 * pointer to a tuple index <em>(pi)</em> varies as this:
1896 * \a bgTuples <= \a pi < \a endTuples.
1897 * \param [in] bgComp - index of the first component of \a this array to assign to.
1898 * \param [in] endComp - index of the component before which the components to assign
1900 * \param [in] stepComp - index increment to get index of the next component to assign to.
1901 * \throw If \a this is not allocated.
1902 * \throw If any index of tuple given by \a bgTuples is out of a valid range for
1904 * \throw If parameters specifying components to assign to, do not give a
1905 * non-empty range of increasing indices or indices are out of a valid range
1906 * for \c this array.
1908 * \if ENABLE_EXAMPLES
1909 * \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
1913 void DataArrayTemplate<T>::setPartOfValuesSimple3(T a, const mcIdType *bgTuples, const mcIdType *endTuples, mcIdType bgComp, mcIdType endComp, mcIdType stepComp)
1915 const char msg[]="DataArrayTemplate::setPartOfValuesSimple3";
1917 std::size_t newNbOfComp(DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg));
1918 std::size_t nbComp(getNumberOfComponents());
1919 mcIdType nbOfTuples(getNumberOfTuples());
1920 DataArray::CheckValueInRangeEx(ToIdType(nbComp),bgComp,endComp,"invalid component value");
1921 T *pt(getPointer()+bgComp);
1922 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1923 for(std::size_t j=0;j<newNbOfComp;j++)
1925 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1926 pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
1931 * Copy all values from another DataArrayDouble into specified tuples and components
1932 * of \a this array. Textual data is not copied.
1933 * The tree parameters defining set of indices of tuples and components are similar to
1934 * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
1935 * \param [in] a - the array to copy values from.
1936 * \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
1937 * \param [in] endTuples - index of the tuple before which the tuples to assign to
1939 * \param [in] stepTuples - index increment to get index of the next tuple to assign to.
1940 * \param [in] bgComp - pointer to an array of component indices of \a this array to
1942 * \param [in] endComp - specifies the end of the array \a bgTuples, so that
1943 * pointer to a component index (\a pi) varies as this:
1944 * \a bgComp <= \a pi < \a endComp.
1945 * \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents()
1946 * must be equal to the number of columns to assign to, else an
1947 * exception is thrown; if \a false, then it is only required that \a
1948 * a->getNbOfElems() equals to number of values to assign to (this condition
1949 * must be respected even if \a strictCompoCompare is \a true). The number of
1950 * values to assign to is given by following Python expression:
1951 * \a nbTargetValues =
1952 * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
1953 * \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1954 * \throw If \a a is NULL.
1955 * \throw If \a a is not allocated.
1956 * \throw If \a this is not allocated.
1957 * \throw If parameters specifying tuples and components to assign to do not give a
1958 * non-empty range of increasing indices.
1959 * \throw If \a a->getNbOfElems() != \a nbTargetValues.
1960 * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
1961 * \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1965 void DataArrayTemplate<T>::setPartOfValues4(const typename Traits<T>::ArrayType *a, mcIdType bgTuples, mcIdType endTuples, mcIdType stepTuples, const mcIdType *bgComp, const mcIdType *endComp, bool strictCompoCompare)
1967 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValues4 : input DataArrayTemplate is NULL !");
1968 const char msg[]="DataArrayTemplate::setPartOfValues4";
1970 a->checkAllocated();
1971 mcIdType newNbOfTuples(DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg));
1972 std::size_t newNbOfComp(std::distance(bgComp,endComp));
1973 std::size_t nbComp(getNumberOfComponents());
1974 for(const mcIdType *z=bgComp;z!=endComp;z++)
1975 DataArray::CheckValueInRange(ToIdType(nbComp),*z,"invalid component id");
1976 mcIdType nbOfTuples(getNumberOfTuples());
1977 DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
1978 bool assignTech(true);
1979 if(a->getNbOfElems()==ToIdType(newNbOfTuples*newNbOfComp))
1981 if(strictCompoCompare)
1982 a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1986 a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
1989 const T *srcPt(a->getConstPointer());
1990 T *pt(getPointer()+bgTuples*nbComp);
1993 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1994 for(const mcIdType *z=bgComp;z!=endComp;z++,srcPt++)
1999 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2001 const T *srcPt2(srcPt);
2002 for(const mcIdType *z=bgComp;z!=endComp;z++,srcPt2++)
2009 void DataArrayTemplate<T>::setPartOfValuesSimple4(T a, mcIdType bgTuples, mcIdType endTuples, mcIdType stepTuples, const mcIdType *bgComp, const mcIdType *endComp)
2011 const char msg[]="DataArrayTemplate::setPartOfValuesSimple4";
2013 mcIdType newNbOfTuples(DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg));
2014 std::size_t nbComp(getNumberOfComponents());
2015 for(const mcIdType *z=bgComp;z!=endComp;z++)
2016 DataArray::CheckValueInRange(ToIdType(nbComp),*z,"invalid component id");
2017 mcIdType nbOfTuples(getNumberOfTuples());
2018 DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2019 T *pt=getPointer()+bgTuples*nbComp;
2020 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2021 for(const mcIdType *z=bgComp;z!=endComp;z++)
2026 * Copy some tuples from another DataArrayDouble into specified tuples
2027 * of \a this array. Textual data is not copied. Both arrays must have equal number of
2029 * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2030 * All components of selected tuples are copied.
2031 * \param [in] a - the array to copy values from.
2032 * \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2033 * target tuples of \a this. \a tuplesSelec has two components, and the
2034 * first component specifies index of the source tuple and the second
2035 * one specifies index of the target tuple.
2036 * \throw If \a this is not allocated.
2037 * \throw If \a a is NULL.
2038 * \throw If \a a is not allocated.
2039 * \throw If \a tuplesSelec is NULL.
2040 * \throw If \a tuplesSelec is not allocated.
2041 * \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2042 * \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2043 * \throw If any tuple index given by \a tuplesSelec is out of a valid range for
2044 * the corresponding (\a this or \a a) array.
2047 void DataArrayTemplate<T>::setPartOfValuesAdv(const typename Traits<T>::ArrayType *a, const DataArrayIdType *tuplesSelec)
2049 if(!a || !tuplesSelec)
2050 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValuesAdv : input DataArrayTemplate is NULL !");
2052 a->checkAllocated();
2053 tuplesSelec->checkAllocated();
2054 std::size_t nbOfComp(getNumberOfComponents());
2055 if(nbOfComp!=a->getNumberOfComponents())
2056 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValuesAdv : This and a do not have the same number of components !");
2057 if(tuplesSelec->getNumberOfComponents()!=2)
2058 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2059 mcIdType thisNt(getNumberOfTuples());
2060 mcIdType aNt(a->getNumberOfTuples());
2061 T *valsToSet(getPointer());
2062 const T *valsSrc(a->getConstPointer());
2063 for(const mcIdType *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2065 if(tuple[1]>=0 && tuple[1]<aNt)
2067 if(tuple[0]>=0 && tuple[0]<thisNt)
2068 std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2071 std::ostringstream oss; oss << "DataArrayTemplate::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2072 oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2073 throw INTERP_KERNEL::Exception(oss.str().c_str());
2078 std::ostringstream oss; oss << "DataArrayTemplate::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2079 oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2080 throw INTERP_KERNEL::Exception(oss.str().c_str());
2086 * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2087 * of \a this array. Textual data is not copied. Both arrays must have equal number of
2089 * The tuples to assign to are defined by index of the first tuple, and
2090 * their number is defined by \a tuplesSelec->getNumberOfTuples().
2091 * The tuples to copy are defined by values of a DataArrayInt.
2092 * All components of selected tuples are copied.
2093 * \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2095 * \param [in] aBase - the array to copy values from.
2096 * \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2097 * \throw If \a this is not allocated.
2098 * \throw If \a aBase is NULL.
2099 * \throw If \a aBase is not allocated.
2100 * \throw If \a tuplesSelec is NULL.
2101 * \throw If \a tuplesSelec is not allocated.
2102 * \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2103 * \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2104 * \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2105 * \throw If any tuple index given by \a tuplesSelec is out of a valid range for
2109 void DataArrayTemplate<T>::setContigPartOfSelectedValues(mcIdType tupleIdStart, const DataArray *aBase, const DataArrayIdType *tuplesSelec)
2111 if(!aBase || !tuplesSelec)
2112 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : input DataArray is NULL !");
2113 const typename Traits<T>::ArrayType *a(dynamic_cast<const typename Traits<T>::ArrayType *>(aBase));
2115 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2117 a->checkAllocated();
2118 tuplesSelec->checkAllocated();
2119 std::size_t nbOfComp(getNumberOfComponents());
2120 if(nbOfComp!=a->getNumberOfComponents())
2121 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2122 if(tuplesSelec->getNumberOfComponents()!=1)
2123 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2124 mcIdType thisNt(getNumberOfTuples());
2125 mcIdType aNt(a->getNumberOfTuples());
2126 mcIdType nbOfTupleToWrite(tuplesSelec->getNumberOfTuples());
2127 T *valsToSet(getPointer()+tupleIdStart*nbOfComp);
2128 if(tupleIdStart+nbOfTupleToWrite>thisNt)
2129 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : invalid number range of values to write !");
2130 const T *valsSrc=a->getConstPointer();
2131 for(const mcIdType *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2133 if(*tuple>=0 && *tuple<aNt)
2135 std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2139 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2140 oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2141 throw INTERP_KERNEL::Exception(oss.str().c_str());
2147 * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2148 * of \a this array. Textual data is not copied. Both arrays must have equal number of
2150 * The tuples to copy are defined by three values similar to parameters of
2151 * the Python function \c range(\c start,\c stop,\c step).
2152 * The tuples to assign to are defined by index of the first tuple, and
2153 * their number is defined by number of tuples to copy.
2154 * All components of selected tuples are copied.
2155 * \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2157 * \param [in] aBase - the array to copy values from.
2158 * \param [in] bg - index of the first tuple to copy of the array \a aBase.
2159 * \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2161 * \param [in] step - index increment to get index of the next tuple to copy.
2162 * \throw If \a this is not allocated.
2163 * \throw If \a aBase is NULL.
2164 * \throw If \a aBase is not allocated.
2165 * \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2166 * \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2167 * \throw If parameters specifying tuples to copy, do not give a
2168 * non-empty range of increasing indices or indices are out of a valid range
2169 * for the array \a aBase.
2172 void DataArrayTemplate<T>::setContigPartOfSelectedValuesSlice(mcIdType tupleIdStart, const DataArray *aBase, mcIdType bg, mcIdType end2, mcIdType step)
2176 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::setContigPartOfSelectedValuesSlice : input DataArray is NULL !";
2177 throw INTERP_KERNEL::Exception(oss.str().c_str());
2179 const typename Traits<T>::ArrayType *a(dynamic_cast<const typename Traits<T>::ArrayType *>(aBase));
2181 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValuesSlice : input DataArray aBase is not a DataArrayDouble !");
2183 a->checkAllocated();
2184 std::size_t nbOfComp(getNumberOfComponents());
2185 const char msg[]="DataArrayDouble::setContigPartOfSelectedValuesSlice";
2186 mcIdType nbOfTupleToWrite(DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg));
2187 if(nbOfComp!=a->getNumberOfComponents())
2188 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValuesSlice : This and a do not have the same number of components !");
2189 mcIdType thisNt(getNumberOfTuples());
2190 mcIdType aNt(a->getNumberOfTuples());
2191 T *valsToSet(getPointer()+tupleIdStart*nbOfComp);
2192 if(tupleIdStart+nbOfTupleToWrite>thisNt)
2193 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValuesSlice : invalid number range of values to write !");
2195 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValuesSlice : invalid range of values to read !");
2196 const T *valsSrc(a->getConstPointer()+bg*nbOfComp);
2197 for(mcIdType i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2199 std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2204 * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
2205 * of tuples specified by \a ranges parameter.
2206 * For more info on renumbering see \ref numbering.
2207 * \param [in] ranges - std::vector of std::pair's each of which defines a range
2208 * of tuples in [\c begin,\c end) format.
2209 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2210 * is to delete using decrRef() as it is no more needed.
2211 * \throw If \a end < \a begin.
2212 * \throw If \a end > \a this->getNumberOfTuples().
2213 * \throw If \a this is not allocated.
2216 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleRanges(const std::vector<std::pair<mcIdType,mcIdType> >& ranges) const
2219 std::size_t nbOfComp(getNumberOfComponents());
2220 mcIdType nbOfTuplesThis(getNumberOfTuples());
2223 MCAuto<DataArray> ret0(buildNewEmptyInstance());
2224 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
2225 ret->alloc(0,nbOfComp);
2226 ret->copyStringInfoFrom(*this);
2229 mcIdType ref(ranges.front().first),nbOfTuples(0);
2230 bool isIncreasing(true);
2231 for(std::vector<std::pair<mcIdType,mcIdType> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
2233 if((*it).first<=(*it).second)
2235 if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
2237 nbOfTuples+=(*it).second-(*it).first;
2239 isIncreasing=ref<=(*it).first;
2244 std::ostringstream oss; oss << "DataArrayTemplate::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
2245 oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
2246 throw INTERP_KERNEL::Exception(oss.str().c_str());
2251 std::ostringstream oss; oss << "DataArrayTemplate::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
2252 oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
2253 throw INTERP_KERNEL::Exception(oss.str().c_str());
2256 if(isIncreasing && nbOfTuplesThis==nbOfTuples)
2257 return static_cast<typename Traits<T>::ArrayType *>(deepCopy());
2258 MCAuto<DataArray> ret0(buildNewEmptyInstance());
2259 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
2260 ret->alloc(nbOfTuples,nbOfComp);
2261 ret->copyStringInfoFrom(*this);
2262 const T *src(getConstPointer());
2263 T *work(ret->getPointer());
2264 for(std::vector<std::pair<mcIdType,mcIdType> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
2265 work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
2270 * Returns the first value of \a this.
2271 * \return double - the last value of \a this array.
2272 * \throw If \a this is not allocated.
2273 * \throw If \a this->getNumberOfComponents() != 1.
2274 * \throw If \a this->getNumberOfTuples() < 1.
2277 T DataArrayTemplate<T>::front() const
2280 if(getNumberOfComponents()!=1)
2281 throw INTERP_KERNEL::Exception("DataArrayTemplate::front : number of components not equal to one !");
2282 mcIdType nbOfTuples=getNumberOfTuples();
2284 throw INTERP_KERNEL::Exception("DataArrayTemplate::front : number of tuples must be >= 1 !");
2285 return *(getConstPointer());
2289 * Returns the last value of \a this.
2290 * \return double - the last value of \a this array.
2291 * \throw If \a this is not allocated.
2292 * \throw If \a this->getNumberOfComponents() != 1.
2293 * \throw If \a this->getNumberOfTuples() < 1.
2296 T DataArrayTemplate<T>::back() const
2299 if(getNumberOfComponents()!=1)
2300 throw INTERP_KERNEL::Exception("DataArrayTemplate::back : number of components not equal to one !");
2301 mcIdType nbOfTuples=getNumberOfTuples();
2303 throw INTERP_KERNEL::Exception("DataArrayTemplate::back : number of tuples must be >= 1 !");
2304 return *(getConstPointer()+nbOfTuples-1);
2308 * Returns the maximal value and its location within \a this one-dimensional array.
2309 * \param [out] tupleId - index of the tuple holding the maximal value.
2310 * \return double - the maximal value among all values of \a this array.
2311 * \throw If \a this->getNumberOfComponents() != 1
2312 * \throw If \a this->getNumberOfTuples() < 1
2313 * \sa getMaxAbsValue, getMinValue
2316 T DataArrayTemplate<T>::getMaxValue(mcIdType& tupleId) const
2319 if(getNumberOfComponents()!=1)
2320 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 !");
2321 mcIdType nbOfTuples=getNumberOfTuples();
2323 throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
2324 const T *vals(getConstPointer());
2325 const T *loc(std::max_element(vals,vals+nbOfTuples));
2326 tupleId=ToIdType(std::distance(vals,loc));
2331 * Returns the maximal value within \a this array that is allowed to have more than
2333 * \return double - the maximal value among all values of \a this array.
2334 * \throw If \a this is not allocated.
2335 * \sa getMaxAbsValueInArray, getMinValueInArray
2338 T DataArrayTemplate<T>::getMaxValueInArray() const
2341 const T *loc(std::max_element(begin(),end()));
2346 * Returns the maximal absolute value in \a this and the first occurrence location associated to it.
2347 * \return the element in this (positive or negative) having the max abs value in \a this.
2348 * \throw If \a this is not allocated.
2349 * \throw If \a this is non one component array.
2350 * \throw If \a this is empty.
2353 T DataArrayTemplate<T>::getMaxAbsValue(std::size_t& tupleId) const
2356 if(getNumberOfComponents()!=1)
2357 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 !");
2358 mcIdType nbTuples(this->getNumberOfTuples());
2360 throw INTERP_KERNEL::Exception("DataArrayTemplate<T>::getMaxAbsValue : empty array !");
2363 const T *pt(begin());
2364 for(mcIdType i=0;i<nbTuples;i++,pt++)
2366 T cand((T)std::abs(*pt));
2373 return this->getIJ(ToIdType(tupleId),0);
2377 * Returns the maximal absolute value in \a this.
2378 * \throw If \a this is not allocated.
2379 * \throw If \a this is non one component array.
2380 * \throw If \a this is empty.
2383 T DataArrayTemplate<T>::getMaxAbsValueInArray() const
2386 return getMaxAbsValue(dummy);
2390 * Returns the minimal value and its location within \a this one-dimensional array.
2391 * \param [out] tupleId - index of the tuple holding the minimal value.
2392 * \return double - the minimal value among all values of \a this array.
2393 * \throw If \a this->getNumberOfComponents() != 1
2394 * \throw If \a this->getNumberOfTuples() < 1
2397 T DataArrayTemplate<T>::getMinValue(mcIdType& tupleId) const
2400 if(getNumberOfComponents()!=1)
2401 throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
2402 mcIdType nbOfTuples=getNumberOfTuples();
2404 throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
2405 const T *vals(getConstPointer());
2406 const T *loc(std::min_element(vals,vals+nbOfTuples));
2407 tupleId=ToIdType(std::distance(vals,loc));
2412 * Returns the minimal value within \a this array that is allowed to have more than
2414 * \return double - the minimal value among all values of \a this array.
2415 * \throw If \a this is not allocated.
2418 T DataArrayTemplate<T>::getMinValueInArray() const
2421 const T *loc=std::min_element(begin(),end());
2426 void DataArrayTemplate<T>::circularPermutation(mcIdType nbOfShift)
2429 std::size_t nbOfCompo(getNumberOfComponents());
2430 mcIdType nbTuples(getNumberOfTuples());
2431 mcIdType effNbSh(EffectiveCircPerm(nbOfShift,nbTuples));
2434 T *work(getPointer());
2435 if(effNbSh<nbTuples-effNbSh)
2437 typename INTERP_KERNEL::AutoPtr<T> buf(new T[effNbSh*nbOfCompo]);
2438 std::copy(work,work+effNbSh*nbOfCompo,(T *)buf);
2439 std::copy(work+effNbSh*nbOfCompo,work+nbTuples*nbOfCompo,work);// ze big shift
2440 std::copy((T *)buf,(T *)buf+effNbSh*nbOfCompo,work+(nbTuples-effNbSh)*nbOfCompo);
2444 typename INTERP_KERNEL::AutoPtr<T> buf(new T[(nbTuples-effNbSh)*nbOfCompo]);
2445 std::copy(work+effNbSh*nbOfCompo,work+nbTuples*nbOfCompo,(T *)buf);
2446 std::copy(work,work+effNbSh*nbOfCompo,work+(nbTuples-effNbSh)*nbOfCompo);// ze big shift
2447 std::copy((T*)buf,(T *)buf+(nbTuples-effNbSh)*nbOfCompo,work);
2452 void DataArrayTemplate<T>::circularPermutationPerTuple(mcIdType nbOfShift)
2455 std::size_t nbOfCompo(getNumberOfComponents());
2456 mcIdType nbTuples(getNumberOfTuples());
2457 mcIdType effNbSh(EffectiveCircPerm(nbOfShift,ToIdType(nbOfCompo)));
2460 T *work(getPointer());
2461 if(effNbSh<ToIdType(nbOfCompo)-effNbSh)
2463 typename INTERP_KERNEL::AutoPtr<T> buf(new T[effNbSh]);
2464 for(mcIdType i=0;i<nbTuples;i++,work+=nbOfCompo)
2466 std::copy(work,work+effNbSh,(T *)buf);
2467 std::copy(work+effNbSh,work+nbOfCompo,work);// ze big shift
2468 std::copy((T *)buf,(T *)buf+effNbSh,work+(nbOfCompo-effNbSh));
2473 typename INTERP_KERNEL::AutoPtr<T> buf(new T[nbOfCompo-effNbSh]);
2474 for(mcIdType i=0;i<nbTuples;i++,work+=nbOfCompo)
2476 std::copy(work+effNbSh,work+nbOfCompo,(T *)buf);
2477 std::copy(work,work+effNbSh,work+(nbOfCompo-effNbSh));// ze big shift
2478 std::copy((T*)buf,(T *)buf+(nbOfCompo-effNbSh),work);
2481 std::vector<std::string> sts(nbOfCompo);
2482 for(std::size_t i=0;i<nbOfCompo;i++)
2483 sts[i]=_info_on_compo[(i+effNbSh)%nbOfCompo];
2484 setInfoOnComponents(sts);
2488 void DataArrayTemplate<T>::reversePerTuple()
2491 std::size_t nbOfCompo(getNumberOfComponents());
2492 mcIdType nbTuples(getNumberOfTuples());
2495 T *work(getPointer());
2496 for(mcIdType i=0;i<nbTuples;i++,work+=nbOfCompo)
2497 std::reverse(work,work+nbOfCompo);
2498 std::reverse(_info_on_compo.begin(),_info_on_compo.end());
2502 * Assign pointer to one array to a pointer to another appay. Reference counter of
2503 * \a arrayToSet is incremented / decremented.
2504 * \param [in] newArray - the pointer to array to assign to \a arrayToSet.
2505 * \param [in,out] arrayToSet - the pointer to array to assign to.
2508 void DataArrayTemplate<T>::SetArrayIn(typename Traits<T>::ArrayType *newArray, typename Traits<T>::ArrayType* &arrayToSet)
2510 if(newArray!=arrayToSet)
2513 arrayToSet->decrRef();
2514 arrayToSet=newArray;
2516 arrayToSet->incrRef();
2521 * Assign zero to all values in \a this array. To know more on filling arrays see
2522 * \ref MEDCouplingArrayFill.
2523 * \throw If \a this is not allocated.
2526 void DataArrayTemplate<T>::fillWithZero()
2528 fillWithValue((T)0);
2531 //////////////////////////////
2535 // local static function to copy arrays without warnings
2536 template <class TIn, class TOut>
2537 static void copyCast (const TIn *begin, const TIn *end, TOut* dest)
2539 for (const TIn *src = begin; src != end; ++src, ++dest)
2540 *dest=static_cast<TOut>(*src);
2546 MCAuto< typename Traits<U>::ArrayType > DataArrayTemplateClassic<T>::convertToOtherTypeOfArr() const
2548 this->checkAllocated();
2549 MCAuto<typename Traits<U>::ArrayType> ret(Traits<U>::ArrayType::New());
2550 ret->alloc(this->getNumberOfTuples(),this->getNumberOfComponents());
2551 std::size_t nbOfVals(this->getNbOfElems());
2552 const T *src(this->begin());
2553 U *dest(ret->getPointer());
2554 // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
2555 copyCast(src, src+nbOfVals, dest);
2556 //std::copy(src,src+nbOfVals,dest);
2557 ret->copyStringInfoFrom(*this);
2562 * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
2563 * array to the new one.
2564 * \return DataArrayDouble * - the new instance of DataArrayInt.
2567 MCAuto<DataArrayDouble> DataArrayTemplateClassic<T>::convertToDblArr() const
2569 return convertToOtherTypeOfArr<double>();
2573 * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
2574 * array to the new one.
2575 * \return DataArrayInt * - the new instance of DataArrayInt.
2578 MCAuto<DataArrayInt> DataArrayTemplateClassic<T>::convertToIntArr() const
2580 return convertToOtherTypeOfArr<int>();
2584 * Creates a new DataArrayFloat and assigns all (textual and numerical) data of \a this
2585 * array to the new one.
2586 * \return DataArrayFloat * - the new instance of DataArrayInt.
2589 MCAuto<DataArrayFloat> DataArrayTemplateClassic<T>::convertToFloatArr() const
2591 return convertToOtherTypeOfArr<float>();
2595 * Apply a linear function to a given component of \a this array, so that
2596 * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
2597 * \param [in] a - the first coefficient of the function.
2598 * \param [in] b - the second coefficient of the function.
2599 * \param [in] compoId - the index of component to modify.
2600 * \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
2603 void DataArrayTemplateClassic<T>::applyLin(T a, T b, std::size_t compoId)
2605 this->checkAllocated();
2606 std::size_t nbOfComp=this->getNumberOfComponents();
2607 if(compoId>=nbOfComp)
2609 std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
2610 throw INTERP_KERNEL::Exception(oss.str().c_str());
2612 T *ptr(this->getPointer()+compoId);
2613 mcIdType nbOfTuple=this->getNumberOfTuples();
2614 for(mcIdType i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
2616 this->declareAsNew();
2620 * Apply a linear function to all elements of \a this array, so that
2621 * an element _x_ becomes \f$ a * x + b \f$.
2622 * \param [in] a - the first coefficient of the function.
2623 * \param [in] b - the second coefficient of the function.
2624 * \throw If \a this is not allocated.
2627 void DataArrayTemplateClassic<T>::applyLin(T a, T b)
2629 this->checkAllocated();
2630 T *ptr(this->getPointer());
2631 std::size_t nbOfElems(this->getNbOfElems());
2632 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2634 this->declareAsNew();
2638 * Returns a full copy of \a this array except that sign of all elements is reversed.
2639 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2640 * same number of tuples and component as \a this array.
2641 * The caller is to delete this result array using decrRef() as it is no more
2643 * \throw If \a this is not allocated.
2646 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::negate() const
2648 this->checkAllocated();
2649 MCAuto<typename Traits<T>::ArrayType> newArr(Traits<T>::ArrayType::New());
2650 mcIdType nbOfTuples(this->getNumberOfTuples());
2651 std::size_t nbOfComp(this->getNumberOfComponents());
2652 newArr->alloc(nbOfTuples,nbOfComp);
2653 const T *cptr(this->begin());
2654 std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<T>());
2655 newArr->copyStringInfoFrom(*this);
2656 return newArr.retn();
2661 void DataArrayTemplateClassic<T>::somethingEqual(const typename Traits<T>::ArrayType *other)
2664 throw INTERP_KERNEL::Exception("DataArray<T>::SomethingEqual : input DataArray<T> instance is NULL !");
2665 const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
2666 this->checkAllocated();
2667 other->checkAllocated();
2668 mcIdType nbOfTuple(this->getNumberOfTuples());
2669 mcIdType nbOfTuple2(other->getNumberOfTuples());
2670 std::size_t nbOfComp(this->getNumberOfComponents());
2671 std::size_t nbOfComp2(other->getNumberOfComponents());
2672 if(nbOfTuple==nbOfTuple2)
2674 if(nbOfComp==nbOfComp2)
2676 std::transform(this->begin(),this->end(),other->begin(),this->getPointer(),FCT());
2678 else if(nbOfComp2==1)
2680 T *ptr(this->getPointer());
2681 const T *ptrc(other->begin());
2682 for(mcIdType i=0;i<nbOfTuple;i++)
2683 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(FCT(),*ptrc++));
2686 throw INTERP_KERNEL::Exception(msg);
2688 else if(nbOfTuple2==1)
2690 if(nbOfComp2==nbOfComp)
2692 T *ptr(this->getPointer());
2693 const T *ptrc(other->begin());
2694 for(mcIdType i=0;i<nbOfTuple;i++)
2695 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,FCT());
2698 throw INTERP_KERNEL::Exception(msg);
2701 throw INTERP_KERNEL::Exception(msg);
2702 this->declareAsNew();
2706 * Adds values of another DataArrayDouble to values of \a this one. There are 3
2708 * 1. The arrays have same number of tuples and components. Then each value of
2709 * \a other array is added to the corresponding value of \a this array, i.e.:
2710 * _a_ [ i, j ] += _other_ [ i, j ].
2711 * 2. The arrays have same number of tuples and \a other array has one component. Then
2712 * _a_ [ i, j ] += _other_ [ i, 0 ].
2713 * 3. The arrays have same number of components and \a other array has one tuple. Then
2714 * _a_ [ i, j ] += _a2_ [ 0, j ].
2716 * \param [in] other - an array to add to \a this one.
2717 * \throw If \a other is NULL.
2718 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
2719 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
2720 * \a other has number of both tuples and components not equal to 1.
2723 void DataArrayTemplateClassic<T>::addEqual(const typename Traits<T>::ArrayType *other)
2725 this->somethingEqual< std::plus<T> >(other);
2729 * Subtract values of another DataArrayDouble from values of \a this one. There are 3
2731 * 1. The arrays have same number of tuples and components. Then each value of
2732 * \a other array is subtracted from the corresponding value of \a this array, i.e.:
2733 * _a_ [ i, j ] -= _other_ [ i, j ].
2734 * 2. The arrays have same number of tuples and \a other array has one component. Then
2735 * _a_ [ i, j ] -= _other_ [ i, 0 ].
2736 * 3. The arrays have same number of components and \a other array has one tuple. Then
2737 * _a_ [ i, j ] -= _a2_ [ 0, j ].
2739 * \param [in] other - an array to subtract from \a this one.
2740 * \throw If \a other is NULL.
2741 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
2742 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
2743 * \a other has number of both tuples and components not equal to 1.
2746 void DataArrayTemplateClassic<T>::substractEqual(const typename Traits<T>::ArrayType *other)
2748 this->somethingEqual< std::minus<T> >(other);
2752 * Multiply values of another DataArrayDouble to values of \a this one. There are 3
2754 * 1. The arrays have same number of tuples and components. Then each value of
2755 * \a other array is multiplied to the corresponding value of \a this array, i.e.
2756 * _this_ [ i, j ] *= _other_ [ i, j ].
2757 * 2. The arrays have same number of tuples and \a other array has one component. Then
2758 * _this_ [ i, j ] *= _other_ [ i, 0 ].
2759 * 3. The arrays have same number of components and \a other array has one tuple. Then
2760 * _this_ [ i, j ] *= _a2_ [ 0, j ].
2762 * \param [in] other - an array to multiply to \a this one.
2763 * \throw If \a other is NULL.
2764 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
2765 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
2766 * \a other has number of both tuples and components not equal to 1.
2769 void DataArrayTemplateClassic<T>::multiplyEqual(const typename Traits<T>::ArrayType *other)
2771 this->somethingEqual< std::multiplies<T> >(other);
2775 * Divide values of \a this array by values of another DataArrayDouble. There are 3
2777 * 1. The arrays have same number of tuples and components. Then each value of
2778 * \a this array is divided by the corresponding value of \a other one, i.e.:
2779 * _a_ [ i, j ] /= _other_ [ i, j ].
2780 * 2. The arrays have same number of tuples and \a other array has one component. Then
2781 * _a_ [ i, j ] /= _other_ [ i, 0 ].
2782 * 3. The arrays have same number of components and \a other array has one tuple. Then
2783 * _a_ [ i, j ] /= _a2_ [ 0, j ].
2785 * \warning No check of division by zero is performed!
2786 * \param [in] other - an array to divide \a this one by.
2787 * \throw If \a other is NULL.
2788 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
2789 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
2790 * \a other has number of both tuples and components not equal to 1.
2793 void DataArrayTemplateClassic<T>::divideEqual(const typename Traits<T>::ArrayType *other)
2795 this->somethingEqual< std::divides<T> >(other);
2798 template<class T, class FCT>
2799 typename Traits<T>::ArrayType *DivSub(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
2802 throw INTERP_KERNEL::Exception("DivSub : input DataArrayDouble instance is NULL !");
2803 mcIdType nbOfTuple1(a1->getNumberOfTuples());
2804 mcIdType nbOfTuple2(a2->getNumberOfTuples());
2805 std::size_t nbOfComp1(a1->getNumberOfComponents());
2806 std::size_t nbOfComp2(a2->getNumberOfComponents());
2807 if(nbOfTuple2==nbOfTuple1)
2809 if(nbOfComp1==nbOfComp2)
2811 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
2812 ret->alloc(nbOfTuple2,nbOfComp1);
2813 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),FCT());
2814 ret->copyStringInfoFrom(*a1);
2817 else if(nbOfComp2==1)
2819 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
2820 ret->alloc(nbOfTuple1,nbOfComp1);
2821 const T *a2Ptr(a2->begin()),*a1Ptr(a1->begin());
2822 T *res(ret->getPointer());
2823 for(mcIdType i=0;i<nbOfTuple1;i++)
2824 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(FCT(),a2Ptr[i]));
2825 ret->copyStringInfoFrom(*a1);
2830 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
2834 else if(nbOfTuple2==1)
2836 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
2837 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
2838 ret->alloc(nbOfTuple1,nbOfComp1);
2839 const T *a1ptr=a1->begin(),*a2ptr(a2->begin());
2840 T *pt(ret->getPointer());
2841 for(mcIdType i=0;i<nbOfTuple1;i++)
2842 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,FCT());
2843 ret->copyStringInfoFrom(*a1);
2848 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
2854 * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
2856 * 1. The arrays have same number of tuples and components. Then each value of
2857 * the result array (_a_) is a subtraction of the corresponding values of \a a1 and
2858 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
2859 * 2. The arrays have same number of tuples and one array, say _a2_, has one
2861 * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
2862 * 3. The arrays have same number of components and one array, say _a2_, has one
2864 * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
2866 * Info on components is copied either from the first array (in the first case) or from
2867 * the array with maximal number of elements (getNbOfElems()).
2868 * \param [in] a1 - an array to subtract from.
2869 * \param [in] a2 - an array to subtract.
2870 * \return DataArrayDouble * - the new instance of DataArrayDouble.
2871 * The caller is to delete this result array using decrRef() as it is no more
2873 * \throw If either \a a1 or \a a2 is NULL.
2874 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
2875 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
2876 * none of them has number of tuples or components equal to 1.
2879 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Substract(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
2881 return DivSub< T,std::minus<T> >(a1,a2);
2885 * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
2887 * 1. The arrays have same number of tuples and components. Then each value of
2888 * the result array (_a_) is a division of the corresponding values of \a a1 and
2889 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
2890 * 2. The arrays have same number of tuples and one array, say _a2_, has one
2892 * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
2893 * 3. The arrays have same number of components and one array, say _a2_, has one
2895 * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
2897 * Info on components is copied either from the first array (in the first case) or from
2898 * the array with maximal number of elements (getNbOfElems()).
2899 * \warning No check of division by zero is performed!
2900 * \param [in] a1 - a numerator array.
2901 * \param [in] a2 - a denominator array.
2902 * \return DataArrayDouble * - the new instance of DataArrayDouble.
2903 * The caller is to delete this result array using decrRef() as it is no more
2905 * \throw If either \a a1 or \a a2 is NULL.
2906 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
2907 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
2908 * none of them has number of tuples or components equal to 1.
2911 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Divide(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
2913 return DivSub< T,std::divides<T> >(a1,a2);
2916 template<class T, class FCT>
2917 typename Traits<T>::ArrayType *MulAdd(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
2920 throw INTERP_KERNEL::Exception("DataArrayDouble::MulAdd : input DataArrayDouble instance is NULL !");
2921 mcIdType nbOfTuple(a1->getNumberOfTuples());
2922 mcIdType nbOfTuple2(a2->getNumberOfTuples());
2923 std::size_t nbOfComp(a1->getNumberOfComponents());
2924 std::size_t nbOfComp2(a2->getNumberOfComponents());
2925 MCAuto<typename Traits<T>::ArrayType> ret=0;
2926 if(nbOfTuple==nbOfTuple2)
2928 if(nbOfComp==nbOfComp2)
2930 ret=Traits<T>::ArrayType::New();
2931 ret->alloc(nbOfTuple,nbOfComp);
2932 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),FCT());
2933 ret->copyStringInfoFrom(*a1);
2937 std::size_t nbOfCompMin,nbOfCompMax;
2938 const typename Traits<T>::ArrayType *aMin, *aMax;
2939 if(nbOfComp>nbOfComp2)
2941 nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
2946 nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
2951 ret=Traits<T>::ArrayType::New();
2952 ret->alloc(nbOfTuple,nbOfCompMax);
2953 const T *aMinPtr(aMin->begin());
2954 const T *aMaxPtr(aMax->begin());
2955 T *res=ret->getPointer();
2956 for(mcIdType i=0;i<nbOfTuple;i++)
2957 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(FCT(),aMinPtr[i]));
2958 ret->copyStringInfoFrom(*aMax);
2961 throw INTERP_KERNEL::Exception("Nb of components mismatch for array MulAdd !");
2964 else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
2966 if(nbOfComp==nbOfComp2)
2968 mcIdType nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
2969 const typename Traits<T>::ArrayType *aMin(nbOfTuple>nbOfTuple2?a2:a1);
2970 const typename Traits<T>::ArrayType *aMax(nbOfTuple>nbOfTuple2?a1:a2);
2971 const T *aMinPtr(aMin->begin()),*aMaxPtr(aMax->begin());
2972 ret=Traits<T>::ArrayType::New();
2973 ret->alloc(nbOfTupleMax,nbOfComp);
2974 T *res(ret->getPointer());
2975 for(mcIdType i=0;i<nbOfTupleMax;i++)
2976 res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,FCT());
2977 ret->copyStringInfoFrom(*aMax);
2980 throw INTERP_KERNEL::Exception("Nb of components mismatch for array MulAdd !");
2983 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array MulAdd !");
2988 * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
2990 * 1. The arrays have same number of tuples and components. Then each value of
2991 * the result array (_a_) is a product of the corresponding values of \a a1 and
2992 * \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
2993 * 2. The arrays have same number of tuples and one array, say _a2_, has one
2995 * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
2996 * 3. The arrays have same number of components and one array, say _a2_, has one
2998 * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
3000 * Info on components is copied either from the first array (in the first case) or from
3001 * the array with maximal number of elements (getNbOfElems()).
3002 * \param [in] a1 - a factor array.
3003 * \param [in] a2 - another factor array.
3004 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3005 * The caller is to delete this result array using decrRef() as it is no more
3007 * \throw If either \a a1 or \a a2 is NULL.
3008 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3009 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3010 * none of them has number of tuples or components equal to 1.
3013 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Multiply(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
3015 return MulAdd< T , std::multiplies<T> >(a1,a2);
3019 * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
3021 * 1. The arrays have same number of tuples and components. Then each value of
3022 * the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
3023 * i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
3024 * 2. The arrays have same number of tuples and one array, say _a2_, has one
3026 * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
3027 * 3. The arrays have same number of components and one array, say _a2_, has one
3029 * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
3031 * Info on components is copied either from the first array (in the first case) or from
3032 * the array with maximal number of elements (getNbOfElems()).
3033 * \param [in] a1 - an array to sum up.
3034 * \param [in] a2 - another array to sum up.
3035 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3036 * The caller is to delete this result array using decrRef() as it is no more
3038 * \throw If either \a a1 or \a a2 is NULL.
3039 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3040 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3041 * none of them has number of tuples or components equal to 1.
3044 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Add(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
3046 return MulAdd< T , std::plus<T> >(a1,a2);
3050 * Returns either a \a deep or \a shallow copy of this array. For more info see
3051 * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
3052 * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
3053 * \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
3054 * == \a true) or \a this instance (if \a dCpy == \a false).
3057 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::PerformCopyOrIncrRef(bool dCpy, const typename Traits<T>::ArrayType& self)
3060 return self.deepCopy();
3064 return const_cast<typename Traits<T>::ArrayType *>(&self);
3071 GreatEqual(T v):_v(v) { }
3072 bool operator()(T v) const { return v>=_v; }
3079 GreaterThan(T v):_v(v) { }
3080 bool operator()(T v) const { return v>_v; }
3087 LowerEqual(T v):_v(v) { }
3088 bool operator()(T v) const { return v<=_v; }
3095 LowerThan(T v):_v(v) { }
3096 bool operator()(T v) const { return v<_v; }
3103 InRange(T a, T b):_a(a),_b(b) { }
3104 bool operator()(T v) const { return v>=_a && v<_b; }
3111 NotInRange(T a, T b):_a(a),_b(b) { }
3112 bool operator()(T v) const { return v<_a || v>=_b; }
3117 * 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.
3119 * \return a newly allocated data array that the caller should deal with.
3120 * \sa DataArrayInt::findIdsInRange
3123 DataArrayIdType *DataArrayTemplateClassic<T>::findIdsStrictlyNegative() const
3125 LowerThan<T> lt((T)0);
3126 MCAuto<DataArrayIdType> ret(findIdsAdv(lt));
3131 MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsGreaterOrEqualTo(T val) const
3133 GreatEqual<T> ge(val);
3134 return findIdsAdv(ge);
3138 MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsGreaterThan(T val) const
3140 GreaterThan<T> gt(val);
3141 return findIdsAdv(gt);
3145 MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsLowerOrEqualTo(T val) const
3147 LowerEqual<T> le(val);
3148 return findIdsAdv(le);
3152 MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsLowerThan(T val) const
3154 LowerThan<T> lt(val);
3155 return findIdsAdv(lt);
3159 * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
3160 * of components in the result array is a sum of the number of components of given arrays
3161 * and (2) the number of tuples in the result array is same as that of each of given
3162 * arrays. In other words the i-th tuple of result array includes all components of
3163 * i-th tuples of all given arrays.
3164 * Number of tuples in the given arrays must be the same.
3165 * \param [in] a1 - an array to include in the result array.
3166 * \param [in] a2 - another array to include in the result array.
3167 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3168 * The caller is to delete this result array using decrRef() as it is no more
3170 * \throw If both \a a1 and \a a2 are NULL.
3171 * \throw If any given array is not allocated.
3172 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3175 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Meld(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
3177 std::vector<const typename Traits<T>::ArrayType *> arr(2);
3178 arr[0]=a1; arr[1]=a2;
3183 * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
3184 * of components in the result array is a sum of the number of components of given arrays
3185 * and (2) the number of tuples in the result array is same as that of each of given
3186 * arrays. In other words the i-th tuple of result array includes all components of
3187 * i-th tuples of all given arrays.
3188 * Number of tuples in the given arrays must be the same.
3189 * \param [in] arr - a sequence of arrays to include in the result array.
3190 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3191 * The caller is to delete this result array using decrRef() as it is no more
3193 * \throw If all arrays within \a arr are NULL.
3194 * \throw If any given array is not allocated.
3195 * \throw If getNumberOfTuples() of arrays within \a arr is different.
3198 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Meld(const std::vector<const typename Traits<T>::ArrayType *>& arr)
3200 std::vector<const typename Traits<T>::ArrayType *> a;
3201 for(typename std::vector<const typename Traits<T>::ArrayType *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3205 throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
3206 typename std::vector<const typename Traits<T>::ArrayType *>::const_iterator it;
3207 for(it=a.begin();it!=a.end();it++)
3208 (*it)->checkAllocated();
3210 mcIdType nbOfTuples((*it)->getNumberOfTuples());
3211 std::vector<std::size_t> nbc(a.size());
3212 std::vector<const T *> pts(a.size());
3213 nbc[0]=(*it)->getNumberOfComponents();
3214 pts[0]=(*it++)->getConstPointer();
3215 for(mcIdType i=1;it!=a.end();it++,i++)
3217 if(nbOfTuples!=(*it)->getNumberOfTuples())
3218 throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
3219 nbc[i]=(*it)->getNumberOfComponents();
3220 pts[i]=(*it)->getConstPointer();
3222 std::size_t totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),(std::size_t)0);
3223 typename Traits<T>::ArrayType *ret(Traits<T>::ArrayType::New());
3224 ret->alloc(nbOfTuples,totalNbOfComp);
3225 T *retPtr(ret->getPointer());
3226 for(mcIdType i=0;i<nbOfTuples;i++)
3227 for(std::size_t j=0;j<a.size();j++)
3229 retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
3233 for(std::size_t i=0;i<a.size();i++)
3234 for(std::size_t j=0;j<nbc[i];j++,k++)
3235 ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
3240 * Returns a new DataArrayDouble holding the same values as \a this array but differently
3241 * arranged in memory. If \a this array holds 2 components of 3 values:
3242 * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
3243 * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
3244 * \warning Do not confuse this method with transpose()!
3245 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
3246 * is to delete using decrRef() as it is no more needed.
3247 * \throw If \a this is not allocated.
3250 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::fromNoInterlace() const
3252 if(this->_mem.isNull())
3253 throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
3254 T *tab(this->_mem.fromNoInterlace(this->getNumberOfComponents()));
3255 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
3256 ret->useArray(tab,true,DeallocType::C_DEALLOC,this->getNumberOfTuples(),this->getNumberOfComponents());
3261 * Returns a new DataArrayDouble holding the same values as \a this array but differently
3262 * arranged in memory. If \a this array holds 2 components of 3 values:
3263 * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
3264 * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
3265 * \warning Do not confuse this method with transpose()!
3266 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
3267 * is to delete using decrRef() as it is no more needed.
3268 * \throw If \a this is not allocated.
3271 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::toNoInterlace() const
3273 if(this->_mem.isNull())
3274 throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
3275 T *tab(this->_mem.toNoInterlace(this->getNumberOfComponents()));
3276 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
3277 ret->useArray(tab,true,DeallocType::C_DEALLOC,this->getNumberOfTuples(),this->getNumberOfComponents());
3282 * Appends components of another array to components of \a this one, tuple by tuple.
3283 * So that the number of tuples of \a this array remains the same and the number of
3284 * components increases.
3285 * \param [in] other - the DataArrayDouble to append to \a this one.
3286 * \throw If \a this is not allocated.
3287 * \throw If \a this and \a other arrays have different number of tuples.
3289 * \if ENABLE_EXAMPLES
3290 * \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
3292 * \ref py_mcdataarraydouble_meldwith "Here is a Python example".
3296 void DataArrayTemplateClassic<T>::meldWith(const typename Traits<T>::ArrayType *other)
3298 this->checkAllocated();
3299 other->checkAllocated();
3300 mcIdType nbOfTuples(this->getNumberOfTuples());
3301 if(nbOfTuples!=other->getNumberOfTuples())
3302 throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
3303 std::size_t nbOfComp1=this->getNumberOfComponents();
3304 std::size_t nbOfComp2=other->getNumberOfComponents();
3305 T *newArr=(T *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(T));
3307 const T *inp1(this->begin()),*inp2(other->begin());
3308 for(mcIdType i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
3310 w=std::copy(inp1,inp1+nbOfComp1,w);
3311 w=std::copy(inp2,inp2+nbOfComp2,w);
3313 this->useArray(newArr,true,DeallocType::C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
3314 std::vector<std::size_t> compIds(nbOfComp2);
3315 for(std::size_t i=0;i<nbOfComp2;i++)
3316 compIds[i]=nbOfComp1+i;
3317 this->copyPartOfStringInfoFrom2(compIds,*other);
3322 * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
3323 * \a nbTimes should be at least equal to 1.
3324 * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
3325 * \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.
3328 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::duplicateEachTupleNTimes(mcIdType nbTimes) const
3330 this->checkAllocated();
3331 if(this->getNumberOfComponents()!=1)
3332 throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
3334 throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
3335 mcIdType nbTuples=this->getNumberOfTuples();
3336 const T *inPtr(this->begin());
3337 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New()); ret->alloc(nbTimes*nbTuples,1);
3338 T *retPtr(ret->getPointer());
3339 for(mcIdType i=0;i<nbTuples;i++,inPtr++)
3342 for(mcIdType j=0;j<nbTimes;j++,retPtr++)
3345 ret->copyStringInfoFrom(*this);
3350 void DataArrayTemplateClassic<T>::aggregate(const typename Traits<T>::ArrayType *other)
3353 throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !");
3354 if(this->getNumberOfComponents()!=other->getNumberOfComponents())
3355 throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !");
3356 this->_mem.insertAtTheEnd(other->begin(),other->end());
3360 * Converts every value of \a this array to its absolute value.
3361 * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
3362 * should be called instead.
3364 * \throw If \a this is not allocated.
3365 * \sa DataArrayDouble::computeAbs
3368 void DataArrayTemplateClassic<T>::abs()
3370 this->checkAllocated();
3371 T *ptr(this->getPointer());
3372 std::size_t nbOfElems(this->getNbOfElems());
3373 std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<T,T>(std::abs));
3374 this->declareAsNew();
3378 * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
3379 * This method is a const method (that do not change any values in \a this) contrary to DataArrayDouble::abs method.
3381 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3382 * same number of tuples and component as \a this array.
3383 * The caller is to delete this result array using decrRef() as it is no more
3385 * \throw If \a this is not allocated.
3386 * \sa DataArrayDouble::abs
3389 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::computeAbs() const
3391 this->checkAllocated();
3392 MCAuto<typename Traits<T>::ArrayType> newArr(Traits<T>::ArrayType::New());
3393 mcIdType nbOfTuples(this->getNumberOfTuples());
3394 std::size_t nbOfComp(this->getNumberOfComponents());
3395 newArr->alloc(nbOfTuples,nbOfComp);
3396 std::transform(this->begin(),this->end(),newArr->getPointer(),std::ptr_fun<T,T>(std::abs));
3397 newArr->copyStringInfoFrom(*this);
3398 return newArr.retn();
3402 * Returns either a \a deep or \a shallow copy of this array. For more info see
3403 * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
3404 * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
3405 * \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
3406 * == \a true) or \a this instance (if \a dCpy == \a false).
3409 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::performCopyOrIncrRef(bool dCpy) const
3411 const typename Traits<T>::ArrayType *thisC(static_cast<const typename Traits<T>::ArrayType *>(this));
3412 return DataArrayTemplateClassic<T>::PerformCopyOrIncrRef(dCpy,*thisC);
3416 * Computes for each tuple the sum of number of components values in the tuple and return it.
3418 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3419 * same number of tuples as \a this array and one component.
3420 * The caller is to delete this result array using decrRef() as it is no more
3422 * \throw If \a this is not allocated.
3425 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::sumPerTuple() const
3427 this->checkAllocated();
3428 std::size_t nbOfComp(this->getNumberOfComponents());
3429 mcIdType nbOfTuple(this->getNumberOfTuples());
3430 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
3431 ret->alloc(nbOfTuple,1);
3432 const T *src(this->begin());
3433 T *dest(ret->getPointer());
3434 for(mcIdType i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3435 *dest=std::accumulate(src,src+nbOfComp,(T)0);
3440 * Set all values in \a this array so that the i-th element equals to \a init + i
3441 * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
3442 * \param [in] init - value to assign to the first element of array.
3443 * \throw If \a this->getNumberOfComponents() != 1
3444 * \throw If \a this is not allocated.
3447 void DataArrayTemplateClassic<T>::iota(T init)
3449 this->checkAllocated();
3450 if(this->getNumberOfComponents()!=1)
3451 throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
3452 T *ptr(this->getPointer());
3453 mcIdType ntuples(this->getNumberOfTuples());
3454 for(mcIdType i=0;i<ntuples;i++)
3456 this->declareAsNew();
3460 struct ImplReprTraits { static void SetPrecision(std::ostream& oss) { } };
3463 struct ImplReprTraits<double> { static void SetPrecision(std::ostream& oss) { oss.precision(17); } };
3466 struct ImplReprTraits<float> { static void SetPrecision(std::ostream& oss) { oss.precision(7); } };
3469 void DataArrayTemplateClassic<T>::reprStream(std::ostream& stream) const
3471 stream << "Name of " << Traits<T>::ReprStr << " array : \"" << this->_name << "\"\n";
3472 reprWithoutNameStream(stream);
3476 void DataArrayTemplateClassic<T>::reprZipStream(std::ostream& stream) const
3478 stream << "Name of " << Traits<T>::ReprStr << " array : \"" << this->_name << "\"\n";
3479 reprZipWithoutNameStream(stream);
3483 void DataArrayTemplateClassic<T>::reprNotTooLongStream(std::ostream& stream) const
3485 stream << "Name of "<< Traits<T>::ReprStr << " array : \"" << this->_name << "\"\n";
3486 reprNotTooLongWithoutNameStream(stream);
3490 void DataArrayTemplateClassic<T>::reprWithoutNameStream(std::ostream& stream) const
3492 DataArray::reprWithoutNameStream(stream);
3493 ImplReprTraits<T>::SetPrecision(stream);
3494 this->_mem.repr(ToIdType(this->getNumberOfComponents()),stream);
3498 void DataArrayTemplateClassic<T>::reprZipWithoutNameStream(std::ostream& stream) const
3500 DataArray::reprWithoutNameStream(stream);
3501 ImplReprTraits<T>::SetPrecision(stream);
3502 this->_mem.reprZip(ToIdType(this->getNumberOfComponents()),stream);
3506 void DataArrayTemplateClassic<T>::reprNotTooLongWithoutNameStream(std::ostream& stream) const
3508 DataArray::reprWithoutNameStream(stream);
3509 ImplReprTraits<T>::SetPrecision(stream);
3510 this->_mem.reprNotTooLong(ToIdType(this->getNumberOfComponents()),stream);
3514 * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
3515 * printed out to avoid to consume too much space in interpretor.
3519 std::string DataArrayTemplateClassic<T>::reprNotTooLong() const
3521 std::ostringstream ret;
3522 reprNotTooLongStream(ret);
3527 * Returns a textual and human readable representation of \a this instance of
3528 * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
3529 * \return std::string - text describing \a this DataArrayInt.
3531 * \sa reprNotTooLong, reprZip
3534 std::string DataArrayTemplateClassic<T>::repr() const
3536 std::ostringstream ret;
3537 DataArrayTemplateClassic<T>::reprStream(ret);
3542 std::string DataArrayTemplateClassic<T>::reprZip() const
3544 std::ostringstream ret;
3545 DataArrayTemplateClassic<T>::reprZipStream(ret);
3549 /////////////////////////////////
3552 * Checks if all values in \a this array are equal to \a val at precision \a eps.
3553 * \param [in] val - value to check equality of array values to.
3554 * \param [in] eps - precision to check the equality.
3555 * \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
3557 * \throw If \a this->getNumberOfComponents() != 1
3558 * \throw If \a this is not allocated.
3561 bool DataArrayTemplateFP<T>::isUniform(T val, T eps) const
3563 this->checkAllocated();
3564 if(this->getNumberOfComponents()!=1)
3565 throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3566 const T *w(this->begin()),*end2(this->end());
3567 const T vmin(val-eps),vmax(val+eps);
3569 if(*w<vmin || *w>vmax)
3574 /////////////////////////////////
3577 * Returns the only one value in \a this, if and only if number of elements
3578 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3579 * \return double - the sole value stored in \a this array.
3580 * \throw If at least one of conditions stated above is not fulfilled.
3583 T DataArrayDiscrete<T>::intValue() const
3585 if(this->isAllocated())
3587 if(this->getNbOfElems()==1)
3589 return *this->getConstPointer();
3592 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3595 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3599 * Equivalent to DataArrayInt::isEqual except that if false the reason of
3600 * mismatch is given.
3602 * \param [in] other the instance to be compared with \a this
3603 * \param [out] reason In case of inequality returns the reason.
3604 * \sa DataArrayInt::isEqual
3607 bool DataArrayDiscrete<T>::isEqualIfNotWhy(const DataArrayDiscrete<T>& other, std::string& reason) const
3609 if(!this->areInfoEqualsIfNotWhy(other,reason))
3611 return this->_mem.isEqual(other._mem,0,reason);
3615 * Checks if \a this and another DataArrayInt are fully equal. For more info see
3616 * \ref MEDCouplingArrayBasicsCompare.
3617 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
3618 * \return bool - \a true if the two arrays are equal, \a false else.
3621 bool DataArrayDiscrete<T>::isEqual(const DataArrayDiscrete<T>& other) const
3624 return isEqualIfNotWhy(other,tmp);
3628 * Returns a new instance of DataArrayInt. The caller is to delete this array
3629 * using decrRef() as it is no more needed.
3632 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::New()
3634 return new typename Traits<T>::ArrayType;
3638 * Returns a newly created array containing a copy of the input array defined by [ \a arrBegin, \a arrEnd )
3641 MCAuto< typename Traits<T>::ArrayType > DataArrayDiscrete<T>::NewFromArray(const T *arrBegin, const T *arrEnd)
3643 MCAuto< typename Traits<T>::ArrayType > ret(DataArrayDiscrete<T>::New());
3644 std::size_t nbElts(std::distance(arrBegin,arrEnd));
3645 ret->alloc(nbElts,1);
3646 std::copy(arrBegin,arrEnd,ret->getPointer());
3651 * Checks if values of \a this and another DataArrayInt are equal. For more info see
3652 * \ref MEDCouplingArrayBasicsCompare.
3653 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
3654 * \return bool - \a true if the values of two arrays are equal, \a false else.
3657 bool DataArrayDiscrete<T>::isEqualWithoutConsideringStr(const DataArrayDiscrete<T>& other) const
3660 return this->_mem.isEqual(other._mem,0,tmp);
3664 * Checks if values of \a this and another DataArrayInt are equal. Comparison is
3665 * performed on sorted value sequences.
3666 * For more info see\ref MEDCouplingArrayBasicsCompare.
3667 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
3668 * \return bool - \a true if the sorted values of two arrays are equal, \a false else.
3671 bool DataArrayDiscrete<T>::isEqualWithoutConsideringStrAndOrder(const typename Traits<T>::ArrayType& other) const
3673 MCAuto<typename Traits<T>::ArrayType> a((static_cast<const typename Traits<T>::ArrayType *>(this))->deepCopy());
3674 MCAuto<typename Traits<T>::ArrayType> b((static_cast<const typename Traits<T>::ArrayType *>(&other))->deepCopy());
3677 return a->isEqualWithoutConsideringStr(*b);
3682 void DataArrayDiscrete<T>::switchOnTupleAlg(T val, std::vector<bool>& vec, ALG algo) const
3684 this->checkAllocated();
3685 if(this->getNumberOfComponents()!=1)
3686 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
3687 mcIdType nbOfTuples(this->getNumberOfTuples());
3688 if(nbOfTuples!=ToIdType(vec.size()))
3689 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
3690 const T *pt(this->begin());
3691 for(mcIdType i=0;i<nbOfTuples;i++)
3697 * 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
3698 * put True to the corresponding entry in \a vec.
3699 * \a vec is expected to be with the same size than the number of tuples of \a this.
3701 * \sa DataArrayInt::switchOnTupleNotEqualTo.
3704 void DataArrayDiscrete<T>::switchOnTupleEqualTo(T val, std::vector<bool>& vec) const
3706 switchOnTupleAlg(val,vec,std::equal_to<T>());
3710 * 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
3711 * put True to the corresponding entry in \a vec.
3712 * \a vec is expected to be with the same size than the number of tuples of \a this.
3714 * \sa DataArrayInt::switchOnTupleEqualTo.
3717 void DataArrayDiscrete<T>::switchOnTupleNotEqualTo(T val, std::vector<bool>& vec) const
3719 switchOnTupleAlg(val,vec,std::not_equal_to<T>());
3723 * 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
3724 * appearing several times. If each element in \a this appears once an 1 component array containing only 0 will be returned.
3727 * - \a this : [5, 3, 2, 1, 4, 5, 2, 1, 0, 11, 5, 4]
3728 * - \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.
3730 * \return DataArrayInt * - a new instance of DataArrayInt with same number of tuples than \a this. The caller is to delete this
3731 * array using decrRef() as it is no more needed.
3732 * \throw If either this not allocated or not with one component.
3734 * \sa DataArrayInt::FindPermutationFromFirstToSecond
3737 DataArrayIdType *DataArrayDiscrete<T>::occurenceRankInThis() const
3739 constexpr char MSG0[] = "occurenceRankInThis :";
3740 this->checkAllocated();
3741 this->checkNbOfComps(1,MSG0);
3742 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
3743 ret->alloc(this->getNumberOfTuples(),1);
3744 mcIdType *retPtr(ret->getPointer());
3745 std::map<T,mcIdType> m;
3746 for(const T *pt = this->begin() ; pt != this->end() ; ++pt, ++retPtr )
3748 auto it = m.find(*pt);
3756 *retPtr = (*it).second++;
3763 * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
3764 * one-dimensional arrays that must be of the same length. The result array describes
3765 * correspondence between \a this and \a other arrays, so that
3766 * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
3767 * not possible because some element in \a other is not in \a this, an exception is thrown.
3768 * \param [in] other - an array to compute permutation to.
3769 * \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
3770 * from \a this to \a other. The caller is to delete this array using decrRef() as it is
3772 * \throw If \a this->getNumberOfComponents() != 1.
3773 * \throw If \a other->getNumberOfComponents() != 1.
3774 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
3775 * \throw If \a other includes a value which is not in \a this array.
3777 * \if ENABLE_EXAMPLES
3778 * \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
3780 * \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
3784 DataArrayIdType *DataArrayDiscrete<T>::buildPermutationArr(const DataArrayDiscrete<T>& other) const
3786 this->checkAllocated();
3787 if(this->getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
3788 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
3789 mcIdType nbTuple(this->getNumberOfTuples());
3790 other.checkAllocated();
3791 if(nbTuple!=other.getNumberOfTuples())
3792 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
3793 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
3794 ret->alloc(nbTuple,1);
3795 ret->fillWithValue(-1);
3796 const T *pt(this->begin());
3797 std::map<mcIdType,mcIdType> mm;
3798 for(mcIdType i=0;i<nbTuple;i++)
3799 mm[ToIdType(pt[i])]=i;
3801 mcIdType *retToFill(ret->getPointer());
3802 for(mcIdType i=0;i<nbTuple;i++)
3804 std::map<mcIdType,mcIdType>::const_iterator it=mm.find(ToIdType(pt[i]));
3807 std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
3808 throw INTERP_KERNEL::Exception(oss.str().c_str());
3810 retToFill[i]=(*it).second;
3816 * Elements of \a partOfThis are expected to be included in \a this.
3817 * The returned array \a ret is so that this[ret]==partOfThis
3819 * 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]
3820 * the return array will contain [3,2,5,7].
3822 * \a this is expected to be a 1 compo allocated array.
3823 * \param [in] partOfThis - A 1 compo allocated array
3824 * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis.
3825 * \throw if two same element is present twice in \a this
3826 * \throw if an element in \a partOfThis is \b NOT in \a this.
3829 DataArrayIdType *DataArrayDiscrete<T>::indicesOfSubPart(const DataArrayDiscrete<T>& partOfThis) const
3831 if(this->getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1)
3832 throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !");
3833 this->checkAllocated(); partOfThis.checkAllocated();
3834 mcIdType thisNbTuples(this->getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples());
3835 const T *thisPt(this->begin()),*pt(partOfThis.begin());
3836 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
3837 ret->alloc(nbTuples,1);
3838 mcIdType *retPt(ret->getPointer());
3839 std::map<mcIdType,mcIdType> m;
3840 for(mcIdType i=0;i<thisNbTuples;i++,thisPt++)
3841 m[ToIdType(*thisPt)]=i;
3842 if(ToIdType(m.size())!=thisNbTuples)
3843 throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : some elements appears more than once !");
3844 for(mcIdType i=0;i<nbTuples;i++,retPt++,pt++)
3846 std::map<mcIdType,mcIdType>::const_iterator it(m.find(ToIdType(*pt)));
3848 *retPt=(*it).second;
3851 std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !";
3852 throw INTERP_KERNEL::Exception(oss.str());
3859 * Checks that \a this array is consistently **increasing** or **decreasing** in value.
3860 * If not an exception is thrown.
3861 * \param [in] increasing - if \a true, the array values should be increasing.
3862 * \throw If sequence of values is not strictly monotonic in agreement with \a
3864 * \throw If \a this->getNumberOfComponents() != 1.
3865 * \throw If \a this is not allocated.
3868 void DataArrayDiscrete<T>::checkMonotonic(bool increasing) const
3870 if(!isMonotonic(increasing))
3873 throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
3875 throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
3880 * Checks that \a this array is consistently **increasing** or **decreasing** in value.
3881 * \param [in] increasing - if \a true, array values should be increasing.
3882 * \return bool - \a true if values change in accordance with \a increasing arg.
3883 * \throw If \a this->getNumberOfComponents() != 1.
3884 * \throw If \a this is not allocated.
3887 bool DataArrayDiscrete<T>::isMonotonic(bool increasing) const
3889 this->checkAllocated();
3890 if(this->getNumberOfComponents()!=1)
3891 throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
3892 std::size_t nbOfElements(this->getNumberOfTuples());
3893 const T *ptr(this->begin());
3899 for(std::size_t i=1;i<nbOfElements;i++)
3909 for(std::size_t i=1;i<nbOfElements;i++)
3921 * This method check that array consistently INCREASING or DECREASING in value.
3924 bool DataArrayDiscrete<T>::isStrictlyMonotonic(bool increasing) const
3926 this->checkAllocated();
3927 if(this->getNumberOfComponents()!=1)
3928 throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
3929 std::size_t nbOfElements(this->getNumberOfTuples());
3930 const T *ptr(this->begin());
3936 for(std::size_t i=1;i<nbOfElements;i++)
3946 for(std::size_t i=1;i<nbOfElements;i++)
3958 * This method check that array consistently INCREASING or DECREASING in value.
3961 void DataArrayDiscrete<T>::checkStrictlyMonotonic(bool increasing) const
3963 if(!isStrictlyMonotonic(increasing))
3966 throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
3968 throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
3973 * Returns an integer value characterizing \a this array, which is useful for a quick
3974 * comparison of many instances of DataArrayInt.
3975 * \return mcIdType - the hash value.
3976 * \throw If \a this is not allocated.
3979 mcIdType DataArrayDiscrete<T>::getHashCode() const
3981 this->checkAllocated();
3982 mcIdType nbOfElems=ToIdType(this->getNbOfElems());
3983 mcIdType ret=nbOfElems*65536;
3988 const T *pt(this->begin());
3989 for(mcIdType i=0;i<nbOfElems;i+=delta)
3990 ret0+=pt[i] & 0x1FFF;
3991 return ToIdType(ret+ret0);
3995 void DataArrayDiscrete<T>::reprCppStream(const std::string& varName, std::ostream& stream) const
3997 mcIdType nbTuples(this->getNumberOfTuples());
3998 std::size_t nbComp(this->getNumberOfComponents());
3999 const T *data(this->getConstPointer());
4000 stream << Traits<T>::ArrayTypeName << " *" << varName << "=" << Traits<T>::ArrayTypeName << "::New();" << std::endl;
4001 if(nbTuples*nbComp>=1)
4003 stream << "const mcIdType " << varName << "Data[" << nbTuples*nbComp << "]={";
4004 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<T>(stream,","));
4005 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
4006 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
4009 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
4010 stream << varName << "->setName(\"" << this->getName() << "\");" << std::endl;
4014 * Method that gives a quick overvien of \a this for python.
4017 void DataArrayDiscrete<T>::reprQuickOverview(std::ostream& stream) const
4019 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
4020 stream << Traits<T>::ArrayTypeName << " C++ instance at " << this << ". ";
4021 if(this->isAllocated())
4023 std::size_t nbOfCompo(this->getNumberOfComponents());
4026 mcIdType nbOfTuples(this->getNumberOfTuples());
4027 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
4028 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
4031 stream << "Number of components : 0.";
4034 stream << "*** No data allocated ****";
4038 void DataArrayDiscrete<T>::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
4040 const T *data(this->begin());
4041 mcIdType nbOfTuples(this->getNumberOfTuples());
4042 std::size_t nbOfCompo(this->getNumberOfComponents());
4043 std::ostringstream oss2; oss2 << "[";
4044 std::string oss2Str(oss2.str());
4045 bool isFinished=true;
4046 for(mcIdType i=0;i<nbOfTuples && isFinished;i++)
4051 for(std::size_t j=0;j<nbOfCompo;j++,data++)
4054 if(j!=nbOfCompo-1) oss2 << ", ";
4060 if(i!=nbOfTuples-1) oss2 << ", ";
4061 std::string oss3Str(oss2.str());
4062 if(oss3Str.length()<maxNbOfByteInRepr)
4074 void DataArrayDiscrete<T>::writeVTK(std::ostream& ofs, mcIdType indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
4076 static const char SPACE[4]={' ',' ',' ',' '};
4077 this->checkAllocated();
4078 std::string idt(indent,' ');
4079 ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << this->getNumberOfComponents() << "\"";
4082 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
4083 if(std::string(type)==Traits<T>::VTKReprStr)
4085 const char *data(reinterpret_cast<const char *>(this->begin()));
4086 std::size_t sz(this->getNbOfElems()*sizeof(T));
4087 byteArr->insertAtTheEnd(data,data+sz);
4088 byteArr->insertAtTheEnd(SPACE,SPACE+4);
4090 else if(std::string(type)=="Int8")
4092 INTERP_KERNEL::AutoPtr<char> tmp(new char[this->getNbOfElems()]);
4093 copyCast(this->begin(),this->end(),(char *)tmp);
4094 byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+this->getNbOfElems());
4095 byteArr->insertAtTheEnd(SPACE,SPACE+4);
4097 else if(std::string(type)=="UInt8")
4099 INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[this->getNbOfElems()]);
4100 copyCast(this->begin(),this->end(),(unsigned char *)tmp);
4101 byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+this->getNbOfElems());
4102 byteArr->insertAtTheEnd(SPACE,SPACE+4);
4106 std::ostringstream oss;
4107 oss << Traits<T>::ArrayTypeName << "::writeVTK : Only " << Traits<T>::VTKReprStr << ", Int8 and UInt8 supported !";
4108 throw INTERP_KERNEL::Exception(oss.str());
4113 ofs << " RangeMin=\"" << this->getMinValueInArray() << "\" RangeMax=\"" << this->getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
4114 std::copy(this->begin(),this->end(),std::ostream_iterator<T>(ofs," "));
4116 ofs << std::endl << idt << "</DataArray>\n";
4120 * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4121 * i.e. a current value is used as in index to get a new value from \a indArrBg.
4122 * \param [in] indArrBg - pointer to the first element of array of new values to assign
4124 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4125 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4126 * \throw If \a this->getNumberOfComponents() != 1
4127 * \throw If any value of \a this can't be used as a valid index for
4128 * [\a indArrBg, \a indArrEnd).
4130 * \sa changeValue, findIdForEach
4133 void DataArrayDiscrete<T>::transformWithIndArr(const T *indArrBg, const T *indArrEnd)
4135 this->checkAllocated();
4136 if(this->getNumberOfComponents()!=1)
4137 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4138 mcIdType nbElemsIn=ToIdType(std::distance(indArrBg,indArrEnd));
4139 mcIdType nbOfTuples(this->getNumberOfTuples());
4140 T *pt(this->getPointer());
4141 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
4143 if(*pt>=0 && *pt<nbElemsIn)
4147 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4148 throw INTERP_KERNEL::Exception(oss.str());
4151 this->declareAsNew();
4155 void DataArrayDiscrete<T>::transformWithIndArr(const MapKeyVal<T, T>& m)
4157 this->checkAllocated();
4158 if(this->getNumberOfComponents()!=1)
4159 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4160 const typename std::map<T,T>& dat(m.data());
4161 mcIdType nbOfTuples(this->getNumberOfTuples());
4162 T *pt(this->getPointer());
4163 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
4165 typename std::map<T,T>::const_iterator it(dat.find(*pt));
4170 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !";
4171 throw INTERP_KERNEL::Exception(oss.str());
4174 this->declareAsNew();
4178 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
4179 * given one. The ids are sorted in the ascending order.
4180 * \param [in] val - the value to find within \a this.
4181 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4182 * array using decrRef() as it is no more needed.
4183 * \throw If \a this is not allocated.
4184 * \throw If \a this->getNumberOfComponents() != 1.
4185 * \sa DataArrayInt::findIdsEqualTuple
4188 DataArrayIdType *DataArrayDiscrete<T>::findIdsEqual(T val) const
4190 this->checkAllocated();
4191 if(this->getNumberOfComponents()!=1)
4192 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
4193 const T *cptr(this->getConstPointer());
4194 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(0,1);
4195 mcIdType nbOfTuples(this->getNumberOfTuples());
4196 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
4198 ret->pushBackSilent(ToIdType(i));
4203 * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from
4204 * values of \a this (\a a) and the given (\a indArr) arrays as follows:
4205 * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
4206 * new value in place \a indArr[ \a v ] is i.
4207 * \param [in] indArrBg - the array holding indices within the result array to assign
4208 * indices of values of \a this array pointing to values of \a indArrBg.
4209 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4210 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4211 * \return DataArrayInt * - the new instance of DataArrayInt.
4212 * The caller is to delete this result array using decrRef() as it is no more
4214 * \throw If \a this->getNumberOfComponents() != 1.
4215 * \throw If any value of \a this array is not a valid index for \a indArrBg array.
4216 * \throw If any value of \a indArrBg is not a valid index for \a this array.
4219 DataArrayIdType *DataArrayDiscrete<T>::transformWithIndArrR(const T *indArrBg, const T *indArrEnd) const
4221 this->checkAllocated();
4222 if(this->getNumberOfComponents()!=1)
4223 throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4224 mcIdType nbElemsIn=ToIdType(std::distance(indArrBg,indArrEnd));
4225 mcIdType nbOfTuples(this->getNumberOfTuples());
4226 const T *pt=this->getConstPointer();
4227 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
4228 ret->alloc(nbOfTuples,1);
4229 ret->fillWithValue(-1);
4230 mcIdType *tmp=ret->getPointer();
4231 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
4233 if(*pt>=0 && *pt<nbElemsIn)
4235 T pos=indArrBg[*pt];
4236 if(pos>=0 && pos<nbOfTuples)
4237 tmp[ToIdType(pos)]=i;
4240 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
4241 throw INTERP_KERNEL::Exception(oss.str().c_str());
4246 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
4247 throw INTERP_KERNEL::Exception(oss.str().c_str());
4254 * Computes distribution of values of \a this one-dimensional array between given value
4255 * ranges (casts). This method is typically useful for entity number splitting by types,
4257 * \warning The values contained in \a arrBg should be sorted ascendently. No
4258 * check of this is be done. If not, the result is not warranted.
4259 * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
4260 * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
4261 * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
4262 * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
4263 * should be more than every value in \a this array.
4264 * \param [in] arrEnd - specifies the end of the array \a arrBg, so that
4265 * the last value of \a arrBg is \a arrEnd[ -1 ].
4266 * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
4267 * (same number of tuples and components), the caller is to delete
4268 * using decrRef() as it is no more needed.
4269 * This array contains indices of ranges for every value of \a this array. I.e.
4270 * the i-th value of \a castArr gives the index of range the i-th value of \a this
4271 * belongs to. Or, in other words, this parameter contains for each tuple in \a
4272 * this in which cast it holds.
4273 * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
4274 * array, the caller is to delete using decrRef() as it is no more needed.
4275 * This array contains ranks of values of \a this array within ranges
4276 * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
4277 * the i-th value of \a this array within the \a castArr[ i ]-th range, to which
4278 * the i-th value of \a this belongs to. Or, in other words, this param contains
4279 * for each tuple its rank inside its cast. The rank is computed as difference
4280 * between the value and the lowest value of range.
4281 * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
4282 * ranges (casts) to which at least one value of \a this array belongs.
4283 * Or, in other words, this param contains the casts that \a this contains.
4284 * The caller is to delete this array using decrRef() as it is no more needed.
4286 * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
4287 * the output of this method will be :
4288 * - \a castArr : [1,1,0,0,0,1,1,0,1]
4289 * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
4290 * - \a castsPresent : [0,1]
4292 * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
4293 * range #1 and its rank within this range is 2; etc.
4295 * \throw If \a this->getNumberOfComponents() != 1.
4296 * \throw If \a arrEnd - arrBg < 2.
4297 * \throw If any value of \a this is not less than \a arrEnd[-1].
4300 void DataArrayDiscrete<T>::splitByValueRange(const T *arrBg, const T *arrEnd,
4301 DataArrayType *& castArr, DataArrayType *& rankInsideCast, DataArrayType *& castsPresent) const
4303 this->checkAllocated();
4304 if(this->getNumberOfComponents()!=1)
4305 throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4306 mcIdType nbOfTuples=this->getNumberOfTuples();
4307 std::size_t nbOfCast=std::distance(arrBg,arrEnd);
4309 throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
4311 const T *work=this->getConstPointer();
4312 typedef std::reverse_iterator<const T *> rintstart;
4313 rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
4314 rintstart end2(arrBg);
4315 MCAuto<DataArrayType> ret1=DataArrayType::New();
4316 MCAuto<DataArrayType> ret2=DataArrayType::New();
4317 MCAuto<DataArrayType> ret3=DataArrayType::New();
4318 ret1->alloc(nbOfTuples,1);
4319 ret2->alloc(nbOfTuples,1);
4320 T *ret1Ptr=ret1->getPointer();
4321 T *ret2Ptr=ret2->getPointer();
4322 std::set<T> castsDetected;
4323 for(mcIdType i=0;i<nbOfTuples;i++)
4325 rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<T>(), work[i]));
4326 std::size_t pos=std::distance(bg,res);
4327 std::size_t pos2=nbOfCast-pos;
4330 ret1Ptr[i]=static_cast<T>(pos2);
4331 ret2Ptr[i]=work[i]-arrBg[pos2];
4332 castsDetected.insert(ret1Ptr[i]);
4336 std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
4337 throw INTERP_KERNEL::Exception(oss.str().c_str());
4340 ret3->alloc(castsDetected.size(),1);
4341 std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
4342 castArr=ret1.retn();
4343 rankInsideCast=ret2.retn();
4344 castsPresent=ret3.retn();
4348 * 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 ).
4349 * 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 ).
4350 * This method works only if \a this is allocated and single component. If not an exception will be thrown.
4352 * \param [out] strt - the start of the range (included) if true is returned.
4353 * \param [out] sttoopp - the end of the range (not included) if true is returned.
4354 * \param [out] stteepp - the step of the range if true is returned.
4355 * \return the verdict of the check.
4357 * \sa DataArray::GetNumberOfItemGivenBES
4360 bool DataArrayDiscrete<T>::isRange(T& strt, T& sttoopp, T& stteepp) const
4362 this->checkAllocated();
4363 if(this->getNumberOfComponents()!=1)
4364 throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
4365 mcIdType nbTuples(this->getNumberOfTuples());
4367 { strt=0; sttoopp=0; stteepp=1; return true; }
4368 const T *pt(this->begin());
4371 { sttoopp=strt+1; stteepp=1; return true; }
4372 strt=*pt; sttoopp=pt[nbTuples-1];
4378 T a(sttoopp-1-strt),tmp(strt);
4379 if(a%(nbTuples-1)!=0)
4381 stteepp=a/(FromIdType<T>(nbTuples)-1);
4382 for(mcIdType i=0;i<nbTuples;i++,tmp+=stteepp)
4390 T a(strt-sttoopp-1),tmp(strt);
4391 if(a%(nbTuples-1)!=0)
4393 stteepp=-(a/(FromIdType<T>(nbTuples)-1));
4394 for(mcIdType i=0;i<nbTuples;i++,tmp+=stteepp)
4402 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4403 * from values of \a this array, which is supposed to contain a renumbering map in
4404 * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
4405 * To know how to use the renumbering maps see \ref numbering.
4406 * \param [in] newNbOfElem - the number of tuples in the result array.
4407 * \return DataArrayInt * - the new instance of DataArrayInt.
4408 * The caller is to delete this result array using decrRef() as it is no more
4411 * \if ENABLE_EXAMPLES
4412 * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
4413 * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
4417 DataArrayIdType * DataArrayDiscrete<T>::invertArrayO2N2N2O(mcIdType newNbOfElem) const
4419 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
4420 ret->alloc(newNbOfElem,1);
4421 mcIdType nbOfOldNodes(this->getNumberOfTuples());
4422 const T *old2New(this->begin());
4423 mcIdType *pt(ret->getPointer());
4424 for(mcIdType i=0;i!=nbOfOldNodes;i++)
4429 if(newp>=0 && newp<newNbOfElem)
4433 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4434 throw INTERP_KERNEL::Exception(oss.str().c_str());
4442 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4443 * from values of \a this array, which is supposed to contain a renumbering map in
4444 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4445 * To know how to use the renumbering maps see \ref numbering.
4446 * \param [in] newNbOfElem - the number of tuples in the result array.
4447 * \return DataArrayInt * - the new instance of DataArrayInt.
4448 * The caller is to delete this result array using decrRef() as it is no more
4451 * \if ENABLE_EXAMPLES
4452 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4454 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4455 * \sa invertArrayN2O2O2NOptimized
4459 DataArrayIdType *DataArrayDiscrete<T>::invertArrayN2O2O2N(mcIdType oldNbOfElem) const
4461 this->checkAllocated();
4462 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
4463 ret->alloc(oldNbOfElem,1);
4464 const T *new2Old=this->getConstPointer();
4465 mcIdType *pt=ret->getPointer();
4466 std::fill(pt,pt+oldNbOfElem,-1);
4467 mcIdType nbOfNewElems(this->getNumberOfTuples());
4468 for(mcIdType i=0;i<nbOfNewElems;i++)
4471 if(v>=0 && v<oldNbOfElem)
4475 std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
4476 throw INTERP_KERNEL::Exception(oss.str().c_str());
4483 * This method is similar to DataArrayInt::invertArrayO2N2N2O except that
4484 * 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]
4487 DataArrayIdType *DataArrayDiscrete<T>::invertArrayO2N2N2OBis(mcIdType newNbOfElem) const
4489 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
4490 ret->alloc(newNbOfElem,1);
4491 mcIdType nbOfOldNodes(this->getNumberOfTuples());
4492 const T *old2New=this->getConstPointer();
4493 mcIdType *pt=ret->getPointer();
4494 for(mcIdType i=nbOfOldNodes-1;i>=0;i--)
4499 if(newp>=0 && newp<newNbOfElem)
4503 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4504 throw INTERP_KERNEL::Exception(oss.str().c_str());
4512 * Creates a map, whose contents are computed
4513 * from values of \a this array, which is supposed to contain a renumbering map in
4514 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4515 * To know how to use the renumbering maps see \ref numbering.
4516 * \param [in] newNbOfElem - the number of tuples in the result array.
4517 * \return MapII - the new instance of Map.
4519 * \if ENABLE_EXAMPLES
4520 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4522 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4523 * \sa invertArrayN2O2O2N, giveN2OOptimized, MEDCouplingPointSet::renumberNodesInConn
4527 MCAuto< MapKeyVal<T, mcIdType> > DataArrayDiscrete<T>::invertArrayN2O2O2NOptimized() const
4529 this->checkAllocated();
4530 if(this->getNumberOfComponents()!=1)
4531 throw INTERP_KERNEL::Exception("DataArrayInt::invertArrayN2O2O2NOptimized : single component expected !");
4532 MCAuto< MapKeyVal<T, mcIdType> > ret(MapKeyVal<T, mcIdType>::New());
4533 std::map<T, mcIdType>& m(ret->data());
4534 const T *new2Old(this->begin());
4535 mcIdType nbOfNewElems(this->getNumberOfTuples());
4536 for(mcIdType i=0;i<nbOfNewElems;i++)
4545 * Creates a map, whose contents are computed
4546 * from values of \a this array, which is supposed to contain a renumbering map in
4547 * "New to Old" mode. The result array contains a renumbering map in "New to Old" mode as C++ map for performance reasons.
4549 * \sa invertArrayN2O2O2NOptimized, MEDCouplingPointSet::renumberNodesInConn
4552 MCAuto< MapKeyVal<mcIdType, T> > DataArrayDiscrete<T>::giveN2OOptimized() const
4554 this->checkAllocated();
4555 if(this->getNumberOfComponents()!=1)
4556 throw INTERP_KERNEL::Exception("DataArrayInt::giveN2OOptimized : single component expected !");
4557 MCAuto< MapKeyVal<mcIdType, T> > ret(MapKeyVal<mcIdType, T>::New());
4558 std::map<mcIdType,T>& m(ret->data());
4559 const T *new2Old(this->begin());
4560 mcIdType nbOfNewElems(this->getNumberOfTuples());
4561 for(mcIdType i=0;i<nbOfNewElems;i++)
4570 * This method finds for each element \a ELT in [valsBg,valsEnd) elements in \a this equal to it. Associated to ELT
4571 * this method will return the tuple id of last element found. If there is no element in \a this equal to ELT
4572 * an exception will be thrown.
4574 * In case of success this[ret]==vals. Samely ret->transformWithIndArr(this->begin(),this->end())==vals.
4575 * Where \a vals is the [valsBg,valsEnd) array and \a ret the array returned by this method.
4576 * This method can be seen as an extension of FindPermutationFromFirstToSecond.
4579 * - \a this: [17,27,2,10,-4,3,12,27,16]
4580 * - \a val : [3,16,-4,27,17]
4581 * - result: [5,8,4,7,0]
4583 * \return - An array of size std::distance(valsBg,valsEnd)
4585 * \sa DataArrayInt::FindPermutationFromFirstToSecond , DataArrayInt::FindPermutationFromFirstToSecondDuplicate
4588 MCAuto<DataArrayIdType> DataArrayDiscrete<T>::findIdForEach(const T *valsBg, const T *valsEnd) const
4590 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
4591 std::size_t nbOfTuplesOut(std::distance(valsBg,valsEnd));
4592 ret->alloc(nbOfTuplesOut,1);
4593 MCAuto< MapKeyVal<T, mcIdType> > zeMap(this->invertArrayN2O2O2NOptimized());
4594 const std::map<T, mcIdType>& dat(zeMap->data());
4595 mcIdType *ptToFeed(ret->getPointer());
4596 for(const T *pt=valsBg;pt!=valsEnd;pt++)
4598 typename std::map<T,mcIdType>::const_iterator it(dat.find(*pt));
4600 *ptToFeed++=(*it).second;
4603 std::ostringstream oss; oss << "DataArrayInt::findIdForEach : error for element at place " << std::distance(valsBg,pt);
4604 oss << " of input array value is " << *pt << " which is not in this !";
4605 throw INTERP_KERNEL::Exception(oss.str());
4612 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4613 * This map, if applied to \a this array, would make it sorted. For example, if
4614 * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4615 * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4616 * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4617 * This method is useful for renumbering (in MED file for example). For more info
4618 * on renumbering see \ref numbering.
4619 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4620 * array using decrRef() as it is no more needed.
4621 * \throw If \a this is not allocated.
4622 * \throw If \a this->getNumberOfComponents() != 1.
4623 * \throw If there are equal values in \a this array.
4626 DataArrayIdType *DataArrayDiscrete<T>::checkAndPreparePermutation() const
4628 this->checkAllocated();
4629 if(this->getNumberOfComponents()!=1)
4630 throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4631 mcIdType nbTuples(this->getNumberOfTuples());
4632 const T *pt=this->getConstPointer();
4633 mcIdType *pt2=this->CheckAndPreparePermutation(pt,pt+nbTuples);
4634 DataArrayIdType *ret=DataArrayIdType::New();
4635 ret->useArray(pt2,true,DeallocType::C_DEALLOC,nbTuples,1);
4640 * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4641 * onto a set of values of size \a targetNb (\a B). The surjective function is
4642 * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4643 * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4644 * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4645 * The first of out arrays returns indices of elements of \a this array, grouped by their
4646 * place in the set \a B. The second out array is the index of the first one; it shows how
4647 * many elements of \a A are mapped into each element of \a B. <br>
4649 * mapping and its usage in renumbering see \ref numbering. <br>
4651 * - \a this: [0,3,2,3,2,2,1,2]
4653 * - \a arr: [0, 6, 2,4,5,7, 1,3]
4654 * - \a arrI: [0,1,2,6,8]
4656 * This result means: <br>
4657 * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4658 * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4659 * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4660 * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] :
4661 * \a arrI[ 2+1 ]]); <br> etc.
4662 * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4663 * than the maximal value of \a A.
4664 * \param [out] arr - a new instance of DataArrayInt returning indices of
4665 * elements of \a this, grouped by their place in the set \a B. The caller is to delete
4666 * this array using decrRef() as it is no more needed.
4667 * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4668 * elements of \a this. The caller is to delete this array using decrRef() as it
4669 * is no more needed.
4670 * \throw If \a this is not allocated.
4671 * \throw If \a this->getNumberOfComponents() != 1.
4672 * \throw If any value in \a this is more or equal to \a targetNb.
4675 void DataArrayDiscrete<T>::changeSurjectiveFormat(T targetNb, DataArrayIdType *&arr, DataArrayIdType *&arrI) const
4677 this->checkAllocated();
4678 if(this->getNumberOfComponents()!=1)
4679 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4680 mcIdType nbOfTuples(this->getNumberOfTuples());
4681 const T *input=this->getConstPointer();
4682 std::vector< std::vector<mcIdType> > tmp(targetNb);
4683 for(mcIdType i=0;i<nbOfTuples;i++)
4686 if(tmp2>=0 && tmp2<targetNb)
4687 tmp[tmp2].push_back(i);
4690 std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4691 throw INTERP_KERNEL::Exception(oss.str().c_str());
4695 MCAuto<DataArrayIdType> retI(DataArrayIdType::New());
4696 retI->alloc(targetNb+1,1);
4697 mcIdType *retIPtr=retI->getPointer();
4699 for(std::vector< std::vector<mcIdType> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4700 retIPtr[1]=retIPtr[0]+ToIdType((*it1).size());
4701 if(nbOfTuples!=retI->getIJ(ToIdType(targetNb),0))
4702 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4703 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
4704 ret->alloc(nbOfTuples,1);
4705 mcIdType *retPtr=ret->getPointer();
4706 for(std::vector< std::vector<mcIdType> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4707 retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4713 * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4714 * which if applied to \a this array would make it sorted ascendingly.
4715 * For more info on renumbering see \ref numbering. <br>
4717 * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4718 * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4719 * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2]
4721 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4722 * array using decrRef() as it is no more needed.
4723 * \throw If \a this is not allocated.
4724 * \throw If \a this->getNumberOfComponents() != 1.
4727 DataArrayIdType *DataArrayDiscrete<T>::buildPermArrPerLevel() const
4729 this->checkAllocated();
4730 if(this->getNumberOfComponents()!=1)
4731 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4732 mcIdType nbOfTuples=this->getNumberOfTuples();
4733 const T *pt=this->getConstPointer();
4734 std::map<T,mcIdType> m;
4735 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
4736 ret->alloc(nbOfTuples,1);
4737 mcIdType *opt=ret->getPointer();
4738 for(mcIdType i=0;i<nbOfTuples;i++,pt++,opt++)
4741 typename std::map<T,mcIdType>::iterator it=m.find(val);
4750 m.insert(std::pair<T,mcIdType>(val,1));
4754 for(typename std::map<T,mcIdType>::iterator it=m.begin();it!=m.end();it++)
4756 mcIdType vt=(*it).second;
4760 pt=this->getConstPointer();
4761 opt=ret->getPointer();
4762 for(mcIdType i=0;i<nbOfTuples;i++,pt++,opt++)
4769 * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4770 * iota(). This method is particularly useful for DataArrayInt instances that represent
4771 * a renumbering array, to check if there is a real need in renumbering.
4772 * This method checks than \a this can be considered as an identity mapping
4773 * of a set having \a sizeExpected elements into itself.
4775 * \param [in] sizeExpected - The number of elements expected.
4776 * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4777 * \throw If \a this is not allocated.
4778 * \throw If \a this->getNumberOfComponents() != 1.
4781 bool DataArrayDiscrete<T>::isIota(mcIdType sizeExpected) const
4783 this->checkAllocated();
4784 if(this->getNumberOfComponents()!=1)
4786 mcIdType nbOfTuples(this->getNumberOfTuples());
4787 if(nbOfTuples!=sizeExpected)
4789 const T *pt=this->getConstPointer();
4790 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
4797 * Checks if all values in \a this array are equal to \a val.
4798 * \param [in] val - value to check equality of array values to.
4799 * \return bool - \a true if all values are \a val.
4800 * \throw If \a this is not allocated.
4801 * \throw If \a this->getNumberOfComponents() != 1
4802 * \sa DataArrayInt::checkUniformAndGuess
4805 bool DataArrayDiscrete<T>::isUniform(T val) const
4807 this->checkAllocated();
4808 if(this->getNumberOfComponents()!=1)
4809 throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4810 const T *w(this->begin()),*end2(this->end());
4818 * This method checks that \a this is uniform. If not and exception will be thrown.
4819 * In case of uniformity the corresponding value is returned.
4821 * \return mcIdType - the unique value contained in this
4822 * \throw If \a this is not allocated.
4823 * \throw If \a this->getNumberOfComponents() != 1
4824 * \throw If \a this is not uniform.
4825 * \sa DataArrayInt::isUniform
4828 T DataArrayDiscrete<T>::checkUniformAndGuess() const
4830 this->checkAllocated();
4831 if(this->getNumberOfComponents()!=1)
4832 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4834 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
4835 const T *w(this->begin()),*end2(this->end());
4839 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
4844 * Checks if all values in \a this array are unique.
4845 * \return bool - \a true if condition above is true
4846 * \throw If \a this is not allocated.
4847 * \throw If \a this->getNumberOfComponents() != 1
4850 bool DataArrayDiscrete<T>::hasUniqueValues() const
4852 this->checkAllocated();
4853 if(this->getNumberOfComponents()!=1)
4854 throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4855 std::size_t nbOfElements(this->getNumberOfTuples());
4856 std::set<T> s(this->begin(),this->end()); // in C++11, should use unordered_set (O(1) complexity)
4857 if (s.size() != nbOfElements)
4863 * Copy all components in a specified order from another DataArrayInt.
4864 * The specified components become the first ones in \a this array.
4865 * Both numerical and textual data is copied. The number of tuples in \a this and
4866 * the other array can be different.
4867 * \param [in] a - the array to copy data from.
4868 * \param [in] compoIds - sequence of zero based indices of components, data of which is
4870 * \throw If \a a is NULL.
4871 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
4872 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
4874 * \if ENABLE_EXAMPLES
4875 * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
4879 void DataArrayDiscrete<T>::setSelectedComponents(const DataArrayType *a, const std::vector<std::size_t>& compoIds)
4882 throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
4883 this->checkAllocated();
4884 a->checkAllocated();
4885 this->copyPartOfStringInfoFrom2(compoIds,*a);
4886 std::size_t partOfCompoSz=compoIds.size();
4887 std::size_t nbOfCompo = this->getNumberOfComponents();
4888 mcIdType nbOfTuples=std::min(this->getNumberOfTuples(),a->getNumberOfTuples());
4889 const T *ac=a->getConstPointer();
4890 T *nc=this->getPointer();
4891 for(mcIdType i=0;i<nbOfTuples;i++)
4892 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
4893 nc[nbOfCompo*i+compoIds[j]]=*ac;
4897 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
4898 * equal to a given one.
4899 * \param [in] val - the value to ignore within \a this.
4900 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4901 * array using decrRef() as it is no more needed.
4902 * \throw If \a this is not allocated.
4903 * \throw If \a this->getNumberOfComponents() != 1.
4906 DataArrayIdType *DataArrayDiscrete<T>::findIdsNotEqual(T val) const
4908 this->checkAllocated();
4909 if(this->getNumberOfComponents()!=1)
4910 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
4911 const T *cptr(this->getConstPointer());
4912 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
4914 mcIdType nbOfTuples(this->getNumberOfTuples());
4915 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
4917 ret->pushBackSilent(i);
4922 * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
4923 * This method is an extension of DataArrayInt::findIdsEqual method.
4925 * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
4926 * \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
4927 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4928 * array using decrRef() as it is no more needed.
4929 * \throw If \a this is not allocated.
4930 * \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
4931 * \throw If \a this->getNumberOfComponents() is equal to 0.
4932 * \sa DataArrayInt::findIdsEqual
4935 DataArrayIdType *DataArrayDiscrete<T>::findIdsEqualTuple(const T *tupleBg, const T *tupleEnd) const
4937 std::size_t nbOfCompoExp=std::distance(tupleBg,tupleEnd);
4938 this->checkAllocated();
4939 if(this->getNumberOfComponents()!=nbOfCompoExp)
4941 std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << this->getNumberOfComponents() << " components !";
4942 throw INTERP_KERNEL::Exception(oss.str().c_str());
4945 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
4946 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
4948 const T *bg(this->begin()),*end2(this->end()),*work(this->begin());
4951 work=std::search(work,end2,tupleBg,tupleEnd);
4954 std::ptrdiff_t pos=std::distance(bg,work);
4955 if(pos%nbOfCompoExp==0)
4956 ret->pushBackSilent(ToIdType(pos/nbOfCompoExp));
4964 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
4965 * one of given values.
4966 * \param [in] valsBg - an array of values to find within \a this array.
4967 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4968 * the last value of \a valsBg is \a valsEnd[ -1 ].
4969 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4970 * array using decrRef() as it is no more needed.
4971 * \throw If \a this->getNumberOfComponents() != 1.
4974 DataArrayIdType *DataArrayDiscrete<T>::findIdsEqualList(const T *valsBg, const T *valsEnd) const
4976 if(this->getNumberOfComponents()!=1)
4977 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
4978 std::set<T> vals2(valsBg,valsEnd);
4979 const T *cptr(this->getConstPointer());
4980 mcIdType nbOfTuples(this->getNumberOfTuples());
4981 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(0,1);
4982 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
4983 if(vals2.find(*cptr)!=vals2.end())
4984 ret->pushBackSilent(i);
4989 * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
4990 * equal to any of given values.
4991 * \param [in] valsBg - an array of values to ignore within \a this array.
4992 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4993 * the last value of \a valsBg is \a valsEnd[ -1 ].
4994 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4995 * array using decrRef() as it is no more needed.
4996 * \throw If \a this->getNumberOfComponents() != 1.
4999 DataArrayIdType *DataArrayDiscrete<T>::findIdsNotEqualList(const T *valsBg, const T *valsEnd) const
5001 if(this->getNumberOfComponents()!=1)
5002 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
5003 std::set<T> vals2(valsBg,valsEnd);
5004 const T *cptr=this->getConstPointer();
5005 mcIdType nbOfTuples(this->getNumberOfTuples());
5006 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(0,1);
5007 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
5008 if(vals2.find(*cptr)==vals2.end())
5009 ret->pushBackSilent(i);
5014 * This method expects to be called when number of components of this is equal to one.
5015 * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
5016 * If not any tuple contains \b value -1 is returned.
5017 * \sa DataArrayInt::presenceOfValue
5020 mcIdType DataArrayDiscrete<T>::findIdFirstEqual(T value) const
5022 this->checkAllocated();
5023 if(this->getNumberOfComponents()!=1)
5024 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
5025 const T *cptr=this->getConstPointer();
5026 mcIdType nbOfTuples(this->getNumberOfTuples());
5027 const T *ret=std::find(cptr,cptr+nbOfTuples,value);
5028 if(ret!=cptr+nbOfTuples)
5029 return ToIdType(std::distance(cptr,ret));
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 so that the value is contained in \b vals.
5036 * If not any tuple contains one of the values contained in 'vals' -1 is returned.
5037 * \sa DataArrayInt::presenceOfValue
5040 mcIdType DataArrayDiscrete<T>::findIdFirstEqual(const std::vector<T>& vals) 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 std::set<T> vals2(vals.begin(),vals.end());
5046 const T *cptr=this->getConstPointer();
5047 mcIdType nbOfTuples(this->getNumberOfTuples());
5048 for(const T *w=cptr;w!=cptr+nbOfTuples;w++)
5049 if(vals2.find(*w)!=vals2.end())
5050 return ToIdType(std::distance(cptr,w));
5055 * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
5056 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5057 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5058 * If any the tuple id is returned. If not -1 is returned.
5060 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5061 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5063 * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
5064 * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
5067 mcIdType DataArrayDiscrete<T>::findIdFirstEqualTuple(const std::vector<T>& tupl) const
5069 this->checkAllocated();
5070 std::size_t nbOfCompo(this->getNumberOfComponents());
5072 throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
5073 if(nbOfCompo!=tupl.size())
5075 std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
5076 throw INTERP_KERNEL::Exception(oss.str().c_str());
5078 const T *cptr=this->getConstPointer();
5079 std::size_t nbOfVals=this->getNbOfElems();
5080 for(const T *work=cptr;work!=cptr+nbOfVals;)
5082 work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
5083 if(work!=cptr+nbOfVals)
5085 if(std::distance(cptr,work)%nbOfCompo!=0)
5088 return ToIdType (std::distance(cptr,work)/nbOfCompo);
5095 * This method searches the sequence specified in input parameter \b vals in \b this.
5096 * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
5097 * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
5098 * \sa DataArrayInt::findIdFirstEqualTuple
5101 mcIdType DataArrayDiscrete<T>::findIdSequence(const std::vector<T>& vals) const
5103 this->checkAllocated();
5104 std::size_t nbOfCompo=this->getNumberOfComponents();
5106 throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
5107 const T *cptr=this->getConstPointer();
5108 std::size_t nbOfVals=this->getNbOfElems();
5109 const T *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
5110 if(loc!=cptr+nbOfVals)
5111 return ToIdType(std::distance(cptr,loc));
5116 * Assigns \a newValue to all elements holding \a oldValue within \a this
5117 * one-dimensional array.
5118 * \param [in] oldValue - the value to replace.
5119 * \param [in] newValue - the value to assign.
5120 * \return mcIdType - number of replacements performed.
5121 * \throw If \a this is not allocated.
5122 * \throw If \a this->getNumberOfComponents() != 1.
5125 mcIdType DataArrayDiscrete<T>::changeValue(T oldValue, T newValue)
5127 this->checkAllocated();
5128 if(this->getNumberOfComponents()!=1)
5129 throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
5130 if(oldValue==newValue)
5132 T *start(this->getPointer()),*end2(start+this->getNbOfElems());
5134 for(T *val=start;val!=end2;val++)
5143 this->declareAsNew();
5148 * This method returns the number of values in \a this that are equals to input parameter \a value.
5149 * This method only works for single component array.
5151 * \return a value in [ 0, \c this->getNumberOfTuples() )
5153 * \throw If \a this is not allocated
5157 mcIdType DataArrayDiscrete<T>::count(T value) const
5160 this->checkAllocated();
5161 if(this->getNumberOfComponents()!=1)
5162 throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5163 const T *vals=this->begin();
5164 std::size_t nbOfElements=this->getNumberOfTuples();
5165 for(std::size_t i=0;i<nbOfElements;i++,vals++)
5172 * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
5173 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5174 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5175 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5176 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5177 * \sa DataArrayInt::findIdFirstEqualTuple
5180 bool DataArrayDiscrete<T>::presenceOfTuple(const std::vector<T>& tupl) const
5182 return this->findIdFirstEqualTuple(tupl)!=-1;
5187 * Returns \a true if a given value is present within \a this one-dimensional array.
5188 * \param [in] value - the value to find within \a this array.
5189 * \return bool - \a true in case if \a value is present within \a this array.
5190 * \throw If \a this is not allocated.
5191 * \throw If \a this->getNumberOfComponents() != 1.
5192 * \sa findIdFirstEqual()
5195 bool DataArrayDiscrete<T>::presenceOfValue(T value) const
5197 return this->findIdFirstEqual(value)!=-1;
5201 * This method expects to be called when number of components of this is equal to one.
5202 * This method returns true if it exists a tuple so that the value is contained in \b vals.
5203 * If not any tuple contains one of the values contained in 'vals' false is returned.
5204 * \sa DataArrayInt::findIdFirstEqual
5207 bool DataArrayDiscrete<T>::presenceOfValue(const std::vector<T>& vals) const
5209 return this->findIdFirstEqual(vals)!=-1;
5213 * Accumulates values of each component of \a this array.
5214 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
5215 * by the caller, that is filled by this method with sum value for each
5217 * \throw If \a this is not allocated.
5220 void DataArrayDiscrete<T>::accumulate(T *res) const
5222 this->checkAllocated();
5223 const T *ptr=this->getConstPointer();
5224 mcIdType nbTuple(this->getNumberOfTuples());
5225 std::size_t nbComps(this->getNumberOfComponents());
5226 std::fill(res,res+nbComps,0);
5227 for(mcIdType i=0;i<nbTuple;i++)
5228 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<T>());
5232 T DataArrayDiscrete<T>::accumulate(std::size_t compId) const
5234 this->checkAllocated();
5235 const T *ptr=this->getConstPointer();
5236 mcIdType nbTuple(this->getNumberOfTuples());
5237 std::size_t nbComps(this->getNumberOfComponents());
5238 if(compId<0 || compId>=nbComps)
5239 throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
5241 for(mcIdType i=0;i<nbTuple;i++)
5242 ret+=ptr[i*nbComps+compId];
5247 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
5248 * The returned array will have same number of components than \a this and number of tuples equal to
5249 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
5251 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
5253 * \param [in] bgOfIndex - begin (included) of the input index array.
5254 * \param [in] endOfIndex - end (excluded) of the input index array.
5255 * \return DataArrayInt * - the new instance having the same number of components than \a this.
5257 * \throw If bgOfIndex or end is NULL.
5258 * \throw If input index array is not ascendingly sorted.
5259 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
5260 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
5263 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::accumulatePerChunck(const mcIdType *bgOfIndex, const mcIdType *endOfIndex) const
5265 if(!bgOfIndex || !endOfIndex)
5266 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
5267 this->checkAllocated();
5268 std::size_t nbCompo(this->getNumberOfComponents());
5269 mcIdType nbOfTuples(this->getNumberOfTuples());
5270 mcIdType sz=ToIdType(std::distance(bgOfIndex,endOfIndex));
5272 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
5274 MCAuto<DataArrayType> ret=DataArrayType::New(); ret->alloc(sz,nbCompo);
5275 const mcIdType *w=bgOfIndex;
5276 if(*w<0 || *w>=nbOfTuples)
5277 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
5278 const T *srcPt=this->begin()+(*w)*nbCompo;
5279 T *tmp=ret->getPointer();
5280 for(mcIdType i=0;i<sz;i++,tmp+=nbCompo,w++)
5282 std::fill(tmp,tmp+nbCompo,0);
5285 for(mcIdType j=w[0];j<w[1];j++,srcPt+=nbCompo)
5287 if(j>=0 && j<nbOfTuples)
5288 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<T>());
5291 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
5292 throw INTERP_KERNEL::Exception(oss.str().c_str());
5298 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
5299 throw INTERP_KERNEL::Exception(oss.str().c_str());
5302 ret->copyStringInfoFrom(*this);
5307 * Returns in a single walk in \a this the min value and the max value in \a this.
5308 * \a this is expected to be single component array.
5310 * \param [out] minValue - the min value in \a this.
5311 * \param [out] maxValue - the max value in \a this.
5313 * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5316 void DataArrayDiscrete<T>::getMinMaxValues(T& minValue, T& maxValue) const
5318 this->checkAllocated();
5319 if(this->getNumberOfComponents()!=1)
5320 throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5321 std::size_t nbElements(this->getNumberOfTuples());
5322 const T *pt(this->begin());
5323 minValue=std::numeric_limits<T>::max(); maxValue=-std::numeric_limits<T>::max();
5324 for(std::size_t i=0;i<nbElements;i++,pt++)
5334 * Modify all elements of \a this array, so that
5335 * an element _x_ becomes \f$ numerator / x \f$.
5336 * \warning If an exception is thrown because of presence of 0 element in \a this
5337 * array, all elements processed before detection of the zero element remain
5339 * \param [in] numerator - the numerator used to modify array elements.
5340 * \throw If \a this is not allocated.
5341 * \throw If there is an element equal to 0 in \a this array.
5344 void DataArrayDiscrete<T>::applyInv(T numerator)
5346 this->checkAllocated();
5347 T *ptr=this->getPointer();
5348 std::size_t nbOfElems=this->getNbOfElems();
5349 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5353 *ptr=numerator/(*ptr);
5357 std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/(this->getNumberOfComponents()) << " component #" << i%(this->getNumberOfComponents());
5359 throw INTERP_KERNEL::Exception(oss.str().c_str());
5362 this->declareAsNew();
5366 * Modify all elements of \a this array, so that
5367 * an element _x_ becomes \f$ x / val \f$.
5368 * \param [in] val - the denominator used to modify array elements.
5369 * \throw If \a this is not allocated.
5370 * \throw If \a val == 0.
5373 void DataArrayDiscrete<T>::applyDivideBy(T val)
5376 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5377 this->checkAllocated();
5378 T *ptr=this->getPointer();
5379 std::size_t nbOfElems=this->getNbOfElems();
5380 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<T>(),val));
5381 this->declareAsNew();
5385 * Modify all elements of \a this array, so that
5386 * an element _x_ becomes <em> x % val </em>.
5387 * \param [in] val - the divisor used to modify array elements.
5388 * \throw If \a this is not allocated.
5389 * \throw If \a val <= 0.
5392 void DataArrayDiscrete<T>::applyModulus(T val)
5395 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5396 this->checkAllocated();
5397 T *ptr=this->getPointer();
5398 std::size_t nbOfElems=this->getNbOfElems();
5399 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<T>(),val));
5400 this->declareAsNew();
5404 * Modify all elements of \a this array, so that
5405 * an element _x_ becomes <em> val % x </em>.
5406 * \warning If an exception is thrown because of presence of an element <= 0 in \a this
5407 * array, all elements processed before detection of the zero element remain
5409 * \param [in] val - the divident used to modify array elements.
5410 * \throw If \a this is not allocated.
5411 * \throw If there is an element equal to or less than 0 in \a this array.
5414 void DataArrayDiscrete<T>::applyRModulus(T val)
5416 this->checkAllocated();
5417 T *ptr=this->getPointer();
5418 std::size_t nbOfElems=this->getNbOfElems();
5419 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5427 std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/(this->getNumberOfComponents()) << " component #" << i%(this->getNumberOfComponents());
5429 throw INTERP_KERNEL::Exception(oss.str().c_str());
5432 this->declareAsNew();
5436 * Modify all elements of \a this array, so that
5437 * an element _x_ becomes <em> val ^ x </em>.
5438 * \param [in] val - the value used to apply pow on all array elements.
5439 * \throw If \a this is not allocated.
5440 * \throw If \a val < 0.
5443 void DataArrayDiscrete<T>::applyPow(T val)
5445 this->checkAllocated();
5447 throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5448 T *ptr=this->getPointer();
5449 std::size_t nbOfElems=this->getNbOfElems();
5452 std::fill(ptr,ptr+nbOfElems,1);
5455 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5458 for(T j=0;j<val;j++)
5462 this->declareAsNew();
5466 * Modify all elements of \a this array, so that
5467 * an element _x_ becomes \f$ val ^ x \f$.
5468 * \param [in] val - the value used to apply pow on all array elements.
5469 * \throw If \a this is not allocated.
5470 * \throw If there is an element < 0 in \a this array.
5471 * \warning If an exception is thrown because of presence of 0 element in \a this
5472 * array, all elements processed before detection of the zero element remain
5476 void DataArrayDiscrete<T>::applyRPow(T val)
5478 this->checkAllocated();
5479 T *ptr=this->getPointer();
5480 std::size_t nbOfElems=this->getNbOfElems();
5481 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5486 for(T j=0;j<*ptr;j++)
5492 std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/(this->getNumberOfComponents()) << " component #" << i%(this->getNumberOfComponents());
5494 throw INTERP_KERNEL::Exception(oss.str().c_str());
5497 this->declareAsNew();
5501 * This method works only on data array with one component.
5502 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5503 * this[*id] in [\b vmin,\b vmax)
5505 * \param [in] vmin begin of range. This value is included in range (included).
5506 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5507 * \return a newly allocated data array that the caller should deal with.
5509 * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5512 DataArrayIdType *DataArrayDiscrete<T>::findIdsInRange(T vmin, T vmax) const
5514 InRange<T> ir(vmin,vmax);
5515 MCAuto<DataArrayIdType> ret(this->findIdsAdv(ir));
5520 * This method works only on data array with one component.
5521 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5522 * this[*id] \b not in [\b vmin,\b vmax)
5524 * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5525 * \param [in] vmax end of range. This value is included in range (included).
5526 * \return a newly allocated data array that the caller should deal with.
5528 * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5531 DataArrayIdType *DataArrayDiscrete<T>::findIdsNotInRange(T vmin, T vmax) const
5533 NotInRange<T> nir(vmin,vmax);
5534 MCAuto<DataArrayIdType> ret(this->findIdsAdv(nir));
5539 * This method works only on data array with one component.
5540 * 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.
5542 * \param [in] vmin begin of range. This value is included in range (included).
5543 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5544 * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5546 bool DataArrayDiscrete<T>::checkAllIdsInRange(T vmin, T vmax) const
5548 this->checkAllocated();
5549 if(this->getNumberOfComponents()!=1)
5550 throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5551 mcIdType nbOfTuples(this->getNumberOfTuples());
5553 const T *cptr=this->getConstPointer();
5554 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
5556 if(*cptr>=vmin && *cptr<vmax)
5557 { ret=ret && *cptr==i; }
5560 std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5561 throw INTERP_KERNEL::Exception(oss.str().c_str());
5568 * Returns a new DataArrayInt which contains a complement of elements of \a this
5569 * one-dimensional array. I.e. the result array contains all elements from the range [0,
5570 * \a nbOfElement) not present in \a this array.
5571 * \param [in] nbOfElement - maximal size of the result array.
5572 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5573 * array using decrRef() as it is no more needed.
5574 * \throw If \a this is not allocated.
5575 * \throw If \a this->getNumberOfComponents() != 1.
5576 * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
5580 DataArrayIdType *DataArrayDiscrete<T>::buildComplement(mcIdType nbOfElement) const
5582 this->checkAllocated();
5583 if(this->getNumberOfComponents()!=1)
5584 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
5585 std::vector<bool> tmp(nbOfElement);
5586 const T *pt=this->getConstPointer();
5587 std::size_t nbOfElements=this->getNumberOfTuples();
5588 for(const T *w=pt;w!=pt+nbOfElements;w++)
5589 if(*w>=0 && *w<nbOfElement)
5592 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
5593 std::size_t nbOfRetVal=std::count(tmp.begin(),tmp.end(),false);
5594 DataArrayIdType *ret=DataArrayIdType::New();
5595 ret->alloc(nbOfRetVal,1);
5597 mcIdType *retPtr=ret->getPointer();
5598 for(mcIdType i=0;i<nbOfElement;i++)
5605 * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
5606 * from an \a other one-dimensional array.
5607 * \param [in] other - a DataArrayInt containing elements not to include in the result array.
5608 * \return DataArrayInt * - a new instance of DataArrayInt with one component. The
5609 * caller is to delete this array using decrRef() as it is no more needed.
5610 * \throw If \a other is NULL.
5611 * \throw If \a other is not allocated.
5612 * \throw If \a other->getNumberOfComponents() != 1.
5613 * \throw If \a this is not allocated.
5614 * \throw If \a this->getNumberOfComponents() != 1.
5615 * \sa DataArrayInt::buildSubstractionOptimized()
5618 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildSubstraction(const DataArrayType *other) const
5621 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
5622 this->checkAllocated();
5623 other->checkAllocated();
5624 if(this->getNumberOfComponents()!=1)
5625 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
5626 if(other->getNumberOfComponents()!=1)
5627 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
5628 const T *pt=this->getConstPointer();
5629 std::size_t nbOfElements=this->getNumberOfTuples();
5630 std::set<T> s1(pt,pt+nbOfElements);
5631 pt=other->getConstPointer();
5632 nbOfElements=other->getNumberOfTuples();
5633 std::set<T> s2(pt,pt+nbOfElements);
5635 std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<T> >(r));
5636 DataArrayType *ret=DataArrayType::New();
5637 ret->alloc(r.size(),1);
5638 std::copy(r.begin(),r.end(),ret->getPointer());
5643 * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
5644 * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
5646 * \param [in] other an array with one component and expected to be sorted ascendingly.
5647 * \ret list of ids in \a this but not in \a other.
5648 * \sa DataArrayInt::buildSubstraction
5651 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildSubstractionOptimized(const DataArrayType *other) const
5653 static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
5654 if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
5655 this->checkAllocated(); other->checkAllocated();
5656 if(this->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5657 if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5658 const T *pt1Bg(this->begin()),*pt1End(this->end()),*pt2Bg(other->begin()),*pt2End(other->end());
5659 const T *work1(pt1Bg),*work2(pt2Bg);
5660 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(0,1);
5661 for(;work1!=pt1End;work1++)
5663 if(work2!=pt2End && *work1==*work2)
5666 ret->pushBackSilent(*work1);
5672 * Returns a new DataArrayInt which contains all elements of \a this and a given
5673 * one-dimensional arrays. The result array does not contain any duplicates
5674 * and its values are sorted in ascending order.
5675 * \param [in] other - an array to unite with \a this one.
5676 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5677 * array using decrRef() as it is no more needed.
5678 * \throw If \a this or \a other is not allocated.
5679 * \throw If \a this->getNumberOfComponents() != 1.
5680 * \throw If \a other->getNumberOfComponents() != 1.
5683 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildUnion(const DataArrayType *other) const
5685 std::vector<const DataArrayType *>arrs(2);
5686 arrs[0]=dynamic_cast<const DataArrayType *>(this); arrs[1]=other;
5687 return DataArrayDiscrete<T>::BuildUnion(arrs);
5691 * Returns a new DataArrayInt which contains elements present in both \a this and a given
5692 * one-dimensional arrays. The result array does not contain any duplicates
5693 * and its values are sorted in ascending order.
5694 * \param [in] other - an array to intersect with \a this one.
5695 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5696 * array using decrRef() as it is no more needed.
5697 * \throw If \a this or \a other is not allocated.
5698 * \throw If \a this->getNumberOfComponents() != 1.
5699 * \throw If \a other->getNumberOfComponents() != 1.
5702 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildIntersection(const DataArrayType *other) const
5704 std::vector<const DataArrayType *>arrs(2);
5705 arrs[0]=dynamic_cast<const DataArrayType *>(this); arrs[1]=other;
5706 return DataArrayDiscrete<T>::BuildIntersection(arrs);
5709 * This method can be applied on allocated with one component DataArrayInt instance.
5710 * 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.
5711 * Number of tuples of returned array is equal to size of \a this->buildUnique() + 1.
5712 * Last value of returned array is equal to \a this->getNumberOfTuples()
5715 * - \a this : [0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 5, 11]
5716 * - \a return is : [0, 1, 3, 5, 6, 8, 11, 12]
5718 * \return a newly allocated array containing the indexed array of
5719 * \throw if \a this is not allocated or if \a this has not exactly one component or if number of tuples is equal to 0.
5720 * \sa DataArrayInt::buildUnique, MEDCouplingSkyLineArray::groupPacks
5723 DataArrayIdType *DataArrayDiscrete<T>::indexOfSameConsecutiveValueGroups() const
5725 this->checkAllocated();
5726 if(this->getNumberOfComponents()!=1)
5727 throw INTERP_KERNEL::Exception("DataArrayInt::indexOfSameConsecutiveValueGroups : only single component allowed !");
5728 if(this->getNumberOfTuples()==0)
5729 throw INTERP_KERNEL::Exception("DataArrayInt::indexOfSameConsecutiveValueGroups : number of tuples must be > 0 !");
5730 const T *pt(this->begin());
5731 const T *const ptEnd(this->end()) , * const ptBg(this->begin());
5733 // first find nb of different values in this
5734 std::size_t nbOfTuplesOut(0);
5735 while( pt != ptEnd )
5738 const T *endOfPack(std::find_if(pt+1,ptEnd,[val](T elt){ return val!=elt; }));
5742 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(nbOfTuplesOut+1,1);
5743 mcIdType *retPtr(ret->getPointer()); *retPtr++ = 0;
5745 while( pt != ptEnd )
5748 const T *endOfPack(std::find_if(pt+1,ptEnd,[val](T elt){ return val!=elt; }));
5749 *retPtr++ = ToIdType( std::distance(ptBg,endOfPack) );
5757 * This method can be applied on allocated with one component DataArrayInt instance.
5758 * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
5759 * 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]
5761 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5762 * \throw if \a this is not allocated or if \a this has not exactly one component.
5763 * \sa DataArrayInt::buildUniqueNotSorted, DataArrayInt::indexOfSameConsecutiveValueGroups
5766 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildUnique() const
5768 this->checkAllocated();
5769 if(this->getNumberOfComponents()!=1)
5770 throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
5771 std::size_t nbOfElements(this->getNumberOfTuples());
5772 MCAuto<DataArrayType> tmp(DataArrayType::New());
5773 tmp->deepCopyFrom(*this);
5774 T *data(tmp->getPointer());
5775 T *last(std::unique(data,data+nbOfElements));
5776 MCAuto<DataArrayType> ret(DataArrayType::New());
5777 ret->alloc(std::distance(data,last),1);
5778 std::copy(data,last,ret->getPointer());
5783 * This method can be applied on allocated with one component DataArrayInt instance.
5784 * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
5786 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5788 * \throw if \a this is not allocated or if \a this has not exactly one component.
5790 * \sa DataArrayInt::buildUnique
5793 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildUniqueNotSorted() const
5795 this->checkAllocated();
5796 if(this->getNumberOfComponents()!=1)
5797 throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
5799 this->getMinMaxValues(minVal,maxVal);
5800 std::vector<bool> b(maxVal-minVal+1,false);
5801 const T *ptBg(this->begin()),*endBg(this->end());
5802 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(0,1);
5803 for(const T *pt=ptBg;pt!=endBg;pt++)
5807 ret->pushBackSilent(*pt);
5811 ret->copyStringInfoFrom(*this);
5816 * Returns a new DataArrayInt which contains size of every of groups described by \a this
5817 * "index" array. Such "index" array is returned for example by
5818 * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
5819 * "MEDCouplingUMesh::buildDescendingConnectivity" and
5820 * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
5821 * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
5822 * This method performs the reverse operation of DataArrayInt::computeOffsetsFull.
5823 * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
5824 * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
5825 * The caller is to delete this array using decrRef() as it is no more needed.
5826 * \throw If \a this is not allocated.
5827 * \throw If \a this->getNumberOfComponents() != 1.
5828 * \throw If \a this->getNumberOfTuples() < 2.
5831 * - this contains [1,3,6,7,7,9,15]
5832 * - result array contains [2,3,1,0,2,6],
5833 * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
5835 * \sa DataArrayInt::computeOffsetsFull
5838 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::deltaShiftIndex() const
5840 this->checkAllocated();
5841 if(this->getNumberOfComponents()!=1)
5842 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
5843 std::size_t nbOfElements=this->getNumberOfTuples();
5845 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
5846 const T *ptr=this->getConstPointer();
5847 DataArrayType *ret=DataArrayType::New();
5848 ret->alloc(nbOfElements-1,1);
5849 T *out=ret->getPointer();
5850 std::transform(ptr+1,ptr+nbOfElements,ptr,out,std::minus<T>());
5855 * Modifies \a this one-dimensional array so that value of each element \a x
5856 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5857 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
5858 * and components remains the same.<br>
5859 * This method is useful for allToAllV in MPI with contiguous policy. This method
5860 * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
5862 * \throw If \a this is not allocated.
5863 * \throw If \a this->getNumberOfComponents() != 1.
5866 * - Before \a this contains [3,5,1,2,0,8]
5867 * - After \a this contains [0,3,8,9,11,11]<br>
5868 * Note that the last element 19 = 11 + 8 is missing because size of \a this
5869 * array is retained and thus there is no space to store the last element.
5872 void DataArrayDiscrete<T>::computeOffsets()
5874 this->checkAllocated();
5875 if(this->getNumberOfComponents()!=1)
5876 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
5877 std::size_t nbOfElements=this->getNumberOfTuples();
5880 T *work=this->getPointer();
5883 for(std::size_t i=1;i<nbOfElements;i++)
5886 work[i]=work[i-1]+tmp;
5889 this->declareAsNew();
5893 * Modifies \a this one-dimensional array so that value of each element \a x
5894 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5895 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
5896 * components remains the same and number of tuples is inceamented by one.<br>
5897 * This method is useful for allToAllV in MPI with contiguous policy. This method
5898 * differs from computeOffsets() in that the number of tuples is changed by this one.
5899 * This method performs the reverse operation of DataArrayInt::deltaShiftIndex.
5900 * \throw If \a this is not allocated.
5901 * \throw If \a this->getNumberOfComponents() != 1.
5904 * - Before \a this contains [3,5,1,2,0,8]
5905 * - After \a this contains [0,3,8,9,11,11,19]<br>
5906 * \sa DataArrayInt::deltaShiftIndex
5909 void DataArrayDiscrete<T>::computeOffsetsFull()
5911 this->checkAllocated();
5912 if(this->getNumberOfComponents()!=1)
5913 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
5914 std::size_t nbOfElements=this->getNumberOfTuples();
5915 T *ret=(T *)malloc((nbOfElements+1)*sizeof(T));
5916 const T *work=this->getConstPointer();
5918 for(std::size_t i=0;i<nbOfElements;i++)
5919 ret[i+1]=work[i]+ret[i];
5920 this->useArray(ret,true,DeallocType::C_DEALLOC,nbOfElements+1,1);
5921 this->declareAsNew();
5925 * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
5926 * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
5927 * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
5928 * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
5929 * filling completely one of the ranges in \a this.
5931 * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
5932 * \param [out] rangeIdsFetched the range ids fetched
5933 * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
5934 * \a idsInInputListThatFetch is a part of input \a listOfIds.
5936 * \sa DataArrayInt::computeOffsetsFull
5939 * - \a this : [0,3,7,9,15,18]
5940 * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
5941 * - \a rangeIdsFetched result array: [0,2,4]
5942 * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
5943 * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
5947 void DataArrayDiscrete<T>::findIdsRangesInListOfIds(const DataArrayType *listOfIds, DataArrayIdType *& rangeIdsFetched, DataArrayType *& idsInInputListThatFetch) const
5950 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
5951 listOfIds->checkAllocated(); this->checkAllocated();
5952 if(listOfIds->getNumberOfComponents()!=1)
5953 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
5954 if(this->getNumberOfComponents()!=1)
5955 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
5956 MCAuto<DataArrayIdType> ret0=DataArrayIdType::New(); ret0->alloc(0,1);
5957 MCAuto<DataArrayType> ret1=DataArrayType::New(); ret1->alloc(0,1);
5958 const T *tupPtr(listOfIds->begin()), *tupEnd(listOfIds->end());
5959 const T *offBg(this->begin()),*offEnd(this->end()-1);
5960 const T *offPtr(offBg);
5961 while(tupPtr!=tupEnd && offPtr!=offEnd)
5963 if(*tupPtr==*offPtr)
5966 while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
5969 ret0->pushBackSilent(ToIdType(std::distance(offBg,offPtr)));
5970 ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
5975 { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
5977 rangeIdsFetched=ret0.retn();
5978 idsInInputListThatFetch=ret1.retn();
5982 * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
5983 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
5984 * "index" array of a "iota" array, thus, whose each element gives an index of a group
5985 * beginning within the "iota" array. And \a this is a one-dimensional array
5986 * considered as a selector of groups described by \a offsets to include into the result array.
5987 * \throw If \a offsets is NULL.
5988 * \throw If \a offsets is not allocated.
5989 * \throw If \a offsets->getNumberOfComponents() != 1.
5990 * \throw If \a offsets is not monotonically increasing.
5991 * \throw If \a this is not allocated.
5992 * \throw If \a this->getNumberOfComponents() != 1.
5993 * \throw If any element of \a this is not a valid index for \a offsets array.
5996 * - \a this: [0,2,3]
5997 * - \a offsets: [0,3,6,10,14,20]
5998 * - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
5999 * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
6000 * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) +
6001 * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) +
6002 * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
6005 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildExplicitArrByRanges(const DataArrayType *offsets) const
6008 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
6009 this->checkAllocated();
6010 if(this->getNumberOfComponents()!=1)
6011 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
6012 offsets->checkAllocated();
6013 if(offsets->getNumberOfComponents()!=1)
6014 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
6015 mcIdType othNbTuples=offsets->getNumberOfTuples()-1;
6016 mcIdType nbOfTuples=this->getNumberOfTuples();
6018 const T *work=this->getConstPointer();
6019 const T *offPtr=offsets->getConstPointer();
6020 for(mcIdType i=0;i<nbOfTuples;i++)
6023 if(val>=0 && val<othNbTuples)
6025 T delta=offPtr[val+1]-offPtr[val];
6027 retNbOftuples+=delta;
6030 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
6031 throw INTERP_KERNEL::Exception(oss.str().c_str());
6036 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
6037 oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
6038 throw INTERP_KERNEL::Exception(oss.str().c_str());
6041 MCAuto<DataArrayType> ret=DataArrayType::New();
6042 ret->alloc(retNbOftuples,1);
6043 T *retPtr=ret->getPointer();
6044 for(mcIdType i=0;i<nbOfTuples;i++)
6047 T start=offPtr[val];
6048 T off=offPtr[val+1]-start;
6049 for(T j=0;j<off;j++,retPtr++)
6056 * Returns a new DataArrayInt whose contents is computed using \a this that must be a
6057 * scaled array (monotonically increasing).
6058 from that of \a this and \a
6059 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6060 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6061 * beginning within the "iota" array. And \a this is a one-dimensional array
6062 * considered as a selector of groups described by \a offsets to include into the result array.
6063 * \throw If \a is NULL.
6064 * \throw If \a this is not allocated.
6065 * \throw If \a this->getNumberOfComponents() != 1.
6066 * \throw If \a this->getNumberOfTuples() == 0.
6067 * \throw If \a this is not monotonically increasing.
6068 * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
6071 * - \a bg , \a stop and \a step : (0,5,2)
6072 * - \a this: [0,3,6,10,14,20]
6073 * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
6076 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildExplicitArrOfSliceOnScaledArr(T bg, T stop, T step) const
6078 if(!this->isAllocated())
6079 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
6080 if(this->getNumberOfComponents()!=1)
6081 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
6082 mcIdType nbOfTuples(this->getNumberOfTuples());
6084 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
6085 const T *ids(this->begin());
6086 mcIdType nbOfEltsInSlc=DataArrayTools<T>::GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr");
6088 for(mcIdType i=0;i<nbOfEltsInSlc;i++,pos+=step)
6090 if(pos>=0 && pos<nbOfTuples-1)
6092 T delta(ids[pos+1]-ids[pos]);
6096 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
6097 throw INTERP_KERNEL::Exception(oss.str().c_str());
6102 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";
6103 throw INTERP_KERNEL::Exception(oss.str().c_str());
6106 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(sz,1);
6107 T *retPtr(ret->getPointer());
6109 for(mcIdType i=0;i<nbOfEltsInSlc;i++,pos+=step)
6111 T delta(ids[pos+1]-ids[pos]);
6112 for(T j=0;j<delta;j++,retPtr++)
6119 * 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.
6120 * 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
6121 * in tuple **i** of returned DataArrayInt.
6122 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6124 * 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)]
6125 * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6127 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6128 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6129 * \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
6130 * is thrown if no ranges in \a ranges contains value in \a this.
6132 * \sa DataArrayInt::findIdInRangeForEachTuple
6135 DataArrayIdType *DataArrayDiscrete<T>::findRangeIdForEachTuple(const DataArrayType *ranges) const
6138 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6139 if(ranges->getNumberOfComponents()!=2)
6140 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6141 this->checkAllocated();
6142 if(this->getNumberOfComponents()!=1)
6143 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6144 mcIdType nbTuples(this->getNumberOfTuples());
6145 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(nbTuples,1);
6146 mcIdType nbOfRanges(ranges->getNumberOfTuples());
6147 const T *rangesPtr=ranges->getConstPointer();
6148 mcIdType *retPtr=ret->getPointer();
6149 const T *inPtr=this->getConstPointer();
6150 for(mcIdType i=0;i<nbTuples;i++,retPtr++)
6154 for(mcIdType j=0;j<nbOfRanges && !found;j++)
6155 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6156 { *retPtr=j; found=true; }
6161 std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6162 throw INTERP_KERNEL::Exception(oss.str().c_str());
6169 * 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.
6170 * 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
6171 * in tuple **i** of returned DataArrayInt.
6172 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6174 * 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)]
6175 * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6176 * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6178 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6179 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6180 * \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
6181 * is thrown if no ranges in \a ranges contains value in \a this.
6182 * \sa DataArrayInt::findRangeIdForEachTuple
6185 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::findIdInRangeForEachTuple(const DataArrayType *ranges) const
6188 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6189 if(ranges->getNumberOfComponents()!=2)
6190 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6191 this->checkAllocated();
6192 if(this->getNumberOfComponents()!=1)
6193 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6194 mcIdType nbTuples=this->getNumberOfTuples();
6195 MCAuto<DataArrayType> ret=DataArrayType::New(); ret->alloc(nbTuples,1);
6196 mcIdType nbOfRanges=ranges->getNumberOfTuples();
6197 const T *rangesPtr=ranges->getConstPointer();
6198 T *retPtr=ret->getPointer();
6199 const T *inPtr=this->getConstPointer();
6200 for(mcIdType i=0;i<nbTuples;i++,retPtr++)
6204 for(mcIdType j=0;j<nbOfRanges && !found;j++)
6205 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6206 { *retPtr=val-rangesPtr[2*j]; found=true; }
6211 std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6212 throw INTERP_KERNEL::Exception(oss.str().c_str());
6219 * \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).
6220 * 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).
6221 * 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 !
6222 * If this method has correctly worked, \a this will be able to be considered as a linked list.
6223 * This method does nothing if number of tuples is lower of equal to 1.
6225 * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internally the connectivity without any coordinates consideration.
6227 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
6230 void DataArrayDiscrete<T>::sortEachPairToMakeALinkedList()
6232 this->checkAllocated();
6233 if(this->getNumberOfComponents()!=2)
6234 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6235 mcIdType nbOfTuples(this->getNumberOfTuples());
6238 T *conn(this->getPointer());
6239 for(mcIdType i=1;i<nbOfTuples;i++,conn+=2)
6243 if(conn[2]==conn[3])
6245 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6246 throw INTERP_KERNEL::Exception(oss.str().c_str());
6248 if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6249 std::swap(conn[2],conn[3]);
6250 //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6251 if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6253 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6254 throw INTERP_KERNEL::Exception(oss.str().c_str());
6259 if(conn[0]==conn[1] || conn[2]==conn[3])
6260 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6263 s.insert(conn,conn+4);
6265 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6266 if(std::count(conn,conn+4,conn[0])==2)
6271 if(conn[2]==conn[0])
6275 std::copy(tmp,tmp+4,conn);
6278 {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6279 if(conn[1]==conn[3])
6280 std::swap(conn[2],conn[3]);
6287 * \a this is expected to be a correctly linked list of pairs.
6289 * \sa DataArrayInt::sortEachPairToMakeALinkedList
6292 MCAuto<typename Traits<T>::ArrayType> DataArrayDiscrete<T>::fromLinkedListOfPairToList() const
6294 this->checkAllocated();
6295 this->checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6296 mcIdType nbTuples(this->getNumberOfTuples());
6298 throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6299 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(nbTuples+1,1);
6300 const T *thisPtr(this->begin());
6301 T *retPtr(ret->getPointer());
6302 retPtr[0]=thisPtr[0];
6303 for(mcIdType i=0;i<nbTuples;i++)
6305 retPtr[i+1]=thisPtr[2*i+1];
6307 if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6309 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 ?";
6310 throw INTERP_KERNEL::Exception(oss.str());
6317 * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6318 * But the number of components can be different from one.
6319 * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6322 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::getDifferentValues() const
6324 this->checkAllocated();
6326 ret.insert(this->begin(),this->end());
6327 MCAuto<DataArrayType> ret2=DataArrayType::New();
6328 ret2->alloc(ret.size(),1);
6329 std::copy(ret.begin(),ret.end(),ret2->getPointer());
6334 * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6335 * them it tells which tuple id have this id.
6336 * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6337 * This method returns two arrays having same size.
6338 * 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.
6339 * 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]]
6342 std::vector<DataArrayIdType *> DataArrayDiscrete<T>::partitionByDifferentValues(std::vector<T>& differentIds) const
6344 this->checkAllocated();
6345 if(this->getNumberOfComponents()!=1)
6346 throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6348 std::map<T,mcIdType> m,m2,m3;
6349 for(const T *w=this->begin();w!=this->end();w++)
6351 differentIds.resize(m.size());
6352 std::vector<DataArrayIdType *> ret(m.size());
6353 std::vector<mcIdType *> retPtr(m.size());
6354 for(typename std::map<T,mcIdType>::const_iterator it=m.begin();it!=m.end();it++,id++)
6357 ret[id]=DataArrayIdType::New();
6358 ret[id]->alloc((*it).second,1);
6359 retPtr[id]=ret[id]->getPointer();
6360 differentIds[id]=(*it).first;
6363 for(const T *w=this->begin();w!=this->end();w++,id++)
6365 retPtr[m2[*w]][m3[*w]++]=id;
6371 * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6372 * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6374 * \param [in] nbOfSlices - number of slices expected.
6375 * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6377 * \sa DataArray::GetSlice
6378 * \throw If \a this is not allocated or not with exactly one component.
6379 * \throw If an element in \a this if < 0.
6382 std::vector< std::pair<mcIdType,mcIdType> > DataArrayDiscrete<T>::splitInBalancedSlices(mcIdType nbOfSlices) const
6384 if(!this->isAllocated() || this->getNumberOfComponents()!=1)
6385 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6387 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6388 T sum(this->accumulate((std::size_t)0));
6389 mcIdType nbOfTuples(this->getNumberOfTuples());
6390 T sumPerSlc(sum/FromIdType<T>(nbOfSlices));
6392 const T *w(this->begin());
6393 std::vector< std::pair<mcIdType,mcIdType> > ret(nbOfSlices);
6394 for(mcIdType i=0;i<nbOfSlices;i++)
6396 std::pair<mcIdType, mcIdType> p(pos,-1);
6398 while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6402 p.second=nbOfTuples;
6409 * Modify \a this array so that each value becomes a modulus of division of this value by
6410 * a value of another DataArrayInt. There are 3 valid cases.
6411 * 1. The arrays have same number of tuples and components. Then each value of
6412 * \a this array is divided by the corresponding value of \a other one, i.e.:
6413 * _a_ [ i, j ] %= _other_ [ i, j ].
6414 * 2. The arrays have same number of tuples and \a other array has one component. Then
6415 * _a_ [ i, j ] %= _other_ [ i, 0 ].
6416 * 3. The arrays have same number of components and \a other array has one tuple. Then
6417 * _a_ [ i, j ] %= _a2_ [ 0, j ].
6419 * \warning No check of division by zero is performed!
6420 * \param [in] other - a divisor array.
6421 * \throw If \a other is NULL.
6422 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
6423 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
6424 * \a other has number of both tuples and components not equal to 1.
6427 void DataArrayDiscrete<T>::modulusEqual(const DataArrayType *other)
6430 throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
6431 const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
6432 this->checkAllocated(); other->checkAllocated();
6433 mcIdType nbOfTuple(this->getNumberOfTuples());
6434 mcIdType nbOfTuple2(other->getNumberOfTuples());
6435 std::size_t nbOfComp(this->getNumberOfComponents());
6436 std::size_t nbOfComp2(other->getNumberOfComponents());
6437 if(nbOfTuple==nbOfTuple2)
6439 if(nbOfComp==nbOfComp2)
6441 std::transform(this->begin(),this->end(),other->begin(),this->getPointer(),std::modulus<T>());
6443 else if(nbOfComp2==1)
6445 if(nbOfComp2==nbOfComp)
6447 T *ptr=this->getPointer();
6448 const T *ptrc=other->getConstPointer();
6449 for(mcIdType i=0;i<nbOfTuple;i++)
6450 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<T>(),*ptrc++));
6453 throw INTERP_KERNEL::Exception(msg);
6456 throw INTERP_KERNEL::Exception(msg);
6458 else if(nbOfTuple2==1)
6460 T *ptr=this->getPointer();
6461 const T *ptrc=other->getConstPointer();
6462 for(mcIdType i=0;i<nbOfTuple;i++)
6463 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<T>());
6466 throw INTERP_KERNEL::Exception(msg);
6467 this->declareAsNew();
6471 * Apply pow on values of another DataArrayInt to values of \a this one.
6473 * \param [in] other - an array to pow to \a this one.
6474 * \throw If \a other is NULL.
6475 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
6476 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
6477 * \throw If there is a negative value in \a other.
6480 void DataArrayDiscrete<T>::powEqual(const DataArrayType *other)
6483 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
6484 mcIdType nbOfTuple=this->getNumberOfTuples();
6485 mcIdType nbOfTuple2=other->getNumberOfTuples();
6486 std::size_t nbOfComp=this->getNumberOfComponents();
6487 std::size_t nbOfComp2=other->getNumberOfComponents();
6488 if(nbOfTuple!=nbOfTuple2)
6489 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
6490 if(nbOfComp!=1 || nbOfComp2!=1)
6491 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
6492 T *ptr=this->getPointer();
6493 const T *ptrc=other->begin();
6494 for(mcIdType i=0;i<nbOfTuple;i++,ptrc++,ptr++)
6499 for(T j=0;j<*ptrc;j++)
6505 std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
6506 throw INTERP_KERNEL::Exception(oss.str().c_str());
6509 this->declareAsNew();
6512 ////////////////////////////////////
6514 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6518 void DataArrayDiscrete<T>::getTinySerializationIntInformation(std::vector<mcIdType>& tinyInfo) const
6521 if(this->isAllocated())
6523 tinyInfo[0]=this->getNumberOfTuples();
6524 tinyInfo[1]=ToIdType(this->getNumberOfComponents());
6534 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6538 void DataArrayDiscrete<T>::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
6540 if(this->isAllocated())
6542 std::size_t nbOfCompo(this->getNumberOfComponents());
6543 tinyInfo.resize(nbOfCompo+1);
6544 tinyInfo[0]=this->getName();
6545 for(std::size_t i=0;i<nbOfCompo;i++)
6546 tinyInfo[i+1]=this->getInfoOnComponent(i);
6551 tinyInfo[0]=this->getName();
6556 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6557 * This method returns if a feeding is needed.
6560 bool DataArrayDiscrete<T>::resizeForUnserialization(const std::vector<mcIdType>& tinyInfoI)
6562 mcIdType nbOfTuple=tinyInfoI[0];
6563 mcIdType nbOfComp=tinyInfoI[1];
6564 if(nbOfTuple!=-1 || nbOfComp!=-1)
6566 this->alloc(nbOfTuple,nbOfComp);
6573 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6574 * This method returns if a feeding is needed.
6577 void DataArrayDiscrete<T>::finishUnserialization(const std::vector<mcIdType>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
6579 this->setName(tinyInfoS[0]);
6580 if(this->isAllocated())
6582 mcIdType nbOfCompo=tinyInfoI[1];
6583 for(mcIdType i=0;i<nbOfCompo;i++)
6584 this->setInfoOnComponent(i,tinyInfoS[i+1]);
6588 ////////////////////////////////////
6591 * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
6594 * \param [in] a1 - an array to pow up.
6595 * \param [in] a2 - another array to sum up.
6596 * \return DataArrayInt * - the new instance of DataArrayInt.
6597 * The caller is to delete this result array using decrRef() as it is no more
6599 * \throw If either \a a1 or \a a2 is NULL.
6600 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6601 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
6602 * \throw If there is a negative value in \a a2.
6605 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Pow(const DataArrayType *a1, const DataArrayType *a2)
6608 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
6609 mcIdType nbOfTuple=a1->getNumberOfTuples();
6610 mcIdType nbOfTuple2=a2->getNumberOfTuples();
6611 std::size_t nbOfComp=a1->getNumberOfComponents();
6612 std::size_t nbOfComp2=a2->getNumberOfComponents();
6613 if(nbOfTuple!=nbOfTuple2)
6614 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
6615 if(nbOfComp!=1 || nbOfComp2!=1)
6616 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
6617 MCAuto<DataArrayType> ret=DataArrayType::New(); ret->alloc(nbOfTuple,1);
6618 const T *ptr1(a1->begin()),*ptr2(a2->begin());
6619 T *ptr=ret->getPointer();
6620 for(mcIdType i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
6625 for(T j=0;j<*ptr2;j++)
6631 std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
6632 throw INTERP_KERNEL::Exception(oss.str().c_str());
6639 * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6641 * 1. The arrays have same number of tuples and components. Then each value of
6642 * the result array (_a_) is a division of the corresponding values of \a a1 and
6643 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6644 * 2. The arrays have same number of tuples and one array, say _a2_, has one
6646 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6647 * 3. The arrays have same number of components and one array, say _a2_, has one
6649 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6651 * Info on components is copied either from the first array (in the first case) or from
6652 * the array with maximal number of elements (getNbOfElems()).
6653 * \warning No check of division by zero is performed!
6654 * \param [in] a1 - a dividend array.
6655 * \param [in] a2 - a divisor array.
6656 * \return DataArrayInt * - the new instance of DataArrayInt.
6657 * The caller is to delete this result array using decrRef() as it is no more
6659 * \throw If either \a a1 or \a a2 is NULL.
6660 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6661 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6662 * none of them has number of tuples or components equal to 1.
6665 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Modulus(const DataArrayType *a1, const DataArrayType *a2)
6668 throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6669 mcIdType nbOfTuple1(a1->getNumberOfTuples());
6670 mcIdType nbOfTuple2(a2->getNumberOfTuples());
6671 std::size_t nbOfComp1(a1->getNumberOfComponents());
6672 std::size_t nbOfComp2(a2->getNumberOfComponents());
6673 if(nbOfTuple2==nbOfTuple1)
6675 if(nbOfComp1==nbOfComp2)
6677 MCAuto<DataArrayType> ret=DataArrayType::New();
6678 ret->alloc(nbOfTuple2,nbOfComp1);
6679 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<T>());
6680 ret->copyStringInfoFrom(*a1);
6683 else if(nbOfComp2==1)
6685 MCAuto<DataArrayType> ret=DataArrayType::New();
6686 ret->alloc(nbOfTuple1,nbOfComp1);
6687 const T *a2Ptr=a2->getConstPointer();
6688 const T *a1Ptr=a1->getConstPointer();
6689 T *res=ret->getPointer();
6690 for(mcIdType i=0;i<nbOfTuple1;i++)
6691 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<T>(),a2Ptr[i]));
6692 ret->copyStringInfoFrom(*a1);
6697 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6701 else if(nbOfTuple2==1)
6703 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6704 MCAuto<DataArrayType> ret=DataArrayType::New();
6705 ret->alloc(nbOfTuple1,nbOfComp1);
6706 const T *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6707 T *pt=ret->getPointer();
6708 for(mcIdType i=0;i<nbOfTuple1;i++)
6709 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<T>());
6710 ret->copyStringInfoFrom(*a1);
6715 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
6721 * 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
6722 * input array \a ids2.
6723 * \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.
6724 * 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
6726 * In case of success both assertion will be true (no throw) :
6727 * \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
6728 * \c ret->transformWithIndArr(ids2)->isEqual(ids1)
6731 * - \a ids1 : [3,1,103,4,6,10,-7,205]
6732 * - \a ids2 : [-7,1,205,10,6,3,103,4]
6733 * - \a return is : [5,1,6,7,4,3,0,2] because ids2[5]==ids1[0], ids2[1]==ids1[1], ids2[6]==ids1[2]...
6735 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6736 * array using decrRef() as it is no more needed.
6737 * \throw If either ids1 or ids2 is null not allocated or not with one components.
6739 * \sa DataArrayInt::findIdForEach, DataArrayInt::FindPermutationFromFirstToSecondDuplicate, DataArrayInt::rankOfElementInThis
6742 DataArrayIdType *DataArrayDiscrete<T>::FindPermutationFromFirstToSecond(const DataArrayType *ids1, const DataArrayType *ids2)
6745 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
6746 if(!ids1->isAllocated() || !ids2->isAllocated())
6747 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
6748 if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
6749 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
6750 if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
6752 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 !";
6753 throw INTERP_KERNEL::Exception(oss.str().c_str());
6755 MCAuto<DataArrayType> c1(ids1->deepCopy());
6756 MCAuto<DataArrayType> c2(ids2->deepCopy());
6757 c1->sort(true); c2->sort(true);
6758 if(!c1->isEqualWithoutConsideringStr(*c2))
6759 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
6760 MCAuto<DataArrayIdType> p1=ids1->checkAndPreparePermutation();
6761 MCAuto<DataArrayIdType> p2=ids2->checkAndPreparePermutation();
6762 p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
6763 p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
6768 * 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
6769 * input array \a ids2.
6770 * \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.
6771 * 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
6773 * The difference with DataArrayInt::FindPermutationFromFirstToSecond is that this method supports multiple same values in \a ids1 and \a ids2 whereas
6774 * DataArrayInt::FindPermutationFromFirstToSecond doesn't. It implies that this method my be slower than the DataArrayInt::FindPermutationFromFirstToSecond one.
6776 * In case of success both assertion will be true (no throw) :
6777 * \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
6778 * \c ret->transformWithIndArr(ids2)->isEqual(ids1)
6781 * - \a ids1 : [5, 3, 2, 1, 4, 5, 2, 1, 0, 11, 5, 4]
6782 * - \a ids2 : [0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 5, 11]
6783 * - \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]...
6785 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6786 * array using decrRef() as it is no more needed.
6787 * \throw If either ids1 or ids2 is null not allocated or not with one components.
6789 * \sa DataArrayInt::findIdForEach, DataArrayInt::FindPermutationFromFirstToSecond, DataArrayInt::occurenceRankInThis
6792 DataArrayIdType *DataArrayDiscrete<T>::FindPermutationFromFirstToSecondDuplicate(const DataArrayType *ids1, const DataArrayType *ids2)
6795 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecondDuplicate : the two input arrays must be not null !");
6796 constexpr char MSG0[] = "DataArrayInt::FindPermutationFromFirstToSecondDuplicate :";
6797 ids1->checkAllocated(); ids2->checkAllocated();
6798 ids1->checkNbOfComps(1,MSG0); ids2->checkNbOfComps(1,MSG0);
6799 mcIdType nbTuples(ids1->getNumberOfTuples());
6800 if(nbTuples != ids2->getNumberOfTuples())
6802 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 !";
6803 throw INTERP_KERNEL::Exception(oss.str().c_str());
6805 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(nbTuples,1);
6806 MCAuto<DataArrayIdType> oids2(ids2->occurenceRankInThis());
6807 std::map< std::pair<T,mcIdType>, mcIdType> m;
6809 const mcIdType *oids2Ptr(oids2->begin());
6810 for(const T * it2 = ids2->begin() ; it2 != ids2->end() ; ++it2, ++oids2Ptr, ++pos)
6811 m[{*it2,*oids2Ptr}] = pos;
6812 mcIdType *retPtr(ret->getPointer());
6814 std::map<T,mcIdType> mOccurence1; // see DataArrayInt::occurenceRankInThis : avoid to compute additionnal temporary array
6816 for(const T * it1 = ids1->begin() ; it1 != ids1->end() ; ++it1, ++retPtr)
6818 auto it = mOccurence1.find(*it1);
6820 if( it == mOccurence1.end() )
6823 mOccurence1[*it1] = 1;
6827 occRk1 = (*it).second++;
6830 auto it2 = m.find({*it1,occRk1});
6833 *retPtr = (*it2).second;
6837 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 !";
6838 throw INTERP_KERNEL::Exception(oss.str());
6846 * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
6847 * This map, if applied to \a start array, would make it sorted. For example, if
6848 * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
6849 * [5,6,0,3,2,7,1,4].
6850 * \param [in] start - pointer to the first element of the array for which the
6851 * permutation map is computed.
6852 * \param [in] end - pointer specifying the end of the array \a start, so that
6853 * the last value of \a start is \a end[ -1 ].
6854 * \return mcIdType * - the result permutation array that the caller is to delete as it is no
6856 * \throw If there are equal values in the input array.
6859 mcIdType *DataArrayDiscrete<T>::CheckAndPreparePermutation(const T *start, const T *end)
6861 std::size_t sz=std::distance(start,end);
6862 mcIdType *ret=(mcIdType *)malloc(sz*sizeof(mcIdType));
6864 std::copy(start,end,work);
6865 std::sort(work,work+sz);
6866 if(std::unique(work,work+sz)!=work+sz)
6870 throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
6872 std::map<T,mcIdType> m;
6873 for(T *workPt=work;workPt!=work+sz;workPt++)
6874 m[*workPt]=ToIdType(std::distance(work,workPt));
6875 mcIdType *iter2=ret;
6876 for(const T *iter=start;iter!=end;iter++,iter2++)
6883 * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
6884 * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
6885 * offsetA2</em> and (2)
6886 * the number of component in the result array is same as that of each of given arrays.
6887 * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
6888 * Info on components is copied from the first of the given arrays. Number of components
6889 * in the given arrays must be the same.
6890 * \param [in] a1 - an array to include in the result array.
6891 * \param [in] a2 - another array to include in the result array.
6892 * \param [in] offsetA2 - number of tuples of \a a2 to skip.
6893 * \return DataArrayInt * - the new instance of DataArrayInt.
6894 * The caller is to delete this result array using decrRef() as it is no more
6896 * \throw If either \a a1 or \a a2 is NULL.
6897 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
6900 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Aggregate(const DataArrayType *a1, const DataArrayType *a2, T offsetA2)
6903 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
6904 std::size_t nbOfComp(a1->getNumberOfComponents());
6905 if(nbOfComp!=a2->getNumberOfComponents())
6906 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
6907 mcIdType nbOfTuple1(a1->getNumberOfTuples()),nbOfTuple2(a2->getNumberOfTuples());
6908 MCAuto<DataArrayType> ret(DataArrayType::New());
6909 ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
6910 T *pt=std::copy(a1->begin(),a1->end(),ret->getPointer());
6911 std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
6912 ret->copyStringInfoFrom(*a1);
6917 * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
6918 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
6919 * the number of component in the result array is same as that of each of given arrays.
6920 * Info on components is copied from the first of the given arrays. Number of components
6921 * in the given arrays must be the same.
6922 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
6923 * not the object itself.
6924 * \param [in] arr - a sequence of arrays to include in the result array.
6925 * \return DataArrayInt * - the new instance of DataArrayInt.
6926 * The caller is to delete this result array using decrRef() as it is no more
6928 * \throw If all arrays within \a arr are NULL.
6929 * \throw If getNumberOfComponents() of arrays within \a arr.
6932 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Aggregate(const std::vector<const DataArrayType *>& arr)
6934 std::vector<const DataArrayType *> a;
6935 for(typename std::vector<const DataArrayType *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6939 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
6940 typename std::vector<const DataArrayType *>::const_iterator it=a.begin();
6941 std::size_t nbOfComp((*it)->getNumberOfComponents());
6942 mcIdType nbt((*it++)->getNumberOfTuples());
6943 for(;it!=a.end();it++)
6945 if((*it)->getNumberOfComponents()!=nbOfComp)
6946 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
6947 nbt+=(*it)->getNumberOfTuples();
6949 MCAuto<DataArrayType> ret=DataArrayType::New();
6950 ret->alloc(nbt,nbOfComp);
6951 T *pt=ret->getPointer();
6952 for(it=a.begin();it!=a.end();it++)
6953 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
6954 ret->copyStringInfoFrom(*(a[0]));
6959 * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
6960 * A packed index array is an allocated array with one component, and at least one tuple. The first element
6961 * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
6962 * 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.
6964 * \return DataArrayInt * - a new object to be managed by the caller.
6967 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::AggregateIndexes(const std::vector<const DataArrayType *>& arrs)
6970 for(typename std::vector<const DataArrayType *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
6974 (*it4)->checkAllocated();
6975 if((*it4)->getNumberOfComponents()!=1)
6977 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6978 throw INTERP_KERNEL::Exception(oss.str().c_str());
6980 mcIdType nbTupl((*it4)->getNumberOfTuples());
6983 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6984 throw INTERP_KERNEL::Exception(oss.str().c_str());
6986 if((*it4)->front()!=0)
6988 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
6989 throw INTERP_KERNEL::Exception(oss.str().c_str());
6995 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
6996 throw INTERP_KERNEL::Exception(oss.str().c_str());
7000 throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
7001 MCAuto<DataArrayType> ret=DataArrayType::New();
7002 ret->alloc(retSz,1);
7003 T *pt=ret->getPointer(); *pt++=0;
7004 for(typename std::vector<const DataArrayType *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
7005 pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<T>(),pt[-1]));
7006 ret->copyStringInfoFrom(*(arrs[0]));
7011 * Returns a new DataArrayInt which contains all elements of given one-dimensional
7012 * arrays. The result array does not contain any duplicates and its values
7013 * are sorted in ascending order.
7014 * \param [in] arr - sequence of DataArrayInt's to unite.
7015 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7016 * array using decrRef() as it is no more needed.
7017 * \throw If any \a arr[i] is not allocated.
7018 * \throw If \a arr[i]->getNumberOfComponents() != 1.
7021 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::BuildUnion(const std::vector<const DataArrayType *>& arr)
7023 std::vector<const DataArrayType *> a;
7024 for(typename std::vector<const DataArrayType *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7027 for(typename std::vector<const DataArrayType *>::const_iterator it=a.begin();it!=a.end();it++)
7029 (*it)->checkAllocated();
7030 if((*it)->getNumberOfComponents()!=1)
7031 throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
7035 for(typename std::vector<const DataArrayType *>::const_iterator it=a.begin();it!=a.end();it++)
7037 const T *pt=(*it)->getConstPointer();
7038 mcIdType nbOfTuples((*it)->getNumberOfTuples());
7039 r.insert(pt,pt+nbOfTuples);
7041 DataArrayType *ret=DataArrayType::New();
7042 ret->alloc(r.size(),1);
7043 std::copy(r.begin(),r.end(),ret->getPointer());
7048 * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
7049 * arrays. The result array does not contain any duplicates and its values
7050 * are sorted in ascending order.
7051 * \param [in] arr - sequence of DataArrayInt's to intersect.
7052 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7053 * array using decrRef() as it is no more needed.
7054 * \throw If any \a arr[i] is not allocated.
7055 * \throw If \a arr[i]->getNumberOfComponents() != 1.
7058 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::BuildIntersection(const std::vector<const DataArrayType *>& arr)
7060 std::vector<const DataArrayType *> a;
7061 for(typename std::vector<const DataArrayType *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7064 for(typename std::vector<const DataArrayType *>::const_iterator it=a.begin();it!=a.end();it++)
7066 (*it)->checkAllocated();
7067 if((*it)->getNumberOfComponents()!=1)
7068 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
7072 for(typename std::vector<const DataArrayType *>::const_iterator it=a.begin();it!=a.end();it++)
7074 const T *pt=(*it)->getConstPointer();
7075 mcIdType nbOfTuples((*it)->getNumberOfTuples());
7076 std::set<T> s1(pt,pt+nbOfTuples);
7080 std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
7086 DataArrayType *ret(DataArrayType::New());
7087 ret->alloc(r.size(),1);
7088 std::copy(r.begin(),r.end(),ret->getPointer());
7093 * This method allows to put a vector of vector of integer into a more compact data structure (skyline).
7094 * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<mcIdType> >.
7096 * \param [in] v the input data structure to be translate into skyline format.
7097 * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
7098 * \param [out] dataIndex the second element of the skyline format.
7101 void DataArrayDiscrete<T>::PutIntoToSkylineFrmt(const std::vector< std::vector<T> >& v, DataArrayType *& data, DataArrayIdType *& dataIndex)
7103 std::size_t sz(v.size());
7104 MCAuto<DataArrayType> retDat(DataArrayType::New());
7105 MCAuto<DataArrayIdType> retIdx(DataArrayIdType::New());
7106 retIdx->alloc(sz+1,1);
7107 mcIdType *ptid(retIdx->getPointer()); *ptid=0;
7108 for(std::size_t i=0;i<sz;i++,ptid++)
7109 ptid[1]=ptid[0]+ToIdType(v[i].size());
7110 retDat->alloc(retIdx->back(),1);
7111 T *pt=retDat->getPointer();
7112 for(std::size_t i=0;i<sz;i++)
7113 pt=std::copy(v[i].begin(),v[i].end(),pt);
7114 data=retDat.retn(); dataIndex=retIdx.retn();
7118 * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn
7119 * (\ref numbering-indirect).
7120 * This method returns the result of the extraction ( specified by a set of ids in [\b idsOfSelectBg , \b idsOfSelectEnd ) ).
7121 * The selection of extraction is done standardly in new2old format.
7122 * This method returns indexed arrays (\ref numbering-indirect) using 2 arrays (arrOut,arrIndexOut).
7124 * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
7125 * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
7126 * \param [in] arrIn arr origin array from which the extraction will be done.
7127 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7128 * \param [out] arrOut the resulting array
7129 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
7130 * \sa DataArrayInt::ExtractFromIndexedArraysSlice
7133 void DataArrayDiscrete<T>::ExtractFromIndexedArrays(const mcIdType *idsOfSelectBg, const mcIdType *idsOfSelectEnd,
7134 const DataArrayType *arrIn, const DataArrayIdType *arrIndxIn,
7135 DataArrayType* &arrOut, DataArrayIdType* &arrIndexOut)
7137 if(!arrIn || !arrIndxIn)
7138 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArrays : input pointer is NULL !");
7139 arrIn->checkAllocated(); arrIndxIn->checkAllocated();
7140 if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1)
7141 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArrays : input arrays must have exactly one component !");
7142 std::size_t sz=std::distance(idsOfSelectBg,idsOfSelectEnd);
7143 const T *arrInPtr=arrIn->begin();
7144 const mcIdType *arrIndxPtr=arrIndxIn->begin();
7145 mcIdType nbOfGrps=arrIndxIn->getNumberOfTuples()-1;
7147 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArrays : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !");
7148 mcIdType maxSizeOfArr(arrIn->getNumberOfTuples());
7149 MCAuto<DataArrayType> arro=DataArrayType::New();
7150 MCAuto<DataArrayIdType> arrIo=DataArrayIdType::New();
7151 arrIo->alloc(sz+1,1);
7152 const mcIdType *idsIt=idsOfSelectBg;
7153 mcIdType *work=arrIo->getPointer();
7156 for(std::size_t i=0;i<sz;i++,work++,idsIt++)
7158 if(*idsIt>=0 && *idsIt<nbOfGrps)
7159 lgth+=arrIndxPtr[*idsIt+1]-arrIndxPtr[*idsIt];
7162 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " ! Must be in [0," << nbOfGrps << ") !";
7163 throw INTERP_KERNEL::Exception(oss.str());
7169 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " and at this pos arrIndxIn[" << *idsIt;
7170 oss << "+1]-arrIndxIn[" << *idsIt << "] < 0 ! The input index array is bugged !";
7171 throw INTERP_KERNEL::Exception(oss.str());
7174 arro->alloc(lgth,1);
7175 T *data=arro->getPointer();
7176 idsIt=idsOfSelectBg;
7177 for(std::size_t i=0;i<sz;i++,idsIt++)
7179 if(arrIndxPtr[*idsIt]>=0 && arrIndxPtr[*idsIt+1]<=maxSizeOfArr)
7180 data=std::copy(arrInPtr+arrIndxPtr[*idsIt],arrInPtr+arrIndxPtr[*idsIt+1],data);
7183 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " arrIndx[" << *idsIt << "] must be >= 0 and arrIndx[";
7184 oss << *idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!";
7185 throw INTERP_KERNEL::Exception(oss.str());
7189 arrIndexOut=arrIo.retn();
7193 * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn
7194 * (\ref numbering-indirect).
7195 * 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 ).
7196 * The selection of extraction is done standardly in new2old format.
7197 * This method returns indexed arrays (\ref numbering-indirect) using 2 arrays (arrOut,arrIndexOut).
7199 * \param [in] idsOfSelectStart begin of set of ids of the input extraction (included)
7200 * \param [in] idsOfSelectStop end of set of ids of the input extraction (excluded)
7201 * \param [in] idsOfSelectStep
7202 * \param [in] arrIn arr origin array from which the extraction will be done.
7203 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7204 * \param [out] arrOut the resulting array
7205 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
7206 * \sa DataArrayInt::ExtractFromIndexedArrays
7209 void DataArrayDiscrete<T>::ExtractFromIndexedArraysSlice(mcIdType idsOfSelectStart, mcIdType idsOfSelectStop, mcIdType idsOfSelectStep,
7210 const DataArrayType *arrIn, const DataArrayIdType *arrIndxIn,
7211 DataArrayType* &arrOut, DataArrayIdType* &arrIndexOut)
7213 if(!arrIn || !arrIndxIn)
7214 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArraysSlice : input pointer is NULL !");
7215 arrIn->checkAllocated(); arrIndxIn->checkAllocated();
7216 if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1)
7217 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArraysSlice : input arrays must have exactly one component !");
7218 mcIdType sz=DataArray::GetNumberOfItemGivenBESRelative(idsOfSelectStart,idsOfSelectStop,idsOfSelectStep,"MEDCouplingUMesh::ExtractFromIndexedArraysSlice : Input slice ");
7219 const T *arrInPtr=arrIn->begin();
7220 const mcIdType *arrIndxPtr=arrIndxIn->begin();
7221 mcIdType nbOfGrps=arrIndxIn->getNumberOfTuples()-1;
7223 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArraysSlice : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !");
7224 mcIdType maxSizeOfArr(arrIn->getNumberOfTuples());
7225 MCAuto<DataArrayType> arro=DataArrayType::New();
7226 MCAuto<DataArrayIdType> arrIo=DataArrayIdType::New();
7227 arrIo->alloc(sz+1,1);
7228 mcIdType idsIt=idsOfSelectStart;
7229 mcIdType *work=arrIo->getPointer();
7232 for(mcIdType i=0;i<sz;i++,work++,idsIt+=idsOfSelectStep)
7234 if(idsIt>=0 && idsIt<nbOfGrps)
7235 lgth+=arrIndxPtr[idsIt+1]-arrIndxPtr[idsIt];
7238 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArraysSlice : id located on pos #" << i << " value is " << idsIt << " ! Must be in [0," << nbOfGrps << ") !";
7239 throw INTERP_KERNEL::Exception(oss.str());
7245 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArraysSlice : id located on pos #" << i << " value is " << idsIt << " and at this pos arrIndxIn[" << idsIt;
7246 oss << "+1]-arrIndxIn[" << idsIt << "] < 0 ! The input index array is bugged !";
7247 throw INTERP_KERNEL::Exception(oss.str());
7250 arro->alloc(lgth,1);
7251 T *data=arro->getPointer();
7252 idsIt=idsOfSelectStart;
7253 for(mcIdType i=0;i<sz;i++,idsIt+=idsOfSelectStep)
7255 if(arrIndxPtr[idsIt]>=0 && arrIndxPtr[idsIt+1]<=maxSizeOfArr)
7256 data=std::copy(arrInPtr+arrIndxPtr[idsIt],arrInPtr+arrIndxPtr[idsIt+1],data);
7259 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArraysSlice : id located on pos #" << i << " value is " << idsIt << " arrIndx[" << idsIt << "] must be >= 0 and arrIndx[";
7260 oss << idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!";
7261 throw INTERP_KERNEL::Exception(oss.str());
7265 arrIndexOut=arrIo.retn();
7269 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
7270 * 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
7271 * cellIds \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex).
7272 * This method is an generalization of MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitly a result output arrays.
7274 * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
7275 * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
7276 * \param [in] arrIn arr origin array from which the extraction will be done.
7277 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7278 * \param [in] srcArr input array that will be used as source of copy for ids in [ \b idsOfSelectBg, \b idsOfSelectEnd )
7279 * \param [in] srcArrIndex index array of \b srcArr
7280 * \param [out] arrOut the resulting array
7281 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
7283 * \sa DataArrayInt::SetPartOfIndexedArraysSameIdx
7286 void DataArrayDiscrete<T>::SetPartOfIndexedArrays(const mcIdType *idsOfSelectBg, const mcIdType *idsOfSelectEnd,
7287 const DataArrayType *arrIn, const DataArrayIdType *arrIndxIn,
7288 const DataArrayType *srcArr, const DataArrayIdType *srcArrIndex,
7289 DataArrayType* &arrOut, DataArrayIdType* &arrIndexOut)
7291 if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
7292 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArrays : presence of null pointer in input parameter !");
7293 MCAuto<DataArrayType> arro=DataArrayType::New();
7294 MCAuto<DataArrayIdType> arrIo=DataArrayIdType::New();
7295 mcIdType nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
7296 std::vector<bool> v(nbOfTuples,true);
7298 const mcIdType *arrIndxInPtr=arrIndxIn->begin();
7299 const mcIdType *srcArrIndexPtr=srcArrIndex->begin();
7300 for(const mcIdType *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++)
7302 if(*it>=0 && *it<nbOfTuples)
7305 offset+=(srcArrIndexPtr[1]-srcArrIndexPtr[0])-(arrIndxInPtr[*it+1]-arrIndxInPtr[*it]);
7309 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArrays : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !";
7310 throw INTERP_KERNEL::Exception(oss.str());
7313 srcArrIndexPtr=srcArrIndex->begin();
7314 arrIo->alloc(nbOfTuples+1,1);
7315 arro->alloc(arrIn->getNumberOfTuples()+offset,1);
7316 const T *arrInPtr=arrIn->begin();
7317 const T *srcArrPtr=srcArr->begin();
7318 mcIdType *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0;
7319 T *arroPtr=arro->getPointer();
7320 for(mcIdType ii=0;ii<nbOfTuples;ii++,arrIoPtr++)
7324 arroPtr=std::copy(arrInPtr+arrIndxInPtr[ii],arrInPtr+arrIndxInPtr[ii+1],arroPtr);
7325 *arrIoPtr=arrIoPtr[-1]+(arrIndxInPtr[ii+1]-arrIndxInPtr[ii]);
7329 std::size_t pos=std::distance(idsOfSelectBg,std::find(idsOfSelectBg,idsOfSelectEnd,ii));
7330 arroPtr=std::copy(srcArrPtr+srcArrIndexPtr[pos],srcArrPtr+srcArrIndexPtr[pos+1],arroPtr);
7331 *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]);
7335 arrIndexOut=arrIo.retn();
7339 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
7340 * 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
7341 * cellIds \b in [\b idsOfSelectBg, \b idsOfSelectEnd) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex).
7342 * This method is an generalization of DataArrayInt::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitly a result output arrays.
7344 * \param [in] start begin of set of ids of the input extraction (included)
7345 * \param [in] end end of set of ids of the input extraction (excluded)
7346 * \param [in] step step of the set of ids in range mode.
7347 * \param [in] arrIn arr origin array from which the extraction will be done.
7348 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7349 * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd)
7350 * \param [in] srcArrIndex index array of \b srcArr
7351 * \param [out] arrOut the resulting array
7352 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
7354 * \sa DataArrayInt::SetPartOfIndexedArraysSameIdx DataArrayInt::SetPartOfIndexedArrays
7357 void DataArrayDiscrete<T>::SetPartOfIndexedArraysSlice(mcIdType start, mcIdType end, mcIdType step,
7358 const DataArrayType *arrIn, const DataArrayIdType *arrIndxIn,
7359 const DataArrayType *srcArr, const DataArrayIdType *srcArrIndex,
7360 DataArrayType* &arrOut, DataArrayIdType* &arrIndexOut)
7362 if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
7363 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArraysSlice : presence of null pointer in input parameter !");
7364 MCAuto<DataArrayType> arro=DataArrayType::New();
7365 MCAuto<DataArrayIdType> arrIo=DataArrayIdType::New();
7366 mcIdType nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
7368 const mcIdType *arrIndxInPtr=arrIndxIn->begin();
7369 const mcIdType *srcArrIndexPtr=srcArrIndex->begin();
7370 mcIdType nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"DataArrayInt::SetPartOfIndexedArraysSlice : ");
7372 for(mcIdType i=0;i<nbOfElemsToSet;i++,srcArrIndexPtr++,it+=step)
7374 if(it>=0 && it<nbOfTuples)
7375 offset+=(srcArrIndexPtr[1]-srcArrIndexPtr[0])-(arrIndxInPtr[it+1]-arrIndxInPtr[it]);
7378 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSlice : On pos #" << i << " value is " << it << " not in [0," << nbOfTuples << ") !";
7379 throw INTERP_KERNEL::Exception(oss.str());
7382 srcArrIndexPtr=srcArrIndex->begin();
7383 arrIo->alloc(nbOfTuples+1,1);
7384 arro->alloc(arrIn->getNumberOfTuples()+offset,1);
7385 const T *arrInPtr=arrIn->begin();
7386 const T *srcArrPtr=srcArr->begin();
7387 mcIdType *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0;
7388 T *arroPtr=arro->getPointer();
7389 for(mcIdType ii=0;ii<nbOfTuples;ii++,arrIoPtr++)
7391 mcIdType pos=DataArray::GetPosOfItemGivenBESRelativeNoThrow(ii,start,end,step);
7394 arroPtr=std::copy(arrInPtr+arrIndxInPtr[ii],arrInPtr+arrIndxInPtr[ii+1],arroPtr);
7395 *arrIoPtr=arrIoPtr[-1]+(arrIndxInPtr[ii+1]-arrIndxInPtr[ii]);
7399 arroPtr=std::copy(srcArrPtr+srcArrIndexPtr[pos],srcArrPtr+srcArrIndexPtr[pos+1],arroPtr);
7400 *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]);
7404 arrIndexOut=arrIo.retn();
7408 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
7409 * This method is an specialization of MEDCouplingUMesh::SetPartOfIndexedArrays in the case of assignment do not modify the index in \b arrIndxIn.
7411 * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
7412 * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
7413 * \param [in,out] arrInOut arr origin array from which the extraction will be done.
7414 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7415 * \param [in] srcArr input array that will be used as source of copy for ids in [ \b idsOfSelectBg , \b idsOfSelectEnd )
7416 * \param [in] srcArrIndex index array of \b srcArr
7418 * \sa DataArrayInt::SetPartOfIndexedArrays
7421 void DataArrayDiscrete<T>::SetPartOfIndexedArraysSameIdx(const mcIdType *idsOfSelectBg, const mcIdType *idsOfSelectEnd,
7422 DataArrayType *arrInOut, const DataArrayIdType *arrIndxIn,
7423 const DataArrayType *srcArr, const DataArrayIdType *srcArrIndex)
7425 if(arrInOut==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
7426 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArraysSameIdx : presence of null pointer in input parameter !");
7427 mcIdType nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
7428 const mcIdType *arrIndxInPtr=arrIndxIn->begin();
7429 const mcIdType *srcArrIndexPtr=srcArrIndex->begin();
7430 T *arrInOutPtr=arrInOut->getPointer();
7431 const T *srcArrPtr=srcArr->begin();
7432 for(const mcIdType *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++)
7434 if(*it>=0 && *it<nbOfTuples)
7436 if(srcArrIndexPtr[1]-srcArrIndexPtr[0]==arrIndxInPtr[*it+1]-arrIndxInPtr[*it])
7437 std::copy(srcArrPtr+srcArrIndexPtr[0],srcArrPtr+srcArrIndexPtr[1],arrInOutPtr+arrIndxInPtr[*it]);
7440 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] !";
7441 throw INTERP_KERNEL::Exception(oss.str());
7446 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSameIdx : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !";
7447 throw INTERP_KERNEL::Exception(oss.str());
7453 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
7454 * This method is an specialization of MEDCouplingUMesh::SetPartOfIndexedArrays in the case of assignment do not modify the index in \b arrIndxIn.
7456 * \param [in] start begin of set of ids of the input extraction (included)
7457 * \param [in] end end of set of ids of the input extraction (excluded)
7458 * \param [in] step step of the set of ids in range mode.
7459 * \param [in,out] arrInOut arr origin array from which the extraction will be done.
7460 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7461 * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd)
7462 * \param [in] srcArrIndex index array of \b srcArr
7464 * \sa DataArrayInt::SetPartOfIndexedArraysSlice DataArrayInt::SetPartOfIndexedArraysSameIdx
7467 void DataArrayDiscrete<T>::SetPartOfIndexedArraysSameIdxSlice(mcIdType start, mcIdType end, mcIdType step,
7468 DataArrayType *arrInOut, const DataArrayIdType *arrIndxIn,
7469 const DataArrayType *srcArr, const DataArrayIdType *srcArrIndex)
7471 if(arrInOut==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
7472 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : presence of null pointer in input parameter !");
7473 mcIdType nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
7474 const mcIdType *arrIndxInPtr=arrIndxIn->begin();
7475 const mcIdType *srcArrIndexPtr=srcArrIndex->begin();
7476 T *arrInOutPtr=arrInOut->getPointer();
7477 const T *srcArrPtr=srcArr->begin();
7478 mcIdType nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : ");
7480 for(mcIdType i=0;i<nbOfElemsToSet;i++,srcArrIndexPtr++,it+=step)
7482 if(it>=0 && it<nbOfTuples)
7484 if(srcArrIndexPtr[1]-srcArrIndexPtr[0]==arrIndxInPtr[it+1]-arrIndxInPtr[it])
7485 std::copy(srcArrPtr+srcArrIndexPtr[0],srcArrPtr+srcArrIndexPtr[1],arrInOutPtr+arrIndxInPtr[it]);
7488 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : On pos #" << i << " id (idsOfSelectBg[" << i << "]) is " << it << " arrIndxIn[id+1]-arrIndxIn[id]!=srcArrIndex[pos+1]-srcArrIndex[pos] !";
7489 throw INTERP_KERNEL::Exception(oss.str());
7494 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : On pos #" << i << " value is " << it << " not in [0," << nbOfTuples << ") !";
7495 throw INTERP_KERNEL::Exception(oss.str());
7501 * This method works on an input pair (\b arr, \b arrIndx) where \b arr indexes is in \b arrIndx.
7502 * 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.
7504 * \param [in] idsToRemoveBg begin of set of ids to remove in \b arr (included)
7505 * \param [in] idsToRemoveEnd end of set of ids to remove in \b arr (excluded)
7506 * \param [in,out] arr array in which the remove operation will be done.
7507 * \param [in,out] arrIndx array in the remove operation will modify
7508 * \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])
7509 * \return true if \b arr and \b arrIndx have been modified, false if not.
7512 bool DataArrayDiscrete<T>::RemoveIdsFromIndexedArrays(const T *idsToRemoveBg, const T *idsToRemoveEnd,
7513 DataArrayType *arr, DataArrayIdType *arrIndx, mcIdType offsetForRemoval)
7515 if(!arrIndx || !arr)
7516 throw INTERP_KERNEL::Exception("DataArrayInt::RemoveIdsFromIndexedArrays : some input arrays are empty !");
7517 if(offsetForRemoval<0)
7518 throw INTERP_KERNEL::Exception("DataArrayInt::RemoveIdsFromIndexedArrays : offsetForRemoval should be >=0 !");
7519 std::set<T> s(idsToRemoveBg,idsToRemoveEnd);
7520 mcIdType nbOfGrps=arrIndx->getNumberOfTuples()-1;
7521 mcIdType *arrIPtr=arrIndx->getPointer();
7523 mcIdType previousArrI=0;
7524 const T *arrPtr=arr->begin();
7525 std::vector<T> arrOut;//no utility to switch to DataArrayInt because copy always needed
7526 for(mcIdType i=0;i<nbOfGrps;i++,arrIPtr++)
7528 if(*arrIPtr-previousArrI>offsetForRemoval)
7530 for(const T *work=arrPtr+previousArrI+offsetForRemoval;work!=arrPtr+*arrIPtr;work++)
7532 if(s.find(*work)==s.end())
7533 arrOut.push_back(*work);
7536 previousArrI=*arrIPtr;
7537 *arrIPtr=ToIdType(arrOut.size());
7539 if(arr->getNumberOfTuples()==ToIdType(arrOut.size()))
7541 arr->alloc(arrOut.size(),1);
7542 std::copy(arrOut.begin(),arrOut.end(),arr->getPointer());
7547 * Returns a new DataArrayInt containing an arithmetic progression
7548 * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step )
7550 * \param [in] begin - the start value of the result sequence.
7551 * \param [in] end - limiting value, so that every value of the result array is less than
7553 * \param [in] step - specifies the increment or decrement.
7554 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7555 * array using decrRef() as it is no more needed.
7556 * \throw If \a step == 0.
7557 * \throw If \a end < \a begin && \a step > 0.
7558 * \throw If \a end > \a begin && \a step < 0.
7561 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Range(T begin, T end, T step)
7563 mcIdType nbOfTuples=DataArrayTools<T>::GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
7564 MCAuto<DataArrayType> ret=DataArrayType::New();
7565 ret->alloc(nbOfTuples,1);
7566 T *ptr=ret->getPointer();
7569 for(T i=begin;i<end;i+=step,ptr++)
7574 for(T i=begin;i>end;i+=step,ptr++)
7581 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7582 * from a zip representation of a surjective format (returned e.g. by
7583 * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7584 * for example). The result array minimizes the permutation. <br>
7585 * For more info on renumbering see \ref numbering. <br>
7587 * - \a nbOfOldTuples: 10
7588 * - \a arr : [0,3, 5,7,9]
7589 * - \a arrIBg : [0,2,5]
7590 * - \a newNbOfTuples: 7
7591 * - result array : [0,1,2,0,3,4,5,4,6,4]
7593 * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7594 * \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7595 * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7596 * (indices of) equal values. Its every element (except the last one) points to
7597 * the first element of a group of equal values.
7598 * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7599 * arrIBg is \a arrIEnd[ -1 ].
7600 * \param [out] newNbOfTuples - number of tuples after surjection application.
7601 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7602 * array using decrRef() as it is no more needed.
7603 * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7606 DataArrayIdType *DataArrayDiscrete<T>::ConvertIndexArrayToO2N(mcIdType nbOfOldTuples, const mcIdType *arr, const mcIdType *arrIBg, const mcIdType *arrIEnd, mcIdType &newNbOfTuples)
7608 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
7609 ret->alloc(nbOfOldTuples,1);
7610 mcIdType *pt=ret->getPointer();
7611 std::fill(pt,pt+nbOfOldTuples,-1);
7612 mcIdType nbOfGrps=ToIdType(std::distance(arrIBg,arrIEnd))-1;
7613 const mcIdType *cIPtr=arrIBg;
7614 for(mcIdType i=0;i<nbOfGrps;i++)
7615 pt[arr[cIPtr[i]]]=-(i+2);
7617 for(mcIdType iNode=0;iNode<nbOfOldTuples;iNode++)
7625 mcIdType grpId=-(pt[iNode]+2);
7626 for(mcIdType j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7628 if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7632 std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7633 throw INTERP_KERNEL::Exception(oss.str().c_str());
7640 newNbOfTuples=newNb;
7645 * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
7646 * The i-th item of the result array is an ID of a set of elements belonging to a
7647 * unique set of groups, which the i-th element is a part of. This set of elements
7648 * belonging to a unique set of groups is called \a family, so the result array contains
7649 * IDs of families each element belongs to.
7651 * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
7652 * then there are 3 families:
7653 * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
7654 * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
7655 * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
7656 * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
7657 * stands for the element #3 which is in none of groups.
7659 * \param [in] groups - sequence of groups of element IDs.
7660 * \param [in] newNb - total number of elements; it must be more than max ID of element
7662 * \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
7663 * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
7664 * each element with ID from range [0, \a newNb ) belongs to. The caller is to
7665 * delete this array using decrRef() as it is no more needed.
7666 * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
7669 DataArrayIdType *DataArrayDiscrete<T>::MakePartition(const std::vector<const DataArrayType *>& groups, mcIdType newNb, std::vector< std::vector<mcIdType> >& fidsOfGroups)
7671 std::vector<const DataArrayType *> groups2;
7672 for(typename std::vector<const DataArrayType *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
7674 groups2.push_back(*it4);
7675 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
7676 ret->alloc(newNb,1);
7677 mcIdType *retPtr=ret->getPointer();
7678 std::fill(retPtr,retPtr+newNb,0);
7680 for(typename std::vector<const DataArrayType *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
7682 const T *ptr=(*iter)->getConstPointer();
7683 std::size_t nbOfElem=(*iter)->getNbOfElems();
7685 for(mcIdType j=0;j<sfid;j++)
7688 for(std::size_t i=0;i<nbOfElem;i++)
7690 if(ptr[i]>=0 && ptr[i]<newNb)
7692 if(retPtr[ptr[i]]==j)
7700 std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
7702 throw INTERP_KERNEL::Exception(oss.str().c_str());
7709 fidsOfGroups.clear();
7710 fidsOfGroups.resize(groups2.size());
7712 for(typename std::vector<const DataArrayType *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
7714 std::set<mcIdType> tmp;
7715 const T *ptr=(*iter)->getConstPointer();
7716 std::size_t nbOfElem=(*iter)->getNbOfElems();
7717 for(const T *p=ptr;p!=ptr+nbOfElem;p++)
7718 tmp.insert(retPtr[*p]);
7719 fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
7727 namespace MEDCouplingImpl
7733 OpSwitchedOn(T *pt):_pt(pt),_cnt(0) { }
7734 void operator()(const bool& b) { if(b) *_pt++=FromIdType<T>(_cnt); _cnt++; }
7737 MEDCoupling::mcIdType _cnt;
7744 OpSwitchedOff(T *pt):_pt(pt),_cnt(0) { }
7745 void operator()(const bool& b) { if(!b) *_pt++=FromIdType<T>(_cnt); _cnt++; }
7748 MEDCoupling::mcIdType _cnt;
7753 namespace MEDCoupling
7756 * This method returns the list of ids in ascending mode so that v[id]==true.
7759 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::BuildListOfSwitchedOn(const std::vector<bool>& v)
7761 std::size_t sz(std::count(v.begin(),v.end(),true));
7762 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(sz,1);
7763 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn<T>(ret->getPointer()));
7768 * This method returns the list of ids in ascending mode so that v[id]==false.
7771 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::BuildListOfSwitchedOff(const std::vector<bool>& v)
7773 std::size_t sz(std::count(v.begin(),v.end(),false));
7774 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(sz,1);
7775 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff<T>(ret->getPointer()));
7780 namespace MEDCoupling
7783 * This method compares content of input vector \a v and \a this.
7784 * 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.
7785 * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
7787 * \param [in] v - the vector of 'flags' to be compared with \a this.
7789 * \throw If \a this is not sorted ascendingly.
7790 * \throw If \a this has not exactly one component.
7791 * \throw If \a this is not allocated.
7794 bool DataArrayDiscreteSigned<T>::isFittingWith(const std::vector<bool>& v) const
7796 this->checkAllocated();
7797 if(this->getNumberOfComponents()!=1)
7798 throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
7799 const T *w(this->begin()),*end2(this->end());
7800 T refVal=-std::numeric_limits<T>::max();
7802 std::vector<bool>::const_iterator it(v.begin());
7803 for(;it!=v.end();it++,i++)
7815 std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(this->begin(),w-1) << " this is not sorted ascendingly !";
7816 throw INTERP_KERNEL::Exception(oss.str().c_str());