- * \throw If \a this or \a other is not allocated.
- * \throw If \a this->getNumberOfComponents() != 1.
- * \throw If \a other->getNumberOfComponents() != 1.
- */
-DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
-{
- std::vector<const DataArrayInt *>arrs(2);
- arrs[0]=this; arrs[1]=other;
- return BuildIntersection(arrs);
-}
-
-/*!
- * This method can be applied on allocated with one component DataArrayInt instance.
- * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
- * 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]
- *
- * \return a newly allocated array that contain the result of the unique operation applied on \a this.
- * \throw if \a this is not allocated or if \a this has not exactly one component.
- * \sa DataArrayInt::buildUniqueNotSorted
- */
-DataArrayInt *DataArrayInt::buildUnique() const
-{
- checkAllocated();
- if(getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
- int nbOfTuples=getNumberOfTuples();
- MCAuto<DataArrayInt> tmp=deepCopy();
- int *data=tmp->getPointer();
- int *last=std::unique(data,data+nbOfTuples);
- MCAuto<DataArrayInt> ret=DataArrayInt::New();
- ret->alloc(std::distance(data,last),1);
- std::copy(data,last,ret->getPointer());
- return ret.retn();
-}
-
-/*!
- * This method can be applied on allocated with one component DataArrayInt instance.
- * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
- *
- * \return a newly allocated array that contain the result of the unique operation applied on \a this.
- *
- * \throw if \a this is not allocated or if \a this has not exactly one component.
- *
- * \sa DataArrayInt::buildUnique
- */
-DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
-{
- checkAllocated();
- if(getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
- int minVal,maxVal;
- getMinMaxValues(minVal,maxVal);
- std::vector<bool> b(maxVal-minVal+1,false);
- const int *ptBg(begin()),*endBg(end());
- MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
- for(const int *pt=ptBg;pt!=endBg;pt++)
- {
- if(!b[*pt-minVal])
- {
- ret->pushBackSilent(*pt);
- b[*pt-minVal]=true;
- }
- }
- ret->copyStringInfoFrom(*this);
- return ret.retn();
-}
-
-/*!
- * Returns a new DataArrayInt which contains size of every of groups described by \a this
- * "index" array. Such "index" array is returned for example by
- * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
- * "MEDCouplingUMesh::buildDescendingConnectivity" and
- * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
- * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
- * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
- * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
- * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
- * The caller is to delete this array using decrRef() as it is no more needed.
- * \throw If \a this is not allocated.
- * \throw If \a this->getNumberOfComponents() != 1.
- * \throw If \a this->getNumberOfTuples() < 2.
- *
- * \b Example: <br>
- * - this contains [1,3,6,7,7,9,15]
- * - result array contains [2,3,1,0,2,6],
- * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
- *
- * \sa DataArrayInt::computeOffsetsFull
- */
-DataArrayInt *DataArrayInt::deltaShiftIndex() const
-{
- checkAllocated();
- if(getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
- int nbOfTuples=getNumberOfTuples();
- if(nbOfTuples<2)
- throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
- const int *ptr=getConstPointer();
- DataArrayInt *ret=DataArrayInt::New();
- ret->alloc(nbOfTuples-1,1);
- int *out=ret->getPointer();
- std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
- return ret;
-}
-
-/*!
- * Modifies \a this one-dimensional array so that value of each element \a x
- * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
- * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
- * and components remains the same.<br>
- * This method is useful for allToAllV in MPI with contiguous policy. This method
- * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
- * this one.
- * \throw If \a this is not allocated.
- * \throw If \a this->getNumberOfComponents() != 1.
- *
- * \b Example: <br>
- * - Before \a this contains [3,5,1,2,0,8]
- * - After \a this contains [0,3,8,9,11,11]<br>
- * Note that the last element 19 = 11 + 8 is missing because size of \a this
- * array is retained and thus there is no space to store the last element.
- */
-void DataArrayInt::computeOffsets()
-{
- checkAllocated();
- if(getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
- int nbOfTuples=getNumberOfTuples();
- if(nbOfTuples==0)
- return ;
- int *work=getPointer();
- int tmp=work[0];
- work[0]=0;
- for(int i=1;i<nbOfTuples;i++)
- {
- int tmp2=work[i];
- work[i]=work[i-1]+tmp;
- tmp=tmp2;
- }
- declareAsNew();
-}
-
-
-/*!
- * Modifies \a this one-dimensional array so that value of each element \a x
- * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
- * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
- * components remains the same and number of tuples is inceamented by one.<br>
- * This method is useful for allToAllV in MPI with contiguous policy. This method
- * differs from computeOffsets() in that the number of tuples is changed by this one.
- * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
- * \throw If \a this is not allocated.
- * \throw If \a this->getNumberOfComponents() != 1.
- *
- * \b Example: <br>
- * - Before \a this contains [3,5,1,2,0,8]
- * - After \a this contains [0,3,8,9,11,11,19]<br>
- * \sa DataArrayInt::deltaShiftIndex
- */
-void DataArrayInt::computeOffsetsFull()
-{
- checkAllocated();
- if(getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
- int nbOfTuples=getNumberOfTuples();
- int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
- const int *work=getConstPointer();
- ret[0]=0;
- for(int i=0;i<nbOfTuples;i++)
- ret[i+1]=work[i]+ret[i];
- useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
- declareAsNew();
-}
-
-/*!
- * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
- * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
- * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
- * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
- * filling completely one of the ranges in \a this.
- *
- * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
- * \param [out] rangeIdsFetched the range ids fetched
- * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
- * \a idsInInputListThatFetch is a part of input \a listOfIds.
- *
- * \sa DataArrayInt::computeOffsetsFull
- *
- * \b Example: <br>
- * - \a this : [0,3,7,9,15,18]
- * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
- * - \a rangeIdsFetched result array: [0,2,4]
- * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
- * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
- * <br>
- */
-void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
-{
- if(!listOfIds)
- throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
- listOfIds->checkAllocated(); checkAllocated();
- if(listOfIds->getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
- if(getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
- MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
- MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
- const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
- const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
- while(tupPtr!=tupEnd && offPtr!=offEnd)
- {
- if(*tupPtr==*offPtr)
- {
- int i=offPtr[0];
- while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
- if(i==offPtr[1])
- {
- ret0->pushBackSilent((int)std::distance(offBg,offPtr));
- ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
- offPtr++;
- }
- }
- else
- { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
- }
- rangeIdsFetched=ret0.retn();
- idsInInputListThatFetch=ret1.retn();
-}
-
-/*!
- * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
- * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
- * "index" array of a "iota" array, thus, whose each element gives an index of a group
- * beginning within the "iota" array. And \a this is a one-dimensional array
- * considered as a selector of groups described by \a offsets to include into the result array.
- * \throw If \a offsets is NULL.
- * \throw If \a offsets is not allocated.
- * \throw If \a offsets->getNumberOfComponents() != 1.
- * \throw If \a offsets is not monotonically increasing.
- * \throw If \a this is not allocated.
- * \throw If \a this->getNumberOfComponents() != 1.
- * \throw If any element of \a this is not a valid index for \a offsets array.
- *
- * \b Example: <br>
- * - \a this: [0,2,3]
- * - \a offsets: [0,3,6,10,14,20]
- * - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
- * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
- * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) +
- * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) +
- * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
- */
-DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
-{
- if(!offsets)
- throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
- checkAllocated();
- if(getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
- offsets->checkAllocated();
- if(offsets->getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
- int othNbTuples=offsets->getNumberOfTuples()-1;
- int nbOfTuples=getNumberOfTuples();
- int retNbOftuples=0;
- const int *work=getConstPointer();
- const int *offPtr=offsets->getConstPointer();
- for(int i=0;i<nbOfTuples;i++)
- {
- int val=work[i];
- if(val>=0 && val<othNbTuples)
- {
- int delta=offPtr[val+1]-offPtr[val];
- if(delta>=0)
- retNbOftuples+=delta;
- else
- {
- std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
- throw INTERP_KERNEL::Exception(oss.str().c_str());
- }
- }
- else
- {
- std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
- oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
- throw INTERP_KERNEL::Exception(oss.str().c_str());
- }
- }
- MCAuto<DataArrayInt> ret=DataArrayInt::New();
- ret->alloc(retNbOftuples,1);
- int *retPtr=ret->getPointer();
- for(int i=0;i<nbOfTuples;i++)
- {
- int val=work[i];
- int start=offPtr[val];
- int off=offPtr[val+1]-start;
- for(int j=0;j<off;j++,retPtr++)
- *retPtr=start+j;
- }
- return ret.retn();
-}
-
-/*!
- * Returns a new DataArrayInt whose contents is computed using \a this that must be a
- * scaled array (monotonically increasing).
-from that of \a this and \a
- * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
- * "index" array of a "iota" array, thus, whose each element gives an index of a group
- * beginning within the "iota" array. And \a this is a one-dimensional array
- * considered as a selector of groups described by \a offsets to include into the result array.
- * \throw If \a is NULL.
- * \throw If \a this is not allocated.
- * \throw If \a this->getNumberOfComponents() != 1.
- * \throw If \a this->getNumberOfTuples() == 0.
- * \throw If \a this is not monotonically increasing.
- * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
- *
- * \b Example: <br>
- * - \a bg , \a stop and \a step : (0,5,2)
- * - \a this: [0,3,6,10,14,20]
- * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
- */
-DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
-{
- if(!isAllocated())
- throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
- if(getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
- int nbOfTuples(getNumberOfTuples());
- if(nbOfTuples==0)
- throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
- const int *ids(begin());
- int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
- for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
- {
- if(pos>=0 && pos<nbOfTuples-1)
- {
- int delta(ids[pos+1]-ids[pos]);
- sz+=delta;
- if(delta<0)
- {
- std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
- throw INTERP_KERNEL::Exception(oss.str().c_str());
- }
- }
- else
- {
- std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";
- throw INTERP_KERNEL::Exception(oss.str().c_str());
- }
- }
- MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
- int *retPtr(ret->getPointer());
- pos=bg;
- for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
- {
- int delta(ids[pos+1]-ids[pos]);
- for(int j=0;j<delta;j++,retPtr++)
- *retPtr=pos;
- }
- return ret.retn();