X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingMemArray.cxx;h=ee514548315a710085ad4ca73fd66512bcc491a8;hb=a25fc7c3173633c8eec4a4db9cda520f947317b7;hp=ed5371df95b8e9aa6fb010fd5ceea85a5597c7a8;hpb=62d18e09efe179d5bb72d21c0b359ab489d4aa0e;p=tools%2Fmedcoupling.git diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index ed5371df9..ee5145483 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-2015 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 @@ -120,7 +120,7 @@ std::size_t DataArray::getHeapMemorySizeWithoutChildren() const return sz1+sz2+sz3; } -std::vector DataArray::getDirectChildren() const +std::vector DataArray::getDirectChildrenWithNull() const { return std::vector(); } @@ -130,7 +130,7 @@ std::vector DataArray::getDirectChildren() const * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information. * \param [in] name - new array name */ -void DataArray::setName(const char *name) +void DataArray::setName(const std::string& name) { _name=name; } @@ -164,7 +164,7 @@ void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vect throw INTERP_KERNEL::Exception(oss.str().c_str()); } for(std::size_t i=0;i& compoIds, const DataArray& other) @@ -180,7 +180,7 @@ void DataArray::copyPartOfStringInfoFrom2(const std::vector& compoIds, cons throw INTERP_KERNEL::Exception(oss.str().c_str()); } for(std::size_t i=0;i& arrs) * \param [in] info - the string containing the information. * \throw If \a i is not a valid component index. */ -void DataArray::setInfoOnComponent(int i, const char *info) +void DataArray::setInfoOnComponent(int i, const std::string& info) { if(i<(int)_info_on_compo.size() && i>=0) _info_on_compo[i]=info; @@ -516,7 +528,7 @@ void DataArray::setInfoAndChangeNbOfCompo(const std::vector& info) _info_on_compo=info; } -void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const +void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const { if(getNumberOfTuples()!=nbOfTuples) { @@ -525,7 +537,7 @@ void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const } } -void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const +void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const { if(getNumberOfComponents()!=nbOfCompo) { @@ -534,7 +546,7 @@ void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const } } -void DataArray::checkNbOfElems(std::size_t nbOfElems, const char *msg) const +void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const { if(getNbOfElems()!=nbOfElems) { @@ -543,9 +555,9 @@ void DataArray::checkNbOfElems(std::size_t nbOfElems, const char *msg) const } } -void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const +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()); @@ -557,7 +569,7 @@ void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) } } -void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const +void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const { checkNbOfTuples(nbOfTuples,msg); checkNbOfComps(nbOfCompo,msg); @@ -566,7 +578,7 @@ void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char /*! * Simply this method checks that \b value is in [0,\b ref). */ -void DataArray::CheckValueInRange(int ref, int value, const char *msg) +void DataArray::CheckValueInRange(int ref, int value, const std::string& msg) { if(value<0 || value>=ref) { @@ -579,7 +591,7 @@ void DataArray::CheckValueInRange(int ref, int value, const char *msg) * This method checks that [\b start, \b end) is compliant with ref length \b value. * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported. */ -void DataArray::CheckValueInRangeEx(int value, int start, int end, const char *msg) +void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg) { if(start<0 || start>=value) { @@ -596,7 +608,7 @@ void DataArray::CheckValueInRangeEx(int value, int start, int end, const char *m } } -void DataArray::CheckClosingParInRange(int ref, int value, const char *msg) +void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg) { if(value<0 || value>ref) { @@ -644,7 +656,7 @@ void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSli stopSlice=stop; } -int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg) +int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg) { if(end::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() << "\">"; @@ -1164,7 +1199,7 @@ void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char *nameIn float *pt(tmp); // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp); for(const double *src=begin();src!=end();src++,pt++) - *pt=int(*src); + *pt=float(*src); const char *data(reinterpret_cast((float *)tmp)); std::size_t sz(getNbOfElems()*sizeof(float)); byteArr->insertAtTheEnd(data,data+sz); @@ -1190,6 +1225,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,7 +1245,14 @@ void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const _mem.reprZip(getNumberOfComponents(),stream); } -void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const +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(); const double *data=getConstPointer(); @@ -1348,9 +1396,8 @@ DataArrayInt *DataArrayDouble::convertToIntArr() const { DataArrayInt *ret=DataArrayInt::New(); ret->alloc(getNumberOfTuples(),getNumberOfComponents()); - std::size_t nbOfVals=getNbOfElems(); int *dest=ret->getPointer(); - // to make Visual C++ happy : instead of std::copy(src,src+nbOfVals,dest); + // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest); for(const double *src=begin();src!=end();src++,dest++) *dest=(int)*src; ret->copyStringInfoFrom(*this); @@ -1784,10 +1831,10 @@ DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double d for(;jsetName(getName().c_str()); + ret->setName(getName()); for(int i=0;isetInfoOnComponent(i,getInfoOnComponent(i).c_str()); - ret->setName(getName().c_str()); + ret->setInfoOnComponent(i,getInfoOnComponent(i)); + ret->setName(getName()); return ret.retn(); } @@ -1847,9 +1894,11 @@ void DataArrayDouble::transpose() * \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 +DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector& compoIds) const { checkAllocated(); MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); @@ -1880,9 +1929,11 @@ DataArray *DataArrayDouble::keepSelectedComponents(const std::vector& compo * \throw If \a this is not allocated. * \throw If \a this and \a other arrays have different number of tuples. * + * \if ENABLE_EXAMPLES * \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example". * * \ref py_mcdataarraydouble_meldwith "Here is a Python example". + * \endif */ void DataArrayDouble::meldWith(const DataArrayDouble *other) { @@ -1960,25 +2011,30 @@ bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, * [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1 * gives the number of groups of coincident tuples. * \throw If \a this is not allocated. - * \throw If the number of components is not in [1,2,3]. + * \throw If the number of components is not in [1,2,3,4]. * + * \if ENABLE_EXAMPLES * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example". * * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example". + * \endif * \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe */ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const { checkAllocated(); int nbOfCompo=getNumberOfComponents(); - if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work - throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3."); - + 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); switch(nbOfCompo) - { + { + case 4: + findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI); + break; case 3: findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI); break; @@ -1989,8 +2045,8 @@ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayI findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI); break; default: - throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !"); - } + 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(); } @@ -2078,7 +2134,7 @@ DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) 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])); @@ -2106,7 +2162,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(); } @@ -2143,7 +2199,7 @@ DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble const double *thisBBPtr(begin()); int *retPtr(ret->getPointer()); switch(nbOfComp/2) - { + { case 3: { BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps); @@ -2167,8 +2223,8 @@ DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble } default: throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !"); - } - + } + return ret.retn(); } @@ -2186,9 +2242,11 @@ DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble * \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 the number of components is not in [1,2,3]. + * \throw If the number of components is not in [1,2,3,4]. * + * \if ENABLE_EXAMPLES * \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example". + * \endif */ DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const { @@ -2212,7 +2270,9 @@ DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTuple * \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_mcdataarraydouble_setselectedcomponents "Here is a Python example". + * \endif */ void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector& compoIds) { @@ -2262,7 +2322,9 @@ void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std: * \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) { @@ -2325,7 +2387,9 @@ void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, i * 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) { @@ -2379,7 +2443,9 @@ void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTupl * \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) { @@ -2450,7 +2516,9 @@ void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTu * \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) { @@ -2510,7 +2578,9 @@ void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, cons * 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) { @@ -2582,7 +2652,9 @@ void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTu * 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) { @@ -3082,7 +3154,7 @@ void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, do int nbOfTuplesOther=other->getNumberOfTuples(); MEDCouplingAutoRefCountObjectPtr 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); @@ -3103,7 +3175,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(); } @@ -3294,25 +3366,50 @@ double DataArrayDouble::norm2() const /*! * Returns the maximum norm of the vector defined by \a this array. + * This method works even if the number of components is diferent from one. + * If the number of elements in \a this is 0, -1. is returned. * \return double - the value of the maximum norm, i.e. - * the maximal absolute value among values of \a this array. + * the maximal absolute value among values of \a this array (whatever its number of components). * \throw If \a this is not allocated. */ double DataArrayDouble::normMax() const { checkAllocated(); - double ret=-1.; - std::size_t nbOfElems=getNbOfElems(); - const double *pt=getConstPointer(); + double ret(-1.); + std::size_t nbOfElems(getNbOfElems()); + const double *pt(getConstPointer()); for(std::size_t i=0;iret) ret=val; } return ret; } +/*! + * Returns the minimum norm (absolute value) of the vector defined by \a this array. + * This method works even if the number of components is diferent from one. + * If the number of elements in \a this is 0, std::numeric_limits::max() is returned. + * \return double - the value of the minimum norm, i.e. + * the minimal absolute value among values of \a this array (whatever its number of components). + * \throw If \a this is not allocated. + */ +double DataArrayDouble::normMin() const +{ + checkAllocated(); + double ret(std::numeric_limits::max()); + std::size_t nbOfElems(getNbOfElems()); + const double *pt(getConstPointer()); + for(std::size_t i=0;igetNumberOfComponents(), allocated @@ -3509,7 +3606,7 @@ DataArrayDouble *DataArrayDouble::fromCylToCart() const w[1]=wIn[0]*sin(wIn[1]); w[2]=wIn[2]; } - ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str()); + ret->setInfoOnComponent(2,getInfoOnComponent(2)); return ret; } @@ -3588,7 +3685,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 !"); - } + } } /*! @@ -3686,7 +3783,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()); + ret->alloc(nbOfTuple,1); + const double *src(getConstPointer()); + double *dest(ret->getPointer()); + for(int i=0;i(fabs)); declareAsNew(); } /*! - * Apply a liner function to a given component of \a this array, so that + * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this. + * This method is a const method (that do not change any values in \a this) contrary to DataArrayDouble::abs method. + * + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of tuples and component as \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. + * \sa DataArrayDouble::abs + */ +DataArrayDouble *DataArrayDouble::computeAbs() const +{ + checkAllocated(); + DataArrayDouble *newArr(DataArrayDouble::New()); + int nbOfTuples(getNumberOfTuples()); + int nbOfComp(getNumberOfComponents()); + newArr->alloc(nbOfTuples,nbOfComp); + std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun(fabs)); + newArr->copyStringInfoFrom(*this); + return newArr; +} + +/*! + * Apply a linear function to a given component of \a this array, so that * an array element (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 @@ -4200,144 +4352,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 char *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 applyFunc3(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 char *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()); + MEDCouplingAutoRefCountObjectPtr 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 applyFunc2 or applyFunc3 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()) { - try + 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) + { + 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 char *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 applyFunc2 or applyFunc3 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::applyFunc2(int nbOfComp, const std::string& func, bool isSafe) const +{ + return applyFunc3(nbOfComp,getVarsOnComponent(),func,isSafe); } /*! @@ -4348,6 +4566,8 @@ DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) con * \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 @@ -4356,14 +4576,20 @@ DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) con * \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 char *func) const +DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector& varsOrder, const std::string& func, bool isSafe) const { + if(nbOfComp<=0) + throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc3 : 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 "; @@ -4371,32 +4597,52 @@ 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(); + MEDCouplingAutoRefCountObjectPtr 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 char *func) +void DataArrayDouble::applyFuncFast32(const std::string& func) { checkAllocated(); INTERP_KERNEL::ExprParser expr(func); @@ -4414,7 +4660,7 @@ void DataArrayDouble::applyFuncFast32(const char *func) declareAsNew(); } -void DataArrayDouble::applyFuncFast64(const char *func) +void DataArrayDouble::applyFuncFast64(const std::string& func) { checkAllocated(); INTERP_KERNEL::ExprParser expr(func); @@ -4447,23 +4693,53 @@ DataArrayDoubleIterator *DataArrayDouble::iterator() * needed. * \throw If \a this->getNumberOfComponents() != 1. * + * \sa DataArrayDouble::getIdsNotInRange + * + * \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 { checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !"); - const double *cptr=getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(0,1); - int nbOfTuples=getNumberOfTuples(); + const double *cptr(begin()); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); + int nbOfTuples(getNumberOfTuples()); for(int i=0;i=vmin && *cptr<=vmax) ret->pushBackSilent(i); return ret.retn(); } +/*! + * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional + * array whose values are not within a given range. Textual data is not copied. + * \param [in] vmin - a lowest not acceptable value (excluded). + * \param [in] vmax - a greatest not acceptable value (excluded). + * \return DataArrayInt * - the new instance of DataArrayInt. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this->getNumberOfComponents() != 1. + * + * \sa DataArrayDouble::getIdsInRange + */ +DataArrayInt *DataArrayDouble::getIdsNotInRange(double vmin, double vmax) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsNotInRange : this must have exactly one component !"); + const double *cptr(begin()); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); + int nbOfTuples(getNumberOfTuples()); + for(int i=0;ivmax) + ret->pushBackSilent(i); + return ret.retn(); +} + /*! * Returns a new DataArrayDouble by concatenating two 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) @@ -4491,6 +4767,8 @@ DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const Dat * the number of component in the result array is same as that of each of given arrays. * Info on components is copied from the first of the given arrays. Number of components * in the given arrays must be the same. + * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it + * not the object itself. * \param [in] arr - a sequence of arrays to include in the result array. * \return DataArrayDouble * - the new instance of DataArrayDouble. * The caller is to delete this result array using decrRef() as it is no more @@ -4599,7 +4877,7 @@ DataArrayDouble *DataArrayDouble::Meld(const std::vectorsetInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str()); + ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j)); return ret; } @@ -4643,8 +4921,8 @@ DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArray sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j]; retPtr[i]=sum; } - ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str()); - ret->setName(a1->getName().c_str()); + ret->setInfoOnComponent(0,a1->getInfoOnComponent(0)); + ret->setName(a1->getName()); return ret; } @@ -5431,11 +5709,42 @@ void DataArrayDouble::powEqual(const DataArrayDouble *other) *ptr=pow(*ptr,*ptrc); else { - std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !"; + std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + declareAsNew(); +} + +/*! + * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context. + * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true. + * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown. + * + * \throw if \a this is not allocated. + * \throw if \a this has not exactly one component. + */ +std::vector 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 */ void DataArrayDouble::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoS) { - setName(tinyInfoS[0].c_str()); + setName(tinyInfoS[0]); if(isAllocated()) { int nbOfCompo=getNumberOfComponents(); for(int i=0;igetNumberOfComponents() != 1 * \throw If any value of \a this can't be used as a valid index for * [\a indArrBg, \a indArrEnd). + * + * \sa replaceOneValByInThis */ 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 && *ptstrt) + { + sttoopp++; + int a(sttoopp-1-strt),tmp(strt); + if(a%(nbTuples-1)!=0) + return false; + stteepp=a/(nbTuples-1); + for(int i=0;i * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example". + * \endif */ DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const { @@ -6312,9 +6726,11 @@ DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const * The caller is to delete this result array using decrRef() as it is no more * needed. * + * \if ENABLE_EXAMPLES * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example". * * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example". + * \endif */ DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const { @@ -6329,7 +6745,7 @@ DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const { int v(new2Old[i]); if(v>=0 && v& v) const checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !"); - int nbOfTuples(getNumberOfTuples()); const int *w(begin()),*end2(end()); int refVal=-std::numeric_limits::max(); int i=0; @@ -6441,6 +6856,25 @@ bool DataArrayInt::isFittingWith(const std::vector& v) const return w==end2; } +/*! + * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple equal to \a val + * put True to the corresponding entry in \a vec. + * \a vec is expected to be with the same size than the number of tuples of \a this. + */ +void DataArrayInt::switchOnTupleEqualTo(int val, std::vector& vec) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !"); + int nbOfTuples(getNumberOfTuples()); + if(nbOfTuples!=(int)vec.size()) + throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !"); + const int *pt(begin()); + for(int i=0;i ret(DataArrayInt::New()); + ret->alloc(nbOfTuple,1); + const int *src(getConstPointer()); + int *dest(ret->getPointer()); + for(int i=0;igetNumberOfComponents() < 1. @@ -6593,9 +7049,11 @@ void DataArrayInt::checkStrictlyMonotonic(bool increasing) const * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples(). * \throw If \a other includes a value which is not in \a this array. * + * \if ENABLE_EXAMPLES * \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example". * * \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example". + * \endif */ DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const { @@ -7271,17 +7729,20 @@ DataArrayInt *DataArrayInt::buildPermArrPerLevel() const /*! * Checks if contents of \a this array are equal to that of an array filled with * iota(). This method is particularly useful for DataArrayInt instances that represent - * a renumbering array to check the real need in renumbering. + * a renumbering array to check the real need in renumbering. In this case it is better to use isIdentity2 + * method of isIdentity method. + * * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples()) * \throw If \a this is not allocated. * \throw If \a this->getNumberOfComponents() != 1. + * \sa isIdentity2 */ bool DataArrayInt::isIdentity() const { checkAllocated(); if(getNumberOfComponents()!=1) return false; - int nbOfTuples=getNumberOfTuples(); + int nbOfTuples(getNumberOfTuples()); const int *pt=getConstPointer(); for(int i=0;igetNumberOfTuples()) and if \a this has \a sizeExpected tuples in it. + * + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \sa isIdentity + */ +bool DataArrayInt::isIdentity2(int sizeExpected) const +{ + bool ret0(isIdentity()); + if(!ret0) + return false; + return getNumberOfTuples()==sizeExpected; +} + /*! * Checks if all values in \a this array are equal to \a val. * \param [in] val - value to check equality of array values to. @@ -7441,10 +7921,10 @@ DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) for(;jsetName(getName().c_str()); + ret->setName(getName()); for(int i=0;isetInfoOnComponent(i,getInfoOnComponent(i).c_str()); - ret->setName(getName().c_str()); + ret->setInfoOnComponent(i,getInfoOnComponent(i)); + ret->setName(getName()); return ret.retn(); } @@ -7478,9 +7958,11 @@ void DataArrayInt::reAlloc(int nbOfTuples) * \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 +DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector& compoIds) const { checkAllocated(); MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); @@ -7507,9 +7989,11 @@ DataArray *DataArrayInt::keepSelectedComponents(const std::vector& compoIds * \throw If \a this is not allocated. * \throw If \a this and \a other arrays have different number of tuples. * + * \if ENABLE_EXAMPLES * \ref cpp_mcdataarrayint_meldwith "Here is a C++ example". * * \ref py_mcdataarrayint_meldwith "Here is a Python example". + * \endif */ void DataArrayInt::meldWith(const DataArrayInt *other) { @@ -7550,7 +8034,9 @@ void DataArrayInt::meldWith(const DataArrayInt *other) * \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 */ void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector& compoIds) { @@ -7601,7 +8087,9 @@ void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vecto * \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) { @@ -7664,7 +8152,9 @@ void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int end * non-empty range of increasing indices or indices are out of a valid range * for \this array. * + * \if ENABLE_EXAMPLES * \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example". + * \endif */ void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) { @@ -7719,7 +8209,9 @@ void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, in * \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) { @@ -7790,7 +8282,9 @@ void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, * \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) { @@ -7850,7 +8344,9 @@ void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int * 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) { @@ -7922,7 +8418,9 @@ void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, * 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) { @@ -8262,19 +8760,20 @@ DataArrayIntIterator *DataArrayInt::iterator() /*! * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a - * given one. + * given one. The ids are sorted in the ascending order. * \param [in] val - the value to find within \a this. * \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. + * \sa DataArrayInt::getIdsEqualTuple */ DataArrayInt *DataArrayInt::getIdsEqual(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 !"); - const int *cptr=getConstPointer(); + const int *cptr(getConstPointer()); MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); int nbOfTuples=getNumberOfTuples(); for(int i=0;i 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 + */ +DataArrayInt *DataArrayInt::getIdsEqualTuple(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 !"; + 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); + const int *bg(begin()),*end2(end()),*work(begin()); + while(work!=end2) + { + work=std::search(work,end2,tupleBg,tupleEnd); + if(work!=end2) + { + std::size_t pos(std::distance(bg,work)); + if(pos%nbOfCompoExp==0) + ret->pushBackSilent(pos/nbOfCompoExp); + work++; + } + } + return ret.retn(); +} /*! * Assigns \a newValue to all elements holding \a oldValue within \a this @@ -8675,6 +9213,8 @@ DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt * the number of component in the result array is same as that of each of given arrays. * Info on components is copied from the first of the given arrays. Number of components * in the given arrays must be the same. + * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it + * not the object itself. * \param [in] arr - a sequence of arrays to include in the result array. * \return DataArrayInt * - the new instance of DataArrayInt. * The caller is to delete this result array using decrRef() as it is no more @@ -8827,19 +9367,72 @@ int DataArrayInt::getMinValueInArray() const return *loc; } +/*! + * 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 + */ +void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + 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; + } +} + /*! * Converts every value of \a this array to its absolute value. - * \throw If \a this is not allocated. + * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs + * should be called instead. + * + * \throw If \a this is not allocated. + * \sa DataArrayInt::computeAbs */ void DataArrayInt::abs() { checkAllocated(); - int *ptr=getPointer(); - std::size_t nbOfElems=getNbOfElems(); + int *ptr(getPointer()); + std::size_t nbOfElems(getNbOfElems()); std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun(std::abs)); declareAsNew(); } +/*! + * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this. + * This method is a const method (that do not change any values in \a this) contrary to DataArrayInt::abs method. + * + * \return DataArrayInt * - the new instance of DataArrayInt containing the + * same number of tuples and component as \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. + * \sa DataArrayInt::abs + */ +DataArrayInt *DataArrayInt::computeAbs() const +{ + checkAllocated(); + DataArrayInt *newArr(DataArrayInt::New()); + int nbOfTuples(getNumberOfTuples()); + int nbOfComp(getNumberOfComponents()); + newArr->alloc(nbOfTuples,nbOfComp); + std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun(std::abs)); + newArr->copyStringInfoFrom(*this); + return newArr; +} + /*! * Apply a liner function to a given component of \a this array, so that * an array element (x) becomes \f$ a * x + b \f$. @@ -8972,29 +9565,75 @@ void DataArrayInt::applyModulus(int val) * \param [in] vmin begin of range. This value is included in range (included). * \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 , DataArrayInt::getIdsStrictlyNegative */ DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const { checkAllocated(); if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !"); - const int *cptr=getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(0,1); - int nbOfTuples=getNumberOfTuples(); + const int *cptr(begin()); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); + int nbOfTuples(getNumberOfTuples()); for(int i=0;i=vmin && *cptrpushBackSilent(i); return ret.retn(); } +/*! + * This method works only on data array with one component. + * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that + * this[*id] \b not in [\b vmin,\b vmax) + * + * \param [in] vmin begin of range. This value is \b not included in range (excluded). + * \param [in] vmax end of range. This value is included in range (included). + * \return a newly allocated data array that the caller should deal with. + * + * \sa DataArrayInt::getIdsInRange , DataArrayInt::getIdsStrictlyNegative + */ +DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotInRange : this must have exactly one component !"); + const int *cptr(getConstPointer()); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); + int nbOfTuples(getNumberOfTuples()); + for(int i=0;i=vmax) + ret->pushBackSilent(i); + 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::getIdsInRange + */ +DataArrayInt *DataArrayInt::getIdsStrictlyNegative() const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::getIdsStrictlyNegative : this must have exactly one component !"); + const int *cptr(getConstPointer()); + MEDCouplingAutoRefCountObjectPtr 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. * * \param [in] vmin begin of range. This value is included in range (included). * \param [in] vmax end of range. This value is \b not included in range (excluded). - * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). - */ + * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */ bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const { checkAllocated(); @@ -9185,7 +9824,7 @@ DataArrayInt *DataArrayInt::Meld(const std::vector& arr) int k=0; for(int i=0;i<(int)a.size();i++) for(int j=0;jsetInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str()); + ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j)); return ret; } @@ -9342,12 +9981,82 @@ DataArrayInt *DataArrayInt::BuildIntersection(const std::vectoralloc((int)r.size(),1); std::copy(r.begin(),r.end(),ret->getPointer()); return ret; } +/// @cond INTERNAL +namespace ParaMEDMEMImpl +{ + class OpSwitchedOn + { + public: + OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { } + void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; } + private: + int *_pt; + int _cnt; + }; + + class OpSwitchedOff + { + public: + OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { } + void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; } + private: + int *_pt; + int _cnt; + }; +} +/// @endcond + +/*! + * This method returns the list of ids in ascending mode so that v[id]==true. + */ +DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector& v) +{ + int sz((int)std::count(v.begin(),v.end(),true)); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(sz,1); + std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::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)); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(sz,1); + std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::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 >. + * + * \param [in] v the input data structure to be translate into skyline format. + * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array. + * \param [out] dataIndex the second element of the skyline format. + */ +void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector >& v, DataArrayInt *& data, DataArrayInt *& dataIndex) +{ + int sz((int)v.size()); + MEDCouplingAutoRefCountObjectPtr ret0(DataArrayInt::New()),ret1(DataArrayInt::New()); + ret1->alloc(sz+1,1); + int *pt(ret1->getPointer()); *pt=0; + for(int i=0;ialloc(ret1->back(),1); + pt=ret0->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;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); @@ -9436,7 +10145,8 @@ 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); + const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()); + const int *work1(pt1Bg),*work2(pt2Bg); MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); for(;work1!=pt1End;work1++) { @@ -9493,12 +10203,13 @@ 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(); int *data=tmp->getPointer(); @@ -9509,6 +10220,38 @@ DataArrayInt *DataArrayInt::buildUnique() const 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()); + MEDCouplingAutoRefCountObjectPtr 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 @@ -9535,7 +10278,7 @@ 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' !"); @@ -9568,7 +10311,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 ; @@ -9702,10 +10445,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; @@ -9759,14 +10502,14 @@ from that of \a this and \a * \throw If \a this->getNumberOfComponents() != 1. * \throw If \a this->getNumberOfTuples() == 0. * \throw If \a this is not monotonically increasing. - * \throw If any element of ids in ( \a gb \a end \a step ) points outside the scale in \a this. + * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this. * * \b Example:
- * - \a bg , \a end and \a step : (0,5,2) + * - \a bg , \a stop and \a step : (0,5,2) * - \a this: [0,3,6,10,14,20] * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] ==
*/ -DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int end, int step) const +DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const { if(!isAllocated()) throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !"); @@ -9776,7 +10519,7 @@ DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int end, if(nbOfTuples==0) throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !"); const int *ids(begin()); - int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,end,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg); + int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg); for(int i=0;i=0 && posgetIJ(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); + } + } + } +} + /*! * * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance. @@ -10637,7 +11442,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(); @@ -10970,12 +11775,12 @@ bool DataArrayInt::resizeForUnserialization(const std::vector& tinyInfoI) */ void DataArrayInt::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoS) { - setName(tinyInfoS[0].c_str()); + setName(tinyInfoS[0]); if(isAllocated()) { int nbOfCompo=tinyInfoI[1]; for(int i=0;i