1 // Copyright (C) 2007-2024 CEA, EDF
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"
32 #include "BBTreeDiscrete.txx"
44 void MEDCouplingPointer<T>::setInternal(T *pointer)
51 void MEDCouplingPointer<T>::setExternal(const T *pointer)
58 MemArray<T>::MemArray(const MemArray<T>& other):_nb_of_elem(0),_nb_of_elem_alloc(0),_ownership(false),_dealloc(0),_param_for_deallocator(0)
60 if(!other._pointer.isNull())
62 _nb_of_elem_alloc=other._nb_of_elem;
63 T *pointer=(T*)malloc(_nb_of_elem_alloc*sizeof(T));
64 std::copy(other._pointer.getConstPointer(),other._pointer.getConstPointer()+other._nb_of_elem,pointer);
65 useArray(pointer,true,DeallocType::C_DEALLOC,other._nb_of_elem);
70 void MemArray<T>::useArray(const T *array, bool ownership, DeallocType type, std::size_t nbOfElem)
74 _nb_of_elem_alloc=nbOfElem;
76 _pointer.setInternal(const_cast<T *>(array));
78 _pointer.setExternal(array);
80 _dealloc=BuildFromType(type);
84 void MemArray<T>::useExternalArrayWithRWAccess(const T *array, std::size_t nbOfElem)
88 _nb_of_elem_alloc=nbOfElem;
89 _pointer.setInternal(const_cast<T *>(array));
91 _dealloc=CPPDeallocator;
95 void MemArray<T>::writeOnPlace(std::size_t id, T element0, const T *others, std::size_t sizeOfOthers)
97 if(id+sizeOfOthers>=_nb_of_elem_alloc)
98 reserve(2*_nb_of_elem+sizeOfOthers+1);
99 T *pointer=_pointer.getPointer();
100 pointer[id]=element0;
101 std::copy(others,others+sizeOfOthers,pointer+id+1);
102 _nb_of_elem=std::max<std::size_t>(_nb_of_elem,id+sizeOfOthers+1);
106 void MemArray<T>::pushBack(T elem)
108 if(_nb_of_elem>=_nb_of_elem_alloc)
109 reserve(_nb_of_elem_alloc>0?2*_nb_of_elem_alloc:1);
111 pt[_nb_of_elem++]=elem;
115 T MemArray<T>::popBack()
119 const T *pt=getConstPointer();
120 return pt[--_nb_of_elem];
122 throw INTERP_KERNEL::Exception("MemArray::popBack : nothing to pop in array !");
126 void MemArray<T>::pack() const
128 (const_cast<MemArray<T> * >(this))->reserve(_nb_of_elem);
132 bool MemArray<T>::isEqual(const MemArray<T>& other, T prec, std::string& reason) const
134 std::ostringstream oss; oss.precision(15);
135 if(_nb_of_elem!=other._nb_of_elem)
137 oss << "Number of elements in coarse data of DataArray mismatch : this=" << _nb_of_elem << " other=" << other._nb_of_elem;
141 const T *pt1=_pointer.getConstPointer();
142 const T *pt2=other._pointer.getConstPointer();
147 oss << "coarse data pointer is defined for only one DataArray instance !";
153 for(std::size_t i=0;i<_nb_of_elem;i++)
154 if(pt1[i]-pt2[i]<-prec || (pt1[i]-pt2[i])>prec)
156 oss << "The content of data differs at pos #" << i << " of coarse data ! this[i]=" << pt1[i] << " other[i]=" << pt2[i];
164 * \param [in] sl is typically the number of components
165 * \return True if a not null pointer is present, False if not.
168 bool MemArray<T>::reprHeader(mcIdType sl, std::ostream& stream) const
170 stream << "Number of tuples : ";
171 if(!_pointer.isNull())
174 stream << _nb_of_elem/sl << std::endl << "Internal memory facts : " << _nb_of_elem << "/" << _nb_of_elem_alloc;
176 stream << "Empty Data";
181 stream << "Data content :\n";
182 bool ret=!_pointer.isNull();
184 stream << "No data !\n";
189 * \param [in] sl is typically the number of components
192 void MemArray<T>::repr(mcIdType sl, std::ostream& stream) const
194 if(reprHeader(sl,stream))
196 const T *data=getConstPointer();
197 if(_nb_of_elem!=0 && sl!=0)
199 std::size_t nbOfTuples=_nb_of_elem/std::abs(sl);
200 for(std::size_t i=0;i<nbOfTuples;i++)
202 stream << "Tuple #" << i << " : ";
203 std::copy(data,data+sl,std::ostream_iterator<T>(stream," "));
209 stream << "Empty Data\n";
214 * \param [in] sl is typically the number of components
217 void MemArray<T>::reprZip(mcIdType sl, std::ostream& stream) const
219 stream << "Number of tuples : ";
220 if(!_pointer.isNull())
223 stream << _nb_of_elem/sl;
225 stream << "Empty Data";
230 stream << "Data content : ";
231 const T *data=getConstPointer();
232 if(!_pointer.isNull())
234 if(_nb_of_elem!=0 && sl!=0)
236 std::size_t nbOfTuples=_nb_of_elem/std::abs(sl);
237 for(std::size_t i=0;i<nbOfTuples;i++)
240 std::copy(data,data+sl,std::ostream_iterator<T>(stream," "));
247 stream << "Empty Data\n";
250 stream << "No data !\n";
254 * \param [in] sl is typically the number of components
257 void MemArray<T>::reprNotTooLong(mcIdType sl, std::ostream& stream) const
259 if(reprHeader(sl,stream))
261 const T *data=getConstPointer();
262 if(_nb_of_elem!=0 && sl!=0)
264 std::size_t nbOfTuples=_nb_of_elem/std::abs(sl);
267 for(std::size_t i=0;i<nbOfTuples;i++)
269 stream << "Tuple #" << i << " : ";
270 std::copy(data,data+sl,std::ostream_iterator<T>(stream," "));
276 {// too much tuples -> print the 3 first tuples and 3 last.
277 stream << "Tuple #0 : ";
278 std::copy(data,data+sl,std::ostream_iterator<T>(stream," ")); stream << "\n";
279 stream << "Tuple #1 : ";
280 std::copy(data+sl,data+2*sl,std::ostream_iterator<T>(stream," ")); stream << "\n";
281 stream << "Tuple #2 : ";
282 std::copy(data+2*sl,data+3*sl,std::ostream_iterator<T>(stream," ")); stream << "\n";
284 stream << "Tuple #" << nbOfTuples-3 << " : ";
285 std::copy(data+(nbOfTuples-3)*sl,data+(nbOfTuples-2)*sl,std::ostream_iterator<T>(stream," ")); stream << "\n";
286 stream << "Tuple #" << nbOfTuples-2 << " : ";
287 std::copy(data+(nbOfTuples-2)*sl,data+(nbOfTuples-1)*sl,std::ostream_iterator<T>(stream," ")); stream << "\n";
288 stream << "Tuple #" << nbOfTuples-1 << " : ";
289 std::copy(data+(nbOfTuples-1)*sl,data+nbOfTuples*sl,std::ostream_iterator<T>(stream," ")); stream << "\n";
293 stream << "Empty Data\n";
298 void MemArray<T>::fillWithValue(const T& val)
300 T *pt=_pointer.getPointer();
301 std::fill(pt,pt+_nb_of_elem,val);
305 T *MemArray<T>::fromNoInterlace(std::size_t nbOfComp) const
308 throw INTERP_KERNEL::Exception("MemArray<T>::fromNoInterlace : number of components must be > 0 !");
309 const T *pt=_pointer.getConstPointer();
310 std::size_t nbOfTuples=_nb_of_elem/nbOfComp;
311 T *ret=(T*)malloc(_nb_of_elem*sizeof(T));
313 for(std::size_t i=0;i<nbOfTuples;i++)
314 for(std::size_t j=0;j<nbOfComp;j++,w++)
315 *w=pt[j*nbOfTuples+i];
320 T *MemArray<T>::toNoInterlace(std::size_t nbOfComp) const
323 throw INTERP_KERNEL::Exception("MemArray<T>::toNoInterlace : number of components must be > 0 !");
324 const T *pt=_pointer.getConstPointer();
325 std::size_t nbOfTuples=_nb_of_elem/nbOfComp;
326 T *ret=(T*)malloc(_nb_of_elem*sizeof(T));
328 for(std::size_t i=0;i<nbOfComp;i++)
329 for(std::size_t j=0;j<nbOfTuples;j++,w++)
335 void MemArray<T>::sort(bool asc)
337 T *pt=_pointer.getPointer();
339 std::sort(pt,pt+_nb_of_elem);
342 typename std::reverse_iterator<T *> it1(pt+_nb_of_elem);
343 typename std::reverse_iterator<T *> it2(pt);
349 void MemArray<T>::reverse(std::size_t nbOfComp)
352 throw INTERP_KERNEL::Exception("MemArray<T>::reverse : only supported with 'this' array with ONE or more than ONE component !");
353 T *pt=_pointer.getPointer();
356 std::reverse(pt,pt+_nb_of_elem);
361 T *pt2=pt+_nb_of_elem-nbOfComp;
362 std::size_t nbOfTuples=_nb_of_elem/nbOfComp;
363 for(std::size_t i=0;i<nbOfTuples/2;i++,pt+=nbOfComp,pt2-=nbOfComp)
365 for(std::size_t j=0;j<nbOfComp;j++)
366 std::swap(pt[j],pt2[j]);
372 void MemArray<T>::alloc(std::size_t nbOfElements)
375 _nb_of_elem=nbOfElements;
376 _nb_of_elem_alloc=nbOfElements;
377 _pointer.setInternal((T*)malloc(_nb_of_elem_alloc*sizeof(T)));
379 _dealloc=CDeallocator;
383 * This method performs systematically an allocation of \a newNbOfElements elements in \a this.
384 * \a _nb_of_elem and \a _nb_of_elem_alloc will \b NOT be systematically equal (contrary to MemArray<T>::reAlloc method.
385 * 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
386 * \a newNbOfElements. This method is typically used to perform a pushBack to avoid systematic allocations-copy-deallocation.
387 * So after the call of this method the accessible content is perfectly set.
389 * So this method should not be confused with MemArray<T>::reserve that is close to MemArray<T>::reAlloc but not same.
392 void MemArray<T>::reserve(std::size_t newNbOfElements)
394 if(_nb_of_elem_alloc==newNbOfElements)
396 T *pointer=(T*)malloc(newNbOfElements*sizeof(T));
397 std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min<std::size_t>(_nb_of_elem,newNbOfElements),pointer);
399 DestroyPointer(const_cast<T *>(_pointer.getConstPointer()),_dealloc,_param_for_deallocator);//Do not use getPointer because in case of _external
400 _pointer.setInternal(pointer);
401 _nb_of_elem=std::min<std::size_t>(_nb_of_elem,newNbOfElements);
402 _nb_of_elem_alloc=newNbOfElements;
404 _dealloc=CDeallocator;
405 _param_for_deallocator=0;
409 * This method performs systematically an allocation of \a newNbOfElements elements in \a this.
410 * \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 .
411 * The remaining part of the new allocated chunk are available but not set previously !
413 * So this method should not be confused with MemArray<T>::reserve that is close to MemArray<T>::reAlloc but not same.
416 void MemArray<T>::reAlloc(std::size_t newNbOfElements)
418 if(_nb_of_elem==newNbOfElements)
420 T *pointer=(T*)malloc(newNbOfElements*sizeof(T));
421 std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min<std::size_t>(_nb_of_elem,newNbOfElements),pointer);
423 DestroyPointer(const_cast<T *>(_pointer.getConstPointer()),_dealloc,_param_for_deallocator);//Do not use getPointer because in case of _external
424 _pointer.setInternal(pointer);
425 _nb_of_elem=newNbOfElements;
426 _nb_of_elem_alloc=newNbOfElements;
428 _dealloc=CDeallocator;
429 _param_for_deallocator=0;
433 void MemArray<T>::CPPDeallocator(void *pt, void *param)
435 delete [] reinterpret_cast<T*>(pt);
439 void MemArray<T>::CDeallocator(void *pt, void *param)
445 void MemArray<T>::COffsetDeallocator(void *pt, void *param)
447 int64_t *offset(reinterpret_cast<int64_t *>(param));
448 char *ptcast(reinterpret_cast<char *>(pt));
449 free(ptcast+*offset);
453 typename MemArray<T>::Deallocator MemArray<T>::BuildFromType(DeallocType type)
457 case DeallocType::CPP_DEALLOC:
458 return CPPDeallocator;
459 case DeallocType::C_DEALLOC:
461 case DeallocType::C_DEALLOC_WITH_OFFSET:
462 return COffsetDeallocator;
464 throw INTERP_KERNEL::Exception("Invalid deallocation requested ! Unrecognized enum DeallocType !");
469 void MemArray<T>::DestroyPointer(T *pt, typename MemArray<T>::Deallocator dealloc, void *param)
476 void MemArray<T>::destroy()
479 DestroyPointer(const_cast<T *>(_pointer.getConstPointer()),_dealloc,_param_for_deallocator);//Do not use getPointer because in case of _external
483 _param_for_deallocator=NULL;
489 MemArray<T> &MemArray<T>::operator=(const MemArray<T>& other)
491 alloc(other._nb_of_elem);
492 std::copy(other._pointer.getConstPointer(),other._pointer.getConstPointer()+_nb_of_elem,_pointer.getPointer());
496 //////////////////////////////////
499 DataArrayIterator<T>::DataArrayIterator(typename Traits<T>::ArrayType *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
504 if(_da->isAllocated())
506 _nb_comp=da->getNumberOfComponents();
507 _nb_tuple=da->getNumberOfTuples();
508 _pt=da->getPointer();
514 DataArrayIterator<T>::~DataArrayIterator()
521 typename Traits<T>::ArrayTuple *DataArrayIterator<T>::nextt()
523 if(_tuple_id<_nb_tuple)
526 typename Traits<T>::ArrayTuple *ret=new typename Traits<T>::ArrayTuple(_pt,_nb_comp);
534 //////////////////////////////////
537 DataArrayTuple<T>::DataArrayTuple(T *pt, std::size_t nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
542 T DataArrayTuple<T>::zeValue() const
546 throw INTERP_KERNEL::Exception("DataArrayTuple<T>::zeValue : DataArrayTuple instance has not exactly 1 component -> Not possible to convert it into a single value !");
550 typename Traits<T>::ArrayType *DataArrayTuple<T>::buildDA(std::size_t nbOfTuples, std::size_t nbOfCompo) const
552 if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
554 typename Traits<T>::ArrayType *ret=Traits<T>::ArrayType::New();
555 ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
560 std::ostringstream oss; oss << "DataArrayTuple<T>::buildDA : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
561 oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
562 throw INTERP_KERNEL::Exception(oss.str().c_str());
566 //////////////////////////////////
569 * 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,
570 * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
572 * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
574 * \param [in] start - the start of the input slice of the whole work to perform split into slices.
575 * \param [in] stop - the stop of the input slice of the whole work to perform split into slices.
576 * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform split into slices.
577 * \param [in] sliceId - the slice id considered
578 * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
579 * \param [out] startSlice - the start of the slice considered
580 * \param [out] stopSlice - the stop of the slice consided
582 * \throw If \a step == 0
583 * \throw If \a nbOfSlices not > 0
584 * \throw If \a sliceId not in [0,nbOfSlices)
587 void DataArrayTools<T>::GetSlice(T start, T stop, T step, mcIdType sliceId, mcIdType nbOfSlices, T& startSlice, T& stopSlice)
591 std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
592 throw INTERP_KERNEL::Exception(oss.str().c_str());
594 if(sliceId<0 || sliceId>=nbOfSlices)
596 std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
597 throw INTERP_KERNEL::Exception(oss.str().c_str());
599 mcIdType nbElems=DataArrayTools<T>::GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
600 mcIdType minNbOfElemsPerSlice=nbElems/nbOfSlices;
601 startSlice=start+minNbOfElemsPerSlice*step*sliceId;
602 if(sliceId<nbOfSlices-1)
603 stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
609 mcIdType DataArrayTools<T>::GetNumberOfItemGivenBES(T begin, T end, T step, const std::string& msg)
613 std::ostringstream oss; oss << msg << " : end before begin !";
614 throw INTERP_KERNEL::Exception(oss.str().c_str());
620 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
621 throw INTERP_KERNEL::Exception(oss.str().c_str());
623 return ToIdType((end-1-begin)/step+1);
627 mcIdType DataArrayTools<T>::GetNumberOfItemGivenBESRelative(T begin, T end, T step, const std::string& msg)
630 throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
631 if(end<begin && step>0)
633 std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
634 throw INTERP_KERNEL::Exception(oss.str().c_str());
636 if(begin<end && step<0)
638 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
639 throw INTERP_KERNEL::Exception(oss.str().c_str());
642 return ToIdType((std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1);
648 mcIdType DataArrayTools<T>::GetPosOfItemGivenBESRelativeNoThrow(T value, T begin, T end, T step)
653 if((step>0 && begin<=value && value<end) ||
654 (step<0 && begin>=value && value>end))
656 mcIdType id = ToIdType((value-begin)/step);
657 if (begin + step * id == value)
666 //////////////////////////////////
669 MCAuto< typename Traits<T>::ArrayTypeCh > DataArrayTemplate<T>::NewFromStdVector(const typename std::vector<T>& v)
671 std::size_t sz(v.size());
672 MCAuto< typename Traits<T>::ArrayTypeCh > ret(Traits<T>::ArrayTypeCh::New());
674 T *pt(ret->getPointer());
675 std::copy(v.begin(),v.end(),pt);
680 * Returns a newly created array containing a copy of the input array defined by [ \a arrBegin, \a arrEnd )
683 MCAuto< typename Traits<T>::ArrayTypeCh > DataArrayTemplate<T>::NewFromArray(const T *arrBegin, const T *arrEnd)
685 using DataArrayT = typename Traits<T>::ArrayTypeCh;
686 MCAuto< DataArrayT > ret(DataArrayT::New());
687 std::size_t nbElts(std::distance(arrBegin,arrEnd));
688 ret->alloc(nbElts,1);
689 std::copy(arrBegin,arrEnd,ret->getPointer());
694 std::vector< MCAuto< typename Traits<T>::ArrayTypeCh > > DataArrayTemplate<T>::explodeComponents() const
697 std::size_t sz(getNumberOfComponents());
698 mcIdType nbTuples(getNumberOfTuples());
699 std::string name(getName());
700 std::vector<std::string> compNames(getInfoOnComponents());
701 std::vector< MCAuto< typename Traits<T>::ArrayTypeCh > > ret(sz);
702 const T *thisPt(begin());
703 for(std::size_t i=0;i<sz;i++)
705 MCAuto< typename Traits<T>::ArrayTypeCh > part(Traits<T>::ArrayTypeCh::New());
706 part->alloc(nbTuples,1);
708 part->setInfoOnComponent(0,compNames[i]);
709 T *otherPt(part->getPointer());
710 for(mcIdType j=0;j<nbTuples;j++)
711 otherPt[j]=thisPt[sz*j+i];
718 std::size_t DataArrayTemplate<T>::getHeapMemorySizeWithoutChildren() const
720 std::size_t sz(_mem.getNbOfElemAllocated());
722 return DataArray::getHeapMemorySizeWithoutChildren()+sz;
726 * Allocates the raw data in memory. If the memory was already allocated, then it is
727 * freed and re-allocated. See an example of this method use
728 * \ref MEDCouplingArraySteps1WC "here".
729 * \param [in] nbOfTuple - number of tuples of data to allocate.
730 * \param [in] nbOfCompo - number of components of data to allocate.
731 * \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
734 void DataArrayTemplate<T>::alloc(std::size_t nbOfTuple, std::size_t nbOfCompo)
736 _info_on_compo.resize(nbOfCompo);
737 _mem.alloc(nbOfCompo*nbOfTuple);
742 * Sets a C array to be used as raw data of \a this. The previously set info
743 * of components is retained and re-sized.
744 * For more info see \ref MEDCouplingArraySteps1.
745 * \param [in] array - the C array to be used as raw data of \a this.
746 * \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
747 * \param [in] type - specifies how to deallocate \a array. If \a type == MEDCoupling::CPP_DEALLOC,
748 * \c delete [] \c array; will be called. If \a type == MEDCoupling::C_DEALLOC,
749 * \c free(\c array ) will be called.
750 * \param [in] nbOfTuple - new number of tuples in \a this.
751 * \param [in] nbOfCompo - new number of components in \a this.
754 void DataArrayTemplate<T>::useArray(const T *array, bool ownership, DeallocType type, std::size_t nbOfTuple, std::size_t nbOfCompo)
756 _info_on_compo.resize(nbOfCompo);
757 _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
762 void DataArrayTemplate<T>::useExternalArrayWithRWAccess(const T *array, std::size_t nbOfTuple, std::size_t nbOfCompo)
764 _info_on_compo.resize(nbOfCompo);
765 _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
770 * Returns a value located at specified tuple and component.
771 * This method is equivalent to DataArrayTemplate<T>::getIJ() except that validity of
772 * parameters is checked. So this method is safe but expensive if used to go through
773 * all values of \a this.
774 * \param [in] tupleId - index of tuple of interest.
775 * \param [in] compoId - index of component of interest.
776 * \return double - value located by \a tupleId and \a compoId.
777 * \throw If \a this is not allocated.
778 * \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
779 * \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
782 T DataArrayTemplate<T>::getIJSafe(std::size_t tupleId, std::size_t compoId) const
785 if(ToIdType(tupleId)>=getNumberOfTuples())
787 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
788 throw INTERP_KERNEL::Exception(oss.str().c_str());
790 if(compoId>=getNumberOfComponents())
792 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
793 throw INTERP_KERNEL::Exception(oss.str().c_str());
795 return _mem[tupleId*_info_on_compo.size()+compoId];
799 * 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.
801 * \sa DataArray::getHeapMemorySizeWithoutChildren, DataArrayTemplate<T>::reserve
804 void DataArrayTemplate<T>::pack() const
810 * Checks if raw data is allocated. Read more on the raw data
811 * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
812 * \return bool - \a true if the raw data is allocated, \a false else.
815 bool DataArrayTemplate<T>::isAllocated() const
817 return getConstPointer()!=0;
821 * Checks if raw data is allocated and throws an exception if it is not the case.
822 * \throw If the raw data is not allocated.
825 void DataArrayTemplate<T>::checkAllocated() const
829 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !";
830 throw INTERP_KERNEL::Exception(oss.str().c_str());
835 * This method deallocated \a this without modification of information relative to the components.
836 * After call of this method, DataArrayDouble::isAllocated will return false.
837 * If \a this is already not allocated, \a this is let unchanged.
840 void DataArrayTemplate<T>::desallocate()
846 * This method reserve nbOfElems elements in memory ( nbOfElems*sizeof(T) ) \b without impacting the number of tuples in \a this.
847 * 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.
848 * If \a this has not already been allocated, number of components is set to one.
849 * This method allows to reduce number of reallocations on invocation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
851 * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
854 void DataArrayTemplate<T>::reserve(std::size_t nbOfElems)
856 std::size_t nbCompo(getNumberOfComponents());
859 _mem.reserve(nbOfElems);
863 _mem.reserve(nbOfElems);
864 _info_on_compo.resize(1);
868 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::reserve : not available for DataArrayDouble with number of components different than 1 !";
869 throw INTERP_KERNEL::Exception(oss.str().c_str());
874 * 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
875 * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
877 * \param [in] val the value to be added in \a this
878 * \throw If \a this has already been allocated with number of components different from one.
879 * \sa DataArrayDouble::pushBackValsSilent
882 void DataArrayTemplate<T>::pushBackSilent(T val)
884 std::size_t nbCompo(getNumberOfComponents());
889 _info_on_compo.resize(1);
894 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !";
895 throw INTERP_KERNEL::Exception(oss.str().c_str());
900 * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
901 * \throw If \a this is already empty.
902 * \throw If \a this has number of components different from one.
905 T DataArrayTemplate<T>::popBackSilent()
907 if(getNumberOfComponents()==1)
908 return _mem.popBack();
911 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::popBackSilent : not available for DataArrayDouble with number of components different than 1 !";
912 throw INTERP_KERNEL::Exception(oss.str().c_str());
917 * Allocates the raw data in memory. If exactly same memory as needed already
918 * allocated, it is not re-allocated.
919 * \param [in] nbOfTuple - number of tuples of data to allocate.
920 * \param [in] nbOfCompo - number of components of data to allocate.
921 * \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
924 void DataArrayTemplate<T>::allocIfNecessary(std::size_t nbOfTuple, std::size_t nbOfCompo)
928 if(ToIdType(nbOfTuple)!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
929 alloc(nbOfTuple,nbOfCompo);
932 alloc(nbOfTuple,nbOfCompo);
936 * Checks the number of tuples.
937 * \return bool - \a true if getNumberOfTuples() == 0, \a false else.
938 * \throw If \a this is not allocated.
941 bool DataArrayTemplate<T>::empty() const
944 return getNumberOfTuples()==0;
948 * Copies all the data from another DataArrayDouble. For more info see
949 * \ref MEDCouplingArrayBasicsCopyDeepAssign.
950 * \param [in] other - another instance of DataArrayDouble to copy data from.
951 * \throw If the \a other is not allocated.
954 void DataArrayTemplate<T>::deepCopyFrom(const DataArrayTemplate<T>& other)
956 other.checkAllocated();
957 mcIdType nbOfTuples(other.getNumberOfTuples());
958 std::size_t nbOfComp(other.getNumberOfComponents());
959 allocIfNecessary(nbOfTuples,nbOfComp);
960 std::size_t nbOfElems(nbOfTuples*nbOfComp);
962 const T *ptI(other.begin());
963 for(std::size_t i=0;i<nbOfElems;i++)
965 copyStringInfoFrom(other);
969 * Reverse the array values.
970 * \throw If \a this->getNumberOfComponents() < 1.
971 * \throw If \a this is not allocated.
974 void DataArrayTemplate<T>::reverse()
977 _mem.reverse(getNumberOfComponents());
982 * Assign \a val to all values in \a this array. To know more on filling arrays see
983 * \ref MEDCouplingArrayFill.
984 * \param [in] val - the value to fill with.
985 * \throw If \a this is not allocated.
988 void DataArrayTemplate<T>::fillWithValue(T val)
991 _mem.fillWithValue(val);
996 * Changes number of tuples in the array. If the new number of tuples is smaller
997 * than the current number the array is truncated, otherwise the array is extended.
998 * \param [in] nbOfTuples - new number of tuples.
999 * \throw If \a this is not allocated.
1000 * \throw If \a nbOfTuples is negative.
1003 void DataArrayTemplate<T>::reAlloc(std::size_t nbOfTuples)
1006 _mem.reAlloc(getNumberOfComponents()*nbOfTuples);
1011 * Permutes values of \a this array as required by \a old2New array. The values are
1012 * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1013 * the same as in \c this one.
1014 * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
1015 * For more info on renumbering see \ref numbering.
1016 * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1017 * giving a new position for i-th old value.
1020 void DataArrayTemplate<T>::renumberInPlace(const mcIdType *old2New)
1023 mcIdType nbTuples(getNumberOfTuples());
1024 std::size_t nbOfCompo(getNumberOfComponents());
1025 T *tmp(new T[nbTuples*nbOfCompo]);
1026 const T *iptr(begin());
1027 for(mcIdType i=0;i<nbTuples;i++)
1029 mcIdType v=old2New[i];
1030 if(v>=0 && v<nbTuples)
1031 std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1034 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1035 throw INTERP_KERNEL::Exception(oss.str().c_str());
1038 std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1045 * Permutes values of \a this array as required by \a new2Old array. The values are
1046 * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1047 * the same as in \c this one.
1048 * For more info on renumbering see \ref numbering.
1049 * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1050 * giving a previous position of i-th new value.
1053 void DataArrayTemplate<T>::renumberInPlaceR(const mcIdType *new2Old)
1056 mcIdType nbTuples(getNumberOfTuples());
1057 std::size_t nbOfCompo(getNumberOfComponents());
1058 T *tmp(new T[nbTuples*nbOfCompo]);
1059 const T *iptr(begin());
1060 for(mcIdType i=0;i<nbTuples;i++)
1062 mcIdType v=new2Old[i];
1063 if(v>=0 && v<nbTuples)
1064 std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1067 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1068 throw INTERP_KERNEL::Exception(oss.str().c_str());
1071 std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1077 * Sorts values of the array. \b Warning, this method is not const, it alterates \a this content.
1079 * \param [in] asc - \a true means ascending order, \a false, descending.
1080 * \throw If \a this is not allocated.
1081 * \throw If \a this->getNumberOfComponents() != 1.
1085 void DataArrayTemplate<T>::sort(bool asc)
1088 if(getNumberOfComponents()!=1)
1090 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::sort : only supported with 'this' array with ONE component !";
1091 throw INTERP_KERNEL::Exception(oss.str().c_str());
1098 * Sorts value within every tuple of \a this array.
1099 * \param [in] asc - if \a true, the values are sorted in ascending order, else,
1100 * in descending order.
1101 * \throw If \a this is not allocated.
1104 void DataArrayTemplate<T>::sortPerTuple(bool asc)
1106 this->checkAllocated();
1107 T *pt( this->getPointer() );
1108 mcIdType nbOfTuple(this->getNumberOfTuples());
1109 std::size_t nbOfComp(this->getNumberOfComponents());
1111 for(mcIdType i=0;i<nbOfTuple;i++,pt+=nbOfComp)
1112 std::sort(pt,pt+nbOfComp);
1114 for(mcIdType i=0;i<nbOfTuple;i++,pt+=nbOfComp)
1115 std::sort(pt,pt+nbOfComp,std::greater<double>());
1116 this->declareAsNew();
1120 * Sorts values of the array and put the result in a newly allocated returned array.
1121 * This method does not alterate \a this content.
1123 * \param [in] asc - \a true means ascending order, \a false, descending.
1124 * \throw If \a this is not allocated.
1125 * \throw If \a this->getNumberOfComponents() != 1.
1129 typename Traits<T>::ArrayTypeCh *DataArrayTemplate<T>::copySortedImpl(bool asc) const
1131 MCAuto<typename Traits<T>::ArrayTypeCh> ret(static_cast<typename Traits<T>::ArrayTypeCh *>(this->deepCopy()));
1137 * Returns a copy of \a this array with values permuted as required by \a old2New array.
1138 * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ].
1139 * Number of tuples in the result array remains the same as in \c this one.
1140 * If a permutation reduction is needed, renumberAndReduce() should be used.
1141 * For more info on renumbering see \ref numbering.
1142 * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1143 * giving a new position for i-th old value.
1144 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1145 * is to delete using decrRef() as it is no more needed.
1146 * \throw If \a this is not allocated.
1149 typename Traits<T>::ArrayType *DataArrayTemplate<T>::renumber(const mcIdType *old2New) const
1152 mcIdType nbTuples(getNumberOfTuples());
1153 std::size_t nbOfCompo(getNumberOfComponents());
1154 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1155 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1156 ret->alloc(nbTuples,nbOfCompo);
1157 ret->copyStringInfoFrom(*this);
1158 const T *iptr(begin());
1159 T *optr(ret->getPointer());
1160 for(mcIdType i=0;i<nbTuples;i++)
1161 std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1162 ret->copyStringInfoFrom(*this);
1167 * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1168 * The values are permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1169 * tuples in the result array remains the same as in \c this one.
1170 * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
1171 * For more info on renumbering see \ref numbering.
1172 * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1173 * giving a previous position of i-th new value.
1174 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1175 * is to delete using decrRef() as it is no more needed.
1178 typename Traits<T>::ArrayType *DataArrayTemplate<T>::renumberR(const mcIdType *new2Old) const
1181 mcIdType nbTuples(getNumberOfTuples());
1182 std::size_t nbOfCompo(getNumberOfComponents());
1183 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1184 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1185 ret->alloc(nbTuples,nbOfCompo);
1186 ret->copyStringInfoFrom(*this);
1187 const T *iptr(getConstPointer());
1188 T *optr(ret->getPointer());
1189 for(mcIdType i=0;i<nbTuples;i++)
1190 std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1191 ret->copyStringInfoFrom(*this);
1196 * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1197 * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1198 * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ] for all
1199 * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which
1200 * \a old2New[ i ] is negative, is missing from the result array.
1201 * For more info on renumbering see \ref numbering.
1202 * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1203 * giving a new position for i-th old tuple and giving negative position for
1204 * for i-th old tuple that should be omitted.
1205 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1206 * is to delete using decrRef() as it is no more needed.
1209 typename Traits<T>::ArrayType *DataArrayTemplate<T>::renumberAndReduce(const mcIdType *old2New, mcIdType newNbOfTuple) const
1212 mcIdType nbTuples(getNumberOfTuples());
1213 std::size_t nbOfCompo(getNumberOfComponents());
1214 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1215 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1216 ret->alloc(newNbOfTuple,nbOfCompo);
1217 const T *iptr=getConstPointer();
1218 T *optr=ret->getPointer();
1219 for(mcIdType i=0;i<nbTuples;i++)
1221 mcIdType w=old2New[i];
1223 std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1225 ret->copyStringInfoFrom(*this);
1230 * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1231 * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1232 * \a new2OldBg array.
1233 * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1234 * This method is equivalent to renumberAndReduce() except that convention in input is
1235 * \c new2old and \b not \c old2new.
1236 * For more info on renumbering see \ref numbering.
1237 * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1238 * tuple index in \a this array to fill the i-th tuple in the new array.
1239 * \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1240 * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1241 * \a new2OldBg <= \a pi < \a new2OldEnd.
1242 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1243 * is to delete using decrRef() as it is no more needed.
1246 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleId(const mcIdType *new2OldBg, const mcIdType *new2OldEnd) const
1249 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1250 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1251 std::size_t nbComp(getNumberOfComponents());
1252 ret->alloc(std::distance(new2OldBg,new2OldEnd),nbComp);
1253 ret->copyStringInfoFrom(*this);
1254 T *pt(ret->getPointer());
1255 const T *srcPt(getConstPointer());
1257 for(const mcIdType *w=new2OldBg;w!=new2OldEnd;w++,i++)
1258 std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1259 ret->copyStringInfoFrom(*this);
1264 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleId(const DataArrayIdType& di) const
1266 return this->mySelectByTupleId(di.begin(),di.end());
1270 MCAuto<typename Traits<T>::ArrayTypeCh> DataArrayTemplate<T>::selectPartDef(const PartDefinition *pd) const
1273 throw INTERP_KERNEL::Exception("DataArrayTemplate<T>::selectPartDef : null input pointer !");
1274 MCAuto<typename Traits<T>::ArrayTypeCh> ret(Traits<T>::ArrayTypeCh::New());
1275 const SlicePartDefinition *spd(dynamic_cast<const SlicePartDefinition *>(pd));
1279 spd->getSlice(a,b,c);
1280 if(a==0 && b==getNumberOfTuples() && c==1)
1282 DataArrayTemplate<T> *directRet(const_cast<DataArrayTemplate<T> *>(this));
1283 directRet->incrRef();
1284 MCAuto<DataArrayTemplate<T> > ret2(directRet);
1285 return DynamicCastSafe<DataArrayTemplate<T>,typename Traits<T>::ArrayTypeCh>(ret2);
1289 MCAuto<DataArray> ret2(selectByTupleIdSafeSlice(a,b,c));
1290 return DynamicCastSafe<DataArray,typename Traits<T>::ArrayTypeCh>(ret2);
1293 const DataArrayPartDefinition *dpd(dynamic_cast<const DataArrayPartDefinition *>(pd));
1296 MCAuto<DataArrayIdType> arr(dpd->toDAI());
1297 MCAuto<DataArray> ret2(selectByTupleIdSafe(arr->begin(),arr->end()));
1298 return DynamicCastSafe<DataArray,typename Traits<T>::ArrayTypeCh>(ret2);
1301 throw INTERP_KERNEL::Exception("DataArrayTemplate<T>::selectPartDef : unrecognized part def !");
1305 * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1306 * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1307 * \a new2OldBg array.
1308 * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1309 * This method is equivalent to renumberAndReduce() except that convention in input is
1310 * \c new2old and \b not \c old2new.
1311 * This method is equivalent to selectByTupleId() except that it prevents coping data
1312 * from behind the end of \a this array.
1313 * For more info on renumbering see \ref numbering.
1314 * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1315 * tuple index in \a this array to fill the i-th tuple in the new array.
1316 * \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1317 * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1318 * \a new2OldBg <= \a pi < \a new2OldEnd.
1319 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1320 * is to delete using decrRef() as it is no more needed.
1321 * \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1324 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleIdSafe(const mcIdType *new2OldBg, const mcIdType *new2OldEnd) const
1327 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1328 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1329 std::size_t nbComp(getNumberOfComponents());
1330 mcIdType oldNbOfTuples(getNumberOfTuples());
1331 ret->alloc(std::distance(new2OldBg,new2OldEnd),nbComp);
1332 ret->copyStringInfoFrom(*this);
1333 T *pt(ret->getPointer());
1334 const T *srcPt(getConstPointer());
1336 for(const mcIdType *w=new2OldBg;w!=new2OldEnd;w++,i++)
1337 if(*w>=0 && *w<oldNbOfTuples)
1338 std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1341 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !";
1342 throw INTERP_KERNEL::Exception(oss.str().c_str());
1344 ret->copyStringInfoFrom(*this);
1349 * Changes the number of components within \a this array so that its raw data **does
1350 * not** change, instead splitting this data into tuples changes.
1351 * \warning This method erases all (name and unit) component info set before!
1352 * \param [in] newNbOfCompo - number of components for \a this array to have.
1353 * \throw If \a this is not allocated
1354 * \throw If getNbOfElems() % \a newNbOfCompo != 0.
1355 * \throw If \a newNbOfCompo is lower than 1.
1356 * \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1357 * \warning This method erases all (name and unit) component info set before!
1360 void DataArrayTemplate<T>::rearrange(std::size_t newNbOfCompo)
1365 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::rearrange : input newNbOfCompo must be > 0 !";
1366 throw INTERP_KERNEL::Exception(oss.str().c_str());
1368 std::size_t nbOfElems=getNbOfElems();
1369 if(nbOfElems%newNbOfCompo!=0)
1371 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::rearrange : nbOfElems%newNbOfCompo!=0 !";
1372 throw INTERP_KERNEL::Exception(oss.str().c_str());
1374 if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<mcIdType>::max())
1376 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !";
1377 throw INTERP_KERNEL::Exception(oss.str().c_str());
1379 _info_on_compo.clear();
1380 _info_on_compo.resize(newNbOfCompo);
1385 * Changes the number of components within \a this array to be equal to its number
1386 * of tuples, and inversely its number of tuples to become equal to its number of
1387 * components. So that its raw data **does not** change, instead splitting this
1388 * data into tuples changes.
1389 * \warning This method erases all (name and unit) component info set before!
1390 * \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1391 * \throw If \a this is not allocated.
1395 void DataArrayTemplate<T>::transpose()
1398 rearrange(getNumberOfTuples());
1402 * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1403 * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1404 * is truncated to have \a newNbOfComp components, keeping first components. If \a
1405 * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1406 * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1408 * \param [in] newNbOfComp - number of components for the new array to have.
1409 * \param [in] dftValue - value assigned to new values added to the new array.
1410 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1411 * is to delete using decrRef() as it is no more needed.
1412 * \throw If \a this is not allocated.
1415 typename Traits<T>::ArrayType *DataArrayTemplate<T>::changeNbOfComponents(std::size_t newNbOfComp, T dftValue) const
1418 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1419 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1420 ret->alloc(getNumberOfTuples(),newNbOfComp);
1421 const T *oldc(getConstPointer());
1422 T *nc(ret->getPointer());
1423 mcIdType nbOfTuples=getNumberOfTuples();
1424 std::size_t oldNbOfComp=getNumberOfComponents();
1425 std::size_t dim(std::min(oldNbOfComp,newNbOfComp));
1426 for(mcIdType i=0;i<nbOfTuples;i++)
1430 nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1431 for(;j<newNbOfComp;j++)
1432 nc[newNbOfComp*i+j]=dftValue;
1434 ret->setName(getName());
1435 for(std::size_t i=0;i<dim;i++)
1436 ret->setInfoOnComponent(i,getInfoOnComponent(i));
1437 ret->setName(getName());
1442 * Returns a copy of \a this array composed of selected components.
1443 * The new DataArrayDouble has the same number of tuples but includes components
1444 * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1445 * can be either less, same or more than \a this->getNbOfElems().
1446 * \param [in] compoIds - sequence of zero based indices of components to include
1447 * into the new array.
1448 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1449 * is to delete using decrRef() as it is no more needed.
1450 * \throw If \a this is not allocated.
1451 * \throw If a component index (\a i) is not valid:
1452 * \a i < 0 || \a i >= \a this->getNumberOfComponents().
1454 * \if ENABLE_EXAMPLES
1455 * \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1459 typename Traits<T>::ArrayType *DataArrayTemplate<T>::myKeepSelectedComponents(const std::vector<std::size_t>& compoIds) const
1462 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1463 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1464 std::size_t newNbOfCompo=compoIds.size();
1465 std::size_t oldNbOfCompo=getNumberOfComponents();
1466 for(std::vector<std::size_t>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1467 if((*it)>=oldNbOfCompo) // (*it) >= 0 (it is a size_t)
1469 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1470 throw INTERP_KERNEL::Exception(oss.str().c_str());
1472 mcIdType nbOfTuples(getNumberOfTuples());
1473 ret->alloc(nbOfTuples,newNbOfCompo);
1474 ret->copyPartOfStringInfoFrom(*this,compoIds);
1475 const T *oldc(getConstPointer());
1476 T *nc(ret->getPointer());
1477 for(mcIdType i=0;i<nbOfTuples;i++)
1478 for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1479 *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1484 * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1485 * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1486 * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1487 * This method is a specialization of selectByTupleIdSafeSlice().
1488 * \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1489 * \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1490 * If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1491 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1492 * is to delete using decrRef() as it is no more needed.
1493 * \throw If \a tupleIdBg < 0.
1494 * \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1495 * \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1496 * \sa DataArrayDouble::selectByTupleIdSafeSlice
1499 typename Traits<T>::ArrayType *DataArrayTemplate<T>::subArray(mcIdType tupleIdBg, mcIdType tupleIdEnd) const
1502 mcIdType nbt=getNumberOfTuples();
1505 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::subArray : The tupleIdBg parameter must be greater than 0 !";
1506 throw INTERP_KERNEL::Exception(oss.str().c_str());
1510 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << ":subArray : The tupleIdBg parameter is greater than number of tuples !";
1511 throw INTERP_KERNEL::Exception(oss.str().c_str());
1513 mcIdType trueEnd=tupleIdEnd;
1518 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << ":subArray : The tupleIdBg parameter is greater than number of tuples !";
1519 throw INTERP_KERNEL::Exception(oss.str().c_str());
1524 std::size_t nbComp=getNumberOfComponents();
1525 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1526 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1527 ret->alloc(trueEnd-tupleIdBg,nbComp);
1528 ret->copyStringInfoFrom(*this);
1529 std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1534 * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1535 * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1536 * tuple. Indices of the selected tuples are the same as ones returned by the Python
1537 * command \c range( \a bg, \a end2, \a step ).
1538 * This method is equivalent to selectByTupleIdSafe() except that the input array is
1539 * not constructed explicitly.
1540 * For more info on renumbering see \ref numbering.
1541 * \param [in] bg - index of the first tuple to copy from \a this array.
1542 * \param [in] end2 - index of the tuple before which the tuples to copy are located.
1543 * \param [in] step - index increment to get index of the next tuple to copy.
1544 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1545 * is to delete using decrRef() as it is no more needed.
1546 * \sa DataArrayDouble::subArray.
1549 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleIdSafeSlice(mcIdType bg, mcIdType end2, mcIdType step) const
1552 MCAuto<DataArray> ret0(buildNewEmptyInstance());
1553 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
1554 std::size_t nbComp(getNumberOfComponents());
1555 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::selectByTupleIdSafeSlice : ";
1556 mcIdType newNbOfTuples(GetNumberOfItemGivenBESRelative(bg,end2,step,oss.str()));
1557 ret->alloc(newNbOfTuples,nbComp);
1558 T *pt(ret->getPointer());
1559 const T *srcPt(getConstPointer()+bg*nbComp);
1560 for(mcIdType i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1561 std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1562 ret->copyStringInfoFrom(*this);
1567 * Copy all values from another DataArrayDouble into specified tuples and components
1568 * of \a this array. Textual data is not copied.
1569 * The tree parameters defining set of indices of tuples and components are similar to
1570 * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
1571 * \param [in] a - the array to copy values from.
1572 * \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
1573 * \param [in] endTuples - index of the tuple before which the tuples to assign to
1575 * \param [in] stepTuples - index increment to get index of the next tuple to assign to.
1576 * \param [in] bgComp - index of the first component of \a this array to assign values to.
1577 * \param [in] endComp - index of the component before which the components to assign
1579 * \param [in] stepComp - index increment to get index of the next component to assign to.
1580 * \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents()
1581 * must be equal to the number of columns to assign to, else an
1582 * exception is thrown; if \a false, then it is only required that \a
1583 * a->getNbOfElems() equals to number of values to assign to (this condition
1584 * must be respected even if \a strictCompoCompare is \a true). The number of
1585 * values to assign to is given by following Python expression:
1586 * \a nbTargetValues =
1587 * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
1588 * \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1589 * \throw If \a a is NULL.
1590 * \throw If \a a is not allocated.
1591 * \throw If \a this is not allocated.
1592 * \throw If parameters specifying tuples and components to assign to do not give a
1593 * non-empty range of increasing indices.
1594 * \throw If \a a->getNbOfElems() != \a nbTargetValues.
1595 * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
1596 * \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1598 * \if ENABLE_EXAMPLES
1599 * \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
1603 void DataArrayTemplate<T>::setPartOfValues1(const typename Traits<T>::ArrayType *a, mcIdType bgTuples, mcIdType endTuples, mcIdType stepTuples, mcIdType bgComp, mcIdType endComp, mcIdType stepComp, bool strictCompoCompare)
1607 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::setPartOfValues1 : input DataArrayDouble is NULL !";
1608 throw INTERP_KERNEL::Exception(oss.str().c_str());
1610 const char msg[]="DataArrayTemplate::setPartOfValues1";
1612 a->checkAllocated();
1613 mcIdType newNbOfTuples(DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg));
1614 mcIdType newNbOfComp(DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg));
1615 std::size_t nbComp(getNumberOfComponents());
1616 mcIdType nbOfTuples(getNumberOfTuples());
1617 DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
1618 DataArray::CheckValueInRangeEx(ToIdType(nbComp),bgComp,endComp,"invalid component value");
1619 bool assignTech(true);
1620 if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
1622 if(strictCompoCompare)
1623 a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1627 a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
1630 const T *srcPt(a->getConstPointer());
1631 T *pt(getPointer()+bgTuples*nbComp+bgComp);
1634 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1635 for(mcIdType j=0;j<newNbOfComp;j++,srcPt++)
1636 pt[j*stepComp]=*srcPt;
1640 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1642 const T*srcPt2=srcPt;
1643 for(mcIdType j=0;j<newNbOfComp;j++,srcPt2++)
1644 pt[j*stepComp]=*srcPt2;
1650 * Assign a given value to values at specified tuples and components of \a this array.
1651 * The tree parameters defining set of indices of tuples and components are similar to
1652 * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
1653 * \param [in] a - the value to assign.
1654 * \param [in] bgTuples - index of the first tuple of \a this array to assign to.
1655 * \param [in] endTuples - index of the tuple before which the tuples to assign to
1657 * \param [in] stepTuples - index increment to get index of the next tuple to assign to.
1658 * \param [in] bgComp - index of the first component of \a this array to assign to.
1659 * \param [in] endComp - index of the component before which the components to assign
1661 * \param [in] stepComp - index increment to get index of the next component to assign to.
1662 * \throw If \a this is not allocated.
1663 * \throw If parameters specifying tuples and components to assign to, do not give a
1664 * non-empty range of increasing indices or indices are out of a valid range
1665 * for \c this array.
1667 * \if ENABLE_EXAMPLES
1668 * \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
1672 void DataArrayTemplate<T>::setPartOfValuesSimple1(T a, mcIdType bgTuples, mcIdType endTuples, mcIdType stepTuples, mcIdType bgComp, mcIdType endComp, mcIdType stepComp)
1674 const char msg[]="DataArrayTemplate::setPartOfValuesSimple1";
1676 mcIdType newNbOfTuples(DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg));
1677 mcIdType newNbOfComp(DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg));
1678 std::size_t nbComp(getNumberOfComponents());
1679 mcIdType nbOfTuples(getNumberOfTuples());
1680 DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
1681 DataArray::CheckValueInRangeEx(ToIdType(nbComp),bgComp,endComp,"invalid component value");
1682 T *pt=getPointer()+bgTuples*nbComp+bgComp;
1683 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
1684 for(mcIdType j=0;j<newNbOfComp;j++)
1689 * Copy all values from another DataArrayDouble (\a a) into specified tuples and
1690 * components of \a this array. Textual data is not copied.
1691 * The tuples and components to assign to are defined by C arrays of indices.
1692 * There are two *modes of usage*:
1693 * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
1694 * of \a a is assigned to its own location within \a this array.
1695 * - If \a a includes one tuple, then all values of \a a are assigned to the specified
1696 * components of every specified tuple of \a this array. In this mode it is required
1697 * that \a a->getNumberOfComponents() equals to the number of specified components.
1699 * \param [in] a - the array to copy values from.
1700 * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
1701 * assign values of \a a to.
1702 * \param [in] endTuples - specifies the end of the array \a bgTuples, so that
1703 * pointer to a tuple index <em>(pi)</em> varies as this:
1704 * \a bgTuples <= \a pi < \a endTuples.
1705 * \param [in] bgComp - pointer to an array of component indices of \a this array to
1706 * assign values of \a a to.
1707 * \param [in] endComp - specifies the end of the array \a bgTuples, so that
1708 * pointer to a component index <em>(pi)</em> varies as this:
1709 * \a bgComp <= \a pi < \a endComp.
1710 * \param [in] strictCompoCompare - this parameter is checked only if the
1711 * *mode of usage* is the first; if it is \a true (default),
1712 * then \a a->getNumberOfComponents() must be equal
1713 * to the number of specified columns, else this is not required.
1714 * \throw If \a a is NULL.
1715 * \throw If \a a is not allocated.
1716 * \throw If \a this is not allocated.
1717 * \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
1718 * out of a valid range for \a this array.
1719 * \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
1720 * if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
1721 * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
1722 * <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
1724 * \if ENABLE_EXAMPLES
1725 * \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
1729 void DataArrayTemplate<T>::setPartOfValues2(const typename Traits<T>::ArrayType *a, const mcIdType *bgTuples, const mcIdType *endTuples, const mcIdType *bgComp, const mcIdType *endComp, bool strictCompoCompare)
1732 throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
1733 const char msg[]="DataArrayTemplate::setPartOfValues2";
1735 a->checkAllocated();
1736 std::size_t nbComp(getNumberOfComponents());
1737 mcIdType nbOfTuples(getNumberOfTuples());
1738 for(const mcIdType *z=bgComp;z!=endComp;z++)
1739 DataArray::CheckValueInRange(ToIdType(nbComp),*z,"invalid component id");
1740 mcIdType newNbOfTuples(ToIdType(std::distance(bgTuples,endTuples)));
1741 mcIdType newNbOfComp(ToIdType(std::distance(bgComp,endComp)));
1742 bool assignTech(true);
1743 if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
1745 if(strictCompoCompare)
1746 a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1750 a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
1753 T *pt(getPointer());
1754 const T *srcPt(a->getConstPointer());
1757 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1759 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1760 for(const mcIdType *z=bgComp;z!=endComp;z++,srcPt++)
1762 pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
1768 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1770 const T *srcPt2=srcPt;
1771 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1772 for(const mcIdType *z=bgComp;z!=endComp;z++,srcPt2++)
1774 pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
1781 * Assign a given value to values at specified tuples and components of \a this array.
1782 * The tuples and components to assign to are defined by C arrays of indices.
1783 * \param [in] a - the value to assign.
1784 * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
1786 * \param [in] endTuples - specifies the end of the array \a bgTuples, so that
1787 * pointer to a tuple index (\a pi) varies as this:
1788 * \a bgTuples <= \a pi < \a endTuples.
1789 * \param [in] bgComp - pointer to an array of component indices of \a this array to
1791 * \param [in] endComp - specifies the end of the array \a bgTuples, so that
1792 * pointer to a component index (\a pi) varies as this:
1793 * \a bgComp <= \a pi < \a endComp.
1794 * \throw If \a this is not allocated.
1795 * \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
1796 * out of a valid range for \a this array.
1798 * \if ENABLE_EXAMPLES
1799 * \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
1803 void DataArrayTemplate<T>::setPartOfValuesSimple2(T a, const mcIdType *bgTuples, const mcIdType *endTuples, const mcIdType *bgComp, const mcIdType *endComp)
1806 std::size_t nbComp=getNumberOfComponents();
1807 mcIdType nbOfTuples=getNumberOfTuples();
1808 for(const mcIdType *z=bgComp;z!=endComp;z++)
1809 DataArray::CheckValueInRange(ToIdType(nbComp),*z,"invalid component id");
1810 T *pt(getPointer());
1811 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1812 for(const mcIdType *z=bgComp;z!=endComp;z++)
1814 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1815 pt[(std::size_t)(*w)*nbComp+(*z)]=a;
1820 * Copy all values from another DataArrayDouble (\a a) into specified tuples and
1821 * components of \a this array. Textual data is not copied.
1822 * The tuples to assign to are defined by a C array of indices.
1823 * The components to assign to are defined by three values similar to parameters of
1824 * the Python function \c range(\c start,\c stop,\c step).
1825 * There are two *modes of usage*:
1826 * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
1827 * of \a a is assigned to its own location within \a this array.
1828 * - If \a a includes one tuple, then all values of \a a are assigned to the specified
1829 * components of every specified tuple of \a this array. In this mode it is required
1830 * that \a a->getNumberOfComponents() equals to the number of specified components.
1832 * \param [in] a - the array to copy values from.
1833 * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
1834 * assign values of \a a to.
1835 * \param [in] endTuples - specifies the end of the array \a bgTuples, so that
1836 * pointer to a tuple index <em>(pi)</em> varies as this:
1837 * \a bgTuples <= \a pi < \a endTuples.
1838 * \param [in] bgComp - index of the first component of \a this array to assign to.
1839 * \param [in] endComp - index of the component before which the components to assign
1841 * \param [in] stepComp - index increment to get index of the next component to assign to.
1842 * \param [in] strictCompoCompare - this parameter is checked only in the first
1843 * *mode of usage*; if \a strictCompoCompare is \a true (default),
1844 * then \a a->getNumberOfComponents() must be equal
1845 * to the number of specified columns, else this is not required.
1846 * \throw If \a a is NULL.
1847 * \throw If \a a is not allocated.
1848 * \throw If \a this is not allocated.
1849 * \throw If any index of tuple given by \a bgTuples is out of a valid range for
1851 * \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
1852 * if <em> a->getNumberOfComponents()</em> is unequal to the number of components
1853 * defined by <em>(bgComp,endComp,stepComp)</em>.
1854 * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
1855 * <em> a->getNumberOfComponents()</em> is unequal to the number of components
1856 * defined by <em>(bgComp,endComp,stepComp)</em>.
1857 * \throw If parameters specifying components to assign to, do not give a
1858 * non-empty range of increasing indices or indices are out of a valid range
1859 * for \c this array.
1861 * \if ENABLE_EXAMPLES
1862 * \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
1866 void DataArrayTemplate<T>::setPartOfValues3(const typename Traits<T>::ArrayType *a, const mcIdType *bgTuples, const mcIdType *endTuples, mcIdType bgComp, mcIdType endComp, mcIdType stepComp, bool strictCompoCompare)
1869 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValues3 : input DataArrayDouble is NULL !");
1870 const char msg[]="DataArrayTemplate::setPartOfValues3";
1872 a->checkAllocated();
1873 mcIdType newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
1874 std::size_t nbComp(getNumberOfComponents());
1875 mcIdType nbOfTuples(getNumberOfTuples());
1876 DataArray::CheckValueInRangeEx(ToIdType(nbComp),bgComp,endComp,"invalid component value");
1877 mcIdType newNbOfTuples=ToIdType(std::distance(bgTuples,endTuples));
1878 bool assignTech=true;
1879 if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
1881 if(strictCompoCompare)
1882 a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
1886 a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
1889 T *pt(getPointer()+bgComp);
1890 const T *srcPt(a->getConstPointer());
1893 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1894 for(mcIdType j=0;j<newNbOfComp;j++,srcPt++)
1896 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1897 pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
1902 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1904 const T *srcPt2=srcPt;
1905 for(mcIdType j=0;j<newNbOfComp;j++,srcPt2++)
1907 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1908 pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
1915 * Assign a given value to values at specified tuples and components of \a this array.
1916 * The tuples to assign to are defined by a C array of indices.
1917 * The components to assign to are defined by three values similar to parameters of
1918 * the Python function \c range(\c start,\c stop,\c step).
1919 * \param [in] a - the value to assign.
1920 * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
1922 * \param [in] endTuples - specifies the end of the array \a bgTuples, so that
1923 * pointer to a tuple index <em>(pi)</em> varies as this:
1924 * \a bgTuples <= \a pi < \a endTuples.
1925 * \param [in] bgComp - index of the first component of \a this array to assign to.
1926 * \param [in] endComp - index of the component before which the components to assign
1928 * \param [in] stepComp - index increment to get index of the next component to assign to.
1929 * \throw If \a this is not allocated.
1930 * \throw If any index of tuple given by \a bgTuples is out of a valid range for
1932 * \throw If parameters specifying components to assign to, do not give a
1933 * non-empty range of increasing indices or indices are out of a valid range
1934 * for \c this array.
1936 * \if ENABLE_EXAMPLES
1937 * \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
1941 void DataArrayTemplate<T>::setPartOfValuesSimple3(T a, const mcIdType *bgTuples, const mcIdType *endTuples, mcIdType bgComp, mcIdType endComp, mcIdType stepComp)
1943 const char msg[]="DataArrayTemplate::setPartOfValuesSimple3";
1945 std::size_t newNbOfComp(DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg));
1946 std::size_t nbComp(getNumberOfComponents());
1947 mcIdType nbOfTuples(getNumberOfTuples());
1948 DataArray::CheckValueInRangeEx(ToIdType(nbComp),bgComp,endComp,"invalid component value");
1949 T *pt(getPointer()+bgComp);
1950 for(const mcIdType *w=bgTuples;w!=endTuples;w++)
1951 for(std::size_t j=0;j<newNbOfComp;j++)
1953 DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
1954 pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
1959 * Copy all values from another DataArrayDouble into specified tuples and components
1960 * of \a this array. Textual data is not copied.
1961 * The tree parameters defining set of indices of tuples and components are similar to
1962 * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
1963 * \param [in] a - the array to copy values from.
1964 * \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
1965 * \param [in] endTuples - index of the tuple before which the tuples to assign to
1967 * \param [in] stepTuples - index increment to get index of the next tuple to assign to.
1968 * \param [in] bgComp - pointer to an array of component indices of \a this array to
1970 * \param [in] endComp - specifies the end of the array \a bgTuples, so that
1971 * pointer to a component index (\a pi) varies as this:
1972 * \a bgComp <= \a pi < \a endComp.
1973 * \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents()
1974 * must be equal to the number of columns to assign to, else an
1975 * exception is thrown; if \a false, then it is only required that \a
1976 * a->getNbOfElems() equals to number of values to assign to (this condition
1977 * must be respected even if \a strictCompoCompare is \a true). The number of
1978 * values to assign to is given by following Python expression:
1979 * \a nbTargetValues =
1980 * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
1981 * \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1982 * \throw If \a a is NULL.
1983 * \throw If \a a is not allocated.
1984 * \throw If \a this is not allocated.
1985 * \throw If parameters specifying tuples and components to assign to do not give a
1986 * non-empty range of increasing indices.
1987 * \throw If \a a->getNbOfElems() != \a nbTargetValues.
1988 * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
1989 * \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
1993 void DataArrayTemplate<T>::setPartOfValues4(const typename Traits<T>::ArrayType *a, mcIdType bgTuples, mcIdType endTuples, mcIdType stepTuples, const mcIdType *bgComp, const mcIdType *endComp, bool strictCompoCompare)
1995 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValues4 : input DataArrayTemplate is NULL !");
1996 const char msg[]="DataArrayTemplate::setPartOfValues4";
1998 a->checkAllocated();
1999 mcIdType newNbOfTuples(DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg));
2000 std::size_t newNbOfComp(std::distance(bgComp,endComp));
2001 std::size_t nbComp(getNumberOfComponents());
2002 for(const mcIdType *z=bgComp;z!=endComp;z++)
2003 DataArray::CheckValueInRange(ToIdType(nbComp),*z,"invalid component id");
2004 mcIdType nbOfTuples(getNumberOfTuples());
2005 DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2006 bool assignTech(true);
2007 if(a->getNbOfElems()==ToIdType(newNbOfTuples*newNbOfComp))
2009 if(strictCompoCompare)
2010 a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2014 a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2017 const T *srcPt(a->getConstPointer());
2018 T *pt(getPointer()+bgTuples*nbComp);
2021 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2022 for(const mcIdType *z=bgComp;z!=endComp;z++,srcPt++)
2027 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2029 const T *srcPt2(srcPt);
2030 for(const mcIdType *z=bgComp;z!=endComp;z++,srcPt2++)
2037 void DataArrayTemplate<T>::setPartOfValuesSimple4(T a, mcIdType bgTuples, mcIdType endTuples, mcIdType stepTuples, const mcIdType *bgComp, const mcIdType *endComp)
2039 const char msg[]="DataArrayTemplate::setPartOfValuesSimple4";
2041 mcIdType newNbOfTuples(DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg));
2042 std::size_t nbComp(getNumberOfComponents());
2043 for(const mcIdType *z=bgComp;z!=endComp;z++)
2044 DataArray::CheckValueInRange(ToIdType(nbComp),*z,"invalid component id");
2045 mcIdType nbOfTuples(getNumberOfTuples());
2046 DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2047 T *pt=getPointer()+bgTuples*nbComp;
2048 for(mcIdType i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2049 for(const mcIdType *z=bgComp;z!=endComp;z++)
2054 * Copy some tuples from another DataArrayDouble into specified tuples
2055 * of \a this array. Textual data is not copied. Both arrays must have equal number of
2057 * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2058 * All components of selected tuples are copied.
2059 * \param [in] a - the array to copy values from.
2060 * \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2061 * target tuples of \a this. \a tuplesSelec has two components, and the
2062 * first component specifies index of the source tuple and the second
2063 * one specifies index of the target tuple.
2064 * \throw If \a this is not allocated.
2065 * \throw If \a a is NULL.
2066 * \throw If \a a is not allocated.
2067 * \throw If \a tuplesSelec is NULL.
2068 * \throw If \a tuplesSelec is not allocated.
2069 * \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2070 * \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2071 * \throw If any tuple index given by \a tuplesSelec is out of a valid range for
2072 * the corresponding (\a this or \a a) array.
2075 void DataArrayTemplate<T>::setPartOfValuesAdv(const typename Traits<T>::ArrayType *a, const DataArrayIdType *tuplesSelec)
2077 if(!a || !tuplesSelec)
2078 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValuesAdv : input DataArrayTemplate is NULL !");
2080 a->checkAllocated();
2081 tuplesSelec->checkAllocated();
2082 std::size_t nbOfComp(getNumberOfComponents());
2083 if(nbOfComp!=a->getNumberOfComponents())
2084 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValuesAdv : This and a do not have the same number of components !");
2085 if(tuplesSelec->getNumberOfComponents()!=2)
2086 throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2087 mcIdType thisNt(getNumberOfTuples());
2088 mcIdType aNt(a->getNumberOfTuples());
2089 T *valsToSet(getPointer());
2090 const T *valsSrc(a->getConstPointer());
2091 for(const mcIdType *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2093 if(tuple[1]>=0 && tuple[1]<aNt)
2095 if(tuple[0]>=0 && tuple[0]<thisNt)
2096 std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2099 std::ostringstream oss; oss << "DataArrayTemplate::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2100 oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2101 throw INTERP_KERNEL::Exception(oss.str().c_str());
2106 std::ostringstream oss; oss << "DataArrayTemplate::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2107 oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2108 throw INTERP_KERNEL::Exception(oss.str().c_str());
2114 * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2115 * of \a this array. Textual data is not copied. Both arrays must have equal number of
2117 * The tuples to assign to are defined by index of the first tuple, and
2118 * their number is defined by \a tuplesSelec->getNumberOfTuples().
2119 * The tuples to copy are defined by values of a DataArrayInt.
2120 * All components of selected tuples are copied.
2121 * \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2123 * \param [in] aBase - the array to copy values from.
2124 * \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2125 * \throw If \a this is not allocated.
2126 * \throw If \a aBase is NULL.
2127 * \throw If \a aBase is not allocated.
2128 * \throw If \a tuplesSelec is NULL.
2129 * \throw If \a tuplesSelec is not allocated.
2130 * \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2131 * \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2132 * \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2133 * \throw If any tuple index given by \a tuplesSelec is out of a valid range for
2137 void DataArrayTemplate<T>::setContigPartOfSelectedValues(mcIdType tupleIdStart, const DataArray *aBase, const DataArrayIdType *tuplesSelec)
2139 if(!aBase || !tuplesSelec)
2140 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : input DataArray is NULL !");
2141 const typename Traits<T>::ArrayType *a(dynamic_cast<const typename Traits<T>::ArrayType *>(aBase));
2143 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2145 a->checkAllocated();
2146 tuplesSelec->checkAllocated();
2147 std::size_t nbOfComp(getNumberOfComponents());
2148 if(nbOfComp!=a->getNumberOfComponents())
2149 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2150 if(tuplesSelec->getNumberOfComponents()!=1)
2151 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2152 mcIdType thisNt(getNumberOfTuples());
2153 mcIdType aNt(a->getNumberOfTuples());
2154 mcIdType nbOfTupleToWrite(tuplesSelec->getNumberOfTuples());
2155 T *valsToSet(getPointer()+tupleIdStart*nbOfComp);
2156 if(tupleIdStart+nbOfTupleToWrite>thisNt)
2157 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : invalid number range of values to write !");
2158 const T *valsSrc=a->getConstPointer();
2159 for(const mcIdType *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2161 if(*tuple>=0 && *tuple<aNt)
2163 std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2167 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2168 oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2169 throw INTERP_KERNEL::Exception(oss.str().c_str());
2175 * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2176 * of \a this array. Textual data is not copied. Both arrays must have equal number of
2178 * The tuples to copy are defined by three values similar to parameters of
2179 * the Python function \c range(\c start,\c stop,\c step).
2180 * The tuples to assign to are defined by index of the first tuple, and
2181 * their number is defined by number of tuples to copy.
2182 * All components of selected tuples are copied.
2183 * \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2185 * \param [in] aBase - the array to copy values from.
2186 * \param [in] bg - index of the first tuple to copy of the array \a aBase.
2187 * \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2189 * \param [in] step - index increment to get index of the next tuple to copy.
2190 * \throw If \a this is not allocated.
2191 * \throw If \a aBase is NULL.
2192 * \throw If \a aBase is not allocated.
2193 * \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2194 * \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2195 * \throw If parameters specifying tuples to copy, do not give a
2196 * non-empty range of increasing indices or indices are out of a valid range
2197 * for the array \a aBase.
2200 void DataArrayTemplate<T>::setContigPartOfSelectedValuesSlice(mcIdType tupleIdStart, const DataArray *aBase, mcIdType bg, mcIdType end2, mcIdType step)
2204 std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::setContigPartOfSelectedValuesSlice : input DataArray is NULL !";
2205 throw INTERP_KERNEL::Exception(oss.str().c_str());
2207 const typename Traits<T>::ArrayType *a(dynamic_cast<const typename Traits<T>::ArrayType *>(aBase));
2209 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValuesSlice : input DataArray aBase is not a DataArrayDouble !");
2211 a->checkAllocated();
2212 std::size_t nbOfComp(getNumberOfComponents());
2213 const char msg[]="DataArrayDouble::setContigPartOfSelectedValuesSlice";
2214 mcIdType nbOfTupleToWrite(DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg));
2215 if(nbOfComp!=a->getNumberOfComponents())
2216 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValuesSlice : This and a do not have the same number of components !");
2217 mcIdType thisNt(getNumberOfTuples());
2218 mcIdType aNt(a->getNumberOfTuples());
2219 T *valsToSet(getPointer()+tupleIdStart*nbOfComp);
2220 if(tupleIdStart+nbOfTupleToWrite>thisNt)
2221 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValuesSlice : invalid number range of values to write !");
2223 throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValuesSlice : invalid range of values to read !");
2224 const T *valsSrc(a->getConstPointer()+bg*nbOfComp);
2225 for(mcIdType i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2227 std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2232 * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
2233 * of tuples specified by \a ranges parameter.
2234 * For more info on renumbering see \ref numbering.
2235 * \param [in] ranges - std::vector of std::pair's each of which defines a range
2236 * of tuples in [\c begin,\c end) format.
2237 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2238 * is to delete using decrRef() as it is no more needed.
2239 * \throw If \a end < \a begin.
2240 * \throw If \a end > \a this->getNumberOfTuples().
2241 * \throw If \a this is not allocated.
2244 typename Traits<T>::ArrayType *DataArrayTemplate<T>::mySelectByTupleRanges(const std::vector<std::pair<mcIdType,mcIdType> >& ranges) const
2247 std::size_t nbOfComp(getNumberOfComponents());
2248 mcIdType nbOfTuplesThis(getNumberOfTuples());
2251 MCAuto<DataArray> ret0(buildNewEmptyInstance());
2252 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
2253 ret->alloc(0,nbOfComp);
2254 ret->copyStringInfoFrom(*this);
2257 mcIdType ref(ranges.front().first),nbOfTuples(0);
2258 bool isIncreasing(true);
2259 for(std::vector<std::pair<mcIdType,mcIdType> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
2261 if((*it).first<=(*it).second)
2263 if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
2265 nbOfTuples+=(*it).second-(*it).first;
2267 isIncreasing=ref<=(*it).first;
2272 std::ostringstream oss; oss << "DataArrayTemplate::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
2273 oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
2274 throw INTERP_KERNEL::Exception(oss.str().c_str());
2279 std::ostringstream oss; oss << "DataArrayTemplate::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
2280 oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
2281 throw INTERP_KERNEL::Exception(oss.str().c_str());
2284 if(isIncreasing && nbOfTuplesThis==nbOfTuples)
2285 return static_cast<typename Traits<T>::ArrayType *>(deepCopy());
2286 MCAuto<DataArray> ret0(buildNewEmptyInstance());
2287 MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
2288 ret->alloc(nbOfTuples,nbOfComp);
2289 ret->copyStringInfoFrom(*this);
2290 const T *src(getConstPointer());
2291 T *work(ret->getPointer());
2292 for(std::vector<std::pair<mcIdType,mcIdType> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
2293 work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
2298 * Returns the first value of \a this.
2299 * \return double - the last value of \a this array.
2300 * \throw If \a this is not allocated.
2301 * \throw If \a this->getNumberOfComponents() != 1.
2302 * \throw If \a this->getNumberOfTuples() < 1.
2305 T DataArrayTemplate<T>::front() const
2308 if(getNumberOfComponents()!=1)
2309 throw INTERP_KERNEL::Exception("DataArrayTemplate::front : number of components not equal to one !");
2310 mcIdType nbOfTuples=getNumberOfTuples();
2312 throw INTERP_KERNEL::Exception("DataArrayTemplate::front : number of tuples must be >= 1 !");
2313 return *(getConstPointer());
2317 * Returns the last value of \a this.
2318 * \return double - the last value of \a this array.
2319 * \throw If \a this is not allocated.
2320 * \throw If \a this->getNumberOfComponents() != 1.
2321 * \throw If \a this->getNumberOfTuples() < 1.
2324 T DataArrayTemplate<T>::back() const
2327 if(getNumberOfComponents()!=1)
2328 throw INTERP_KERNEL::Exception("DataArrayTemplate::back : number of components not equal to one !");
2329 mcIdType nbOfTuples=getNumberOfTuples();
2331 throw INTERP_KERNEL::Exception("DataArrayTemplate::back : number of tuples must be >= 1 !");
2332 return *(getConstPointer()+nbOfTuples-1);
2336 * Returns the maximal value and its location within \a this one-dimensional array.
2337 * \param [out] tupleId - index of the tuple holding the maximal value.
2338 * \return double - the maximal value among all values of \a this array.
2339 * \throw If \a this->getNumberOfComponents() != 1
2340 * \throw If \a this->getNumberOfTuples() < 1
2341 * \sa getMaxAbsValue, getMinValue
2344 T DataArrayTemplate<T>::getMaxValue(mcIdType& tupleId) const
2347 if(getNumberOfComponents()!=1)
2348 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 !");
2349 mcIdType nbOfTuples=getNumberOfTuples();
2351 throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
2352 const T *vals(getConstPointer());
2353 const T *loc(std::max_element(vals,vals+nbOfTuples));
2354 tupleId=ToIdType(std::distance(vals,loc));
2359 * Returns the maximal value within \a this array that is allowed to have more than
2361 * \return double - the maximal value among all values of \a this array.
2362 * \throw If \a this is not allocated.
2363 * If \a this is empty.
2364 * \sa getMaxAbsValueInArray, getMinValueInArray
2367 T DataArrayTemplate<T>::getMaxValueInArray() const
2371 THROW_IK_EXCEPTION("getMaxValueInArray : this is empty !");
2372 const T *loc(std::max_element(begin(),end()));
2377 * Returns the maximal absolute value in \a this and the first occurrence location associated to it.
2378 * \return the element in this (positive or negative) having the max abs value in \a this.
2379 * \throw If \a this is not allocated.
2380 * \throw If \a this is non one component array.
2381 * \throw If \a this is empty.
2384 T DataArrayTemplate<T>::getMaxAbsValue(std::size_t& tupleId) const
2387 if(getNumberOfComponents()!=1)
2388 throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxAbsValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before or call 'getMaxValueInArray' method !");
2389 mcIdType nbTuples(this->getNumberOfTuples());
2391 throw INTERP_KERNEL::Exception("DataArrayTemplate<T>::getMaxAbsValue : empty array !");
2394 const T *pt(begin());
2395 for(mcIdType i=0;i<nbTuples;i++,pt++)
2397 T cand((T)std::abs(*pt));
2404 return this->getIJ(ToIdType(tupleId),0);
2408 * Returns the maximal absolute value in \a this.
2409 * \throw If \a this is not allocated.
2410 * \throw If \a this is non one component array.
2411 * \throw If \a this is empty.
2414 T DataArrayTemplate<T>::getMaxAbsValueInArray() const
2417 return getMaxAbsValue(dummy);
2421 * Returns the minimal value and its location within \a this one-dimensional array.
2422 * \param [out] tupleId - index of the tuple holding the minimal value.
2423 * \return double - the minimal value among all values of \a this array.
2424 * \throw If \a this->getNumberOfComponents() != 1
2425 * \throw If \a this->getNumberOfTuples() < 1
2428 T DataArrayTemplate<T>::getMinValue(mcIdType& tupleId) const
2431 if(getNumberOfComponents()!=1)
2432 throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
2433 mcIdType nbOfTuples=getNumberOfTuples();
2435 throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
2436 const T *vals(getConstPointer());
2437 const T *loc(std::min_element(vals,vals+nbOfTuples));
2438 tupleId=ToIdType(std::distance(vals,loc));
2443 * Returns the minimal value within \a this array that is allowed to have more than
2445 * \return double - the minimal value among all values of \a this array.
2446 * \throw If \a this is not allocated.
2449 T DataArrayTemplate<T>::getMinValueInArray() const
2452 const T *loc=std::min_element(begin(),end());
2457 void DataArrayTemplate<T>::circularPermutation(mcIdType nbOfShift)
2460 std::size_t nbOfCompo(getNumberOfComponents());
2461 mcIdType nbTuples(getNumberOfTuples());
2462 mcIdType effNbSh(EffectiveCircPerm(nbOfShift,nbTuples));
2465 T *work(getPointer());
2466 if(effNbSh<nbTuples-effNbSh)
2468 typename INTERP_KERNEL::AutoPtr<T> buf(new T[effNbSh*nbOfCompo]);
2469 std::copy(work,work+effNbSh*nbOfCompo,(T *)buf);
2470 std::copy(work+effNbSh*nbOfCompo,work+nbTuples*nbOfCompo,work);// ze big shift
2471 std::copy((T *)buf,(T *)buf+effNbSh*nbOfCompo,work+(nbTuples-effNbSh)*nbOfCompo);
2475 typename INTERP_KERNEL::AutoPtr<T> buf(new T[(nbTuples-effNbSh)*nbOfCompo]);
2476 std::copy(work+effNbSh*nbOfCompo,work+nbTuples*nbOfCompo,(T *)buf);
2477 std::copy(work,work+effNbSh*nbOfCompo,work+(nbTuples-effNbSh)*nbOfCompo);// ze big shift
2478 std::copy((T*)buf,(T *)buf+(nbTuples-effNbSh)*nbOfCompo,work);
2483 void DataArrayTemplate<T>::circularPermutationPerTuple(mcIdType nbOfShift)
2486 std::size_t nbOfCompo(getNumberOfComponents());
2487 mcIdType nbTuples(getNumberOfTuples());
2488 mcIdType effNbSh(EffectiveCircPerm(nbOfShift,ToIdType(nbOfCompo)));
2491 T *work(getPointer());
2492 if(effNbSh<ToIdType(nbOfCompo)-effNbSh)
2494 typename INTERP_KERNEL::AutoPtr<T> buf(new T[effNbSh]);
2495 for(mcIdType i=0;i<nbTuples;i++,work+=nbOfCompo)
2497 std::copy(work,work+effNbSh,(T *)buf);
2498 std::copy(work+effNbSh,work+nbOfCompo,work);// ze big shift
2499 std::copy((T *)buf,(T *)buf+effNbSh,work+(nbOfCompo-effNbSh));
2504 typename INTERP_KERNEL::AutoPtr<T> buf(new T[nbOfCompo-effNbSh]);
2505 for(mcIdType i=0;i<nbTuples;i++,work+=nbOfCompo)
2507 std::copy(work+effNbSh,work+nbOfCompo,(T *)buf);
2508 std::copy(work,work+effNbSh,work+(nbOfCompo-effNbSh));// ze big shift
2509 std::copy((T*)buf,(T *)buf+(nbOfCompo-effNbSh),work);
2512 std::vector<std::string> sts(nbOfCompo);
2513 for(std::size_t i=0;i<nbOfCompo;i++)
2514 sts[i]=_info_on_compo[(i+effNbSh)%nbOfCompo];
2515 setInfoOnComponents(sts);
2519 void DataArrayTemplate<T>::reversePerTuple()
2522 std::size_t nbOfCompo(getNumberOfComponents());
2523 mcIdType nbTuples(getNumberOfTuples());
2526 T *work(getPointer());
2527 for(mcIdType i=0;i<nbTuples;i++,work+=nbOfCompo)
2528 std::reverse(work,work+nbOfCompo);
2529 std::reverse(_info_on_compo.begin(),_info_on_compo.end());
2533 * Assign pointer to one array to a pointer to another appay. Reference counter of
2534 * \a arrayToSet is incremented / decremented.
2535 * \param [in] newArray - the pointer to array to assign to \a arrayToSet.
2536 * \param [in,out] arrayToSet - the pointer to array to assign to.
2539 void DataArrayTemplate<T>::SetArrayIn(typename Traits<T>::ArrayType *newArray, typename Traits<T>::ArrayType* &arrayToSet)
2541 if(newArray!=arrayToSet)
2544 arrayToSet->decrRef();
2545 arrayToSet=newArray;
2547 arrayToSet->incrRef();
2552 * Assign zero to all values in \a this array. To know more on filling arrays see
2553 * \ref MEDCouplingArrayFill.
2554 * \throw If \a this is not allocated.
2557 void DataArrayTemplate<T>::fillWithZero()
2559 fillWithValue((T)0);
2562 //////////////////////////////
2566 // local static function to copy arrays without warnings
2567 template <class TIn, class TOut>
2568 static void copyCast (const TIn *begin, const TIn *end, TOut* dest)
2570 for (const TIn *src = begin; src != end; ++src, ++dest)
2571 *dest=static_cast<TOut>(*src);
2577 MCAuto< typename Traits<U>::ArrayType > DataArrayTemplateClassic<T>::convertToOtherTypeOfArr() const
2579 this->checkAllocated();
2580 MCAuto<typename Traits<U>::ArrayType> ret(Traits<U>::ArrayType::New());
2581 ret->alloc(this->getNumberOfTuples(),this->getNumberOfComponents());
2582 std::size_t nbOfVals(this->getNbOfElems());
2583 const T *src(this->begin());
2584 U *dest(ret->getPointer());
2585 // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
2586 copyCast(src, src+nbOfVals, dest);
2587 //std::copy(src,src+nbOfVals,dest);
2588 ret->copyStringInfoFrom(*this);
2593 * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
2594 * array to the new one.
2595 * \return DataArrayDouble * - the new instance of DataArrayInt.
2598 MCAuto<DataArrayDouble> DataArrayTemplateClassic<T>::convertToDblArr() const
2600 return convertToOtherTypeOfArr<double>();
2604 * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
2605 * array to the new one.
2606 * \return DataArrayInt * - the new instance of DataArrayInt.
2609 MCAuto<DataArrayInt> DataArrayTemplateClassic<T>::convertToIntArr() const
2611 return convertToOtherTypeOfArr<int>();
2615 * Creates a new DataArrayInt64 and assigns all (textual and numerical) data of \a this
2616 * array to the new one.
2617 * \return DataArrayInt * - the new instance of DataArrayInt64.
2620 MCAuto<DataArrayInt64> DataArrayTemplateClassic<T>::convertToInt64Arr() const
2622 return convertToOtherTypeOfArr<Int64>();
2625 * Creates a new DataArrayFloat and assigns all (textual and numerical) data of \a this
2626 * array to the new one.
2627 * \return DataArrayFloat * - the new instance of DataArrayInt.
2630 MCAuto<DataArrayFloat> DataArrayTemplateClassic<T>::convertToFloatArr() const
2632 return convertToOtherTypeOfArr<float>();
2636 * Apply a linear function to a given component of \a this array, so that
2637 * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
2638 * \param [in] a - the first coefficient of the function.
2639 * \param [in] b - the second coefficient of the function.
2640 * \param [in] compoId - the index of component to modify.
2641 * \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
2644 void DataArrayTemplateClassic<T>::applyLin(T a, T b, std::size_t compoId)
2646 this->checkAllocated();
2647 std::size_t nbOfComp=this->getNumberOfComponents();
2648 if(compoId>=nbOfComp)
2650 std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
2651 throw INTERP_KERNEL::Exception(oss.str().c_str());
2653 T *ptr(this->getPointer()+compoId);
2654 mcIdType nbOfTuple=this->getNumberOfTuples();
2655 for(mcIdType i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
2657 this->declareAsNew();
2661 * Apply a linear function to all elements of \a this array, so that
2662 * an element _x_ becomes \f$ a * x + b \f$.
2663 * \param [in] a - the first coefficient of the function.
2664 * \param [in] b - the second coefficient of the function.
2665 * \throw If \a this is not allocated.
2668 void DataArrayTemplateClassic<T>::applyLin(T a, T b)
2670 this->checkAllocated();
2671 T *ptr(this->getPointer());
2672 std::size_t nbOfElems(this->getNbOfElems());
2673 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2675 this->declareAsNew();
2679 * Returns a full copy of \a this array except that sign of all elements is reversed.
2680 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2681 * same number of tuples and component as \a this array.
2682 * The caller is to delete this result array using decrRef() as it is no more
2684 * \throw If \a this is not allocated.
2687 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::negate() const
2689 this->checkAllocated();
2690 MCAuto<typename Traits<T>::ArrayType> newArr(Traits<T>::ArrayType::New());
2691 mcIdType nbOfTuples(this->getNumberOfTuples());
2692 std::size_t nbOfComp(this->getNumberOfComponents());
2693 newArr->alloc(nbOfTuples,nbOfComp);
2694 const T *cptr(this->begin());
2695 std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<T>());
2696 newArr->copyStringInfoFrom(*this);
2697 return newArr.retn();
2702 void DataArrayTemplateClassic<T>::somethingEqual(const typename Traits<T>::ArrayType *other)
2705 throw INTERP_KERNEL::Exception("DataArray<T>::SomethingEqual : input DataArray<T> instance is NULL !");
2706 const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
2707 this->checkAllocated();
2708 other->checkAllocated();
2709 mcIdType nbOfTuple(this->getNumberOfTuples());
2710 mcIdType nbOfTuple2(other->getNumberOfTuples());
2711 std::size_t nbOfComp(this->getNumberOfComponents());
2712 std::size_t nbOfComp2(other->getNumberOfComponents());
2713 if(nbOfTuple==nbOfTuple2)
2715 if(nbOfComp==nbOfComp2)
2717 std::transform(this->begin(),this->end(),other->begin(),this->getPointer(),FCT());
2719 else if(nbOfComp2==1)
2721 T *ptr(this->getPointer());
2722 const T *ptrc(other->begin());
2723 for(mcIdType i=0;i<nbOfTuple;i++)
2724 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind(FCT(),std::placeholders::_1,*ptrc++));
2727 throw INTERP_KERNEL::Exception(msg);
2729 else if(nbOfTuple2==1)
2731 if(nbOfComp2==nbOfComp)
2733 T *ptr(this->getPointer());
2734 const T *ptrc(other->begin());
2735 for(mcIdType i=0;i<nbOfTuple;i++)
2736 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,FCT());
2739 throw INTERP_KERNEL::Exception(msg);
2742 throw INTERP_KERNEL::Exception(msg);
2743 this->declareAsNew();
2747 * Adds values of another DataArrayDouble to values of \a this one. There are 3
2749 * 1. The arrays have same number of tuples and components. Then each value of
2750 * \a other array is added to the corresponding value of \a this array, i.e.:
2751 * _a_ [ i, j ] += _other_ [ i, j ].
2752 * 2. The arrays have same number of tuples and \a other array has one component. Then
2753 * _a_ [ i, j ] += _other_ [ i, 0 ].
2754 * 3. The arrays have same number of components and \a other array has one tuple. Then
2755 * _a_ [ i, j ] += _a2_ [ 0, j ].
2757 * \param [in] other - an array to add to \a this one.
2758 * \throw If \a other is NULL.
2759 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
2760 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
2761 * \a other has number of both tuples and components not equal to 1.
2764 void DataArrayTemplateClassic<T>::addEqual(const typename Traits<T>::ArrayType *other)
2766 this->somethingEqual< std::plus<T> >(other);
2770 * Subtract values of another DataArrayDouble from values of \a this one. There are 3
2772 * 1. The arrays have same number of tuples and components. Then each value of
2773 * \a other array is subtracted from the corresponding value of \a this array, i.e.:
2774 * _a_ [ i, j ] -= _other_ [ i, j ].
2775 * 2. The arrays have same number of tuples and \a other array has one component. Then
2776 * _a_ [ i, j ] -= _other_ [ i, 0 ].
2777 * 3. The arrays have same number of components and \a other array has one tuple. Then
2778 * _a_ [ i, j ] -= _a2_ [ 0, j ].
2780 * \param [in] other - an array to subtract from \a this one.
2781 * \throw If \a other is NULL.
2782 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
2783 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
2784 * \a other has number of both tuples and components not equal to 1.
2787 void DataArrayTemplateClassic<T>::substractEqual(const typename Traits<T>::ArrayType *other)
2789 this->somethingEqual< std::minus<T> >(other);
2793 * Multiply values of another DataArrayDouble to values of \a this one. There are 3
2795 * 1. The arrays have same number of tuples and components. Then each value of
2796 * \a other array is multiplied to the corresponding value of \a this array, i.e.
2797 * _this_ [ i, j ] *= _other_ [ i, j ].
2798 * 2. The arrays have same number of tuples and \a other array has one component. Then
2799 * _this_ [ i, j ] *= _other_ [ i, 0 ].
2800 * 3. The arrays have same number of components and \a other array has one tuple. Then
2801 * _this_ [ i, j ] *= _a2_ [ 0, j ].
2803 * \param [in] other - an array to multiply to \a this one.
2804 * \throw If \a other is NULL.
2805 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
2806 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
2807 * \a other has number of both tuples and components not equal to 1.
2810 void DataArrayTemplateClassic<T>::multiplyEqual(const typename Traits<T>::ArrayType *other)
2812 this->somethingEqual< std::multiplies<T> >(other);
2816 * Divide values of \a this array by values of another DataArrayDouble. There are 3
2818 * 1. The arrays have same number of tuples and components. Then each value of
2819 * \a this array is divided by the corresponding value of \a other one, i.e.:
2820 * _a_ [ i, j ] /= _other_ [ i, j ].
2821 * 2. The arrays have same number of tuples and \a other array has one component. Then
2822 * _a_ [ i, j ] /= _other_ [ i, 0 ].
2823 * 3. The arrays have same number of components and \a other array has one tuple. Then
2824 * _a_ [ i, j ] /= _a2_ [ 0, j ].
2826 * \warning No check of division by zero is performed!
2827 * \param [in] other - an array to divide \a this one by.
2828 * \throw If \a other is NULL.
2829 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
2830 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
2831 * \a other has number of both tuples and components not equal to 1.
2834 void DataArrayTemplateClassic<T>::divideEqual(const typename Traits<T>::ArrayType *other)
2836 this->somethingEqual< std::divides<T> >(other);
2839 template<class T, class FCT>
2840 typename Traits<T>::ArrayType *DivSub(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
2843 throw INTERP_KERNEL::Exception("DivSub : input DataArrayDouble instance is NULL !");
2844 mcIdType nbOfTuple1(a1->getNumberOfTuples());
2845 mcIdType nbOfTuple2(a2->getNumberOfTuples());
2846 std::size_t nbOfComp1(a1->getNumberOfComponents());
2847 std::size_t nbOfComp2(a2->getNumberOfComponents());
2848 if(nbOfTuple2==nbOfTuple1)
2850 if(nbOfComp1==nbOfComp2)
2852 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
2853 ret->alloc(nbOfTuple2,nbOfComp1);
2854 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),FCT());
2855 ret->copyStringInfoFrom(*a1);
2858 else if(nbOfComp2==1)
2860 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
2861 ret->alloc(nbOfTuple1,nbOfComp1);
2862 const T *a2Ptr(a2->begin()),*a1Ptr(a1->begin());
2863 T *res(ret->getPointer());
2864 for(mcIdType i=0;i<nbOfTuple1;i++)
2865 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind(FCT(),std::placeholders::_1,a2Ptr[i]));
2866 ret->copyStringInfoFrom(*a1);
2871 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
2875 else if(nbOfTuple2==1)
2877 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
2878 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
2879 ret->alloc(nbOfTuple1,nbOfComp1);
2880 const T *a1ptr=a1->begin(),*a2ptr(a2->begin());
2881 T *pt(ret->getPointer());
2882 for(mcIdType i=0;i<nbOfTuple1;i++)
2883 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,FCT());
2884 ret->copyStringInfoFrom(*a1);
2889 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
2895 * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
2897 * 1. The arrays have same number of tuples and components. Then each value of
2898 * the result array (_a_) is a subtraction of the corresponding values of \a a1 and
2899 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
2900 * 2. The arrays have same number of tuples and one array, say _a2_, has one
2902 * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
2903 * 3. The arrays have same number of components and one array, say _a2_, has one
2905 * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
2907 * Info on components is copied either from the first array (in the first case) or from
2908 * the array with maximal number of elements (getNbOfElems()).
2909 * \param [in] a1 - an array to subtract from.
2910 * \param [in] a2 - an array to subtract.
2911 * \return DataArrayDouble * - the new instance of DataArrayDouble.
2912 * The caller is to delete this result array using decrRef() as it is no more
2914 * \throw If either \a a1 or \a a2 is NULL.
2915 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
2916 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
2917 * none of them has number of tuples or components equal to 1.
2920 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Substract(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
2922 return DivSub< T,std::minus<T> >(a1,a2);
2926 * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
2928 * 1. The arrays have same number of tuples and components. Then each value of
2929 * the result array (_a_) is a division of the corresponding values of \a a1 and
2930 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
2931 * 2. The arrays have same number of tuples and one array, say _a2_, has one
2933 * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
2934 * 3. The arrays have same number of components and one array, say _a2_, has one
2936 * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
2938 * Info on components is copied either from the first array (in the first case) or from
2939 * the array with maximal number of elements (getNbOfElems()).
2940 * \warning No check of division by zero is performed!
2941 * \param [in] a1 - a numerator array.
2942 * \param [in] a2 - a denominator array.
2943 * \return DataArrayDouble * - the new instance of DataArrayDouble.
2944 * The caller is to delete this result array using decrRef() as it is no more
2946 * \throw If either \a a1 or \a a2 is NULL.
2947 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
2948 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
2949 * none of them has number of tuples or components equal to 1.
2952 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Divide(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
2954 return DivSub< T,std::divides<T> >(a1,a2);
2957 template<class T, class FCT>
2958 typename Traits<T>::ArrayType *MulAdd(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
2961 throw INTERP_KERNEL::Exception("DataArrayDouble::MulAdd : input DataArrayDouble instance is NULL !");
2962 mcIdType nbOfTuple(a1->getNumberOfTuples());
2963 mcIdType nbOfTuple2(a2->getNumberOfTuples());
2964 std::size_t nbOfComp(a1->getNumberOfComponents());
2965 std::size_t nbOfComp2(a2->getNumberOfComponents());
2966 MCAuto<typename Traits<T>::ArrayType> ret=0;
2967 if(nbOfTuple==nbOfTuple2)
2969 if(nbOfComp==nbOfComp2)
2971 ret=Traits<T>::ArrayType::New();
2972 ret->alloc(nbOfTuple,nbOfComp);
2973 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),FCT());
2974 ret->copyStringInfoFrom(*a1);
2978 std::size_t nbOfCompMin,nbOfCompMax;
2979 const typename Traits<T>::ArrayType *aMin, *aMax;
2980 if(nbOfComp>nbOfComp2)
2982 nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
2987 nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
2992 ret=Traits<T>::ArrayType::New();
2993 ret->alloc(nbOfTuple,nbOfCompMax);
2994 const T *aMinPtr(aMin->begin());
2995 const T *aMaxPtr(aMax->begin());
2996 T *res=ret->getPointer();
2997 for(mcIdType i=0;i<nbOfTuple;i++)
2998 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind(FCT(),std::placeholders::_1,aMinPtr[i]));
2999 ret->copyStringInfoFrom(*aMax);
3002 throw INTERP_KERNEL::Exception("Nb of components mismatch for array MulAdd !");
3005 else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
3007 if(nbOfComp==nbOfComp2)
3009 mcIdType nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
3010 const typename Traits<T>::ArrayType *aMin(nbOfTuple>nbOfTuple2?a2:a1);
3011 const typename Traits<T>::ArrayType *aMax(nbOfTuple>nbOfTuple2?a1:a2);
3012 const T *aMinPtr(aMin->begin()),*aMaxPtr(aMax->begin());
3013 ret=Traits<T>::ArrayType::New();
3014 ret->alloc(nbOfTupleMax,nbOfComp);
3015 T *res(ret->getPointer());
3016 for(mcIdType i=0;i<nbOfTupleMax;i++)
3017 res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,FCT());
3018 ret->copyStringInfoFrom(*aMax);
3021 throw INTERP_KERNEL::Exception("Nb of components mismatch for array MulAdd !");
3024 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array MulAdd !");
3029 * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
3031 * 1. The arrays have same number of tuples and components. Then each value of
3032 * the result array (_a_) is a product of the corresponding values of \a a1 and
3033 * \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
3034 * 2. The arrays have same number of tuples and one array, say _a2_, has one
3036 * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
3037 * 3. The arrays have same number of components and one array, say _a2_, has one
3039 * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
3041 * Info on components is copied either from the first array (in the first case) or from
3042 * the array with maximal number of elements (getNbOfElems()).
3043 * \param [in] a1 - a factor array.
3044 * \param [in] a2 - another factor array.
3045 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3046 * The caller is to delete this result array using decrRef() as it is no more
3048 * \throw If either \a a1 or \a a2 is NULL.
3049 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3050 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3051 * none of them has number of tuples or components equal to 1.
3054 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Multiply(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
3056 return MulAdd< T , std::multiplies<T> >(a1,a2);
3060 * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
3062 * 1. The arrays have same number of tuples and components. Then each value of
3063 * the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
3064 * i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
3065 * 2. The arrays have same number of tuples and one array, say _a2_, has one
3067 * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
3068 * 3. The arrays have same number of components and one array, say _a2_, has one
3070 * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
3072 * Info on components is copied either from the first array (in the first case) or from
3073 * the array with maximal number of elements (getNbOfElems()).
3074 * \param [in] a1 - an array to sum up.
3075 * \param [in] a2 - another array to sum up.
3076 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3077 * The caller is to delete this result array using decrRef() as it is no more
3079 * \throw If either \a a1 or \a a2 is NULL.
3080 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3081 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3082 * none of them has number of tuples or components equal to 1.
3085 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Add(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
3087 return MulAdd< T , std::plus<T> >(a1,a2);
3091 * Returns either a \a deep or \a shallow copy of this array. For more info see
3092 * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
3093 * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
3094 * \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
3095 * == \a true) or \a this instance (if \a dCpy == \a false).
3098 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::PerformCopyOrIncrRef(bool dCpy, const typename Traits<T>::ArrayType& self)
3101 return self.deepCopy();
3105 return const_cast<typename Traits<T>::ArrayType *>(&self);
3112 GreatEqual(T v):_v(v) { }
3113 bool operator()(T v) const { return v>=_v; }
3120 GreaterThan(T v):_v(v) { }
3121 bool operator()(T v) const { return v>_v; }
3128 LowerEqual(T v):_v(v) { }
3129 bool operator()(T v) const { return v<=_v; }
3136 LowerThan(T v):_v(v) { }
3137 bool operator()(T v) const { return v<_v; }
3144 InRange(T a, T b):_a(a),_b(b) { }
3145 bool operator()(T v) const { return v>=_a && v<_b; }
3152 NotInRange(T a, T b):_a(a),_b(b) { }
3153 bool operator()(T v) const { return v<_a || v>=_b; }
3158 * This method works only on data array with one component. This method returns a newly allocated array storing stored ascendantly of tuple ids in \a this so that this[id]<0.
3160 * \return a newly allocated data array that the caller should deal with.
3161 * \sa DataArrayInt::findIdsInRange
3164 DataArrayIdType *DataArrayTemplateClassic<T>::findIdsStrictlyNegative() const
3166 LowerThan<T> lt((T)0);
3167 MCAuto<DataArrayIdType> ret(findIdsAdv(lt));
3172 MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsGreaterOrEqualTo(T val) const
3174 GreatEqual<T> ge(val);
3175 return findIdsAdv(ge);
3179 MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsGreaterThan(T val) const
3181 GreaterThan<T> gt(val);
3182 return findIdsAdv(gt);
3186 MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsLowerOrEqualTo(T val) const
3188 LowerEqual<T> le(val);
3189 return findIdsAdv(le);
3193 MCAuto<DataArrayIdType> DataArrayTemplateClassic<T>::findIdsLowerThan(T val) const
3195 LowerThan<T> lt(val);
3196 return findIdsAdv(lt);
3200 * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
3201 * of components in the result array is a sum of the number of components of given arrays
3202 * and (2) the number of tuples in the result array is same as that of each of given
3203 * arrays. In other words the i-th tuple of result array includes all components of
3204 * i-th tuples of all given arrays.
3205 * Number of tuples in the given arrays must be the same.
3206 * \param [in] a1 - an array to include in the result array.
3207 * \param [in] a2 - another array to include in the result array.
3208 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3209 * The caller is to delete this result array using decrRef() as it is no more
3211 * \throw If both \a a1 and \a a2 are NULL.
3212 * \throw If any given array is not allocated.
3213 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3216 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Meld(const typename Traits<T>::ArrayType *a1, const typename Traits<T>::ArrayType *a2)
3218 std::vector<const typename Traits<T>::ArrayType *> arr(2);
3219 arr[0]=a1; arr[1]=a2;
3224 * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
3225 * of components in the result array is a sum of the number of components of given arrays
3226 * and (2) the number of tuples in the result array is same as that of each of given
3227 * arrays. In other words the i-th tuple of result array includes all components of
3228 * i-th tuples of all given arrays.
3229 * Number of tuples in the given arrays must be the same.
3230 * \param [in] arr - a sequence of arrays to include in the result array.
3231 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3232 * The caller is to delete this result array using decrRef() as it is no more
3234 * \throw If all arrays within \a arr are NULL.
3235 * \throw If any given array is not allocated.
3236 * \throw If getNumberOfTuples() of arrays within \a arr is different.
3239 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::Meld(const std::vector<const typename Traits<T>::ArrayType *>& arr)
3241 std::vector<const typename Traits<T>::ArrayType *> a;
3242 for(typename std::vector<const typename Traits<T>::ArrayType *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3246 throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
3247 typename std::vector<const typename Traits<T>::ArrayType *>::const_iterator it;
3248 for(it=a.begin();it!=a.end();it++)
3249 (*it)->checkAllocated();
3251 mcIdType nbOfTuples((*it)->getNumberOfTuples());
3252 std::vector<std::size_t> nbc(a.size());
3253 std::vector<const T *> pts(a.size());
3254 nbc[0]=(*it)->getNumberOfComponents();
3255 pts[0]=(*it++)->getConstPointer();
3256 for(mcIdType i=1;it!=a.end();it++,i++)
3258 if(nbOfTuples!=(*it)->getNumberOfTuples())
3259 throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
3260 nbc[i]=(*it)->getNumberOfComponents();
3261 pts[i]=(*it)->getConstPointer();
3263 std::size_t totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),(std::size_t)0);
3264 typename Traits<T>::ArrayType *ret(Traits<T>::ArrayType::New());
3265 ret->alloc(nbOfTuples,totalNbOfComp);
3266 T *retPtr(ret->getPointer());
3267 for(mcIdType i=0;i<nbOfTuples;i++)
3268 for(std::size_t j=0;j<a.size();j++)
3270 retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
3274 for(std::size_t i=0;i<a.size();i++)
3275 for(std::size_t j=0;j<nbc[i];j++,k++)
3276 ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
3281 * Returns a new DataArrayDouble holding the same values as \a this array but differently
3282 * arranged in memory. If \a this array holds 2 components of 3 values:
3283 * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
3284 * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
3285 * \warning Do not confuse this method with transpose()!
3286 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
3287 * is to delete using decrRef() as it is no more needed.
3288 * \throw If \a this is not allocated.
3291 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::fromNoInterlace() const
3293 if(this->_mem.isNull())
3294 throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
3295 T *tab(this->_mem.fromNoInterlace(this->getNumberOfComponents()));
3296 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
3297 ret->useArray(tab,true,DeallocType::C_DEALLOC,this->getNumberOfTuples(),this->getNumberOfComponents());
3302 * Returns a new DataArrayDouble holding the same values as \a this array but differently
3303 * arranged in memory. If \a this array holds 2 components of 3 values:
3304 * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
3305 * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
3306 * \warning Do not confuse this method with transpose()!
3307 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
3308 * is to delete using decrRef() as it is no more needed.
3309 * \throw If \a this is not allocated.
3312 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::toNoInterlace() const
3314 if(this->_mem.isNull())
3315 throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
3316 T *tab(this->_mem.toNoInterlace(this->getNumberOfComponents()));
3317 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
3318 ret->useArray(tab,true,DeallocType::C_DEALLOC,this->getNumberOfTuples(),this->getNumberOfComponents());
3323 * Appends components of another array to components of \a this one, tuple by tuple.
3324 * So that the number of tuples of \a this array remains the same and the number of
3325 * components increases.
3326 * \param [in] other - the DataArrayDouble to append to \a this one.
3327 * \throw If \a this is not allocated.
3328 * \throw If \a this and \a other arrays have different number of tuples.
3330 * \if ENABLE_EXAMPLES
3331 * \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
3333 * \ref py_mcdataarraydouble_meldwith "Here is a Python example".
3337 void DataArrayTemplateClassic<T>::meldWith(const typename Traits<T>::ArrayType *other)
3339 this->checkAllocated();
3340 other->checkAllocated();
3341 mcIdType nbOfTuples(this->getNumberOfTuples());
3342 if(nbOfTuples!=other->getNumberOfTuples())
3343 throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
3344 std::size_t nbOfComp1=this->getNumberOfComponents();
3345 std::size_t nbOfComp2=other->getNumberOfComponents();
3346 T *newArr=(T *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(T));
3348 const T *inp1(this->begin()),*inp2(other->begin());
3349 for(mcIdType i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
3351 w=std::copy(inp1,inp1+nbOfComp1,w);
3352 w=std::copy(inp2,inp2+nbOfComp2,w);
3354 this->useArray(newArr,true,DeallocType::C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
3355 std::vector<std::size_t> compIds(nbOfComp2);
3356 for(std::size_t i=0;i<nbOfComp2;i++)
3357 compIds[i]=nbOfComp1+i;
3358 this->copyPartOfStringInfoFrom2(compIds,*other);
3363 * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
3364 * \a nbTimes should be at least equal to 1.
3365 * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
3366 * \throw if \a this is not allocated or if \a this has not number of components set to one or if \a nbTimes is lower than 1.
3369 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::duplicateEachTupleNTimes(mcIdType nbTimes) const
3371 this->checkAllocated();
3372 if(this->getNumberOfComponents()!=1)
3373 throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
3375 throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
3376 mcIdType nbTuples=this->getNumberOfTuples();
3377 const T *inPtr(this->begin());
3378 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New()); ret->alloc(nbTimes*nbTuples,1);
3379 T *retPtr(ret->getPointer());
3380 for(mcIdType i=0;i<nbTuples;i++,inPtr++)
3383 for(mcIdType j=0;j<nbTimes;j++,retPtr++)
3386 ret->copyStringInfoFrom(*this);
3391 void DataArrayTemplateClassic<T>::aggregate(const typename Traits<T>::ArrayType *other)
3394 throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !");
3395 if(this->getNumberOfComponents()!=other->getNumberOfComponents())
3396 throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !");
3397 this->_mem.insertAtTheEnd(other->begin(),other->end());
3401 * Converts every value of \a this array to its absolute value.
3402 * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
3403 * should be called instead.
3405 * \throw If \a this is not allocated.
3406 * \sa DataArrayDouble::computeAbs
3409 void DataArrayTemplateClassic<T>::abs()
3411 this->checkAllocated();
3412 T *ptr(this->getPointer());
3413 std::size_t nbOfElems(this->getNbOfElems());
3414 std::transform(ptr,ptr+nbOfElems,ptr,[](T c){return std::abs(c);});
3415 this->declareAsNew();
3419 * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
3420 * This method is a const method (that do not change any values in \a this) contrary to DataArrayDouble::abs method.
3422 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3423 * same number of tuples and component as \a this array.
3424 * The caller is to delete this result array using decrRef() as it is no more
3426 * \throw If \a this is not allocated.
3427 * \sa DataArrayDouble::abs
3430 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::computeAbs() const
3432 this->checkAllocated();
3433 MCAuto<typename Traits<T>::ArrayType> newArr(Traits<T>::ArrayType::New());
3434 mcIdType nbOfTuples(this->getNumberOfTuples());
3435 std::size_t nbOfComp(this->getNumberOfComponents());
3436 newArr->alloc(nbOfTuples,nbOfComp);
3437 std::transform(this->begin(),this->end(),newArr->getPointer(),[](T c){return std::abs(c);});
3438 newArr->copyStringInfoFrom(*this);
3439 return newArr.retn();
3443 * Returns either a \a deep or \a shallow copy of this array. For more info see
3444 * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
3445 * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
3446 * \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
3447 * == \a true) or \a this instance (if \a dCpy == \a false).
3450 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::performCopyOrIncrRef(bool dCpy) const
3452 const typename Traits<T>::ArrayType *thisC(static_cast<const typename Traits<T>::ArrayType *>(this));
3453 return DataArrayTemplateClassic<T>::PerformCopyOrIncrRef(dCpy,*thisC);
3457 * Computes for each tuple the sum of number of components values in the tuple and return it.
3459 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3460 * same number of tuples as \a this array and one component.
3461 * The caller is to delete this result array using decrRef() as it is no more
3463 * \throw If \a this is not allocated.
3466 typename Traits<T>::ArrayType *DataArrayTemplateClassic<T>::sumPerTuple() const
3468 this->checkAllocated();
3469 std::size_t nbOfComp(this->getNumberOfComponents());
3470 mcIdType nbOfTuple(this->getNumberOfTuples());
3471 MCAuto<typename Traits<T>::ArrayType> ret(Traits<T>::ArrayType::New());
3472 ret->alloc(nbOfTuple,1);
3473 const T *src(this->begin());
3474 T *dest(ret->getPointer());
3475 for(mcIdType i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3476 *dest=std::accumulate(src,src+nbOfComp,(T)0);
3481 * Set all values in \a this array so that the i-th element equals to \a init + i
3482 * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
3483 * \param [in] init - value to assign to the first element of array.
3484 * \throw If \a this->getNumberOfComponents() != 1
3485 * \throw If \a this is not allocated.
3488 void DataArrayTemplateClassic<T>::iota(T init)
3490 this->checkAllocated();
3491 if(this->getNumberOfComponents()!=1)
3492 throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
3493 T *ptr(this->getPointer());
3494 mcIdType ntuples(this->getNumberOfTuples());
3495 for(mcIdType i=0;i<ntuples;i++)
3497 this->declareAsNew();
3501 struct ImplReprTraits { static void SetPrecision(std::ostream& oss) { } };
3504 struct ImplReprTraits<double> { static void SetPrecision(std::ostream& oss) { oss.precision(17); } };
3507 struct ImplReprTraits<float> { static void SetPrecision(std::ostream& oss) { oss.precision(7); } };
3510 void DataArrayTemplateClassic<T>::reprStream(std::ostream& stream) const
3512 stream << "Name of " << Traits<T>::ReprStr << " array : \"" << this->_name << "\"\n";
3513 reprWithoutNameStream(stream);
3517 void DataArrayTemplateClassic<T>::reprZipStream(std::ostream& stream) const
3519 stream << "Name of " << Traits<T>::ReprStr << " array : \"" << this->_name << "\"\n";
3520 reprZipWithoutNameStream(stream);
3524 void DataArrayTemplateClassic<T>::reprNotTooLongStream(std::ostream& stream) const
3526 stream << "Name of "<< Traits<T>::ReprStr << " array : \"" << this->_name << "\"\n";
3527 reprNotTooLongWithoutNameStream(stream);
3531 void DataArrayTemplateClassic<T>::reprWithoutNameStream(std::ostream& stream) const
3533 DataArray::reprWithoutNameStream(stream);
3534 ImplReprTraits<T>::SetPrecision(stream);
3535 this->_mem.repr(ToIdType(this->getNumberOfComponents()),stream);
3539 void DataArrayTemplateClassic<T>::reprZipWithoutNameStream(std::ostream& stream) const
3541 DataArray::reprWithoutNameStream(stream);
3542 ImplReprTraits<T>::SetPrecision(stream);
3543 this->_mem.reprZip(ToIdType(this->getNumberOfComponents()),stream);
3547 void DataArrayTemplateClassic<T>::reprNotTooLongWithoutNameStream(std::ostream& stream) const
3549 DataArray::reprWithoutNameStream(stream);
3550 ImplReprTraits<T>::SetPrecision(stream);
3551 this->_mem.reprNotTooLong(ToIdType(this->getNumberOfComponents()),stream);
3555 * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
3556 * printed out to avoid to consume too much space in interpretor.
3560 std::string DataArrayTemplateClassic<T>::reprNotTooLong() const
3562 std::ostringstream ret;
3563 reprNotTooLongStream(ret);
3568 * Returns a textual and human readable representation of \a this instance of
3569 * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
3570 * \return std::string - text describing \a this DataArrayInt.
3572 * \sa reprNotTooLong, reprZip
3575 std::string DataArrayTemplateClassic<T>::repr() const
3577 std::ostringstream ret;
3578 DataArrayTemplateClassic<T>::reprStream(ret);
3583 std::string DataArrayTemplateClassic<T>::reprZip() const
3585 std::ostringstream ret;
3586 DataArrayTemplateClassic<T>::reprZipStream(ret);
3590 /////////////////////////////////
3593 * Checks if all values in \a this array are equal to \a val at precision \a eps.
3594 * \param [in] val - value to check equality of array values to.
3595 * \param [in] eps - precision to check the equality.
3596 * \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
3598 * \throw If \a this->getNumberOfComponents() != 1
3599 * \throw If \a this is not allocated.
3602 bool DataArrayTemplateFP<T>::isUniform(T val, T eps) const
3604 this->checkAllocated();
3605 if(this->getNumberOfComponents()!=1)
3606 throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3607 const T *w(this->begin()),*end2(this->end());
3608 const T vmin(val-eps),vmax(val+eps);
3610 if(*w<vmin || *w>vmax)
3615 /////////////////////////////////
3618 * Returns the only one value in \a this, if and only if number of elements
3619 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3620 * \return double - the sole value stored in \a this array.
3621 * \throw If at least one of conditions stated above is not fulfilled.
3624 T DataArrayDiscrete<T>::intValue() const
3626 if(this->isAllocated())
3628 if(this->getNbOfElems()==1)
3630 return *this->getConstPointer();
3633 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3636 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3640 * Equivalent to DataArrayInt::isEqual except that if false the reason of
3641 * mismatch is given.
3643 * \param [in] other the instance to be compared with \a this
3644 * \param [out] reason In case of inequality returns the reason.
3645 * \sa DataArrayInt::isEqual
3648 bool DataArrayDiscrete<T>::isEqualIfNotWhy(const DataArrayDiscrete<T>& other, std::string& reason) const
3650 if(!this->areInfoEqualsIfNotWhy(other,reason))
3652 return this->_mem.isEqual(other._mem,0,reason);
3656 * Checks if \a this and another DataArrayInt are fully equal. For more info see
3657 * \ref MEDCouplingArrayBasicsCompare.
3658 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
3659 * \return bool - \a true if the two arrays are equal, \a false else.
3662 bool DataArrayDiscrete<T>::isEqual(const DataArrayDiscrete<T>& other) const
3665 return isEqualIfNotWhy(other,tmp);
3669 * Returns a new instance of DataArrayInt. The caller is to delete this array
3670 * using decrRef() as it is no more needed.
3673 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::New()
3675 return new typename Traits<T>::ArrayType;
3679 * Checks if values of \a this and another DataArrayInt are equal. For more info see
3680 * \ref MEDCouplingArrayBasicsCompare.
3681 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
3682 * \return bool - \a true if the values of two arrays are equal, \a false else.
3685 bool DataArrayDiscrete<T>::isEqualWithoutConsideringStr(const DataArrayDiscrete<T>& other) const
3688 return this->_mem.isEqual(other._mem,0,tmp);
3692 * Checks if values of \a this and another DataArrayInt are equal. Comparison is
3693 * performed on sorted value sequences.
3694 * For more info see\ref MEDCouplingArrayBasicsCompare.
3695 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
3696 * \return bool - \a true if the sorted values of two arrays are equal, \a false else.
3699 bool DataArrayDiscrete<T>::isEqualWithoutConsideringStrAndOrder(const typename Traits<T>::ArrayType& other) const
3701 MCAuto<typename Traits<T>::ArrayType> a((static_cast<const typename Traits<T>::ArrayType *>(this))->deepCopy());
3702 MCAuto<typename Traits<T>::ArrayType> b((static_cast<const typename Traits<T>::ArrayType *>(&other))->deepCopy());
3705 return a->isEqualWithoutConsideringStr(*b);
3710 void DataArrayDiscrete<T>::switchOnTupleAlg(T val, std::vector<bool>& vec, ALG algo) const
3712 this->checkAllocated();
3713 if(this->getNumberOfComponents()!=1)
3714 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
3715 mcIdType nbOfTuples(this->getNumberOfTuples());
3716 if(nbOfTuples!=ToIdType(vec.size()))
3717 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
3718 const T *pt(this->begin());
3719 for(mcIdType i=0;i<nbOfTuples;i++)
3725 * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple equal to \a val
3726 * put True to the corresponding entry in \a vec.
3727 * \a vec is expected to be with the same size than the number of tuples of \a this.
3729 * \sa DataArrayInt::switchOnTupleNotEqualTo.
3732 void DataArrayDiscrete<T>::switchOnTupleEqualTo(T val, std::vector<bool>& vec) const
3734 switchOnTupleAlg(val,vec,std::equal_to<T>());
3738 * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple different from \a val
3739 * put True to the corresponding entry in \a vec.
3740 * \a vec is expected to be with the same size than the number of tuples of \a this.
3742 * \sa DataArrayInt::switchOnTupleEqualTo.
3745 void DataArrayDiscrete<T>::switchOnTupleNotEqualTo(T val, std::vector<bool>& vec) const
3747 switchOnTupleAlg(val,vec,std::not_equal_to<T>());
3751 * Compute for each element in \a this the occurence rank of that element. This method is typically useful of one-component array having a same element
3752 * appearing several times. If each element in \a this appears once an 1 component array containing only 0 will be returned.
3755 * - \a this : [5, 3, 2, 1, 4, 5, 2, 1, 0, 11, 5, 4]
3756 * - \a return is : [0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 2, 1] because at pos #0 of \a this (ie value 5) is the first occurrence ->0. At pos #10 of \a this (ie value 5 also) is the third occurrence of 5 -> 2.
3758 * \return DataArrayInt * - a new instance of DataArrayInt with same number of tuples than \a this. The caller is to delete this
3759 * array using decrRef() as it is no more needed.
3760 * \throw If either this not allocated or not with one component.
3762 * \sa DataArrayInt::FindPermutationFromFirstToSecond
3765 DataArrayIdType *DataArrayDiscrete<T>::occurenceRankInThis() const
3767 constexpr char MSG0[] = "occurenceRankInThis :";
3768 this->checkAllocated();
3769 this->checkNbOfComps(1,MSG0);
3770 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
3771 ret->alloc(this->getNumberOfTuples(),1);
3772 mcIdType *retPtr(ret->getPointer());
3773 std::map<T,mcIdType> m;
3774 for(const T *pt = this->begin() ; pt != this->end() ; ++pt, ++retPtr )
3776 auto it = m.find(*pt);
3784 *retPtr = (*it).second++;
3791 * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
3792 * one-dimensional arrays that must be of the same length. The result array describes
3793 * correspondence between \a this and \a other arrays, so that
3794 * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
3795 * not possible because some element in \a other is not in \a this, an exception is thrown.
3796 * \param [in] other - an array to compute permutation to.
3797 * \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
3798 * from \a this to \a other. The caller is to delete this array using decrRef() as it is
3800 * \throw If \a this->getNumberOfComponents() != 1.
3801 * \throw If \a other->getNumberOfComponents() != 1.
3802 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
3803 * \throw If \a other includes a value which is not in \a this array.
3805 * \if ENABLE_EXAMPLES
3806 * \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
3808 * \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
3812 DataArrayIdType *DataArrayDiscrete<T>::buildPermutationArr(const DataArrayDiscrete<T>& other) const
3814 this->checkAllocated();
3815 if(this->getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
3816 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
3817 mcIdType nbTuple(this->getNumberOfTuples());
3818 other.checkAllocated();
3819 if(nbTuple!=other.getNumberOfTuples())
3820 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
3821 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
3822 ret->alloc(nbTuple,1);
3823 ret->fillWithValue(-1);
3824 const T *pt(this->begin());
3825 std::map<mcIdType,mcIdType> mm;
3826 for(mcIdType i=0;i<nbTuple;i++)
3827 mm[ToIdType(pt[i])]=i;
3829 mcIdType *retToFill(ret->getPointer());
3830 for(mcIdType i=0;i<nbTuple;i++)
3832 std::map<mcIdType,mcIdType>::const_iterator it=mm.find(ToIdType(pt[i]));
3835 std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
3836 throw INTERP_KERNEL::Exception(oss.str().c_str());
3838 retToFill[i]=(*it).second;
3844 * Elements of \a partOfThis are expected to be included in \a this.
3845 * The returned array \a ret is so that this[ret]==partOfThis
3847 * For example, if \a this array contents are [9,10,0,6,4,11,3,8] and if \a partOfThis contains [6,0,11,8]
3848 * the return array will contain [3,2,5,7].
3850 * \a this is expected to be a 1 compo allocated array.
3851 * \param [in] partOfThis - A 1 compo allocated array
3852 * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis.
3853 * \throw if two same element is present twice in \a this
3854 * \throw if an element in \a partOfThis is \b NOT in \a this.
3857 DataArrayIdType *DataArrayDiscrete<T>::indicesOfSubPart(const DataArrayDiscrete<T>& partOfThis) const
3859 if(this->getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1)
3860 throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !");
3861 this->checkAllocated(); partOfThis.checkAllocated();
3862 mcIdType thisNbTuples(this->getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples());
3863 const T *thisPt(this->begin()),*pt(partOfThis.begin());
3864 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
3865 ret->alloc(nbTuples,1);
3866 mcIdType *retPt(ret->getPointer());
3867 std::map<mcIdType,mcIdType> m;
3868 for(mcIdType i=0;i<thisNbTuples;i++,thisPt++)
3869 m[ToIdType(*thisPt)]=i;
3870 if(ToIdType(m.size())!=thisNbTuples)
3871 throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : some elements appears more than once !");
3872 for(mcIdType i=0;i<nbTuples;i++,retPt++,pt++)
3874 std::map<mcIdType,mcIdType>::const_iterator it(m.find(ToIdType(*pt)));
3876 *retPt=(*it).second;
3879 std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !";
3880 throw INTERP_KERNEL::Exception(oss.str());
3887 * Checks that \a this array is consistently **increasing** or **decreasing** in value.
3888 * If not an exception is thrown.
3889 * \param [in] increasing - if \a true, the array values should be increasing.
3890 * \throw If sequence of values is not strictly monotonic in agreement with \a
3892 * \throw If \a this->getNumberOfComponents() != 1.
3893 * \throw If \a this is not allocated.
3896 void DataArrayDiscrete<T>::checkMonotonic(bool increasing) const
3898 if(!isMonotonic(increasing))
3901 throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
3903 throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
3908 * Checks that \a this array is consistently **increasing** or **decreasing** in value.
3909 * \param [in] increasing - if \a true, array values should be increasing.
3910 * \return bool - \a true if values change in accordance with \a increasing arg.
3911 * \throw If \a this->getNumberOfComponents() != 1.
3912 * \throw If \a this is not allocated.
3915 bool DataArrayDiscrete<T>::isMonotonic(bool increasing) const
3917 this->checkAllocated();
3918 if(this->getNumberOfComponents()!=1)
3919 throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
3920 std::size_t nbOfElements(this->getNumberOfTuples());
3921 const T *ptr(this->begin());
3927 for(std::size_t i=1;i<nbOfElements;i++)
3937 for(std::size_t i=1;i<nbOfElements;i++)
3949 * This method check that array consistently INCREASING or DECREASING in value.
3952 bool DataArrayDiscrete<T>::isStrictlyMonotonic(bool increasing) const
3954 this->checkAllocated();
3955 if(this->getNumberOfComponents()!=1)
3956 throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
3957 std::size_t nbOfElements(this->getNumberOfTuples());
3958 const T *ptr(this->begin());
3964 for(std::size_t i=1;i<nbOfElements;i++)
3974 for(std::size_t i=1;i<nbOfElements;i++)
3986 * This method check that array consistently INCREASING or DECREASING in value.
3989 void DataArrayDiscrete<T>::checkStrictlyMonotonic(bool increasing) const
3991 if(!isStrictlyMonotonic(increasing))
3994 throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
3996 throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
4001 * Returns an integer value characterizing \a this array, which is useful for a quick
4002 * comparison of many instances of DataArrayInt.
4003 * \return mcIdType - the hash value.
4004 * \throw If \a this is not allocated.
4007 mcIdType DataArrayDiscrete<T>::getHashCode() const
4009 this->checkAllocated();
4010 mcIdType nbOfElems=ToIdType(this->getNbOfElems());
4011 mcIdType ret=nbOfElems*65536;
4016 const T *pt(this->begin());
4017 for(mcIdType i=0;i<nbOfElems;i+=delta)
4018 ret0+=pt[i] & 0x1FFF;
4019 return ToIdType(ret+ret0);
4023 void DataArrayDiscrete<T>::reprCppStream(const std::string& varName, std::ostream& stream) const
4025 mcIdType nbTuples(this->getNumberOfTuples());
4026 std::size_t nbComp(this->getNumberOfComponents());
4027 const T *data(this->getConstPointer());
4028 stream << Traits<T>::ArrayTypeName << " *" << varName << "=" << Traits<T>::ArrayTypeName << "::New();" << std::endl;
4029 if(nbTuples*nbComp>=1)
4031 stream << "const mcIdType " << varName << "Data[" << nbTuples*nbComp << "]={";
4032 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<T>(stream,","));
4033 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
4034 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
4037 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
4038 stream << varName << "->setName(\"" << this->getName() << "\");" << std::endl;
4042 * Method that gives a quick overvien of \a this for python.
4045 void DataArrayDiscrete<T>::reprQuickOverview(std::ostream& stream) const
4047 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
4048 stream << Traits<T>::ArrayTypeName << " C++ instance at " << this << ". ";
4049 if(this->isAllocated())
4051 std::size_t nbOfCompo(this->getNumberOfComponents());
4054 mcIdType nbOfTuples(this->getNumberOfTuples());
4055 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
4056 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
4059 stream << "Number of components : 0.";
4062 stream << "*** No data allocated ****";
4066 void DataArrayDiscrete<T>::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
4068 const T *data(this->begin());
4069 mcIdType nbOfTuples(this->getNumberOfTuples());
4070 std::size_t nbOfCompo(this->getNumberOfComponents());
4071 std::ostringstream oss2; oss2 << "[";
4072 std::string oss2Str(oss2.str());
4073 bool isFinished=true;
4074 for(mcIdType i=0;i<nbOfTuples && isFinished;i++)
4079 for(std::size_t j=0;j<nbOfCompo;j++,data++)
4082 if(j!=nbOfCompo-1) oss2 << ", ";
4088 if(i!=nbOfTuples-1) oss2 << ", ";
4089 std::string oss3Str(oss2.str());
4090 if(oss3Str.length()<maxNbOfByteInRepr)
4102 void DataArrayDiscrete<T>::writeVTK(std::ostream& ofs, mcIdType indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
4104 static const char SPACE[4]={' ',' ',' ',' '};
4105 this->checkAllocated();
4106 std::string idt(indent,' ');
4107 ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << this->getNumberOfComponents() << "\"";
4110 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
4111 if(std::string(type)==Traits<T>::VTKReprStr)
4113 const char *data(reinterpret_cast<const char *>(this->begin()));
4114 std::size_t sz(this->getNbOfElems()*sizeof(T));
4115 byteArr->insertAtTheEnd(data,data+sz);
4116 byteArr->insertAtTheEnd(SPACE,SPACE+4);
4118 else if(std::string(type)=="Int8")
4120 INTERP_KERNEL::AutoPtr<char> tmp(new char[this->getNbOfElems()]);
4121 copyCast(this->begin(),this->end(),(char *)tmp);
4122 byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+this->getNbOfElems());
4123 byteArr->insertAtTheEnd(SPACE,SPACE+4);
4125 else if(std::string(type)=="UInt8")
4127 INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[this->getNbOfElems()]);
4128 copyCast(this->begin(),this->end(),(unsigned char *)tmp);
4129 byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+this->getNbOfElems());
4130 byteArr->insertAtTheEnd(SPACE,SPACE+4);
4134 std::ostringstream oss;
4135 oss << Traits<T>::ArrayTypeName << "::writeVTK : Only " << Traits<T>::VTKReprStr << ", Int8 and UInt8 supported !";
4136 throw INTERP_KERNEL::Exception(oss.str());
4141 ofs << " RangeMin=\"" << this->getMinValueInArray() << "\" RangeMax=\"" << this->getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
4142 std::copy(this->begin(),this->end(),std::ostream_iterator<T>(ofs," "));
4144 ofs << std::endl << idt << "</DataArray>\n";
4148 * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4149 * i.e. a current value is used as in index to get a new value from \a indArrBg.
4150 * \param [in] indArrBg - pointer to the first element of array of new values to assign
4152 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4153 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4154 * \throw If \a this->getNumberOfComponents() != 1
4155 * \throw If any value of \a this can't be used as a valid index for
4156 * [\a indArrBg, \a indArrEnd).
4158 * \sa changeValue, findIdForEach
4161 void DataArrayDiscrete<T>::transformWithIndArr(const T *indArrBg, const T *indArrEnd)
4163 this->checkAllocated();
4164 if(this->getNumberOfComponents()!=1)
4165 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4166 mcIdType nbElemsIn=ToIdType(std::distance(indArrBg,indArrEnd));
4167 mcIdType nbOfTuples(this->getNumberOfTuples());
4168 T *pt(this->getPointer());
4169 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
4171 if(*pt>=0 && *pt<nbElemsIn)
4175 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4176 throw INTERP_KERNEL::Exception(oss.str());
4179 this->declareAsNew();
4183 void DataArrayDiscrete<T>::transformWithIndArr(const MapKeyVal<T, T>& m)
4185 this->checkAllocated();
4186 if(this->getNumberOfComponents()!=1)
4187 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4188 const typename std::map<T,T>& dat(m.data());
4189 mcIdType nbOfTuples(this->getNumberOfTuples());
4190 T *pt(this->getPointer());
4191 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
4193 typename std::map<T,T>::const_iterator it(dat.find(*pt));
4198 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !";
4199 throw INTERP_KERNEL::Exception(oss.str());
4202 this->declareAsNew();
4206 template<int SPACEDIM>
4207 void DataArrayDiscrete<T>::findCommonTuplesAlg(const T *bbox, mcIdType nbNodes, mcIdType limitNodeId, DataArrayIdType *c, DataArrayIdType *cI) const
4209 const T *coordsPtr(this->begin());
4210 BBTreeDiscrete<SPACEDIM,T,mcIdType> myTree(bbox,nullptr,0,nbNodes);
4211 std::vector<bool> isDone(nbNodes);
4212 for(mcIdType i=0;i<nbNodes;i++)
4216 std::vector<mcIdType> intersectingElems;
4217 myTree.getIntersectingElems(coordsPtr+i*SPACEDIM,intersectingElems);
4218 if(intersectingElems.size()>1)
4220 std::vector<mcIdType> commonNodes;
4221 for(std::vector<mcIdType>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
4223 if(*it>=limitNodeId)
4225 commonNodes.push_back(*it);
4228 if(!commonNodes.empty())
4230 cI->pushBackSilent(cI->back()+ToIdType(commonNodes.size())+1);
4231 c->pushBackSilent(i);
4232 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
4240 void DataArrayDiscrete<T>::findCommonTuples(mcIdType limitTupleId, MCAuto<DataArrayIdType> &comm, MCAuto<DataArrayIdType>& commIndex) const
4242 this->checkAllocated();
4243 std::size_t nbOfCompo( this->getNumberOfComponents() );
4244 if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
4245 throw INTERP_KERNEL::Exception("DataArrayDiscrete::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
4247 mcIdType nbOfTuples( this->getNumberOfTuples() );
4249 comm = DataArrayIdType::New(); commIndex = DataArrayIdType::New(); comm->alloc(0,1); commIndex->pushBackSilent(0);
4253 findCommonTuplesAlg<4>(this->begin(),nbOfTuples,limitTupleId,comm,commIndex);
4256 findCommonTuplesAlg<3>(this->begin(),nbOfTuples,limitTupleId,comm,commIndex);
4259 findCommonTuplesAlg<2>(this->begin(),nbOfTuples,limitTupleId,comm,commIndex);
4262 findCommonTuplesAlg<1>(this->begin(),nbOfTuples,limitTupleId,comm,commIndex);
4265 throw INTERP_KERNEL::Exception("DataArrayDiscrete::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
4270 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
4271 * given one. The ids are sorted in the ascending order.
4272 * \param [in] val - the value to find within \a this.
4273 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4274 * array using decrRef() as it is no more needed.
4275 * \throw If \a this is not allocated.
4276 * \throw If \a this->getNumberOfComponents() != 1.
4277 * \sa DataArrayInt::findIdsEqualTuple
4280 DataArrayIdType *DataArrayDiscrete<T>::findIdsEqual(T val) const
4282 this->checkAllocated();
4283 if(this->getNumberOfComponents()!=1)
4284 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
4285 const T *cptr(this->getConstPointer());
4286 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(0,1);
4287 mcIdType nbOfTuples(this->getNumberOfTuples());
4288 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
4290 ret->pushBackSilent(ToIdType(i));
4295 * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from
4296 * values of \a this (\a a) and the given (\a indArr) arrays as follows:
4297 * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
4298 * new value in place \a indArr[ \a v ] is i.
4299 * \param [in] indArrBg - the array holding indices within the result array to assign
4300 * indices of values of \a this array pointing to values of \a indArrBg.
4301 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4302 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4303 * \return DataArrayInt * - the new instance of DataArrayInt.
4304 * The caller is to delete this result array using decrRef() as it is no more
4306 * \throw If \a this->getNumberOfComponents() != 1.
4307 * \throw If any value of \a this array is not a valid index for \a indArrBg array.
4308 * \throw If any value of \a indArrBg is not a valid index for \a this array.
4311 DataArrayIdType *DataArrayDiscrete<T>::transformWithIndArrR(const T *indArrBg, const T *indArrEnd) const
4313 this->checkAllocated();
4314 if(this->getNumberOfComponents()!=1)
4315 throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4316 mcIdType nbElemsIn=ToIdType(std::distance(indArrBg,indArrEnd));
4317 mcIdType nbOfTuples(this->getNumberOfTuples());
4318 const T *pt=this->getConstPointer();
4319 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
4320 ret->alloc(nbOfTuples,1);
4321 ret->fillWithValue(-1);
4322 mcIdType *tmp=ret->getPointer();
4323 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
4325 if(*pt>=0 && *pt<nbElemsIn)
4327 T pos=indArrBg[*pt];
4328 if(pos>=0 && pos<nbOfTuples)
4329 tmp[ToIdType(pos)]=i;
4332 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
4333 throw INTERP_KERNEL::Exception(oss.str().c_str());
4338 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
4339 throw INTERP_KERNEL::Exception(oss.str().c_str());
4346 * Computes distribution of values of \a this one-dimensional array between given value
4347 * ranges (casts). This method is typically useful for entity number splitting by types,
4349 * \warning The values contained in \a arrBg should be sorted ascendently. No
4350 * check of this is be done. If not, the result is not warranted.
4351 * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
4352 * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
4353 * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
4354 * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
4355 * should be more than every value in \a this array.
4356 * \param [in] arrEnd - specifies the end of the array \a arrBg, so that
4357 * the last value of \a arrBg is \a arrEnd[ -1 ].
4358 * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
4359 * (same number of tuples and components), the caller is to delete
4360 * using decrRef() as it is no more needed.
4361 * This array contains indices of ranges for every value of \a this array. I.e.
4362 * the i-th value of \a castArr gives the index of range the i-th value of \a this
4363 * belongs to. Or, in other words, this parameter contains for each tuple in \a
4364 * this in which cast it holds.
4365 * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
4366 * array, the caller is to delete using decrRef() as it is no more needed.
4367 * This array contains ranks of values of \a this array within ranges
4368 * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
4369 * the i-th value of \a this array within the \a castArr[ i ]-th range, to which
4370 * the i-th value of \a this belongs to. Or, in other words, this param contains
4371 * for each tuple its rank inside its cast. The rank is computed as difference
4372 * between the value and the lowest value of range.
4373 * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
4374 * ranges (casts) to which at least one value of \a this array belongs.
4375 * Or, in other words, this param contains the casts that \a this contains.
4376 * The caller is to delete this array using decrRef() as it is no more needed.
4378 * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
4379 * the output of this method will be :
4380 * - \a castArr : [1,1,0,0,0,1,1,0,1]
4381 * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
4382 * - \a castsPresent : [0,1]
4384 * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
4385 * range #1 and its rank within this range is 2; etc.
4387 * \throw If \a this->getNumberOfComponents() != 1.
4388 * \throw If \a arrEnd - arrBg < 2.
4389 * \throw If any value of \a this is not less than \a arrEnd[-1].
4392 void DataArrayDiscrete<T>::splitByValueRange(const T *arrBg, const T *arrEnd,
4393 DataArrayType *& castArr, DataArrayType *& rankInsideCast, DataArrayType *& castsPresent) const
4395 this->checkAllocated();
4396 if(this->getNumberOfComponents()!=1)
4397 throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4398 mcIdType nbOfTuples=this->getNumberOfTuples();
4399 std::size_t nbOfCast=std::distance(arrBg,arrEnd);
4401 throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
4403 const T *work=this->getConstPointer();
4404 typedef std::reverse_iterator<const T *> rintstart;
4405 rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
4406 rintstart end2(arrBg);
4407 MCAuto<DataArrayType> ret1=DataArrayType::New();
4408 MCAuto<DataArrayType> ret2=DataArrayType::New();
4409 MCAuto<DataArrayType> ret3=DataArrayType::New();
4410 ret1->alloc(nbOfTuples,1);
4411 ret2->alloc(nbOfTuples,1);
4412 T *ret1Ptr=ret1->getPointer();
4413 T *ret2Ptr=ret2->getPointer();
4414 std::set<T> castsDetected;
4415 for(mcIdType i=0;i<nbOfTuples;i++)
4417 rintstart res=std::find_if(bg,end2,std::bind(std::less_equal<T>(),std::placeholders::_1,work[i]));
4418 std::size_t pos=std::distance(bg,res);
4419 std::size_t pos2=nbOfCast-pos;
4422 ret1Ptr[i]=static_cast<T>(pos2);
4423 ret2Ptr[i]=work[i]-arrBg[pos2];
4424 castsDetected.insert(ret1Ptr[i]);
4428 std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
4429 throw INTERP_KERNEL::Exception(oss.str().c_str());
4432 ret3->alloc(castsDetected.size(),1);
4433 std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
4434 castArr=ret1.retn();
4435 rankInsideCast=ret2.retn();
4436 castsPresent=ret3.retn();
4440 * 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 ).
4441 * 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 ).
4442 * This method works only if \a this is allocated and single component. If not an exception will be thrown.
4444 * \param [out] strt - the start of the range (included) if true is returned.
4445 * \param [out] sttoopp - the end of the range (not included) if true is returned.
4446 * \param [out] stteepp - the step of the range if true is returned.
4447 * \return the verdict of the check.
4449 * \sa DataArray::GetNumberOfItemGivenBES
4452 bool DataArrayDiscrete<T>::isRange(T& strt, T& sttoopp, T& stteepp) const
4454 this->checkAllocated();
4455 if(this->getNumberOfComponents()!=1)
4456 throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
4457 mcIdType nbTuples(this->getNumberOfTuples());
4459 { strt=0; sttoopp=0; stteepp=1; return true; }
4460 const T *pt(this->begin());
4463 { sttoopp=strt+1; stteepp=1; return true; }
4464 strt=*pt; sttoopp=pt[nbTuples-1];
4470 T a(sttoopp-1-strt),tmp(strt);
4471 if(a%(nbTuples-1)!=0)
4473 stteepp=a/(FromIdType<T>(nbTuples)-1);
4474 for(mcIdType i=0;i<nbTuples;i++,tmp+=stteepp)
4482 T a(strt-sttoopp-1),tmp(strt);
4483 if(a%(nbTuples-1)!=0)
4485 stteepp=-(a/(FromIdType<T>(nbTuples)-1));
4486 for(mcIdType i=0;i<nbTuples;i++,tmp+=stteepp)
4494 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4495 * from values of \a this array, which is supposed to contain a renumbering map in
4496 * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
4497 * To know how to use the renumbering maps see \ref numbering.
4498 * \param [in] newNbOfElem - the number of tuples in the result array.
4499 * \return DataArrayInt * - the new instance of DataArrayInt.
4500 * The caller is to delete this result array using decrRef() as it is no more
4503 * \if ENABLE_EXAMPLES
4504 * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
4505 * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
4509 DataArrayIdType * DataArrayDiscrete<T>::invertArrayO2N2N2O(mcIdType newNbOfElem) const
4511 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
4512 ret->alloc(newNbOfElem,1);
4513 mcIdType nbOfOldNodes(this->getNumberOfTuples());
4514 const T *old2New(this->begin());
4515 mcIdType *pt(ret->getPointer());
4516 for(mcIdType i=0;i!=nbOfOldNodes;i++)
4521 if(newp>=0 && newp<newNbOfElem)
4525 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4526 throw INTERP_KERNEL::Exception(oss.str().c_str());
4534 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4535 * from values of \a this array, which is supposed to contain a renumbering map in
4536 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4537 * To know how to use the renumbering maps see \ref numbering.
4538 * \param [in] oldNbOfElem - the number of tuples in the result array.
4539 * \return DataArrayInt * - the new instance of DataArrayInt.
4540 * The caller is to delete this result array using decrRef() as it is no more
4543 * \if ENABLE_EXAMPLES
4544 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4546 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4547 * \sa invertArrayN2O2O2NOptimized
4551 DataArrayIdType *DataArrayDiscrete<T>::invertArrayN2O2O2N(mcIdType oldNbOfElem) const
4553 this->checkAllocated();
4554 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
4555 ret->alloc(oldNbOfElem,1);
4556 const T *new2Old=this->getConstPointer();
4557 mcIdType *pt=ret->getPointer();
4558 std::fill(pt,pt+oldNbOfElem,-1);
4559 mcIdType nbOfNewElems(this->getNumberOfTuples());
4560 for(mcIdType i=0;i<nbOfNewElems;i++)
4563 if(v>=0 && v<oldNbOfElem)
4567 std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
4568 throw INTERP_KERNEL::Exception(oss.str().c_str());
4575 * This method is similar to DataArrayInt::invertArrayO2N2N2O except that
4576 * 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]
4579 DataArrayIdType *DataArrayDiscrete<T>::invertArrayO2N2N2OBis(mcIdType newNbOfElem) const
4581 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
4582 ret->alloc(newNbOfElem,1);
4583 mcIdType nbOfOldNodes(this->getNumberOfTuples());
4584 const T *old2New=this->getConstPointer();
4585 mcIdType *pt=ret->getPointer();
4586 for(mcIdType i=nbOfOldNodes-1;i>=0;i--)
4591 if(newp>=0 && newp<newNbOfElem)
4595 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4596 throw INTERP_KERNEL::Exception(oss.str().c_str());
4604 * Creates a map, whose contents are computed
4605 * from values of \a this array, which is supposed to contain a renumbering map in
4606 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4607 * To know how to use the renumbering maps see \ref numbering.
4608 * \return MapII - the new instance of Map.
4610 * \if ENABLE_EXAMPLES
4611 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4613 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4614 * \sa invertArrayN2O2O2N, giveN2OOptimized, MEDCouplingPointSet::renumberNodesInConn
4618 MCAuto< MapKeyVal<T, mcIdType> > DataArrayDiscrete<T>::invertArrayN2O2O2NOptimized() const
4620 this->checkAllocated();
4621 if(this->getNumberOfComponents()!=1)
4622 throw INTERP_KERNEL::Exception("DataArrayInt::invertArrayN2O2O2NOptimized : single component expected !");
4623 MCAuto< MapKeyVal<T, mcIdType> > ret(MapKeyVal<T, mcIdType>::New());
4624 std::map<T, mcIdType>& m(ret->data());
4625 const T *new2Old(this->begin());
4626 mcIdType nbOfNewElems(this->getNumberOfTuples());
4627 for(mcIdType i=0;i<nbOfNewElems;i++)
4636 * Creates a map, whose contents are computed
4637 * from values of \a this array, which is supposed to contain a renumbering map in
4638 * "New to Old" mode. The result array contains a renumbering map in "New to Old" mode as C++ map for performance reasons.
4640 * \sa invertArrayN2O2O2NOptimized, MEDCouplingPointSet::renumberNodesInConn
4643 MCAuto< MapKeyVal<mcIdType, T> > DataArrayDiscrete<T>::giveN2OOptimized() const
4645 this->checkAllocated();
4646 if(this->getNumberOfComponents()!=1)
4647 throw INTERP_KERNEL::Exception("DataArrayInt::giveN2OOptimized : single component expected !");
4648 MCAuto< MapKeyVal<mcIdType, T> > ret(MapKeyVal<mcIdType, T>::New());
4649 std::map<mcIdType,T>& m(ret->data());
4650 const T *new2Old(this->begin());
4651 mcIdType nbOfNewElems(this->getNumberOfTuples());
4652 for(mcIdType i=0;i<nbOfNewElems;i++)
4661 * This method finds for each element \a ELT in [valsBg,valsEnd) elements in \a this equal to it. Associated to ELT
4662 * this method will return the tuple id of last element found. If there is no element in \a this equal to ELT
4663 * an exception will be thrown.
4665 * In case of success this[ret]==vals. Samely ret->transformWithIndArr(this->begin(),this->end())==vals.
4666 * Where \a vals is the [valsBg,valsEnd) array and \a ret the array returned by this method.
4667 * This method can be seen as an extension of FindPermutationFromFirstToSecond.
4670 * - \a this: [17,27,2,10,-4,3,12,27,16]
4671 * - \a val : [3,16,-4,27,17]
4672 * - result: [5,8,4,7,0]
4674 * \return - An array of size std::distance(valsBg,valsEnd)
4676 * \sa DataArrayInt::FindPermutationFromFirstToSecond , DataArrayInt::FindPermutationFromFirstToSecondDuplicate
4679 MCAuto<DataArrayIdType> DataArrayDiscrete<T>::findIdForEach(const T *valsBg, const T *valsEnd) const
4681 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
4682 std::size_t nbOfTuplesOut(std::distance(valsBg,valsEnd));
4683 ret->alloc(nbOfTuplesOut,1);
4684 MCAuto< MapKeyVal<T, mcIdType> > zeMap(this->invertArrayN2O2O2NOptimized());
4685 const std::map<T, mcIdType>& dat(zeMap->data());
4686 mcIdType *ptToFeed(ret->getPointer());
4687 for(const T *pt=valsBg;pt!=valsEnd;pt++)
4689 typename std::map<T,mcIdType>::const_iterator it(dat.find(*pt));
4691 *ptToFeed++=(*it).second;
4694 std::ostringstream oss; oss << "DataArrayInt::findIdForEach : error for element at place " << std::distance(valsBg,pt);
4695 oss << " of input array value is " << *pt << " which is not in this !";
4696 throw INTERP_KERNEL::Exception(oss.str());
4703 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4704 * This map, if applied to \a this array, would make it sorted. For example, if
4705 * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4706 * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4707 * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4708 * This method is useful for renumbering (in MED file for example). For more info
4709 * on renumbering see \ref numbering.
4710 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4711 * array using decrRef() as it is no more needed.
4712 * \throw If \a this is not allocated.
4713 * \throw If \a this->getNumberOfComponents() != 1.
4714 * \throw If there are equal values in \a this array.
4717 DataArrayIdType *DataArrayDiscrete<T>::checkAndPreparePermutation() const
4719 this->checkAllocated();
4720 if(this->getNumberOfComponents()!=1)
4721 throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4722 mcIdType nbTuples(this->getNumberOfTuples());
4723 const T *pt=this->getConstPointer();
4724 mcIdType *pt2=this->CheckAndPreparePermutation(pt,pt+nbTuples);
4725 DataArrayIdType *ret=DataArrayIdType::New();
4726 ret->useArray(pt2,true,DeallocType::C_DEALLOC,nbTuples,1);
4731 * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4732 * onto a set of values of size \a targetNb (\a B). The surjective function is
4733 * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4734 * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4735 * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4736 * The first of out arrays returns indices of elements of \a this array, grouped by their
4737 * place in the set \a B. The second out array is the index of the first one; it shows how
4738 * many elements of \a A are mapped into each element of \a B. <br>
4740 * mapping and its usage in renumbering see \ref numbering. <br>
4742 * - \a this: [0,3,2,3,2,2,1,2]
4744 * - \a arr: [0, 6, 2,4,5,7, 1,3]
4745 * - \a arrI: [0,1,2,6,8]
4747 * This result means: <br>
4748 * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4749 * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4750 * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4751 * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] :
4752 * \a arrI[ 2+1 ]]); <br> etc.
4753 * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4754 * than the maximal value of \a A.
4755 * \param [out] arr - a new instance of DataArrayInt returning indices of
4756 * elements of \a this, grouped by their place in the set \a B. The caller is to delete
4757 * this array using decrRef() as it is no more needed.
4758 * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4759 * elements of \a this. The caller is to delete this array using decrRef() as it
4760 * is no more needed.
4761 * \throw If \a this is not allocated.
4762 * \throw If \a this->getNumberOfComponents() != 1.
4763 * \throw If any value in \a this is more or equal to \a targetNb.
4766 void DataArrayDiscrete<T>::changeSurjectiveFormat(T targetNb, DataArrayIdType *&arr, DataArrayIdType *&arrI) const
4768 this->checkAllocated();
4769 if(this->getNumberOfComponents()!=1)
4770 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4771 mcIdType nbOfTuples(this->getNumberOfTuples());
4772 const T *input=this->getConstPointer();
4773 std::vector< std::vector<mcIdType> > tmp(targetNb);
4774 for(mcIdType i=0;i<nbOfTuples;i++)
4777 if(tmp2>=0 && tmp2<targetNb)
4778 tmp[tmp2].push_back(i);
4781 std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4782 throw INTERP_KERNEL::Exception(oss.str().c_str());
4786 MCAuto<DataArrayIdType> retI(DataArrayIdType::New());
4787 retI->alloc(targetNb+1,1);
4788 mcIdType *retIPtr=retI->getPointer();
4790 for(std::vector< std::vector<mcIdType> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4791 retIPtr[1]=retIPtr[0]+ToIdType((*it1).size());
4792 if(nbOfTuples!=retI->getIJ(ToIdType(targetNb),0))
4793 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4794 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
4795 ret->alloc(nbOfTuples,1);
4796 mcIdType *retPtr=ret->getPointer();
4797 for(std::vector< std::vector<mcIdType> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4798 retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4804 * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4805 * which if applied to \a this array would make it sorted ascendingly.
4806 * For more info on renumbering see \ref numbering. <br>
4808 * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4809 * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4810 * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2]
4812 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4813 * array using decrRef() as it is no more needed.
4814 * \throw If \a this is not allocated.
4815 * \throw If \a this->getNumberOfComponents() != 1.
4818 DataArrayIdType *DataArrayDiscrete<T>::buildPermArrPerLevel() const
4820 this->checkAllocated();
4821 if(this->getNumberOfComponents()!=1)
4822 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4823 mcIdType nbOfTuples=this->getNumberOfTuples();
4824 const T *pt=this->getConstPointer();
4825 std::map<T,mcIdType> m;
4826 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
4827 ret->alloc(nbOfTuples,1);
4828 mcIdType *opt=ret->getPointer();
4829 for(mcIdType i=0;i<nbOfTuples;i++,pt++,opt++)
4832 typename std::map<T,mcIdType>::iterator it=m.find(val);
4841 m.insert(std::pair<T,mcIdType>(val,1));
4845 for(typename std::map<T,mcIdType>::iterator it=m.begin();it!=m.end();it++)
4847 mcIdType vt=(*it).second;
4851 pt=this->getConstPointer();
4852 opt=ret->getPointer();
4853 for(mcIdType i=0;i<nbOfTuples;i++,pt++,opt++)
4860 * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4861 * iota(). This method is particularly useful for DataArrayInt instances that represent
4862 * a renumbering array, to check if there is a real need in renumbering.
4863 * This method checks than \a this can be considered as an identity mapping
4864 * of a set having \a sizeExpected elements into itself.
4866 * \param [in] sizeExpected - The number of elements expected.
4867 * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4868 * \throw If \a this is not allocated.
4869 * \throw If \a this->getNumberOfComponents() != 1.
4872 bool DataArrayDiscrete<T>::isIota(mcIdType sizeExpected) const
4874 this->checkAllocated();
4875 if(this->getNumberOfComponents()!=1)
4877 mcIdType nbOfTuples(this->getNumberOfTuples());
4878 if(nbOfTuples!=sizeExpected)
4880 const T *pt=this->getConstPointer();
4881 for(mcIdType i=0;i<nbOfTuples;i++,pt++)
4888 * Checks if all values in \a this array are equal to \a val.
4889 * \param [in] val - value to check equality of array values to.
4890 * \return bool - \a true if all values are \a val.
4891 * \throw If \a this is not allocated.
4892 * \throw If \a this->getNumberOfComponents() != 1
4893 * \sa DataArrayInt::checkUniformAndGuess
4896 bool DataArrayDiscrete<T>::isUniform(T val) const
4898 this->checkAllocated();
4899 if(this->getNumberOfComponents()!=1)
4900 throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4901 const T *w(this->begin()),*end2(this->end());
4909 * This method checks that \a this is uniform. If not and exception will be thrown.
4910 * In case of uniformity the corresponding value is returned.
4912 * \return mcIdType - the unique value contained in this
4913 * \throw If \a this is not allocated.
4914 * \throw If \a this->getNumberOfComponents() != 1
4915 * \throw If \a this is not uniform.
4916 * \sa DataArrayInt::isUniform
4919 T DataArrayDiscrete<T>::checkUniformAndGuess() const
4921 this->checkAllocated();
4922 if(this->getNumberOfComponents()!=1)
4923 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4925 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
4926 const T *w(this->begin()),*end2(this->end());
4930 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
4935 * Checks if all values in \a this array are unique.
4936 * \return bool - \a true if condition above is true
4937 * \throw If \a this is not allocated.
4938 * \throw If \a this->getNumberOfComponents() != 1
4941 bool DataArrayDiscrete<T>::hasUniqueValues() const
4943 this->checkAllocated();
4944 if(this->getNumberOfComponents()!=1)
4945 throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4946 std::size_t nbOfElements(this->getNumberOfTuples());
4947 std::set<T> s(this->begin(),this->end()); // in C++11, should use unordered_set (O(1) complexity)
4948 if (s.size() != nbOfElements)
4954 * Copy all components in a specified order from another DataArrayInt.
4955 * The specified components become the first ones in \a this array.
4956 * Both numerical and textual data is copied. The number of tuples in \a this and
4957 * the other array can be different.
4958 * \param [in] a - the array to copy data from.
4959 * \param [in] compoIds - sequence of zero based indices of components, data of which is
4961 * \throw If \a a is NULL.
4962 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
4963 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
4965 * \if ENABLE_EXAMPLES
4966 * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
4970 void DataArrayDiscrete<T>::setSelectedComponents(const DataArrayType *a, const std::vector<std::size_t>& compoIds)
4973 throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
4974 this->checkAllocated();
4975 a->checkAllocated();
4976 this->copyPartOfStringInfoFrom2(compoIds,*a);
4977 std::size_t partOfCompoSz=compoIds.size();
4978 std::size_t nbOfCompo = this->getNumberOfComponents();
4979 mcIdType nbOfTuples=std::min(this->getNumberOfTuples(),a->getNumberOfTuples());
4980 const T *ac=a->getConstPointer();
4981 T *nc=this->getPointer();
4982 for(mcIdType i=0;i<nbOfTuples;i++)
4983 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
4984 nc[nbOfCompo*i+compoIds[j]]=*ac;
4988 * This method searches each value in \a valToSearchIntoTuples among values in \a this given the corresponding tuple to find into.
4989 * If the value at the corresponding tuple is not found in the tuple an exception will be thrown.
4990 * If the value is found the corresponding component id is returned.
4992 * \param [in] valToSearchIntoTuples - a one component array containing the values to find in \a this
4993 * \param [in] tupleIdHint - a one component array having same size than \a valToSearchIntoTuples giving for each value the tuple to find into
4994 * \return DataArrayInt * - A newly allocated array having same size than \a valToSearchIntoTuples with one component
4997 * - \a this: [(0, 1, 2), (3, 4, 5), (6, 2, 3), (7, 8, 9), (9, 0, 10), (11, 12, 13), (14, 5, 11), (15, 16, 17)]
4998 * - \a valToSearchIntoTuples: [1, 4, 6, 8, 10, 12, 14, 16, 17]
4999 * - \a tupleIdHint: [0, 1, 2, 3, 4, 5, 6, 7, 7]
5000 * - result array: [1, 1, 0, 1, 2, 1, 0, 1, 2] == <br>
5003 DataArrayIdType *DataArrayDiscrete<T>::locateComponentId(const DataArrayType *valToSearchIntoTuples, const DataArrayIdType *tupleIdHint) const
5005 if(!valToSearchIntoTuples || !tupleIdHint)
5006 THROW_IK_EXCEPTION("DataArrayInt::locateComponentId : valToSearchIntoTuples and tupleIdHint must be not nullptr !");
5007 valToSearchIntoTuples->checkAllocated(); tupleIdHint->checkAllocated();
5008 this->checkAllocated();
5009 constexpr char MSG1[] = "DataArrayInt::locateComponentId : single component array expected";
5010 valToSearchIntoTuples->checkNbOfComps(1,MSG1); tupleIdHint->checkNbOfComps(1,MSG1);
5011 std::size_t nbOfCompo( this->getNumberOfComponents() );
5012 mcIdType thisNbTuples( this->getNumberOfTuples() );
5013 mcIdType nbOfTuples( valToSearchIntoTuples->getNumberOfTuples() );
5014 tupleIdHint->checkNbOfTuples(nbOfTuples,"Number of tuples of input arrays must be the same.");
5015 const T *cPtr(this->begin()),*valSearchPt(valToSearchIntoTuples->begin());
5016 const mcIdType *tHintPtr(tupleIdHint->begin());
5017 MCAuto<DataArrayIdType> ret = DataArrayIdType::New();
5018 ret->alloc(nbOfTuples,1);
5019 mcIdType *retPtr(ret->getPointer());
5020 for(auto i = 0 ; i < nbOfTuples ; ++i)
5022 if( tHintPtr[i] >=0 && tHintPtr[i] < thisNbTuples )
5024 auto strtSearch(cPtr+nbOfCompo*tHintPtr[i]),endSearch(cPtr+nbOfCompo*(tHintPtr[i]+1));
5025 auto pos = std::find(strtSearch,endSearch,valSearchPt[i]);
5026 if(pos != endSearch)
5027 *retPtr++ = ToIdType( std::distance(strtSearch,pos) );
5029 THROW_IK_EXCEPTION("At pos " << i << " value " << valSearchPt[i] << " is not present at tuple " << tHintPtr[i]);
5032 THROW_IK_EXCEPTION("At pos " << i << " hint tuple is " << tHintPtr[i] << " not in [0," << thisNbTuples << ")");
5038 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
5039 * equal to a given one.
5040 * \param [in] val - the value to ignore within \a this.
5041 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5042 * array using decrRef() as it is no more needed.
5043 * \throw If \a this is not allocated.
5044 * \throw If \a this->getNumberOfComponents() != 1.
5047 DataArrayIdType *DataArrayDiscrete<T>::findIdsNotEqual(T val) const
5049 this->checkAllocated();
5050 if(this->getNumberOfComponents()!=1)
5051 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
5052 const T *cptr(this->getConstPointer());
5053 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
5055 mcIdType nbOfTuples(this->getNumberOfTuples());
5056 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
5058 ret->pushBackSilent(i);
5063 * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
5064 * This method is an extension of DataArrayInt::findIdsEqual method.
5066 * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
5067 * \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
5068 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5069 * array using decrRef() as it is no more needed.
5070 * \throw If \a this is not allocated.
5071 * \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
5072 * \throw If \a this->getNumberOfComponents() is equal to 0.
5073 * \sa DataArrayInt::findIdsEqual
5076 DataArrayIdType *DataArrayDiscrete<T>::findIdsEqualTuple(const T *tupleBg, const T *tupleEnd) const
5078 std::size_t nbOfCompoExp=std::distance(tupleBg,tupleEnd);
5079 this->checkAllocated();
5080 if(this->getNumberOfComponents()!=nbOfCompoExp)
5082 std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << this->getNumberOfComponents() << " components !";
5083 throw INTERP_KERNEL::Exception(oss.str().c_str());
5086 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
5087 MCAuto<DataArrayIdType> ret(DataArrayIdType::New());
5089 const T *bg(this->begin()),*end2(this->end()),*work(this->begin());
5092 work=std::search(work,end2,tupleBg,tupleEnd);
5095 std::ptrdiff_t pos=std::distance(bg,work);
5096 if(pos%nbOfCompoExp==0)
5097 ret->pushBackSilent(ToIdType(pos/nbOfCompoExp));
5105 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
5106 * one of given values.
5107 * \param [in] valsBg - an array of values to find within \a this array.
5108 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5109 * the last value of \a valsBg is \a valsEnd[ -1 ].
5110 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5111 * array using decrRef() as it is no more needed.
5112 * \throw If \a this->getNumberOfComponents() != 1.
5115 DataArrayIdType *DataArrayDiscrete<T>::findIdsEqualList(const T *valsBg, const T *valsEnd) const
5117 if(this->getNumberOfComponents()!=1)
5118 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
5119 std::set<T> vals2(valsBg,valsEnd);
5120 const T *cptr(this->getConstPointer());
5121 mcIdType nbOfTuples(this->getNumberOfTuples());
5122 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(0,1);
5123 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
5124 if(vals2.find(*cptr)!=vals2.end())
5125 ret->pushBackSilent(i);
5130 * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
5131 * equal to any of given values.
5132 * \param [in] valsBg - an array of values to ignore within \a this array.
5133 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5134 * the last value of \a valsBg is \a valsEnd[ -1 ].
5135 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5136 * array using decrRef() as it is no more needed.
5137 * \throw If \a this->getNumberOfComponents() != 1.
5140 DataArrayIdType *DataArrayDiscrete<T>::findIdsNotEqualList(const T *valsBg, const T *valsEnd) const
5142 if(this->getNumberOfComponents()!=1)
5143 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
5144 std::set<T> vals2(valsBg,valsEnd);
5145 const T *cptr=this->getConstPointer();
5146 mcIdType nbOfTuples(this->getNumberOfTuples());
5147 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(0,1);
5148 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
5149 if(vals2.find(*cptr)==vals2.end())
5150 ret->pushBackSilent(i);
5155 * This method expects to be called when number of components of this is equal to one.
5156 * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
5157 * If not any tuple contains \b value -1 is returned.
5158 * \sa DataArrayInt::presenceOfValue
5161 mcIdType DataArrayDiscrete<T>::findIdFirstEqual(T value) const
5163 this->checkAllocated();
5164 if(this->getNumberOfComponents()!=1)
5165 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
5166 const T *cptr=this->getConstPointer();
5167 mcIdType nbOfTuples(this->getNumberOfTuples());
5168 const T *ret=std::find(cptr,cptr+nbOfTuples,value);
5169 if(ret!=cptr+nbOfTuples)
5170 return ToIdType(std::distance(cptr,ret));
5175 * This method expects to be called when number of components of this is equal to one.
5176 * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
5177 * If not any tuple contains one of the values contained in 'vals' -1 is returned.
5178 * \sa DataArrayInt::presenceOfValue
5181 mcIdType DataArrayDiscrete<T>::findIdFirstEqual(const std::vector<T>& vals) const
5183 this->checkAllocated();
5184 if(this->getNumberOfComponents()!=1)
5185 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
5186 std::set<T> vals2(vals.begin(),vals.end());
5187 const T *cptr=this->getConstPointer();
5188 mcIdType nbOfTuples(this->getNumberOfTuples());
5189 for(const T *w=cptr;w!=cptr+nbOfTuples;w++)
5190 if(vals2.find(*w)!=vals2.end())
5191 return ToIdType(std::distance(cptr,w));
5196 * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
5197 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5198 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5199 * If any the tuple id is returned. If not -1 is returned.
5201 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5202 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5204 * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
5205 * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
5208 mcIdType DataArrayDiscrete<T>::findIdFirstEqualTuple(const std::vector<T>& tupl) const
5210 this->checkAllocated();
5211 std::size_t nbOfCompo(this->getNumberOfComponents());
5213 throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
5214 if(nbOfCompo!=tupl.size())
5216 std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
5217 throw INTERP_KERNEL::Exception(oss.str().c_str());
5219 const T *cptr=this->getConstPointer();
5220 std::size_t nbOfVals=this->getNbOfElems();
5221 for(const T *work=cptr;work!=cptr+nbOfVals;)
5223 work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
5224 if(work!=cptr+nbOfVals)
5226 if(std::distance(cptr,work)%nbOfCompo!=0)
5229 return ToIdType (std::distance(cptr,work)/nbOfCompo);
5236 * This method searches the sequence specified in input parameter \b vals in \b this.
5237 * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
5238 * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
5239 * \sa DataArrayInt::findIdFirstEqualTuple
5242 mcIdType DataArrayDiscrete<T>::findIdSequence(const std::vector<T>& vals) const
5244 this->checkAllocated();
5245 std::size_t nbOfCompo=this->getNumberOfComponents();
5247 throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
5248 const T *cptr=this->getConstPointer();
5249 std::size_t nbOfVals=this->getNbOfElems();
5250 const T *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
5251 if(loc!=cptr+nbOfVals)
5252 return ToIdType(std::distance(cptr,loc));
5257 * Assigns \a newValue to all elements holding \a oldValue within \a this
5258 * one-dimensional array.
5259 * \param [in] oldValue - the value to replace.
5260 * \param [in] newValue - the value to assign.
5261 * \return mcIdType - number of replacements performed.
5262 * \throw If \a this is not allocated.
5263 * \throw If \a this->getNumberOfComponents() != 1.
5266 mcIdType DataArrayDiscrete<T>::changeValue(T oldValue, T newValue)
5268 this->checkAllocated();
5269 if(this->getNumberOfComponents()!=1)
5270 throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
5271 if(oldValue==newValue)
5273 T *start(this->getPointer()),*end2(start+this->getNbOfElems());
5275 for(T *val=start;val!=end2;val++)
5284 this->declareAsNew();
5289 * This method returns the number of values in \a this that are equals to input parameter \a value.
5290 * This method only works for single component array.
5292 * \return a value in [ 0, \c this->getNumberOfTuples() )
5294 * \throw If \a this is not allocated
5298 mcIdType DataArrayDiscrete<T>::count(T value) const
5301 this->checkAllocated();
5302 if(this->getNumberOfComponents()!=1)
5303 throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5304 const T *vals=this->begin();
5305 std::size_t nbOfElements=this->getNumberOfTuples();
5306 for(std::size_t i=0;i<nbOfElements;i++,vals++)
5313 * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
5314 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5315 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5316 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5317 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5318 * \sa DataArrayInt::findIdFirstEqualTuple
5321 bool DataArrayDiscrete<T>::presenceOfTuple(const std::vector<T>& tupl) const
5323 return this->findIdFirstEqualTuple(tupl)!=-1;
5328 * Returns \a true if a given value is present within \a this one-dimensional array.
5329 * \param [in] value - the value to find within \a this array.
5330 * \return bool - \a true in case if \a value is present within \a this array.
5331 * \throw If \a this is not allocated.
5332 * \throw If \a this->getNumberOfComponents() != 1.
5333 * \sa findIdFirstEqual()
5336 bool DataArrayDiscrete<T>::presenceOfValue(T value) const
5338 return this->findIdFirstEqual(value)!=-1;
5342 * This method expects to be called when number of components of this is equal to one.
5343 * This method returns true if it exists a tuple so that the value is contained in \b vals.
5344 * If not any tuple contains one of the values contained in 'vals' false is returned.
5345 * \sa DataArrayInt::findIdFirstEqual
5348 bool DataArrayDiscrete<T>::presenceOfValue(const std::vector<T>& vals) const
5350 return this->findIdFirstEqual(vals)!=-1;
5354 * Accumulates values of each component of \a this array.
5355 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
5356 * by the caller, that is filled by this method with sum value for each
5358 * \throw If \a this is not allocated.
5361 void DataArrayDiscrete<T>::accumulate(T *res) const
5363 this->checkAllocated();
5364 const T *ptr=this->getConstPointer();
5365 mcIdType nbTuple(this->getNumberOfTuples());
5366 std::size_t nbComps(this->getNumberOfComponents());
5367 std::fill(res,res+nbComps,0);
5368 for(mcIdType i=0;i<nbTuple;i++)
5369 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<T>());
5373 T DataArrayDiscrete<T>::accumulate(std::size_t compId) const
5375 this->checkAllocated();
5376 const T *ptr=this->getConstPointer();
5377 mcIdType nbTuple(this->getNumberOfTuples());
5378 std::size_t nbComps(this->getNumberOfComponents());
5379 if(compId>=nbComps) // compId >= 0 (it is a size_t)
5380 throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
5382 for(mcIdType i=0;i<nbTuple;i++)
5383 ret+=ptr[i*nbComps+compId];
5388 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
5389 * The returned array will have same number of components than \a this and number of tuples equal to
5390 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
5392 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
5394 * \param [in] bgOfIndex - begin (included) of the input index array.
5395 * \param [in] endOfIndex - end (excluded) of the input index array.
5396 * \return DataArrayInt * - the new instance having the same number of components than \a this.
5398 * \throw If bgOfIndex or end is NULL.
5399 * \throw If input index array is not ascendingly sorted.
5400 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
5401 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
5404 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::accumulatePerChunck(const mcIdType *bgOfIndex, const mcIdType *endOfIndex) const
5406 if(!bgOfIndex || !endOfIndex)
5407 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
5408 this->checkAllocated();
5409 std::size_t nbCompo(this->getNumberOfComponents());
5410 mcIdType nbOfTuples(this->getNumberOfTuples());
5411 mcIdType sz=ToIdType(std::distance(bgOfIndex,endOfIndex));
5413 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
5415 MCAuto<DataArrayType> ret=DataArrayType::New(); ret->alloc(sz,nbCompo);
5416 const mcIdType *w=bgOfIndex;
5417 if(*w<0 || *w>=nbOfTuples)
5418 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
5419 const T *srcPt=this->begin()+(*w)*nbCompo;
5420 T *tmp=ret->getPointer();
5421 for(mcIdType i=0;i<sz;i++,tmp+=nbCompo,w++)
5423 std::fill(tmp,tmp+nbCompo,0);
5426 for(mcIdType j=w[0];j<w[1];j++,srcPt+=nbCompo)
5428 if(j>=0 && j<nbOfTuples)
5429 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<T>());
5432 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
5433 throw INTERP_KERNEL::Exception(oss.str().c_str());
5439 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
5440 throw INTERP_KERNEL::Exception(oss.str().c_str());
5443 ret->copyStringInfoFrom(*this);
5448 * Returns in a single walk in \a this the min value and the max value in \a this.
5449 * \a this is expected to be single component array.
5451 * \param [out] minValue - the min value in \a this.
5452 * \param [out] maxValue - the max value in \a this.
5454 * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5457 void DataArrayDiscrete<T>::getMinMaxValues(T& minValue, T& maxValue) const
5459 this->checkAllocated();
5460 if(this->getNumberOfComponents()!=1)
5461 throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5462 std::size_t nbElements(this->getNumberOfTuples());
5463 const T *pt(this->begin());
5464 minValue=std::numeric_limits<T>::max(); maxValue=-std::numeric_limits<T>::max();
5465 for(std::size_t i=0;i<nbElements;i++,pt++)
5475 * Modify all elements of \a this array, so that
5476 * an element _x_ becomes \f$ numerator / x \f$.
5477 * \warning If an exception is thrown because of presence of 0 element in \a this
5478 * array, all elements processed before detection of the zero element remain
5480 * \param [in] numerator - the numerator used to modify array elements.
5481 * \throw If \a this is not allocated.
5482 * \throw If there is an element equal to 0 in \a this array.
5485 void DataArrayDiscrete<T>::applyInv(T numerator)
5487 this->checkAllocated();
5488 T *ptr=this->getPointer();
5489 std::size_t nbOfElems=this->getNbOfElems();
5490 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5494 *ptr=numerator/(*ptr);
5498 std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/(this->getNumberOfComponents()) << " component #" << i%(this->getNumberOfComponents());
5500 throw INTERP_KERNEL::Exception(oss.str().c_str());
5503 this->declareAsNew();
5507 * Modify all elements of \a this array, so that
5508 * an element _x_ becomes \f$ x / val \f$.
5509 * \param [in] val - the denominator used to modify array elements.
5510 * \throw If \a this is not allocated.
5511 * \throw If \a val == 0.
5514 void DataArrayDiscrete<T>::applyDivideBy(T val)
5517 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5518 this->checkAllocated();
5519 T *ptr=this->getPointer();
5520 std::size_t nbOfElems=this->getNbOfElems();
5521 std::transform(ptr,ptr+nbOfElems,ptr,std::bind(std::divides<T>(),std::placeholders::_1,val));
5522 this->declareAsNew();
5526 * Modify all elements of \a this array, so that
5527 * an element _x_ becomes <em> x % val </em>.
5528 * \param [in] val - the divisor used to modify array elements.
5529 * \throw If \a this is not allocated.
5530 * \throw If \a val <= 0.
5533 void DataArrayDiscrete<T>::applyModulus(T val)
5536 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5537 this->checkAllocated();
5538 T *ptr=this->getPointer();
5539 std::size_t nbOfElems=this->getNbOfElems();
5540 std::transform(ptr,ptr+nbOfElems,ptr,std::bind(std::modulus<T>(),std::placeholders::_1,val));
5541 this->declareAsNew();
5545 * Modify all elements of \a this array, so that
5546 * an element _x_ becomes <em> val % x </em>.
5547 * \warning If an exception is thrown because of presence of an element <= 0 in \a this
5548 * array, all elements processed before detection of the zero element remain
5550 * \param [in] val - the divident used to modify array elements.
5551 * \throw If \a this is not allocated.
5552 * \throw If there is an element equal to or less than 0 in \a this array.
5555 void DataArrayDiscrete<T>::applyRModulus(T val)
5557 this->checkAllocated();
5558 T *ptr=this->getPointer();
5559 std::size_t nbOfElems=this->getNbOfElems();
5560 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5568 std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/(this->getNumberOfComponents()) << " component #" << i%(this->getNumberOfComponents());
5570 throw INTERP_KERNEL::Exception(oss.str().c_str());
5573 this->declareAsNew();
5577 * Modify all elements of \a this array, so that
5578 * an element _x_ becomes <em> val ^ x </em>.
5579 * \param [in] val - the value used to apply pow on all array elements.
5580 * \throw If \a this is not allocated.
5581 * \throw If \a val < 0.
5584 void DataArrayDiscrete<T>::applyPow(T val)
5586 this->checkAllocated();
5588 throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5589 T *ptr=this->getPointer();
5590 std::size_t nbOfElems=this->getNbOfElems();
5593 std::fill(ptr,ptr+nbOfElems,1);
5596 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5599 for(T j=0;j<val;j++)
5603 this->declareAsNew();
5607 * Modify all elements of \a this array, so that
5608 * an element _x_ becomes \f$ val ^ x \f$.
5609 * \param [in] val - the value used to apply pow on all array elements.
5610 * \throw If \a this is not allocated.
5611 * \throw If there is an element < 0 in \a this array.
5612 * \warning If an exception is thrown because of presence of 0 element in \a this
5613 * array, all elements processed before detection of the zero element remain
5617 void DataArrayDiscrete<T>::applyRPow(T val)
5619 this->checkAllocated();
5620 T *ptr=this->getPointer();
5621 std::size_t nbOfElems=this->getNbOfElems();
5622 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5627 for(T j=0;j<*ptr;j++)
5633 std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/(this->getNumberOfComponents()) << " component #" << i%(this->getNumberOfComponents());
5635 throw INTERP_KERNEL::Exception(oss.str().c_str());
5638 this->declareAsNew();
5642 * This method works only on data array with one component.
5643 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5644 * this[*id] in [\b vmin,\b vmax)
5646 * \param [in] vmin begin of range. This value is included in range (included).
5647 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5648 * \return a newly allocated data array that the caller should deal with.
5650 * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5653 DataArrayIdType *DataArrayDiscrete<T>::findIdsInRange(T vmin, T vmax) const
5655 InRange<T> ir(vmin,vmax);
5656 MCAuto<DataArrayIdType> ret(this->findIdsAdv(ir));
5661 * This method works only on data array with one component.
5662 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5663 * this[*id] \b not in [\b vmin,\b vmax)
5665 * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5666 * \param [in] vmax end of range. This value is included in range (included).
5667 * \return a newly allocated data array that the caller should deal with.
5669 * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5672 DataArrayIdType *DataArrayDiscrete<T>::findIdsNotInRange(T vmin, T vmax) const
5674 NotInRange<T> nir(vmin,vmax);
5675 MCAuto<DataArrayIdType> ret(this->findIdsAdv(nir));
5680 * This method works only on data array with one component.
5681 * 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.
5683 * \param [in] vmin begin of range. This value is included in range (included).
5684 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5685 * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5687 bool DataArrayDiscrete<T>::checkAllIdsInRange(T vmin, T vmax) const
5689 this->checkAllocated();
5690 if(this->getNumberOfComponents()!=1)
5691 throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5692 mcIdType nbOfTuples(this->getNumberOfTuples());
5694 const T *cptr=this->getConstPointer();
5695 for(mcIdType i=0;i<nbOfTuples;i++,cptr++)
5697 if(*cptr>=vmin && *cptr<vmax)
5698 { ret=ret && *cptr==i; }
5701 std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5702 throw INTERP_KERNEL::Exception(oss.str().c_str());
5709 * Returns a new DataArrayInt which contains a complement of elements of \a this
5710 * one-dimensional array. I.e. the result array contains all elements from the range [0,
5711 * \a nbOfElement) not present in \a this array.
5712 * \param [in] nbOfElement - maximal size of the result array.
5713 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5714 * array using decrRef() as it is no more needed.
5715 * \throw If \a this is not allocated.
5716 * \throw If \a this->getNumberOfComponents() != 1.
5717 * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
5721 DataArrayIdType *DataArrayDiscrete<T>::buildComplement(mcIdType nbOfElement) const
5723 this->checkAllocated();
5724 if(this->getNumberOfComponents()!=1)
5725 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
5726 std::vector<bool> tmp(nbOfElement);
5727 const T *pt=this->getConstPointer();
5728 std::size_t nbOfElements=this->getNumberOfTuples();
5729 for(const T *w=pt;w!=pt+nbOfElements;w++)
5730 if(*w>=0 && *w<nbOfElement)
5733 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
5734 std::size_t nbOfRetVal=std::count(tmp.begin(),tmp.end(),false);
5735 DataArrayIdType *ret=DataArrayIdType::New();
5736 ret->alloc(nbOfRetVal,1);
5738 mcIdType *retPtr=ret->getPointer();
5739 for(mcIdType i=0;i<nbOfElement;i++)
5746 * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
5747 * from an \a other one-dimensional array.
5748 * \param [in] other - a DataArrayInt containing elements not to include in the result array.
5749 * \return DataArrayInt * - a new instance of DataArrayInt with one component. The
5750 * caller is to delete this array using decrRef() as it is no more needed.
5751 * \throw If \a other is NULL.
5752 * \throw If \a other is not allocated.
5753 * \throw If \a other->getNumberOfComponents() != 1.
5754 * \throw If \a this is not allocated.
5755 * \throw If \a this->getNumberOfComponents() != 1.
5756 * \sa DataArrayInt::buildSubstractionOptimized()
5759 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildSubstraction(const DataArrayType *other) const
5762 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
5763 this->checkAllocated();
5764 other->checkAllocated();
5765 if(this->getNumberOfComponents()!=1)
5766 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
5767 if(other->getNumberOfComponents()!=1)
5768 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
5769 const T *pt=this->getConstPointer();
5770 std::size_t nbOfElements=this->getNumberOfTuples();
5771 std::set<T> s1(pt,pt+nbOfElements);
5772 pt=other->getConstPointer();
5773 nbOfElements=other->getNumberOfTuples();
5774 std::set<T> s2(pt,pt+nbOfElements);
5776 std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<T> >(r));
5777 DataArrayType *ret=DataArrayType::New();
5778 ret->alloc(r.size(),1);
5779 std::copy(r.begin(),r.end(),ret->getPointer());
5784 * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
5785 * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
5787 * \param [in] other an array with one component and expected to be sorted ascendingly.
5788 * \ret list of ids in \a this but not in \a other.
5789 * \sa DataArrayInt::buildSubstraction
5792 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildSubstractionOptimized(const DataArrayType *other) const
5794 static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
5795 if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
5796 this->checkAllocated(); other->checkAllocated();
5797 if(this->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5798 if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5799 const T *pt1Bg(this->begin()),*pt1End(this->end()),*pt2Bg(other->begin()),*pt2End(other->end());
5800 const T *work1(pt1Bg),*work2(pt2Bg);
5801 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(0,1);
5802 for(;work1!=pt1End;work1++)
5804 if(work2!=pt2End && *work1==*work2)
5807 ret->pushBackSilent(*work1);
5813 * Returns a new DataArrayInt which contains all elements of \a this and a given
5814 * one-dimensional arrays. The result array does not contain any duplicates
5815 * and its values are sorted in ascending order.
5816 * \param [in] other - an array to unite with \a this one.
5817 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5818 * array using decrRef() as it is no more needed.
5819 * \throw If \a this or \a other is not allocated.
5820 * \throw If \a this->getNumberOfComponents() != 1.
5821 * \throw If \a other->getNumberOfComponents() != 1.
5824 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildUnion(const DataArrayType *other) const
5826 std::vector<const DataArrayType *>arrs(2);
5827 arrs[0]=dynamic_cast<const DataArrayType *>(this); arrs[1]=other;
5828 return DataArrayDiscrete<T>::BuildUnion(arrs);
5832 * Returns a new DataArrayInt which contains elements present in both \a this and a given
5833 * one-dimensional arrays. The result array does not contain any duplicates
5834 * and its values are sorted in ascending order.
5835 * \param [in] other - an array to intersect with \a this one.
5836 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5837 * array using decrRef() as it is no more needed.
5838 * \throw If \a this or \a other is not allocated.
5839 * \throw If \a this->getNumberOfComponents() != 1.
5840 * \throw If \a other->getNumberOfComponents() != 1.
5843 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildIntersection(const DataArrayType *other) const
5845 std::vector<const DataArrayType *>arrs(2);
5846 arrs[0]=dynamic_cast<const DataArrayType *>(this); arrs[1]=other;
5847 return DataArrayDiscrete<T>::BuildIntersection(arrs);
5850 * This method can be applied on allocated with one component DataArrayInt instance.
5851 * 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.
5852 * Number of tuples of returned array is equal to size of \a this->buildUnique() + 1.
5853 * Last value of returned array is equal to \a this->getNumberOfTuples()
5856 * - \a this : [0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 5, 11]
5857 * - \a return is : [0, 1, 3, 5, 6, 8, 11, 12]
5859 * \return a newly allocated array containing the indexed array format of groups by same consecutive value.
5860 * \throw if \a this is not allocated or if \a this has not exactly one component.
5861 * \sa DataArrayInt::buildUnique, MEDCouplingSkyLineArray::groupPacks
5864 DataArrayIdType *DataArrayDiscrete<T>::indexOfSameConsecutiveValueGroups() const
5866 this->checkAllocated();
5867 if(this->getNumberOfComponents()!=1)
5868 throw INTERP_KERNEL::Exception("DataArrayInt::indexOfSameConsecutiveValueGroups : only single component allowed !");
5869 const T *pt(this->begin());
5870 const T *const ptEnd(this->end()) , * const ptBg(this->begin());
5871 // first find nb of different values in this
5872 std::size_t nbOfTuplesOut(0);
5873 while( pt != ptEnd )
5876 const T *endOfPack(std::find_if(pt+1,ptEnd,[val](T elt){ return val!=elt; }));
5880 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(nbOfTuplesOut+1,1);
5881 mcIdType *retPtr(ret->getPointer()); *retPtr++ = 0;
5883 while( pt != ptEnd )
5886 const T *endOfPack(std::find_if(pt+1,ptEnd,[val](T elt){ return val!=elt; }));
5887 *retPtr++ = ToIdType( std::distance(ptBg,endOfPack) );
5895 * This method can be applied on allocated with one component DataArrayInt instance.
5896 * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
5897 * 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]
5899 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5900 * \throw if \a this is not allocated or if \a this has not exactly one component.
5901 * \sa DataArrayInt::buildUniqueNotSorted, DataArrayInt::indexOfSameConsecutiveValueGroups
5904 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildUnique() const
5906 this->checkAllocated();
5907 if(this->getNumberOfComponents()!=1)
5908 throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
5909 std::size_t nbOfElements(this->getNumberOfTuples());
5910 MCAuto<DataArrayType> tmp(DataArrayType::New());
5911 tmp->deepCopyFrom(*this);
5912 T *data(tmp->getPointer());
5913 T *last(std::unique(data,data+nbOfElements));
5914 MCAuto<DataArrayType> ret(DataArrayType::New());
5915 ret->alloc(std::distance(data,last),1);
5916 std::copy(data,last,ret->getPointer());
5921 * This method can be applied on allocated with one component DataArrayInt instance.
5922 * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
5924 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5926 * \throw if \a this is not allocated or if \a this has not exactly one component.
5928 * \sa DataArrayInt::buildUnique
5931 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildUniqueNotSorted() const
5933 this->checkAllocated();
5934 if(this->getNumberOfComponents()!=1)
5935 throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
5937 this->getMinMaxValues(minVal,maxVal);
5938 std::vector<bool> b(maxVal-minVal+1,false);
5939 const T *ptBg(this->begin()),*endBg(this->end());
5940 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(0,1);
5941 for(const T *pt=ptBg;pt!=endBg;pt++)
5945 ret->pushBackSilent(*pt);
5949 ret->copyStringInfoFrom(*this);
5954 * Returns a new DataArrayInt which contains size of every of groups described by \a this
5955 * "index" array. Such "index" array is returned for example by
5956 * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
5957 * "MEDCouplingUMesh::buildDescendingConnectivity" and
5958 * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
5959 * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
5960 * This method performs the reverse operation of DataArrayInt::computeOffsetsFull.
5961 * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
5962 * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
5963 * The caller is to delete this array using decrRef() as it is no more needed.
5964 * \throw If \a this is not allocated.
5965 * \throw If \a this->getNumberOfComponents() != 1.
5966 * \throw If \a this->getNumberOfTuples() < 1.
5969 * - this contains [1,3,6,7,7,9,15]
5970 * - result array contains [2,3,1,0,2,6],
5971 * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
5973 * \sa DataArrayInt::computeOffsetsFull
5976 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::deltaShiftIndex() const
5978 this->checkAllocated();
5979 if(this->getNumberOfComponents()!=1)
5980 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
5981 std::size_t nbOfElements=this->getNumberOfTuples();
5983 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 2 tuples at least must be present in 'this' !");
5984 const T *ptr=this->getConstPointer();
5985 DataArrayType *ret=DataArrayType::New();
5986 ret->alloc(nbOfElements-1,1);
5987 T *out=ret->getPointer();
5988 std::transform(ptr+1,ptr+nbOfElements,ptr,out,std::minus<T>());
5993 * Modifies \a this one-dimensional array so that value of each element \a x
5994 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5995 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
5996 * and components remains the same.<br>
5997 * This method is useful for allToAllV in MPI with contiguous policy. This method
5998 * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
6000 * \throw If \a this is not allocated.
6001 * \throw If \a this->getNumberOfComponents() != 1.
6004 * - Before \a this contains [3,5,1,2,0,8]
6005 * - After \a this contains [0,3,8,9,11,11]<br>
6006 * Note that the last element 19 = 11 + 8 is missing because size of \a this
6007 * array is retained and thus there is no space to store the last element.
6010 void DataArrayDiscrete<T>::computeOffsets()
6012 this->checkAllocated();
6013 if(this->getNumberOfComponents()!=1)
6014 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
6015 std::size_t nbOfElements=this->getNumberOfTuples();
6018 T *work=this->getPointer();
6021 for(std::size_t i=1;i<nbOfElements;i++)
6024 work[i]=work[i-1]+tmp;
6027 this->declareAsNew();
6031 * Modifies \a this one-dimensional array so that value of each element \a x
6032 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
6033 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
6034 * components remains the same and number of tuples is inceamented by one.<br>
6035 * This method is useful for allToAllV in MPI with contiguous policy. This method
6036 * differs from computeOffsets() in that the number of tuples is changed by this one.
6037 * This method performs the reverse operation of DataArrayInt::deltaShiftIndex.
6038 * \throw If \a this is not allocated.
6039 * \throw If \a this->getNumberOfComponents() != 1.
6042 * - Before \a this contains [3,5,1,2,0,8]
6043 * - After \a this contains [0,3,8,9,11,11,19]<br>
6044 * \sa DataArrayInt::deltaShiftIndex
6047 void DataArrayDiscrete<T>::computeOffsetsFull()
6049 this->checkAllocated();
6050 if(this->getNumberOfComponents()!=1)
6051 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
6052 std::size_t nbOfElements=this->getNumberOfTuples();
6053 T *ret=(T *)malloc((nbOfElements+1)*sizeof(T));
6054 const T *work=this->getConstPointer();
6056 for(std::size_t i=0;i<nbOfElements;i++)
6057 ret[i+1]=work[i]+ret[i];
6058 this->useArray(ret,true,DeallocType::C_DEALLOC,nbOfElements+1,1);
6059 this->declareAsNew();
6063 * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
6064 * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
6065 * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
6066 * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
6067 * filling completely one of the ranges in \a this.
6069 * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
6070 * \param [out] rangeIdsFetched the range ids fetched
6071 * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
6072 * \a idsInInputListThatFetch is a part of input \a listOfIds.
6074 * \sa DataArrayInt::computeOffsetsFull
6077 * - \a this : [0,3,7,9,15,18]
6078 * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
6079 * - \a rangeIdsFetched result array: [0,2,4]
6080 * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
6081 * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
6085 void DataArrayDiscrete<T>::findIdsRangesInListOfIds(const DataArrayType *listOfIds, DataArrayIdType *& rangeIdsFetched, DataArrayType *& idsInInputListThatFetch) const
6088 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
6089 listOfIds->checkAllocated(); this->checkAllocated();
6090 if(listOfIds->getNumberOfComponents()!=1)
6091 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
6092 if(this->getNumberOfComponents()!=1)
6093 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
6094 MCAuto<DataArrayIdType> ret0=DataArrayIdType::New(); ret0->alloc(0,1);
6095 MCAuto<DataArrayType> ret1=DataArrayType::New(); ret1->alloc(0,1);
6096 const T *tupPtr(listOfIds->begin()), *tupEnd(listOfIds->end());
6097 const T *offBg(this->begin()),*offEnd(this->end()-1);
6098 const T *offPtr(offBg);
6099 while(tupPtr!=tupEnd && offPtr!=offEnd)
6101 if(*tupPtr==*offPtr)
6104 while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
6107 ret0->pushBackSilent(ToIdType(std::distance(offBg,offPtr)));
6108 ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
6113 { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
6115 rangeIdsFetched=ret0.retn();
6116 idsInInputListThatFetch=ret1.retn();
6120 * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
6121 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6122 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6123 * beginning within the "iota" array. And \a this is a one-dimensional array
6124 * considered as a selector of groups described by \a offsets to include into the result array.
6125 * \throw If \a offsets is NULL.
6126 * \throw If \a offsets is not allocated.
6127 * \throw If \a offsets->getNumberOfComponents() != 1.
6128 * \throw If \a offsets is not monotonically increasing.
6129 * \throw If \a this is not allocated.
6130 * \throw If \a this->getNumberOfComponents() != 1.
6131 * \throw If any element of \a this is not a valid index for \a offsets array.
6134 * - \a this: [0,2,3]
6135 * - \a offsets: [0,3,6,10,14,20]
6136 * - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
6137 * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
6138 * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) +
6139 * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) +
6140 * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
6143 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildExplicitArrByRanges(const DataArrayType *offsets) const
6146 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
6147 this->checkAllocated();
6148 if(this->getNumberOfComponents()!=1)
6149 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
6150 offsets->checkAllocated();
6151 if(offsets->getNumberOfComponents()!=1)
6152 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
6153 mcIdType othNbTuples=offsets->getNumberOfTuples()-1;
6154 mcIdType nbOfTuples=this->getNumberOfTuples();
6156 const T *work=this->getConstPointer();
6157 const T *offPtr=offsets->getConstPointer();
6158 for(mcIdType i=0;i<nbOfTuples;i++)
6161 if(val>=0 && val<othNbTuples)
6163 T delta=offPtr[val+1]-offPtr[val];
6165 retNbOftuples+=delta;
6168 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
6169 throw INTERP_KERNEL::Exception(oss.str().c_str());
6174 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
6175 oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
6176 throw INTERP_KERNEL::Exception(oss.str().c_str());
6179 MCAuto<DataArrayType> ret=DataArrayType::New();
6180 ret->alloc(retNbOftuples,1);
6181 T *retPtr=ret->getPointer();
6182 for(mcIdType i=0;i<nbOfTuples;i++)
6185 T start=offPtr[val];
6186 T off=offPtr[val+1]-start;
6187 for(T j=0;j<off;j++,retPtr++)
6194 * Returns a new DataArrayInt whose contents is computed using \a this that must be a
6195 * scaled array (monotonically increasing).
6196 from that of \a this and \a
6197 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6198 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6199 * beginning within the "iota" array. And \a this is a one-dimensional array
6200 * considered as a selector of groups described by \a offsets to include into the result array.
6201 * \throw If \a is NULL.
6202 * \throw If \a this is not allocated.
6203 * \throw If \a this->getNumberOfComponents() != 1.
6204 * \throw If \a this->getNumberOfTuples() == 0.
6205 * \throw If \a this is not monotonically increasing.
6206 * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
6209 * - \a bg , \a stop and \a step : (0,5,2)
6210 * - \a this: [0,3,6,10,14,20]
6211 * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
6214 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::buildExplicitArrOfSliceOnScaledArr(T bg, T stop, T step) const
6216 if(!this->isAllocated())
6217 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
6218 if(this->getNumberOfComponents()!=1)
6219 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
6220 mcIdType nbOfTuples(this->getNumberOfTuples());
6222 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
6223 const T *ids(this->begin());
6224 mcIdType nbOfEltsInSlc=DataArrayTools<T>::GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr");
6226 for(mcIdType i=0;i<nbOfEltsInSlc;i++,pos+=step)
6228 if(pos>=0 && pos<nbOfTuples-1)
6230 T delta(ids[pos+1]-ids[pos]);
6234 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
6235 throw INTERP_KERNEL::Exception(oss.str().c_str());
6240 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";
6241 throw INTERP_KERNEL::Exception(oss.str().c_str());
6244 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(sz,1);
6245 T *retPtr(ret->getPointer());
6247 for(mcIdType i=0;i<nbOfEltsInSlc;i++,pos+=step)
6249 T delta(ids[pos+1]-ids[pos]);
6250 for(T j=0;j<delta;j++,retPtr++)
6257 * 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.
6258 * 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
6259 * in tuple **i** of returned DataArrayInt.
6260 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6262 * 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)]
6263 * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6265 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6266 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6267 * \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
6268 * is thrown if no ranges in \a ranges contains value in \a this.
6270 * \sa DataArrayInt::findIdInRangeForEachTuple
6273 DataArrayIdType *DataArrayDiscrete<T>::findRangeIdForEachTuple(const DataArrayType *ranges) const
6276 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6277 if(ranges->getNumberOfComponents()!=2)
6278 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6279 this->checkAllocated();
6280 if(this->getNumberOfComponents()!=1)
6281 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6282 mcIdType nbTuples(this->getNumberOfTuples());
6283 MCAuto<DataArrayIdType> ret=DataArrayIdType::New(); ret->alloc(nbTuples,1);
6284 mcIdType nbOfRanges(ranges->getNumberOfTuples());
6285 const T *rangesPtr=ranges->getConstPointer();
6286 mcIdType *retPtr=ret->getPointer();
6287 const T *inPtr=this->getConstPointer();
6288 for(mcIdType i=0;i<nbTuples;i++,retPtr++)
6292 for(mcIdType j=0;j<nbOfRanges && !found;j++)
6293 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6294 { *retPtr=j; found=true; }
6299 std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6300 throw INTERP_KERNEL::Exception(oss.str().c_str());
6307 * 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.
6308 * 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
6309 * in tuple **i** of returned DataArrayInt.
6310 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6312 * 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)]
6313 * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6314 * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6316 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6317 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6318 * \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
6319 * is thrown if no ranges in \a ranges contains value in \a this.
6320 * \sa DataArrayInt::findRangeIdForEachTuple
6323 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::findIdInRangeForEachTuple(const DataArrayType *ranges) const
6326 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6327 if(ranges->getNumberOfComponents()!=2)
6328 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6329 this->checkAllocated();
6330 if(this->getNumberOfComponents()!=1)
6331 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6332 mcIdType nbTuples=this->getNumberOfTuples();
6333 MCAuto<DataArrayType> ret=DataArrayType::New(); ret->alloc(nbTuples,1);
6334 mcIdType nbOfRanges=ranges->getNumberOfTuples();
6335 const T *rangesPtr=ranges->getConstPointer();
6336 T *retPtr=ret->getPointer();
6337 const T *inPtr=this->getConstPointer();
6338 for(mcIdType i=0;i<nbTuples;i++,retPtr++)
6342 for(mcIdType j=0;j<nbOfRanges && !found;j++)
6343 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6344 { *retPtr=val-rangesPtr[2*j]; found=true; }
6349 std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6350 throw INTERP_KERNEL::Exception(oss.str().c_str());
6357 * \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).
6358 * 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).
6359 * 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 !
6360 * If this method has correctly worked, \a this will be able to be considered as a linked list.
6361 * This method does nothing if number of tuples is lower of equal to 1.
6363 * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internally the connectivity without any coordinates consideration.
6365 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::sortToHaveConsecutivePairs(), DataArrayInt::fromLinkedListOfPairToList
6368 void DataArrayDiscrete<T>::sortEachPairToMakeALinkedList()
6370 this->checkAllocated();
6371 if(this->getNumberOfComponents()!=2)
6372 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6373 mcIdType nbOfTuples(this->getNumberOfTuples());
6376 T *conn(this->getPointer());
6377 for(mcIdType i=1;i<nbOfTuples;i++,conn+=2)
6381 if(conn[2]==conn[3])
6383 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6384 throw INTERP_KERNEL::Exception(oss.str().c_str());
6386 if(conn[2]!=conn[1] && conn[3]!=conn[1])
6388 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : There is no common noeud between the tuple #" << i << " and the tuple #" << i + 1 << ". Need call DataArrayInt::sortToHaveConsecutivePairs() ";
6389 throw INTERP_KERNEL::Exception(oss.str().c_str());
6391 if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6392 std::swap(conn[2],conn[3]);
6393 //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6394 if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6396 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6397 throw INTERP_KERNEL::Exception(oss.str().c_str());
6402 if(conn[0]==conn[1] || conn[2]==conn[3])
6403 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6406 s.insert(conn,conn+4);
6408 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6409 if(std::count(conn,conn+4,conn[0])==2)
6414 if(conn[2]==conn[0])
6418 std::copy(tmp,tmp+4,conn);
6421 {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6422 if(conn[1]==conn[3])
6423 std::swap(conn[2],conn[3]);
6430 * This method is the improvement from the method sortEachPairToMakeALinkedList().
6432 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::sortEachPairToMakeALinkedList(), DataArrayInt::fromLinkedListOfPairToList
6435 void DataArrayDiscrete<T>::sortToHaveConsecutivePairs()
6437 this->checkAllocated();
6438 if(this->getNumberOfComponents()!=2)
6439 throw INTERP_KERNEL::Exception("DataArrayInt::sortToHaveConsecutivePairs : Only works on DataArrayInt instance with nb of components equal to 2 !");
6440 mcIdType nbOfTuples(this->getNumberOfTuples());
6441 T *thisPtr(this->getPointer());
6442 mcIdType idOfLastTuple = 0;
6443 std::pair<T*,T*> tmp;
6444 if(thisPtr[0]==thisPtr[1])
6446 THROW_IK_EXCEPTION("DataArrayInt::sortToHaveConsecutivePairs : In the first tuple presence of a pair filled with same ids !");
6448 while(idOfLastTuple < nbOfTuples-1)
6450 mcIdType i = idOfLastTuple+1;
6451 tmp.first = &thisPtr[2*i];
6452 tmp.second = &thisPtr[2*i+1];
6453 if(std::get<0>(tmp)[0] == std::get<1>(tmp)[0])
6455 THROW_IK_EXCEPTION("DataArrayInt::sortToHaveConsecutivePairs : In the tuple #" << i << " presence of a pair filled with same ids !");
6457 while((this->getIJ(idOfLastTuple,1) != std::get<0>(tmp)[0] &&
6458 this->getIJ(idOfLastTuple,1) != std::get<1>(tmp)[0]) &&
6461 std::swap(std::get<0>(tmp)[0],thisPtr[2*(i+1)]);
6462 std::swap(std::get<1>(tmp)[0],thisPtr[2*(i+1)+1]);
6465 if(i < nbOfTuples-1 ||
6466 this->getIJ(idOfLastTuple,1) == std::get<0>(tmp)[0] ||
6467 this->getIJ(idOfLastTuple,1) == std::get<1>(tmp)[0])
6469 if(this->getIJ(idOfLastTuple,1) != std::get<0>(tmp)[0])
6470 std::swap(std::get<0>(tmp)[0],std::get<1>(tmp)[0]);
6475 THROW_IK_EXCEPTION("DataArrayInt::sortToHaveConsecutivePairs : not found the tuple which have the common noeud = " << this->getIJ(idOfLastTuple,1));
6481 * \a this is expected to be a correctly linked list of pairs.
6483 * \sa DataArrayInt::sortEachPairToMakeALinkedList
6486 MCAuto<typename Traits<T>::ArrayType> DataArrayDiscrete<T>::fromLinkedListOfPairToList() const
6488 this->checkAllocated();
6489 this->checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6490 mcIdType nbTuples(this->getNumberOfTuples());
6492 throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6493 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(nbTuples+1,1);
6494 const T *thisPtr(this->begin());
6495 T *retPtr(ret->getPointer());
6496 retPtr[0]=thisPtr[0];
6497 for(mcIdType i=0;i<nbTuples;i++)
6499 retPtr[i+1]=thisPtr[2*i+1];
6501 if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6503 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 ?";
6504 throw INTERP_KERNEL::Exception(oss.str());
6511 * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6512 * But the number of components can be different from one.
6513 * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6516 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::getDifferentValues() const
6518 this->checkAllocated();
6520 ret.insert(this->begin(),this->end());
6521 MCAuto<DataArrayType> ret2=DataArrayType::New();
6522 ret2->alloc(ret.size(),1);
6523 std::copy(ret.begin(),ret.end(),ret2->getPointer());
6528 class PartitionCfg : public std::set<T>
6531 PartitionCfg() = default;
6532 void setID(T id) { _id = id; }
6533 T getID() const { return _id; }
6534 bool operator<(const PartitionCfg<T>& other) { return std::set<T>::operator<( other._data ); }
6535 bool operator>(const PartitionCfg<T>& other) { return std::set<T>::operator>( other._data ); }
6536 bool operator==(const PartitionCfg<T>& other) { return std::set<T>::operator==( other._data ); }
6542 * \a this is considered as an array defining a partition. It means that values in \a this define partition-ids. All tuples in \a this with same value can be considered as partition.
6543 * Typically MED stores families uses this compact storage method.
6545 * This method computes and returns the partition stored in \a this on reduced space using a reduction operation specified by pairs \a commonEntities and \a commonEntitiesIndex parameters.
6546 * The reduction operation is the consequence of a fusion of enties. It explains the storage format defining reduction.
6548 * An another way to consider this method : This method can be seen as an interpolation on integer field (\a this). For fused entities it returns in compact way all combinations of partition configuration.
6550 * \param [out] partitionsToBeModified - For all partitions impacted by the reduction a n-uplet is returned (n is deduced thanks to \a partitionsToBeModifiedIndex)
6551 * Each n-uplet represents a list of partitions impacted by reduction. The first element of n-uplet represents the ID to locate entities (using for example findIdsEqual in returned array)
6552 * Remaining IDs in n-uplet are Partition IDs impacted.
6553 * \param [out] partitionsToBeModifiedIndex - Index attached to \a partitionsToBeModified to interprete.
6555 * \return - The partition array that is the output of the reduction of \a this.
6557 * \sa MEDCouplingUMesh::findCommonCells, DataArrayDouble::findCommonTuples
6560 MCAuto< typename DataArrayDiscrete<T>::DataArrayType > DataArrayDiscrete<T>::forThisAsPartitionBuildReduction(const MCAuto<DataArrayIdType>& commonEntities, const MCAuto<DataArrayIdType>& commonEntitiesIndex, MCAuto<DataArrayType>& partitionsToBeModified, MCAuto<DataArrayIdType>& partitionsToBeModifiedIndex) const
6562 constexpr char MSG[] = "this should have only one component";
6563 this->checkAllocated(); this->checkNbOfComps(1,MSG);
6564 commonEntities->checkAllocated(); commonEntities->checkNbOfComps(1,MSG);
6565 commonEntitiesIndex->checkAllocated(); commonEntitiesIndex->checkNbOfComps(1,MSG);
6566 std::size_t initialSpaceSz( this->getNumberOfTuples() );
6567 mcIdType returnedSpaceSz( 0 );// store size of reducted returned size
6569 MCAuto<DataArrayIdType> sizeOfPacks( commonEntitiesIndex->deltaShiftIndex() );
6571 MCAuto<DataArrayIdType> o2n( DataArrayIdType::ConvertIndexArrayToO2N(initialSpaceSz,commonEntities->begin(),commonEntitiesIndex->begin(),commonEntitiesIndex->end(),returnedSpaceSz) );
6572 MCAuto< DataArrayType > ret( DataArrayDiscrete<T>::New() );
6573 ret->alloc( returnedSpaceSz, 1 );
6574 ret->fillWithValue( std::numeric_limits<T>::max() );
6575 // First deal with entities not fused.
6576 MCAuto<DataArrayIdType> eltsNotFused( commonEntities->copySorted() );
6577 eltsNotFused = eltsNotFused->buildComplement( initialSpaceSz );
6578 MCAuto<DataArrayType> partionIdsOfNotFused = this->mySelectByTupleIdSafe(eltsNotFused->begin(),eltsNotFused->end());
6579 MCAuto<DataArrayIdType> tupleIdsToSelect = o2n->selectByTupleIdSafe(eltsNotFused->begin(),eltsNotFused->end());
6580 ret->setPartOfValues3(partionIdsOfNotFused,tupleIdsToSelect->begin(),tupleIdsToSelect->end(),0,1,1);
6581 T *retPt( ret->getPointer() );
6582 const mcIdType *o2nPt( o2n->begin() );
6584 partitionsToBeModified = DataArrayType::New(); partitionsToBeModified->alloc(0,1);
6585 partitionsToBeModifiedIndex = DataArrayIdType::New(); partitionsToBeModifiedIndex->alloc(1,1); partitionsToBeModifiedIndex->setIJSilent(0,0,0);
6586 if( !sizeOfPacks->empty() )// if empty -> no fusion -> ret is already ready at this point -> nothing to do.
6588 mcIdType maxSizeOfPacks = sizeOfPacks->getMaxValueInArray();// store the max size of common entities
6589 T newValueInThis = this->getMaxValueInArray() + 1;
6590 const T *ptOfThisData( this->begin() );
6591 const mcIdType *ceBg( commonEntities->begin() ), *ceiBg( commonEntitiesIndex->begin() );
6592 for(mcIdType szOfPack = 2 ; szOfPack <= maxSizeOfPacks ; ++szOfPack)
6594 MCAuto<DataArrayIdType> idsInThisWithSamePackSz = sizeOfPacks->findIdsEqual( FromIdType<T>( szOfPack ) );
6595 std::set< PartitionCfg<T> > partitionCfgHolder;
6596 for( const mcIdType *idsInThisWithSamePackSzIt = idsInThisWithSamePackSz->begin() ; idsInThisWithSamePackSzIt != idsInThisWithSamePackSz->end() ; ++idsInThisWithSamePackSzIt )
6598 PartitionCfg<T> partitionCfg;
6599 std::transform(ceBg + ceiBg[*idsInThisWithSamePackSzIt],ceBg + ceiBg[*idsInThisWithSamePackSzIt + 1], std::inserter(partitionCfg,partitionCfg.end()),[ptOfThisData](mcIdType elt) { return ptOfThisData[elt]; });
6600 auto existCfg = partitionCfgHolder.find( partitionCfg );
6601 if( existCfg != partitionCfgHolder.end() )
6602 {//partition already exist by a previous pack -> reuse it !
6603 T newPartitionID = existCfg->getID();
6604 retPt[ o2nPt[ ceBg [ ceiBg[*idsInThisWithSamePackSzIt] ] ] ] = newPartitionID;// hypothesis that o2n is so that all o2n[ceBg + ceiBg[*idsInThisWithSamePackSzIt],ceBg + ceiBg[*idsInThisWithSamePackSzIt + 1]) points to the same point in new renumbering
6607 {//partition does not exist yet -> create it !
6608 partitionCfg.setID( newValueInThis++ );
6609 partitionCfgHolder.insert( partitionCfg );
6610 retPt[ o2nPt[ ceBg [ ceiBg[*idsInThisWithSamePackSzIt] ] ] ] = partitionCfg.getID();
6611 partitionsToBeModified->pushBackSilent( partitionCfg.getID() );
6612 partitionsToBeModified->pushBackValsSilent(partitionCfg.begin(),partitionCfg.end());
6613 partitionsToBeModifiedIndex->pushBackSilent( partitionsToBeModifiedIndex->back() + partitionCfg.size() + 1 );
6622 * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6623 * them it tells which tuple id have this id.
6624 * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6625 * This method returns two arrays having same size.
6626 * 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.
6627 * 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]]
6630 std::vector<DataArrayIdType *> DataArrayDiscrete<T>::partitionByDifferentValues(std::vector<T>& differentIds) const
6632 this->checkAllocated();
6633 if(this->getNumberOfComponents()!=1)
6634 throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6636 std::map<T,mcIdType> m,m2,m3;
6637 for(const T *w=this->begin();w!=this->end();w++)
6639 differentIds.resize(m.size());
6640 std::vector<DataArrayIdType *> ret(m.size());
6641 std::vector<mcIdType *> retPtr(m.size());
6642 for(typename std::map<T,mcIdType>::const_iterator it=m.begin();it!=m.end();it++,id++)
6645 ret[id]=DataArrayIdType::New();
6646 ret[id]->alloc((*it).second,1);
6647 retPtr[id]=ret[id]->getPointer();
6648 differentIds[id]=(*it).first;
6651 for(const T *w=this->begin();w!=this->end();w++,id++)
6653 retPtr[m2[*w]][m3[*w]++]=id;
6659 * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6660 * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6662 * \param [in] nbOfSlices - number of slices expected.
6663 * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6665 * \sa DataArray::GetSlice
6666 * \throw If \a this is not allocated or not with exactly one component.
6667 * \throw If an element in \a this if < 0.
6670 std::vector< std::pair<mcIdType,mcIdType> > DataArrayDiscrete<T>::splitInBalancedSlices(mcIdType nbOfSlices) const
6672 if(!this->isAllocated() || this->getNumberOfComponents()!=1)
6673 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6675 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6676 T sum(this->accumulate((std::size_t)0));
6677 mcIdType nbOfTuples(this->getNumberOfTuples());
6678 T sumPerSlc(sum/FromIdType<T>(nbOfSlices));
6680 const T *w(this->begin());
6681 std::vector< std::pair<mcIdType,mcIdType> > ret(nbOfSlices);
6682 for(mcIdType i=0;i<nbOfSlices;i++)
6684 std::pair<mcIdType, mcIdType> p(pos,-1);
6686 while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6690 p.second=nbOfTuples;
6697 * Modify \a this array so that each value becomes a modulus of division of this value by
6698 * a value of another DataArrayInt. There are 3 valid cases.
6699 * 1. The arrays have same number of tuples and components. Then each value of
6700 * \a this array is divided by the corresponding value of \a other one, i.e.:
6701 * _a_ [ i, j ] %= _other_ [ i, j ].
6702 * 2. The arrays have same number of tuples and \a other array has one component. Then
6703 * _a_ [ i, j ] %= _other_ [ i, 0 ].
6704 * 3. The arrays have same number of components and \a other array has one tuple. Then
6705 * _a_ [ i, j ] %= _a2_ [ 0, j ].
6707 * \warning No check of division by zero is performed!
6708 * \param [in] other - a divisor array.
6709 * \throw If \a other is NULL.
6710 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
6711 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
6712 * \a other has number of both tuples and components not equal to 1.
6715 void DataArrayDiscrete<T>::modulusEqual(const DataArrayType *other)
6718 throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
6719 const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
6720 this->checkAllocated(); other->checkAllocated();
6721 mcIdType nbOfTuple(this->getNumberOfTuples());
6722 mcIdType nbOfTuple2(other->getNumberOfTuples());
6723 std::size_t nbOfComp(this->getNumberOfComponents());
6724 std::size_t nbOfComp2(other->getNumberOfComponents());
6725 if(nbOfTuple==nbOfTuple2)
6727 if(nbOfComp==nbOfComp2)
6729 std::transform(this->begin(),this->end(),other->begin(),this->getPointer(),std::modulus<T>());
6731 else if(nbOfComp2==1)
6733 if(nbOfComp2==nbOfComp)
6735 T *ptr=this->getPointer();
6736 const T *ptrc=other->getConstPointer();
6737 for(mcIdType i=0;i<nbOfTuple;i++)
6738 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind(std::modulus<T>(),std::placeholders::_1,*ptrc++));
6741 throw INTERP_KERNEL::Exception(msg);
6744 throw INTERP_KERNEL::Exception(msg);
6746 else if(nbOfTuple2==1)
6748 T *ptr=this->getPointer();
6749 const T *ptrc=other->getConstPointer();
6750 for(mcIdType i=0;i<nbOfTuple;i++)
6751 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<T>());
6754 throw INTERP_KERNEL::Exception(msg);
6755 this->declareAsNew();
6759 * Apply pow on values of another DataArrayInt to values of \a this one.
6761 * \param [in] other - an array to pow to \a this one.
6762 * \throw If \a other is NULL.
6763 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
6764 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
6765 * \throw If there is a negative value in \a other.
6768 void DataArrayDiscrete<T>::powEqual(const DataArrayType *other)
6771 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
6772 mcIdType nbOfTuple=this->getNumberOfTuples();
6773 mcIdType nbOfTuple2=other->getNumberOfTuples();
6774 std::size_t nbOfComp=this->getNumberOfComponents();
6775 std::size_t nbOfComp2=other->getNumberOfComponents();
6776 if(nbOfTuple!=nbOfTuple2)
6777 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
6778 if(nbOfComp!=1 || nbOfComp2!=1)
6779 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
6780 T *ptr=this->getPointer();
6781 const T *ptrc=other->begin();
6782 for(mcIdType i=0;i<nbOfTuple;i++,ptrc++,ptr++)
6787 for(T j=0;j<*ptrc;j++)
6793 std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
6794 throw INTERP_KERNEL::Exception(oss.str().c_str());
6797 this->declareAsNew();
6800 ////////////////////////////////////
6802 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6806 void DataArrayDiscrete<T>::getTinySerializationIntInformation(std::vector<mcIdType>& tinyInfo) const
6809 if(this->isAllocated())
6811 tinyInfo[0]=this->getNumberOfTuples();
6812 tinyInfo[1]=ToIdType(this->getNumberOfComponents());
6822 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6826 void DataArrayDiscrete<T>::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
6828 if(this->isAllocated())
6830 std::size_t nbOfCompo(this->getNumberOfComponents());
6831 tinyInfo.resize(nbOfCompo+1);
6832 tinyInfo[0]=this->getName();
6833 for(std::size_t i=0;i<nbOfCompo;i++)
6834 tinyInfo[i+1]=this->getInfoOnComponent(i);
6839 tinyInfo[0]=this->getName();
6844 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6845 * This method returns if a feeding is needed.
6848 bool DataArrayDiscrete<T>::resizeForUnserialization(const std::vector<mcIdType>& tinyInfoI)
6850 mcIdType nbOfTuple=tinyInfoI[0];
6851 mcIdType nbOfComp=tinyInfoI[1];
6852 if(nbOfTuple!=-1 || nbOfComp!=-1)
6854 this->alloc(nbOfTuple,nbOfComp);
6861 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6862 * This method returns if a feeding is needed.
6865 void DataArrayDiscrete<T>::finishUnserialization(const std::vector<mcIdType>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
6867 this->setName(tinyInfoS[0]);
6868 if(this->isAllocated())
6870 mcIdType nbOfCompo=tinyInfoI[1];
6871 for(mcIdType i=0;i<nbOfCompo;i++)
6872 this->setInfoOnComponent(i,tinyInfoS[i+1]);
6876 ////////////////////////////////////
6879 * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
6882 * \param [in] a1 - an array to pow up.
6883 * \param [in] a2 - another array to sum up.
6884 * \return DataArrayInt * - the new instance of DataArrayInt.
6885 * The caller is to delete this result array using decrRef() as it is no more
6887 * \throw If either \a a1 or \a a2 is NULL.
6888 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6889 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
6890 * \throw If there is a negative value in \a a2.
6893 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Pow(const DataArrayType *a1, const DataArrayType *a2)
6896 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
6897 mcIdType nbOfTuple=a1->getNumberOfTuples();
6898 mcIdType nbOfTuple2=a2->getNumberOfTuples();
6899 std::size_t nbOfComp=a1->getNumberOfComponents();
6900 std::size_t nbOfComp2=a2->getNumberOfComponents();
6901 if(nbOfTuple!=nbOfTuple2)
6902 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
6903 if(nbOfComp!=1 || nbOfComp2!=1)
6904 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
6905 MCAuto<DataArrayType> ret=DataArrayType::New(); ret->alloc(nbOfTuple,1);
6906 const T *ptr1(a1->begin()),*ptr2(a2->begin());
6907 T *ptr=ret->getPointer();
6908 for(mcIdType i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
6913 for(T j=0;j<*ptr2;j++)
6919 std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
6920 throw INTERP_KERNEL::Exception(oss.str().c_str());
6927 * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6929 * 1. The arrays have same number of tuples and components. Then each value of
6930 * the result array (_a_) is a division of the corresponding values of \a a1 and
6931 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6932 * 2. The arrays have same number of tuples and one array, say _a2_, has one
6934 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6935 * 3. The arrays have same number of components and one array, say _a2_, has one
6937 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6939 * Info on components is copied either from the first array (in the first case) or from
6940 * the array with maximal number of elements (getNbOfElems()).
6941 * \warning No check of division by zero is performed!
6942 * \param [in] a1 - a dividend array.
6943 * \param [in] a2 - a divisor array.
6944 * \return DataArrayInt * - the new instance of DataArrayInt.
6945 * The caller is to delete this result array using decrRef() as it is no more
6947 * \throw If either \a a1 or \a a2 is NULL.
6948 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6949 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6950 * none of them has number of tuples or components equal to 1.
6953 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Modulus(const DataArrayType *a1, const DataArrayType *a2)
6956 throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6957 mcIdType nbOfTuple1(a1->getNumberOfTuples());
6958 mcIdType nbOfTuple2(a2->getNumberOfTuples());
6959 std::size_t nbOfComp1(a1->getNumberOfComponents());
6960 std::size_t nbOfComp2(a2->getNumberOfComponents());
6961 if(nbOfTuple2==nbOfTuple1)
6963 if(nbOfComp1==nbOfComp2)
6965 MCAuto<DataArrayType> ret=DataArrayType::New();
6966 ret->alloc(nbOfTuple2,nbOfComp1);
6967 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<T>());
6968 ret->copyStringInfoFrom(*a1);
6971 else if(nbOfComp2==1)
6973 MCAuto<DataArrayType> ret=DataArrayType::New();
6974 ret->alloc(nbOfTuple1,nbOfComp1);
6975 const T *a2Ptr=a2->getConstPointer();
6976 const T *a1Ptr=a1->getConstPointer();
6977 T *res=ret->getPointer();
6978 for(mcIdType i=0;i<nbOfTuple1;i++)
6979 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind(std::modulus<T>(),std::placeholders::_1,a2Ptr[i]));
6980 ret->copyStringInfoFrom(*a1);
6985 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6989 else if(nbOfTuple2==1)
6991 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6992 MCAuto<DataArrayType> ret=DataArrayType::New();
6993 ret->alloc(nbOfTuple1,nbOfComp1);
6994 const T *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6995 T *pt=ret->getPointer();
6996 for(mcIdType i=0;i<nbOfTuple1;i++)
6997 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<T>());
6998 ret->copyStringInfoFrom(*a1);
7003 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
7009 * 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
7010 * input array \a ids2.
7011 * \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.
7012 * 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
7014 * In case of success both assertion will be true (no throw) :
7015 * \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7016 * \c ret->transformWithIndArr(ids2)->isEqual(ids1)
7019 * - \a ids1 : [3,1,103,4,6,10,-7,205]
7020 * - \a ids2 : [-7,1,205,10,6,3,103,4]
7021 * - \a return is : [5,1,6,7,4,3,0,2] because ids2[5]==ids1[0], ids2[1]==ids1[1], ids2[6]==ids1[2]...
7023 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7024 * array using decrRef() as it is no more needed.
7025 * \throw If either ids1 or ids2 is null not allocated or not with one components.
7027 * \sa DataArrayInt::findIdForEach, DataArrayInt::FindPermutationFromFirstToSecondDuplicate, DataArrayInt::rankOfElementInThis
7030 DataArrayIdType *DataArrayDiscrete<T>::FindPermutationFromFirstToSecond(const DataArrayType *ids1, const DataArrayType *ids2)
7033 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7034 if(!ids1->isAllocated() || !ids2->isAllocated())
7035 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7036 if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7037 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7038 if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7040 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 !";
7041 throw INTERP_KERNEL::Exception(oss.str().c_str());
7043 MCAuto<DataArrayType> c1(ids1->deepCopy());
7044 MCAuto<DataArrayType> c2(ids2->deepCopy());
7045 c1->sort(true); c2->sort(true);
7046 if(!c1->isEqualWithoutConsideringStr(*c2))
7047 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7048 MCAuto<DataArrayIdType> p1=ids1->checkAndPreparePermutation();
7049 MCAuto<DataArrayIdType> p2=ids2->checkAndPreparePermutation();
7050 p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7051 p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7056 * 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
7057 * input array \a ids2.
7058 * \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.
7059 * 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
7061 * The difference with DataArrayInt::FindPermutationFromFirstToSecond is that this method supports multiple same values in \a ids1 and \a ids2 whereas
7062 * DataArrayInt::FindPermutationFromFirstToSecond doesn't. It implies that this method my be slower than the DataArrayInt::FindPermutationFromFirstToSecond one.
7064 * In case of success both assertion will be true (no throw) :
7065 * \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7066 * \c ret->transformWithIndArr(ids2)->isEqual(ids1)
7069 * - \a ids1 : [5, 3, 2, 1, 4, 5, 2, 1, 0, 11, 5, 4]
7070 * - \a ids2 : [0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 5, 11]
7071 * - \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]...
7073 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7074 * array using decrRef() as it is no more needed.
7075 * \throw If either ids1 or ids2 is null not allocated or not with one components.
7077 * \sa DataArrayInt::findIdForEach, DataArrayInt::FindPermutationFromFirstToSecond, DataArrayInt::occurenceRankInThis
7080 DataArrayIdType *DataArrayDiscrete<T>::FindPermutationFromFirstToSecondDuplicate(const DataArrayType *ids1, const DataArrayType *ids2)
7083 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecondDuplicate : the two input arrays must be not null !");
7084 constexpr char MSG0[] = "DataArrayInt::FindPermutationFromFirstToSecondDuplicate :";
7085 ids1->checkAllocated(); ids2->checkAllocated();
7086 ids1->checkNbOfComps(1,MSG0); ids2->checkNbOfComps(1,MSG0);
7087 mcIdType nbTuples(ids1->getNumberOfTuples());
7088 if(nbTuples != ids2->getNumberOfTuples())
7090 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 !";
7091 throw INTERP_KERNEL::Exception(oss.str().c_str());
7093 MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(nbTuples,1);
7094 MCAuto<DataArrayIdType> oids2(ids2->occurenceRankInThis());
7095 std::map< std::pair<T,mcIdType>, mcIdType> m;
7097 const mcIdType *oids2Ptr(oids2->begin());
7098 for(const T * it2 = ids2->begin() ; it2 != ids2->end() ; ++it2, ++oids2Ptr, ++pos)
7099 m[{*it2,*oids2Ptr}] = pos;
7100 mcIdType *retPtr(ret->getPointer());
7102 std::map<T,mcIdType> mOccurence1; // see DataArrayInt::occurenceRankInThis : avoid to compute additionnal temporary array
7104 for(const T * it1 = ids1->begin() ; it1 != ids1->end() ; ++it1, ++retPtr)
7106 auto it = mOccurence1.find(*it1);
7108 if( it == mOccurence1.end() )
7111 mOccurence1[*it1] = 1;
7115 occRk1 = (*it).second++;
7118 auto it2 = m.find({*it1,occRk1});
7121 *retPtr = (*it2).second;
7125 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 !";
7126 throw INTERP_KERNEL::Exception(oss.str());
7134 * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
7135 * This map, if applied to \a start array, would make it sorted. For example, if
7136 * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
7137 * [5,6,0,3,2,7,1,4].
7138 * \param [in] start - pointer to the first element of the array for which the
7139 * permutation map is computed.
7140 * \param [in] end - pointer specifying the end of the array \a start, so that
7141 * the last value of \a start is \a end[ -1 ].
7142 * \return mcIdType * - the result permutation array that the caller is to delete as it is no
7144 * \throw If there are equal values in the input array.
7147 mcIdType *DataArrayDiscrete<T>::CheckAndPreparePermutation(const T *start, const T *end)
7149 std::size_t sz=std::distance(start,end);
7150 mcIdType *ret=(mcIdType *)malloc(sz*sizeof(mcIdType));
7152 std::copy(start,end,work);
7153 std::sort(work,work+sz);
7154 if(std::unique(work,work+sz)!=work+sz)
7158 throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
7160 std::map<T,mcIdType> m;
7161 for(T *workPt=work;workPt!=work+sz;workPt++)
7162 m[*workPt]=ToIdType(std::distance(work,workPt));
7163 mcIdType *iter2=ret;
7164 for(const T *iter=start;iter!=end;iter++,iter2++)
7171 * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
7172 * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
7173 * offsetA2</em> and (2)
7174 * the number of component in the result array is same as that of each of given arrays.
7175 * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
7176 * Info on components is copied from the first of the given arrays. Number of components
7177 * in the given arrays must be the same.
7178 * \param [in] a1 - an array to include in the result array.
7179 * \param [in] a2 - another array to include in the result array.
7180 * \param [in] offsetA2 - number of tuples of \a a2 to skip.
7181 * \return DataArrayInt * - the new instance of DataArrayInt.
7182 * The caller is to delete this result array using decrRef() as it is no more
7184 * \throw If either \a a1 or \a a2 is NULL.
7185 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
7188 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Aggregate(const DataArrayType *a1, const DataArrayType *a2, T offsetA2)
7191 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
7192 std::size_t nbOfComp(a1->getNumberOfComponents());
7193 if(nbOfComp!=a2->getNumberOfComponents())
7194 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
7195 mcIdType nbOfTuple1(a1->getNumberOfTuples()),nbOfTuple2(a2->getNumberOfTuples());
7196 MCAuto<DataArrayType> ret(DataArrayType::New());
7197 ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
7198 T *pt=std::copy(a1->begin(),a1->end(),ret->getPointer());
7199 std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
7200 ret->copyStringInfoFrom(*a1);
7205 * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
7206 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
7207 * the number of component in the result array is same as that of each of given arrays.
7208 * Info on components is copied from the first of the given arrays. Number of components
7209 * in the given arrays must be the same.
7210 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
7211 * not the object itself.
7212 * \param [in] arr - a sequence of arrays to include in the result array.
7213 * \return DataArrayInt * - the new instance of DataArrayInt.
7214 * The caller is to delete this result array using decrRef() as it is no more
7216 * \throw If all arrays within \a arr are NULL.
7217 * \throw If getNumberOfComponents() of arrays within \a arr.
7220 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Aggregate(const std::vector<const DataArrayType *>& arr)
7222 std::vector<const DataArrayType *> a;
7223 for(typename std::vector<const DataArrayType *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7227 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
7228 typename std::vector<const DataArrayType *>::const_iterator it=a.begin();
7229 std::size_t nbOfComp((*it)->getNumberOfComponents());
7230 mcIdType nbt((*it++)->getNumberOfTuples());
7231 for(;it!=a.end();it++)
7233 if((*it)->getNumberOfComponents()!=nbOfComp)
7234 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
7235 nbt+=(*it)->getNumberOfTuples();
7237 MCAuto<DataArrayType> ret=DataArrayType::New();
7238 ret->alloc(nbt,nbOfComp);
7239 T *pt=ret->getPointer();
7240 for(it=a.begin();it!=a.end();it++)
7241 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
7242 ret->copyStringInfoFrom(*(a[0]));
7247 * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
7248 * A packed index array is an allocated array with one component, and at least one tuple. The first element
7249 * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
7250 * 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.
7252 * \return DataArrayInt * - a new object to be managed by the caller.
7255 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::AggregateIndexes(const std::vector<const DataArrayType *>& arrs)
7258 for(typename std::vector<const DataArrayType *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
7262 (*it4)->checkAllocated();
7263 if((*it4)->getNumberOfComponents()!=1)
7265 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
7266 throw INTERP_KERNEL::Exception(oss.str().c_str());
7268 mcIdType nbTupl((*it4)->getNumberOfTuples());
7271 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
7272 throw INTERP_KERNEL::Exception(oss.str().c_str());
7274 if((*it4)->front()!=0)
7276 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
7277 throw INTERP_KERNEL::Exception(oss.str().c_str());
7283 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
7284 throw INTERP_KERNEL::Exception(oss.str().c_str());
7288 throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
7289 MCAuto<DataArrayType> ret=DataArrayType::New();
7290 ret->alloc(retSz,1);
7291 T *pt=ret->getPointer(); *pt++=0;
7292 for(typename std::vector<const DataArrayType *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
7293 pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind(std::plus<T>(),std::placeholders::_1,pt[-1]));
7294 ret->copyStringInfoFrom(*(arrs[0]));
7299 * Returns a new DataArrayInt which contains all elements of given one-dimensional
7300 * arrays. The result array does not contain any duplicates and its values
7301 * are sorted in ascending order.
7302 * \param [in] arr - sequence of DataArrayInt's to unite.
7303 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7304 * array using decrRef() as it is no more needed.
7305 * \throw If any \a arr[i] is not allocated.
7306 * \throw If \a arr[i]->getNumberOfComponents() != 1.
7309 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::BuildUnion(const std::vector<const DataArrayType *>& arr)
7311 std::vector<const DataArrayType *> a;
7312 for(typename std::vector<const DataArrayType *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7315 for(typename std::vector<const DataArrayType *>::const_iterator it=a.begin();it!=a.end();it++)
7317 (*it)->checkAllocated();
7318 if((*it)->getNumberOfComponents()!=1)
7319 throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
7323 for(typename std::vector<const DataArrayType *>::const_iterator it=a.begin();it!=a.end();it++)
7325 const T *pt=(*it)->getConstPointer();
7326 mcIdType nbOfTuples((*it)->getNumberOfTuples());
7327 r.insert(pt,pt+nbOfTuples);
7329 DataArrayType *ret=DataArrayType::New();
7330 ret->alloc(r.size(),1);
7331 std::copy(r.begin(),r.end(),ret->getPointer());
7336 * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
7337 * arrays. The result array does not contain any duplicates and its values
7338 * are sorted in ascending order.
7339 * \param [in] arr - sequence of DataArrayInt's to intersect.
7340 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7341 * array using decrRef() as it is no more needed.
7342 * \throw If any \a arr[i] is not allocated.
7343 * \throw If \a arr[i]->getNumberOfComponents() != 1.
7346 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::BuildIntersection(const std::vector<const DataArrayType *>& arr)
7348 std::vector<const DataArrayType *> a;
7349 for(typename std::vector<const DataArrayType *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7352 for(typename std::vector<const DataArrayType *>::const_iterator it=a.begin();it!=a.end();it++)
7354 (*it)->checkAllocated();
7355 if((*it)->getNumberOfComponents()!=1)
7356 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
7360 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single not null element in array ! For safety reasons exception is raised !");
7363 for(typename std::vector<const DataArrayType *>::const_iterator it=a.begin();it!=a.end();it++)
7365 const T *pt=(*it)->getConstPointer();
7366 mcIdType nbOfTuples((*it)->getNumberOfTuples());
7367 std::set<T> s1(pt,pt+nbOfTuples);
7371 std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
7377 DataArrayType *ret(DataArrayType::New());
7378 ret->alloc(r.size(),1);
7379 std::copy(r.begin(),r.end(),ret->getPointer());
7384 * This method allows to put a vector of vector of integer into a more compact data structure (skyline).
7385 * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<mcIdType> >.
7387 * \param [in] v the input data structure to be translate into skyline format.
7388 * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
7389 * \param [out] dataIndex the second element of the skyline format.
7392 void DataArrayDiscrete<T>::PutIntoToSkylineFrmt(const std::vector< std::vector<T> >& v, DataArrayType *& data, DataArrayIdType *& dataIndex)
7394 std::size_t sz(v.size());
7395 MCAuto<DataArrayType> retDat(DataArrayType::New());
7396 MCAuto<DataArrayIdType> retIdx(DataArrayIdType::New());
7397 retIdx->alloc(sz+1,1);
7398 mcIdType *ptid(retIdx->getPointer()); *ptid=0;
7399 for(std::size_t i=0;i<sz;i++,ptid++)
7400 ptid[1]=ptid[0]+ToIdType(v[i].size());
7401 retDat->alloc(retIdx->back(),1);
7402 T *pt=retDat->getPointer();
7403 for(std::size_t i=0;i<sz;i++)
7404 pt=std::copy(v[i].begin(),v[i].end(),pt);
7405 data=retDat.retn(); dataIndex=retIdx.retn();
7409 * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn
7410 * (\ref numbering-indirect).
7411 * This method returns the result of the extraction ( specified by a set of ids in [\b idsOfSelectBg , \b idsOfSelectEnd ) ).
7412 * The selection of extraction is done standardly in new2old format.
7413 * This method returns indexed arrays (\ref numbering-indirect) using 2 arrays (arrOut,arrIndexOut).
7415 * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
7416 * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
7417 * \param [in] arrIn arr origin array from which the extraction will be done.
7418 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7419 * \param [out] arrOut the resulting array
7420 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
7421 * \sa DataArrayInt::ExtractFromIndexedArraysSlice
7424 void DataArrayDiscrete<T>::ExtractFromIndexedArrays(const mcIdType *idsOfSelectBg, const mcIdType *idsOfSelectEnd,
7425 const DataArrayType *arrIn, const DataArrayIdType *arrIndxIn,
7426 DataArrayType* &arrOut, DataArrayIdType* &arrIndexOut)
7428 if(!arrIn || !arrIndxIn)
7429 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArrays : input pointer is NULL !");
7430 arrIn->checkAllocated(); arrIndxIn->checkAllocated();
7431 if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1)
7432 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArrays : input arrays must have exactly one component !");
7433 std::size_t sz=std::distance(idsOfSelectBg,idsOfSelectEnd);
7434 const T *arrInPtr=arrIn->begin();
7435 const mcIdType *arrIndxPtr=arrIndxIn->begin();
7436 mcIdType nbOfGrps=arrIndxIn->getNumberOfTuples()-1;
7438 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArrays : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !");
7439 mcIdType maxSizeOfArr(arrIn->getNumberOfTuples());
7440 MCAuto<DataArrayType> arro=DataArrayType::New();
7441 MCAuto<DataArrayIdType> arrIo=DataArrayIdType::New();
7442 arrIo->alloc(sz+1,1);
7443 const mcIdType *idsIt=idsOfSelectBg;
7444 mcIdType *work=arrIo->getPointer();
7447 for(std::size_t i=0;i<sz;i++,work++,idsIt++)
7449 if(*idsIt>=0 && *idsIt<nbOfGrps)
7450 lgth+=arrIndxPtr[*idsIt+1]-arrIndxPtr[*idsIt];
7453 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " ! Must be in [0," << nbOfGrps << ") !";
7454 throw INTERP_KERNEL::Exception(oss.str());
7460 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " and at this pos arrIndxIn[" << *idsIt;
7461 oss << "+1]-arrIndxIn[" << *idsIt << "] < 0 ! The input index array is bugged !";
7462 throw INTERP_KERNEL::Exception(oss.str());
7465 arro->alloc(lgth,1);
7466 T *data=arro->getPointer();
7467 idsIt=idsOfSelectBg;
7468 for(std::size_t i=0;i<sz;i++,idsIt++)
7470 if(arrIndxPtr[*idsIt]>=0 && arrIndxPtr[*idsIt+1]<=maxSizeOfArr)
7471 data=std::copy(arrInPtr+arrIndxPtr[*idsIt],arrInPtr+arrIndxPtr[*idsIt+1],data);
7474 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " arrIndx[" << *idsIt << "] must be >= 0 and arrIndx[";
7475 oss << *idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!";
7476 throw INTERP_KERNEL::Exception(oss.str());
7480 arrIndexOut=arrIo.retn();
7484 * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn
7485 * (\ref numbering-indirect).
7486 * 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 ).
7487 * The selection of extraction is done standardly in new2old format.
7488 * This method returns indexed arrays (\ref numbering-indirect) using 2 arrays (arrOut,arrIndexOut).
7490 * \param [in] idsOfSelectStart begin of set of ids of the input extraction (included)
7491 * \param [in] idsOfSelectStop end of set of ids of the input extraction (excluded)
7492 * \param [in] idsOfSelectStep step of set of ids of the input extraction
7493 * \param [in] arrIn arr origin array from which the extraction will be done.
7494 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7495 * \param [out] arrOut the resulting array
7496 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
7497 * \sa DataArrayInt::ExtractFromIndexedArrays
7500 void DataArrayDiscrete<T>::ExtractFromIndexedArraysSlice(mcIdType idsOfSelectStart, mcIdType idsOfSelectStop, mcIdType idsOfSelectStep,
7501 const DataArrayType *arrIn, const DataArrayIdType *arrIndxIn,
7502 DataArrayType* &arrOut, DataArrayIdType* &arrIndexOut)
7504 if(!arrIn || !arrIndxIn)
7505 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArraysSlice : input pointer is NULL !");
7506 arrIn->checkAllocated(); arrIndxIn->checkAllocated();
7507 if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1)
7508 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArraysSlice : input arrays must have exactly one component !");
7509 mcIdType sz=DataArray::GetNumberOfItemGivenBESRelative(idsOfSelectStart,idsOfSelectStop,idsOfSelectStep,"MEDCouplingUMesh::ExtractFromIndexedArraysSlice : Input slice ");
7510 const T *arrInPtr=arrIn->begin();
7511 const mcIdType *arrIndxPtr=arrIndxIn->begin();
7512 mcIdType nbOfGrps=arrIndxIn->getNumberOfTuples()-1;
7514 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArraysSlice : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !");
7515 mcIdType maxSizeOfArr(arrIn->getNumberOfTuples());
7516 MCAuto<DataArrayType> arro=DataArrayType::New();
7517 MCAuto<DataArrayIdType> arrIo=DataArrayIdType::New();
7518 arrIo->alloc(sz+1,1);
7519 mcIdType idsIt=idsOfSelectStart;
7520 mcIdType *work=arrIo->getPointer();
7523 for(mcIdType i=0;i<sz;i++,work++,idsIt+=idsOfSelectStep)
7525 if(idsIt>=0 && idsIt<nbOfGrps)
7526 lgth+=arrIndxPtr[idsIt+1]-arrIndxPtr[idsIt];
7529 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArraysSlice : id located on pos #" << i << " value is " << idsIt << " ! Must be in [0," << nbOfGrps << ") !";
7530 throw INTERP_KERNEL::Exception(oss.str());
7536 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArraysSlice : id located on pos #" << i << " value is " << idsIt << " and at this pos arrIndxIn[" << idsIt;
7537 oss << "+1]-arrIndxIn[" << idsIt << "] < 0 ! The input index array is bugged !";
7538 throw INTERP_KERNEL::Exception(oss.str());
7541 arro->alloc(lgth,1);
7542 T *data=arro->getPointer();
7543 idsIt=idsOfSelectStart;
7544 for(mcIdType i=0;i<sz;i++,idsIt+=idsOfSelectStep)
7546 if(arrIndxPtr[idsIt]>=0 && arrIndxPtr[idsIt+1]<=maxSizeOfArr)
7547 data=std::copy(arrInPtr+arrIndxPtr[idsIt],arrInPtr+arrIndxPtr[idsIt+1],data);
7550 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArraysSlice : id located on pos #" << i << " value is " << idsIt << " arrIndx[" << idsIt << "] must be >= 0 and arrIndx[";
7551 oss << idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!";
7552 throw INTERP_KERNEL::Exception(oss.str());
7556 arrIndexOut=arrIo.retn();
7560 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
7561 * 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
7562 * cellIds \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex).
7563 * This method is an generalization of MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitly a result output arrays.
7565 * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
7566 * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
7567 * \param [in] arrIn arr origin array from which the extraction will be done.
7568 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7569 * \param [in] srcArr input array that will be used as source of copy for ids in [ \b idsOfSelectBg, \b idsOfSelectEnd )
7570 * \param [in] srcArrIndex index array of \b srcArr
7571 * \param [out] arrOut the resulting array
7572 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
7574 * \sa DataArrayInt::SetPartOfIndexedArraysSameIdx
7577 void DataArrayDiscrete<T>::SetPartOfIndexedArrays(const mcIdType *idsOfSelectBg, const mcIdType *idsOfSelectEnd,
7578 const DataArrayType *arrIn, const DataArrayIdType *arrIndxIn,
7579 const DataArrayType *srcArr, const DataArrayIdType *srcArrIndex,
7580 DataArrayType* &arrOut, DataArrayIdType* &arrIndexOut)
7582 if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
7583 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArrays : presence of null pointer in input parameter !");
7584 MCAuto<DataArrayType> arro=DataArrayType::New();
7585 MCAuto<DataArrayIdType> arrIo=DataArrayIdType::New();
7586 mcIdType nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
7587 std::vector<bool> v(nbOfTuples,true);
7589 const mcIdType *arrIndxInPtr=arrIndxIn->begin();
7590 const mcIdType *srcArrIndexPtr=srcArrIndex->begin();
7591 for(const mcIdType *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++)
7593 if(*it>=0 && *it<nbOfTuples)
7596 offset+=(srcArrIndexPtr[1]-srcArrIndexPtr[0])-(arrIndxInPtr[*it+1]-arrIndxInPtr[*it]);
7600 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArrays : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !";
7601 throw INTERP_KERNEL::Exception(oss.str());
7604 srcArrIndexPtr=srcArrIndex->begin();
7605 arrIo->alloc(nbOfTuples+1,1);
7606 arro->alloc(arrIn->getNumberOfTuples()+offset,1);
7607 const T *arrInPtr=arrIn->begin();
7608 const T *srcArrPtr=srcArr->begin();
7609 mcIdType *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0;
7610 T *arroPtr=arro->getPointer();
7611 for(mcIdType ii=0;ii<nbOfTuples;ii++,arrIoPtr++)
7615 arroPtr=std::copy(arrInPtr+arrIndxInPtr[ii],arrInPtr+arrIndxInPtr[ii+1],arroPtr);
7616 *arrIoPtr=arrIoPtr[-1]+(arrIndxInPtr[ii+1]-arrIndxInPtr[ii]);
7620 std::size_t pos=std::distance(idsOfSelectBg,std::find(idsOfSelectBg,idsOfSelectEnd,ii));
7621 arroPtr=std::copy(srcArrPtr+srcArrIndexPtr[pos],srcArrPtr+srcArrIndexPtr[pos+1],arroPtr);
7622 *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]);
7626 arrIndexOut=arrIo.retn();
7630 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
7631 * 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
7632 * cellIds \b in [\b idsOfSelectBg, \b idsOfSelectEnd) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex).
7633 * This method is an generalization of DataArrayInt::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitly a result output arrays.
7635 * \param [in] start begin of set of ids of the input extraction (included)
7636 * \param [in] end end of set of ids of the input extraction (excluded)
7637 * \param [in] step step of the set of ids in range mode.
7638 * \param [in] arrIn arr origin array from which the extraction will be done.
7639 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7640 * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd)
7641 * \param [in] srcArrIndex index array of \b srcArr
7642 * \param [out] arrOut the resulting array
7643 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
7645 * \sa DataArrayInt::SetPartOfIndexedArraysSameIdx DataArrayInt::SetPartOfIndexedArrays
7648 void DataArrayDiscrete<T>::SetPartOfIndexedArraysSlice(mcIdType start, mcIdType end, mcIdType step,
7649 const DataArrayType *arrIn, const DataArrayIdType *arrIndxIn,
7650 const DataArrayType *srcArr, const DataArrayIdType *srcArrIndex,
7651 DataArrayType* &arrOut, DataArrayIdType* &arrIndexOut)
7653 if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
7654 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArraysSlice : presence of null pointer in input parameter !");
7655 MCAuto<DataArrayType> arro=DataArrayType::New();
7656 MCAuto<DataArrayIdType> arrIo=DataArrayIdType::New();
7657 mcIdType nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
7659 const mcIdType *arrIndxInPtr=arrIndxIn->begin();
7660 const mcIdType *srcArrIndexPtr=srcArrIndex->begin();
7661 mcIdType nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"DataArrayInt::SetPartOfIndexedArraysSlice : ");
7663 for(mcIdType i=0;i<nbOfElemsToSet;i++,srcArrIndexPtr++,it+=step)
7665 if(it>=0 && it<nbOfTuples)
7666 offset+=(srcArrIndexPtr[1]-srcArrIndexPtr[0])-(arrIndxInPtr[it+1]-arrIndxInPtr[it]);
7669 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSlice : On pos #" << i << " value is " << it << " not in [0," << nbOfTuples << ") !";
7670 throw INTERP_KERNEL::Exception(oss.str());
7673 srcArrIndexPtr=srcArrIndex->begin();
7674 arrIo->alloc(nbOfTuples+1,1);
7675 arro->alloc(arrIn->getNumberOfTuples()+offset,1);
7676 const T *arrInPtr=arrIn->begin();
7677 const T *srcArrPtr=srcArr->begin();
7678 mcIdType *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0;
7679 T *arroPtr=arro->getPointer();
7680 for(mcIdType ii=0;ii<nbOfTuples;ii++,arrIoPtr++)
7682 mcIdType pos=DataArray::GetPosOfItemGivenBESRelativeNoThrow(ii,start,end,step);
7685 arroPtr=std::copy(arrInPtr+arrIndxInPtr[ii],arrInPtr+arrIndxInPtr[ii+1],arroPtr);
7686 *arrIoPtr=arrIoPtr[-1]+(arrIndxInPtr[ii+1]-arrIndxInPtr[ii]);
7690 arroPtr=std::copy(srcArrPtr+srcArrIndexPtr[pos],srcArrPtr+srcArrIndexPtr[pos+1],arroPtr);
7691 *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]);
7695 arrIndexOut=arrIo.retn();
7699 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
7700 * This method is an specialization of MEDCouplingUMesh::SetPartOfIndexedArrays in the case of assignment do not modify the index in \b arrIndxIn.
7702 * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
7703 * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
7704 * \param [in,out] arrInOut arr origin array from which the extraction will be done.
7705 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7706 * \param [in] srcArr input array that will be used as source of copy for ids in [ \b idsOfSelectBg , \b idsOfSelectEnd )
7707 * \param [in] srcArrIndex index array of \b srcArr
7709 * \sa DataArrayInt::SetPartOfIndexedArrays
7712 void DataArrayDiscrete<T>::SetPartOfIndexedArraysSameIdx(const mcIdType *idsOfSelectBg, const mcIdType *idsOfSelectEnd,
7713 DataArrayType *arrInOut, const DataArrayIdType *arrIndxIn,
7714 const DataArrayType *srcArr, const DataArrayIdType *srcArrIndex)
7716 if(arrInOut==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
7717 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArraysSameIdx : presence of null pointer in input parameter !");
7718 mcIdType nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
7719 const mcIdType *arrIndxInPtr=arrIndxIn->begin();
7720 const mcIdType *srcArrIndexPtr=srcArrIndex->begin();
7721 T *arrInOutPtr=arrInOut->getPointer();
7722 const T *srcArrPtr=srcArr->begin();
7723 for(const mcIdType *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++)
7725 if(*it>=0 && *it<nbOfTuples)
7727 if(srcArrIndexPtr[1]-srcArrIndexPtr[0]==arrIndxInPtr[*it+1]-arrIndxInPtr[*it])
7728 std::copy(srcArrPtr+srcArrIndexPtr[0],srcArrPtr+srcArrIndexPtr[1],arrInOutPtr+arrIndxInPtr[*it]);
7731 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] !";
7732 throw INTERP_KERNEL::Exception(oss.str());
7737 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSameIdx : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !";
7738 throw INTERP_KERNEL::Exception(oss.str());
7744 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
7745 * This method is an specialization of MEDCouplingUMesh::SetPartOfIndexedArrays in the case of assignment do not modify the index in \b arrIndxIn.
7747 * \param [in] start begin of set of ids of the input extraction (included)
7748 * \param [in] end end of set of ids of the input extraction (excluded)
7749 * \param [in] step step of the set of ids in range mode.
7750 * \param [in,out] arrInOut arr origin array from which the extraction will be done.
7751 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
7752 * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd)
7753 * \param [in] srcArrIndex index array of \b srcArr
7755 * \sa DataArrayInt::SetPartOfIndexedArraysSlice DataArrayInt::SetPartOfIndexedArraysSameIdx
7758 void DataArrayDiscrete<T>::SetPartOfIndexedArraysSameIdxSlice(mcIdType start, mcIdType end, mcIdType step,
7759 DataArrayType *arrInOut, const DataArrayIdType *arrIndxIn,
7760 const DataArrayType *srcArr, const DataArrayIdType *srcArrIndex)
7762 if(arrInOut==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
7763 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : presence of null pointer in input parameter !");
7764 mcIdType nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
7765 const mcIdType *arrIndxInPtr=arrIndxIn->begin();
7766 const mcIdType *srcArrIndexPtr=srcArrIndex->begin();
7767 T *arrInOutPtr=arrInOut->getPointer();
7768 const T *srcArrPtr=srcArr->begin();
7769 mcIdType nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : ");
7771 for(mcIdType i=0;i<nbOfElemsToSet;i++,srcArrIndexPtr++,it+=step)
7773 if(it>=0 && it<nbOfTuples)
7775 if(srcArrIndexPtr[1]-srcArrIndexPtr[0]==arrIndxInPtr[it+1]-arrIndxInPtr[it])
7776 std::copy(srcArrPtr+srcArrIndexPtr[0],srcArrPtr+srcArrIndexPtr[1],arrInOutPtr+arrIndxInPtr[it]);
7779 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : On pos #" << i << " id (idsOfSelectBg[" << i << "]) is " << it << " arrIndxIn[id+1]-arrIndxIn[id]!=srcArrIndex[pos+1]-srcArrIndex[pos] !";
7780 throw INTERP_KERNEL::Exception(oss.str());
7785 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : On pos #" << i << " value is " << it << " not in [0," << nbOfTuples << ") !";
7786 throw INTERP_KERNEL::Exception(oss.str());
7792 * This method works on an input pair (\b arr, \b arrIndx) where \b arr indexes is in \b arrIndx.
7793 * 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.
7795 * \param [in] idsToRemoveBg begin of set of ids to remove in \b arr (included)
7796 * \param [in] idsToRemoveEnd end of set of ids to remove in \b arr (excluded)
7797 * \param [in,out] arr array in which the remove operation will be done.
7798 * \param [in,out] arrIndx array in the remove operation will modify
7799 * \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])
7800 * \return true if \b arr and \b arrIndx have been modified, false if not.
7803 bool DataArrayDiscrete<T>::RemoveIdsFromIndexedArrays(const T *idsToRemoveBg, const T *idsToRemoveEnd,
7804 DataArrayType *arr, DataArrayIdType *arrIndx, mcIdType offsetForRemoval)
7806 if(!arrIndx || !arr)
7807 throw INTERP_KERNEL::Exception("DataArrayInt::RemoveIdsFromIndexedArrays : some input arrays are empty !");
7808 if(offsetForRemoval<0)
7809 throw INTERP_KERNEL::Exception("DataArrayInt::RemoveIdsFromIndexedArrays : offsetForRemoval should be >=0 !");
7810 std::set<T> s(idsToRemoveBg,idsToRemoveEnd);
7811 mcIdType nbOfGrps=arrIndx->getNumberOfTuples()-1;
7812 mcIdType *arrIPtr=arrIndx->getPointer();
7814 mcIdType previousArrI=0;
7815 const T *arrPtr=arr->begin();
7816 std::vector<T> arrOut;//no utility to switch to DataArrayInt because copy always needed
7817 for(mcIdType i=0;i<nbOfGrps;i++,arrIPtr++)
7819 if(*arrIPtr-previousArrI>offsetForRemoval)
7821 for(const T *work=arrPtr+previousArrI+offsetForRemoval;work!=arrPtr+*arrIPtr;work++)
7823 if(s.find(*work)==s.end())
7824 arrOut.push_back(*work);
7827 previousArrI=*arrIPtr;
7828 *arrIPtr=ToIdType(arrOut.size());
7830 if(arr->getNumberOfTuples()==ToIdType(arrOut.size()))
7832 arr->alloc(arrOut.size(),1);
7833 std::copy(arrOut.begin(),arrOut.end(),arr->getPointer());
7838 * Returns a new DataArrayInt containing an arithmetic progression
7839 * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step )
7841 * \param [in] begin - the start value of the result sequence.
7842 * \param [in] end - limiting value, so that every value of the result array is less than
7844 * \param [in] step - specifies the increment or decrement.
7845 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7846 * array using decrRef() as it is no more needed.
7847 * \throw If \a step == 0.
7848 * \throw If \a end < \a begin && \a step > 0.
7849 * \throw If \a end > \a begin && \a step < 0.
7852 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::Range(T begin, T end, T step)
7854 mcIdType nbOfTuples=DataArrayTools<T>::GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
7855 MCAuto<DataArrayType> ret=DataArrayType::New();
7856 ret->alloc(nbOfTuples,1);
7857 T *ptr=ret->getPointer();
7860 for(T i=begin;i<end;i+=step,ptr++)
7865 for(T i=begin;i>end;i+=step,ptr++)
7872 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7873 * from a zip representation of a surjective format (returned e.g. by
7874 * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7875 * for example). The result array minimizes the permutation. <br>
7876 * For more info on renumbering see \ref numbering. <br>
7878 * - \a nbOfOldTuples: 10
7879 * - \a arr : [0,3, 5,7,9]
7880 * - \a arrIBg : [0,2,5]
7881 * - \a newNbOfTuples: 7
7882 * - result array : [0,1,2,0,3,4,5,4,6,4]
7884 * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7885 * \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7886 * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7887 * (indices of) equal values. Its every element (except the last one) points to
7888 * the first element of a group of equal values.
7889 * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7890 * arrIBg is \a arrIEnd[ -1 ].
7891 * \param [out] newNbOfTuples - number of tuples after surjection application.
7892 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7893 * array using decrRef() as it is no more needed.
7894 * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7897 DataArrayIdType *DataArrayDiscrete<T>::ConvertIndexArrayToO2N(mcIdType nbOfOldTuples, const mcIdType *arr, const mcIdType *arrIBg, const mcIdType *arrIEnd, mcIdType &newNbOfTuples)
7899 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
7900 ret->alloc(nbOfOldTuples,1);
7901 mcIdType *pt=ret->getPointer();
7902 std::fill(pt,pt+nbOfOldTuples,-1);
7903 mcIdType nbOfGrps=ToIdType(std::distance(arrIBg,arrIEnd))-1;
7904 const mcIdType *cIPtr=arrIBg;
7905 for(mcIdType i=0;i<nbOfGrps;i++)
7906 pt[arr[cIPtr[i]]]=-(i+2);
7908 for(mcIdType iNode=0;iNode<nbOfOldTuples;iNode++)
7916 mcIdType grpId=-(pt[iNode]+2);
7917 for(mcIdType j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7919 if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7923 std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7924 throw INTERP_KERNEL::Exception(oss.str().c_str());
7931 newNbOfTuples=newNb;
7936 * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
7937 * The i-th item of the result array is an ID of a set of elements belonging to a
7938 * unique set of groups, which the i-th element is a part of. This set of elements
7939 * belonging to a unique set of groups is called \a family, so the result array contains
7940 * IDs of families each element belongs to.
7942 * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
7943 * then there are 3 families:
7944 * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
7945 * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
7946 * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
7947 * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
7948 * stands for the element #3 which is in none of groups.
7950 * \param [in] groups - sequence of groups of element IDs.
7951 * \param [in] newNb - total number of elements; it must be more than max ID of element
7953 * \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
7954 * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
7955 * each element with ID from range [0, \a newNb ) belongs to. The caller is to
7956 * delete this array using decrRef() as it is no more needed.
7957 * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
7960 DataArrayIdType *DataArrayDiscrete<T>::MakePartition(const std::vector<const DataArrayType *>& groups, mcIdType newNb, std::vector< std::vector<mcIdType> >& fidsOfGroups)
7962 std::vector<const DataArrayType *> groups2;
7963 for(typename std::vector<const DataArrayType *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
7965 groups2.push_back(*it4);
7966 MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
7967 ret->alloc(newNb,1);
7968 mcIdType *retPtr=ret->getPointer();
7969 std::fill(retPtr,retPtr+newNb,0);
7971 for(typename std::vector<const DataArrayType *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
7973 const T *ptr=(*iter)->getConstPointer();
7974 std::size_t nbOfElem=(*iter)->getNbOfElems();
7976 for(mcIdType j=0;j<sfid;j++)
7979 for(std::size_t i=0;i<nbOfElem;i++)
7981 if(ptr[i]>=0 && ptr[i]<newNb)
7983 if(retPtr[ptr[i]]==j)
7991 std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
7993 throw INTERP_KERNEL::Exception(oss.str().c_str());
8000 fidsOfGroups.clear();
8001 fidsOfGroups.resize(groups2.size());
8003 for(typename std::vector<const DataArrayType *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
8005 std::set<mcIdType> tmp;
8006 const T *ptr=(*iter)->getConstPointer();
8007 std::size_t nbOfElem=(*iter)->getNbOfElems();
8008 for(const T *p=ptr;p!=ptr+nbOfElem;p++)
8009 tmp.insert(retPtr[*p]);
8010 fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
8018 namespace MEDCouplingImpl
8024 OpSwitchedOn(T *pt):_pt(pt),_cnt(0) { }
8025 void operator()(const bool& b) { if(b) *_pt++=FromIdType<T>(_cnt); _cnt++; }
8028 MEDCoupling::mcIdType _cnt;
8035 OpSwitchedOff(T *pt):_pt(pt),_cnt(0) { }
8036 void operator()(const bool& b) { if(!b) *_pt++=FromIdType<T>(_cnt); _cnt++; }
8039 MEDCoupling::mcIdType _cnt;
8044 namespace MEDCoupling
8047 * This method returns the list of ids in ascending mode so that v[id]==true.
8050 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::BuildListOfSwitchedOn(const std::vector<bool>& v)
8052 std::size_t sz(std::count(v.begin(),v.end(),true));
8053 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(sz,1);
8054 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn<T>(ret->getPointer()));
8059 * This method returns the list of ids in ascending mode so that v[id]==false.
8062 typename Traits<T>::ArrayType *DataArrayDiscrete<T>::BuildListOfSwitchedOff(const std::vector<bool>& v)
8064 std::size_t sz(std::count(v.begin(),v.end(),false));
8065 MCAuto<DataArrayType> ret(DataArrayType::New()); ret->alloc(sz,1);
8066 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff<T>(ret->getPointer()));
8071 namespace MEDCoupling
8074 * This method compares content of input vector \a v and \a this.
8075 * 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.
8076 * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
8078 * \param [in] v - the vector of 'flags' to be compared with \a this.
8080 * \throw If \a this is not sorted ascendingly.
8081 * \throw If \a this has not exactly one component.
8082 * \throw If \a this is not allocated.
8085 bool DataArrayDiscreteSigned<T>::isFittingWith(const std::vector<bool>& v) const
8087 this->checkAllocated();
8088 if(this->getNumberOfComponents()!=1)
8089 throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
8090 const T *w(this->begin()),*end2(this->end());
8091 T refVal=-std::numeric_limits<T>::max();
8093 std::vector<bool>::const_iterator it(v.begin());
8094 for(;it!=v.end();it++,i++)
8106 std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(this->begin(),w-1) << " this is not sorted ascendingly !";
8107 throw INTERP_KERNEL::Exception(oss.str().c_str());