X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingMemArray.cxx;h=194cdccf4dc382df760b3f55f1ce0ce6e3c0fabb;hb=cdd09520be1ff9d51b7f67e39fb0866bb71db901;hp=ed49f555949d29ca89e08dcb624d4aebfedd01f4;hpb=1a9af3cb21941312cdda3f0466677b61beba7ade;p=tools%2Fmedcoupling.git diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index ed49f5559..194cdccf4 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -1,9 +1,9 @@ -// Copyright (C) 2007-2013 CEA/DEN, EDF R&D +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -19,7 +19,6 @@ // Author : Anthony Geay (CEA/DEN) #include "MEDCouplingMemArray.txx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" #include "BBTree.txx" #include "GenMathFormulae.hxx" @@ -35,7 +34,10 @@ typedef double (*MYFUNCPTR)(double); -using namespace ParaMEDMEM; +using namespace MEDCoupling; + +template class DataArrayTemplate; +template class DataArrayTemplate; template void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const @@ -120,7 +122,7 @@ std::size_t DataArray::getHeapMemorySizeWithoutChildren() const return sz1+sz2+sz3; } -std::vector DataArray::getDirectChildren() const +std::vector DataArray::getDirectChildrenWithNull() const { return std::vector(); } @@ -422,6 +424,33 @@ std::string DataArray::GetUnitFromInfo(const std::string& info) return info.substr(p1+1,p2-p1-1); } +/*! + * This method put in info format the result of the merge of \a var and \a unit. + * The standard format for that is "var [unit]". + * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo. + */ +std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit) +{ + std::ostringstream oss; + oss << var << " [" << unit << "]"; + return oss.str(); +} + +std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at) +{ + switch(at) + { + case AX_CART: + return std::string("AX_CART"); + case AX_CYL: + return std::string("AX_CYL"); + case AX_SPHER: + return std::string("AX_SPHER"); + default: + throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !"); + } +} + /*! * 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) @@ -545,7 +574,7 @@ void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) co void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const { - if(getNumberOfTuples()!=other.getNumberOfTuples()) + if(getNumberOfTuples()!=other.getNumberOfTuples()) { std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); @@ -723,43 +752,6 @@ DataArrayDouble *DataArrayDouble::New() return new DataArrayDouble; } -/*! - * Checks if raw data is allocated. Read more on the raw data - * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information. - * \return bool - \a true if the raw data is allocated, \a false else. - */ -bool DataArrayDouble::isAllocated() const -{ - return getConstPointer()!=0; -} - -/*! - * Checks if raw data is allocated and throws an exception if it is not the case. - * \throw If the raw data is not allocated. - */ -void DataArrayDouble::checkAllocated() const -{ - if(!isAllocated()) - 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() -{ - _mem.destroy(); -} - -std::size_t DataArrayDouble::getHeapMemorySizeWithoutChildren() const -{ - std::size_t sz(_mem.getNbOfElemAllocated()); - sz*=sizeof(double); - return DataArray::getHeapMemorySizeWithoutChildren()+sz; -} - /*! * Returns the only one value in \a this, if and only if number of elements * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated. @@ -781,24 +773,13 @@ double DataArrayDouble::doubleValue() const throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !"); } -/*! - * Checks the number of tuples. - * \return bool - \a true if getNumberOfTuples() == 0, \a false else. - * \throw If \a this is not allocated. - */ -bool DataArrayDouble::empty() const -{ - checkAllocated(); - return getNumberOfTuples()==0; -} - /*! * Returns a full copy of \a this. For more info on copying data arrays see * \ref MEDCouplingArrayBasicsCopyDeep. * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to * delete this array using decrRef() as it is no more needed. */ -DataArrayDouble *DataArrayDouble::deepCpy() const +DataArrayDouble *DataArrayDouble::deepCopy() const { return new DataArrayDouble(*this); } @@ -810,10 +791,10 @@ DataArrayDouble *DataArrayDouble::deepCpy() const * \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy * == \a true) or \a this instance (if \a dCpy == \a false). */ -DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const +DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const { if(dCpy) - return deepCpy(); + return deepCopy(); else { incrRef(); @@ -821,154 +802,6 @@ DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const } } -/*! - * Copies all the data from another DataArrayDouble. For more info see - * \ref MEDCouplingArrayBasicsCopyDeepAssign. - * \param [in] other - another instance of DataArrayDouble to copy data from. - * \throw If the \a other is not allocated. - */ -void DataArrayDouble::cpyFrom(const DataArrayDouble& other) -{ - other.checkAllocated(); - int nbOfTuples=other.getNumberOfTuples(); - int nbOfComp=other.getNumberOfComponents(); - allocIfNecessary(nbOfTuples,nbOfComp); - std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp; - double *pt=getPointer(); - const double *ptI=other.getConstPointer(); - for(std::size_t i=0;igetNumberOfComponents() != 1. - */ -void DataArrayDouble::sort(bool asc) -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !"); - _mem.sort(asc); - declareAsNew(); -} - -/*! - * Reverse the array values. - * \throw If \a this->getNumberOfComponents() < 1. - * \throw If \a this is not allocated. - */ -void DataArrayDouble::reverse() -{ - checkAllocated(); - _mem.reverse(getNumberOfComponents()); - declareAsNew(); -} - /*! * Checks that \a this array is consistently **increasing** or **decreasing** in value, * with at least absolute difference value of |\a eps| at each step. @@ -1134,7 +925,9 @@ bool DataArrayDouble::isMonotonic(bool increasing, double eps) const /*! * Returns a textual and human readable representation of \a this instance of * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python. - * \return std::string - text describing \a this DataArrayDouble. + * \return std::string - text describing \a this DataArrayDouble. + * + * \sa reprNotTooLong, reprZip */ std::string DataArrayDouble::repr() const { @@ -1150,6 +943,18 @@ std::string DataArrayDouble::reprZip() const return ret.str(); } +/*! + * 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 + */ +std::string DataArrayDouble::reprNotTooLong() const +{ + std::ostringstream ret; + reprNotTooLongStream(ret); + return ret.str(); +} + void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const { static const char SPACE[4]={' ',' ',' ',' '}; @@ -1157,6 +962,15 @@ void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& std::string idt(indent,' '); ofs.precision(17); ofs << idt << "::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++) + if(!(*it).empty()) + areAllEmpty=false; + if(!areAllEmpty) + for(std::size_t i=0;i<_info_on_compo.size();i++) + ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\""; + // if(byteArr) { ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">"; @@ -1190,6 +1004,12 @@ void DataArrayDouble::reprZipStream(std::ostream& stream) const reprZipWithoutNameStream(stream); } +void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const +{ + stream << "Name of double array : \"" << _name << "\"\n"; + reprNotTooLongWithoutNameStream(stream); +} + void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const { DataArray::reprWithoutNameStream(stream); @@ -1204,6 +1024,13 @@ void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const _mem.reprZip(getNumberOfComponents(),stream); } +void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const +{ + DataArray::reprWithoutNameStream(stream); + stream.precision(17); + _mem.reprNotTooLong(getNumberOfComponents(),stream); +} + void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const { int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents(); @@ -1323,22 +1150,6 @@ bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, return _mem.isEqual(other._mem,prec,tmp); } -/*! - * Changes number of tuples in the array. If the new number of tuples is smaller - * 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) -{ - 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(); -} - /*! * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this * array to the new one. @@ -1397,546 +1208,69 @@ DataArrayDouble *DataArrayDouble::toNoInterlace() const } /*! - * Permutes values of \a this array as required by \a old2New array. The values are - * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains - * the same as in \this one. - * If a permutation reduction is needed, substr() or selectByTupleId() should be used. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. - * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() - * giving a new position for i-th old value. - */ -void DataArrayDouble::renumberInPlace(const int *old2New) -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - double *tmp=new double[nbTuples*nbOfCompo]; - const double *iptr=getConstPointer(); - for(int i=0;i=0 && vgetNumberOfTuples() - * giving a previous position of i-th new value. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. + * 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::renumberInPlaceR(const int *new2Old) +void DataArrayDouble::meldWith(const DataArrayDouble *other) { checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - double *tmp=new double[nbTuples*nbOfCompo]; - const double *iptr=getConstPointer(); - for(int i=0;icheckAllocated(); + 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=0 && v compIds(nbOfComp2); + for(int i=0;igetNumberOfTuples() - * giving a new position for i-th old value. - * \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. + * This method checks that all tuples in \a other are in \a this. + * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this. + * For each i in [ 0 , other->getNumberOfTuples() ) 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 */ -DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const +bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const { - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbTuples,nbOfCompo); - ret->copyStringInfoFrom(*this); - const double *iptr=getConstPointer(); - double *optr=ret->getPointer(); - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a copy of \a this array with values permuted as required by \a new2Old array. - * The values are permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of - * tuples in the result array remains the same as in \this one. - * If a permutation reduction is needed, substr() or selectByTupleId() should be used. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. - * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples() - * giving a previous position of i-th new value. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - */ -DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbTuples,nbOfCompo); - ret->copyStringInfoFrom(*this); - const double *iptr=getConstPointer(); - double *optr=ret->getPointer(); - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is - * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array. - * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ] for all - * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which - * \a old2New[ i ] is negative, is missing from the result array. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. - * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() - * giving a new position for i-th old tuple and giving negative position for - * for i-th old tuple that should be omitted. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - */ -DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(newNbOfTuple,nbOfCompo); - const double *iptr=getConstPointer(); - double *optr=ret->getPointer(); - for(int i=0;i=0) - std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo); - } - ret->copyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is - * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by - * \a new2OldBg array. - * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]]. - * This method is equivalent to renumberAndReduce() except that convention in input is - * \c new2old and \b not \c old2new. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. - * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a - * tuple index in \a this array to fill the i-th tuple in the new array. - * \param [in] new2OldEnd - specifies the end of the permutation array that starts at - * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this: - * \a new2OldBg <= \a pi < \a new2OldEnd. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - */ -DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int nbComp=getNumberOfComponents(); - ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); - ret->copyStringInfoFrom(*this); - double *pt=ret->getPointer(); - const double *srcPt=getConstPointer(); - int i=0; - for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++) - std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp); - ret->copyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is - * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by - * \a new2OldBg array. - * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]]. - * This method is equivalent to renumberAndReduce() except that convention in input is - * \c new2old and \b not \c old2new. - * This method is equivalent to selectByTupleId() except that it prevents coping data - * from behind the end of \a this array. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. - * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a - * tuple index in \a this array to fill the i-th tuple in the new array. - * \param [in] new2OldEnd - specifies the end of the permutation array that starts at - * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this: - * \a new2OldBg <= \a pi < \a new2OldEnd. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples(). - */ -DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int nbComp=getNumberOfComponents(); - int oldNbOfTuples=getNumberOfTuples(); - ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); - ret->copyStringInfoFrom(*this); - double *pt=ret->getPointer(); - const double *srcPt=getConstPointer(); - int i=0; - for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++) - if(*w>=0 && *wgetNumberOfTuples) !"); - ret->copyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten copy of \a this array. The new DataArrayDouble contains every - * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th - * tuple. Indices of the selected tuples are the same as ones returned by the Python - * command \c range( \a bg, \a end2, \a step ). - * This method is equivalent to selectByTupleIdSafe() except that the input array is - * not constructed explicitly. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. - * \param [in] bg - index of the first tuple to copy from \a this array. - * \param [in] end2 - index of the tuple before which the tuples to copy are located. - * \param [in] step - index increment to get index of the next tuple to copy. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - * \sa DataArrayDouble::substr. - */ -DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int nbComp=getNumberOfComponents(); - int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : "); - ret->alloc(newNbOfTuples,nbComp); - double *pt=ret->getPointer(); - const double *srcPt=getConstPointer()+bg*nbComp; - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges - * of tuples specified by \a ranges parameter. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. - * \param [in] ranges - std::vector of std::pair's each of which defines a range - * of tuples in [\c begin,\c end) format. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a end < \a begin. - * \throw If \a end > \a this->getNumberOfTuples(). - * \throw If \a this is not allocated. - */ -DataArray *DataArrayDouble::selectByTupleRanges(const std::vector >& ranges) const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - int nbOfTuplesThis=getNumberOfTuples(); - if(ranges.empty()) - { - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(0,nbOfComp); - ret->copyStringInfoFrom(*this); - return ret; - } - int ref=ranges.front().first; - int nbOfTuples=0; - bool isIncreasing=true; - for(std::vector >::const_iterator it=ranges.begin();it!=ranges.end();it++) - { - if((*it).first<=(*it).second) - { - if((*it).first>=0 && (*it).second<=nbOfTuplesThis) - { - nbOfTuples+=(*it).second-(*it).first; - if(isIncreasing) - isIncreasing=ref<=(*it).first; - ref=(*it).second; - } - else - { - std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it); - oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it); - oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(isIncreasing && nbOfTuplesThis==nbOfTuples) - return deepCpy(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuples,nbOfComp); - ret->copyStringInfoFrom(*this); - const double *src=getConstPointer(); - double *work=ret->getPointer(); - for(std::vector >::const_iterator it=ranges.begin();it!=ranges.end();it++) - work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work); - return ret.retn(); -} - -/*! - * Returns a shorten copy of \a this array. The new DataArrayDouble contains all - * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before - * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr(). - * This method is a specialization of selectByTupleId2(). - * \param [in] tupleIdBg - index of the first tuple to copy from \a this array. - * \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located. - * If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied. - * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a tupleIdBg < 0. - * \throw If \a tupleIdBg > \a this->getNumberOfTuples(). - \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples(). - * \sa DataArrayDouble::selectByTupleId2 - */ -DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const -{ - checkAllocated(); - int nbt=getNumberOfTuples(); - if(tupleIdBg<0) - throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !"); - if(tupleIdBg>nbt) - throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !"); - int trueEnd=tupleIdEnd; - if(tupleIdEnd!=-1) - { - if(tupleIdEnd>nbt) - throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !"); - } - else - trueEnd=nbt; - int nbComp=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(trueEnd-tupleIdBg,nbComp); - ret->copyStringInfoFrom(*this); - std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer()); - return ret.retn(); -} - -/*! - * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less - * than \a this->getNumberOfComponents() then the result array is shorten as each tuple - * is truncated to have \a newNbOfComp components, keeping first components. If \a - * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is - * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp - * components. - * \param [in] newNbOfComp - number of components for the new array to have. - * \param [in] dftValue - value assigned to new values added to the new array. - * \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::changeNbOfComponents(int newNbOfComp, double dftValue) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(getNumberOfTuples(),newNbOfComp); - const double *oldc=getConstPointer(); - double *nc=ret->getPointer(); - int nbOfTuples=getNumberOfTuples(); - int oldNbOfComp=getNumberOfComponents(); - int dim=std::min(oldNbOfComp,newNbOfComp); - for(int i=0;isetName(getName()); - for(int i=0;isetInfoOnComponent(i,getInfoOnComponent(i)); - ret->setName(getName()); - return ret.retn(); -} - -/*! - * Changes the number of components within \a this array so that its raw data **does - * not** change, instead splitting this data into tuples changes. - * \warning This method erases all (name and unit) component info set before! - * \param [in] newNbOfComp - number of components for \a this array to have. - * \throw If \a this is not allocated - * \throw If getNbOfElems() % \a newNbOfCompo != 0. - * \throw If \a newNbOfCompo is lower than 1. - * \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !). - * \warning This method erases all (name and unit) component info set before! - */ -void DataArrayDouble::rearrange(int newNbOfCompo) -{ - checkAllocated(); - if(newNbOfCompo<1) - throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !"); - std::size_t nbOfElems=getNbOfElems(); - if(nbOfElems%newNbOfCompo!=0) - throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !"); - if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits::max()) - throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !"); - _info_on_compo.clear(); - _info_on_compo.resize(newNbOfCompo); - declareAsNew(); -} - -/*! - * Changes the number of components within \a this array to be equal to its number - * of tuples, and inversely its number of tuples to become equal to its number of - * components. So that its raw data **does not** change, instead splitting this - * data into tuples changes. - * \warning This method erases all (name and unit) component info set before! - * \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()! - * \throw If \a this is not allocated. - * \sa rearrange() - */ -void DataArrayDouble::transpose() -{ - checkAllocated(); - int nbOfTuples=getNumberOfTuples(); - rearrange(nbOfTuples); -} - -/*! - * Returns a copy of \a this array composed of selected components. - * The new DataArrayDouble has the same number of tuples but includes components - * specified by \a compoIds parameter. So that getNbOfElems() of the result array - * can be either less, same or more than \a this->getNbOfElems(). - * \param [in] compoIds - sequence of zero based indices of components to include - * into the new array. - * \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. - * \throw If a component index (\a i) is not valid: - * \a i < 0 || \a i >= \a this->getNumberOfComponents(). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example". - * \endif - */ -DataArray *DataArrayDouble::keepSelectedComponents(const std::vector& compoIds) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); - std::size_t newNbOfCompo=compoIds.size(); - int oldNbOfCompo=getNumberOfComponents(); - for(std::vector::const_iterator it=compoIds.begin();it!=compoIds.end();it++) - if((*it)<0 || (*it)>=oldNbOfCompo) - { - std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbOfTuples=getNumberOfTuples(); - ret->alloc(nbOfTuples,(int)newNbOfCompo); - ret->copyPartOfStringInfoFrom(*this,compoIds); - const double *oldc=getConstPointer(); - double *nc=ret->getPointer(); - for(int i=0;icheckAllocated(); - 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() ) 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 -{ - 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(); + 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 !"); + MCAuto a=DataArrayDouble::Aggregate(this,other); + DataArrayInt *c=0,*ci=0; + a->findCommonTuples(prec,getNumberOfTuples(),c,ci); + MCAuto cSafe(c),ciSafe(ci); + int newNbOfTuples=-1; + MCAuto ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples); + MCAuto ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1); + tupleIds=ret1.retn(); + return newNbOfTuples==getNumberOfTuples(); } /*! @@ -1970,7 +1304,7 @@ bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, * * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example". * \endif - * \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe + * \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe */ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const { @@ -1978,12 +1312,12 @@ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayI int nbOfCompo=getNumberOfComponents(); if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4."); - + int nbOfTuples=getNumberOfTuples(); // - MEDCouplingAutoRefCountObjectPtr c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0); + MCAuto c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0); switch(nbOfCompo) - { + { case 4: findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI); break; @@ -1998,7 +1332,7 @@ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayI break; default: throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !"); - } + } comm=c.retn(); commIndex=cI.retn(); } @@ -2019,7 +1353,7 @@ DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !"); int nbTuples=getNumberOfTuples(); const double *inPtr=getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1); + MCAuto ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1); double *retPtr=ret->getPointer(); for(int i=0;i part1=findClosestTupleId(other); + MCAuto part1=findClosestTupleId(other); int nbOfCompo(getNumberOfComponents()); int otherNbTuples(other->getNumberOfTuples()); const double *thisPt(begin()),*otherPt(other->begin()); @@ -2082,11 +1416,11 @@ DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) } int nbOfTuples=other->getNumberOfTuples(); int thisNbOfTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1); double bounds[6]; getMinMaxPerComponent(bounds); switch(nbOfCompo) - { + { case 3: { double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4])); @@ -2114,7 +1448,7 @@ DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) } default: throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3."); - } + } return ret.retn(); } @@ -2147,11 +1481,11 @@ DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1); + MCAuto ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1); const double *thisBBPtr(begin()); int *retPtr(ret->getPointer()); switch(nbOfComp/2) - { + { case 3: { BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps); @@ -2175,8 +1509,8 @@ DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble } default: throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !"); - } - + } + return ret.retn(); } @@ -2205,9 +1539,9 @@ DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTuple checkAllocated(); DataArrayInt *c0=0,*cI0=0; findCommonTuples(prec,limitTupleId,c0,cI0); - MEDCouplingAutoRefCountObjectPtr c(c0),cI(cI0); + MCAuto c(c0),cI(cI0); int newNbOfTuples=-1; - MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples); + MCAuto o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples); return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples); } @@ -2242,755 +1576,25 @@ void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std: nc[nbOfCompo*i+compoIds[j]]=*ac; } -/*! - * Copy all values from another DataArrayDouble into specified tuples and components - * of \a this array. Textual data is not copied. - * The tree parameters defining set of indices of tuples and components are similar to - * the tree parameters of the Python function \c range(\c start,\c stop,\c step). - * \param [in] a - the array to copy values from. - * \param [in] bgTuples - index of the first tuple of \a this array to assign values to. - * \param [in] endTuples - index of the tuple before which the tuples to assign to - * are located. - * \param [in] stepTuples - index increment to get index of the next tuple to assign to. - * \param [in] bgComp - index of the first component of \a this array to assign values to. - * \param [in] endComp - index of the component before which the components to assign - * to are located. - * \param [in] stepComp - index increment to get index of the next component to assign to. - * \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() - * must be equal to the number of columns to assign to, else an - * exception is thrown; if \a false, then it is only required that \a - * a->getNbOfElems() equals to number of values to assign to (this condition - * must be respected even if \a strictCompoCompare is \a true). The number of - * values to assign to is given by following Python expression: - * \a nbTargetValues = - * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) * - * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). - * \throw If \a a is NULL. - * \throw If \a a is not allocated. - * \throw If \a this is not allocated. - * \throw If parameters specifying tuples and components to assign to do not give a - * non-empty range of increasing indices. - * \throw If \a a->getNbOfElems() != \a nbTargetValues. - * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() != - * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example". - * \endif - */ -void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) +void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet) { - if(!a) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !"); - const char msg[]="DataArrayDouble::setPartOfValues1"; - checkAllocated(); - a->checkAllocated(); - int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg); - int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value"); - DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - const double *srcPt=a->getConstPointer(); - double *pt=getPointer()+bgTuples*nbComp+bgComp; - if(assignTech) - { - for(int i=0;idecrRef(); + arrayToSet=newArray; + if(arrayToSet) + arrayToSet->incrRef(); } } -/*! - * Assign a given value to values at specified tuples and components of \a this array. - * The tree parameters defining set of indices of tuples and components are similar to - * the tree parameters of the Python function \c range(\c start,\c stop,\c step).. - * \param [in] a - the value to assign. - * \param [in] bgTuples - index of the first tuple of \a this array to assign to. - * \param [in] endTuples - index of the tuple before which the tuples to assign to - * are located. - * \param [in] stepTuples - index increment to get index of the next tuple to assign to. - * \param [in] bgComp - index of the first component of \a this array to assign to. - * \param [in] endComp - index of the component before which the components to assign - * to are located. - * \param [in] stepComp - index increment to get index of the next component to assign to. - * \throw If \a this is not allocated. - * \throw If parameters specifying tuples and components to assign to, do not give a - * non-empty range of increasing indices or indices are out of a valid range - * for \this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example". - * \endif - */ -void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) -{ - const char msg[]="DataArrayDouble::setPartOfValuesSimple1"; - checkAllocated(); - int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg); - int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value"); - DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - double *pt=getPointer()+bgTuples*nbComp+bgComp; - for(int i=0;igetNbOfElems() equals to number of values to assign to, then every value - * of \a a is assigned to its own location within \a this array. - * - If \a a includes one tuple, then all values of \a a are assigned to the specified - * components of every specified tuple of \a this array. In this mode it is required - * that \a a->getNumberOfComponents() equals to the number of specified components. - * - * \param [in] a - the array to copy values from. - * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to - * assign values of \a a to. - * \param [in] endTuples - specifies the end of the array \a bgTuples, so that - * pointer to a tuple index (pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - pointer to an array of component indices of \a this array to - * assign values of \a a to. - * \param [in] endComp - specifies the end of the array \a bgTuples, so that - * pointer to a component index (pi) varies as this: - * \a bgComp <= \a pi < \a endComp. - * \param [in] strictCompoCompare - this parameter is checked only if the - * *mode of usage* is the first; if it is \a true (default), - * then \a a->getNumberOfComponents() must be equal - * to the number of specified columns, else this is not required. - * \throw If \a a is NULL. - * \throw If \a a is not allocated. - * \throw If \a this is not allocated. - * \throw If any index of tuple/component given by bgTuples / bgComp is - * out of a valid range for \a this array. - * \throw In the first *mode of usage*, if strictCompoCompare == true and - * if a->getNumberOfComponents() != (endComp - bgComp) . - * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or - * a->getNumberOfComponents() != (endComp - bgComp). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example". - * \endif - */ -void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !"); - const char msg[]="DataArrayDouble::setPartOfValues2"; - checkAllocated(); - a->checkAllocated(); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - for(const int *z=bgComp;z!=endComp;z++) - DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); - int newNbOfTuples=(int)std::distance(bgTuples,endTuples); - int newNbOfComp=(int)std::distance(bgComp,endComp); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - double *pt=getPointer(); - const double *srcPt=a->getConstPointer(); - if(assignTech) - { - for(const int *w=bgTuples;w!=endTuples;w++) - { - DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); - for(const int *z=bgComp;z!=endComp;z++,srcPt++) - { - pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt; - } - } - } - else - { - for(const int *w=bgTuples;w!=endTuples;w++) - { - const double *srcPt2=srcPt; - DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); - for(const int *z=bgComp;z!=endComp;z++,srcPt2++) - { - pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2; - } - } - } -} - -/*! - * Assign a given value to values at specified tuples and components of \a this array. - * The tuples and components to assign to are defined by C arrays of indices. - * \param [in] a - the value to assign. - * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to - * assign \a a to. - * \param [in] endTuples - specifies the end of the array \a bgTuples, so that - * pointer to a tuple index (\a pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - pointer to an array of component indices of \a this array to - * assign \a a to. - * \param [in] endComp - specifies the end of the array \a bgTuples, so that - * pointer to a component index (\a pi) varies as this: - * \a bgComp <= \a pi < \a endComp. - * \throw If \a this is not allocated. - * \throw If any index of tuple/component given by bgTuples / bgComp is - * out of a valid range for \a this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example". - * \endif - */ -void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) -{ - checkAllocated(); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - for(const int *z=bgComp;z!=endComp;z++) - DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); - double *pt=getPointer(); - for(const int *w=bgTuples;w!=endTuples;w++) - for(const int *z=bgComp;z!=endComp;z++) - { - DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); - pt[(std::size_t)(*w)*nbComp+(*z)]=a; - } -} - -/*! - * Copy all values from another DataArrayDouble (\a a) into specified tuples and - * components of \a this array. Textual data is not copied. - * The tuples to assign to are defined by a C array of indices. - * The components to assign to are defined by three values similar to parameters of - * the Python function \c range(\c start,\c stop,\c step). - * There are two *modes of usage*: - * - If \a a->getNbOfElems() equals to number of values to assign to, then every value - * of \a a is assigned to its own location within \a this array. - * - If \a a includes one tuple, then all values of \a a are assigned to the specified - * components of every specified tuple of \a this array. In this mode it is required - * that \a a->getNumberOfComponents() equals to the number of specified components. - * - * \param [in] a - the array to copy values from. - * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to - * assign values of \a a to. - * \param [in] endTuples - specifies the end of the array \a bgTuples, so that - * pointer to a tuple index (pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - index of the first component of \a this array to assign to. - * \param [in] endComp - index of the component before which the components to assign - * to are located. - * \param [in] stepComp - index increment to get index of the next component to assign to. - * \param [in] strictCompoCompare - this parameter is checked only in the first - * *mode of usage*; if \a strictCompoCompare is \a true (default), - * then \a a->getNumberOfComponents() must be equal - * to the number of specified columns, else this is not required. - * \throw If \a a is NULL. - * \throw If \a a is not allocated. - * \throw If \a this is not allocated. - * \throw If any index of tuple given by \a bgTuples is out of a valid range for - * \a this array. - * \throw In the first *mode of usage*, if strictCompoCompare == true and - * if a->getNumberOfComponents() is unequal to the number of components - * defined by (bgComp,endComp,stepComp). - * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or - * a->getNumberOfComponents() is unequal to the number of components - * defined by (bgComp,endComp,stepComp). - * \throw If parameters specifying components to assign to, do not give a - * non-empty range of increasing indices or indices are out of a valid range - * for \this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example". - * \endif - */ -void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !"); - const char msg[]="DataArrayDouble::setPartOfValues3"; - checkAllocated(); - a->checkAllocated(); - int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - int newNbOfTuples=(int)std::distance(bgTuples,endTuples); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - double *pt=getPointer()+bgComp; - const double *srcPt=a->getConstPointer(); - if(assignTech) - { - for(const int *w=bgTuples;w!=endTuples;w++) - for(int j=0;j(pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - index of the first component of \a this array to assign to. - * \param [in] endComp - index of the component before which the components to assign - * to are located. - * \param [in] stepComp - index increment to get index of the next component to assign to. - * \throw If \a this is not allocated. - * \throw If any index of tuple given by \a bgTuples is out of a valid range for - * \a this array. - * \throw If parameters specifying components to assign to, do not give a - * non-empty range of increasing indices or indices are out of a valid range - * for \this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example". - * \endif - */ -void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) -{ - const char msg[]="DataArrayDouble::setPartOfValuesSimple3"; - checkAllocated(); - int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - double *pt=getPointer()+bgComp; - for(const int *w=bgTuples;w!=endTuples;w++) - for(int j=0;jgetNumberOfComponents() - * must be equal to the number of columns to assign to, else an - * exception is thrown; if \a false, then it is only required that \a - * a->getNbOfElems() equals to number of values to assign to (this condition - * must be respected even if \a strictCompoCompare is \a true). The number of - * values to assign to is given by following Python expression: - * \a nbTargetValues = - * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) * - * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). - * \throw If \a a is NULL. - * \throw If \a a is not allocated. - * \throw If \a this is not allocated. - * \throw If parameters specifying tuples and components to assign to do not give a - * non-empty range of increasing indices. - * \throw If \a a->getNbOfElems() != \a nbTargetValues. - * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() != - * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). - * - */ -void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !"); - const char msg[]="DataArrayDouble::setPartOfValues4"; - checkAllocated(); - a->checkAllocated(); - int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg); - int newNbOfComp=(int)std::distance(bgComp,endComp); - int nbComp=getNumberOfComponents(); - for(const int *z=bgComp;z!=endComp;z++) - DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value"); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - const double *srcPt=a->getConstPointer(); - double *pt=getPointer()+bgTuples*nbComp; - if(assignTech) - { - for(int i=0;ithis->getNumberOfComponents() != a->getNumberOfComponents(). - * \throw If \a tuplesSelec->getNumberOfComponents() != 2. - * \throw If any tuple index given by \a tuplesSelec is out of a valid range for - * the corresponding (\a this or \a a) array. - */ -void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) -{ - if(!a || !tuplesSelec) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !"); - checkAllocated(); - a->checkAllocated(); - tuplesSelec->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !"); - if(tuplesSelec->getNumberOfComponents()!=2) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - double *valsToSet=getPointer(); - const double *valsSrc=a->getConstPointer(); - for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2) - { - if(tuple[1]>=0 && tuple[1]=0 && tuple[0]begin(),tuple)/2; - oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2; - oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -/*! - * 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 - * their number is defined by \a tuplesSelec->getNumberOfTuples(). - * The tuples to copy are defined by values of a 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] 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 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() != 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 aBase array. - */ -void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) -{ - if(!aBase || !tuplesSelec) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !"); - const DataArrayDouble *a=dynamic_cast(aBase); - if(!a) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !"); - checkAllocated(); - a->checkAllocated(); - tuplesSelec->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !"); - if(tuplesSelec->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples(); - double *valsToSet=getPointer()+tupleIdStart*nbOfComp; - if(tupleIdStart+nbOfTupleToWrite>thisNt) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !"); - const double *valsSrc=a->getConstPointer(); - for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp) - { - if(*tuple>=0 && *tuplebegin(),tuple); - oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -/*! - * 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 - * the Python function \c range(\c start,\c stop,\c step). - * The tuples to assign to are defined by index of the first tuple, and - * their number is defined by number of tuples to copy. - * 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] 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 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 aBase. - */ -void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) -{ - if(!aBase) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !"); - const DataArrayDouble *a=dynamic_cast(aBase); - if(!a) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !"); - checkAllocated(); - a->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2"; - int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - double *valsToSet=getPointer()+tupleIdStart*nbOfComp; - if(tupleIdStart+nbOfTupleToWrite>thisNt) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !"); - if(end2>aNt) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !"); - const double *valsSrc=a->getConstPointer()+bg*nbOfComp; - for(int i=0;i( 0 <= tupleId < this->getNumberOfTuples() ) is violated. - * \throw If condition ( 0 <= compoId < this->getNumberOfComponents() ) is violated. - */ -double DataArrayDouble::getIJSafe(int tupleId, int compoId) const -{ - checkAllocated(); - if(tupleId<0 || tupleId>=getNumberOfTuples()) - { - std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(compoId<0 || compoId>=getNumberOfComponents()) - { - std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - 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 -{ - 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. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If \a this->getNumberOfTuples() < 1. - */ -double DataArrayDouble::back() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<1) - throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !"); - return *(getConstPointer()+nbOfTuples-1); -} - -void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet) -{ - if(newArray!=arrayToSet) - { - if(arrayToSet) - arrayToSet->decrRef(); - arrayToSet=newArray; - if(arrayToSet) - arrayToSet->incrRef(); - } -} - -/*! - * Sets a C array to be used as raw data of \a this. The previously set info - * of components is retained and re-sized. - * For more info see \ref MEDCouplingArraySteps1. - * \param [in] array - the C array to be used as raw data of \a this. - * \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this. - * \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC, - * \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC, - * \c free(\c array ) will be called. - * \param [in] nbOfTuple - new number of tuples in \a this. - * \param [in] nbOfCompo - new number of components in \a this. - */ -void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) -{ - _info_on_compo.resize(nbOfCompo); - _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo); - declareAsNew(); -} - -void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) +void DataArrayDouble::aggregate(const DataArrayDouble *other) { - _info_on_compo.resize(nbOfCompo); - _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo); - declareAsNew(); + 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()); } /*! @@ -3061,7 +1665,7 @@ DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const const double *dataPtr=getConstPointer(); int nbOfCompo=getNumberOfComponents(); int nbTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr bbox=DataArrayDouble::New(); + MCAuto bbox=DataArrayDouble::New(); bbox->alloc(nbTuples,2*nbOfCompo); double *bboxPtr=bbox->getPointer(); for(int i=0;igetNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0); + MCAuto cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0); switch(nbOfCompo) - { + { case 3: { BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps); @@ -3127,7 +1731,7 @@ void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, do } default: throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3."); - } + } c=cArr.retn(); cI=cIArr.retn(); } @@ -3154,40 +1758,6 @@ void DataArrayDouble::recenterForMaxPrecision(double eps) } } -/*! - * Returns the maximal value and its location within \a this one-dimensional array. - * \param [out] tupleId - index of the tuple holding the maximal value. - * \return double - the maximal value among all values of \a this array. - * \throw If \a this->getNumberOfComponents() != 1 - * \throw If \a this->getNumberOfTuples() < 1 - */ -double DataArrayDouble::getMaxValue(int& tupleId) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before or call 'getMaxValueInArray' method !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<=0) - throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !"); - const double *vals=getConstPointer(); - const double *loc=std::max_element(vals,vals+nbOfTuples); - tupleId=(int)std::distance(vals,loc); - return *loc; -} - -/*! - * Returns the maximal value within \a this array that is allowed to have more than - * one component. - * \return double - the maximal value among all values of \a this array. - * \throw If \a this is not allocated. - */ -double DataArrayDouble::getMaxValueInArray() const -{ - checkAllocated(); - const double *loc=std::max_element(begin(),end()); - return *loc; -} - /*! * Returns the maximal value and all its locations within \a this one-dimensional array. * \param [out] tupleIds - a new instance of DataArrayInt containg indices of @@ -3202,60 +1772,26 @@ double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const int tmp; tupleIds=0; double ret=getMaxValue(tmp); - tupleIds=getIdsInRange(ret,ret); + tupleIds=findIdsInRange(ret,ret); return ret; } /*! - * Returns the minimal value and its location within \a this one-dimensional array. - * \param [out] tupleId - index of the tuple holding the minimal value. + * Returns the minimal value and all its locations within \a this one-dimensional array. + * \param [out] tupleIds - a new instance of DataArrayInt containg indices of + * tuples holding the minimal value. The caller is to delete it using + * decrRef() as it is no more needed. * \return double - the minimal value among all values of \a this array. * \throw If \a this->getNumberOfComponents() != 1 * \throw If \a this->getNumberOfTuples() < 1 */ -double DataArrayDouble::getMinValue(int& tupleId) const +double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const { - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<=0) - throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !"); - const double *vals=getConstPointer(); - const double *loc=std::min_element(vals,vals+nbOfTuples); - tupleId=(int)std::distance(vals,loc); - return *loc; -} - -/*! - * Returns the minimal value within \a this array that is allowed to have more than - * one component. - * \return double - the minimal value among all values of \a this array. - * \throw If \a this is not allocated. - */ -double DataArrayDouble::getMinValueInArray() const -{ - checkAllocated(); - const double *loc=std::min_element(begin(),end()); - return *loc; -} - -/*! - * Returns the minimal value and all its locations within \a this one-dimensional array. - * \param [out] tupleIds - a new instance of DataArrayInt containg indices of - * tuples holding the minimal value. The caller is to delete it using - * decrRef() as it is no more needed. - * \return double - the minimal value among all values of \a this array. - * \throw If \a this->getNumberOfComponents() != 1 - * \throw If \a this->getNumberOfTuples() < 1 - */ -double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const -{ - int tmp; - tupleIds=0; - double ret=getMinValue(tmp); - tupleIds=getIdsInRange(ret,ret); - return ret; + int tmp; + tupleIds=0; + double ret=getMinValue(tmp); + tupleIds=findIdsInRange(ret,ret); + return ret; } /*! @@ -3469,7 +2005,7 @@ DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, cons if(sz<1) throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !"); sz--; - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo); + MCAuto ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo); const int *w=bgOfIndex; if(*w<0 || *w>=nbOfTuples) throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !"); @@ -3514,14 +2050,14 @@ DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, cons DataArrayDouble *DataArrayDouble::fromPolarToCart() const { checkAllocated(); - int nbOfComp=getNumberOfComponents(); + int nbOfComp(getNumberOfComponents()); if(nbOfComp!=2) throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !"); - int nbOfTuple=getNumberOfTuples(); - DataArrayDouble *ret=DataArrayDouble::New(); + int nbOfTuple(getNumberOfTuples()); + DataArrayDouble *ret(DataArrayDouble::New()); ret->alloc(nbOfTuple,2); - double *w=ret->getPointer(); - const double *wIn=getConstPointer(); + double *w(ret->getPointer()); + const double *wIn(getConstPointer()); for(int i=0;ialloc(getNumberOfTuples(),3); - double *w=ret->getPointer(); - const double *wIn=getConstPointer(); + double *w(ret->getPointer()); + const double *wIn(getConstPointer()); for(int i=0;ialloc(getNumberOfTuples(),3); - double *w=ret->getPointer(); - const double *wIn=getConstPointer(); + double *w(ret->getPointer()); + const double *wIn(getConstPointer()); for(int i=0;i ret; + switch(atOfThis) + { + case AX_CART: + ret=deepCopy(); + case AX_CYL: + if(nbOfComp==3) + { + ret=fromCylToCart(); + break; + } + if(nbOfComp==2) + { + ret=fromPolarToCart(); + break; + } + else + throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !"); + case AX_SPHER: + if(nbOfComp==3) + { + ret=fromSpherToCart(); + break; + } + if(nbOfComp==2) + { + ret=fromPolarToCart(); + break; + } + else + throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !"); + default: + throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !"); + } + ret->copyStringInfoFrom(*this); + return ret.retn(); +} + /*! * Computes the doubly contracted product of every tensor defined by the tuple of \a this * array contating 6 components. @@ -3605,7 +2191,7 @@ DataArrayDouble *DataArrayDouble::fromSpherToCart() const DataArrayDouble *DataArrayDouble::doublyContractedProduct() const { checkAllocated(); - int nbOfComp=getNumberOfComponents(); + int nbOfComp(getNumberOfComponents()); if(nbOfComp!=6) throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !"); DataArrayDouble *ret=DataArrayDouble::New(); @@ -3637,7 +2223,7 @@ DataArrayDouble *DataArrayDouble::determinant() const const double *src=getConstPointer(); double *dest=ret->getPointer(); switch(getNumberOfComponents()) - { + { case 6: for(int i=0;idecrRef(); throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !"); - } + } } /*! @@ -3735,7 +2321,7 @@ DataArrayDouble *DataArrayDouble::inverse() const ret->alloc(nbOfTuple,nbOfComp); const double *src=getConstPointer(); double *dest=ret->getPointer(); -if(nbOfComp==6) + if(nbOfComp==6) for(int i=0;i ret(DataArrayDouble::New()); + MCAuto ret(DataArrayDouble::New()); ret->alloc(nbOfTuple,1); const double *src(getConstPointer()); double *dest(ret->getPointer()); @@ -3902,7 +2488,7 @@ DataArrayDouble *DataArrayDouble::maxPerTuple() const { checkAllocated(); int nbOfComp=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); + MCAuto ret=DataArrayDouble::New(); int nbOfTuple=getNumberOfTuples(); ret->alloc(nbOfTuple,1); const double *src=getConstPointer(); @@ -3929,8 +2515,8 @@ DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdO { checkAllocated(); int nbOfComp=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret0=DataArrayDouble::New(); - MEDCouplingAutoRefCountObjectPtr ret1=DataArrayInt::New(); + MCAuto ret0=DataArrayDouble::New(); + MCAuto ret1=DataArrayInt::New(); int nbOfTuple=getNumberOfTuples(); ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1); const double *src=getConstPointer(); @@ -3953,7 +2539,7 @@ DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdO * * \warning use this method with care because it can leads to big amount of consumed memory ! * - * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with. + * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with. * * \throw If \a this is not allocated. * @@ -3965,7 +2551,7 @@ DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const int nbOfComp=getNumberOfComponents(); int nbOfTuples=getNumberOfTuples(); const double *inData=getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); + MCAuto ret=DataArrayDouble::New(); ret->alloc(nbOfTuples*nbOfTuples,1); double *outData=ret->getPointer(); for(int i=0;igetNumberOfTuples(); const double *inData=getConstPointer(); const double *inDataOther=other->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); + MCAuto ret=DataArrayDouble::New(); ret->alloc(otherNbOfTuples*nbOfTuples,1); double *outData=ret->getPointer(); for(int i=0;i(x) becomes \f$ a * x + b \f$. * \param [in] a - the first coefficient of the function. * \param [in] b - the second coefficient of the function. * \param [in] compoId - the index of component to modify. - * \throw If \a this is not allocated. + * \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ). */ void DataArrayDouble::applyLin(double a, double b, int compoId) { checkAllocated(); - double *ptr=getPointer()+compoId; - int nbOfComp=getNumberOfComponents(); - int nbOfTuple=getNumberOfTuples(); + double *ptr(getPointer()+compoId); + int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples()); + if(compoId<0 || compoId>=nbOfComp) + { + std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } for(int i=0;i 1. ...) leads to a throw of an exception. + * If false the computation is carried on without any notification. When false the evaluation is a little faster. * \return DataArrayDouble * - the new instance of DataArrayDouble containing the * same number of tuples as \a this array and \a nbOfComp components. * The caller is to delete this result array using decrRef() as it is no more @@ -4298,144 +2890,210 @@ DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate fun * \throw If \a this is not allocated. * \throw If computing \a func fails. */ -DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func) const +DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const { - checkAllocated(); INTERP_KERNEL::ExprParser expr(func); expr.parse(); std::set vars; expr.getTrueSetOfVars(vars); - int oldNbOfComp=getNumberOfComponents(); - if((int)vars.size()>oldNbOfComp) - { - std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are "; - oss << vars.size() << " variables : "; - std::copy(vars.begin(),vars.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } std::vector varsV(vars.begin(),vars.end()); - expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp); - // - DataArrayDouble *newArr=DataArrayDouble::New(); - int nbOfTuples=getNumberOfTuples(); - newArr->alloc(nbOfTuples,nbOfComp); - const double *ptr=getConstPointer(); - double *ptrToFill=newArr->getPointer(); - for(int i=0;i(oss,", ")); - oss << ") : Evaluation of function failed !" << e.what(); - newArr->decrRef(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return newArr; + return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe); } /*! * Returns a new DataArrayDouble created from \a this one by applying a function to every - * tuple of \a this array. Textual data is not copied. + * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size). + * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster. + * * For more info see \ref MEDCouplingArrayApplyFunc0. * \param [in] func - the expression defining how to transform a tuple of \a this array. * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here". + * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception. + * If false the computation is carried on without any notification. When false the evaluation is a little faster. * \return DataArrayDouble * - the new instance of DataArrayDouble containing the * same number of tuples and components as \a this array. * The caller is to delete this result array using decrRef() as it is no more * needed. + * \sa applyFuncOnThis * \throw If \a this is not allocated. * \throw If computing \a func fails. */ -DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func) const +DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const { + int nbOfComp(getNumberOfComponents()); + if(nbOfComp<=0) + throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !"); checkAllocated(); + int nbOfTuples(getNumberOfTuples()); + MCAuto newArr(DataArrayDouble::New()); + newArr->alloc(nbOfTuples,nbOfComp); INTERP_KERNEL::ExprParser expr(func); expr.parse(); - expr.prepareExprEvaluationVec(); - // - DataArrayDouble *newArr=DataArrayDouble::New(); - int nbOfTuples=getNumberOfTuples(); - int nbOfComp=getNumberOfComponents(); - newArr->alloc(nbOfTuples,nbOfComp); - const double *ptr=getConstPointer(); - double *ptrToFill=newArr->getPointer(); - for(int i=0;i vars; + expr.getTrueSetOfVars(vars); + if((int)vars.size()>1) + { + std::ostringstream oss; oss << "DataArrayDouble::applyFunc : this method works only with at most one var func expression ! If you need to map comps on variables please use applyFuncCompo or applyFuncNamedCompo instead ! Vars in expr are : "; + std::copy(vars.begin(),vars.end(),std::ostream_iterator(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(vars.empty()) + { + expr.prepareFastEvaluator(); + newArr->rearrange(1); + newArr->fillWithValue(expr.evaluateDouble()); + newArr->rearrange(nbOfComp); + return newArr.retn(); + } + std::vector vars2(vars.begin(),vars.end()); + double buff,*ptrToFill(newArr->getPointer()); + const double *ptr(begin()); + std::vector stck; + expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1); + expr.prepareFastEvaluator(); + if(!isSafe) { - try + for(int i=0;i(oss,", ")); - oss << ") : Evaluation of function failed ! " << e.what(); - newArr->decrRef(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); + for(int iComp=0;iCompgetInfoOnComponent(). - * \throw If computing \a func fails. + * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception. + * If false the computation is carried on without any notification. When false the evaluation is a little faster. + * + * \sa applyFunc */ -DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const std::string& func) const +void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe) { + int nbOfComp(getNumberOfComponents()); + if(nbOfComp<=0) + throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !"); checkAllocated(); + int nbOfTuples(getNumberOfTuples()); INTERP_KERNEL::ExprParser expr(func); expr.parse(); std::set vars; expr.getTrueSetOfVars(vars); - int oldNbOfComp=getNumberOfComponents(); - if((int)vars.size()>oldNbOfComp) + if((int)vars.size()>1) { - std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are "; - oss << vars.size() << " variables : "; + std::ostringstream oss; oss << "DataArrayDouble::applyFuncOnThis : this method works only with at most one var func expression ! If you need to map comps on variables please use applyFuncCompo or applyFuncNamedCompo instead ! Vars in expr are : "; std::copy(vars.begin(),vars.end(),std::ostream_iterator(oss," ")); throw INTERP_KERNEL::Exception(oss.str().c_str()); } - expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp); - // - DataArrayDouble *newArr=DataArrayDouble::New(); - int nbOfTuples=getNumberOfTuples(); - newArr->alloc(nbOfTuples,nbOfComp); - const double *ptr=getConstPointer(); - double *ptrToFill=newArr->getPointer(); - for(int i=0;i compInfo(getInfoOnComponents()); + rearrange(1); + fillWithValue(expr.evaluateDouble()); + rearrange(nbOfComp); + setInfoOnComponents(compInfo); + return ; + } + std::vector vars2(vars.begin(),vars.end()); + double buff,*ptrToFill(getPointer()); + const double *ptr(begin()); + std::vector stck; + expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1); + expr.prepareFastEvaluator(); + if(!isSafe) { - try + for(int i=0;i(oss,", ")); - oss << ") : Evaluation of function failed !" << e.what(); - newArr->decrRef(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); + for(int iComp=0;iComp 1. ...) leads to a throw of an exception. + * If false the computation is carried on without any notification. When false the evaluation is a little faster. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of tuples 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. + * \throw If \a func contains vars that are not in \a this->getInfoOnComponent(). + * \throw If computing \a func fails. + */ +DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const +{ + return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe); } /*! @@ -4446,6 +3104,8 @@ DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const std::string& fu * \param [in] varsOrder - sequence of vars defining their order. * \param [in] func - the expression defining how to transform a tuple of \a this array. * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here". + * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception. + * If false the computation is carried on without any notification. When false the evaluation is a little faster. * \return DataArrayDouble * - the new instance of DataArrayDouble containing the * same number of tuples as \a this array. * The caller is to delete this result array using decrRef() as it is no more @@ -4454,14 +3114,20 @@ DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const std::string& fu * \throw If \a func contains vars not in \a varsOrder. * \throw If computing \a func fails. */ -DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector& varsOrder, const std::string& func) const +DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector& varsOrder, const std::string& func, bool isSafe) const { + if(nbOfComp<=0) + throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !"); + std::vector varsOrder2(varsOrder); + int oldNbOfComp(getNumberOfComponents()); + for(int i=(int)varsOrder.size();i vars; expr.getTrueSetOfVars(vars); - int oldNbOfComp=getNumberOfComponents(); if((int)vars.size()>oldNbOfComp) { std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are "; @@ -4469,29 +3135,49 @@ DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector(oss," ")); throw INTERP_KERNEL::Exception(oss.str().c_str()); } - expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp); - // - DataArrayDouble *newArr=DataArrayDouble::New(); - int nbOfTuples=getNumberOfTuples(); + MCAuto newArr(DataArrayDouble::New()); newArr->alloc(nbOfTuples,nbOfComp); - const double *ptr=getConstPointer(); - double *ptrToFill=newArr->getPointer(); - for(int i=0;i buff(new double[oldNbOfComp]); + double *buffPtr(buff),*ptrToFill; + std::vector stck; + for(int iComp=0;iCompgetPointer()+iComp; + if(!isSafe) + { + for(int i=0;i(oss,", ")); - oss << ") : Evaluation of function failed !" << e.what(); - newArr->decrRef(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); + for(int i=0;i(oss,", ")); + oss << ") : Evaluation of function failed !" << e.what(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } } } - return newArr; + return newArr.retn(); } void DataArrayDouble::applyFuncFast32(const std::string& func) @@ -4530,6 +3216,21 @@ void DataArrayDouble::applyFuncFast64(const std::string& func) declareAsNew(); } +/*! + * \return a new object that is the result of the symmetry along 3D plane defined by its normal vector \a normalVector and a point \a point. + */ +MCAuto DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const +{ + checkAllocated(); + if(getNumberOfComponents()!=3) + throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !"); + int nbTuples(getNumberOfTuples()); + MCAuto ret(DataArrayDouble::New()); + ret->alloc(nbTuples,3); + Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer()); + return ret; +} + DataArrayDoubleIterator *DataArrayDouble::iterator() { return new DataArrayDoubleIterator(this); @@ -4545,20 +3246,20 @@ DataArrayDoubleIterator *DataArrayDouble::iterator() * needed. * \throw If \a this->getNumberOfComponents() != 1. * - * \sa DataArrayDouble::getIdsNotInRange + * \sa DataArrayDouble::findIdsNotInRange * * \if ENABLE_EXAMPLES * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".
* \ref py_mcdataarraydouble_getidsinrange "Here is a Python example". * \endif */ -DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const +DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const { checkAllocated(); if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !"); + throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !"); const double *cptr(begin()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); + MCAuto ret(DataArrayInt::New()); ret->alloc(0,1); int nbOfTuples(getNumberOfTuples()); for(int i=0;i=vmin && *cptr<=vmax) @@ -4576,15 +3277,15 @@ DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const * needed. * \throw If \a this->getNumberOfComponents() != 1. * - * \sa DataArrayDouble::getIdsInRange + * \sa DataArrayDouble::findIdsInRange */ -DataArrayInt *DataArrayDouble::getIdsNotInRange(double vmin, double vmax) const +DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const { checkAllocated(); if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsNotInRange : this must have exactly one component !"); + throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !"); const double *cptr(begin()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); + MCAuto ret(DataArrayInt::New()); ret->alloc(0,1); int nbOfTuples(getNumberOfTuples()); for(int i=0;ivmax) @@ -4645,7 +3346,7 @@ DataArrayDouble *DataArrayDouble::Aggregate(const std::vectorgetNumberOfTuples(); } - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); + MCAuto ret=DataArrayDouble::New(); ret->alloc(nbt,nbOfComp); double *pt=ret->getPointer(); for(it=a.begin();it!=a.end();it++) @@ -4925,7 +3626,7 @@ DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArray int nbOfTuple2=a2->getNumberOfTuples(); int nbOfComp=a1->getNumberOfComponents(); int nbOfComp2=a2->getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=0; + MCAuto ret=0; if(nbOfTuple==nbOfTuple2) { if(nbOfComp==nbOfComp2) @@ -5085,7 +3786,7 @@ DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const Dat { if(nbOfComp1==nbOfComp2) { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); + MCAuto ret=DataArrayDouble::New(); ret->alloc(nbOfTuple2,nbOfComp1); std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus()); ret->copyStringInfoFrom(*a1); @@ -5093,7 +3794,7 @@ DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const Dat } else if(nbOfComp2==1) { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); + MCAuto ret=DataArrayDouble::New(); ret->alloc(nbOfTuple1,nbOfComp1); const double *a2Ptr=a2->getConstPointer(); const double *a1Ptr=a1->getConstPointer(); @@ -5112,7 +3813,7 @@ DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const Dat else if(nbOfTuple2==1) { a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); + MCAuto ret=DataArrayDouble::New(); ret->alloc(nbOfTuple1,nbOfComp1); const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); double *pt=ret->getPointer(); @@ -5222,7 +3923,7 @@ DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const Data int nbOfTuple2=a2->getNumberOfTuples(); int nbOfComp=a1->getNumberOfComponents(); int nbOfComp2=a2->getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=0; + MCAuto ret=0; if(nbOfTuple==nbOfTuple2) { if(nbOfComp==nbOfComp2) @@ -5383,7 +4084,7 @@ DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataAr { if(nbOfComp1==nbOfComp2) { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); + MCAuto ret=DataArrayDouble::New(); ret->alloc(nbOfTuple2,nbOfComp1); std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides()); ret->copyStringInfoFrom(*a1); @@ -5391,7 +4092,7 @@ DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataAr } else if(nbOfComp2==1) { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); + MCAuto ret=DataArrayDouble::New(); ret->alloc(nbOfTuple1,nbOfComp1); const double *a2Ptr=a2->getConstPointer(); const double *a1Ptr=a1->getConstPointer(); @@ -5410,7 +4111,7 @@ DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataAr else if(nbOfTuple2==1) { a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); + MCAuto ret=DataArrayDouble::New(); ret->alloc(nbOfTuple1,nbOfComp1); const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); double *pt=ret->getPointer(); @@ -5514,7 +4215,7 @@ DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArray throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !"); if(nbOfComp!=1 || nbOfComp2!=1) throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1); + MCAuto ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1); const double *ptr1(a1->begin()),*ptr2(a2->begin()); double *ptr=ret->getPointer(); for(int i=0;i DataArrayDouble::toVectorOfBool(double eps) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !"); + int nbt(getNumberOfTuples()); + std::vector ret(nbt); + const double *pt(begin()); + for(int i=0;i& tinyInfoI, c } } +/*! + * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn + * around an axe ( \a center, \a vect) and with angle \a angle. + */ +void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut) +{ + if(!center || !vect) + throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !"); + double sina(sin(angle)); + double cosa(cos(angle)); + double vectorNorm[3]; + double matrix[9]; + double matrixTmp[9]; + double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2])); + if(norm::min()) + throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !"); + std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies(),1/norm)); + //rotation matrix computation + matrix[0]=cosa; matrix[1]=0.; matrix[2]=0.; matrix[3]=0.; matrix[4]=cosa; matrix[5]=0.; matrix[6]=0.; matrix[7]=0.; matrix[8]=cosa; + matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2]; + matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2]; + matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2]; + std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies(),1-cosa)); + std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus()); + matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1]; + matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0]; + matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.; + std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies(),sina)); + std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus()); + //rotation matrix computed. + double tmp[3]; + for(int i=0; i()); + coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0]; + coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1]; + coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2]; + } +} + +void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut) +{ + double matrix[9],matrix2[9],matrix3[9]; + double vect[3],crossVect[3]; + INTERP_KERNEL::orthogonalVect3(normalVector,vect); + crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1]; + crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2]; + crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0]; + double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect)); + matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni; + matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni; + matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni; + matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv; + matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc; + matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni; + for(int i=0;i<3;i++) + for(int j=0;j<3;j++) + { + double val(0.); + for(int k=0;k<3;k++) + val+=matrix[3*i+k]*matrix2[3*k+j]; + matrix3[3*i+j]=val; + } + //rotation matrix computed. + double tmp[3]; + for(int i=0; i()); + coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0]; + coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1]; + coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2]; + } +} + +void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9]) +{ + double vect[3],crossVect[3]; + INTERP_KERNEL::orthogonalVect3(normalVector,vect); + crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1]; + crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2]; + crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0]; + double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect)); + baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv; + baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc; + baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni; +} + +/*! + * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords + * around the center point \a center and with angle \a angle. + */ +void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut) +{ + double cosa=cos(angle); + double sina=sin(angle); + double matrix[4]; + matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa; + double tmp[2]; + for(int i=0; i()); + coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0]; + coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1]; + } +} + DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0) { if(_da) @@ -5693,8 +4531,8 @@ double DataArrayDoubleTuple::doubleValue() const } /*! - * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef. - * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false. + * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef. + * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false. * This method throws an INTERP_KERNEL::Exception is it is impossible to match sizes of \b this that is too say \b nbOfCompo=this->_nb_of_elem and \bnbOfTuples==1 or * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem. */ @@ -5724,49 +4562,12 @@ DataArrayInt *DataArrayInt::New() } /*! - * Checks if raw data is allocated. Read more on the raw data - * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information. - * \return bool - \a true if the raw data is allocated, \a false else. + * Returns the only one value in \a this, if and only if number of elements + * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated. + * \return double - the sole value stored in \a this array. + * \throw If at least one of conditions stated above is not fulfilled. */ -bool DataArrayInt::isAllocated() const -{ - return getConstPointer()!=0; -} - -/*! - * Checks if raw data is allocated and throws an exception if it is not the case. - * \throw If the raw data is not allocated. - */ -void DataArrayInt::checkAllocated() const -{ - if(!isAllocated()) - 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() -{ - _mem.destroy(); -} - -std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const -{ - std::size_t sz(_mem.getNbOfElemAllocated()); - sz*=sizeof(int); - return DataArray::getHeapMemorySizeWithoutChildren()+sz; -} - -/*! - * Returns the only one value in \a this, if and only if number of elements - * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated. - * \return double - the sole value stored in \a this array. - * \throw If at least one of conditions stated above is not fulfilled. - */ -int DataArrayInt::intValue() const +int DataArrayInt::intValue() const { if(isAllocated()) { @@ -5802,23 +4603,12 @@ int DataArrayInt::getHashCode() const return ret+ret0; } -/*! - * Checks the number of tuples. - * \return bool - \a true if getNumberOfTuples() == 0, \a false else. - * \throw If \a this is not allocated. - */ -bool DataArrayInt::empty() const -{ - checkAllocated(); - return getNumberOfTuples()==0; -} - /*! * Returns a full copy of \a this. For more info on copying data arrays see * \ref MEDCouplingArrayBasicsCopyDeep. * \return DataArrayInt * - a new instance of DataArrayInt. */ -DataArrayInt *DataArrayInt::deepCpy() const +DataArrayInt *DataArrayInt::deepCopy() const { return new DataArrayInt(*this); } @@ -5830,10 +4620,10 @@ DataArrayInt *DataArrayInt::deepCpy() const * \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy * == \a true) or \a this instance (if \a dCpy == \a false). */ -DataArrayInt *DataArrayInt::performCpy(bool dCpy) const +DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const { if(dCpy) - return deepCpy(); + return deepCopy(); else { incrRef(); @@ -5841,154 +4631,6 @@ DataArrayInt *DataArrayInt::performCpy(bool dCpy) const } } -/*! - * Copies all the data from another DataArrayInt. For more info see - * \ref MEDCouplingArrayBasicsCopyDeepAssign. - * \param [in] other - another instance of DataArrayInt to copy data from. - * \throw If the \a other is not allocated. - */ -void DataArrayInt::cpyFrom(const DataArrayInt& other) -{ - other.checkAllocated(); - int nbOfTuples=other.getNumberOfTuples(); - int nbOfComp=other.getNumberOfComponents(); - allocIfNecessary(nbOfTuples,nbOfComp); - std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp; - int *pt=getPointer(); - const int *ptI=other.getConstPointer(); - for(std::size_t 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); - int nbOfTuples=getNumberOfTuples(); - int *pt=getPointer(); + int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer()); for(int i=0;i=0 && *pt rintstart; rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2 rintstart end2(arrBg); - MEDCouplingAutoRefCountObjectPtr ret1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr ret2=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr ret3=DataArrayInt::New(); + MCAuto ret1=DataArrayInt::New(); + MCAuto ret2=DataArrayInt::New(); + MCAuto ret3=DataArrayInt::New(); ret1->alloc(nbOfTuples,1); ret2->alloc(nbOfTuples,1); int *ret1Ptr=ret1->getPointer(); @@ -6317,6 +4971,59 @@ void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd, castsPresent=ret3.retn(); } +/*! + * This method look at \a this if it can be considered as a range defined by the 3-tuple ( \a strt , \a sttoopp , \a stteepp ). + * If false is returned the tuple must be ignored. If true is returned \a this can be considered by a range( \a strt , \a sttoopp , \a stteepp ). + * This method works only if \a this is allocated and single component. If not an exception will be thrown. + * + * \param [out] strt - the start of the range (included) if true is returned. + * \param [out] sttoopp - the end of the range (not included) if true is returned. + * \param [out] stteepp - the step of the range if true is returned. + * \return the verdict of the check. + * + * \sa DataArray::GetNumberOfItemGivenBES + */ +bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !"); + int nbTuples(getNumberOfTuples()); + if(nbTuples==0) + { strt=0; sttoopp=0; stteepp=1; return true; } + const int *pt(begin()); + strt=*pt; + if(nbTuples==1) + { sttoopp=strt+1; stteepp=1; return true; } + strt=*pt; sttoopp=pt[nbTuples-1]; + if(strt==sttoopp) + return false; + if(sttoopp>strt) + { + sttoopp++; + int a(sttoopp-1-strt),tmp(strt); + if(a%(nbTuples-1)!=0) + return false; + stteepp=a/(nbTuples-1); + for(int i=0;i ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1); ret->fillWithValue(-1); int *tmp=ret->getPointer(); @@ -6371,7 +5078,7 @@ DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int * Creates a one-dimensional DataArrayInt of given length, whose contents are computed * from values of \a this array, which is supposed to contain a renumbering map in * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode. - * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering. + * To know how to use the renumbering maps see \ref numbering. * \param [in] newNbOfElem - the number of tuples 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 @@ -6384,7 +5091,7 @@ DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int */ DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(newNbOfElem,1); int nbOfOldNodes=getNumberOfTuples(); const int *old2New=getConstPointer(); @@ -6412,7 +5119,7 @@ DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const */ DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(newNbOfElem,1); int nbOfOldNodes=getNumberOfTuples(); const int *old2New=getConstPointer(); @@ -6438,7 +5145,7 @@ DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const * Creates a one-dimensional DataArrayInt of given length, 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 MEDCouplingArrayRenumbering. + * To know how to use the renumbering maps see \ref numbering. * \param [in] newNbOfElem - the number of tuples 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 @@ -6453,7 +5160,7 @@ DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const { checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(oldNbOfElem,1); const int *new2Old=getConstPointer(); int *pt=ret->getPointer(); @@ -6463,7 +5170,7 @@ DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const { int v(new2Old[i]); if(v>=0 && v a=deepCpy(); - MEDCouplingAutoRefCountObjectPtr b=other.deepCpy(); + MCAuto a=deepCopy(); + MCAuto b=other.deepCopy(); a->sort(); b->sort(); return a->isEqualWithoutConsideringStr(*b); @@ -6575,18 +5282,45 @@ bool DataArrayInt::isFittingWith(const std::vector& v) const } /*! - * Sorts values of the array. - * \param [in] asc - \a true means ascending order, \a false, descending. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. + * 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::sort(bool asc) +void DataArrayInt::switchOnTupleEqualTo(int val, std::vector& vec) const { checkAllocated(); if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !"); - _mem.sort(asc); - declareAsNew(); + 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()); + MCAuto ret(DataArrayInt::New()); ret->alloc(nbOfTuple,1); const int *src(getConstPointer()); int *dest(ret->getPointer()); @@ -6611,18 +5345,6 @@ DataArrayInt *DataArrayInt::sumPerTuple() const return ret.retn(); } -/*! - * Reverse the array values. - * \throw If \a this->getNumberOfComponents() < 1. - * \throw If \a this is not allocated. - */ -void DataArrayInt::reverse() -{ - checkAllocated(); - _mem.reverse(getNumberOfComponents()); - declareAsNew(); -} - /*! * Checks that \a this array is consistently **increasing** or **decreasing** in value. * If not an exception is thrown. @@ -6763,7 +5485,7 @@ DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const other.checkAllocated(); if(nbTuple!=other.getNumberOfTuples()) throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbTuple,1); ret->fillWithValue(-1); const int *pt=getConstPointer(); @@ -6785,30 +5507,13 @@ DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const return ret.retn(); } -/*! - * Sets a C array to be used as raw data of \a this. The previously set info - * of components is retained and re-sized. - * For more info see \ref MEDCouplingArraySteps1. - * \param [in] array - the C array to be used as raw data of \a this. - * \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this. - * \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC, - * \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC, - * \c free(\c array ) will be called. - * \param [in] nbOfTuple - new number of tuples in \a this. - * \param [in] nbOfCompo - new number of components in \a this. - */ -void DataArrayInt::useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) -{ - _info_on_compo.resize(nbOfCompo); - _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo); - declareAsNew(); -} - -void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) +void DataArrayInt::aggregate(const DataArrayInt *other) { - _info_on_compo.resize(nbOfCompo); - _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo); - declareAsNew(); + 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()); } /*! @@ -6854,385 +5559,68 @@ DataArrayInt *DataArrayInt::toNoInterlace() const } /*! - * Permutes values of \a this array as required by \a old2New array. The values are - * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains - * the same as in \this one. - * If a permutation reduction is needed, substr() or selectByTupleId() should be used. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. - * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() - * giving a new position for i-th old value. + * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode. + * This map, if applied to \a this array, would make it sorted. For example, if + * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array + * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call + * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11]. + * This method is useful for renumbering (in MED file for example). For more info + * on renumbering see \ref numbering. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If there are equal values in \a this array. */ -void DataArrayInt::renumberInPlace(const int *old2New) +DataArrayInt *DataArrayInt::checkAndPreparePermutation() const { checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !"); int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - int *tmp=new int[nbTuples*nbOfCompo]; - const int *iptr=getConstPointer(); - for(int i=0;i=0 && vuseArray(pt2,true,C_DEALLOC,nbTuples,1); + return ret; } /*! - * Permutes values of \a this array as required by \a new2Old array. The values are - * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains - * the same as in \this one. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. - * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples() - * giving a previous position of i-th new value. - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. + * This method tries to find the permutation to apply to the first input \a ids1 to obtain the same array (without considering strings informations) the second + * input array \a ids2. + * \a ids1 and \a ids2 are expected to be both a list of ids (both with number of components equal to one) not sorted and with values that can be negative. + * This method will throw an exception is no such permutation array can be obtained. It is typically the case if there is some ids in \a ids1 not in \a ids2 or + * inversely. + * In case of success (no throw) : \c ids1->renumber(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. + * */ -void DataArrayInt::renumberInPlaceR(const int *new2Old) +DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2) { - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - int *tmp=new int[nbTuples*nbOfCompo]; - const int *iptr=getConstPointer(); - for(int i=0;iisAllocated() || !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()) { - int v=new2Old[i]; - if(v>=0 && vgetNumberOfTuples() << " 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()); } - std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer()); - delete [] tmp; - declareAsNew(); -} - -/*! - * Returns a copy of \a this array with values permuted as required by \a old2New array. - * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. - * Number of tuples in the result array remains the same as in \this one. - * If a permutation reduction is needed, renumberAndReduce() should be used. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. - * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() - * giving a new position for i-th old value. - * \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::renumber(const int *old2New) const -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbTuples,nbOfCompo); - ret->copyStringInfoFrom(*this); - const int *iptr=getConstPointer(); - int *optr=ret->getPointer(); - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a copy of \a this array with values permuted as required by \a new2Old array. - * The values are permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of - * tuples in the result array remains the same as in \this one. - * If a permutation reduction is needed, substr() or selectByTupleId() should be used. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. - * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples() - * giving a previous position of i-th new value. - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - */ -DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbTuples,nbOfCompo); - ret->copyStringInfoFrom(*this); - const int *iptr=getConstPointer(); - int *optr=ret->getPointer(); - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is - * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array. - * The values are permuted so that \c new[ \a old2New[ i ]] = \c old[ i ] for all - * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which - * \a old2New[ i ] is negative, is missing from the result array. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. - * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() - * giving a new position for i-th old tuple and giving negative position for - * for i-th old tuple that should be omitted. - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - */ -DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(newNbOfTuple,nbOfCompo); - const int *iptr=getConstPointer(); - int *optr=ret->getPointer(); - for(int i=0;i=0) - std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo); - } - ret->copyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is - * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by - * \a new2OldBg array. - * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]]. - * This method is equivalent to renumberAndReduce() except that convention in input is - * \c new2old and \b not \c old2new. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. - * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a - * tuple index in \a this array to fill the i-th tuple in the new array. - * \param [in] new2OldEnd - specifies the end of the permutation array that starts at - * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this: - * \a new2OldBg <= \a pi < \a new2OldEnd. - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - */ -DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int nbComp=getNumberOfComponents(); - ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); - ret->copyStringInfoFrom(*this); - int *pt=ret->getPointer(); - const int *srcPt=getConstPointer(); - int i=0; - for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++) - std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp); - ret->copyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is - * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by - * \a new2OldBg array. - * The values are permuted so that \c new[ i ] = \c old[ \a new2OldBg[ i ]]. - * This method is equivalent to renumberAndReduce() except that convention in input is - * \c new2old and \b not \c old2new. - * This method is equivalent to selectByTupleId() except that it prevents coping data - * from behind the end of \a this array. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. - * \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a - * tuple index in \a this array to fill the i-th tuple in the new array. - * \param [in] new2OldEnd - specifies the end of the permutation array that starts at - * \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this: - * \a new2OldBg <= \a pi < \a new2OldEnd. - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples(). - */ -DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int nbComp=getNumberOfComponents(); - int oldNbOfTuples=getNumberOfTuples(); - ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); - ret->copyStringInfoFrom(*this); - int *pt=ret->getPointer(); - const int *srcPt=getConstPointer(); - int i=0; - for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++) - if(*w>=0 && *wgetNumberOfTuples) !"); - ret->copyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten copy of \a this array. The new DataArrayInt contains every - * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th - * tuple. Indices of the selected tuples are the same as ones returned by the Python - * command \c range( \a bg, \a end2, \a step ). - * This method is equivalent to selectByTupleIdSafe() except that the input array is - * not constructed explicitly. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. - * \param [in] bg - index of the first tuple to copy from \a this array. - * \param [in] end2 - index of the tuple before which the tuples to copy are located. - * \param [in] step - index increment to get index of the next tuple to copy. - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - * \sa DataArrayInt::substr. - */ -DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int nbComp=getNumberOfComponents(); - int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : "); - ret->alloc(newNbOfTuples,nbComp); - int *pt=ret->getPointer(); - const int *srcPt=getConstPointer()+bg*nbComp; - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges - * of tuples specified by \a ranges parameter. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. - * \param [in] ranges - std::vector of std::pair's each of which defines a range - * of tuples in [\c begin,\c end) format. - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a end < \a begin. - * \throw If \a end > \a this->getNumberOfTuples(). - * \throw If \a this is not allocated. - */ -DataArray *DataArrayInt::selectByTupleRanges(const std::vector >& ranges) const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - int nbOfTuplesThis=getNumberOfTuples(); - if(ranges.empty()) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(0,nbOfComp); - ret->copyStringInfoFrom(*this); - return ret.retn(); - } - int ref=ranges.front().first; - int nbOfTuples=0; - bool isIncreasing=true; - for(std::vector >::const_iterator it=ranges.begin();it!=ranges.end();it++) - { - if((*it).first<=(*it).second) - { - if((*it).first>=0 && (*it).second<=nbOfTuplesThis) - { - nbOfTuples+=(*it).second-(*it).first; - if(isIncreasing) - isIncreasing=ref<=(*it).first; - ref=(*it).second; - } - else - { - std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it); - oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it); - oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(isIncreasing && nbOfTuplesThis==nbOfTuples) - return deepCpy(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuples,nbOfComp); - ret->copyStringInfoFrom(*this); - const int *src=getConstPointer(); - int *work=ret->getPointer(); - for(std::vector >::const_iterator it=ranges.begin();it!=ranges.end();it++) - work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work); - return ret.retn(); -} - -/*! - * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode. - * This map, if applied to \a this array, would make it sorted. For example, if - * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array - * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call - * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11]. - * This method is useful for renumbering (in MED file for example). For more info - * on renumbering see \ref MEDCouplingArrayRenumbering. - * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \throw If there are equal values in \a this array. - */ -DataArrayInt *DataArrayInt::checkAndPreparePermutation() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !"); - int nbTuples=getNumberOfTuples(); - const int *pt=getConstPointer(); - int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples); - DataArrayInt *ret=DataArrayInt::New(); - ret->useArray(pt2,true,C_DEALLOC,nbTuples,1); - return ret; -} - -/*! - * This method tries to find the permutation to apply to the first input \a ids1 to obtain the same array (without considering strings informations) the second - * input array \a ids2. - * \a ids1 and \a ids2 are expected to be both a list of ids (both with number of components equal to one) not sorted and with values that can be negative. - * This method will throw an exception is no such permutation array can be obtained. It is typically the case if there is some ids in \a ids1 not in \a ids2 or - * inversely. - * In case of success (no throw) : \c ids1->renumber(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) -{ - 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(); + MCAuto p1(ids1->deepCopy()); + MCAuto p2(ids2->deepCopy()); + 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(); } /*! @@ -7245,7 +5633,7 @@ DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt * place in the set \a B. The second out array is the index of the first one; it shows how * many elements of \a A are mapped into each element of \a B.
* For more info on - * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering.
+ * mapping and its usage in renumbering see \ref numbering.
* \b Example: * - \a this: [0,3,2,3,2,2,1,2] * - \a targetNb: 4 @@ -7276,8 +5664,8 @@ void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, Data if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !"); int nbOfTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr retI(DataArrayInt::New()); + MCAuto ret(DataArrayInt::New()); + MCAuto retI(DataArrayInt::New()); retI->alloc(targetNb+1,1); const int *input=getConstPointer(); std::vector< std::vector > tmp(targetNb); @@ -7310,9 +5698,9 @@ void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, Data /*! * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed * from a zip representation of a surjective format (returned e.g. by - * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()" + * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()" * for example). The result array minimizes the permutation.
- * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
+ * For more info on renumbering see \ref numbering.
* \b Example:
* - \a nbOfOldTuples: 10 * - \a arr : [0,3, 5,7,9] @@ -7332,9 +5720,9 @@ void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, Data * array using decrRef() as it is no more needed. * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ). */ -DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) +DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbOfOldTuples,1); int *pt=ret->getPointer(); std::fill(pt,pt+nbOfOldTuples,-1); @@ -7358,7 +5746,7 @@ DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTu pt[arr[j]]=newNb; else { - std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !"; + std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } } @@ -7373,7 +5761,7 @@ DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTu /*! * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode, * which if applied to \a this array would make it sorted ascendingly. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
+ * For more info on renumbering see \ref numbering.
* \b Example:
* - \a this: [2,0,1,1,0,1,2,0,1,1,0,0] * - result: [10,0,5,6,1,7,11,2,8,9,3,4] @@ -7392,7 +5780,7 @@ DataArrayInt *DataArrayInt::buildPermArrPerLevel() const int nbOfTuples=getNumberOfTuples(); const int *pt=getConstPointer(); std::map m; - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1); int *opt=ret->getPointer(); for(int i=0;igetNumberOfTuples()) * \throw If \a this is not allocated. * \throw If \a this->getNumberOfComponents() != 1. */ -bool DataArrayInt::isIdentity() const +bool DataArrayInt::isIota(int sizeExpected) const { checkAllocated(); if(getNumberOfComponents()!=1) return false; - int nbOfTuples=getNumberOfTuples(); - const int *pt=getConstPointer(); - for(int i=0;igetNumberOfComponents() != 1 - */ -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; - for(;w!=end2;w++) - if(*w!=val) - return false; - return true; -} - -/*! - * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this - * array to the new one. - * \return DataArrayDouble * - the new instance of DataArrayInt. - */ -DataArrayDouble *DataArrayInt::convertToDblArr() const -{ - checkAllocated(); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(getNumberOfTuples(),getNumberOfComponents()); - std::size_t nbOfVals=getNbOfElems(); - const int *src=getConstPointer(); - double *dest=ret->getPointer(); - std::copy(src,src+nbOfVals,dest); - ret->copyStringInfoFrom(*this); - return ret; -} - -/*! - * Returns a shorten copy of \a this array. The new DataArrayInt contains all - * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before - * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr(). - * This method is a specialization of selectByTupleId2(). - * \param [in] tupleIdBg - index of the first tuple to copy from \a this array. - * \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located. - * If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied. - * \return DataArrayInt * - the new instance of DataArrayInt that the caller - * is to delete using decrRef() as it is no more needed. - * \throw If \a tupleIdBg < 0. - * \throw If \a tupleIdBg > \a this->getNumberOfTuples(). - \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples(). - * \sa DataArrayInt::selectByTupleId2 - */ -DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const -{ - checkAllocated(); - int nbt=getNumberOfTuples(); - if(tupleIdBg<0) - throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !"); - if(tupleIdBg>nbt) - throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !"); - int trueEnd=tupleIdEnd; - if(tupleIdEnd!=-1) - { - if(tupleIdEnd>nbt) - throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !"); - } - else - trueEnd=nbt; - int nbComp=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(trueEnd-tupleIdBg,nbComp); - ret->copyStringInfoFrom(*this); - std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer()); - return ret.retn(); -} - -/*! - * Changes the number of components within \a this array so that its raw data **does - * not** change, instead splitting this data into tuples changes. - * \warning This method erases all (name and unit) component info set before! - * \param [in] newNbOfComp - number of components for \a this array to have. - * \throw If \a this is not allocated - * \throw If getNbOfElems() % \a newNbOfCompo != 0. - * \throw If \a newNbOfCompo is lower than 1. - * \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !). - * \warning This method erases all (name and unit) component info set before! - */ -void DataArrayInt::rearrange(int newNbOfCompo) -{ - checkAllocated(); - if(newNbOfCompo<1) - throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !"); - std::size_t nbOfElems=getNbOfElems(); - if(nbOfElems%newNbOfCompo!=0) - throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !"); - if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits::max()) - throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !"); - _info_on_compo.clear(); - _info_on_compo.resize(newNbOfCompo); - declareAsNew(); -} - -/*! - * Changes the number of components within \a this array to be equal to its number - * of tuples, and inversely its number of tuples to become equal to its number of - * components. So that its raw data **does not** change, instead splitting this - * data into tuples changes. - * \warning This method erases all (name and unit) component info set before! - * \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()! - * \throw If \a this is not allocated. - * \sa rearrange() - */ -void DataArrayInt::transpose() -{ - checkAllocated(); - int nbOfTuples=getNumberOfTuples(); - rearrange(nbOfTuples); -} - -/*! - * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less - * than \a this->getNumberOfComponents() then the result array is shorten as each tuple - * is truncated to have \a newNbOfComp components, keeping first components. If \a - * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is - * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp - * components. - * \param [in] newNbOfComp - number of components for the new array to have. - * \param [in] dftValue - value assigned to new values added to the new array. - * \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. - */ -DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(getNumberOfTuples(),newNbOfComp); - const int *oldc=getConstPointer(); - int *nc=ret->getPointer(); - int nbOfTuples=getNumberOfTuples(); - int oldNbOfComp=getNumberOfComponents(); - int dim=std::min(oldNbOfComp,newNbOfComp); - for(int i=0;isetName(getName()); - for(int i=0;isetInfoOnComponent(i,getInfoOnComponent(i)); - ret->setName(getName()); - return ret.retn(); -} - -/*! - * Changes number of tuples in the array. If the new number of tuples is smaller - * 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) -{ - 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(); -} - - -/*! - * Returns a copy of \a this array composed of selected components. - * The new DataArrayInt has the same number of tuples but includes components - * specified by \a compoIds parameter. So that getNbOfElems() of the result array - * can be either less, same or more than \a this->getNbOfElems(). - * \param [in] compoIds - sequence of zero based indices of components to include - * into the new array. - * \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. - * \throw If a component index (\a i) is not valid: - * \a i < 0 || \a i >= \a this->getNumberOfComponents(). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example". - * \endif - */ -DataArray *DataArrayInt::keepSelectedComponents(const std::vector& compoIds) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); - int newNbOfCompo=(int)compoIds.size(); - int oldNbOfCompo=getNumberOfComponents(); - for(std::vector::const_iterator it=compoIds.begin();it!=compoIds.end();it++) - DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component"); - int nbOfTuples=getNumberOfTuples(); - ret->alloc(nbOfTuples,newNbOfCompo); - ret->copyPartOfStringInfoFrom(*this,compoIds); - const int *oldc=getConstPointer(); - int *nc=ret->getPointer(); - for(int i=0;icheckAllocated(); - 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;igetNumberOfComponents(). - * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents(). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example". - * \endif - */ -void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector& compoIds) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !"); - checkAllocated(); - a->checkAllocated(); - copyPartOfStringInfoFrom2(compoIds,*a); - std::size_t partOfCompoSz=compoIds.size(); - int nbOfCompo=getNumberOfComponents(); - int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples()); - const int *ac=a->getConstPointer(); - int *nc=getPointer(); - for(int i=0;igetNumberOfComponents() - * must be equal to the number of columns to assign to, else an - * exception is thrown; if \a false, then it is only required that \a - * a->getNbOfElems() equals to number of values to assign to (this condition - * must be respected even if \a strictCompoCompare is \a true). The number of - * values to assign to is given by following Python expression: - * \a nbTargetValues = - * \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) * - * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). - * \throw If \a a is NULL. - * \throw If \a a is not allocated. - * \throw If \a this is not allocated. - * \throw If parameters specifying tuples and components to assign to do not give a - * non-empty range of increasing indices. - * \throw If \a a->getNbOfElems() != \a nbTargetValues. - * \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() != - * \c len(\c range(\a bgComp,\a endComp,\a stepComp)). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example". - * \endif - */ -void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !"); - const char msg[]="DataArrayInt::setPartOfValues1"; - checkAllocated(); - a->checkAllocated(); - int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg); - int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value"); - DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - int *pt=getPointer()+bgTuples*nbComp+bgComp; - const int *srcPt=a->getConstPointer(); - if(assignTech) - { - for(int i=0;igetNbOfElems() equals to number of values to assign to, then every value - * of \a a is assigned to its own location within \a this array. - * - If \a a includes one tuple, then all values of \a a are assigned to the specified - * components of every specified tuple of \a this array. In this mode it is required - * that \a a->getNumberOfComponents() equals to the number of specified components. - * - * \param [in] a - the array to copy values from. - * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to - * assign values of \a a to. - * \param [in] endTuples - specifies the end of the array \a bgTuples, so that - * pointer to a tuple index (pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - pointer to an array of component indices of \a this array to - * assign values of \a a to. - * \param [in] endComp - specifies the end of the array \a bgTuples, so that - * pointer to a component index (pi) varies as this: - * \a bgComp <= \a pi < \a endComp. - * \param [in] strictCompoCompare - this parameter is checked only if the - * *mode of usage* is the first; if it is \a true (default), - * then \a a->getNumberOfComponents() must be equal - * to the number of specified columns, else this is not required. - * \throw If \a a is NULL. - * \throw If \a a is not allocated. - * \throw If \a this is not allocated. - * \throw If any index of tuple/component given by bgTuples / bgComp is - * out of a valid range for \a this array. - * \throw In the first *mode of usage*, if strictCompoCompare == true and - * if a->getNumberOfComponents() != (endComp - bgComp) . - * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or - * a->getNumberOfComponents() != (endComp - bgComp). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example". - * \endif - */ -void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !"); - const char msg[]="DataArrayInt::setPartOfValues2"; - checkAllocated(); - a->checkAllocated(); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - for(const int *z=bgComp;z!=endComp;z++) - DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); - int newNbOfTuples=(int)std::distance(bgTuples,endTuples); - int newNbOfComp=(int)std::distance(bgComp,endComp); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - int *pt=getPointer(); - const int *srcPt=a->getConstPointer(); - if(assignTech) - { - for(const int *w=bgTuples;w!=endTuples;w++) - { - DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); - for(const int *z=bgComp;z!=endComp;z++,srcPt++) - { - pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt; - } - } - } - else - { - for(const int *w=bgTuples;w!=endTuples;w++) - { - const int *srcPt2=srcPt; - DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); - for(const int *z=bgComp;z!=endComp;z++,srcPt2++) - { - pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2; - } - } - } -} - -/*! - * Assign a given value to values at specified tuples and components of \a this array. - * The tuples and components to assign to are defined by C arrays of indices. - * \param [in] a - the value to assign. - * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to - * assign \a a to. - * \param [in] endTuples - specifies the end of the array \a bgTuples, so that - * pointer to a tuple index (\a pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - pointer to an array of component indices of \a this array to - * assign \a a to. - * \param [in] endComp - specifies the end of the array \a bgTuples, so that - * pointer to a component index (\a pi) varies as this: - * \a bgComp <= \a pi < \a endComp. - * \throw If \a this is not allocated. - * \throw If any index of tuple/component given by bgTuples / bgComp is - * out of a valid range for \a this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example". - * \endif - */ -void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) -{ - checkAllocated(); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - for(const int *z=bgComp;z!=endComp;z++) - DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); - int *pt=getPointer(); - for(const int *w=bgTuples;w!=endTuples;w++) - for(const int *z=bgComp;z!=endComp;z++) - { - DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); - pt[(std::size_t)(*w)*nbComp+(*z)]=a; - } -} - -/*! - * Copy all values from another DataArrayInt (\a a) into specified tuples and - * components of \a this array. Textual data is not copied. - * The tuples to assign to are defined by a C array of indices. - * The components to assign to are defined by three values similar to parameters of - * the Python function \c range(\c start,\c stop,\c step). - * There are two *modes of usage*: - * - If \a a->getNbOfElems() equals to number of values to assign to, then every value - * of \a a is assigned to its own location within \a this array. - * - If \a a includes one tuple, then all values of \a a are assigned to the specified - * components of every specified tuple of \a this array. In this mode it is required - * that \a a->getNumberOfComponents() equals to the number of specified components. - * - * \param [in] a - the array to copy values from. - * \param [in] bgTuples - pointer to an array of tuple indices of \a this array to - * assign values of \a a to. - * \param [in] endTuples - specifies the end of the array \a bgTuples, so that - * pointer to a tuple index (pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - index of the first component of \a this array to assign to. - * \param [in] endComp - index of the component before which the components to assign - * to are located. - * \param [in] stepComp - index increment to get index of the next component to assign to. - * \param [in] strictCompoCompare - this parameter is checked only in the first - * *mode of usage*; if \a strictCompoCompare is \a true (default), - * then \a a->getNumberOfComponents() must be equal - * to the number of specified columns, else this is not required. - * \throw If \a a is NULL. - * \throw If \a a is not allocated. - * \throw If \a this is not allocated. - * \throw If any index of tuple given by \a bgTuples is out of a valid range for - * \a this array. - * \throw In the first *mode of usage*, if strictCompoCompare == true and - * if a->getNumberOfComponents() is unequal to the number of components - * defined by (bgComp,endComp,stepComp). - * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or - * a->getNumberOfComponents() is unequal to the number of components - * defined by (bgComp,endComp,stepComp). - * \throw If parameters specifying components to assign to, do not give a - * non-empty range of increasing indices or indices are out of a valid range - * for \this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example". - * \endif - */ -void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !"); - const char msg[]="DataArrayInt::setPartOfValues3"; - checkAllocated(); - a->checkAllocated(); - int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - int newNbOfTuples=(int)std::distance(bgTuples,endTuples); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - int *pt=getPointer()+bgComp; - const int *srcPt=a->getConstPointer(); - if(assignTech) - { - for(const int *w=bgTuples;w!=endTuples;w++) - for(int j=0;j(pi) varies as this: - * \a bgTuples <= \a pi < \a endTuples. - * \param [in] bgComp - index of the first component of \a this array to assign to. - * \param [in] endComp - index of the component before which the components to assign - * to are located. - * \param [in] stepComp - index increment to get index of the next component to assign to. - * \throw If \a this is not allocated. - * \throw If any index of tuple given by \a bgTuples is out of a valid range for - * \a this array. - * \throw If parameters specifying components to assign to, do not give a - * non-empty range of increasing indices or indices are out of a valid range - * for \this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example". - * \endif - */ -void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) -{ - const char msg[]="DataArrayInt::setPartOfValuesSimple3"; - checkAllocated(); - int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - int *pt=getPointer()+bgComp; - for(const int *w=bgTuples;w!=endTuples;w++) - for(int j=0;jcheckAllocated(); - int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg); - int newNbOfComp=(int)std::distance(bgComp,endComp); - int nbComp=getNumberOfComponents(); - for(const int *z=bgComp;z!=endComp;z++) - DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value"); - bool assignTech=true; - if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp) - { - if(strictCompoCompare) - a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg); - } - else - { - a->checkNbOfTuplesAndComp(1,newNbOfComp,msg); - assignTech=false; - } - const int *srcPt=a->getConstPointer(); - int *pt=getPointer()+bgTuples*nbComp; - if(assignTech) - { - for(int i=0;ithis->getNumberOfComponents() != a->getNumberOfComponents(). - * \throw If \a tuplesSelec->getNumberOfComponents() != 2. - * \throw If any tuple index given by \a tuplesSelec is out of a valid range for - * the corresponding (\a this or \a a) array. - */ -void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) -{ - if(!a || !tuplesSelec) - throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !"); - checkAllocated(); - a->checkAllocated(); - tuplesSelec->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !"); - if(tuplesSelec->getNumberOfComponents()!=2) - throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - int *valsToSet=getPointer(); - const int *valsSrc=a->getConstPointer(); - for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2) - { - if(tuple[1]>=0 && tuple[1]=0 && tuple[0]begin(),tuple)/2; - oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2; - oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } + int nbOfTuples(getNumberOfTuples()); + if(nbOfTuples!=sizeExpected) + return false; + const int *pt=getConstPointer(); + for(int i=0;igetNumberOfTuples(). - * The tuples to copy are defined by values of a 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] aBase - the array to copy values from. - * \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy. + * Checks if all values in \a this array are equal to \a val. + * \param [in] val - value to check equality of array values to. + * \return bool - \a true if all values are \a val. * \throw If \a this 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 aBase array. - */ -void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) -{ - if(!aBase || !tuplesSelec) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !"); - const DataArrayInt *a=dynamic_cast(aBase); - if(!a) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !"); + * \throw If \a this->getNumberOfComponents() != 1 + */ +bool DataArrayInt::isUniform(int val) const +{ checkAllocated(); - a->checkAllocated(); - tuplesSelec->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !"); - if(tuplesSelec->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples(); - int *valsToSet=getPointer()+tupleIdStart*nbOfComp; - if(tupleIdStart+nbOfTupleToWrite>thisNt) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !"); - const int *valsSrc=a->getConstPointer(); - for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp) - { - if(*tuple>=0 && *tuplebegin(),tuple); - oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } + 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; + for(;w!=end2;w++) + if(*w!=val) + return false; + return true; } /*! - * 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 - * the Python function \c range(\c start,\c stop,\c step). - * The tuples to assign to are defined by index of the first tuple, and - * their number is defined by number of tuples to copy. - * 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] 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. + * Checks if all values in \a this array are unique. + * \return bool - \a true if condition above is true * \throw If \a this is not allocated. - * \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 aBase. + * \throw If \a this->getNumberOfComponents() != 1 */ -void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) +bool DataArrayInt::hasUniqueValues() const { - if(!aBase) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !"); - const DataArrayInt *a=dynamic_cast(aBase); - if(!a) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !"); checkAllocated(); - a->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - const char msg[]="DataArrayInt::setContigPartOfSelectedValues2"; - int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - int *valsToSet=getPointer()+tupleIdStart*nbOfComp; - if(tupleIdStart+nbOfTupleToWrite>thisNt) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !"); - if(end2>aNt) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !"); - const int *valsSrc=a->getConstPointer()+bg*nbOfComp; - for(int i=0;i( 0 <= tupleId < this->getNumberOfTuples() ) is violated. - * \throw If condition ( 0 <= compoId < this->getNumberOfComponents() ) is violated. + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !"); + int nbOfTuples(getNumberOfTuples()); + std::set s(begin(),end()); // in C++11, should use unordered_set (O(1) complexity) + if (s.size() != nbOfTuples) + return false; + return true; +} + +/*! + * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this + * array to the new one. + * \return DataArrayDouble * - the new instance of DataArrayInt. */ -int DataArrayInt::getIJSafe(int tupleId, int compoId) const +DataArrayDouble *DataArrayInt::convertToDblArr() const { checkAllocated(); - if(tupleId<0 || tupleId>=getNumberOfTuples()) - { - std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(compoId<0 || compoId>=getNumberOfComponents()) - { - std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return _mem[tupleId*_info_on_compo.size()+compoId]; + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(getNumberOfTuples(),getNumberOfComponents()); + std::size_t nbOfVals=getNbOfElems(); + const int *src=getConstPointer(); + double *dest=ret->getPointer(); + std::copy(src,src+nbOfVals,dest); + ret->copyStringInfoFrom(*this); + return ret; } /*! - * Returns the first value of \a this. - * \return int - the last value of \a this array. + * 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->getNumberOfComponents() != 1. - * \throw If \a this->getNumberOfTuples() < 1. + * \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 */ -int DataArrayInt::front() const +void DataArrayInt::meldWith(const DataArrayInt *other) { + if(!other) + throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !"); checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !"); + other->checkAllocated(); int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<1) - throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !"); - return *(getConstPointer()); + 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;igetNumberOfComponents() != 1. - * \throw If \a this->getNumberOfTuples() < 1. + * Copy all components in a specified order from another DataArrayInt. + * The specified components become the first ones in \a this array. + * Both numerical and textual data is copied. The number of tuples in \a this and + * the other array can be different. + * \param [in] a - the array to copy data from. + * \param [in] compoIds - sequence of zero based indices of components, data of which is + * to be copied. + * \throw If \a a is NULL. + * \throw If \a compoIds.size() != \a a->getNumberOfComponents(). + * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents(). + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example". + * \endif */ -int DataArrayInt::back() const +void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector& compoIds) { + if(!a) + throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !"); checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<1) - throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !"); - return *(getConstPointer()+nbOfTuples-1); + a->checkAllocated(); + copyPartOfStringInfoFrom2(compoIds,*a); + std::size_t partOfCompoSz=compoIds.size(); + int nbOfCompo=getNumberOfComponents(); + int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples()); + const int *ac=a->getConstPointer(); + int *nc=getPointer(); + for(int i=0;igetNumberOfComponents() != 1. - * \sa DataArrayInt::getIdsEqualTuple + * \sa DataArrayInt::findIdsEqualTuple */ -DataArrayInt *DataArrayInt::getIdsEqual(int val) const +DataArrayInt *DataArrayInt::findIdsEqual(int val) const { checkAllocated(); if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !"); + throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !"); const int *cptr(getConstPointer()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); + MCAuto ret(DataArrayInt::New()); ret->alloc(0,1); int nbOfTuples=getNumberOfTuples(); for(int i=0;igetNumberOfComponents() != 1. */ -DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const +DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const { checkAllocated(); if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !"); + throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !"); const int *cptr(getConstPointer()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); + MCAuto ret(DataArrayInt::New()); ret->alloc(0,1); int nbOfTuples=getNumberOfTuples(); for(int i=0;igetNumberOfComponents() != std::distance(tupleBg,tupleEnd). * \throw If \a this->getNumberOfComponents() is equal to 0. - * \sa DataArrayInt::getIdsEqual + * \sa DataArrayInt::findIdsEqual */ -DataArrayInt *DataArrayInt::getIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const +DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const { std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd)); checkAllocated(); if(getNumberOfComponents()!=(int)nbOfCompoExp) { - std::ostringstream oss; oss << "DataArrayInt::getIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !"; + std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } if(nbOfCompoExp==0) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualTuple : number of components should be > 0 !"); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); + throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !"); + MCAuto ret(DataArrayInt::New()); ret->alloc(0,1); const int *bg(begin()),*end2(end()),*work(begin()); while(work!=end2) { @@ -8536,9 +6094,10 @@ int DataArrayInt::changeValue(int oldValue, int newValue) checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !"); - int *start=getPointer(); - int *end2=start+getNbOfElems(); - int ret=0; + if(oldValue==newValue) + return 0; + int *start(getPointer()),*end2(start+getNbOfElems()); + int ret(0); for(int *val=start;val!=end2;val++) { if(*val==oldValue) @@ -8547,6 +6106,8 @@ int DataArrayInt::changeValue(int oldValue, int newValue) ret++; } } + if(ret>0) + declareAsNew(); return ret; } @@ -8560,15 +6121,15 @@ int DataArrayInt::changeValue(int oldValue, int newValue) * array using decrRef() as it is no more needed. * \throw If \a this->getNumberOfComponents() != 1. */ -DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const +DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const { if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !"); + throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !"); std::set vals2(valsBg,valsEnd); - const int *cptr=getConstPointer(); + const int *cptr(getConstPointer()); std::vector res; - int nbOfTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); + int nbOfTuples(getNumberOfTuples()); + MCAuto ret(DataArrayInt::New()); ret->alloc(0,1); for(int i=0;ipushBackSilent(i); @@ -8585,15 +6146,15 @@ DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEn * array using decrRef() as it is no more needed. * \throw If \a this->getNumberOfComponents() != 1. */ -DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const +DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const { if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !"); + throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !"); std::set vals2(valsBg,valsEnd); const int *cptr=getConstPointer(); std::vector res; int nbOfTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); + MCAuto ret(DataArrayInt::New()); ret->alloc(0,1); for(int i=0;ipushBackSilent(i); @@ -8601,7 +6162,7 @@ DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *val } /*! - * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with + * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case). * This method searches in \b this is there is a tuple that matched the input parameter \b tupl. * If any the tuple id is returned. If not -1 is returned. @@ -8610,17 +6171,17 @@ DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *val * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated. * * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this. - * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple. + * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple. */ -int DataArrayInt::locateTuple(const std::vector& tupl) const +int DataArrayInt::findIdFirstEqualTuple(const std::vector& tupl) const { checkAllocated(); int nbOfCompo=getNumberOfComponents(); if(nbOfCompo==0) - throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !"); + throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !"); if(nbOfCompo!=(int)tupl.size()) { - std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !"; + std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } const int *cptr=getConstPointer(); @@ -8642,15 +6203,15 @@ int DataArrayInt::locateTuple(const std::vector& tupl) const /*! * This method searches the sequence specified in input parameter \b vals in \b this. * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown). - * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple. - * \sa DataArrayInt::locateTuple + * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple. + * \sa DataArrayInt::findIdFirstEqualTuple */ -int DataArrayInt::search(const std::vector& vals) const +int DataArrayInt::findIdSequence(const std::vector& vals) const { checkAllocated(); int nbOfCompo=getNumberOfComponents(); if(nbOfCompo!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !"); + throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !"); const int *cptr=getConstPointer(); std::size_t nbOfVals=getNbOfElems(); const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end()); @@ -8665,7 +6226,7 @@ int DataArrayInt::search(const std::vector& vals) const * If not any tuple contains \b value -1 is returned. * \sa DataArrayInt::presenceOfValue */ -int DataArrayInt::locateValue(int value) const +int DataArrayInt::findIdFirstEqual(int value) const { checkAllocated(); if(getNumberOfComponents()!=1) @@ -8681,10 +6242,10 @@ int DataArrayInt::locateValue(int value) const /*! * This method expects to be called when number of components of this is equal to one. * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals. - * If not any tuple contains one of the values contained in 'vals' false is returned. + * If not any tuple contains one of the values contained in 'vals' -1 is returned. * \sa DataArrayInt::presenceOfValue */ -int DataArrayInt::locateValue(const std::vector& vals) const +int DataArrayInt::findIdFirstEqual(const std::vector& vals) const { checkAllocated(); if(getNumberOfComponents()!=1) @@ -8727,11 +6288,11 @@ int DataArrayInt::count(int value) const * This method searches in \b this is there is a tuple that matched the input parameter \b tupl. * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated. - * \sa DataArrayInt::locateTuple + * \sa DataArrayInt::findIdFirstEqualTuple */ bool DataArrayInt::presenceOfTuple(const std::vector& tupl) const { - return locateTuple(tupl)!=-1; + return findIdFirstEqualTuple(tupl)!=-1; } @@ -8741,22 +6302,22 @@ bool DataArrayInt::presenceOfTuple(const std::vector& tupl) const * \return bool - \a true in case if \a value is present within \a this array. * \throw If \a this is not allocated. * \throw If \a this->getNumberOfComponents() != 1. - * \sa locateValue() + * \sa findIdFirstEqual() */ bool DataArrayInt::presenceOfValue(int value) const { - return locateValue(value)!=-1; + return findIdFirstEqual(value)!=-1; } /*! * This method expects to be called when number of components of this is equal to one. * This method returns true if it exists a tuple so that the value is contained in \b vals. * If not any tuple contains one of the values contained in 'vals' false is returned. - * \sa DataArrayInt::locateValue + * \sa DataArrayInt::findIdFirstEqual */ bool DataArrayInt::presenceOfValue(const std::vector& vals) const { - return locateValue(vals)!=-1; + return findIdFirstEqual(vals)!=-1; } /*! @@ -8818,7 +6379,7 @@ DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int if(sz<1) throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !"); sz--; - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(sz,nbCompo); + MCAuto ret=DataArrayInt::New(); ret->alloc(sz,nbCompo); const int *w=bgOfIndex; if(*w<0 || *w>=nbOfTuples) throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !"); @@ -8916,7 +6477,7 @@ DataArrayInt *DataArrayInt::Aggregate(const std::vector& a throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !"); nbt+=(*it)->getNumberOfTuples(); } - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbt,nbOfComp); int *pt=ret->getPointer(); for(it=a.begin();it!=a.end();it++) @@ -8967,7 +6528,7 @@ DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector ret=DataArrayInt::New(); + MCAuto 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++) @@ -8977,71 +6538,29 @@ DataArrayInt *DataArrayInt::AggregateIndexes(const std::vectorgetNumberOfComponents() != 1 - * \throw If \a this->getNumberOfTuples() < 1 - */ -int DataArrayInt::getMaxValue(int& tupleId) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<=0) - throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !"); - const int *vals=getConstPointer(); - const int *loc=std::max_element(vals,vals+nbOfTuples); - tupleId=(int)std::distance(vals,loc); - return *loc; -} - -/*! - * Returns the maximal value within \a this array that is allowed to have more than - * one component. - * \return int - the maximal value among all values of \a this array. - * \throw If \a this is not allocated. - */ -int DataArrayInt::getMaxValueInArray() const -{ - checkAllocated(); - const int *loc=std::max_element(begin(),end()); - return *loc; -} - -/*! - * Returns the minimal value and its location within \a this one-dimensional array. - * \param [out] tupleId - index of the tuple holding the minimal value. - * \return int - the minimal value among all values of \a this array. - * \throw If \a this->getNumberOfComponents() != 1 - * \throw If \a this->getNumberOfTuples() < 1 + * Returns in a single walk in \a this the min value and the max value in \a this. + * \a this is expected to be single component array. + * + * \param [out] minValue - the min value in \a this. + * \param [out] maxValue - the max value in \a this. + * + * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue */ -int DataArrayInt::getMinValue(int& tupleId) const +void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const { checkAllocated(); if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<=0) - throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !"); - const int *vals=getConstPointer(); - const int *loc=std::min_element(vals,vals+nbOfTuples); - tupleId=(int)std::distance(vals,loc); - return *loc; -} - -/*! - * Returns the minimal value within \a this array that is allowed to have more than - * one component. - * \return int - the minimal value among all values of \a this array. - * \throw If \a this is not allocated. - */ -int DataArrayInt::getMinValueInArray() const -{ - checkAllocated(); - const int *loc=std::min_element(begin(),end()); - return *loc; + throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !"); + int nbTuples(getNumberOfTuples()); + const int *pt(begin()); + minValue=std::numeric_limits::max(); maxValue=-std::numeric_limits::max(); + for(int i=0;imaxValue) + maxValue=*pt; + } } /*! @@ -9217,15 +6736,15 @@ void DataArrayInt::applyModulus(int val) * \param [in] vmax end of range. This value is \b not included in range (excluded). * \return a newly allocated data array that the caller should deal with. * - * \sa DataArrayInt::getIdsNotInRange + * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative */ -DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const +DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const { checkAllocated(); if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !"); + throw INTERP_KERNEL::Exception("DataArrayInt::findIdsInRange : this must have exactly one component !"); const int *cptr(begin()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); + MCAuto ret(DataArrayInt::New()); ret->alloc(0,1); int nbOfTuples(getNumberOfTuples()); for(int i=0;i=vmin && *cptr ret(DataArrayInt::New()); ret->alloc(0,1); + MCAuto ret(DataArrayInt::New()); ret->alloc(0,1); int nbOfTuples(getNumberOfTuples()); for(int i=0;i=vmax) @@ -9258,6 +6777,26 @@ DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const 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 +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::findIdsStricltyNegative : this must have exactly one component !"); + const int *cptr(getConstPointer()); + MCAuto ret(DataArrayInt::New()); ret->alloc(0,1); + int nbOfTuples(getNumberOfTuples()); + for(int i=0;ipushBackSilent(i); + return ret.retn(); +} + /*! * 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. @@ -9489,7 +7028,7 @@ DataArrayInt *DataArrayInt::MakePartition(const std::vector::const_iterator it4=groups.begin();it4!=groups.end();it4++) if(*it4) groups2.push_back(*it4); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(newNb,1); int *retPtr=ret->getPointer(); std::fill(retPtr,retPtr+newNb,0); @@ -9618,6 +7157,53 @@ DataArrayInt *DataArrayInt::BuildIntersection(const std::vector& v) +{ + int sz((int)std::count(v.begin(),v.end(),true)); + MCAuto ret(DataArrayInt::New()); ret->alloc(sz,1); + std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer())); + return ret.retn(); +} + +/*! + * This method returns the list of ids in ascending mode so that v[id]==false. + */ +DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector& v) +{ + int sz((int)std::count(v.begin(),v.end(),false)); + MCAuto ret(DataArrayInt::New()); ret->alloc(sz,1); + std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer())); + return ret.retn(); +} + /*! * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). * This method is not available into python because no available optimized data structure available to map std::vector< std::vector >. @@ -9629,7 +7215,7 @@ DataArrayInt *DataArrayInt::BuildIntersection(const std::vector >& v, DataArrayInt *& data, DataArrayInt *& dataIndex) { int sz((int)v.size()); - MEDCouplingAutoRefCountObjectPtr ret0(DataArrayInt::New()),ret1(DataArrayInt::New()); + MCAuto ret0(DataArrayInt::New()),ret1(DataArrayInt::New()); ret1->alloc(sz+1,1); int *pt(ret1->getPointer()); *pt=0; for(int i=0;i >& v */ DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const { - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !"); - std::vector tmp(nbOfElement); - const int *pt=getConstPointer(); - int nbOfTuples=getNumberOfTuples(); - for(const int *w=pt;w!=pt+nbOfTuples;w++) - if(*w>=0 && *walloc(nbOfRetVal,1); - int j=0; - int *retPtr=ret->getPointer(); - for(int i=0;i tmp(nbOfElement); + const int *pt=getConstPointer(); + int nbOfTuples=getNumberOfTuples(); + for(const int *w=pt;w!=pt+nbOfTuples;w++) + if(*w>=0 && *walloc(nbOfRetVal,1); + int j=0; + int *retPtr=ret->getPointer(); + for(int i=0;icheckAllocated(); if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !"); + throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !"); if(other->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !"); + throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !"); const int *pt=getConstPointer(); int nbOfTuples=getNumberOfTuples(); std::set s1(pt,pt+nbOfTuples); @@ -9729,8 +7315,9 @@ DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other checkAllocated(); other->checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG); if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG); - const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); + const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()); + const int *work1(pt1Bg),*work2(pt2Bg); + MCAuto ret(DataArrayInt::New()); ret->alloc(0,1); for(;work1!=pt1End;work1++) { if(work2!=pt2End && *work1==*work2) @@ -9786,30 +7373,63 @@ DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const * * \return a newly allocated array that contain the result of the unique operation applied on \a this. * \throw if \a this is not allocated or if \a this has not exactly one component. + * \sa DataArrayInt::buildUniqueNotSorted */ DataArrayInt *DataArrayInt::buildUnique() const { checkAllocated(); if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !"); + throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !"); int nbOfTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr tmp=deepCpy(); + MCAuto tmp=deepCopy(); int *data=tmp->getPointer(); int *last=std::unique(data,data+nbOfTuples); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(std::distance(data,last),1); std::copy(data,last,ret->getPointer()); return ret.retn(); } +/*! + * This method can be applied on allocated with one component DataArrayInt instance. + * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted. + * + * \return a newly allocated array that contain the result of the unique operation applied on \a this. + * + * \throw if \a this is not allocated or if \a this has not exactly one component. + * + * \sa DataArrayInt::buildUnique + */ +DataArrayInt *DataArrayInt::buildUniqueNotSorted() const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !"); + int minVal,maxVal; + getMinMaxValues(minVal,maxVal); + std::vector b(maxVal-minVal+1,false); + const int *ptBg(begin()),*endBg(end()); + MCAuto ret(DataArrayInt::New()); ret->alloc(0,1); + for(const int *pt=ptBg;pt!=endBg;pt++) + { + if(!b[*pt-minVal]) + { + ret->pushBackSilent(*pt); + b[*pt-minVal]=true; + } + } + ret->copyStringInfoFrom(*this); + return ret.retn(); +} + /*! * Returns a new DataArrayInt which contains size of every of groups described by \a this * "index" array. Such "index" array is returned for example by - * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity + * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity * "MEDCouplingUMesh::buildDescendingConnectivity" and - * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex + * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex * "MEDCouplingUMesh::getNodalConnectivityIndex" etc. - * This method preforms the reverse operation of DataArrayInt::computeOffsets2. + * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull. * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples * equals to \a this->getNumberOfComponents() - 1, and number of components is 1. * The caller is to delete this array using decrRef() as it is no more needed. @@ -9822,13 +7442,13 @@ DataArrayInt *DataArrayInt::buildUnique() const * - result array contains [2,3,1,0,2,6], * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc. * - * \sa DataArrayInt::computeOffsets2 + * \sa DataArrayInt::computeOffsetsFull */ DataArrayInt *DataArrayInt::deltaShiftIndex() const { checkAllocated(); if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !"); + throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !"); int nbOfTuples=getNumberOfTuples(); if(nbOfTuples<2) throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !"); @@ -9846,7 +7466,7 @@ DataArrayInt *DataArrayInt::deltaShiftIndex() const * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples * and components remains the same.
* This method is useful for allToAllV in MPI with contiguous policy. This method - * differs from computeOffsets2() in that the number of tuples is \b not changed by + * differs from computeOffsetsFull() in that the number of tuples is \b not changed by * this one. * \throw If \a this is not allocated. * \throw If \a this->getNumberOfComponents() != 1. @@ -9861,7 +7481,7 @@ void DataArrayInt::computeOffsets() { checkAllocated(); if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !"); + throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !"); int nbOfTuples=getNumberOfTuples(); if(nbOfTuples==0) return ; @@ -9894,15 +7514,13 @@ void DataArrayInt::computeOffsets() * - After \a this contains [0,3,8,9,11,11,19]
* \sa DataArrayInt::deltaShiftIndex */ -void DataArrayInt::computeOffsets2() +void DataArrayInt::computeOffsetsFull() { checkAllocated(); if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !"); + throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !"); int nbOfTuples=getNumberOfTuples(); int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int)); - if(nbOfTuples==0) - return ; const int *work=getConstPointer(); ret[0]=0; for(int i=0;igetNumberOfComponents() ranges, all ids in \a listOfIds * filling completely one of the ranges in \a this. @@ -9923,7 +7541,7 @@ void DataArrayInt::computeOffsets2() * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So * \a idsInInputListThatFetch is a part of input \a listOfIds. * - * \sa DataArrayInt::computeOffsets2 + * \sa DataArrayInt::computeOffsetsFull * * \b Example:
* - \a this : [0,3,7,9,15,18] @@ -9933,17 +7551,17 @@ void DataArrayInt::computeOffsets2() * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch. *
*/ -void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const +void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const { if(!listOfIds) - throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !"); + throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !"); listOfIds->checkAllocated(); checkAllocated(); if(listOfIds->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !"); + throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !"); if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !"); - MEDCouplingAutoRefCountObjectPtr ret0=DataArrayInt::New(); ret0->alloc(0,1); - MEDCouplingAutoRefCountObjectPtr ret1=DataArrayInt::New(); ret1->alloc(0,1); + throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !"); + MCAuto ret0=DataArrayInt::New(); ret0->alloc(0,1); + MCAuto ret1=DataArrayInt::New(); ret1->alloc(0,1); const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1); const int *tupPtr(listOfIds->begin()),*offPtr(offBg); while(tupPtr!=tupEnd && offPtr!=offEnd) @@ -9995,10 +7613,10 @@ DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !"); checkAllocated(); if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !"); + throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !"); offsets->checkAllocated(); if(offsets->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !"); + throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !"); int othNbTuples=offsets->getNumberOfTuples()-1; int nbOfTuples=getNumberOfTuples(); int retNbOftuples=0; @@ -10025,7 +7643,7 @@ DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets throw INTERP_KERNEL::Exception(oss.str().c_str()); } } - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(retNbOftuples,1); int *retPtr=ret->getPointer(); for(int i=0;i ret(DataArrayInt::New()); ret->alloc(sz,1); + MCAuto ret(DataArrayInt::New()); ret->alloc(sz,1); int *retPtr(ret->getPointer()); pos=bg; for(int i=0;i ret=DataArrayInt::New(); ret->alloc(nbTuples,1); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbTuples,1); int nbOfRanges=ranges->getNumberOfTuples(); const int *rangesPtr=ranges->getConstPointer(); int *retPtr=ret->getPointer(); @@ -10175,7 +7793,7 @@ DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !"); int nbTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbTuples,1); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbTuples,1); int nbOfRanges=ranges->getNumberOfTuples(); const int *rangesPtr=ranges->getConstPointer(); int *retPtr=ret->getPointer(); @@ -10198,6 +7816,73 @@ DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges return ret.retn(); } +/*! + * \b WARNING this method is a \b non \a const \b method. This method works tuple by tuple. Each tuple is expected to be pairs (number of components must be equal to 2). + * This method rearrange each pair in \a this so that, tuple with id \b tid will be after the call \c this->getIJ(tid,0)==this->getIJ(tid-1,1) and \c this->getIJ(tid,1)==this->getIJ(tid+1,0). + * If it is impossible to reach such condition an exception will be thrown ! \b WARNING In case of throw \a this can be partially modified ! + * If this method has correctly worked, \a this will be able to be considered as a linked list. + * This method does nothing if number of tuples is lower of equal to 1. + * + * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration. + * + * \sa MEDCouplingUMesh::orderConsecutiveCells1D + */ +void DataArrayInt::sortEachPairToMakeALinkedList() +{ + checkAllocated(); + if(getNumberOfComponents()!=2) + throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !"); + int nbOfTuples(getNumberOfTuples()); + if(nbOfTuples<=1) + return ; + int *conn(getPointer()); + for(int i=1;i1) + { + if(conn[2]==conn[3]) + { + std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0]) + std::swap(conn[2],conn[3]); + //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0]) + if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0]) + { + std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + if(conn[0]==conn[1] || conn[2]==conn[3]) + throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !"); + int tmp[4]; + std::set s; + s.insert(conn,conn+4); + if(s.size()!=3) + throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !"); + if(std::count(conn,conn+4,conn[0])==2) + { + tmp[0]=conn[1]; + tmp[1]=conn[0]; + tmp[2]=conn[0]; + if(conn[2]==conn[0]) + { tmp[3]=conn[3]; } + else + { tmp[3]=conn[2];} + std::copy(tmp,tmp+4,conn); + } + else + {//here we are sure to have (std::count(conn,conn+4,conn[1])==2) + if(conn[1]==conn[3]) + std::swap(conn[2],conn[3]); + } + } + } +} + /*! * * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance. @@ -10214,7 +7899,7 @@ DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !"); int nbTuples=getNumberOfTuples(); const int *inPtr=getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1); int *retPtr=ret->getPointer(); for(int i=0;i ret; ret.insert(begin(),end()); - MEDCouplingAutoRefCountObjectPtr ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1); + MCAuto ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1); std::copy(ret.begin(),ret.end(),ret2->getPointer()); return ret2.retn(); } @@ -10345,7 +8030,7 @@ DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) int nbOfTuple2=a2->getNumberOfTuples(); int nbOfComp=a1->getNumberOfComponents(); int nbOfComp2=a2->getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=0; + MCAuto ret=0; if(nbOfTuple==nbOfTuple2) { if(nbOfComp==nbOfComp2) @@ -10504,7 +8189,7 @@ DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt { if(nbOfComp1==nbOfComp2) { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbOfTuple2,nbOfComp1); std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus()); ret->copyStringInfoFrom(*a1); @@ -10512,7 +8197,7 @@ DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt } else if(nbOfComp2==1) { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbOfTuple1,nbOfComp1); const int *a2Ptr=a2->getConstPointer(); const int *a1Ptr=a1->getConstPointer(); @@ -10531,7 +8216,7 @@ DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt else if(nbOfTuple2==1) { a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbOfTuple1,nbOfComp1); const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); int *pt=ret->getPointer(); @@ -10635,7 +8320,7 @@ DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt int nbOfTuple2=a2->getNumberOfTuples(); int nbOfComp=a1->getNumberOfComponents(); int nbOfComp2=a2->getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=0; + MCAuto ret=0; if(nbOfTuple==nbOfTuple2) { if(nbOfComp==nbOfComp2) @@ -10797,7 +8482,7 @@ DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a { if(nbOfComp1==nbOfComp2) { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbOfTuple2,nbOfComp1); std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides()); ret->copyStringInfoFrom(*a1); @@ -10805,7 +8490,7 @@ DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a } else if(nbOfComp2==1) { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbOfTuple1,nbOfComp1); const int *a2Ptr=a2->getConstPointer(); const int *a1Ptr=a1->getConstPointer(); @@ -10824,7 +8509,7 @@ DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a else if(nbOfTuple2==1) { a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbOfTuple1,nbOfComp1); const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); int *pt=ret->getPointer(); @@ -10930,7 +8615,7 @@ void DataArrayInt::divideEqual(const DataArrayInt *other) */ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) { - if(!a1 || !a2) + if(!a1 || !a2) throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !"); int nbOfTuple1=a1->getNumberOfTuples(); int nbOfTuple2=a2->getNumberOfTuples(); @@ -10940,7 +8625,7 @@ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt * { if(nbOfComp1==nbOfComp2) { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbOfTuple2,nbOfComp1); std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus()); ret->copyStringInfoFrom(*a1); @@ -10948,7 +8633,7 @@ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt * } else if(nbOfComp2==1) { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbOfTuple1,nbOfComp1); const int *a2Ptr=a2->getConstPointer(); const int *a1Ptr=a1->getConstPointer(); @@ -10967,7 +8652,7 @@ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt * else if(nbOfTuple2==1) { a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbOfTuple1,nbOfComp1); const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); int *pt=ret->getPointer(); @@ -11070,7 +8755,7 @@ DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !"); if(nbOfComp!=1 || nbOfComp2!=1) throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1); const int *ptr1(a1->begin()),*ptr2(a2->begin()); int *ptr=ret->getPointer(); for(int i=0;i ret=DataArrayInt::New(); + MCAuto ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1); int *ptr=ret->getPointer(); if(step>0) @@ -11326,8 +9011,8 @@ int DataArrayIntTuple::intValue() const } /*! - * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef. - * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false. + * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef. + * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false. * This method throws an INTERP_KERNEL::Exception is it is impossible to match sizes of \b this that is too say \b nbOfCompo=this->_nb_of_elem and \bnbOfTuples==1 or * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem. */