-// 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
return sz1+sz2+sz3;
}
-std::vector<const BigMemoryObject *> DataArray::getDirectChildren() const
+std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
{
return std::vector<const BigMemoryObject *>();
}
* 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;
}
throw INTERP_KERNEL::Exception(oss.str().c_str());
}
for(std::size_t i=0;i<newNbOfCompo;i++)
- setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]).c_str());
+ setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
}
void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
throw INTERP_KERNEL::Exception(oss.str().c_str());
}
for(std::size_t i=0;i<partOfCompoToSet;i++)
- setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i).c_str());
+ setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
}
bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
stream << "\n";
}
-std::string DataArray::cppRepr(const char *varName) const
+std::string DataArray::cppRepr(const std::string& varName) const
{
std::ostringstream ret;
reprCppStream(varName,ret);
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)
* \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;
_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)
{
}
}
-void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const
+void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
{
if(getNumberOfComponents()!=nbOfCompo)
{
}
}
-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)
{
}
}
-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());
}
}
-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);
/*!
* 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)
{
* 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)
{
}
}
-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)
{
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<begin)
{
return (end-1-begin)/step+1;
}
-int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg)
+int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
{
if(step==0)
throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
* 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.
/*!
* 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
{
return ret.str();
}
-void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char *nameInFile, DataArrayByte *byteArr) const
+/*!
+ * 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]={' ',' ',' ',' '};
checkAllocated();
std::string idt(indent,' ');
ofs.precision(17);
ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
+ //
+ bool areAllEmpty(true);
+ for(std::vector<std::string>::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() << "\">";
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);
_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();
{
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);
/*!
* 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.
*/
/*!
* 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
/*!
* 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
/*!
* 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
* 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.
* 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
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
* \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
* 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.
/*!
* 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
for(;j<newNbOfComp;j++)
nc[newNbOfComp*i+j]=dftValue;
}
- ret->setName(getName().c_str());
+ ret->setName(getName());
for(int i=0;i<dim;i++)
- ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
- ret->setName(getName().c_str());
+ ret->setInfoOnComponent(i,getInfoOnComponent(i));
+ ret->setName(getName());
return ret.retn();
}
* \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<int>& compoIds) const
+DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
{
checkAllocated();
MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
* \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)
{
* [ \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<DataArrayInt> 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;
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();
}
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]));
}
default:
throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
- }
+ }
return ret.retn();
}
const double *thisBBPtr(begin());
int *retPtr(ret->getPointer());
switch(nbOfComp/2)
- {
+ {
case 3:
{
BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
}
default:
throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
- }
-
+ }
+
return ret.retn();
}
* \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
{
* \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<int>& compoIds)
{
* \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)
{
* \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".
+ * \endif
*/
void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
{
* \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
* <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
*
+ * \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)
{
* \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> 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)
{
* defined by <em>(bgComp,endComp,stepComp)</em>.
* \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".
+ * \endif
*/
void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
{
* \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".
+ * \endif
*/
void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
{
int nbOfTuplesOther=other->getNumberOfTuples();
MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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);
}
default:
throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
- }
+ }
c=cArr.retn(); cI=cIArr.retn();
}
/*!
* 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;i<nbOfElems;i++,pt++)
{
- double val=std::abs(*pt);
+ double val(std::abs(*pt));
if(val>ret)
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<double>::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<double>::max());
+ std::size_t nbOfElems(getNbOfElems());
+ const double *pt(getConstPointer());
+ for(std::size_t i=0;i<nbOfElems;i++,pt++)
+ {
+ double val(std::abs(*pt));
+ if(val<ret)
+ ret=val;
+ }
+ return ret;
+}
+
/*!
* Accumulates values of each component of \a this array.
* \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
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;i<nbOfTuple;i++,w+=2,wIn+=2)
{
w[0]=wIn[0]*cos(wIn[1]);
DataArrayDouble *DataArrayDouble::fromCylToCart() const
{
checkAllocated();
- int nbOfComp=getNumberOfComponents();
+ int nbOfComp(getNumberOfComponents());
if(nbOfComp!=3)
throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
- int nbOfTuple=getNumberOfTuples();
- DataArrayDouble *ret=DataArrayDouble::New();
+ int nbOfTuple(getNumberOfTuples());
+ DataArrayDouble *ret(DataArrayDouble::New());
ret->alloc(getNumberOfTuples(),3);
- double *w=ret->getPointer();
- const double *wIn=getConstPointer();
+ double *w(ret->getPointer());
+ const double *wIn(getConstPointer());
for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
{
w[0]=wIn[0]*cos(wIn[1]);
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;
}
DataArrayDouble *DataArrayDouble::fromSpherToCart() const
{
checkAllocated();
- int nbOfComp=getNumberOfComponents();
+ int nbOfComp(getNumberOfComponents());
if(nbOfComp!=3)
throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
- int nbOfTuple=getNumberOfTuples();
- DataArrayDouble *ret=DataArrayDouble::New();
+ int nbOfTuple(getNumberOfTuples());
+ DataArrayDouble *ret(DataArrayDouble::New());
ret->alloc(getNumberOfTuples(),3);
- double *w=ret->getPointer();
- const double *wIn=getConstPointer();
+ double *w(ret->getPointer());
+ const double *wIn(getConstPointer());
for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
{
w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
return ret;
}
+/*!
+ * This method returns a new array containing the same number of tuples than \a this. To do this, this method needs \a at parameter to specify the convention of \a this.
+ * All the tuples of the returned array will be in cartesian sense. So if \a at equals to AX_CART the returned array is basically a deep copy of \a this.
+ * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
+ *
+ * \param [in] atOfThis - The axis type of \a this.
+ * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
+ */
+DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
+{
+ checkAllocated();
+ int nbOfComp(getNumberOfComponents());
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> 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.
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();
const double *src=getConstPointer();
double *dest=ret->getPointer();
switch(getNumberOfComponents())
- {
+ {
case 6:
for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
*dest=src[0]*src[1]*src[2]+2.*src[4]*src[5]*src[3]-src[0]*src[4]*src[4]-src[2]*src[3]*src[3]-src[1]*src[5]*src[5];
default:
ret->decrRef();
throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
- }
+ }
}
/*!
ret->alloc(nbOfTuple,nbOfComp);
const double *src=getConstPointer();
double *dest=ret->getPointer();
-if(nbOfComp==6)
+ if(nbOfComp==6)
for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
{
double det=src[0]*src[1]*src[2]+2.*src[4]*src[5]*src[3]-src[0]*src[4]*src[4]-src[2]*src[3]*src[3]-src[1]*src[5]*src[5];
return ret;
}
+/*!
+ * Computes for each tuple the sum of number of components values in the tuple and return it.
+ *
+ * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
+ * same number of tuples as \a this array and one component.
+ * The caller is to delete this result array using decrRef() as it is no more
+ * needed.
+ * \throw If \a this is not allocated.
+ */
+DataArrayDouble *DataArrayDouble::sumPerTuple() const
+{
+ checkAllocated();
+ int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
+ ret->alloc(nbOfTuple,1);
+ const double *src(getConstPointer());
+ double *dest(ret->getPointer());
+ for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
+ *dest=std::accumulate(src,src+nbOfComp,0.);
+ return ret.retn();
+}
+
/*!
* Computes the maximal value within every tuple of \a this array.
* \return DataArrayDouble * - the new instance of DataArrayDouble containing the
/*!
* 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 DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
+ * should be called instead.
+ *
+ * \throw If \a this is not allocated.
+ * \sa DataArrayDouble::computeAbs
*/
void DataArrayDouble::abs()
{
checkAllocated();
- double *ptr=getPointer();
- std::size_t nbOfElems=getNbOfElems();
+ double *ptr(getPointer());
+ std::size_t nbOfElems(getNbOfElems());
std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(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<double,double>(fabs));
+ newArr->copyStringInfoFrom(*this);
+ return newArr;
+}
+
+/*!
+ * Apply a linear function to a given component of \a this array, so that
* an array element <em>(x)</em> 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<nbOfTuple;i++,ptr+=nbOfComp)
*ptr=a*(*ptr)+b;
declareAsNew();
}
/*!
- * Apply a liner function to all elements of \a this array, so that
+ * Apply a linear function to all elements of \a this array, so that
* an 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] 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
* \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<std::string> 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<std::string>(oss," "));
- throw INTERP_KERNEL::Exception(oss.str().c_str());
- }
std::vector<std::string> 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<nbOfTuples;i++)
- {
- try
- {
- expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
- }
- catch(INTERP_KERNEL::Exception& e)
- {
- std::ostringstream oss; oss << "For tuple # " << i << " with value (";
- std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(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<DataArrayDouble> 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<nbOfTuples;i++)
+ std::set<std::string> vars;
+ expr.getTrueSetOfVars(vars);
+ if((int)vars.size()>1)
{
- try
+ 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<std::string>(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<std::string> vars2(vars.begin(),vars.end());
+ double buff,*ptrToFill(newArr->getPointer());
+ const double *ptr(begin());
+ std::vector<double> stck;
+ expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
+ expr.prepareFastEvaluator();
+ if(!isSafe)
+ {
+ for(int i=0;i<nbOfTuples;i++)
{
- expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
+ for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
+ {
+ buff=*ptr;
+ expr.evaluateDoubleInternal(stck);
+ *ptrToFill=stck.back();
+ stck.pop_back();
+ }
}
- catch(INTERP_KERNEL::Exception& e)
+ }
+ else
+ {
+ for(int i=0;i<nbOfTuples;i++)
{
- std::ostringstream oss; oss << "For tuple # " << i << " with value (";
- std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
- oss << ") : Evaluation of function failed ! " << e.what();
- newArr->decrRef();
- throw INTERP_KERNEL::Exception(oss.str().c_str());
+ for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
+ {
+ buff=*ptr;
+ try
+ {
+ expr.evaluateDoubleInternalSafe(stck);
+ }
+ catch(INTERP_KERNEL::Exception& e)
+ {
+ std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
+ oss << buff;
+ oss << ") : Evaluation of function failed !" << e.what();
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ *ptrToFill=stck.back();
+ stck.pop_back();
+ }
}
}
- return newArr;
+ return newArr.retn();
}
/*!
- * 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.
- * For more info see \ref MEDCouplingArrayApplyFunc2.
- * \param [in] nbOfComp - number of components in the result array.
+ * This method is a non const method that modify the array in \a this.
+ * This method only works on one component array. It means that function \a func must
+ * contain at most one variable.
+ * This method is a specialization of applyFunc method with one parameter on one component array.
+ *
* \param [in] func - the expression defining how to transform a tuple of \a this array.
* Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
- * \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.
+ * \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<std::string> 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<std::string>(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<nbOfTuples;i++)
+ if(vars.empty())
+ {
+ expr.prepareFastEvaluator();
+ std::vector<std::string> compInfo(getInfoOnComponents());
+ rearrange(1);
+ fillWithValue(expr.evaluateDouble());
+ rearrange(nbOfComp);
+ setInfoOnComponents(compInfo);
+ return ;
+ }
+ std::vector<std::string> vars2(vars.begin(),vars.end());
+ double buff,*ptrToFill(getPointer());
+ const double *ptr(begin());
+ std::vector<double> stck;
+ expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
+ expr.prepareFastEvaluator();
+ if(!isSafe)
{
- try
+ for(int i=0;i<nbOfTuples;i++)
{
- expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
+ for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
+ {
+ buff=*ptr;
+ expr.evaluateDoubleInternal(stck);
+ *ptrToFill=stck.back();
+ stck.pop_back();
+ }
}
- catch(INTERP_KERNEL::Exception& e)
+ }
+ else
+ {
+ for(int i=0;i<nbOfTuples;i++)
{
- std::ostringstream oss; oss << "For tuple # " << i << " with value (";
- std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
- oss << ") : Evaluation of function failed !" << e.what();
- newArr->decrRef();
- throw INTERP_KERNEL::Exception(oss.str().c_str());
+ for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
+ {
+ buff=*ptr;
+ try
+ {
+ expr.evaluateDoubleInternalSafe(stck);
+ }
+ catch(INTERP_KERNEL::Exception& e)
+ {
+ std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
+ oss << buff;
+ oss << ") : Evaluation of function failed !" << e.what();
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ *ptrToFill=stck.back();
+ stck.pop_back();
+ }
}
}
- return newArr;
+}
+
+/*!
+ * 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.
+ * For more info see \ref MEDCouplingArrayApplyFunc2.
+ * \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.
+ * 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);
}
/*!
* \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
* \throw If \a func contains vars not in \a varsOrder.
* \throw If computing \a func fails.
*/
-DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const
+DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& 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<std::string> varsOrder2(varsOrder);
+ int oldNbOfComp(getNumberOfComponents());
+ for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
+ varsOrder2.push_back(std::string());
checkAllocated();
+ int nbOfTuples(getNumberOfTuples());
INTERP_KERNEL::ExprParser expr(func);
expr.parse();
std::set<std::string> vars;
expr.getTrueSetOfVars(vars);
- int oldNbOfComp=getNumberOfComponents();
if((int)vars.size()>oldNbOfComp)
{
std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
throw INTERP_KERNEL::Exception(oss.str().c_str());
}
- expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
- //
- DataArrayDouble *newArr=DataArrayDouble::New();
- int nbOfTuples=getNumberOfTuples();
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newArr(DataArrayDouble::New());
newArr->alloc(nbOfTuples,nbOfComp);
- const double *ptr=getConstPointer();
- double *ptrToFill=newArr->getPointer();
- for(int i=0;i<nbOfTuples;i++)
- {
- try
- {
- expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
+ INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
+ double *buffPtr(buff),*ptrToFill;
+ std::vector<double> stck;
+ for(int iComp=0;iComp<nbOfComp;iComp++)
+ {
+ expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
+ expr.prepareFastEvaluator();
+ const double *ptr(getConstPointer());
+ ptrToFill=newArr->getPointer()+iComp;
+ if(!isSafe)
+ {
+ for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
+ {
+ std::copy(ptr,ptr+oldNbOfComp,buffPtr);
+ expr.evaluateDoubleInternal(stck);
+ *ptrToFill=stck.back();
+ stck.pop_back();
+ }
}
- catch(INTERP_KERNEL::Exception& e)
+ else
{
- std::ostringstream oss; oss << "For tuple # " << i << " with value (";
- std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
- oss << ") : Evaluation of function failed !" << e.what();
- newArr->decrRef();
- throw INTERP_KERNEL::Exception(oss.str().c_str());
+ for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
+ {
+ std::copy(ptr,ptr+oldNbOfComp,buffPtr);
+ try
+ {
+ expr.evaluateDoubleInternalSafe(stck);
+ *ptrToFill=stck.back();
+ stck.pop_back();
+ }
+ catch(INTERP_KERNEL::Exception& e)
+ {
+ std::ostringstream oss; oss << "For tuple # " << i << " with value (";
+ std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(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);
declareAsNew();
}
-void DataArrayDouble::applyFuncFast64(const char *func)
+void DataArrayDouble::applyFuncFast64(const std::string& func)
{
checkAllocated();
INTERP_KERNEL::ExprParser expr(func);
* needed.
* \throw If \a this->getNumberOfComponents() != 1.
*
+ * \sa DataArrayDouble::getIdsNotInRange
+ *
+ * \if ENABLE_EXAMPLES
* \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
* \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<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
- int nbOfTuples=getNumberOfTuples();
+ const double *cptr(begin());
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
+ int nbOfTuples(getNumberOfTuples());
for(int i=0;i<nbOfTuples;i++,cptr++)
if(*cptr>=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<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
+ int nbOfTuples(getNumberOfTuples());
+ for(int i=0;i<nbOfTuples;i++,cptr++)
+ if(*cptr<vmin || *cptr>vmax)
+ 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)
* 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
int k=0;
for(int i=0;i<(int)a.size();i++)
for(int j=0;j<nbc[i];j++,k++)
- ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
+ ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
return ret;
}
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;
}
throw INTERP_KERNEL::Exception(oss.str().c_str());
}
}
- declareAsNew();
+ 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<bool> 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<bool> ret(nbt);
+ const double *pt(begin());
+ for(int i=0;i<nbt;i++)
+ {
+ if(fabs(pt[i])<eps)
+ ret[i]=false;
+ else if(fabs(pt[i]-1.)<eps)
+ ret[i]=true;
+ else
+ {
+ std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ }
+ return ret;
}
/*!
*/
void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
{
- setName(tinyInfoS[0].c_str());
+ setName(tinyInfoS[0]);
if(isAllocated())
{
int nbOfCompo=getNumberOfComponents();
for(int i=0;i<nbOfCompo;i++)
- setInfoOnComponent(i,tinyInfoS[i+1].c_str());
+ setInfoOnComponent(i,tinyInfoS[i+1]);
}
}
* 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.
/*!
* 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
{
return ret.str();
}
-void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile, DataArrayByte *byteArr) const
+/*!
+ * 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]={' ',' ',' ',' '};
checkAllocated();
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);
_mem.reprZip(getNumberOfComponents(),stream);
}
-void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const
+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();
const int *data=getConstPointer();
}
/*!
- * 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.
* \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<nbOfTuples;i++,pt++)
{
if(*pt>=0 && *pt<nbElemsIn)
declareAsNew();
}
+/*!
+ * Modifies in place \a this one-dimensional array like this : each id in \a this so that this[id] equal to \a valToBeReplaced will be replaced at the same place by \a replacedBy.
+ *
+ * \param [in] valToBeReplaced - the value in \a this to be replaced.
+ * \param [in] replacedBy - the value taken by each tuple previously equal to \a valToBeReplaced.
+ *
+ * \sa DataArrayInt::transformWithIndArr
+ */
+void DataArrayInt::replaceOneValByInThis(int valToBeReplaced, int replacedBy)
+{
+ checkAllocated();
+ if(getNumberOfComponents()!=1)
+ throw INTERP_KERNEL::Exception("Call replaceOneValByInThis method on DataArrayInt with only one component, you can call 'rearrange' method before !");
+ if(valToBeReplaced==replacedBy)
+ return ;
+ int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
+ for(int i=0;i<nbOfTuples;i++,pt++)
+ {
+ if(*pt==valToBeReplaced)
+ *pt=replacedBy;
+ }
+}
+
/*!
* Computes distribution of values of \a this one-dimensional array between given value
* ranges (casts). This method is typically useful for entity number spliting by types,
* \throw If any value of \a this is not less than \a arrEnd[-1].
*/
void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
- DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
+ DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
{
checkAllocated();
if(getNumberOfComponents()!=1)
castsPresent=ret3.retn();
}
+/*!
+ * This method look at \a this if it can be considered as a range defined by the 3-tuple ( \a strt , \a sttoopp , \a stteepp ).
+ * If false is returned the tuple must be ignored. If true is returned \a this can be considered by a range( \a strt , \a sttoopp , \a stteepp ).
+ * This method works only if \a this is allocated and single component. If not an exception will be thrown.
+ *
+ * \param [out] strt - the start of the range (included) if true is returned.
+ * \param [out] sttoopp - the end of the range (not included) if true is returned.
+ * \param [out] stteepp - the step of the range if true is returned.
+ * \return the verdict of the check.
+ *
+ * \sa DataArray::GetNumberOfItemGivenBES
+ */
+bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
+{
+ checkAllocated();
+ if(getNumberOfComponents()!=1)
+ throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
+ int nbTuples(getNumberOfTuples());
+ if(nbTuples==0)
+ { strt=0; sttoopp=0; stteepp=1; return true; }
+ const int *pt(begin());
+ strt=*pt;
+ if(nbTuples==1)
+ { sttoopp=strt+1; stteepp=1; return true; }
+ strt=*pt; sttoopp=pt[nbTuples-1];
+ if(strt==sttoopp)
+ return false;
+ if(sttoopp>strt)
+ {
+ sttoopp++;
+ int a(sttoopp-1-strt),tmp(strt);
+ if(a%(nbTuples-1)!=0)
+ return false;
+ stteepp=a/(nbTuples-1);
+ for(int i=0;i<nbTuples;i++,tmp+=stteepp)
+ if(pt[i]!=tmp)
+ return false;
+ return true;
+ }
+ else
+ {
+ sttoopp--;
+ int a(strt-sttoopp-1),tmp(strt);
+ if(a%(nbTuples-1)!=0)
+ return false;
+ stteepp=-(a/(nbTuples-1));
+ for(int i=0;i<nbTuples;i++,tmp+=stteepp)
+ if(pt[i]!=tmp)
+ return false;
+ return true;
+ }
+}
+
/*!
* Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from
* values of \a this (\a a) and the given (\a indArr) arrays as follows:
* Creates a one-dimensional DataArrayInt of given length, whose contents are computed
* from values of \a this array, which is supposed to contain a renumbering map in
* "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
- * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
+ * To know how to use the renumbering maps see \ref numbering.
* \param [in] newNbOfElem - the number of tuples in the result array.
* \return DataArrayInt * - the new instance of DataArrayInt.
* The caller is to delete this result array using decrRef() as it is no more
* needed.
*
+ * \if ENABLE_EXAMPLES
* \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
* \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
+ * \endif
*/
DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
{
* Creates a one-dimensional DataArrayInt of given length, whose contents are computed
* from values of \a this array, which is supposed to contain a renumbering map in
* "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
- * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
+ * To know how to use the renumbering maps see \ref numbering.
* \param [in] newNbOfElem - the number of tuples in the result array.
* \return DataArrayInt * - the new instance of DataArrayInt.
* The caller is to delete this result array using decrRef() as it is no more
* 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
{
{
int v(new2Old[i]);
if(v>=0 && v<oldNbOfElem)
- pt[v]=i;
+ pt[v]=i;
else
{
std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
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<int>::max();
int i=0;
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<bool>& 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<nbOfTuples;i++)
+ if(pt[i]==val)
+ vec[i]=true;
+}
+
/*!
* Sorts values of the array.
* \param [in] asc - \a true means ascending order, \a false, descending.
declareAsNew();
}
+/*!
+ * Computes for each tuple the sum of number of components values in the tuple and return it.
+ *
+ * \return DataArrayInt * - the new instance of DataArrayInt containing the
+ * same number of tuples as \a this array and one component.
+ * The caller is to delete this result array using decrRef() as it is no more
+ * needed.
+ * \throw If \a this is not allocated.
+ */
+DataArrayInt *DataArrayInt::sumPerTuple() const
+{
+ checkAllocated();
+ int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
+ ret->alloc(nbOfTuple,1);
+ const int *src(getConstPointer());
+ int *dest(ret->getPointer());
+ for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
+ *dest=std::accumulate(src,src+nbOfComp,0);
+ return ret.retn();
+}
+
/*!
* Reverse the array values.
* \throw If \a this->getNumberOfComponents() < 1.
* \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
{
/*!
* 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.
*/
/*!
* 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
/*!
* 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
/*!
* 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
* 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.
* 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
* \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
* 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.
/*!
* 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
* are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
* \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
* This method is useful for renumbering (in MED file for example). For more info
- * on renumbering see \ref MEDCouplingArrayRenumbering.
+ * 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.
* 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. <br>
* For more info on
- * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
+ * mapping and its usage in renumbering see \ref numbering. <br>
* \b Example:
* - \a this: [0,3,2,3,2,2,1,2]
* - \a targetNb: 4
* 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. <br>
- * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
+ * For more info on renumbering see \ref numbering. <br>
* \b Example: <br>
* - \a nbOfOldTuples: 10
* - \a arr : [0,3, 5,7,9]
/*!
* 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. <br>
+ * For more info on renumbering see \ref numbering. <br>
* \b Example: <br>
* - \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]
/*!
* 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;i<nbOfTuples;i++,pt++)
if(*pt!=i)
return true;
}
+/*!
+ * This method is stronger than isIdentity method. This method checks than \a this can be considered as an identity function
+ * of a set having \a sizeExpected elements into itself.
+ *
+ * \param [in] sizeExpected - The number of elements
+ * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples()) 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.
for(;j<newNbOfComp;j++)
nc[newNbOfComp*i+j]=dftValue;
}
- ret->setName(getName().c_str());
+ ret->setName(getName());
for(int i=0;i<dim;i++)
- ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
- ret->setName(getName().c_str());
+ ret->setInfoOnComponent(i,getInfoOnComponent(i));
+ ret->setName(getName());
return ret.retn();
}
* \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<int>& compoIds) const
+DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
{
checkAllocated();
MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
* \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)
{
* \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<int>& compoIds)
{
* \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)
{
* \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".
+ * \endif
*/
void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
{
* \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
* <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
*
+ * \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)
{
* \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> 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)
{
* defined by <em>(bgComp,endComp,stepComp)</em>.
* \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".
+ * \endif
*/
void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
{
* \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".
+ * \endif
*/
void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
{
/*!
* 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<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
int nbOfTuples=getNumberOfTuples();
for(int i=0;i<nbOfTuples;i++,cptr++)
checkAllocated();
if(getNumberOfComponents()!=1)
throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
- const int *cptr=getConstPointer();
+ const int *cptr(getConstPointer());
MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
int nbOfTuples=getNumberOfTuples();
for(int i=0;i<nbOfTuples;i++,cptr++)
return ret.retn();
}
+/*!
+ * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
+ * This method is an extension of DataArrayInt::getIdsEqual method.
+ *
+ * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
+ * \param [in] tupleEnd - the end (excluded) of the input tuple 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() != 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<DataArrayInt> 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
* 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
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<int>::max(); maxValue=-std::numeric_limits<int>::max();
+ for(int i=0;i<nbTuples;i++,pt++)
+ {
+ if(*pt<minValue)
+ minValue=*pt;
+ if(*pt>maxValue)
+ 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<int,int>(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<int,int>(std::abs));
+ newArr->copyStringInfoFrom(*this);
+ return newArr;
+}
+
/*!
* Apply a liner function to a given component of \a this array, so that
* an array element <em>(x)</em> becomes \f$ a * x + b \f$.
* \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<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
- int nbOfTuples=getNumberOfTuples();
+ const int *cptr(begin());
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
+ int nbOfTuples(getNumberOfTuples());
for(int i=0;i<nbOfTuples;i++,cptr++)
if(*cptr>=vmin && *cptr<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 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<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
+ int nbOfTuples(getNumberOfTuples());
+ for(int i=0;i<nbOfTuples;i++,cptr++)
+ if(*cptr<vmin || *cptr>=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<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
+ int nbOfTuples(getNumberOfTuples());
+ for(int i=0;i<nbOfTuples;i++,cptr++)
+ if(*cptr<0)
+ ret->pushBackSilent(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();
int k=0;
for(int i=0;i<(int)a.size();i++)
for(int j=0;j<nbc[i];j++,k++)
- ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
+ ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
return ret;
}
else
r=s1;
}
- DataArrayInt *ret=DataArrayInt::New();
+ DataArrayInt *ret(DataArrayInt::New());
ret->alloc((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<bool>& v)
+{
+ int sz((int)std::count(v.begin(),v.end(),true));
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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<bool>& v)
+{
+ int sz((int)std::count(v.begin(),v.end(),false));
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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<int> >.
+ *
+ * \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<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
+{
+ int sz((int)v.size());
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
+ ret1->alloc(sz+1,1);
+ int *pt(ret1->getPointer()); *pt=0;
+ for(int i=0;i<sz;i++,pt++)
+ pt[1]=pt[0]+(int)v[i].size();
+ ret0->alloc(ret1->back(),1);
+ pt=ret0->getPointer();
+ for(int i=0;i<sz;i++)
+ pt=std::copy(v[i].begin(),v[i].end(),pt);
+ data=ret0.retn(); dataIndex=ret1.retn();
+}
+
/*!
* Returns a new DataArrayInt which contains a complement of elements of \a this
* one-dimensional array. I.e. the result array contains all elements from the range [0,
*/
DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
{
- checkAllocated();
- if(getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
- std::vector<bool> tmp(nbOfElement);
- const int *pt=getConstPointer();
- int nbOfTuples=getNumberOfTuples();
- for(const int *w=pt;w!=pt+nbOfTuples;w++)
- if(*w>=0 && *w<nbOfElement)
- tmp[*w]=true;
- else
- throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
- int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
- DataArrayInt *ret=DataArrayInt::New();
- ret->alloc(nbOfRetVal,1);
- int j=0;
- int *retPtr=ret->getPointer();
- for(int i=0;i<nbOfElement;i++)
- if(!tmp[i])
- retPtr[j++]=i;
- return ret;
+ checkAllocated();
+ if(getNumberOfComponents()!=1)
+ throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
+ std::vector<bool> tmp(nbOfElement);
+ const int *pt=getConstPointer();
+ int nbOfTuples=getNumberOfTuples();
+ for(const int *w=pt;w!=pt+nbOfTuples;w++)
+ if(*w>=0 && *w<nbOfElement)
+ tmp[*w]=true;
+ else
+ throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
+ int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
+ DataArrayInt *ret=DataArrayInt::New();
+ ret->alloc(nbOfRetVal,1);
+ int j=0;
+ int *retPtr=ret->getPointer();
+ for(int i=0;i<nbOfElement;i++)
+ if(!tmp[i])
+ retPtr[j++]=i;
+ return ret;
}
/*!
checkAllocated();
other->checkAllocated();
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<int> s1(pt,pt+nbOfTuples);
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<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
for(;work1!=pt1End;work1++)
{
*
* \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<DataArrayInt> tmp=deepCpy();
int *data=tmp->getPointer();
return ret.retn();
}
+/*!
+ * This method can be applied on allocated with one component DataArrayInt instance.
+ * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
+ *
+ * \return a newly allocated array that contain the result of the unique operation applied on \a this.
+ *
+ * \throw if \a this is not allocated or if \a this has not exactly one component.
+ *
+ * \sa DataArrayInt::buildUnique
+ */
+DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
+{
+ checkAllocated();
+ if(getNumberOfComponents()!=1)
+ throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
+ int minVal,maxVal;
+ getMinMaxValues(minVal,maxVal);
+ std::vector<bool> b(maxVal-minVal+1,false);
+ const int *ptBg(begin()),*endBg(end());
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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
{
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' !");
{
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 ;
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;i<nbOfTuples;i++)
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;
* \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: <br>
- * - \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] == <br>
*/
-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 !");
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<nbOfEltsInSlc;i++,pos+=step)
{
if(pos>=0 && pos<nbOfTuples-1)
return ret.retn();
}
+/*!
+ * \b WARNING this method is a \b non \a const \b method. This method works tuple by tuple. Each tuple is expected to be pairs (number of components must be equal to 2).
+ * This method rearrange each pair in \a this so that, tuple with id \b tid will be after the call \c this->getIJ(tid,0)==this->getIJ(tid-1,1) and \c this->getIJ(tid,1)==this->getIJ(tid+1,0).
+ * If it is impossible to reach such condition an exception will be thrown ! \b WARNING In case of throw \a this can be partially modified !
+ * If this method has correctly worked, \a this will be able to be considered as a linked list.
+ * This method does nothing if number of tuples is lower of equal to 1.
+ *
+ * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
+ *
+ * \sa MEDCouplingUMesh::orderConsecutiveCells1D
+ */
+void DataArrayInt::sortEachPairToMakeALinkedList()
+{
+ checkAllocated();
+ if(getNumberOfComponents()!=2)
+ throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
+ int nbOfTuples(getNumberOfTuples());
+ if(nbOfTuples<=1)
+ return ;
+ int *conn(getPointer());
+ for(int i=1;i<nbOfTuples;i++,conn+=2)
+ {
+ if(i>1)
+ {
+ 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<int> 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.
*/
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();
*/
void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
{
- setName(tinyInfoS[0].c_str());
+ setName(tinyInfoS[0]);
if(isAllocated())
{
int nbOfCompo=tinyInfoI[1];
for(int i=0;i<nbOfCompo;i++)
- setInfoOnComponent(i,tinyInfoS[i+1].c_str());
+ setInfoOnComponent(i,tinyInfoS[i+1]);
}
}