X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingMemArray.cxx;h=709fd85cd70e1e182b85aacc5ddbd676a1ef3b2e;hb=c6847bfb1eba9336d97c0f8d3ceed51e0a9f44ea;hp=44a708d7cf31c9543516f4b9396a76ae46e03864;hpb=6bfd8d6afb47fa46fd8fa0bc98d7fe057790460c;p=tools%2Fmedcoupling.git diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 44a708d7c..709fd85cd 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2014 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 @@ -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(); } @@ -903,7 +903,7 @@ void DataArrayDouble::pushBackSilent(double val) * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session. * - * \param [in] valsBg - an array of values to push at the end of \this. + * \param [in] valsBg - an array of values to push at the end of \c this. * \param [in] valsEnd - specifies the end of the array \a valsBg, so that * the last value of \a valsBg is \a valsEnd[ -1 ]. * \throw If \a this has already been allocated with number of components different from one. @@ -1146,7 +1146,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 { @@ -1162,6 +1164,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]={' ',' ',' ',' '}; @@ -1169,6 +1183,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() << "\">"; @@ -1202,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); @@ -1216,6 +1245,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(); @@ -1411,9 +1447,9 @@ 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. + * the same as in \c this one. * If a permutation reduction is needed, substr() or selectByTupleId() should be used. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * For more info on renumbering see \ref numbering. * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() * giving a new position for i-th old value. */ @@ -1443,8 +1479,8 @@ void DataArrayDouble::renumberInPlace(const int *old2New) /*! * 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. + * the same as in \c this one. + * For more info on renumbering see \ref numbering. * \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 @@ -1476,9 +1512,9 @@ void DataArrayDouble::renumberInPlaceR(const int *new2Old) /*! * 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. + * Number of tuples in the result array remains the same as in \c this one. * If a permutation reduction is needed, renumberAndReduce() should be used. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * For more info on renumbering see \ref numbering. * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() * giving a new position for i-th old value. * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller @@ -1504,9 +1540,9 @@ DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const /*! * 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. + * tuples in the result array remains the same as in \c this one. * If a permutation reduction is needed, substr() or selectByTupleId() should be used. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * For more info on renumbering see \ref numbering. * \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 @@ -1534,7 +1570,7 @@ DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const * 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. + * For more info on renumbering see \ref numbering. * \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. @@ -1567,7 +1603,7 @@ DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newN * 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. + * For more info on renumbering see \ref numbering. * \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 @@ -1592,6 +1628,11 @@ DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const in return ret.retn(); } +DataArrayDouble *DataArrayDouble::selectByTupleId(const DataArrayInt & di) const +{ + return selectByTupleId(di.getConstPointer(), di.getConstPointer()+di.getNumberOfTuples()); +} + /*! * 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 @@ -1601,7 +1642,7 @@ DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const in * \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. + * For more info on renumbering see \ref numbering. * \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 @@ -1638,7 +1679,7 @@ DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, cons * 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. + * For more info on renumbering see \ref numbering. * \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. @@ -1664,7 +1705,7 @@ DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) c /*! * 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. + * For more info on renumbering see \ref numbering. * \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 @@ -1862,7 +1903,7 @@ void DataArrayDouble::transpose() * \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()); @@ -2349,7 +2390,7 @@ void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, i * \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. + * for \c this array. * * \if ENABLE_EXAMPLES * \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example". @@ -2540,7 +2581,7 @@ void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, cons * 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. + * for \c this array. * * \if ENABLE_EXAMPLES * \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example". @@ -2614,7 +2655,7 @@ void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTu * \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. + * for \c this array. * * \if ENABLE_EXAMPLES * \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example". @@ -3526,14 +3567,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=deepCpy(); + 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. @@ -3617,7 +3708,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(); @@ -4307,6 +4398,8 @@ DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate fun * \param [in] nbOfComp - number of components in the result array. * \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 and \a nbOfComp components. * The caller is to delete this result array using decrRef() as it is no more @@ -4314,144 +4407,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 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 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()); + 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) { - try - { - expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp); - } - catch(INTERP_KERNEL::Exception& e) - { - std::ostringstream oss; oss << "For tuple # " << i << " with value ("; - std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator(oss,", ")); - oss << ") : Evaluation of function failed ! " << e.what(); - newArr->decrRef(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } + 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()); } - return newArr; + 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) + { + for(int i=0;igetInfoOnComponent(). - * \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 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(oss,", ")); - oss << ") : Evaluation of function failed !" << e.what(); - newArr->decrRef(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } + expr.prepareFastEvaluator(); + std::vector compInfo(getInfoOnComponents()); + rearrange(1); + fillWithValue(expr.evaluateDouble()); + rearrange(nbOfComp); + setInfoOnComponents(compInfo); + return ; } - return newArr; + 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) + { + 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. + * 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); } /*! @@ -4462,6 +4621,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 @@ -4470,14 +4631,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::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 "; @@ -4485,29 +4652,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(); + MEDCouplingAutoRefCountObjectPtr newArr(DataArrayDouble::New()); 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()); - } + INTERP_KERNEL::AutoPtr 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(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } } - return newArr; + return newArr.retn(); } void DataArrayDouble::applyFuncFast32(const std::string& func) @@ -5958,7 +6145,7 @@ void DataArrayInt::pushBackSilent(int val) * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session. * - * \param [in] valsBg - an array of values to push at the end of \this. + * \param [in] valsBg - an array of values to push at the end of \c this. * \param [in] valsEnd - specifies the end of the array \a valsBg, so that * the last value of \a valsBg is \a valsEnd[ -1 ]. * \throw If \a this has already been allocated with number of components different from one. @@ -6083,7 +6270,9 @@ void DataArrayInt::iota(int init) /*! * Returns a textual and human readable representation of \a this instance of * DataArrayInt. This text is shown when a DataArrayInt is printed in Python. - * \return std::string - text describing \a this DataArrayInt. + * \return std::string - text describing \a this DataArrayInt. + * + * \sa reprNotTooLong, reprZip */ std::string DataArrayInt::repr() const { @@ -6099,6 +6288,18 @@ std::string DataArrayInt::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 DataArrayInt::reprNotTooLong() const +{ + std::ostringstream ret; + reprNotTooLongStream(ret); + return ret.str(); +} + void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const { static const char SPACE[4]={' ',' ',' ',' '}; @@ -6152,6 +6353,12 @@ void DataArrayInt::reprZipStream(std::ostream& stream) const reprZipWithoutNameStream(stream); } +void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const +{ + stream << "Name of int array : \"" << _name << "\"\n"; + reprNotTooLongWithoutNameStream(stream); +} + void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const { DataArray::reprWithoutNameStream(stream); @@ -6164,6 +6371,13 @@ void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const _mem.reprZip(getNumberOfComponents(),stream); } +void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const +{ + DataArray::reprWithoutNameStream(stream); + stream.precision(17); + _mem.reprNotTooLong(getNumberOfComponents(),stream); +} + void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const { int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents(); @@ -6240,7 +6454,7 @@ void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNb } /*! - * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ], + * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ], * i.e. a current value is used as in index to get a new value from \a indArrBg. * \param [in] indArrBg - pointer to the first element of array of new values to assign * to \a this array. @@ -6249,15 +6463,15 @@ void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNb * \throw If \a this->getNumberOfComponents() != 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& 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;igetNumberOfTuples() * giving a new position for i-th old value. */ @@ -6935,8 +7244,8 @@ void DataArrayInt::renumberInPlace(const int *old2New) /*! * 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. + * the same as in \c this one. + * For more info on renumbering see \ref numbering. * \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 @@ -6968,9 +7277,9 @@ void DataArrayInt::renumberInPlaceR(const int *new2Old) /*! * 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. + * Number of tuples in the result array remains the same as in \c this one. * If a permutation reduction is needed, renumberAndReduce() should be used. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * For more info on renumbering see \ref numbering. * \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 @@ -6996,9 +7305,9 @@ DataArrayInt *DataArrayInt::renumber(const int *old2New) const /*! * 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. + * tuples in the result array remains the same as in \c this one. * If a permutation reduction is needed, substr() or selectByTupleId() should be used. - * For more info on renumbering see \ref MEDCouplingArrayRenumbering. + * For more info on renumbering see \ref numbering. * \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 @@ -7026,7 +7335,7 @@ DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const * 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. + * For more info on renumbering see \ref numbering. * \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. @@ -7059,7 +7368,7 @@ DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTup * 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. + * For more info on renumbering see \ref numbering. * \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 @@ -7093,7 +7402,7 @@ DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new * \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. + * For more info on renumbering see \ref numbering. * \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 @@ -7130,7 +7439,7 @@ DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int * 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. + * For more info on renumbering see \ref numbering. * \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. @@ -7156,7 +7465,7 @@ DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const /*! * 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. + * For more info on renumbering see \ref numbering. * \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 @@ -7224,7 +7533,7 @@ DataArray *DataArrayInt::selectByTupleRanges(const std::vectorrenumber(\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. + * 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. @@ -7292,7 +7601,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 @@ -7359,7 +7668,7 @@ void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, Data * from a zip representation of a surjective format (returned e.g. by * \ref ParaMEDMEM::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] @@ -7420,7 +7729,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] @@ -7475,17 +7784,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. @@ -7686,7 +8017,7 @@ void DataArrayInt::reAlloc(int nbOfTuples) * \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()); @@ -7874,7 +8205,7 @@ void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int end * \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. + * for \c this array. * * \if ENABLE_EXAMPLES * \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example". @@ -8066,7 +8397,7 @@ void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int * 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. + * for \c this array. * * \if ENABLE_EXAMPLES * \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example". @@ -8140,7 +8471,7 @@ void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, * \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. + * for \c this array. * * \if ENABLE_EXAMPLES * \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example". @@ -8484,7 +8815,7 @@ 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. @@ -9091,6 +9422,32 @@ 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. * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs @@ -9264,7 +9621,7 @@ 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::getIdsNotInRange , DataArrayInt::getIdsStrictlyNegative */ DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const { @@ -9289,7 +9646,7 @@ DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const * \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 + * \sa DataArrayInt::getIdsInRange , DataArrayInt::getIdsStrictlyNegative */ DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const { @@ -9305,6 +9662,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::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. @@ -9823,7 +10200,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++) { @@ -9880,6 +10258,7 @@ 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 { @@ -9896,6 +10275,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 @@ -9995,8 +10406,6 @@ void DataArrayInt::computeOffsets2() throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : 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;igetIJ(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.