X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingMemArray.cxx;h=adc2f0b1c71587f8f95a602d4745d155b940e6ee;hb=ffe6d640bbaae9d66ac15d1015761d047a495ede;hp=d8dee0b6a7f7552bfa07fd860474debac6ad252b;hpb=77bd05418520f5ddc7ce7977776e8da183841e60;p=tools%2Fmedcoupling.git diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index d8dee0b6a..adc2f0b1c 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -247,6 +247,42 @@ void DataArray::setInfoOnComponents(const std::vector& info) throw( _info_on_compo=info; } +/*! + * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true + * type of \a this and \a aBase. + * + * \throw If \a aBase and \a this do not have the same type. + * + * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3. + */ +void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception) +{ + if(!aBase) + throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !"); + DataArrayDouble *this1(dynamic_cast(this)); + DataArrayInt *this2(dynamic_cast(this)); + DataArrayChar *this3(dynamic_cast(this)); + const DataArrayDouble *a1(dynamic_cast(aBase)); + const DataArrayInt *a2(dynamic_cast(aBase)); + const DataArrayChar *a3(dynamic_cast(aBase)); + if(this1 && a1) + { + this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare); + return ; + } + if(this2 && a2) + { + this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare); + return ; + } + if(this3 && a3) + { + this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare); + return ; + } + throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !"); +} + std::vector DataArray::getVarsOnComponent() const throw(INTERP_KERNEL::Exception) { int nbOfCompo=(int)_info_on_compo.size(); @@ -379,6 +415,53 @@ std::string DataArray::GetUnitFromInfo(const std::string& info) throw(INTERP_KER return info.substr(p1+1,p2-p1-1); } +/*! + * Returns a new DataArray by concatenating all given arrays, so that (1) the number + * of tuples in the result array is a sum of the number of tuples of given arrays and (2) + * the number of component in the result array is same as that of each of given arrays. + * Info on components is copied from the first of the given arrays. Number of components + * in the given arrays must be the same. + * \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type. + * \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar). + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If all arrays within \a arrs are NULL. + * \throw If all not null arrays in \a arrs have not the same type. + * \throw If getNumberOfComponents() of arrays within \a arrs. + */ +DataArray *DataArray::Aggregate(const std::vector& arrs) throw(INTERP_KERNEL::Exception) +{ + std::vector arr2; + for(std::vector::const_iterator it=arrs.begin();it!=arrs.end();it++) + if(*it) + arr2.push_back(*it); + if(arr2.empty()) + throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !"); + std::vector arrd; + std::vector arri; + std::vector arrc; + for(std::vector::const_iterator it=arr2.begin();it!=arr2.end();it++) + { + const DataArrayDouble *a=dynamic_cast(*it); + if(a) + { arrd.push_back(a); continue; } + const DataArrayInt *b=dynamic_cast(*it); + if(b) + { arri.push_back(b); continue; } + const DataArrayChar *c=dynamic_cast(*it); + if(c) + { arrc.push_back(c); continue; } + throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !"); + } + if(arr2.size()==arrd.size()) + return DataArrayDouble::Aggregate(arrd); + if(arr2.size()==arri.size()) + return DataArrayInt::Aggregate(arri); + if(arr2.size()==arrc.size()) + return DataArrayChar::Aggregate(arrc); + throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !"); +} + /*! * Sets information on a component specified by an index. * To know more on format of this information @@ -402,7 +485,8 @@ void DataArray::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL: /*! * Sets information on all components. This method can change number of components * at certain conditions; if the conditions are not respected, an exception is thrown. - * The number of components can be changed provided that \a this is not allocated. + * The number of components can be changed in \a this only if \a this is not allocated. + * The condition of number of components must not be changed. * * To know more on format of the component information see * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos". @@ -652,6 +736,16 @@ void DataArrayDouble::checkAllocated() const throw(INTERP_KERNEL::Exception) throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !"); } +/*! + * This method desallocated \a this without modification of informations 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. + */ +void DataArrayDouble::desallocate() throw(INTERP_KERNEL::Exception) +{ + _mem.destroy(); +} + std::size_t DataArrayDouble::getHeapMemorySize() const { std::size_t sz=_mem.getNbOfElemAllocated(); @@ -1209,9 +1303,12 @@ bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, * than the current number the array is truncated, otherwise the array is extended. * \param [in] nbOfTuples - new number of tuples. * \throw If \a this is not allocated. + * \throw If \a nbOfTuples is negative. */ void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception) { + if(nbOfTuples<0) + throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !"); checkAllocated(); _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples); declareAsNew(); @@ -1291,7 +1388,16 @@ void DataArrayDouble::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::E double *tmp=new double[nbTuples*nbOfCompo]; const double *iptr=getConstPointer(); for(int i=0;i=0 && v=0 && vgetNumberOfTuples() ) tuple #i in \a other is equal ( regarding input precision \a prec ) to tuple tupleIds[i] in \a this. + * + * \param [in] other - the array having the same number of components than \a this. + * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has. + * \sa DataArrayDouble::findCommonTuples + */ +bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const throw(INTERP_KERNEL::Exception) +{ + if(!other) + throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !"); + checkAllocated(); other->checkAllocated(); + if(getNumberOfComponents()!=other->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !"); + MEDCouplingAutoRefCountObjectPtr a=DataArrayDouble::Aggregate(this,other); + DataArrayInt *c=0,*ci=0; + a->findCommonTuples(prec,getNumberOfTuples(),c,ci); + MEDCouplingAutoRefCountObjectPtr cSafe(c),ciSafe(ci); + int newNbOfTuples=-1; + MEDCouplingAutoRefCountObjectPtr ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples); + MEDCouplingAutoRefCountObjectPtr ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1); + tupleIds=ret1.retn(); + return newNbOfTuples==getNumberOfTuples(); +} + /*! * Searches for tuples coincident within \a prec tolerance. Each tuple is considered * as coordinates of a point in getNumberOfComponents()-dimensional space. The @@ -1797,7 +1939,7 @@ void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example". * * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example". - * \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(). + * \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe */ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception) { @@ -2525,7 +2667,7 @@ void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArr } /*! - * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples + * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples * of \a this array. Textual data is not copied. Both arrays must have equal number of * components. * The tuples to assign to are defined by index of the first tuple, and @@ -2534,18 +2676,18 @@ void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArr * All components of selected tuples are copied. * \param [in] tupleIdStart - index of the first tuple of \a this array to assign * values to. - * \param [in] a - the array to copy values from. + * \param [in] aBase - the array to copy values from. * \param [in] tuplesSelec - the array specifying tuples of \a a to copy. * \throw If \a this is not allocated. - * \throw If \a a is NULL. - * \throw If \a a is not allocated. + * \throw If \a aBase is NULL. + * \throw If \a aBase is not allocated. * \throw If \a tuplesSelec is NULL. * \throw If \a tuplesSelec is not allocated. - * \throw If this->getNumberOfComponents() != a->getNumberOfComponents(). + * \throw If this->getNumberOfComponents() != aBase->getNumberOfComponents(). * \throw If \a tuplesSelec->getNumberOfComponents() != 1. * \throw If tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples(). * \throw If any tuple index given by \a tuplesSelec is out of a valid range for - * \a a array. + * \a aBase array. */ void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception) { @@ -2585,7 +2727,7 @@ void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const Data } /*! - * Copy some tuples from another DataArrayDouble (\a a) into contiguous tuples + * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples * of \a this array. Textual data is not copied. Both arrays must have equal number of * components. * The tuples to copy are defined by three values similar to parameters of @@ -2595,19 +2737,19 @@ void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const Data * All components of selected tuples are copied. * \param [in] tupleIdStart - index of the first tuple of \a this array to assign * values to. - * \param [in] a - the array to copy values from. - * \param [in] bg - index of the first tuple to copy of the array \a a. - * \param [in] end2 - index of the tuple of \a a before which the tuples to copy + * \param [in] aBase - the array to copy values from. + * \param [in] bg - index of the first tuple to copy of the array \a aBase. + * \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy * are located. * \param [in] step - index increment to get index of the next tuple to copy. * \throw If \a this is not allocated. - * \throw If \a a is NULL. - * \throw If \a a is not allocated. - * \throw If this->getNumberOfComponents() != a->getNumberOfComponents(). + * \throw If \a aBase is NULL. + * \throw If \a aBase is not allocated. + * \throw If this->getNumberOfComponents() != aBase->getNumberOfComponents(). * \throw If tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples(). * \throw If parameters specifying tuples to copy, do not give a * non-empty range of increasing indices or indices are out of a valid range - * for the array \a a. + * for the array \a aBase. */ void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception) { @@ -2665,6 +2807,24 @@ double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_K return _mem[tupleId*_info_on_compo.size()+compoId]; } +/*! + * Returns the first value of \a this. + * \return double - the last value of \a this array. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this->getNumberOfTuples() < 1. + */ +double DataArrayDouble::front() const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<1) + throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !"); + return *(getConstPointer()); +} + /*! * Returns the last value of \a this. * \return double - the last value of \a this array. @@ -5365,6 +5525,16 @@ void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception) throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !"); } +/*! + * This method desallocated \a this without modification of informations relative to the components. + * After call of this method, DataArrayInt::isAllocated will return false. + * If \a this is already not allocated, \a this is let unchanged. + */ +void DataArrayInt::desallocate() throw(INTERP_KERNEL::Exception) +{ + _mem.destroy(); +} + std::size_t DataArrayInt::getHeapMemorySize() const { std::size_t sz=_mem.getNbOfElemAllocated(); @@ -5798,7 +5968,7 @@ void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd *pt=indArrBg[*pt]; else { - std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn; + std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } } @@ -5887,7 +6057,7 @@ void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd, } else { - std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " whereas the last value is " << *bg; + std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } } @@ -6015,7 +6185,16 @@ DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const std::fill(pt,pt+oldNbOfElem,-1); int nbOfNewElems=getNumberOfTuples(); for(int i=0;i=0 && visEqualWithoutConsideringStr(*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 throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !"); + int nbOfTuples(getNumberOfTuples()); + 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; +} + /*! * Sorts values of the array. * \param [in] asc - \a true means ascending order, \a false, descending. @@ -6346,7 +6572,16 @@ void DataArrayInt::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exce int *tmp=new int[nbTuples*nbOfCompo]; const int *iptr=getConstPointer(); for(int i=0;i=0 && v=0 && vrenumber(ret)->isEqual(ids2) where \a ret is the return of this method. + * + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If either ids1 or ids2 is null not allocated or not with one components. + * + */ +DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2) throw(INTERP_KERNEL::Exception) +{ + if(!ids1 || !ids2) + throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !"); + if(!ids1->isAllocated() || !ids2->isAllocated()) + throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !"); + if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !"); + if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples()) + { + 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 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingAutoRefCountObjectPtr p1(ids1->deepCpy()); + MEDCouplingAutoRefCountObjectPtr p2(ids2->deepCpy()); + p1->sort(true); p2->sort(true); + if(!p1->isEqualWithoutConsideringStr(*p2)) + throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !"); + p1=ids1->checkAndPreparePermutation(); + p2=ids2->checkAndPreparePermutation(); + p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples()); + p2=p2->selectByTupleIdSafe(p1->begin(),p1->end()); + return p2.retn(); +} + /*! * Returns two arrays describing a surjective mapping from \a this set of values (\a A) * onto a set of values of size \a targetNb (\a B). The surjective function is @@ -7030,9 +7312,12 @@ DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) * than the current number the array is truncated, otherwise the array is extended. * \param [in] nbOfTuples - new number of tuples. * \throw If \a this is not allocated. + * \throw If \a nbOfTuples is negative. */ void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception) { + if(nbOfTuples<0) + throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !"); checkAllocated(); _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples); declareAsNew(); @@ -7635,7 +7920,7 @@ void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt } /*! - * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples + * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples * of \a this array. Textual data is not copied. Both arrays must have equal number of * components. * The tuples to assign to are defined by index of the first tuple, and @@ -7644,18 +7929,18 @@ void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt * All components of selected tuples are copied. * \param [in] tupleIdStart - index of the first tuple of \a this array to assign * values to. - * \param [in] a - the array to copy values from. - * \param [in] tuplesSelec - the array specifying tuples of \a a to copy. + * \param [in] aBase - the array to copy values from. + * \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy. * \throw If \a this is not allocated. - * \throw If \a a is NULL. - * \throw If \a a is not allocated. + * \throw If \a aBase is NULL. + * \throw If \a aBase is not allocated. * \throw If \a tuplesSelec is NULL. * \throw If \a tuplesSelec is not allocated. * \throw If this->getNumberOfComponents() != a->getNumberOfComponents(). * \throw If \a tuplesSelec->getNumberOfComponents() != 1. * \throw If tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples(). * \throw If any tuple index given by \a tuplesSelec is out of a valid range for - * \a a array. + * \a aBase array. */ void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception) { @@ -7695,7 +7980,7 @@ void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArr } /*! - * Copy some tuples from another DataArrayInt (\a a) into contiguous tuples + * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples * of \a this array. Textual data is not copied. Both arrays must have equal number of * components. * The tuples to copy are defined by three values similar to parameters of @@ -7705,19 +7990,19 @@ void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArr * All components of selected tuples are copied. * \param [in] tupleIdStart - index of the first tuple of \a this array to assign * values to. - * \param [in] a - the array to copy values from. - * \param [in] bg - index of the first tuple to copy of the array \a a. - * \param [in] end2 - index of the tuple of \a a before which the tuples to copy + * \param [in] aBase - the array to copy values from. + * \param [in] bg - index of the first tuple to copy of the array \a aBase. + * \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy * are located. * \param [in] step - index increment to get index of the next tuple to copy. * \throw If \a this is not allocated. - * \throw If \a a is NULL. - * \throw If \a a is not allocated. - * \throw If this->getNumberOfComponents() != a->getNumberOfComponents(). + * \throw If \a aBase is NULL. + * \throw If \a aBase is not allocated. + * \throw If this->getNumberOfComponents() != aBase->getNumberOfComponents(). * \throw If tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples(). * \throw If parameters specifying tuples to copy, do not give a * non-empty range of increasing indices or indices are out of a valid range - * for the array \a a. + * for the array \a aBase. */ void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception) { @@ -7775,9 +8060,27 @@ int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL: return _mem[tupleId*_info_on_compo.size()+compoId]; } +/*! + * Returns the first value of \a this. + * \return int - the last value of \a this array. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this->getNumberOfTuples() < 1. + */ +int DataArrayInt::front() const throw(INTERP_KERNEL::Exception) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<1) + throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !"); + return *(getConstPointer()); +} + /*! * Returns the last value of \a this. - * \return double - the last value of \a this array. + * \return int - the last value of \a this array. * \throw If \a this is not allocated. * \throw If \a this->getNumberOfComponents() != 1. * \throw If \a this->getNumberOfTuples() < 1. @@ -8264,6 +8567,57 @@ DataArrayInt *DataArrayInt::Aggregate(const std::vector& a return ret.retn(); } +/*! + * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays. + * A packed index array is an allocated array with one component, and at least one tuple. The first element + * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic. + * 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. + * + * \return DataArrayInt * - a new object to be managed by the caller. + */ +DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector& arrs) throw(INTERP_KERNEL::Exception) +{ + int retSz=1; + for(std::vector::const_iterator it4=arrs.begin();it4!=arrs.end();it4++) + { + if(*it4) + { + (*it4)->checkAllocated(); + if((*it4)->getNumberOfComponents()!=1) + { + std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbTupl=(*it4)->getNumberOfTuples(); + if(nbTupl<1) + { + std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if((*it4)->front()!=0) + { + std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + retSz+=nbTupl-1; + } + else + { + std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(arrs.empty()) + throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !"); + MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + ret->alloc(retSz,1); + int *pt=ret->getPointer(); *pt++=0; + for(std::vector::const_iterator it=arrs.begin();it!=arrs.end();it++) + pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus(),pt[-1])); + ret->copyStringInfoFrom(*(arrs[0])); + return ret.retn(); +} + /*! * Returns the maximal value and its location within \a this one-dimensional array. * \param [out] tupleId - index of the tuple holding the maximal value. @@ -9021,6 +9375,7 @@ DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception) * "MEDCouplingUMesh::buildDescendingConnectivity" and * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex * "MEDCouplingUMesh::getNodalConnectivityIndex" etc. + * This method preforms the reverse operation of DataArrayInt::computeOffsets2. * \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. @@ -9032,6 +9387,8 @@ DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception) * - 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::computeOffsets2 */ DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception) { @@ -9094,12 +9451,14 @@ void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception) * components remains the same and number of tuples is inceamented by one.
* 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:
* - Before \a this contains [3,5,1,2,0,8] * - After \a this contains [0,3,8,9,11,11,19]
+ * \sa DataArrayInt::deltaShiftIndex */ void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception) { @@ -9246,6 +9605,67 @@ DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets 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 gb \a end \a step ) points outside the scale in \a this. + * + * \b Example:
+ * - \a bg , \a end 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] ==
+ */ +DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int end, int step) const throw(INTERP_KERNEL::Exception) +{ + 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,end,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg); + for(int i=0;i=0 && pos ret(DataArrayInt::New()); ret->alloc(sz,1); + int *retPtr(ret->getPointer()); + pos=bg; + for(int i=0;igetIJ(i,0) and put the result