X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingMemArray.cxx;h=d6d65c9e8bc3010ac364484c5b861246b69a7fe7;hb=c5873d1cac2ac6b6becd4d64a76049adc5a44595;hp=0d5d059a04685eb0884cd269f8348c7107558110;hpb=b4b11b30ec3c8c59b9124a2c4efbd4b99039556f;p=tools%2Fmedcoupling.git diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 0d5d059a0..d6d65c9e8 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-2014 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(); } @@ -422,6 +422,18 @@ std::string DataArray::GetUnitFromInfo(const std::string& info) return info.substr(p1+1,p2-p1-1); } +/*! + * This method put in info format the result of the merge of \a var and \a unit. + * The standard format for that is "var [unit]". + * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo. + */ +std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit) +{ + std::ostringstream oss; + oss << var << " [" << unit << "]"; + return oss.str(); +} + /*! * Returns a new DataArray by concatenating all given arrays, so that (1) the number * of tuples in the result array is a sum of the number of tuples of given arrays and (2) @@ -545,7 +557,7 @@ void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) co void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const { - if(getNumberOfTuples()!=other.getNumberOfTuples()) + if(getNumberOfTuples()!=other.getNumberOfTuples()) { std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); @@ -1846,9 +1858,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()); @@ -1879,9 +1893,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) { @@ -1961,9 +1977,11 @@ bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, * \throw If \a this is not allocated. * \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 @@ -1972,12 +1990,12 @@ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayI int nbOfCompo=getNumberOfComponents(); if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4."); - + int nbOfTuples=getNumberOfTuples(); // MEDCouplingAutoRefCountObjectPtr c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0); switch(nbOfCompo) - { + { case 4: findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI); break; @@ -1992,7 +2010,7 @@ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayI break; default: throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !"); - } + } comm=c.retn(); commIndex=cI.retn(); } @@ -2080,7 +2098,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])); @@ -2108,7 +2126,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(); } @@ -2145,7 +2163,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); @@ -2169,8 +2187,8 @@ DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble } default: throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !"); - } - + } + return ret.retn(); } @@ -2190,7 +2208,9 @@ DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble * \throw If \a this is not allocated. * \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 { @@ -2214,7 +2234,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) { @@ -2264,7 +2286,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) { @@ -2327,7 +2351,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) { @@ -2381,7 +2407,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) { @@ -2452,7 +2480,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) { @@ -2512,7 +2542,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) { @@ -2584,7 +2616,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) { @@ -3084,7 +3118,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); @@ -3105,7 +3139,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(); } @@ -3615,7 +3649,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 !"); - } + } } /*! @@ -3713,7 +3747,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(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 @@ -4276,144 +4316,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) + { + 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()) + { + expr.prepareFastEvaluator(); + newArr->rearrange(1); + newArr->fillWithValue(expr.evaluateDouble()); + newArr->rearrange(nbOfComp); + return newArr.retn(); + } + std::vector vars2(vars.begin(),vars.end()); + double buff,*ptrToFill(newArr->getPointer()); + const double *ptr(begin()); + std::vector stck; + expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1); + expr.prepareFastEvaluator(); + if(!isSafe) { - try + for(int i=0;i(oss,", ")); - oss << ") : Evaluation of function failed ! " << e.what(); - newArr->decrRef(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); + for(int iComp=0;iCompgetInfoOnComponent(). - * \throw If computing \a func fails. + * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception. + * If false the computation is carried on without any notification. When false the evaluation is a little faster. + * + * \sa applyFunc */ -DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const std::string& func) const +void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe) { + int nbOfComp(getNumberOfComponents()); + if(nbOfComp<=0) + throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !"); checkAllocated(); + int nbOfTuples(getNumberOfTuples()); INTERP_KERNEL::ExprParser expr(func); expr.parse(); std::set vars; expr.getTrueSetOfVars(vars); - int oldNbOfComp=getNumberOfComponents(); - if((int)vars.size()>oldNbOfComp) + if((int)vars.size()>1) { - std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are "; - oss << vars.size() << " variables : "; + std::ostringstream oss; oss << "DataArrayDouble::applyFuncOnThis : this method works only with at most one var func expression ! If you need to map comps on variables please use 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); } /*! @@ -4424,6 +4530,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 @@ -4432,14 +4540,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 "; @@ -4447,29 +4561,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 buff(new double[oldNbOfComp]); + double *buffPtr(buff),*ptrToFill; + std::vector stck; + for(int iComp=0;iCompgetPointer()+iComp; + if(!isSafe) + { + for(int i=0;i(oss,", ")); - oss << ") : Evaluation of function failed !" << e.what(); - newArr->decrRef(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); + for(int i=0;i(oss,", ")); + oss << ") : Evaluation of function failed !" << e.what(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } } } - return newArr; + return newArr.retn(); } void DataArrayDouble::applyFuncFast32(const std::string& func) @@ -4525,8 +4659,10 @@ DataArrayDoubleIterator *DataArrayDouble::iterator() * * \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 { @@ -5544,6 +5680,37 @@ void DataArrayDouble::powEqual(const DataArrayDouble *other) 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 * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example". + * \endif */ DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const { @@ -6418,9 +6587,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 { @@ -6435,7 +6606,7 @@ DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const { int v(new2Old[i]); if(v>=0 && vgetNumberOfTuples() != \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 { @@ -7605,9 +7778,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()); @@ -7634,9 +7809,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) { @@ -7677,7 +7854,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) { @@ -7728,7 +7907,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) { @@ -7791,7 +7972,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) { @@ -7846,7 +8029,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) { @@ -7917,7 +8102,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) { @@ -7977,7 +8164,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) { @@ -8049,7 +8238,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) { @@ -8389,7 +8580,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. @@ -9564,12 +9755,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); @@ -9658,7 +9919,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++) { @@ -9720,7 +9982,7 @@ 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(); @@ -9757,7 +10019,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' !"); @@ -9790,7 +10052,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 ; @@ -9924,10 +10186,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; @@ -10859,7 +11121,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();