X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingMemArray.txx;h=48ac1c576fb9298c1a6f4e2a055fc949b0f9356f;hb=e7835cba1eb17f50ef4e130c2cb8d0f54bc25083;hp=941326a87b3a26b7a52341cddaba9a9abc3f5c16;hpb=bc69ae91f0e6c8e5043650f26897a8a0ac2056fb;p=tools%2Fmedcoupling.git diff --git a/src/MEDCoupling/MEDCouplingMemArray.txx b/src/MEDCoupling/MEDCouplingMemArray.txx index 941326a87..48ac1c576 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.txx +++ b/src/MEDCoupling/MEDCouplingMemArray.txx @@ -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) #ifndef __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__ #define __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__ @@ -404,7 +404,7 @@ namespace MEDCoupling /*! * This method performs systematically an allocation of \a newNbOfElements elements in \a this. * \a _nb_of_elem and \a _nb_of_elem_alloc will be equal even if only std::min(_nb_of_elem,newNbOfElements) come from the . - * The remaing part of the new allocated chunk are available but not set previouly ! + * The remaining part of the new allocated chunk are available but not set previously ! * * So this method should not be confused with MemArray::reserve that is close to MemArray::reAlloc but not same. */ @@ -659,7 +659,7 @@ namespace MEDCoupling std::ostringstream oss; oss << Traits::ArrayTypeName << "::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - if(compoId<0 || compoId>=getNumberOfComponents()) + if(compoId<0 || compoId>=(int)getNumberOfComponents()) { std::ostringstream oss; oss << Traits::ArrayTypeName << "::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); @@ -704,7 +704,7 @@ namespace MEDCoupling } /*! - * This method desallocated \a this without modification of informations relative to the components. + * This method deallocated \a this without modification of information relative to the components. * After call of this method, DataArrayDouble::isAllocated will return false. * If \a this is already not allocated, \a this is let unchanged. */ @@ -718,7 +718,7 @@ namespace MEDCoupling * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this. * 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. * If \a this has not already been allocated, number of components is set to one. - * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this. + * This method allows to reduce number of reallocations on invocation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this. * * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent */ @@ -769,7 +769,7 @@ namespace MEDCoupling } /*! - * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation + * This method adds at the end of \a this a series of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session. * * \param [in] valsBg - an array of values to push at the end of \c this. @@ -825,7 +825,7 @@ namespace MEDCoupling { if(isAllocated()) { - if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents()) + if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=(int)getNumberOfComponents()) alloc(nbOfTuple,nbOfCompo); } else @@ -1132,25 +1132,25 @@ namespace MEDCoupling { int a,b,c; spd->getSlice(a,b,c); - if(a==0 && b==getNumberOfTuples() && c==1) + if(a==0 && b==(int)getNumberOfTuples() && c==1) { DataArrayTemplate *directRet(const_cast *>(this)); directRet->incrRef(); - MCAuto > ret(directRet); - return DynamicCastSafe,typename Traits::ArrayTypeCh>(ret); + MCAuto > ret2(directRet); + return DynamicCastSafe,typename Traits::ArrayTypeCh>(ret2); } else { - MCAuto ret(selectByTupleIdSafeSlice(a,b,c)); - return DynamicCastSafe::ArrayTypeCh>(ret); + MCAuto ret2(selectByTupleIdSafeSlice(a,b,c)); + return DynamicCastSafe::ArrayTypeCh>(ret2); } } const DataArrayPartDefinition *dpd(dynamic_cast(pd)); if(dpd) { MCAuto arr(dpd->toDAI()); - MCAuto ret(selectByTupleIdSafe(arr->begin(),arr->end())); - return DynamicCastSafe::ArrayTypeCh>(ret); + MCAuto ret2(selectByTupleIdSafe(arr->begin(),arr->end())); + return DynamicCastSafe::ArrayTypeCh>(ret2); } throw INTERP_KERNEL::Exception("DataArrayTemplate::selectPartDef : unrecognized part def !"); @@ -1928,7 +1928,7 @@ namespace MEDCoupling checkAllocated(); a->checkAllocated(); tuplesSelec->checkAllocated(); - int nbOfComp=getNumberOfComponents(); + std::size_t nbOfComp(getNumberOfComponents()); if(nbOfComp!=a->getNumberOfComponents()) throw INTERP_KERNEL::Exception("DataArrayTemplate::setPartOfValuesAdv : This and a do not have the same number of components !"); if(tuplesSelec->getNumberOfComponents()!=2) @@ -1993,7 +1993,7 @@ namespace MEDCoupling checkAllocated(); a->checkAllocated(); tuplesSelec->checkAllocated(); - int nbOfComp(getNumberOfComponents()); + std::size_t nbOfComp(getNumberOfComponents()); if(nbOfComp!=a->getNumberOfComponents()) throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValues : This and a do not have the same number of components !"); if(tuplesSelec->getNumberOfComponents()!=1) @@ -2058,7 +2058,7 @@ namespace MEDCoupling throw INTERP_KERNEL::Exception("DataArrayTemplate::setContigPartOfSelectedValuesSlice : input DataArray aBase is not a DataArrayDouble !"); checkAllocated(); a->checkAllocated(); - int nbOfComp(getNumberOfComponents()); + std::size_t nbOfComp(getNumberOfComponents()); const char msg[]="DataArrayDouble::setContigPartOfSelectedValuesSlice"; int nbOfTupleToWrite(DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg)); if(nbOfComp!=a->getNumberOfComponents()) @@ -2185,6 +2185,7 @@ namespace MEDCoupling * \return double - the maximal value among all values of \a this array. * \throw If \a this->getNumberOfComponents() != 1 * \throw If \a this->getNumberOfTuples() < 1 + * \sa getMaxAbsValue, getMinValue */ template T DataArrayTemplate::getMaxValue(int& tupleId) const @@ -2206,6 +2207,7 @@ namespace MEDCoupling * one component. * \return double - the maximal value among all values of \a this array. * \throw If \a this is not allocated. + * \sa getMaxAbsValueInArray, getMinValueInArray */ template T DataArrayTemplate::getMaxValueInArray() const @@ -2215,6 +2217,50 @@ namespace MEDCoupling return *loc; } + /*! + * Returns the maximal absolute value in \a this and the first occurrence location associated to it. + * \return the element in this (positive or negative) having the max abs value in \a this. + * \throw If \a this is not allocated. + * \throw If \a this is non one component array. + * \throw If \a this is empty. + */ + template + T DataArrayTemplate::getMaxAbsValue(std::size_t& tupleId) const + { + checkAllocated(); + if(getNumberOfComponents()!=1) + 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 !"); + std::size_t nbTuples(this->getNumberOfTuples()); + if(nbTuples==0) + throw INTERP_KERNEL::Exception("DataArrayTemplate::getMaxAbsValue : empty array !"); + T ret((T)-1); + tupleId=0; + const T *pt(begin()); + for(std::size_t i=0;iret) + { + ret=cand; + tupleId=i; + } + } + return this->getIJ(tupleId,0); + } + + /*! + * Returns the maximal absolute value in \a this. + * \throw If \a this is not allocated. + * \throw If \a this is non one component array. + * \throw If \a this is empty. + */ + template + T DataArrayTemplate::getMaxAbsValueInArray() const + { + std::size_t dummy; + return getMaxAbsValue(dummy); + } + /*! * Returns the minimal value and its location within \a this one-dimensional array. * \param [out] tupleId - index of the tuple holding the minimal value. @@ -2343,6 +2389,19 @@ namespace MEDCoupling } } + /*! + * 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. + */ + template + void DataArrayTemplate::fillWithZero() + { + fillWithValue((T)0); + } + + ////////////////////////////// + template template MCAuto< typename Traits::ArrayType > DataArrayTemplateClassic::convertToOtherTypeOfArr() const @@ -3002,7 +3061,7 @@ struct NotInRange for(it=a.begin();it!=a.end();it++) (*it)->checkAllocated(); it=a.begin(); - int nbOfTuples((*it)->getNumberOfTuples()); + std::size_t nbOfTuples((*it)->getNumberOfTuples()); std::vector nbc(a.size()); std::vector pts(a.size()); nbc[0]=(*it)->getNumberOfComponents(); @@ -3018,8 +3077,8 @@ struct NotInRange typename Traits::ArrayType *ret(Traits::ArrayType::New()); ret->alloc(nbOfTuples,totalNbOfComp); T *retPtr(ret->getPointer()); - for(int i=0;icheckAllocated(); other->checkAllocated(); - int nbOfTuples(this->getNumberOfTuples()); + std::size_t nbOfTuples(this->getNumberOfTuples()); if(nbOfTuples!=other->getNumberOfTuples()) throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !"); int nbOfComp1(this->getNumberOfComponents()),nbOfComp2(other->getNumberOfComponents()); T *newArr=(T *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(T)); T *w=newArr; const T *inp1(this->begin()),*inp2(other->begin()); - for(int i=0;i::ArrayType *thisC(static_cast::ArrayType *>(this)); return DataArrayTemplateClassic::PerformCopyOrIncrRef(dCpy,*thisC); } + + /*! + * 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. + */ + template + typename Traits::ArrayType *DataArrayTemplateClassic::sumPerTuple() const + { + this->checkAllocated(); + std::size_t nbOfComp(this->getNumberOfComponents()),nbOfTuple(this->getNumberOfTuples()); + MCAuto::ArrayType> ret(Traits::ArrayType::New()); + ret->alloc(nbOfTuple,1); + const T *src(this->begin()); + T *dest(ret->getPointer()); + for(std::size_t i=0;igetNumberOfComponents() != 1 + * \throw If \a this is not allocated. + */ + template + void DataArrayTemplateClassic::iota(T init) + { + this->checkAllocated(); + if(this->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !"); + T *ptr(this->getPointer()); + std::size_t ntuples(this->getNumberOfTuples()); + for(std::size_t i=0;ideclareAsNew(); + } + + template + struct ImplReprTraits { static void SetPrecision(std::ostream& oss) { } }; + + template<> + struct ImplReprTraits { static void SetPrecision(std::ostream& oss) { oss.precision(17); } }; + + template<> + struct ImplReprTraits { static void SetPrecision(std::ostream& oss) { oss.precision(7); } }; + + template + void DataArrayTemplateClassic::reprStream(std::ostream& stream) const + { + stream << "Name of " << Traits::ReprStr << " array : \"" << this->_name << "\"\n"; + reprWithoutNameStream(stream); + } + + template + void DataArrayTemplateClassic::reprZipStream(std::ostream& stream) const + { + stream << "Name of " << Traits::ReprStr << " array : \"" << this->_name << "\"\n"; + reprZipWithoutNameStream(stream); + } + + template + void DataArrayTemplateClassic::reprNotTooLongStream(std::ostream& stream) const + { + stream << "Name of "<< Traits::ReprStr << " array : \"" << this->_name << "\"\n"; + reprNotTooLongWithoutNameStream(stream); + } + + template + void DataArrayTemplateClassic::reprWithoutNameStream(std::ostream& stream) const + { + DataArray::reprWithoutNameStream(stream); + ImplReprTraits::SetPrecision(stream); + this->_mem.repr(this->getNumberOfComponents(),stream); + } + + template + void DataArrayTemplateClassic::reprZipWithoutNameStream(std::ostream& stream) const + { + DataArray::reprWithoutNameStream(stream); + ImplReprTraits::SetPrecision(stream); + this->_mem.reprZip(this->getNumberOfComponents(),stream); + } + + template + void DataArrayTemplateClassic::reprNotTooLongWithoutNameStream(std::ostream& stream) const + { + DataArray::reprWithoutNameStream(stream); + ImplReprTraits::SetPrecision(stream); + this->_mem.reprNotTooLong(this->getNumberOfComponents(),stream); + } + + /*! + * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not + * printed out to avoid to consume too much space in interpretor. + * \sa repr + */ + template + std::string DataArrayTemplateClassic::reprNotTooLong() const + { + std::ostringstream ret; + reprNotTooLongStream(ret); + return ret.str(); + } + + ///////////////////////////////// /*! * Checks if all values in \a this array are equal to \a val at precision \a eps. @@ -3221,7 +3392,6 @@ struct NotInRange this->checkAllocated(); if(this->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !"); - int nbOfTuples(this->getNumberOfTuples()); const T *w(this->begin()),*end2(this->end()); const T vmin(val-eps),vmax(val+eps); for(;w!=end2;w++) @@ -3231,23 +3401,362 @@ struct NotInRange } /*! - * 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 + * 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 + */ + template + bool DataArrayDiscrete::isEqualIfNotWhy(const DataArrayDiscrete& other, std::string& reason) const + { + if(!this->areInfoEqualsIfNotWhy(other,reason)) + return false; + return this->_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. + */ + template + bool DataArrayDiscrete::isEqual(const DataArrayDiscrete& 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. + */ + template + bool DataArrayDiscrete::isEqualWithoutConsideringStr(const DataArrayDiscrete& other) const + { + std::string tmp; + return this->_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. + */ + template + bool DataArrayDiscrete::isEqualWithoutConsideringStrAndOrder(const typename Traits::ArrayType& other) const + { + MCAuto a(static_cast::ArrayType *>(this)->deepCopy()),b(other.deepCopy()); + a->sort(); + b->sort(); + return a->isEqualWithoutConsideringStr(*b); + } + + template + template + void DataArrayDiscrete::switchOnTupleAlg(T val, std::vector& vec, ALG algo) const + { + this->checkAllocated(); + if(this->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !"); + int nbOfTuples(this->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 T *pt(this->begin()); + for(int i=0;i + void DataArrayDiscrete::switchOnTupleEqualTo(T val, std::vector& vec) const + { + switchOnTupleAlg(val,vec,std::equal_to()); + } + + /*! + * 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 + * 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::switchOnTupleEqualTo. + */ + template + void DataArrayDiscrete::switchOnTupleNotEqualTo(T val, std::vector& vec) const + { + switchOnTupleAlg(val,vec,std::not_equal_to()); + } + + /*! + * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given + * one-dimensional arrays that must be of the same length. The result array describes + * correspondence between \a this and \a other arrays, so that + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example". + * + * \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example". + * \endif + */ + template + DataArrayIdType *DataArrayDiscrete::buildPermutationArr(const DataArrayDiscrete& other) const + { + this->checkAllocated(); + if(this->getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !"); + std::size_t nbTuple(this->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(DataArrayIdType::New()); + ret->alloc(nbTuple,1); + ret->fillWithValue(-1); + const T *pt(this->begin()); + std::map mm; + for(std::size_t i=0;igetPointer()); + for(std::size_t 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. + */ + template + DataArrayIdType *DataArrayDiscrete::indicesOfSubPart(const DataArrayDiscrete& partOfThis) const + { + if(this->getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !"); + this->checkAllocated(); partOfThis.checkAllocated(); + std::size_t thisNbTuples(this->getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples()); + const T *thisPt(this->begin()),*pt(partOfThis.begin()); + MCAuto ret(DataArrayIdType::New()); + ret->alloc(nbTuples,1); + T *retPt(ret->getPointer()); + std::map m; + for(std::size_t 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()); + } + } + return ret.retn(); + } + + /*! + * Checks that \a this array is consistently **increasing** or **decreasing** in value. + * If not an exception is thrown. + * \param [in] increasing - if \a true, the array values should be increasing. + * \throw If sequence of values is not strictly monotonic in agreement with \a + * increasing arg. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this is not allocated. + */ + template + void DataArrayDiscrete::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. */ template - void DataArrayTemplateFP::iota(T init) + bool DataArrayDiscrete::isMonotonic(bool increasing) const { this->checkAllocated(); if(this->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !"); - T *ptr(this->getPointer()); - int ntuples(this->getNumberOfTuples()); - for(int i=0;ideclareAsNew(); + throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !"); + std::size_t nbOfElements(this->getNumberOfTuples()); + const T *ptr(this->begin()); + if(nbOfElements==0) + return true; + T ref(ptr[0]); + if(increasing) + { + for(std::size_t i=1;i=ref) + ref=ptr[i]; + else + return false; + } + } + else + { + for(std::size_t i=1;i + bool DataArrayDiscrete::isStrictlyMonotonic(bool increasing) const + { + this->checkAllocated(); + if(this->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !"); + std::size_t nbOfElements(this->getNumberOfTuples()); + const T *ptr(this->begin()); + if(nbOfElements==0) + return true; + T ref(ptr[0]); + if(increasing) + { + for(std::size_t i=1;iref) + ref=ptr[i]; + else + return false; + } + } + else + { + for(std::size_t i=1;i + void DataArrayDiscrete::checkStrictlyMonotonic(bool increasing) const + { + if(!isStrictlyMonotonic(increasing)) + { + if (increasing) + throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !"); + else + throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !"); + } + } + + //////////////////////////////////// + + /*! + * 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. + */ + template + bool DataArrayDiscreteSigned::isFittingWith(const std::vector& v) const + { + this->checkAllocated(); + if(this->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !"); + const T *w(this->begin()),*end2(this->end()); + T 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(this->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; } }