X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingMemArray.cxx;h=566c0797687b55bd7ccf6a474920ee22e46d64ec;hb=cefc68f71bbdf67780083bfb364c14b542f3df18;hp=52b1788ad65692f3a2b2f6025462f9e25a629509;hpb=4ad5cbc849666c76b440b3541e1a7684466b8955;p=tools%2Fmedcoupling.git diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 52b1788ad..566c07976 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -16,7 +16,7 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// Author : Anthony Geay (CEA/DEN) +// Author : Anthony Geay (EDF R&D) #include "MEDCouplingMemArray.txx" @@ -45,6 +45,8 @@ template class MEDCoupling::DataArrayTemplateClassic; template class MEDCoupling::DataArrayTemplateFP; template class MEDCoupling::DataArrayIterator; template class MEDCoupling::DataArrayIterator; +template class MEDCoupling::DataArrayDiscrete; +template class MEDCoupling::DataArrayDiscreteSigned; template void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const @@ -807,28 +809,6 @@ DataArrayDouble *DataArrayDouble::deepCopy() const return new DataArrayDouble(*this); } -/*! - * Returns either a \a deep or \a shallow copy of this array. For more info see - * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow. - * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one. - * \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy - * == \a true) or \a this instance (if \a dCpy == \a false). - */ -DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const -{ - return DataArrayTemplateClassic::PerformCopyOrIncrRef(dCpy,*this); -} - -/*! - * Assign zero to all values in \a this array. To know more on filling arrays see - * \ref MEDCouplingArrayFill. - * \throw If \a this is not allocated. - */ -void DataArrayDouble::fillWithZero() -{ - fillWithValue(0.); -} - /*! * Checks that \a this array is consistently **increasing** or **decreasing** in value, * with at least absolute difference value of |\a eps| at each step. @@ -1123,85 +1103,6 @@ bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, return _mem.isEqual(other._mem,prec,tmp); } -/*! - * Returns a new DataArrayDouble holding the same values as \a this array but differently - * arranged in memory. If \a this array holds 2 components of 3 values: - * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged - * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$. - * \warning Do not confuse this method with transpose()! - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - */ -DataArrayDouble *DataArrayDouble::fromNoInterlace() const -{ - if(_mem.isNull()) - throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !"); - double *tab=_mem.fromNoInterlace(getNumberOfComponents()); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); - return ret; -} - -/*! - * Returns a new DataArrayDouble holding the same values as \a this array but differently - * arranged in memory. If \a this array holds 2 components of 3 values: - * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged - * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$. - * \warning Do not confuse this method with transpose()! - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - */ -DataArrayDouble *DataArrayDouble::toNoInterlace() const -{ - if(_mem.isNull()) - throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !"); - double *tab=_mem.toNoInterlace(getNumberOfComponents()); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); - return ret; -} - -/*! - * Appends components of another array to components of \a this one, tuple by tuple. - * So that the number of tuples of \a this array remains the same and the number of - * components increases. - * \param [in] other - the DataArrayDouble to append to \a this one. - * \throw If \a this is not allocated. - * \throw If \a this and \a other arrays have different number of tuples. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example". - * - * \ref py_mcdataarraydouble_meldwith "Here is a Python example". - * \endif - */ -void DataArrayDouble::meldWith(const DataArrayDouble *other) -{ - checkAllocated(); - other->checkAllocated(); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples!=other->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !"); - int nbOfComp1=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double)); - double *w=newArr; - const double *inp1=getConstPointer(); - const double *inp2=other->getConstPointer(); - for(int i=0;i compIds(nbOfComp2); - for(int i=0;igetNumberOfTuples. - * \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. - */ -DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !"); - if(nbTimes<1) - throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !"); - int nbTuples=getNumberOfTuples(); - const double *inPtr=getConstPointer(); - MCAuto ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1); - double *retPtr=ret->getPointer(); - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - /*! * This methods returns the minimal distance between the two set of points \a this and \a other. * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown. @@ -1532,27 +1405,6 @@ void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std: nc[nbOfCompo*i+compoIds[j]]=*ac; } -void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet) -{ - if(newArray!=arrayToSet) - { - if(arrayToSet) - arrayToSet->decrRef(); - arrayToSet=newArray; - if(arrayToSet) - arrayToSet->incrRef(); - } -} - -void DataArrayDouble::aggregate(const DataArrayDouble *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !"); - if(getNumberOfComponents()!=other->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !"); - _mem.insertAtTheEnd(other->begin(),other->end()); -} - /*! * Checks if 0.0 value is present in \a this array. If it is the case, an exception * is thrown. @@ -2543,28 +2395,6 @@ DataArrayDouble *DataArrayDouble::magnitude() const return ret; } -/*! - * Computes for each tuple the sum of number of components values in the tuple and return it. - * - * \return DataArrayDouble * - the new instance of DataArrayDouble containing the - * same number of tuples as \a this array and one component. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If \a this is not allocated. - */ -DataArrayDouble *DataArrayDouble::sumPerTuple() const -{ - checkAllocated(); - int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples()); - MCAuto ret(DataArrayDouble::New()); - ret->alloc(nbOfTuple,1); - const double *src(getConstPointer()); - double *dest(ret->getPointer()); - for(int i=0;i(fabs)); - declareAsNew(); -} - -/*! - * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this. - * This method is a const method (that do not change any values in \a this) contrary to DataArrayDouble::abs method. - * - * \return DataArrayDouble * - the new instance of DataArrayDouble containing the - * same number of tuples and component as \a this array. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If \a this is not allocated. - * \sa DataArrayDouble::abs - */ -DataArrayDouble *DataArrayDouble::computeAbs() const -{ - checkAllocated(); - DataArrayDouble *newArr(DataArrayDouble::New()); - int nbOfTuples(getNumberOfTuples()); - int nbOfComp(getNumberOfComponents()); - newArr->alloc(nbOfTuples,nbOfComp); - std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun(fabs)); - newArr->copyStringInfoFrom(*this); - return newArr; -} - /*! * Modify all elements of \a this array, so that * an element _x_ becomes \f$ numerator / x \f$. @@ -3384,85 +3174,6 @@ DataArrayDouble *DataArrayDouble::Aggregate(const std::vectorgetNumberOfTuples() != \a a2->getNumberOfTuples() - */ -DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) -{ - std::vector arr(2); - arr[0]=a1; arr[1]=a2; - return Meld(arr); -} - -/*! - * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number - * of components in the result array is a sum of the number of components of given arrays - * and (2) the number of tuples in the result array is same as that of each of given - * arrays. In other words the i-th tuple of result array includes all components of - * i-th tuples of all given arrays. - * Number of tuples in the given arrays must be the same. - * \param [in] arr - a sequence of arrays to include in the result array. - * \return DataArrayDouble * - the new instance of DataArrayDouble. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If all arrays within \a arr are NULL. - * \throw If any given array is not allocated. - * \throw If getNumberOfTuples() of arrays within \a arr is different. - */ -DataArrayDouble *DataArrayDouble::Meld(const std::vector& arr) -{ - std::vector a; - for(std::vector::const_iterator it4=arr.begin();it4!=arr.end();it4++) - if(*it4) - a.push_back(*it4); - if(a.empty()) - throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !"); - std::vector::const_iterator it; - for(it=a.begin();it!=a.end();it++) - (*it)->checkAllocated(); - it=a.begin(); - int nbOfTuples=(*it)->getNumberOfTuples(); - std::vector nbc(a.size()); - std::vector pts(a.size()); - nbc[0]=(*it)->getNumberOfComponents(); - pts[0]=(*it++)->getConstPointer(); - for(int i=1;it!=a.end();it++,i++) - { - if(nbOfTuples!=(*it)->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !"); - nbc[i]=(*it)->getNumberOfComponents(); - pts[i]=(*it)->getConstPointer(); - } - int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(nbOfTuples,totalNbOfComp); - double *retPtr=ret->getPointer(); - for(int i=0;isetInfoOnComponent(k,a[i]->getInfoOnComponent(j)); - return ret; -} - /*! * Returns a new DataArrayDouble containing a dot product of two given arrays, so that * the i-th tuple of the result array is a sum of products of j-th components of i-th @@ -3999,50 +3710,9 @@ int DataArrayInt::getHashCode() const * \ref MEDCouplingArrayBasicsCopyDeep. * \return DataArrayInt * - a new instance of DataArrayInt. */ -DataArrayInt *DataArrayInt::deepCopy() const -{ - return new DataArrayInt(*this); -} - -/*! - * Returns either a \a deep or \a shallow copy of this array. For more info see - * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow. - * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one. - * \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy - * == \a true) or \a this instance (if \a dCpy == \a false). - */ -DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const -{ - return DataArrayTemplateClassic::PerformCopyOrIncrRef(dCpy,*this); -} - -/*! - * Assign zero to all values in \a this array. To know more on filling arrays see - * \ref MEDCouplingArrayFill. - * \throw If \a this is not allocated. - */ -void DataArrayInt::fillWithZero() -{ - fillWithValue(0); -} - -/*! - * Set all values in \a this array so that the i-th element equals to \a init + i - * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill. - * \param [in] init - value to assign to the first element of array. - * \throw If \a this->getNumberOfComponents() != 1 - * \throw If \a this is not allocated. - */ -void DataArrayInt::iota(int init) +DataArrayInt32 *DataArrayInt32::deepCopy() const { - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !"); - int *ptr=getPointer(); - int ntuples=getNumberOfTuples(); - for(int i=0;igetNumberOfComponents() != 1 - * \throw If any value of \a this can't be used as a valid index for - * [\a indArrBg, \a indArrEnd). - * - * \sa changeValue - */ -void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !"); - int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer()); - for(int i=0;i=0 && *ptgetNumberOfComponents() != 1 + * \throw If any value of \a this can't be used as a valid index for + * [\a indArrBg, \a indArrEnd). + * + * \sa changeValue + */ +void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) +{ + this->checkAllocated(); + if(this->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !"); + int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer()); + for(int i=0;i=0 && *ptdeclareAsNew(); +} + +void DataArrayInt::transformWithIndArr(const MapKeyVal& m) +{ + this->checkAllocated(); + if(this->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !"); + const std::map dat(m.data()); + int nbOfTuples(getNumberOfTuples()),*pt(getPointer()); + for(int i=0;i::const_iterator it(dat.find(*pt)); + if(it!=dat.end()) + *pt=(*it).second; + else + { + std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + this->declareAsNew(); +} + /*! * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from * values of \a this (\a a) and the given (\a indArr) arrays as follows: @@ -4476,11 +4168,11 @@ DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int */ DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const { - MCAuto ret=DataArrayInt::New(); + MCAuto ret(DataArrayInt::New()); ret->alloc(newNbOfElem,1); - int nbOfOldNodes=getNumberOfTuples(); - const int *old2New=getConstPointer(); - int *pt=ret->getPointer(); + int nbOfOldNodes(this->getNumberOfTuples()); + const int *old2New(begin()); + int *pt(ret->getPointer()); for(int i=0;i!=nbOfOldNodes;i++) { int newp(old2New[i]); @@ -4540,6 +4232,7 @@ DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example". * * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example". + * \sa invertArrayN2O2O2NOptimized * \endif */ DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const @@ -4566,422 +4259,32 @@ DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const } /*! - * Equivalent to DataArrayInt::isEqual except that if false the reason of - * mismatch is given. - * - * \param [in] other the instance to be compared with \a this - * \param [out] reason In case of inequality returns the reason. - * \sa DataArrayInt::isEqual - */ -bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const -{ - if(!areInfoEqualsIfNotWhy(other,reason)) - return false; - return _mem.isEqual(other._mem,0,reason); -} - -/*! - * Checks if \a this and another DataArrayInt are fully equal. For more info see - * \ref MEDCouplingArrayBasicsCompare. - * \param [in] other - an instance of DataArrayInt to compare with \a this one. - * \return bool - \a true if the two arrays are equal, \a false else. - */ -bool DataArrayInt::isEqual(const DataArrayInt& other) const -{ - std::string tmp; - return isEqualIfNotWhy(other,tmp); -} - -/*! - * Checks if values of \a this and another DataArrayInt are equal. For more info see - * \ref MEDCouplingArrayBasicsCompare. - * \param [in] other - an instance of DataArrayInt to compare with \a this one. - * \return bool - \a true if the values of two arrays are equal, \a false else. - */ -bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const -{ - std::string tmp; - return _mem.isEqual(other._mem,0,tmp); -} - -/*! - * Checks if values of \a this and another DataArrayInt are equal. Comparison is - * performed on sorted value sequences. - * For more info see\ref MEDCouplingArrayBasicsCompare. - * \param [in] other - an instance of DataArrayInt to compare with \a this one. - * \return bool - \a true if the sorted values of two arrays are equal, \a false else. - */ -bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const -{ - MCAuto a=deepCopy(); - MCAuto b=other.deepCopy(); - a->sort(); - b->sort(); - return a->isEqualWithoutConsideringStr(*b); -} - -/*! - * This method compares content of input vector \a v and \a this. - * 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. - * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown. - * - * \param [in] v - the vector of 'flags' to be compared with \a this. - * - * \throw If \a this is not sorted ascendingly. - * \throw If \a this has not exactly one component. - * \throw If \a this is not allocated. - */ -bool DataArrayInt::isFittingWith(const std::vector& v) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !"); - const int *w(begin()),*end2(end()); - int refVal=-std::numeric_limits::max(); - int i=0; - std::vector::const_iterator it(v.begin()); - for(;it!=v.end();it++,i++) - { - if(*it) - { - if(w!=end2) - { - if(*w++==i) - { - if(i>refVal) - refVal=i; - else - { - std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - return false; - } - else - return false; - } - } - return w==end2; -} - -/*! - * 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 - * put True to the corresponding entry in \a vec. - * \a vec is expected to be with the same size than the number of tuples of \a this. - * - * \sa DataArrayInt::switchOnTupleNotEqualTo. - */ -void DataArrayInt::switchOnTupleEqualTo(int val, std::vector& vec) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !"); - int nbOfTuples(getNumberOfTuples()); - if(nbOfTuples!=(int)vec.size()) - throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !"); - const int *pt(begin()); - for(int i=0;i& vec) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !"); - int nbOfTuples(getNumberOfTuples()); - if(nbOfTuples!=(int)vec.size()) - throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !"); - const int *pt(begin()); - for(int i=0;i ret(DataArrayInt::New()); - ret->alloc(nbOfTuple,1); - const int *src(getConstPointer()); - int *dest(ret->getPointer()); - for(int i=0;igetNumberOfComponents() != 1. - * \throw If \a this is not allocated. - */ -void DataArrayInt::checkMonotonic(bool increasing) const -{ - if(!isMonotonic(increasing)) - { - if (increasing) - throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !"); - else - throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !"); - } -} - -/*! - * Checks that \a this array is consistently **increasing** or **decreasing** in value. - * \param [in] increasing - if \a true, array values should be increasing. - * \return bool - \a true if values change in accordance with \a increasing arg. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If \a this is not allocated. - */ -bool DataArrayInt::isMonotonic(bool increasing) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !"); - int nbOfElements=getNumberOfTuples(); - const int *ptr=getConstPointer(); - if(nbOfElements==0) - return true; - int ref=ptr[0]; - if(increasing) - { - for(int i=1;i=ref) - ref=ptr[i]; - else - return false; - } - } - else - { - for(int i=1;iref) - ref=ptr[i]; - else - return false; - } - } - else - { - for(int i=1;i other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0). If such a permutation is - * not possible because some element in \a other is not in \a this, an exception is thrown. - * \param [in] other - an array to compute permutation to. - * \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array - * from \a this to \a other. The caller is to delete this array using decrRef() as it is - * no more needed. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If \a other->getNumberOfComponents() != 1. - * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples(). - * \throw If \a other includes a value which is not in \a this array. + * Creates a map, whose contents are computed + * from values of \a this array, which is supposed to contain a renumbering map in + * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode. + * To know how to use the renumbering maps see \ref numbering. + * \param [in] newNbOfElem - the number of tuples in the result array. + * \return MapII - the new instance of Map. * * \if ENABLE_EXAMPLES - * \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example". + * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example". * - * \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example". + * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example". + * \sa invertArrayN2O2O2N * \endif */ -DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const +MCAuto< MapKeyVal > DataArrayInt::invertArrayN2O2O2NOptimized() const { checkAllocated(); - if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !"); - int nbTuple=getNumberOfTuples(); - other.checkAllocated(); - if(nbTuple!=other.getNumberOfTuples()) - throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !"); - MCAuto ret=DataArrayInt::New(); - ret->alloc(nbTuple,1); - ret->fillWithValue(-1); - const int *pt=getConstPointer(); - std::map mm; - for(int i=0;igetPointer(); - for(int i=0;i::const_iterator it=mm.find(pt[i]); - if(it==mm.end()) - { - std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - retToFill[i]=(*it).second; - } - return ret.retn(); -} - -/*! - * Elements of \a partOfThis are expected to be included in \a this. - * The returned array \a ret is so that this[ret]==partOfThis - * - * 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] - * the return array will contain [3,2,5,7]. - * - * \a this is expected to be a 1 compo allocated array. - * \param [in] partOfThis - A 1 compo allocated array - * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis. - * \throw if two same element is present twice in \a this - * \throw if an element in \a partOfThis is \b NOT in \a this. - */ -DataArrayInt *DataArrayInt::indicesOfSubPart(const DataArrayInt& partOfThis) const -{ - if(getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !"); - checkAllocated(); partOfThis.checkAllocated(); - int thisNbTuples(getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples()); - const int *thisPt(begin()),*pt(partOfThis.begin()); - MCAuto ret(DataArrayInt::New()); - ret->alloc(nbTuples,1); - int *retPt(ret->getPointer()); - std::map m; - for(int i=0;i > ret(MapKeyVal::New()); + std::map& m(ret->data()); + const int *new2Old(begin()); + int nbOfNewElems(this->getNumberOfTuples()); + for(int i=0;i::const_iterator it(m.find(*pt)); - if(it!=m.end()) - *retPt=(*it).second; - else - { - std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !"; - throw INTERP_KERNEL::Exception(oss.str()); - } + int v(new2Old[i]); + m[v]=i; } - return ret.retn(); -} - -void DataArrayInt::aggregate(const DataArrayInt *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : null pointer !"); - if(getNumberOfComponents()!=other->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : mismatch number of components !"); - _mem.insertAtTheEnd(other->begin(),other->end()); -} - -/*! - * Returns a new DataArrayInt holding the same values as \a this array but differently - * arranged in memory. If \a this array holds 2 components of 3 values: - * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged - * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$. - * \warning Do not confuse this method with transpose()! - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - */ -DataArrayInt *DataArrayInt::fromNoInterlace() const -{ - checkAllocated(); - if(_mem.isNull()) - throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !"); - int *tab=_mem.fromNoInterlace(getNumberOfComponents()); - DataArrayInt *ret=DataArrayInt::New(); - ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); - return ret; -} - -/*! - * Returns a new DataArrayInt holding the same values as \a this array but differently - * arranged in memory. If \a this array holds 2 components of 3 values: - * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged - * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$. - * \warning Do not confuse this method with transpose()! - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - */ -DataArrayInt *DataArrayInt::toNoInterlace() const -{ - checkAllocated(); - if(_mem.isNull()) - throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !"); - int *tab=_mem.toNoInterlace(getNumberOfComponents()); - DataArrayInt *ret=DataArrayInt::New(); - ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); return ret; } @@ -5273,21 +4576,45 @@ bool DataArrayInt::isIota(int sizeExpected) const * \return bool - \a true if all values are \a val. * \throw If \a this is not allocated. * \throw If \a this->getNumberOfComponents() != 1 + * \sa DataArrayInt::checkUniformAndGuess */ bool DataArrayInt::isUniform(int val) const { checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !"); - int nbOfTuples=getNumberOfTuples(); - const int *w=getConstPointer(); - const int *end2=w+nbOfTuples; + const int *w(begin()),*end2(end()); for(;w!=end2;w++) if(*w!=val) return false; return true; } +/*! + * This method checks that \a this is uniform. If not and exception will be thrown. + * In case of uniformity the corresponding value is returned. + * + * \return int - the unique value contained in this + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this is not uniform. + * \sa DataArrayInt::isUniform + */ +int DataArrayInt::checkUniformAndGuess() const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !"); + if(empty()) + throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !"); + const int *w(begin()),*end2(end()); + int ret(*w); + for(;w!=end2;w++) + if(*w!=ret) + throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !"); + return ret; +} + /*! * Checks if all values in \a this array are unique. * \return bool - \a true if condition above is true @@ -5306,47 +4633,6 @@ bool DataArrayInt::hasUniqueValues() const return true; } -/*! - * Appends components of another array to components of \a this one, tuple by tuple. - * So that the number of tuples of \a this array remains the same and the number of - * components increases. - * \param [in] other - the DataArrayInt to append to \a this one. - * \throw If \a this is not allocated. - * \throw If \a this and \a other arrays have different number of tuples. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcdataarrayint_meldwith "Here is a C++ example". - * - * \ref py_mcdataarrayint_meldwith "Here is a Python example". - * \endif - */ -void DataArrayInt::meldWith(const DataArrayInt *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !"); - checkAllocated(); - other->checkAllocated(); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples!=other->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !"); - int nbOfComp1=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int)); - int *w=newArr; - const int *inp1=getConstPointer(); - const int *inp2=other->getConstPointer(); - for(int i=0;i compIds(nbOfComp2); - for(int i=0;idecrRef(); - arrayToSet=newArray; - if(arrayToSet) - arrayToSet->incrRef(); - } -} - DataArrayIntIterator *DataArrayInt::iterator() { return new DataArrayIntIterator(this); @@ -5973,46 +5241,6 @@ void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const } } -/*! - * Converts every value of \a this array to its absolute value. - * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs - * should be called instead. - * - * \throw If \a this is not allocated. - * \sa DataArrayInt::computeAbs - */ -void DataArrayInt::abs() -{ - checkAllocated(); - int *ptr(getPointer()); - std::size_t nbOfElems(getNbOfElems()); - std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun(std::abs)); - declareAsNew(); -} - -/*! - * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this. - * This method is a const method (that do not change any values in \a this) contrary to DataArrayInt::abs method. - * - * \return DataArrayInt * - the new instance of DataArrayInt containing the - * same number of tuples and component as \a this array. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If \a this is not allocated. - * \sa DataArrayInt::abs - */ -DataArrayInt *DataArrayInt::computeAbs() const -{ - checkAllocated(); - DataArrayInt *newArr(DataArrayInt::New()); - int nbOfTuples(getNumberOfTuples()); - int nbOfComp(getNumberOfComponents()); - newArr->alloc(nbOfTuples,nbOfComp); - std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun(std::abs)); - newArr->copyStringInfoFrom(*this); - return newArr; -} - /*! * Modify all elements of \a this array, so that * an element _x_ becomes \f$ numerator / x \f$. @@ -6080,41 +5308,6 @@ void DataArrayInt::applyModulus(int val) declareAsNew(); } -struct GreatEqual -{ - GreatEqual(int v):_v(v) { } - bool operator()(int v) const { return v>=_v; } - int _v; -}; - -struct GreaterThan -{ - GreaterThan(int v):_v(v) { } - bool operator()(int v) const { return v>_v; } - int _v; -}; - -struct LowerEqual -{ - LowerEqual(int v):_v(v) { } - bool operator()(int v) const { return v<=_v; } - int _v; -}; - -struct LowerThan -{ - LowerThan(int v):_v(v) { } - bool operator()(int v) const { return v<_v; } - int _v; -}; - -struct InRange -{ - InRange(int a, int b):_a(a),_b(b) { } - bool operator()(int v) const { return v>=_a && v<_b; } - int _a,_b; -}; - /*! * This method works only on data array with one component. * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that @@ -6128,18 +5321,11 @@ struct InRange */ DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const { - InRange ir(vmin,vmax); + InRange ir(vmin,vmax); MCAuto ret(findIdsAdv(ir)); return ret.retn(); } -struct NotInRange -{ - NotInRange(int a, int b):_a(a),_b(b) { } - bool operator()(int v) const { return v<_a || v>=_b; } - int _a,_b; -}; - /*! * This method works only on data array with one component. * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that @@ -6153,48 +5339,11 @@ struct NotInRange */ DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const { - NotInRange nir(vmin,vmax); + NotInRange nir(vmin,vmax); MCAuto ret(findIdsAdv(nir)); return ret.retn(); } -/*! - * 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. - * - * \return a newly allocated data array that the caller should deal with. - * \sa DataArrayInt::findIdsInRange - */ -DataArrayInt *DataArrayInt::findIdsStricltyNegative() const -{ - LowerThan lt(0); - MCAuto ret(findIdsAdv(lt)); - return ret.retn(); -} - -MCAuto DataArrayInt::findIdsGreaterOrEqualTo(int val) const -{ - GreatEqual ge(val); - return findIdsAdv(ge); -} - -MCAuto DataArrayInt::findIdsGreaterThan(int val) const -{ - GreaterThan gt(val); - return findIdsAdv(gt); -} - -MCAuto DataArrayInt::findIdsLowerOrEqualTo(int val) const -{ - LowerEqual le(val); - return findIdsAdv(le); -} - -MCAuto DataArrayInt::findIdsLowerThan(int val) const -{ - LowerThan lt(val); - return findIdsAdv(lt); -} - /*! * This method works only on data array with one component. * 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. @@ -6317,85 +5466,6 @@ void DataArrayInt::applyRPow(int val) declareAsNew(); } -/*! - * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number - * of components in the result array is a sum of the number of components of given arrays - * and (2) the number of tuples in the result array is same as that of each of given - * arrays. In other words the i-th tuple of result array includes all components of - * i-th tuples of all given arrays. - * Number of tuples in the given arrays must be the same. - * \param [in] a1 - an array to include in the result array. - * \param [in] a2 - another array to include in the result array. - * \return DataArrayInt * - the new instance of DataArrayInt. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If both \a a1 and \a a2 are NULL. - * \throw If any given array is not allocated. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() - */ -DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) -{ - std::vector arr(2); - arr[0]=a1; arr[1]=a2; - return Meld(arr); -} - -/*! - * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number - * of components in the result array is a sum of the number of components of given arrays - * and (2) the number of tuples in the result array is same as that of each of given - * arrays. In other words the i-th tuple of result array includes all components of - * i-th tuples of all given arrays. - * Number of tuples in the given arrays must be the same. - * \param [in] arr - a sequence of arrays to include in the result array. - * \return DataArrayInt * - the new instance of DataArrayInt. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If all arrays within \a arr are NULL. - * \throw If any given array is not allocated. - * \throw If getNumberOfTuples() of arrays within \a arr is different. - */ -DataArrayInt *DataArrayInt::Meld(const std::vector& arr) -{ - std::vector a; - for(std::vector::const_iterator it4=arr.begin();it4!=arr.end();it4++) - if(*it4) - a.push_back(*it4); - if(a.empty()) - throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !"); - std::vector::const_iterator it; - for(it=a.begin();it!=a.end();it++) - (*it)->checkAllocated(); - it=a.begin(); - int nbOfTuples=(*it)->getNumberOfTuples(); - std::vector nbc(a.size()); - std::vector pts(a.size()); - nbc[0]=(*it)->getNumberOfComponents(); - pts[0]=(*it++)->getConstPointer(); - for(int i=1;it!=a.end();it++,i++) - { - if(nbOfTuples!=(*it)->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !"); - nbc[i]=(*it)->getNumberOfComponents(); - pts[i]=(*it)->getConstPointer(); - } - int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc(nbOfTuples,totalNbOfComp); - int *retPtr=ret->getPointer(); - for(int i=0;isetInfoOnComponent(k,a[i]->getInfoOnComponent(j)); - return ret; -} - /*! * Returns a new DataArrayInt which is a minimal partition of elements of \a groups. * The i-th item of the result array is an ID of a set of elements belonging to a @@ -7310,34 +6380,6 @@ MCAuto DataArrayInt::fromLinkedListOfPairToList() const return ret; } -/*! - * - * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance. - * \a nbTimes should be at least equal to 1. - * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples. - * \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. - */ -DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !"); - if(nbTimes<1) - throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !"); - int nbTuples=getNumberOfTuples(); - const int *inPtr=getConstPointer(); - MCAuto ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1); - int *retPtr=ret->getPointer(); - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - /*! * This method returns all different values found in \a this. This method throws if \a this has not been allocated. * But the number of components can be different from one. @@ -7798,7 +6840,7 @@ DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator(pt,nbOfComp) +DataArrayInt32Tuple::DataArrayInt32Tuple(int *pt, int nbOfComp):DataArrayTuple(pt,nbOfComp) { }