1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (EDF R&D)
21 #include "MEDCouplingMemArray.txx"
24 #include "GenMathFormulae.hxx"
25 #include "InterpKernelAutoPtr.hxx"
26 #include "InterpKernelExprParser.hxx"
28 #include "InterpKernelAutoPtr.hxx"
29 #include "InterpKernelGeo2DEdgeArcCircle.hxx"
30 #include "InterpKernelAutoPtr.hxx"
31 #include "InterpKernelGeo2DNode.hxx"
32 #include "InterpKernelGeo2DEdgeLin.hxx"
41 typedef double (*MYFUNCPTR)(double);
43 using namespace MEDCoupling;
45 template class MEDCoupling::MemArray<int>;
46 template class MEDCoupling::MemArray<double>;
47 template class MEDCoupling::DataArrayTemplate<int>;
48 template class MEDCoupling::DataArrayTemplate<double>;
49 template class MEDCoupling::DataArrayTemplateClassic<int>;
50 template class MEDCoupling::DataArrayTemplateClassic<double>;
51 template class MEDCoupling::DataArrayTemplateFP<double>;
52 template class MEDCoupling::DataArrayIterator<double>;
53 template class MEDCoupling::DataArrayIterator<int>;
54 template class MEDCoupling::DataArrayDiscrete<Int32>;
55 template class MEDCoupling::DataArrayDiscreteSigned<Int32>;
56 template class MEDCoupling::DataArrayDiscrete<Int64>;
57 template class MEDCoupling::DataArrayDiscreteSigned<Int64>;
58 template class MEDCoupling::DataArrayTuple<int>;
59 template class MEDCoupling::DataArrayTuple<double>;
60 template class MEDCoupling::DataArrayTuple<float>;
62 template<int SPACEDIM>
63 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
65 const double *coordsPtr=getConstPointer();
66 BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
67 std::vector<bool> isDone(nbNodes);
68 for(int i=0;i<nbNodes;i++)
72 std::vector<int> intersectingElems;
73 myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
74 if(intersectingElems.size()>1)
76 std::vector<int> commonNodes;
77 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
81 commonNodes.push_back(*it);
84 if(!commonNodes.empty())
86 cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
88 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
95 template<int SPACEDIM>
96 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
97 DataArrayInt *c, DataArrayInt *cI)
99 for(int i=0;i<nbOfTuples;i++)
101 std::vector<int> intersectingElems;
102 myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
103 std::vector<int> commonNodes;
104 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
105 commonNodes.push_back(*it);
106 cI->pushBackSilent(cI->back()+(int)commonNodes.size());
107 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
111 template<int SPACEDIM>
112 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
114 double distOpt(dist);
115 const double *p(pos);
117 for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
122 double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
123 if(ret!=std::numeric_limits<double>::max())
125 distOpt=std::max(ret,1e-4);
130 { distOpt=2*distOpt; continue; }
135 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
138 throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
141 return nbOfShift%nbOfTuples;
147 return nbOfTuples-tmp;
151 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
153 std::size_t sz1=_name.capacity();
154 std::size_t sz2=_info_on_compo.capacity();
156 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
157 sz3+=(*it).capacity();
161 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
163 return std::vector<const BigMemoryObject *>();
167 * Sets the attribute \a _name of \a this array.
168 * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
169 * \param [in] name - new array name
171 void DataArray::setName(const std::string& name)
177 * Copies textual data from an \a other DataArray. The copied data are
178 * - the name attribute,
179 * - the information of components.
181 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
183 * \param [in] other - another instance of DataArray to copy the textual data from.
184 * \throw If number of components of \a this array differs from that of the \a other.
186 void DataArray::copyStringInfoFrom(const DataArray& other)
188 if(_info_on_compo.size()!=other._info_on_compo.size())
189 throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
191 _info_on_compo=other._info_on_compo;
194 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
196 int nbOfCompoOth=other.getNumberOfComponents();
197 std::size_t newNbOfCompo=compoIds.size();
198 for(std::size_t i=0;i<newNbOfCompo;i++)
199 if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
201 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
202 throw INTERP_KERNEL::Exception(oss.str().c_str());
204 for(std::size_t i=0;i<newNbOfCompo;i++)
205 setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
208 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
210 std::size_t nbOfCompo(getNumberOfComponents());
211 std::size_t partOfCompoToSet=compoIds.size();
212 if(partOfCompoToSet!=other.getNumberOfComponents())
213 throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
214 for(std::size_t i=0;i<partOfCompoToSet;i++)
215 if(compoIds[i]>=(int)nbOfCompo || compoIds[i]<0)
217 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
218 throw INTERP_KERNEL::Exception(oss.str().c_str());
220 for(std::size_t i=0;i<partOfCompoToSet;i++)
221 setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
224 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
226 std::ostringstream oss;
227 if(_name!=other._name)
229 oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
233 if(_info_on_compo!=other._info_on_compo)
235 oss << "Components DataArray mismatch : \nThis components=";
236 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
237 oss << "\"" << *it << "\",";
238 oss << "\nOther components=";
239 for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
240 oss << "\"" << *it << "\",";
248 * Compares textual information of \a this DataArray with that of an \a other one.
249 * The compared data are
250 * - the name attribute,
251 * - the information of components.
253 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
254 * \param [in] other - another instance of DataArray to compare the textual data of.
255 * \return bool - \a true if the textual information is same, \a false else.
257 bool DataArray::areInfoEquals(const DataArray& other) const
260 return areInfoEqualsIfNotWhy(other,tmp);
263 void DataArray::reprWithoutNameStream(std::ostream& stream) const
265 stream << "Number of components : "<< getNumberOfComponents() << "\n";
266 stream << "Info of these components : ";
267 for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
268 stream << "\"" << *iter << "\" ";
272 std::string DataArray::cppRepr(const std::string& varName) const
274 std::ostringstream ret;
275 reprCppStream(varName,ret);
280 * Sets information on all components. To know more on format of this information
281 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
282 * \param [in] info - a vector of strings.
283 * \throw If size of \a info differs from the number of components of \a this.
285 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
287 if(getNumberOfComponents()!=info.size())
289 std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
290 throw INTERP_KERNEL::Exception(oss.str().c_str());
296 * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
297 * type of \a this and \a aBase.
299 * \throw If \a aBase and \a this do not have the same type.
301 * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
303 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
306 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
307 DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
308 DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
309 DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
310 const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
311 const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
312 const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
315 this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
320 this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
325 this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
328 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
331 std::vector<std::string> DataArray::getVarsOnComponent() const
333 int nbOfCompo=(int)_info_on_compo.size();
334 std::vector<std::string> ret(nbOfCompo);
335 for(int i=0;i<nbOfCompo;i++)
336 ret[i]=getVarOnComponent(i);
340 std::vector<std::string> DataArray::getUnitsOnComponent() const
342 int nbOfCompo=(int)_info_on_compo.size();
343 std::vector<std::string> ret(nbOfCompo);
344 for(int i=0;i<nbOfCompo;i++)
345 ret[i]=getUnitOnComponent(i);
350 * Returns information on a component specified by an index.
351 * To know more on format of this information
352 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
353 * \param [in] i - the index (zero based) of the component of interest.
354 * \return std::string - a string containing the information on \a i-th component.
355 * \throw If \a i is not a valid component index.
357 std::string DataArray::getInfoOnComponent(int i) const
359 if(i<(int)_info_on_compo.size() && i>=0)
360 return _info_on_compo[i];
363 std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
364 throw INTERP_KERNEL::Exception(oss.str().c_str());
369 * Returns the var part of the full information of the \a i-th component.
370 * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
371 * \c getVarOnComponent(0) returns "SIGXY".
372 * If a unit part of information is not detected by presence of
373 * two square brackets, then the full information is returned.
374 * To read more about the component information format, see
375 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
376 * \param [in] i - the index (zero based) of the component of interest.
377 * \return std::string - a string containing the var information, or the full info.
378 * \throw If \a i is not a valid component index.
380 std::string DataArray::getVarOnComponent(int i) const
382 if(i<(int)_info_on_compo.size() && i>=0)
384 return GetVarNameFromInfo(_info_on_compo[i]);
388 std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
389 throw INTERP_KERNEL::Exception(oss.str().c_str());
394 * Returns the unit part of the full information of the \a i-th component.
395 * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
396 * \c getUnitOnComponent(0) returns " N/m^2".
397 * If a unit part of information is not detected by presence of
398 * two square brackets, then an empty string is returned.
399 * To read more about the component information format, see
400 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
401 * \param [in] i - the index (zero based) of the component of interest.
402 * \return std::string - a string containing the unit information, if any, or "".
403 * \throw If \a i is not a valid component index.
405 std::string DataArray::getUnitOnComponent(int i) const
407 if(i<(int)_info_on_compo.size() && i>=0)
409 return GetUnitFromInfo(_info_on_compo[i]);
413 std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
414 throw INTERP_KERNEL::Exception(oss.str().c_str());
419 * Returns the var part of the full component information.
420 * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
421 * If a unit part of information is not detected by presence of
422 * two square brackets, then the whole \a info is returned.
423 * To read more about the component information format, see
424 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
425 * \param [in] info - the full component information.
426 * \return std::string - a string containing only var information, or the \a info.
428 std::string DataArray::GetVarNameFromInfo(const std::string& info)
430 std::size_t p1=info.find_last_of('[');
431 std::size_t p2=info.find_last_of(']');
432 if(p1==std::string::npos || p2==std::string::npos)
437 return std::string();
438 std::size_t p3=info.find_last_not_of(' ',p1-1);
439 return info.substr(0,p3+1);
443 * Returns the unit part of the full component information.
444 * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
445 * If a unit part of information is not detected by presence of
446 * two square brackets, then an empty string is returned.
447 * To read more about the component information format, see
448 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
449 * \param [in] info - the full component information.
450 * \return std::string - a string containing only unit information, if any, or "".
452 std::string DataArray::GetUnitFromInfo(const std::string& info)
454 std::size_t p1=info.find_last_of('[');
455 std::size_t p2=info.find_last_of(']');
456 if(p1==std::string::npos || p2==std::string::npos)
457 return std::string();
459 return std::string();
460 return info.substr(p1+1,p2-p1-1);
464 * This method put in info format the result of the merge of \a var and \a unit.
465 * The standard format for that is "var [unit]".
466 * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
468 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
470 std::ostringstream oss;
471 oss << var << " [" << unit << "]";
475 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
480 return std::string("AX_CART");
482 return std::string("AX_CYL");
484 return std::string("AX_SPHER");
486 throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
491 * Returns a new DataArray by concatenating all given arrays, so that (1) the number
492 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
493 * the number of component in the result array is same as that of each of given arrays.
494 * Info on components is copied from the first of the given arrays. Number of components
495 * in the given arrays must be the same.
496 * \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
497 * \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
498 * The caller is to delete this result array using decrRef() as it is no more
500 * \throw If all arrays within \a arrs are NULL.
501 * \throw If all not null arrays in \a arrs have not the same type.
502 * \throw If getNumberOfComponents() of arrays within \a arrs.
504 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
506 std::vector<const DataArray *> arr2;
507 for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
511 throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
512 std::vector<const DataArrayDouble *> arrd;
513 std::vector<const DataArrayInt *> arri;
514 std::vector<const DataArrayChar *> arrc;
515 for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
517 const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
519 { arrd.push_back(a); continue; }
520 const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
522 { arri.push_back(b); continue; }
523 const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
525 { arrc.push_back(c); continue; }
526 throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
528 if(arr2.size()==arrd.size())
529 return DataArrayDouble::Aggregate(arrd);
530 if(arr2.size()==arri.size())
531 return DataArrayInt::Aggregate(arri);
532 if(arr2.size()==arrc.size())
533 return DataArrayChar::Aggregate(arrc);
534 throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
538 * Sets information on a component specified by an index.
539 * To know more on format of this information
540 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
541 * \warning Don't pass NULL as \a info!
542 * \param [in] i - the index (zero based) of the component of interest.
543 * \param [in] info - the string containing the information.
544 * \throw If \a i is not a valid component index.
546 void DataArray::setInfoOnComponent(int i, const std::string& info)
548 if(i<(int)_info_on_compo.size() && i>=0)
549 _info_on_compo[i]=info;
552 std::ostringstream oss; oss << "DataArray::setInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
553 throw INTERP_KERNEL::Exception(oss.str().c_str());
558 * Sets information on all components. This method can change number of components
559 * at certain conditions; if the conditions are not respected, an exception is thrown.
560 * The number of components can be changed in \a this only if \a this is not allocated.
561 * The condition of number of components must not be changed.
563 * To know more on format of the component information see
564 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
565 * \param [in] info - a vector of component infos.
566 * \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
568 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
570 if(getNumberOfComponents()!=info.size())
576 std::ostringstream oss; oss << "DataArray::setInfoAndChangeNbOfCompo : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " and this is already allocated !";
577 throw INTERP_KERNEL::Exception(oss.str().c_str());
584 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
586 if((int)getNumberOfTuples()!=nbOfTuples)
588 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << nbOfTuples << " having " << getNumberOfTuples() << " !";
589 throw INTERP_KERNEL::Exception(oss.str().c_str());
593 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
595 if((int)getNumberOfComponents()!=nbOfCompo)
597 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
598 throw INTERP_KERNEL::Exception(oss.str().c_str());
602 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
604 if(getNbOfElems()!=nbOfElems)
606 std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
607 throw INTERP_KERNEL::Exception(oss.str().c_str());
611 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
613 if(getNumberOfTuples()!=other.getNumberOfTuples())
615 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
616 throw INTERP_KERNEL::Exception(oss.str().c_str());
618 if(getNumberOfComponents()!=other.getNumberOfComponents())
620 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
621 throw INTERP_KERNEL::Exception(oss.str().c_str());
625 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
627 checkNbOfTuples(nbOfTuples,msg);
628 checkNbOfComps(nbOfCompo,msg);
632 * Simply this method checks that \b value is in [0,\b ref).
634 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
636 if(value<0 || value>=ref)
638 std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg << " ! Expected in range [0," << ref << "[ having " << value << " !";
639 throw INTERP_KERNEL::Exception(oss.str().c_str());
644 * This method checks that [\b start, \b end) is compliant with ref length \b value.
645 * typically start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
647 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
649 if(start<0 || start>=value)
651 if(value!=start || end!=start)
653 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
654 throw INTERP_KERNEL::Exception(oss.str().c_str());
657 if(end<0 || end>value)
659 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected end " << end << " of input range, in [0," << value << "] !";
660 throw INTERP_KERNEL::Exception(oss.str().c_str());
664 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
666 if(value<0 || value>ref)
668 std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
669 throw INTERP_KERNEL::Exception(oss.str().c_str());
674 * This method is useful to slice work among a pool of threads or processes. \a begin, \a end \a step is the input whole slice of work to perform,
675 * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
677 * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
679 * \param [in] start - the start of the input slice of the whole work to perform split into slices.
680 * \param [in] stop - the stop of the input slice of the whole work to perform split into slices.
681 * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform split into slices.
682 * \param [in] sliceId - the slice id considered
683 * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
684 * \param [out] startSlice - the start of the slice considered
685 * \param [out] stopSlice - the stop of the slice consided
687 * \throw If \a step == 0
688 * \throw If \a nbOfSlices not > 0
689 * \throw If \a sliceId not in [0,nbOfSlices)
691 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
695 std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
696 throw INTERP_KERNEL::Exception(oss.str().c_str());
698 if(sliceId<0 || sliceId>=nbOfSlices)
700 std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
701 throw INTERP_KERNEL::Exception(oss.str().c_str());
703 int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
704 int minNbOfElemsPerSlice=nbElems/nbOfSlices;
705 startSlice=start+minNbOfElemsPerSlice*step*sliceId;
706 if(sliceId<nbOfSlices-1)
707 stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
712 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
716 std::ostringstream oss; oss << msg << " : end before begin !";
717 throw INTERP_KERNEL::Exception(oss.str().c_str());
723 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
724 throw INTERP_KERNEL::Exception(oss.str().c_str());
726 return (end-1-begin)/step+1;
729 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
732 throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
733 if(end<begin && step>0)
735 std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
736 throw INTERP_KERNEL::Exception(oss.str().c_str());
738 if(begin<end && step<0)
740 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
741 throw INTERP_KERNEL::Exception(oss.str().c_str());
744 return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
749 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
755 if(begin<=value && value<end)
757 if((value-begin)%step==0)
758 return (value-begin)/step;
767 if(begin>=value && value>end)
769 if((begin-value)%(-step)==0)
770 return (begin-value)/(-step);
783 * Returns a new instance of DataArrayDouble. The caller is to delete this array
784 * using decrRef() as it is no more needed.
786 DataArrayDouble *DataArrayDouble::New()
788 return new DataArrayDouble;
792 * Returns the only one value in \a this, if and only if number of elements
793 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
794 * \return double - the sole value stored in \a this array.
795 * \throw If at least one of conditions stated above is not fulfilled.
797 double DataArrayDouble::doubleValue() const
801 if(getNbOfElems()==1)
803 return *getConstPointer();
806 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
809 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
813 * Returns a full copy of \a this. For more info on copying data arrays see
814 * \ref MEDCouplingArrayBasicsCopyDeep.
815 * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
816 * delete this array using decrRef() as it is no more needed.
818 DataArrayDouble *DataArrayDouble::deepCopy() const
820 return new DataArrayDouble(*this);
824 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
825 * with at least absolute difference value of |\a eps| at each step.
826 * If not an exception is thrown.
827 * \param [in] increasing - if \a true, the array values should be increasing.
828 * \param [in] eps - minimal absolute difference between the neighbor values at which
829 * the values are considered different.
830 * \throw If sequence of values is not strictly monotonic in agreement with \a
832 * \throw If \a this->getNumberOfComponents() != 1.
833 * \throw If \a this is not allocated.
835 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
837 if(!isMonotonic(increasing,eps))
840 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
842 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
847 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
848 * with at least absolute difference value of |\a eps| at each step.
849 * \param [in] increasing - if \a true, array values should be increasing.
850 * \param [in] eps - minimal absolute difference between the neighbor values at which
851 * the values are considered different.
852 * \return bool - \a true if values change in accordance with \a increasing arg.
853 * \throw If \a this->getNumberOfComponents() != 1.
854 * \throw If \a this is not allocated.
856 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
859 if(getNumberOfComponents()!=1)
860 throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
861 int nbOfElements=getNumberOfTuples();
862 const double *ptr=getConstPointer();
866 double absEps=fabs(eps);
869 for(int i=1;i<nbOfElements;i++)
871 if(ptr[i]<(ref+absEps))
879 for(int i=1;i<nbOfElements;i++)
881 if(ptr[i]>(ref-absEps))
889 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
891 static const char SPACE[4]={' ',' ',' ',' '};
893 std::string idt(indent,' ');
895 ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
897 bool areAllEmpty(true);
898 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
902 for(std::size_t i=0;i<_info_on_compo.size();i++)
903 ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
907 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
908 INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
910 // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
911 for(const double *src=begin();src!=end();src++,pt++)
913 const char *data(reinterpret_cast<const char *>((float *)tmp));
914 std::size_t sz(getNbOfElems()*sizeof(float));
915 byteArr->insertAtTheEnd(data,data+sz);
916 byteArr->insertAtTheEnd(SPACE,SPACE+4);
920 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
921 std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
923 ofs << std::endl << idt << "</DataArray>\n";
926 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
928 int nbTuples(getNumberOfTuples()),nbComp(getNumberOfComponents());
929 const double *data(getConstPointer());
930 stream.precision(17);
931 stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
932 if(nbTuples*nbComp>=1)
934 stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
935 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
936 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
937 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
940 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
941 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
945 * Method that gives a quick overvien of \a this for python.
947 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
949 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
950 stream << "DataArrayDouble C++ instance at " << this << ". ";
953 std::size_t nbOfCompo(_info_on_compo.size());
956 std::size_t nbOfTuples(getNumberOfTuples());
957 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
958 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
961 stream << "Number of components : 0.";
964 stream << "*** No data allocated ****";
967 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
969 const double *data=begin();
970 int nbOfTuples=getNumberOfTuples();
971 int nbOfCompo=(int)_info_on_compo.size();
972 std::ostringstream oss2; oss2 << "[";
974 std::string oss2Str(oss2.str());
975 bool isFinished=true;
976 for(int i=0;i<nbOfTuples && isFinished;i++)
981 for(int j=0;j<nbOfCompo;j++,data++)
984 if(j!=nbOfCompo-1) oss2 << ", ";
990 if(i!=nbOfTuples-1) oss2 << ", ";
991 std::string oss3Str(oss2.str());
992 if(oss3Str.length()<maxNbOfByteInRepr)
1004 * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1005 * mismatch is given.
1007 * \param [in] other the instance to be compared with \a this
1008 * \param [in] prec the precision to compare numeric data of the arrays.
1009 * \param [out] reason In case of inequality returns the reason.
1010 * \sa DataArrayDouble::isEqual
1012 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1014 if(!areInfoEqualsIfNotWhy(other,reason))
1016 return _mem.isEqual(other._mem,prec,reason);
1020 * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1021 * \ref MEDCouplingArrayBasicsCompare.
1022 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1023 * \param [in] prec - precision value to compare numeric data of the arrays.
1024 * \return bool - \a true if the two arrays are equal, \a false else.
1026 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1029 return isEqualIfNotWhy(other,prec,tmp);
1033 * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1034 * \ref MEDCouplingArrayBasicsCompare.
1035 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1036 * \param [in] prec - precision value to compare numeric data of the arrays.
1037 * \return bool - \a true if the values of two arrays are equal, \a false else.
1039 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1042 return _mem.isEqual(other._mem,prec,tmp);
1046 * This method checks that all tuples in \a other are in \a this.
1047 * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1048 * For each i in [ 0 , other->getNumberOfTuples() ) tuple #i in \a other is equal ( regarding input precision \a prec ) to tuple tupleIds[i] in \a this.
1050 * \param [in] other - the array having the same number of components than \a this.
1051 * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1052 * \sa DataArrayDouble::findCommonTuples
1054 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1057 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1058 checkAllocated(); other->checkAllocated();
1059 if(getNumberOfComponents()!=other->getNumberOfComponents())
1060 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1061 MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1062 DataArrayInt *c=0,*ci=0;
1063 a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1064 MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1065 int newNbOfTuples=-1;
1066 MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1067 MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1068 tupleIds=ret1.retn();
1069 return newNbOfTuples==getNumberOfTuples();
1073 * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1074 * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1075 * distance separating two points is computed with the infinite norm.
1077 * Indices of coincident tuples are stored in output arrays.
1078 * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1080 * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1081 * MEDCouplingUMesh::mergeNodes().
1082 * \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1083 * considered not coincident.
1084 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1085 * tuples have id strictly lower than \a limitTupleId then they are not returned.
1086 * \param [out] comm - the array holding ids (== indices) of coincident tuples.
1087 * \a comm->getNumberOfComponents() == 1.
1088 * \a comm->getNumberOfTuples() == \a commIndex->back().
1089 * \param [out] commIndex - the array dividing all indices stored in \a comm into
1090 * groups of (indices of) coincident tuples. Its every value is a tuple
1091 * index where a next group of tuples begins. For example the second
1092 * group of tuples in \a comm is described by following range of indices:
1093 * [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1094 * gives the number of groups of coincident tuples.
1095 * \throw If \a this is not allocated.
1096 * \throw If the number of components is not in [1,2,3,4].
1098 * \if ENABLE_EXAMPLES
1099 * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1101 * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example".
1103 * \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1105 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1108 int nbOfCompo=getNumberOfComponents();
1109 if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1110 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1112 int nbOfTuples=getNumberOfTuples();
1114 MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1118 findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1121 findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1124 findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1127 findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1130 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1133 commIndex=cI.retn();
1137 * This methods returns the minimal distance between the two set of points \a this and \a other.
1138 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1139 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1141 * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1142 * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1143 * \return the minimal distance between the two set of points \a this and \a other.
1144 * \sa DataArrayDouble::findClosestTupleId
1146 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1148 MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1149 int nbOfCompo(getNumberOfComponents());
1150 int otherNbTuples(other->getNumberOfTuples());
1151 const double *thisPt(begin()),*otherPt(other->begin());
1152 const int *part1Pt(part1->begin());
1153 double ret=std::numeric_limits<double>::max();
1154 for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1157 for(int j=0;j<nbOfCompo;j++)
1158 tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1160 { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1166 * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1167 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1168 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1170 * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1171 * \sa DataArrayDouble::minimalDistanceTo
1173 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1176 throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1177 checkAllocated(); other->checkAllocated();
1178 std::size_t nbOfCompo(getNumberOfComponents());
1179 if(nbOfCompo!=other->getNumberOfComponents())
1181 std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1182 oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1183 throw INTERP_KERNEL::Exception(oss.str().c_str());
1185 int nbOfTuples=other->getNumberOfTuples();
1186 int thisNbOfTuples=getNumberOfTuples();
1187 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1189 getMinMaxPerComponent(bounds);
1194 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1195 double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1196 double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1197 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1198 FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1203 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1204 double delta=std::max(xDelta,yDelta);
1205 double characSize=sqrt(delta/(double)thisNbOfTuples);
1206 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1207 FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1212 double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1213 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1214 FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1218 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1224 * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1225 * This method will return a DataArrayInt array having the same number of tuples than \a this. This returned array tells for each cell in \a this
1226 * how many bounding boxes in \a otherBBoxFrmt.
1227 * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1229 * \param [in] otherBBoxFrmt - It is an array .
1230 * \param [in] eps - the absolute precision of the detection. when eps < 0 the bboxes are enlarged so more interactions are detected. Inversely when > 0 the bboxes are stretched.
1231 * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1232 * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1233 * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1235 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1238 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1239 if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1240 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1241 std::size_t nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1242 if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1244 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1245 throw INTERP_KERNEL::Exception(oss.str().c_str());
1249 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1250 throw INTERP_KERNEL::Exception(oss.str().c_str());
1252 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1253 const double *thisBBPtr(begin());
1254 int *retPtr(ret->getPointer());
1259 BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1260 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1261 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1266 BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1267 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1268 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1273 BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1274 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1275 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1279 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1286 * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1287 * considered as coordinates of a point in getNumberOfComponents()-dimensional
1288 * space. The distance between tuples is computed using norm2. If several tuples are
1289 * not far each from other than \a prec, only one of them remains in the result
1290 * array. The order of tuples in the result array is same as in \a this one except
1291 * that coincident tuples are excluded.
1292 * \param [in] prec - minimal absolute distance between two tuples at which they are
1293 * considered not coincident.
1294 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1295 * tuples have id strictly lower than \a limitTupleId then they are not excluded.
1296 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1297 * is to delete using decrRef() as it is no more needed.
1298 * \throw If \a this is not allocated.
1299 * \throw If the number of components is not in [1,2,3,4].
1301 * \if ENABLE_EXAMPLES
1302 * \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1305 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1308 DataArrayInt *c0=0,*cI0=0;
1309 findCommonTuples(prec,limitTupleId,c0,cI0);
1310 MCAuto<DataArrayInt> c(c0),cI(cI0);
1311 int newNbOfTuples=-1;
1312 MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1313 return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1317 * Copy all components in a specified order from another DataArrayDouble.
1318 * Both numerical and textual data is copied. The number of tuples in \a this and
1319 * the other array can be different.
1320 * \param [in] a - the array to copy data from.
1321 * \param [in] compoIds - sequence of zero based indices of components, data of which is
1323 * \throw If \a a is NULL.
1324 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1325 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1327 * \if ENABLE_EXAMPLES
1328 * \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1331 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1334 throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1336 copyPartOfStringInfoFrom2(compoIds,*a);
1337 std::size_t partOfCompoSz=compoIds.size();
1338 int nbOfCompo=getNumberOfComponents();
1339 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1340 const double *ac=a->getConstPointer();
1341 double *nc=getPointer();
1342 for(int i=0;i<nbOfTuples;i++)
1343 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1344 nc[nbOfCompo*i+compoIds[j]]=*ac;
1348 * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1350 * \throw If zero is found in \a this array.
1352 void DataArrayDouble::checkNoNullValues() const
1354 const double *tmp=getConstPointer();
1355 std::size_t nbOfElems=getNbOfElems();
1356 const double *where=std::find(tmp,tmp+nbOfElems,0.);
1357 if(where!=tmp+nbOfElems)
1358 throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1362 * Computes minimal and maximal value in each component. An output array is filled
1363 * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1364 * enough memory before calling this method.
1365 * \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1366 * It is filled as follows:<br>
1367 * \a bounds[0] = \c min_of_component_0 <br>
1368 * \a bounds[1] = \c max_of_component_0 <br>
1369 * \a bounds[2] = \c min_of_component_1 <br>
1370 * \a bounds[3] = \c max_of_component_1 <br>
1373 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1376 int dim=getNumberOfComponents();
1377 for (int idim=0; idim<dim; idim++)
1379 bounds[idim*2]=std::numeric_limits<double>::max();
1380 bounds[idim*2+1]=-std::numeric_limits<double>::max();
1382 const double *ptr=getConstPointer();
1383 int nbOfTuples=getNumberOfTuples();
1384 for(int i=0;i<nbOfTuples;i++)
1386 for(int idim=0;idim<dim;idim++)
1388 if(bounds[idim*2]>ptr[i*dim+idim])
1390 bounds[idim*2]=ptr[i*dim+idim];
1392 if(bounds[idim*2+1]<ptr[i*dim+idim])
1394 bounds[idim*2+1]=ptr[i*dim+idim];
1401 * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1402 * to store both the min and max per component of each tuples.
1403 * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1405 * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1407 * \throw If \a this is not allocated yet.
1409 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1412 const double *dataPtr=getConstPointer();
1413 int nbOfCompo=getNumberOfComponents();
1414 int nbTuples=getNumberOfTuples();
1415 MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1416 bbox->alloc(nbTuples,2*nbOfCompo);
1417 double *bboxPtr=bbox->getPointer();
1418 for(int i=0;i<nbTuples;i++)
1420 for(int j=0;j<nbOfCompo;j++)
1422 bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1423 bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1430 * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1431 * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1433 * \param [in] other a DataArrayDouble having same number of components than \a this.
1434 * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1435 * \param [out] c will contain the set of tuple ids in \a this that are equal to to the tuple ids in \a other contiguously.
1436 * \a cI allows to extract information in \a c.
1437 * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1439 * \throw In case of:
1440 * - \a this is not allocated
1441 * - \a other is not allocated or null
1442 * - \a this and \a other do not have the same number of components
1443 * - if number of components of \a this is not in [1,2,3]
1445 * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1447 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1450 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1452 other->checkAllocated();
1453 int nbOfCompo=getNumberOfComponents();
1454 int otherNbOfCompo=other->getNumberOfComponents();
1455 if(nbOfCompo!=otherNbOfCompo)
1456 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1457 int nbOfTuplesOther=other->getNumberOfTuples();
1458 MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1463 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1464 FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1469 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1470 FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1475 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1476 FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1480 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1482 c=cArr.retn(); cI=cIArr.retn();
1486 * This method recenter tuples in \b this in order to be centered at the origin to benefit about the advantages of maximal precision to be around the box
1487 * around origin of 'radius' 1.
1489 * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1491 void DataArrayDouble::recenterForMaxPrecision(double eps)
1494 int dim=getNumberOfComponents();
1495 std::vector<double> bounds(2*dim);
1496 getMinMaxPerComponent(&bounds[0]);
1497 for(int i=0;i<dim;i++)
1499 double delta=bounds[2*i+1]-bounds[2*i];
1500 double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1502 applyLin(1./delta,-offset/delta,i);
1504 applyLin(1.,-offset,i);
1509 * Returns the maximal value and all its locations within \a this one-dimensional array.
1510 * \param [out] tupleIds - a new instance of DataArrayInt containing indices of
1511 * tuples holding the maximal value. The caller is to delete it using
1512 * decrRef() as it is no more needed.
1513 * \return double - the maximal value among all values of \a this array.
1514 * \throw If \a this->getNumberOfComponents() != 1
1515 * \throw If \a this->getNumberOfTuples() < 1
1517 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1521 double ret=getMaxValue(tmp);
1522 tupleIds=findIdsInRange(ret,ret);
1527 * Returns the minimal value and all its locations within \a this one-dimensional array.
1528 * \param [out] tupleIds - a new instance of DataArrayInt containing indices of
1529 * tuples holding the minimal value. The caller is to delete it using
1530 * decrRef() as it is no more needed.
1531 * \return double - the minimal value among all values of \a this array.
1532 * \throw If \a this->getNumberOfComponents() != 1
1533 * \throw If \a this->getNumberOfTuples() < 1
1535 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1539 double ret=getMinValue(tmp);
1540 tupleIds=findIdsInRange(ret,ret);
1545 * This method returns the number of values in \a this that are equals ( within an absolute precision of \a eps ) to input parameter \a value.
1546 * This method only works for single component array.
1548 * \return a value in [ 0, \c this->getNumberOfTuples() )
1550 * \throw If \a this is not allocated
1553 int DataArrayDouble::count(double value, double eps) const
1557 if(getNumberOfComponents()!=1)
1558 throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1559 const double *vals=begin();
1560 int nbOfTuples=getNumberOfTuples();
1561 for(int i=0;i<nbOfTuples;i++,vals++)
1562 if(fabs(*vals-value)<=eps)
1568 * Returns the average value of \a this one-dimensional array.
1569 * \return double - the average value over all values of \a this array.
1570 * \throw If \a this->getNumberOfComponents() != 1
1571 * \throw If \a this->getNumberOfTuples() < 1
1573 double DataArrayDouble::getAverageValue() const
1575 if(getNumberOfComponents()!=1)
1576 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1577 int nbOfTuples=getNumberOfTuples();
1579 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1580 const double *vals=getConstPointer();
1581 double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1582 return ret/nbOfTuples;
1586 * Returns the Euclidean norm of the vector defined by \a this array.
1587 * \return double - the value of the Euclidean norm, i.e.
1588 * the square root of the inner product of vector.
1589 * \throw If \a this is not allocated.
1591 double DataArrayDouble::norm2() const
1595 std::size_t nbOfElems=getNbOfElems();
1596 const double *pt=getConstPointer();
1597 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1603 * Returns the maximum norm of the vector defined by \a this array.
1604 * This method works even if the number of components is different from one.
1605 * If the number of elements in \a this is 0, -1. is returned.
1606 * \return double - the value of the maximum norm, i.e.
1607 * the maximal absolute value among values of \a this array (whatever its number of components).
1608 * \throw If \a this is not allocated.
1610 double DataArrayDouble::normMax() const
1614 std::size_t nbOfElems(getNbOfElems());
1615 const double *pt(getConstPointer());
1616 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1618 double val(std::abs(*pt));
1626 * Returns the maximum norm of for each component of \a this array.
1627 * If the number of elements in \a this is 0, -1. is returned.
1628 * \param [out] res - pointer to an array of result values, of size at least \a
1629 * this->getNumberOfComponents(), that is to be allocated by the caller.
1630 * \throw If \a this is not allocated.
1632 void DataArrayDouble::normMaxPerComponent(double * res) const
1635 std::size_t nbOfTuples(getNumberOfTuples());
1636 int nbOfCompos(getNumberOfComponents());
1637 std::fill(res, res+nbOfCompos, -1.0);
1638 const double *pt(getConstPointer());
1639 for(std::size_t i=0;i<nbOfTuples;i++)
1640 for (int j=0; j<nbOfCompos; j++, pt++)
1642 double val(std::abs(*pt));
1650 * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1651 * This method works even if the number of components is different from one.
1652 * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1653 * \return double - the value of the minimum norm, i.e.
1654 * the minimal absolute value among values of \a this array (whatever its number of components).
1655 * \throw If \a this is not allocated.
1657 double DataArrayDouble::normMin() const
1660 double ret(std::numeric_limits<double>::max());
1661 std::size_t nbOfElems(getNbOfElems());
1662 const double *pt(getConstPointer());
1663 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1665 double val(std::abs(*pt));
1673 * Accumulates values of each component of \a this array.
1674 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
1675 * by the caller, that is filled by this method with sum value for each
1677 * \throw If \a this is not allocated.
1679 void DataArrayDouble::accumulate(double *res) const
1682 const double *ptr=getConstPointer();
1683 int nbTuple=getNumberOfTuples();
1684 int nbComps=getNumberOfComponents();
1685 std::fill(res,res+nbComps,0.);
1686 for(int i=0;i<nbTuple;i++)
1687 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1691 * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1692 * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1695 * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1696 * \a tupleEnd. If not an exception will be thrown.
1698 * \param [in] tupleBg start pointer (included) of input external tuple
1699 * \param [in] tupleEnd end pointer (not included) of input external tuple
1700 * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1701 * \return the min distance.
1702 * \sa MEDCouplingUMesh::distanceToPoint
1704 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1707 int nbTuple=getNumberOfTuples();
1708 int nbComps=getNumberOfComponents();
1709 if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1710 { std::ostringstream oss; oss << "DataArrayDouble::distanceToTuple : size of input tuple is " << std::distance(tupleBg,tupleEnd) << " should be equal to the number of components in this : " << nbComps << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
1712 throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1713 double ret0=std::numeric_limits<double>::max();
1715 const double *work=getConstPointer();
1716 for(int i=0;i<nbTuple;i++)
1719 for(int j=0;j<nbComps;j++,work++)
1720 val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1724 { ret0=val; tupleId=i; }
1730 * Accumulate values of the given component of \a this array.
1731 * \param [in] compId - the index of the component of interest.
1732 * \return double - a sum value of \a compId-th component.
1733 * \throw If \a this is not allocated.
1734 * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1737 double DataArrayDouble::accumulate(int compId) const
1740 const double *ptr=getConstPointer();
1741 int nbTuple=getNumberOfTuples();
1742 int nbComps=getNumberOfComponents();
1743 if(compId<0 || compId>=nbComps)
1744 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1746 for(int i=0;i<nbTuple;i++)
1747 ret+=ptr[i*nbComps+compId];
1752 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1753 * The returned array will have same number of components than \a this and number of tuples equal to
1754 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1756 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1757 * This method is quite useful for users that need to put a field on cells to field on nodes on the same mesh without a need of conservation.
1759 * \param [in] bgOfIndex - begin (included) of the input index array.
1760 * \param [in] endOfIndex - end (excluded) of the input index array.
1761 * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1763 * \throw If bgOfIndex or end is NULL.
1764 * \throw If input index array is not ascendingly sorted.
1765 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1766 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1768 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1770 if(!bgOfIndex || !endOfIndex)
1771 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1773 int nbCompo=getNumberOfComponents();
1774 int nbOfTuples=getNumberOfTuples();
1775 int sz=(int)std::distance(bgOfIndex,endOfIndex);
1777 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1779 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1780 const int *w=bgOfIndex;
1781 if(*w<0 || *w>=nbOfTuples)
1782 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1783 const double *srcPt=begin()+(*w)*nbCompo;
1784 double *tmp=ret->getPointer();
1785 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1787 std::fill(tmp,tmp+nbCompo,0.);
1790 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1792 if(j>=0 && j<nbOfTuples)
1793 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1796 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
1797 throw INTERP_KERNEL::Exception(oss.str().c_str());
1803 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
1804 throw INTERP_KERNEL::Exception(oss.str().c_str());
1807 ret->copyStringInfoFrom(*this);
1812 * This method is close to numpy cumSum except that number of element is equal to \a this->getNumberOfTuples()+1. First element of DataArray returned is equal to 0.
1813 * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
1814 * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
1816 * \return DataArrayDouble - A newly built array containing cum sum of \a this.
1818 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
1821 checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
1822 int nbOfTuple(getNumberOfTuples());
1823 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
1824 double *ptr(ret->getPointer());
1826 const double *thisPtr(begin());
1827 for(int i=0;i<nbOfTuple;i++)
1828 ptr[i+1]=ptr[i]+thisPtr[i];
1833 * Converts each 2D point defined by the tuple of \a this array from the Polar to the
1834 * Cartesian coordinate system. The two components of the tuple of \a this array are
1835 * considered to contain (1) radius and (2) angle of the point in the Polar CS.
1836 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1837 * contains X and Y coordinates of the point in the Cartesian CS. The caller
1838 * is to delete this array using decrRef() as it is no more needed. The array
1839 * does not contain any textual info on components.
1840 * \throw If \a this->getNumberOfComponents() != 2.
1841 * \sa fromCartToPolar
1843 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
1846 int nbOfComp(getNumberOfComponents());
1848 throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
1849 int nbOfTuple(getNumberOfTuples());
1850 DataArrayDouble *ret(DataArrayDouble::New());
1851 ret->alloc(nbOfTuple,2);
1852 double *w(ret->getPointer());
1853 const double *wIn(getConstPointer());
1854 for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
1856 w[0]=wIn[0]*cos(wIn[1]);
1857 w[1]=wIn[0]*sin(wIn[1]);
1863 * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
1864 * the Cartesian coordinate system. The three components of the tuple of \a this array
1865 * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
1866 * the Cylindrical CS.
1867 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1868 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1869 * on the third component is copied from \a this array. The caller
1870 * is to delete this array using decrRef() as it is no more needed.
1871 * \throw If \a this->getNumberOfComponents() != 3.
1874 DataArrayDouble *DataArrayDouble::fromCylToCart() const
1877 int nbOfComp(getNumberOfComponents());
1879 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
1880 int nbOfTuple(getNumberOfTuples());
1881 DataArrayDouble *ret(DataArrayDouble::New());
1882 ret->alloc(getNumberOfTuples(),3);
1883 double *w(ret->getPointer());
1884 const double *wIn(getConstPointer());
1885 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1887 w[0]=wIn[0]*cos(wIn[1]);
1888 w[1]=wIn[0]*sin(wIn[1]);
1891 ret->setInfoOnComponent(2,getInfoOnComponent(2));
1896 * Converts each 3D point defined by the tuple of \a this array from the Spherical to
1897 * the Cartesian coordinate system. The three components of the tuple of \a this array
1898 * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
1899 * point in the Cylindrical CS.
1900 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1901 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1902 * on the third component is copied from \a this array. The caller
1903 * is to delete this array using decrRef() as it is no more needed.
1904 * \throw If \a this->getNumberOfComponents() != 3.
1905 * \sa fromCartToSpher
1907 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
1910 int nbOfComp(getNumberOfComponents());
1912 throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
1913 int nbOfTuple(getNumberOfTuples());
1914 DataArrayDouble *ret(DataArrayDouble::New());
1915 ret->alloc(getNumberOfTuples(),3);
1916 double *w(ret->getPointer());
1917 const double *wIn(getConstPointer());
1918 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1920 w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
1921 w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
1922 w[2]=wIn[0]*cos(wIn[1]);
1928 * 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.
1929 * 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.
1930 * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
1932 * \param [in] atOfThis - The axis type of \a this.
1933 * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
1935 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
1938 int nbOfComp(getNumberOfComponents());
1939 MCAuto<DataArrayDouble> ret;
1947 ret=fromCylToCart();
1952 ret=fromPolarToCart();
1956 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1960 ret=fromSpherToCart();
1965 ret=fromPolarToCart();
1969 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1971 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
1973 ret->copyStringInfoFrom(*this);
1978 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
1979 * This method expects that \a this has exactly 2 components.
1980 * \sa fromPolarToCart
1982 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
1984 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
1986 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
1988 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
1989 ret->alloc(nbTuples,2);
1990 double *retPtr(ret->getPointer());
1991 const double *ptr(begin());
1992 for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
1994 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
1995 retPtr[1]=atan2(ptr[1],ptr[0]);
2001 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2002 * This method expects that \a this has exactly 3 components.
2005 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2007 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2009 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2011 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2012 ret->alloc(nbTuples,3);
2013 double *retPtr(ret->getPointer());
2014 const double *ptr(begin());
2015 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2017 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2018 retPtr[1]=atan2(ptr[1],ptr[0]);
2025 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2026 * \sa fromSpherToCart
2028 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2030 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2032 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2034 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2035 ret->alloc(nbTuples,3);
2036 double *retPtr(ret->getPointer());
2037 const double *ptr(begin());
2038 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2040 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2041 retPtr[1]=acos(ptr[2]/retPtr[0]);
2042 retPtr[2]=atan2(ptr[1],ptr[0]);
2048 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical relative to the given \a center and a \a vector.
2049 * This method expects that \a this has exactly 3 components.
2050 * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2052 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2055 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2056 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2057 checkAllocated(); coords->checkAllocated();
2058 std::size_t nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2060 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2061 if(coords->getNumberOfComponents()!=3)
2062 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2063 if(coords->getNumberOfTuples()!=nbTuples)
2064 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2065 ret->alloc(nbTuples,nbOfComp);
2066 double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2068 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2069 double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2070 const double *coo(coords->begin()),*vectField(begin());
2071 std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2072 for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2074 std::transform(coo,coo+3,center,Ur,std::minus<double>());
2075 Uteta[0]=Uz[1]*Ur[2]-Uz[2]*Ur[1]; Uteta[1]=Uz[2]*Ur[0]-Uz[0]*Ur[2]; Uteta[2]=Uz[0]*Ur[1]-Uz[1]*Ur[0];
2076 double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2077 std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2078 Ur[0]=Uteta[1]*Uz[2]-Uteta[2]*Uz[1]; Ur[1]=Uteta[2]*Uz[0]-Uteta[0]*Uz[2]; Ur[2]=Uteta[0]*Uz[1]-Uteta[1]*Uz[0];
2079 retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2080 retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2081 retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2083 ret->copyStringInfoFrom(*this);
2088 * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2089 * array containing 6 components.
2090 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2091 * is calculated from the tuple <em>(t)</em> of \a this array as follows:
2092 * \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2093 * The caller is to delete this result array using decrRef() as it is no more needed.
2094 * \throw If \a this->getNumberOfComponents() != 6.
2096 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2099 int nbOfComp(getNumberOfComponents());
2101 throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2102 DataArrayDouble *ret=DataArrayDouble::New();
2103 int nbOfTuple=getNumberOfTuples();
2104 ret->alloc(nbOfTuple,1);
2105 const double *src=getConstPointer();
2106 double *dest=ret->getPointer();
2107 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2108 *dest=src[0]*src[0]+src[1]*src[1]+src[2]*src[2]+2.*src[3]*src[3]+2.*src[4]*src[4]+2.*src[5]*src[5];
2113 * Computes the determinant of every square matrix defined by the tuple of \a this
2114 * array, which contains either 4, 6 or 9 components. The case of 6 components
2115 * corresponds to that of the upper triangular matrix.
2116 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2117 * is the determinant of matrix of the corresponding tuple of \a this array.
2118 * The caller is to delete this result array using decrRef() as it is no more
2120 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2122 DataArrayDouble *DataArrayDouble::determinant() const
2125 DataArrayDouble *ret=DataArrayDouble::New();
2126 int nbOfTuple=getNumberOfTuples();
2127 ret->alloc(nbOfTuple,1);
2128 const double *src=getConstPointer();
2129 double *dest=ret->getPointer();
2130 switch(getNumberOfComponents())
2133 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2134 *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];
2137 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2138 *dest=src[0]*src[3]-src[1]*src[2];
2141 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2142 *dest=src[0]*src[4]*src[8]+src[1]*src[5]*src[6]+src[2]*src[3]*src[7]-src[0]*src[5]*src[7]-src[1]*src[3]*src[8]-src[2]*src[4]*src[6];
2146 throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2151 * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2152 * \a this array, which contains 6 components.
2153 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2154 * components, whose each tuple contains the eigenvalues of the matrix of
2155 * corresponding tuple of \a this array.
2156 * The caller is to delete this result array using decrRef() as it is no more
2158 * \throw If \a this->getNumberOfComponents() != 6.
2160 DataArrayDouble *DataArrayDouble::eigenValues() const
2163 int nbOfComp=getNumberOfComponents();
2165 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2166 DataArrayDouble *ret=DataArrayDouble::New();
2167 int nbOfTuple=getNumberOfTuples();
2168 ret->alloc(nbOfTuple,3);
2169 const double *src=getConstPointer();
2170 double *dest=ret->getPointer();
2171 for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2172 INTERP_KERNEL::computeEigenValues6(src,dest);
2177 * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2178 * \a this array, which contains 6 components.
2179 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2180 * components, whose each tuple contains 3 eigenvectors of the matrix of
2181 * corresponding tuple of \a this array.
2182 * The caller is to delete this result array using decrRef() as it is no more
2184 * \throw If \a this->getNumberOfComponents() != 6.
2186 DataArrayDouble *DataArrayDouble::eigenVectors() const
2189 int nbOfComp=getNumberOfComponents();
2191 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2192 DataArrayDouble *ret=DataArrayDouble::New();
2193 int nbOfTuple=getNumberOfTuples();
2194 ret->alloc(nbOfTuple,9);
2195 const double *src=getConstPointer();
2196 double *dest=ret->getPointer();
2197 for(int i=0;i<nbOfTuple;i++,src+=6)
2200 INTERP_KERNEL::computeEigenValues6(src,tmp);
2201 for(int j=0;j<3;j++,dest+=3)
2202 INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2208 * Computes the inverse matrix of every matrix defined by the tuple of \a this
2209 * array, which contains either 4, 6 or 9 components. The case of 6 components
2210 * corresponds to that of the upper triangular matrix.
2211 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2212 * same number of components as \a this one, whose each tuple is the inverse
2213 * matrix of the matrix of corresponding tuple of \a this array.
2214 * The caller is to delete this result array using decrRef() as it is no more
2216 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2218 DataArrayDouble *DataArrayDouble::inverse() const
2221 int nbOfComp=getNumberOfComponents();
2222 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2223 throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2224 DataArrayDouble *ret=DataArrayDouble::New();
2225 int nbOfTuple=getNumberOfTuples();
2226 ret->alloc(nbOfTuple,nbOfComp);
2227 const double *src=getConstPointer();
2228 double *dest=ret->getPointer();
2230 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2232 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];
2233 dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2234 dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2235 dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2236 dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2237 dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2238 dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2240 else if(nbOfComp==4)
2241 for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2243 double det=src[0]*src[3]-src[1]*src[2];
2245 dest[1]=-src[1]/det;
2246 dest[2]=-src[2]/det;
2250 for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2252 double det=src[0]*src[4]*src[8]+src[1]*src[5]*src[6]+src[2]*src[3]*src[7]-src[0]*src[5]*src[7]-src[1]*src[3]*src[8]-src[2]*src[4]*src[6];
2253 dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2254 dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2255 dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2256 dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2257 dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2258 dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2259 dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2260 dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2261 dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2267 * Computes the trace of every matrix defined by the tuple of \a this
2268 * array, which contains either 4, 6 or 9 components. The case of 6 components
2269 * corresponds to that of the upper triangular matrix.
2270 * \return DataArrayDouble * - the new instance of DataArrayDouble containing
2271 * 1 component, whose each tuple is the trace of
2272 * the matrix of corresponding tuple of \a this array.
2273 * The caller is to delete this result array using decrRef() as it is no more
2275 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2277 DataArrayDouble *DataArrayDouble::trace() const
2280 int nbOfComp=getNumberOfComponents();
2281 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2282 throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2283 DataArrayDouble *ret=DataArrayDouble::New();
2284 int nbOfTuple=getNumberOfTuples();
2285 ret->alloc(nbOfTuple,1);
2286 const double *src=getConstPointer();
2287 double *dest=ret->getPointer();
2289 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2290 *dest=src[0]+src[1]+src[2];
2291 else if(nbOfComp==4)
2292 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2293 *dest=src[0]+src[3];
2295 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2296 *dest=src[0]+src[4]+src[8];
2301 * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2302 * \a this array, which contains 6 components.
2303 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2304 * same number of components and tuples as \a this array.
2305 * The caller is to delete this result array using decrRef() as it is no more
2307 * \throw If \a this->getNumberOfComponents() != 6.
2309 DataArrayDouble *DataArrayDouble::deviator() const
2312 int nbOfComp=getNumberOfComponents();
2314 throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2315 DataArrayDouble *ret=DataArrayDouble::New();
2316 int nbOfTuple=getNumberOfTuples();
2317 ret->alloc(nbOfTuple,6);
2318 const double *src=getConstPointer();
2319 double *dest=ret->getPointer();
2320 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2322 double tr=(src[0]+src[1]+src[2])/3.;
2334 * Computes the magnitude of every vector defined by the tuple of
2336 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2337 * same number of tuples as \a this array and one component.
2338 * The caller is to delete this result array using decrRef() as it is no more
2340 * \throw If \a this is not allocated.
2342 DataArrayDouble *DataArrayDouble::magnitude() const
2345 int nbOfComp=getNumberOfComponents();
2346 DataArrayDouble *ret=DataArrayDouble::New();
2347 int nbOfTuple=getNumberOfTuples();
2348 ret->alloc(nbOfTuple,1);
2349 const double *src=getConstPointer();
2350 double *dest=ret->getPointer();
2351 for(int i=0;i<nbOfTuple;i++,dest++)
2354 for(int j=0;j<nbOfComp;j++,src++)
2362 * Computes the maximal value within every tuple of \a this array.
2363 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2364 * same number of tuples as \a this array and one component.
2365 * The caller is to delete this result array using decrRef() as it is no more
2367 * \throw If \a this is not allocated.
2368 * \sa DataArrayDouble::maxPerTupleWithCompoId
2370 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2373 int nbOfComp=getNumberOfComponents();
2374 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2375 int nbOfTuple=getNumberOfTuples();
2376 ret->alloc(nbOfTuple,1);
2377 const double *src=getConstPointer();
2378 double *dest=ret->getPointer();
2379 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2380 *dest=*std::max_element(src,src+nbOfComp);
2385 * Computes the maximal value within every tuple of \a this array and it returns the first component
2386 * id for each tuple that corresponds to the maximal value within the tuple.
2388 * \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2389 * same number of tuples and only one component.
2390 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2391 * same number of tuples as \a this array and one component.
2392 * The caller is to delete this result array using decrRef() as it is no more
2394 * \throw If \a this is not allocated.
2395 * \sa DataArrayDouble::maxPerTuple
2397 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2400 int nbOfComp=getNumberOfComponents();
2401 MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2402 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2403 int nbOfTuple=getNumberOfTuples();
2404 ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2405 const double *src=getConstPointer();
2406 double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2407 for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2409 const double *loc=std::max_element(src,src+nbOfComp);
2411 *dest1=(int)std::distance(src,loc);
2413 compoIdOfMaxPerTuple=ret1.retn();
2418 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2419 * \n This returned array contains the euclidian distance for each tuple in \a this.
2420 * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2421 * \n The returned array has only one component (and **not** \c this->getNumberOfTuples() components to avoid the useless memory consumption due to components info in returned DataArrayDouble)
2423 * \warning use this method with care because it can leads to big amount of consumed memory !
2425 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2427 * \throw If \a this is not allocated.
2429 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2431 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2434 int nbOfComp=getNumberOfComponents();
2435 int nbOfTuples=getNumberOfTuples();
2436 const double *inData=getConstPointer();
2437 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2438 ret->alloc(nbOfTuples*nbOfTuples,1);
2439 double *outData=ret->getPointer();
2440 for(int i=0;i<nbOfTuples;i++)
2442 outData[i*nbOfTuples+i]=0.;
2443 for(int j=i+1;j<nbOfTuples;j++)
2446 for(int k=0;k<nbOfComp;k++)
2447 { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2449 outData[i*nbOfTuples+j]=dist;
2450 outData[j*nbOfTuples+i]=dist;
2457 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2458 * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this.
2459 * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2460 * \n Output rectangular matrix is sorted along rows.
2461 * \n The returned array has only one component (and **not** \c this->getNumberOfTuples() components to avoid the useless memory consumption due to components info in returned DataArrayDouble)
2463 * \warning use this method with care because it can leads to big amount of consumed memory !
2465 * \param [in] other DataArrayDouble instance having same number of components than \a this.
2466 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2468 * \throw If \a this is not allocated, or if \a other is null or if \a other is not allocated, or if number of components of \a other and \a this differs.
2470 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2472 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2475 throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2477 other->checkAllocated();
2478 int nbOfComp=getNumberOfComponents();
2479 int otherNbOfComp=other->getNumberOfComponents();
2480 if(nbOfComp!=otherNbOfComp)
2482 std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2483 throw INTERP_KERNEL::Exception(oss.str().c_str());
2485 int nbOfTuples=getNumberOfTuples();
2486 int otherNbOfTuples=other->getNumberOfTuples();
2487 const double *inData=getConstPointer();
2488 const double *inDataOther=other->getConstPointer();
2489 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2490 ret->alloc(otherNbOfTuples*nbOfTuples,1);
2491 double *outData=ret->getPointer();
2492 for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2494 for(int j=0;j<nbOfTuples;j++)
2497 for(int k=0;k<nbOfComp;k++)
2498 { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2500 outData[i*nbOfTuples+j]=dist;
2507 * This method expects that \a this stores 3 tuples containing 2 components each.
2508 * Each of this tuples represent a point into 2D space.
2509 * This method tries to find an arc of circle starting from first point (tuple) to 2nd and middle point (tuple) along 3nd and last point (tuple).
2510 * If such arc of circle exists, the corresponding center, radius of circle is returned. And additionnaly the length of arc expressed with an \a ang output variable in ]0,2*pi[.
2512 * \throw If \a this is not allocated.
2513 * \throw If \a this has not 3 tuples of 2 components
2514 * \throw If tuples/points in \a this are aligned
2516 void DataArrayDouble::asArcOfCircle(double center[2], double& radius, double& ang) const
2519 INTERP_KERNEL::QuadraticPlanarPrecision arcPrec(1e-14);
2520 if(getNumberOfTuples()!=3 && getNumberOfComponents()!=2)
2521 throw INTERP_KERNEL::Exception("DataArrayDouble::asArcCircle : this method expects");
2522 const double *pt(begin());
2523 MCAuto<INTERP_KERNEL::Node> n0(new INTERP_KERNEL::Node(pt[0],pt[1])),n1(new INTERP_KERNEL::Node(pt[2],pt[3])),n2(new INTERP_KERNEL::Node(pt[4],pt[5]));
2525 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::EdgeLin> e1(new INTERP_KERNEL::EdgeLin(n0,n2)),e2(new INTERP_KERNEL::EdgeLin(n2,n1));
2526 INTERP_KERNEL::SegSegIntersector inters(*e1,*e2);
2527 bool colinearity(inters.areColinears());
2529 throw INTERP_KERNEL::Exception("DataArrayDouble::asArcOfCircle : 3 points in this have been detected as colinear !");
2531 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::EdgeArcCircle> ret(new INTERP_KERNEL::EdgeArcCircle(n0,n2,n1));
2532 const double *c(ret->getCenter());
2533 center[0]=c[0]; center[1]=c[1];
2534 radius=ret->getRadius();
2535 ang=ret->getAngle();
2539 * Sorts value within every tuple of \a this array.
2540 * \param [in] asc - if \a true, the values are sorted in ascending order, else,
2541 * in descending order.
2542 * \throw If \a this is not allocated.
2544 void DataArrayDouble::sortPerTuple(bool asc)
2547 double *pt=getPointer();
2548 int nbOfTuple=getNumberOfTuples();
2549 int nbOfComp=getNumberOfComponents();
2551 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2552 std::sort(pt,pt+nbOfComp);
2554 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2555 std::sort(pt,pt+nbOfComp,std::greater<double>());
2560 * Modify all elements of \a this array, so that
2561 * an element _x_ becomes \f$ numerator / x \f$.
2562 * \warning If an exception is thrown because of presence of 0.0 element in \a this
2563 * array, all elements processed before detection of the zero element remain
2565 * \param [in] numerator - the numerator used to modify array elements.
2566 * \throw If \a this is not allocated.
2567 * \throw If there is an element equal to 0.0 in \a this array.
2569 void DataArrayDouble::applyInv(double numerator)
2572 double *ptr=getPointer();
2573 std::size_t nbOfElems=getNbOfElems();
2574 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2576 if(std::abs(*ptr)>std::numeric_limits<double>::min())
2578 *ptr=numerator/(*ptr);
2582 std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2584 throw INTERP_KERNEL::Exception(oss.str().c_str());
2591 * Modify all elements of \a this array, so that
2592 * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2593 * all values in \a this have to be >= 0 if val is \b not integer.
2594 * \param [in] val - the value used to apply pow on all array elements.
2595 * \throw If \a this is not allocated.
2596 * \warning If an exception is thrown because of presence of 0 element in \a this
2597 * array and \a val is \b not integer, all elements processed before detection of the zero element remain
2600 void DataArrayDouble::applyPow(double val)
2603 double *ptr=getPointer();
2604 std::size_t nbOfElems=getNbOfElems();
2606 bool isInt=((double)val2)==val;
2609 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2615 std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2616 throw INTERP_KERNEL::Exception(oss.str().c_str());
2622 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2623 *ptr=pow(*ptr,val2);
2629 * Modify all elements of \a this array, so that
2630 * an element _x_ becomes \f$ val ^ x \f$.
2631 * \param [in] val - the value used to apply pow on all array elements.
2632 * \throw If \a this is not allocated.
2633 * \throw If \a val < 0.
2634 * \warning If an exception is thrown because of presence of 0 element in \a this
2635 * array, all elements processed before detection of the zero element remain
2638 void DataArrayDouble::applyRPow(double val)
2642 throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2643 double *ptr=getPointer();
2644 std::size_t nbOfElems=getNbOfElems();
2645 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2651 * Returns a new DataArrayDouble created from \a this one by applying \a
2652 * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2653 * For more info see \ref MEDCouplingArrayApplyFunc
2654 * \param [in] nbOfComp - number of components in the result array.
2655 * \param [in] func - the \a FunctionToEvaluate declared as
2656 * \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res),
2657 * where \a pos points to the first component of a tuple of \a this array
2658 * and \a res points to the first component of a tuple of the result array.
2659 * Note that length (number of components) of \a pos can differ from
2661 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2662 * same number of tuples as \a this array.
2663 * The caller is to delete this result array using decrRef() as it is no more
2665 * \throw If \a this is not allocated.
2666 * \throw If \a func returns \a false.
2668 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2671 DataArrayDouble *newArr=DataArrayDouble::New();
2672 int nbOfTuples=getNumberOfTuples();
2673 int oldNbOfComp=getNumberOfComponents();
2674 newArr->alloc(nbOfTuples,nbOfComp);
2675 const double *ptr=getConstPointer();
2676 double *ptrToFill=newArr->getPointer();
2677 for(int i=0;i<nbOfTuples;i++)
2679 if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2681 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2682 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2683 oss << ") : Evaluation of function failed !";
2685 throw INTERP_KERNEL::Exception(oss.str().c_str());
2692 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2693 * tuple of \a this array. Textual data is not copied.
2694 * For more info see \ref MEDCouplingArrayApplyFunc1.
2695 * \param [in] nbOfComp - number of components in the result array.
2696 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2697 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2698 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2699 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2700 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2701 * same number of tuples as \a this array and \a nbOfComp components.
2702 * The caller is to delete this result array using decrRef() as it is no more
2704 * \throw If \a this is not allocated.
2705 * \throw If computing \a func fails.
2707 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2709 INTERP_KERNEL::ExprParser expr(func);
2711 std::set<std::string> vars;
2712 expr.getTrueSetOfVars(vars);
2713 std::vector<std::string> varsV(vars.begin(),vars.end());
2714 return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2718 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2719 * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2720 * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2722 * For more info see \ref MEDCouplingArrayApplyFunc0.
2723 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2724 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2725 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2726 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2727 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2728 * same number of tuples and components as \a this array.
2729 * The caller is to delete this result array using decrRef() as it is no more
2731 * \sa applyFuncOnThis
2732 * \throw If \a this is not allocated.
2733 * \throw If computing \a func fails.
2735 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
2737 int nbOfComp(getNumberOfComponents());
2739 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
2741 int nbOfTuples(getNumberOfTuples());
2742 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2743 newArr->alloc(nbOfTuples,nbOfComp);
2744 INTERP_KERNEL::ExprParser expr(func);
2746 std::set<std::string> vars;
2747 expr.getTrueSetOfVars(vars);
2748 if((int)vars.size()>1)
2750 std::ostringstream oss; oss << "DataArrayDouble::applyFunc : this method works only with at most one var func expression ! If you need to map comps on variables please use applyFuncCompo or applyFuncNamedCompo instead ! Vars in expr are : ";
2751 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2752 throw INTERP_KERNEL::Exception(oss.str().c_str());
2756 expr.prepareFastEvaluator();
2757 newArr->rearrange(1);
2758 newArr->fillWithValue(expr.evaluateDouble());
2759 newArr->rearrange(nbOfComp);
2760 return newArr.retn();
2762 std::vector<std::string> vars2(vars.begin(),vars.end());
2763 double buff,*ptrToFill(newArr->getPointer());
2764 const double *ptr(begin());
2765 std::vector<double> stck;
2766 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2767 expr.prepareFastEvaluator();
2770 for(int i=0;i<nbOfTuples;i++)
2772 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2775 expr.evaluateDoubleInternal(stck);
2776 *ptrToFill=stck.back();
2783 for(int i=0;i<nbOfTuples;i++)
2785 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2790 expr.evaluateDoubleInternalSafe(stck);
2792 catch(INTERP_KERNEL::Exception& e)
2794 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2796 oss << ") : Evaluation of function failed !" << e.what();
2797 throw INTERP_KERNEL::Exception(oss.str().c_str());
2799 *ptrToFill=stck.back();
2804 return newArr.retn();
2808 * This method is a non const method that modify the array in \a this.
2809 * This method only works on one component array. It means that function \a func must
2810 * contain at most one variable.
2811 * This method is a specialization of applyFunc method with one parameter on one component array.
2813 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2814 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2815 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2816 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2820 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
2822 int nbOfComp(getNumberOfComponents());
2824 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
2826 int nbOfTuples(getNumberOfTuples());
2827 INTERP_KERNEL::ExprParser expr(func);
2829 std::set<std::string> vars;
2830 expr.getTrueSetOfVars(vars);
2831 if((int)vars.size()>1)
2833 std::ostringstream oss; oss << "DataArrayDouble::applyFuncOnThis : this method works only with at most one var func expression ! If you need to map comps on variables please use applyFuncCompo or applyFuncNamedCompo instead ! Vars in expr are : ";
2834 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2835 throw INTERP_KERNEL::Exception(oss.str().c_str());
2839 expr.prepareFastEvaluator();
2840 std::vector<std::string> compInfo(getInfoOnComponents());
2842 fillWithValue(expr.evaluateDouble());
2843 rearrange(nbOfComp);
2844 setInfoOnComponents(compInfo);
2847 std::vector<std::string> vars2(vars.begin(),vars.end());
2848 double buff,*ptrToFill(getPointer());
2849 const double *ptr(begin());
2850 std::vector<double> stck;
2851 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2852 expr.prepareFastEvaluator();
2855 for(int i=0;i<nbOfTuples;i++)
2857 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2860 expr.evaluateDoubleInternal(stck);
2861 *ptrToFill=stck.back();
2868 for(int i=0;i<nbOfTuples;i++)
2870 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2875 expr.evaluateDoubleInternalSafe(stck);
2877 catch(INTERP_KERNEL::Exception& e)
2879 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2881 oss << ") : Evaluation of function failed !" << e.what();
2882 throw INTERP_KERNEL::Exception(oss.str().c_str());
2884 *ptrToFill=stck.back();
2892 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2893 * tuple of \a this array. Textual data is not copied.
2894 * For more info see \ref MEDCouplingArrayApplyFunc2.
2895 * \param [in] nbOfComp - number of components in the result array.
2896 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2897 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2898 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2899 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2900 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2901 * same number of tuples as \a this array.
2902 * The caller is to delete this result array using decrRef() as it is no more
2904 * \throw If \a this is not allocated.
2905 * \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
2906 * \throw If computing \a func fails.
2908 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
2910 return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
2914 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2915 * tuple of \a this array. Textual data is not copied.
2916 * For more info see \ref MEDCouplingArrayApplyFunc3.
2917 * \param [in] nbOfComp - number of components in the result array.
2918 * \param [in] varsOrder - sequence of vars defining their order.
2919 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2920 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2921 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2922 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2923 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2924 * same number of tuples as \a this array.
2925 * The caller is to delete this result array using decrRef() as it is no more
2927 * \throw If \a this is not allocated.
2928 * \throw If \a func contains vars not in \a varsOrder.
2929 * \throw If computing \a func fails.
2931 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
2934 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
2935 std::vector<std::string> varsOrder2(varsOrder);
2936 int oldNbOfComp(getNumberOfComponents());
2937 for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
2938 varsOrder2.push_back(std::string());
2940 int nbOfTuples(getNumberOfTuples());
2941 INTERP_KERNEL::ExprParser expr(func);
2943 std::set<std::string> vars;
2944 expr.getTrueSetOfVars(vars);
2945 if((int)vars.size()>oldNbOfComp)
2947 std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
2948 oss << vars.size() << " variables : ";
2949 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2950 throw INTERP_KERNEL::Exception(oss.str().c_str());
2952 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2953 newArr->alloc(nbOfTuples,nbOfComp);
2954 INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
2955 double *buffPtr(buff),*ptrToFill;
2956 std::vector<double> stck;
2957 for(int iComp=0;iComp<nbOfComp;iComp++)
2959 expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
2960 expr.prepareFastEvaluator();
2961 const double *ptr(getConstPointer());
2962 ptrToFill=newArr->getPointer()+iComp;
2965 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2967 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2968 expr.evaluateDoubleInternal(stck);
2969 *ptrToFill=stck.back();
2975 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2977 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2980 expr.evaluateDoubleInternalSafe(stck);
2981 *ptrToFill=stck.back();
2984 catch(INTERP_KERNEL::Exception& e)
2986 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2987 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2988 oss << ") : Evaluation of function failed !" << e.what();
2989 throw INTERP_KERNEL::Exception(oss.str().c_str());
2994 return newArr.retn();
2997 void DataArrayDouble::applyFuncFast32(const std::string& func)
3000 INTERP_KERNEL::ExprParser expr(func);
3002 char *funcStr=expr.compileX86();
3004 *((void **)&funcPtr)=funcStr;//he he...
3006 double *ptr=getPointer();
3007 int nbOfComp=getNumberOfComponents();
3008 int nbOfTuples=getNumberOfTuples();
3009 int nbOfElems=nbOfTuples*nbOfComp;
3010 for(int i=0;i<nbOfElems;i++,ptr++)
3015 void DataArrayDouble::applyFuncFast64(const std::string& func)
3018 INTERP_KERNEL::ExprParser expr(func);
3020 char *funcStr=expr.compileX86_64();
3022 *((void **)&funcPtr)=funcStr;//he he...
3024 double *ptr=getPointer();
3025 int nbOfComp=getNumberOfComponents();
3026 int nbOfTuples=getNumberOfTuples();
3027 int nbOfElems=nbOfTuples*nbOfComp;
3028 for(int i=0;i<nbOfElems;i++,ptr++)
3034 * \return a new object that is the result of the symmetry along 3D plane defined by its normal vector \a normalVector and a point \a point.
3036 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3039 if(getNumberOfComponents()!=3)
3040 throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3041 int nbTuples(getNumberOfTuples());
3042 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3043 ret->alloc(nbTuples,3);
3044 Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3048 DataArrayDoubleIterator *DataArrayDouble::iterator()
3050 return new DataArrayDoubleIterator(this);
3054 * Returns a new DataArrayInt containing indices of tuples of \a this one-dimensional
3055 * array whose values are within a given range. Textual data is not copied.
3056 * \param [in] vmin - a lowest acceptable value (included).
3057 * \param [in] vmax - a greatest acceptable value (included).
3058 * \return DataArrayInt * - the new instance of DataArrayInt.
3059 * The caller is to delete this result array using decrRef() as it is no more
3061 * \throw If \a this->getNumberOfComponents() != 1.
3063 * \sa DataArrayDouble::findIdsNotInRange
3065 * \if ENABLE_EXAMPLES
3066 * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3067 * \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3070 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3073 if(getNumberOfComponents()!=1)
3074 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3075 const double *cptr(begin());
3076 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3077 int nbOfTuples(getNumberOfTuples());
3078 for(int i=0;i<nbOfTuples;i++,cptr++)
3079 if(*cptr>=vmin && *cptr<=vmax)
3080 ret->pushBackSilent(i);
3085 * Returns a new DataArrayInt containing indices of tuples of \a this one-dimensional
3086 * array whose values are not within a given range. Textual data is not copied.
3087 * \param [in] vmin - a lowest not acceptable value (excluded).
3088 * \param [in] vmax - a greatest not acceptable value (excluded).
3089 * \return DataArrayInt * - the new instance of DataArrayInt.
3090 * The caller is to delete this result array using decrRef() as it is no more
3092 * \throw If \a this->getNumberOfComponents() != 1.
3094 * \sa DataArrayDouble::findIdsInRange
3096 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3099 if(getNumberOfComponents()!=1)
3100 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3101 const double *cptr(begin());
3102 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3103 int nbOfTuples(getNumberOfTuples());
3104 for(int i=0;i<nbOfTuples;i++,cptr++)
3105 if(*cptr<vmin || *cptr>vmax)
3106 ret->pushBackSilent(i);
3111 * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3112 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3113 * the number of component in the result array is same as that of each of given arrays.
3114 * Info on components is copied from the first of the given arrays. Number of components
3115 * in the given arrays must be the same.
3116 * \param [in] a1 - an array to include in the result array.
3117 * \param [in] a2 - another array to include in the result array.
3118 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3119 * The caller is to delete this result array using decrRef() as it is no more
3121 * \throw If both \a a1 and \a a2 are NULL.
3122 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3124 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3126 std::vector<const DataArrayDouble *> tmp(2);
3127 tmp[0]=a1; tmp[1]=a2;
3128 return Aggregate(tmp);
3132 * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3133 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3134 * the number of component in the result array is same as that of each of given arrays.
3135 * Info on components is copied from the first of the given arrays. Number of components
3136 * in the given arrays must be the same.
3137 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3138 * not the object itself.
3139 * \param [in] arr - a sequence of arrays to include in the result array.
3140 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3141 * The caller is to delete this result array using decrRef() as it is no more
3143 * \throw If all arrays within \a arr are NULL.
3144 * \throw If getNumberOfComponents() of arrays within \a arr.
3146 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3148 std::vector<const DataArrayDouble *> a;
3149 for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3153 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3154 std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3155 std::size_t nbOfComp((*it)->getNumberOfComponents());
3156 int nbt=(*it++)->getNumberOfTuples();
3157 for(int i=1;it!=a.end();it++,i++)
3159 if((*it)->getNumberOfComponents()!=nbOfComp)
3160 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3161 nbt+=(*it)->getNumberOfTuples();
3163 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3164 ret->alloc(nbt,nbOfComp);
3165 double *pt=ret->getPointer();
3166 for(it=a.begin();it!=a.end();it++)
3167 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3168 ret->copyStringInfoFrom(*(a[0]));
3173 * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3174 * the i-th tuple of the result array is a sum of products of j-th components of i-th
3175 * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3176 * Info on components and name is copied from the first of the given arrays.
3177 * Number of tuples and components in the given arrays must be the same.
3178 * \param [in] a1 - a given array.
3179 * \param [in] a2 - another given array.
3180 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3181 * The caller is to delete this result array using decrRef() as it is no more
3183 * \throw If either \a a1 or \a a2 is NULL.
3184 * \throw If any given array is not allocated.
3185 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3186 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3188 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3191 throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3192 a1->checkAllocated();
3193 a2->checkAllocated();
3194 std::size_t nbOfComp(a1->getNumberOfComponents());
3195 if(nbOfComp!=a2->getNumberOfComponents())
3196 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3197 std::size_t nbOfTuple(a1->getNumberOfTuples());
3198 if(nbOfTuple!=a2->getNumberOfTuples())
3199 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3200 DataArrayDouble *ret=DataArrayDouble::New();
3201 ret->alloc(nbOfTuple,1);
3202 double *retPtr=ret->getPointer();
3203 const double *a1Ptr=a1->begin(),*a2Ptr(a2->begin());
3204 for(std::size_t i=0;i<nbOfTuple;i++)
3207 for(std::size_t j=0;j<nbOfComp;j++)
3208 sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3211 ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3212 ret->setName(a1->getName());
3217 * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3218 * the i-th tuple of the result array contains 3 components of a vector which is a cross
3219 * product of two vectors defined by the i-th tuples of given arrays.
3220 * Info on components is copied from the first of the given arrays.
3221 * Number of tuples in the given arrays must be the same.
3222 * Number of components in the given arrays must be 3.
3223 * \param [in] a1 - a given array.
3224 * \param [in] a2 - another given array.
3225 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3226 * The caller is to delete this result array using decrRef() as it is no more
3228 * \throw If either \a a1 or \a a2 is NULL.
3229 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3230 * \throw If \a a1->getNumberOfComponents() != 3
3231 * \throw If \a a2->getNumberOfComponents() != 3
3233 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3236 throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3237 std::size_t nbOfComp(a1->getNumberOfComponents());
3238 if(nbOfComp!=a2->getNumberOfComponents())
3239 throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3241 throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3242 std::size_t nbOfTuple(a1->getNumberOfTuples());
3243 if(nbOfTuple!=a2->getNumberOfTuples())
3244 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3245 DataArrayDouble *ret=DataArrayDouble::New();
3246 ret->alloc(nbOfTuple,3);
3247 double *retPtr=ret->getPointer();
3248 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3249 for(std::size_t i=0;i<nbOfTuple;i++)
3251 retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3252 retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3253 retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3255 ret->copyStringInfoFrom(*a1);
3260 * Returns a new DataArrayDouble containing maximal values of two given arrays.
3261 * Info on components is copied from the first of the given arrays.
3262 * Number of tuples and components in the given arrays must be the same.
3263 * \param [in] a1 - an array to compare values with another one.
3264 * \param [in] a2 - another array to compare values with the first one.
3265 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3266 * The caller is to delete this result array using decrRef() as it is no more
3268 * \throw If either \a a1 or \a a2 is NULL.
3269 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3270 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3272 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3275 throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3276 std::size_t nbOfComp(a1->getNumberOfComponents());
3277 if(nbOfComp!=a2->getNumberOfComponents())
3278 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3279 std::size_t nbOfTuple(a1->getNumberOfTuples());
3280 if(nbOfTuple!=a2->getNumberOfTuples())
3281 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3282 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3283 ret->alloc(nbOfTuple,nbOfComp);
3284 double *retPtr(ret->getPointer());
3285 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3286 std::size_t nbElem(nbOfTuple*nbOfComp);
3287 for(std::size_t i=0;i<nbElem;i++)
3288 retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3289 ret->copyStringInfoFrom(*a1);
3294 * Returns a new DataArrayDouble containing minimal values of two given arrays.
3295 * Info on components is copied from the first of the given arrays.
3296 * Number of tuples and components in the given arrays must be the same.
3297 * \param [in] a1 - an array to compare values with another one.
3298 * \param [in] a2 - another array to compare values with the first one.
3299 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3300 * The caller is to delete this result array using decrRef() as it is no more
3302 * \throw If either \a a1 or \a a2 is NULL.
3303 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3304 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3306 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3309 throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3310 std::size_t nbOfComp(a1->getNumberOfComponents());
3311 if(nbOfComp!=a2->getNumberOfComponents())
3312 throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3313 std::size_t nbOfTuple(a1->getNumberOfTuples());
3314 if(nbOfTuple!=a2->getNumberOfTuples())
3315 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3316 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3317 ret->alloc(nbOfTuple,nbOfComp);
3318 double *retPtr(ret->getPointer());
3319 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3320 std::size_t nbElem(nbOfTuple*nbOfComp);
3321 for(std::size_t i=0;i<nbElem;i++)
3322 retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3323 ret->copyStringInfoFrom(*a1);
3328 * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
3331 * \param [in] a1 - an array to pow up.
3332 * \param [in] a2 - another array to sum up.
3333 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3334 * The caller is to delete this result array using decrRef() as it is no more
3336 * \throw If either \a a1 or \a a2 is NULL.
3337 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3338 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
3339 * \throw If there is a negative value in \a a1.
3341 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
3344 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
3345 int nbOfTuple=a1->getNumberOfTuples();
3346 int nbOfTuple2=a2->getNumberOfTuples();
3347 int nbOfComp=a1->getNumberOfComponents();
3348 int nbOfComp2=a2->getNumberOfComponents();
3349 if(nbOfTuple!=nbOfTuple2)
3350 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
3351 if(nbOfComp!=1 || nbOfComp2!=1)
3352 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
3353 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
3354 const double *ptr1(a1->begin()),*ptr2(a2->begin());
3355 double *ptr=ret->getPointer();
3356 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
3360 *ptr=pow(*ptr1,*ptr2);
3364 std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
3365 throw INTERP_KERNEL::Exception(oss.str().c_str());
3372 * Apply pow on values of another DataArrayDouble to values of \a this one.
3374 * \param [in] other - an array to pow to \a this one.
3375 * \throw If \a other is NULL.
3376 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
3377 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
3378 * \throw If there is a negative value in \a this.
3380 void DataArrayDouble::powEqual(const DataArrayDouble *other)
3383 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
3384 int nbOfTuple=getNumberOfTuples();
3385 int nbOfTuple2=other->getNumberOfTuples();
3386 int nbOfComp=getNumberOfComponents();
3387 int nbOfComp2=other->getNumberOfComponents();
3388 if(nbOfTuple!=nbOfTuple2)
3389 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
3390 if(nbOfComp!=1 || nbOfComp2!=1)
3391 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
3392 double *ptr=getPointer();
3393 const double *ptrc=other->begin();
3394 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
3397 *ptr=pow(*ptr,*ptrc);
3400 std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
3401 throw INTERP_KERNEL::Exception(oss.str().c_str());
3408 * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
3409 * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
3410 * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
3412 * \throw if \a this is not allocated.
3413 * \throw if \a this has not exactly one component.
3415 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
3418 if(getNumberOfComponents()!=1)
3419 throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
3420 int nbt(getNumberOfTuples());
3421 std::vector<bool> ret(nbt);
3422 const double *pt(begin());
3423 for(int i=0;i<nbt;i++)
3427 else if(fabs(pt[i]-1.)<eps)
3431 std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
3432 throw INTERP_KERNEL::Exception(oss.str().c_str());
3439 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3442 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
3447 tinyInfo[0]=getNumberOfTuples();
3448 tinyInfo[1]=getNumberOfComponents();
3458 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3461 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
3465 int nbOfCompo=getNumberOfComponents();
3466 tinyInfo.resize(nbOfCompo+1);
3467 tinyInfo[0]=getName();
3468 for(int i=0;i<nbOfCompo;i++)
3469 tinyInfo[i+1]=getInfoOnComponent(i);
3474 tinyInfo[0]=getName();
3479 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3480 * This method returns if a feeding is needed.
3482 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
3484 int nbOfTuple=tinyInfoI[0];
3485 int nbOfComp=tinyInfoI[1];
3486 if(nbOfTuple!=-1 || nbOfComp!=-1)
3488 alloc(nbOfTuple,nbOfComp);
3495 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3497 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
3499 setName(tinyInfoS[0]);
3502 int nbOfCompo=getNumberOfComponents();
3503 for(int i=0;i<nbOfCompo;i++)
3504 setInfoOnComponent(i,tinyInfoS[i+1]);
3509 * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
3510 * around an axe ( \a center, \a vect) and with angle \a angle.
3512 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3514 if(!center || !vect)
3515 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
3516 double sina(sin(angle));
3517 double cosa(cos(angle));
3518 double vectorNorm[3];
3520 double matrixTmp[9];
3521 double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
3522 if(norm<std::numeric_limits<double>::min())
3523 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
3524 std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
3525 //rotation matrix computation
3526 matrix[0]=cosa; matrix[1]=0.; matrix[2]=0.; matrix[3]=0.; matrix[4]=cosa; matrix[5]=0.; matrix[6]=0.; matrix[7]=0.; matrix[8]=cosa;
3527 matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
3528 matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
3529 matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
3530 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
3531 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3532 matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
3533 matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
3534 matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
3535 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
3536 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3537 //rotation matrix computed.
3539 for(int i=0; i<nbNodes; i++)
3541 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
3542 coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
3543 coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
3544 coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
3548 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
3550 double matrix[9],matrix2[9],matrix3[9];
3551 double vect[3],crossVect[3];
3552 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3553 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3554 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3555 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3556 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3557 matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
3558 matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
3559 matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
3560 matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
3561 matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
3562 matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
3563 for(int i=0;i<3;i++)
3564 for(int j=0;j<3;j++)
3567 for(int k=0;k<3;k++)
3568 val+=matrix[3*i+k]*matrix2[3*k+j];
3571 //rotation matrix computed.
3573 for(int i=0; i<nbNodes; i++)
3575 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
3576 coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
3577 coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
3578 coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
3582 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
3584 double vect[3],crossVect[3];
3585 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3586 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3587 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3588 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3589 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3590 baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
3591 baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
3592 baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
3596 * \param [in] seg2 : coordinates of input seg2 expected to have spacedim==2
3597 * \param [in] tri3 : coordinates of input tri3 also expected to have spacedim==2
3598 * \param [out] coeffs : the result of integration normalized to 1. along \a seg2 inside tri3 sorted by the node id of \a tri3
3599 * \param [out] length : the length of seg2. That is too say the length of integration
3601 void DataArrayDouble::ComputeIntegralOfSeg2IntoTri3(const double seg2[4], const double tri3[6], double coeffs[3], double& length)
3603 length=INTERP_KERNEL::norme_vecteur(seg2,seg2+2);
3605 INTERP_KERNEL::mid_of_seg2(seg2,seg2+2,mid);
3606 INTERP_KERNEL::barycentric_coords<2>(tri3,mid,coeffs); // integral along seg2 is equal to value at the center of SEG2 !
3610 * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
3611 * around the center point \a center and with angle \a angle.
3613 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3615 double cosa=cos(angle);
3616 double sina=sin(angle);
3618 matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
3620 for(int i=0; i<nbNodes; i++)
3622 std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
3623 coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
3624 coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
3628 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
3632 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
3637 std::string DataArrayDoubleTuple::repr() const
3639 std::ostringstream oss; oss.precision(17); oss << "(";
3640 for(int i=0;i<_nb_of_compo-1;i++)
3641 oss << _pt[i] << ", ";
3642 oss << _pt[_nb_of_compo-1] << ")";
3646 double DataArrayDoubleTuple::doubleValue() const
3648 return this->zeValue();
3652 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
3653 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
3654 * This method throws an INTERP_KERNEL::Exception is it is impossible to match sizes of \b this that is too say \b nbOfCompo=this->_nb_of_elem and \bnbOfTuples==1 or
3655 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
3657 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
3659 return this->buildDA(nbOfTuples,nbOfCompo);
3663 * Returns the only one value in \a this, if and only if number of elements
3664 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3665 * \return double - the sole value stored in \a this array.
3666 * \throw If at least one of conditions stated above is not fulfilled.
3668 int DataArrayInt::intValue() const
3672 if(getNbOfElems()==1)
3674 return *getConstPointer();
3677 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3680 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3684 * Returns a full copy of \a this. For more info on copying data arrays see
3685 * \ref MEDCouplingArrayBasicsCopyDeep.
3686 * \return DataArrayInt * - a new instance of DataArrayInt.
3688 DataArrayInt32 *DataArrayInt32::deepCopy() const
3690 return new DataArrayInt32(*this);
3694 * Computes distribution of values of \a this one-dimensional array between given value
3695 * ranges (casts). This method is typically useful for entity number splitting by types,
3697 * \warning The values contained in \a arrBg should be sorted ascendently. No
3698 * check of this is be done. If not, the result is not warranted.
3699 * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
3700 * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
3701 * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
3702 * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
3703 * should be more than every value in \a this array.
3704 * \param [in] arrEnd - specifies the end of the array \a arrBg, so that
3705 * the last value of \a arrBg is \a arrEnd[ -1 ].
3706 * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
3707 * (same number of tuples and components), the caller is to delete
3708 * using decrRef() as it is no more needed.
3709 * This array contains indices of ranges for every value of \a this array. I.e.
3710 * the i-th value of \a castArr gives the index of range the i-th value of \a this
3711 * belongs to. Or, in other words, this parameter contains for each tuple in \a
3712 * this in which cast it holds.
3713 * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
3714 * array, the caller is to delete using decrRef() as it is no more needed.
3715 * This array contains ranks of values of \a this array within ranges
3716 * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
3717 * the i-th value of \a this array within the \a castArr[ i ]-th range, to which
3718 * the i-th value of \a this belongs to. Or, in other words, this param contains
3719 * for each tuple its rank inside its cast. The rank is computed as difference
3720 * between the value and the lowest value of range.
3721 * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
3722 * ranges (casts) to which at least one value of \a this array belongs.
3723 * Or, in other words, this param contains the casts that \a this contains.
3724 * The caller is to delete this array using decrRef() as it is no more needed.
3726 * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
3727 * the output of this method will be :
3728 * - \a castArr : [1,1,0,0,0,1,1,0,1]
3729 * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
3730 * - \a castsPresent : [0,1]
3732 * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
3733 * range #1 and its rank within this range is 2; etc.
3735 * \throw If \a this->getNumberOfComponents() != 1.
3736 * \throw If \a arrEnd - arrBg < 2.
3737 * \throw If any value of \a this is not less than \a arrEnd[-1].
3739 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
3740 DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
3743 if(getNumberOfComponents()!=1)
3744 throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3745 int nbOfTuples=getNumberOfTuples();
3746 std::size_t nbOfCast=std::distance(arrBg,arrEnd);
3748 throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
3750 const int *work=getConstPointer();
3751 typedef std::reverse_iterator<const int *> rintstart;
3752 rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
3753 rintstart end2(arrBg);
3754 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
3755 MCAuto<DataArrayInt> ret2=DataArrayInt::New();
3756 MCAuto<DataArrayInt> ret3=DataArrayInt::New();
3757 ret1->alloc(nbOfTuples,1);
3758 ret2->alloc(nbOfTuples,1);
3759 int *ret1Ptr=ret1->getPointer();
3760 int *ret2Ptr=ret2->getPointer();
3761 std::set<std::size_t> castsDetected;
3762 for(int i=0;i<nbOfTuples;i++)
3764 rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
3765 std::size_t pos=std::distance(bg,res);
3766 std::size_t pos2=nbOfCast-pos;
3769 ret1Ptr[i]=(int)pos2;
3770 ret2Ptr[i]=work[i]-arrBg[pos2];
3771 castsDetected.insert(pos2);
3775 std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
3776 throw INTERP_KERNEL::Exception(oss.str().c_str());
3779 ret3->alloc((int)castsDetected.size(),1);
3780 std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
3781 castArr=ret1.retn();
3782 rankInsideCast=ret2.retn();
3783 castsPresent=ret3.retn();
3787 * 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 ).
3788 * 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 ).
3789 * This method works only if \a this is allocated and single component. If not an exception will be thrown.
3791 * \param [out] strt - the start of the range (included) if true is returned.
3792 * \param [out] sttoopp - the end of the range (not included) if true is returned.
3793 * \param [out] stteepp - the step of the range if true is returned.
3794 * \return the verdict of the check.
3796 * \sa DataArray::GetNumberOfItemGivenBES
3798 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
3801 if(getNumberOfComponents()!=1)
3802 throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
3803 int nbTuples(getNumberOfTuples());
3805 { strt=0; sttoopp=0; stteepp=1; return true; }
3806 const int *pt(begin());
3809 { sttoopp=strt+1; stteepp=1; return true; }
3810 strt=*pt; sttoopp=pt[nbTuples-1];
3816 int a(sttoopp-1-strt),tmp(strt);
3817 if(a%(nbTuples-1)!=0)
3819 stteepp=a/(nbTuples-1);
3820 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
3828 int a(strt-sttoopp-1),tmp(strt);
3829 if(a%(nbTuples-1)!=0)
3831 stteepp=-(a/(nbTuples-1));
3832 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
3840 * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from
3841 * values of \a this (\a a) and the given (\a indArr) arrays as follows:
3842 * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
3843 * new value in place \a indArr[ \a v ] is i.
3844 * \param [in] indArrBg - the array holding indices within the result array to assign
3845 * indices of values of \a this array pointing to values of \a indArrBg.
3846 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
3847 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
3848 * \return DataArrayInt * - the new instance of DataArrayInt.
3849 * The caller is to delete this result array using decrRef() as it is no more
3851 * \throw If \a this->getNumberOfComponents() != 1.
3852 * \throw If any value of \a this array is not a valid index for \a indArrBg array.
3853 * \throw If any value of \a indArrBg is not a valid index for \a this array.
3855 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
3858 if(getNumberOfComponents()!=1)
3859 throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3860 int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
3861 int nbOfTuples=getNumberOfTuples();
3862 const int *pt=getConstPointer();
3863 MCAuto<DataArrayInt> ret=DataArrayInt::New();
3864 ret->alloc(nbOfTuples,1);
3865 ret->fillWithValue(-1);
3866 int *tmp=ret->getPointer();
3867 for(int i=0;i<nbOfTuples;i++,pt++)
3869 if(*pt>=0 && *pt<nbElemsIn)
3871 int pos=indArrBg[*pt];
3872 if(pos>=0 && pos<nbOfTuples)
3876 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
3877 throw INTERP_KERNEL::Exception(oss.str().c_str());
3882 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
3883 throw INTERP_KERNEL::Exception(oss.str().c_str());
3890 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
3891 * from values of \a this array, which is supposed to contain a renumbering map in
3892 * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
3893 * To know how to use the renumbering maps see \ref numbering.
3894 * \param [in] newNbOfElem - the number of tuples in the result array.
3895 * \return DataArrayInt * - the new instance of DataArrayInt.
3896 * The caller is to delete this result array using decrRef() as it is no more
3899 * \if ENABLE_EXAMPLES
3900 * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
3901 * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
3904 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
3906 MCAuto<DataArrayInt> ret(DataArrayInt::New());
3907 ret->alloc(newNbOfElem,1);
3908 int nbOfOldNodes(this->getNumberOfTuples());
3909 const int *old2New(begin());
3910 int *pt(ret->getPointer());
3911 for(int i=0;i!=nbOfOldNodes;i++)
3913 int newp(old2New[i]);
3916 if(newp>=0 && newp<newNbOfElem)
3920 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
3921 throw INTERP_KERNEL::Exception(oss.str().c_str());
3929 * This method is similar to DataArrayInt::invertArrayO2N2N2O except that
3930 * Example : If \a this contains [0,1,2,0,3,4,5,4,6,4] this method will return [0,1,2,4,5,6,8] whereas DataArrayInt::invertArrayO2N2N2O returns [3,1,2,4,9,6,8]
3932 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
3934 MCAuto<DataArrayInt> ret=DataArrayInt::New();
3935 ret->alloc(newNbOfElem,1);
3936 int nbOfOldNodes=getNumberOfTuples();
3937 const int *old2New=getConstPointer();
3938 int *pt=ret->getPointer();
3939 for(int i=nbOfOldNodes-1;i>=0;i--)
3941 int newp(old2New[i]);
3944 if(newp>=0 && newp<newNbOfElem)
3948 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
3949 throw INTERP_KERNEL::Exception(oss.str().c_str());
3957 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
3958 * from values of \a this array, which is supposed to contain a renumbering map in
3959 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
3960 * To know how to use the renumbering maps see \ref numbering.
3961 * \param [in] newNbOfElem - the number of tuples in the result array.
3962 * \return DataArrayInt * - the new instance of DataArrayInt.
3963 * The caller is to delete this result array using decrRef() as it is no more
3966 * \if ENABLE_EXAMPLES
3967 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
3969 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
3970 * \sa invertArrayN2O2O2NOptimized
3973 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
3976 MCAuto<DataArrayInt> ret=DataArrayInt::New();
3977 ret->alloc(oldNbOfElem,1);
3978 const int *new2Old=getConstPointer();
3979 int *pt=ret->getPointer();
3980 std::fill(pt,pt+oldNbOfElem,-1);
3981 int nbOfNewElems=getNumberOfTuples();
3982 for(int i=0;i<nbOfNewElems;i++)
3985 if(v>=0 && v<oldNbOfElem)
3989 std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
3990 throw INTERP_KERNEL::Exception(oss.str().c_str());
3997 * Creates a map, whose contents are computed
3998 * from values of \a this array, which is supposed to contain a renumbering map in
3999 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4000 * To know how to use the renumbering maps see \ref numbering.
4001 * \param [in] newNbOfElem - the number of tuples in the result array.
4002 * \return MapII - the new instance of Map.
4004 * \if ENABLE_EXAMPLES
4005 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4007 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4008 * \sa invertArrayN2O2O2N, giveN2OOptimized, MEDCouplingPointSet::renumberNodesInConn
4011 MCAuto< MapKeyVal<int> > DataArrayInt32::invertArrayN2O2O2NOptimized() const
4014 if(getNumberOfComponents()!=1)
4015 throw INTERP_KERNEL::Exception("DataArrayInt32::invertArrayN2O2O2NOptimized : single component expected !");
4016 MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4017 std::map<int,int>& m(ret->data());
4018 const int *new2Old(begin());
4019 std::size_t nbOfNewElems(this->getNumberOfTuples());
4020 for(std::size_t i=0;i<nbOfNewElems;i++)
4029 * Creates a map, whose contents are computed
4030 * from values of \a this array, which is supposed to contain a renumbering map in
4031 * "New to Old" mode. The result array contains a renumbering map in "New to Old" mode as C++ map for performance reasons.
4033 * \sa invertArrayN2O2O2NOptimized, MEDCouplingPointSet::renumberNodesInConn
4035 MCAuto< MapKeyVal<int> > DataArrayInt32::giveN2OOptimized() const
4038 if(getNumberOfComponents()!=1)
4039 throw INTERP_KERNEL::Exception("DataArrayInt32::giveN2OOptimized : single component expected !");
4040 MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4041 std::map<int,int>& m(ret->data());
4042 const int *new2Old(begin());
4043 std::size_t nbOfNewElems(this->getNumberOfTuples());
4044 for(std::size_t i=0;i<nbOfNewElems;i++)
4053 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4054 * This map, if applied to \a this array, would make it sorted. For example, if
4055 * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4056 * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4057 * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4058 * This method is useful for renumbering (in MED file for example). For more info
4059 * on renumbering see \ref numbering.
4060 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4061 * array using decrRef() as it is no more needed.
4062 * \throw If \a this is not allocated.
4063 * \throw If \a this->getNumberOfComponents() != 1.
4064 * \throw If there are equal values in \a this array.
4066 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
4069 if(getNumberOfComponents()!=1)
4070 throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4071 int nbTuples=getNumberOfTuples();
4072 const int *pt=getConstPointer();
4073 int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
4074 DataArrayInt *ret=DataArrayInt::New();
4075 ret->useArray(pt2,true,DeallocType::C_DEALLOC,nbTuples,1);
4080 * This method tries to find the permutation to apply to the first input \a ids1 to obtain the same array (without considering strings information) the second
4081 * input array \a ids2.
4082 * \a ids1 and \a ids2 are expected to be both a list of ids (both with number of components equal to one) not sorted and with values that can be negative.
4083 * This method will throw an exception is no such permutation array can be obtained. It is typically the case if there is some ids in \a ids1 not in \a ids2 or
4085 * In case of success both assertion will be true (no throw) :
4086 * \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
4087 * \c ret->transformWithIndArr(ids2)->isEqual(ids1)
4090 * - \a ids1 : [3,1,103,4,6,10,-7,205]
4091 * - \a ids2 : [-7,1,205,10,6,3,103,4]
4092 * - \a return is : [5,1,6,7,4,3,0,2] because ids2[5]==ids1[0], ids2[1]==ids1[1], ids2[6]==ids1[2]...
4094 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4095 * array using decrRef() as it is no more needed.
4096 * \throw If either ids1 or ids2 is null not allocated or not with one components.
4098 * \sa DataArrayInt32::findIdForEach
4100 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
4103 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
4104 if(!ids1->isAllocated() || !ids2->isAllocated())
4105 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
4106 if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
4107 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
4108 if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
4110 std::ostringstream oss; oss << "DataArrayInt::FindPermutationFromFirstToSecond : first array has " << ids1->getNumberOfTuples() << " tuples and the second one " << ids2->getNumberOfTuples() << " tuples ! No chance to find a permutation between the 2 arrays !";
4111 throw INTERP_KERNEL::Exception(oss.str().c_str());
4113 MCAuto<DataArrayInt> p1(ids1->deepCopy());
4114 MCAuto<DataArrayInt> p2(ids2->deepCopy());
4115 p1->sort(true); p2->sort(true);
4116 if(!p1->isEqualWithoutConsideringStr(*p2))
4117 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
4118 p1=ids1->checkAndPreparePermutation();
4119 p2=ids2->checkAndPreparePermutation();
4120 p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
4121 p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
4126 * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4127 * onto a set of values of size \a targetNb (\a B). The surjective function is
4128 * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4129 * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4130 * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4131 * The first of out arrays returns indices of elements of \a this array, grouped by their
4132 * place in the set \a B. The second out array is the index of the first one; it shows how
4133 * many elements of \a A are mapped into each element of \a B. <br>
4135 * mapping and its usage in renumbering see \ref numbering. <br>
4137 * - \a this: [0,3,2,3,2,2,1,2]
4139 * - \a arr: [0, 6, 2,4,5,7, 1,3]
4140 * - \a arrI: [0,1,2,6,8]
4142 * This result means: <br>
4143 * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4144 * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4145 * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4146 * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] :
4147 * \a arrI[ 2+1 ]]); <br> etc.
4148 * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4149 * than the maximal value of \a A.
4150 * \param [out] arr - a new instance of DataArrayInt returning indices of
4151 * elements of \a this, grouped by their place in the set \a B. The caller is to delete
4152 * this array using decrRef() as it is no more needed.
4153 * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4154 * elements of \a this. The caller is to delete this array using decrRef() as it
4155 * is no more needed.
4156 * \throw If \a this is not allocated.
4157 * \throw If \a this->getNumberOfComponents() != 1.
4158 * \throw If any value in \a this is more or equal to \a targetNb.
4160 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
4163 if(getNumberOfComponents()!=1)
4164 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4165 int nbOfTuples=getNumberOfTuples();
4166 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4167 MCAuto<DataArrayInt> retI(DataArrayInt::New());
4168 retI->alloc(targetNb+1,1);
4169 const int *input=getConstPointer();
4170 std::vector< std::vector<int> > tmp(targetNb);
4171 for(int i=0;i<nbOfTuples;i++)
4174 if(tmp2>=0 && tmp2<targetNb)
4175 tmp[tmp2].push_back(i);
4178 std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4179 throw INTERP_KERNEL::Exception(oss.str().c_str());
4182 int *retIPtr=retI->getPointer();
4184 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4185 retIPtr[1]=retIPtr[0]+(int)((*it1).size());
4186 if(nbOfTuples!=retI->getIJ(targetNb,0))
4187 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4188 ret->alloc(nbOfTuples,1);
4189 int *retPtr=ret->getPointer();
4190 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4191 retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4198 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
4199 * from a zip representation of a surjective format (returned e.g. by
4200 * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
4201 * for example). The result array minimizes the permutation. <br>
4202 * For more info on renumbering see \ref numbering. <br>
4204 * - \a nbOfOldTuples: 10
4205 * - \a arr : [0,3, 5,7,9]
4206 * - \a arrIBg : [0,2,5]
4207 * - \a newNbOfTuples: 7
4208 * - result array : [0,1,2,0,3,4,5,4,6,4]
4210 * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
4211 * \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
4212 * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
4213 * (indices of) equal values. Its every element (except the last one) points to
4214 * the first element of a group of equal values.
4215 * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
4216 * arrIBg is \a arrIEnd[ -1 ].
4217 * \param [out] newNbOfTuples - number of tuples after surjection application.
4218 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4219 * array using decrRef() as it is no more needed.
4220 * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
4222 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
4224 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4225 ret->alloc(nbOfOldTuples,1);
4226 int *pt=ret->getPointer();
4227 std::fill(pt,pt+nbOfOldTuples,-1);
4228 int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
4229 const int *cIPtr=arrIBg;
4230 for(int i=0;i<nbOfGrps;i++)
4231 pt[arr[cIPtr[i]]]=-(i+2);
4233 for(int iNode=0;iNode<nbOfOldTuples;iNode++)
4241 int grpId=-(pt[iNode]+2);
4242 for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
4244 if(arr[j]>=0 && arr[j]<nbOfOldTuples)
4248 std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
4249 throw INTERP_KERNEL::Exception(oss.str().c_str());
4256 newNbOfTuples=newNb;
4261 * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4262 * which if applied to \a this array would make it sorted ascendingly.
4263 * For more info on renumbering see \ref numbering. <br>
4265 * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4266 * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4267 * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2]
4269 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4270 * array using decrRef() as it is no more needed.
4271 * \throw If \a this is not allocated.
4272 * \throw If \a this->getNumberOfComponents() != 1.
4274 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
4277 if(getNumberOfComponents()!=1)
4278 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4279 int nbOfTuples=getNumberOfTuples();
4280 const int *pt=getConstPointer();
4281 std::map<int,int> m;
4282 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4283 ret->alloc(nbOfTuples,1);
4284 int *opt=ret->getPointer();
4285 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4288 std::map<int,int>::iterator it=m.find(val);
4297 m.insert(std::pair<int,int>(val,1));
4301 for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
4303 int vt=(*it).second;
4307 pt=getConstPointer();
4308 opt=ret->getPointer();
4309 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4316 * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4317 * iota(). This method is particularly useful for DataArrayInt instances that represent
4318 * a renumbering array, to check if there is a real need in renumbering.
4319 * This method checks than \a this can be considered as an identity mapping
4320 * of a set having \a sizeExpected elements into itself.
4322 * \param [in] sizeExpected - The number of elements expected.
4323 * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4324 * \throw If \a this is not allocated.
4325 * \throw If \a this->getNumberOfComponents() != 1.
4327 bool DataArrayInt::isIota(int sizeExpected) const
4330 if(getNumberOfComponents()!=1)
4332 int nbOfTuples(getNumberOfTuples());
4333 if(nbOfTuples!=sizeExpected)
4335 const int *pt=getConstPointer();
4336 for(int i=0;i<nbOfTuples;i++,pt++)
4343 * Checks if all values in \a this array are equal to \a val.
4344 * \param [in] val - value to check equality of array values to.
4345 * \return bool - \a true if all values are \a val.
4346 * \throw If \a this is not allocated.
4347 * \throw If \a this->getNumberOfComponents() != 1
4348 * \sa DataArrayInt::checkUniformAndGuess
4350 bool DataArrayInt::isUniform(int val) const
4353 if(getNumberOfComponents()!=1)
4354 throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4355 const int *w(begin()),*end2(end());
4363 * This method checks that \a this is uniform. If not and exception will be thrown.
4364 * In case of uniformity the corresponding value is returned.
4366 * \return int - the unique value contained in this
4367 * \throw If \a this is not allocated.
4368 * \throw If \a this->getNumberOfComponents() != 1
4369 * \throw If \a this is not uniform.
4370 * \sa DataArrayInt::isUniform
4372 int DataArrayInt::checkUniformAndGuess() const
4375 if(getNumberOfComponents()!=1)
4376 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4378 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
4379 const int *w(begin()),*end2(end());
4383 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
4388 * Checks if all values in \a this array are unique.
4389 * \return bool - \a true if condition above is true
4390 * \throw If \a this is not allocated.
4391 * \throw If \a this->getNumberOfComponents() != 1
4393 bool DataArrayInt::hasUniqueValues() const
4396 if(getNumberOfComponents()!=1)
4397 throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4398 std::size_t nbOfTuples(getNumberOfTuples());
4399 std::set<int> s(begin(),end()); // in C++11, should use unordered_set (O(1) complexity)
4400 if (s.size() != nbOfTuples)
4406 * Copy all components in a specified order from another DataArrayInt.
4407 * The specified components become the first ones in \a this array.
4408 * Both numerical and textual data is copied. The number of tuples in \a this and
4409 * the other array can be different.
4410 * \param [in] a - the array to copy data from.
4411 * \param [in] compoIds - sequence of zero based indices of components, data of which is
4413 * \throw If \a a is NULL.
4414 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
4415 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
4417 * \if ENABLE_EXAMPLES
4418 * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
4421 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
4424 throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
4426 a->checkAllocated();
4427 copyPartOfStringInfoFrom2(compoIds,*a);
4428 std::size_t partOfCompoSz=compoIds.size();
4429 int nbOfCompo=getNumberOfComponents();
4430 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
4431 const int *ac=a->getConstPointer();
4432 int *nc=getPointer();
4433 for(int i=0;i<nbOfTuples;i++)
4434 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
4435 nc[nbOfCompo*i+compoIds[j]]=*ac;
4438 DataArrayIntIterator *DataArrayInt::iterator()
4440 return new DataArrayIntIterator(this);
4444 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
4445 * given one. The ids are sorted in the ascending order.
4446 * \param [in] val - the value to find within \a this.
4447 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4448 * array using decrRef() as it is no more needed.
4449 * \throw If \a this is not allocated.
4450 * \throw If \a this->getNumberOfComponents() != 1.
4451 * \sa DataArrayInt::findIdsEqualTuple
4453 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
4456 if(getNumberOfComponents()!=1)
4457 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
4458 const int *cptr(getConstPointer());
4459 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4460 int nbOfTuples=getNumberOfTuples();
4461 for(int i=0;i<nbOfTuples;i++,cptr++)
4463 ret->pushBackSilent(i);
4468 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
4469 * equal to a given one.
4470 * \param [in] val - the value to ignore within \a this.
4471 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4472 * array using decrRef() as it is no more needed.
4473 * \throw If \a this is not allocated.
4474 * \throw If \a this->getNumberOfComponents() != 1.
4476 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
4479 if(getNumberOfComponents()!=1)
4480 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
4481 const int *cptr(getConstPointer());
4482 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4483 int nbOfTuples=getNumberOfTuples();
4484 for(int i=0;i<nbOfTuples;i++,cptr++)
4486 ret->pushBackSilent(i);
4491 * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
4492 * This method is an extension of DataArrayInt::findIdsEqual method.
4494 * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
4495 * \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
4496 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4497 * array using decrRef() as it is no more needed.
4498 * \throw If \a this is not allocated.
4499 * \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
4500 * \throw If \a this->getNumberOfComponents() is equal to 0.
4501 * \sa DataArrayInt::findIdsEqual
4503 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
4505 std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
4507 if(getNumberOfComponents()!=nbOfCompoExp)
4509 std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
4510 throw INTERP_KERNEL::Exception(oss.str().c_str());
4513 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
4514 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4515 const int *bg(begin()),*end2(end()),*work(begin());
4518 work=std::search(work,end2,tupleBg,tupleEnd);
4521 std::size_t pos(std::distance(bg,work));
4522 if(pos%nbOfCompoExp==0)
4523 ret->pushBackSilent(pos/nbOfCompoExp);
4531 * This method finds for each element \a ELT in [valsBg,valsEnd) elements in \a this equal to it. Associated to ELT
4532 * this method will return the tuple id of last element found. If there is no element in \a this equal to ELT
4533 * an exception will be thrown.
4535 * In case of success this[ret]==vals. Samely ret->transformWithIndArr(this->begin(),this->end())==vals.
4536 * Where \a vals is the [valsBg,valsEnd) array and \a ret the array returned by this method.
4537 * This method can be seen as an extension of FindPermutationFromFirstToSecond.
4540 * - \a this: [17,27,2,10,-4,3,12,27,16]
4541 * - \a val : [3,16,-4,27,17]
4542 * - result: [5,8,4,7,0]
4544 * \return - An array of size std::distance(valsBg,valsEnd)
4546 * \sa DataArrayInt32::FindPermutationFromFirstToSecond
4548 MCAuto<DataArrayInt32> DataArrayInt32::findIdForEach(const int *valsBg, const int *valsEnd) const
4550 MCAuto<DataArrayInt32> ret(DataArrayInt32::New());
4551 std::size_t nbOfTuplesOut(std::distance(valsBg,valsEnd));
4552 ret->alloc(nbOfTuplesOut,1);
4553 MCAuto< MapKeyVal<int> > zeMap(invertArrayN2O2O2NOptimized());
4554 const std::map<int,int>& dat(zeMap->data());
4555 int *ptToFeed(ret->getPointer());
4556 for(const int *pt=valsBg;pt!=valsEnd;pt++)
4558 std::map<int,int>::const_iterator it(dat.find(*pt));
4560 *ptToFeed++=(*it).second;
4563 std::ostringstream oss; oss << "DataArrayInt32::findIdForEach : error for element at place " << std::distance(valsBg,pt);
4564 oss << " of input array value is " << *pt << " which is not in this !";
4565 throw INTERP_KERNEL::Exception(oss.str());
4572 * Assigns \a newValue to all elements holding \a oldValue within \a this
4573 * one-dimensional array.
4574 * \param [in] oldValue - the value to replace.
4575 * \param [in] newValue - the value to assign.
4576 * \return int - number of replacements performed.
4577 * \throw If \a this is not allocated.
4578 * \throw If \a this->getNumberOfComponents() != 1.
4580 int DataArrayInt::changeValue(int oldValue, int newValue)
4583 if(getNumberOfComponents()!=1)
4584 throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
4585 if(oldValue==newValue)
4587 int *start(getPointer()),*end2(start+getNbOfElems());
4589 for(int *val=start;val!=end2;val++)
4603 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
4604 * one of given values.
4605 * \param [in] valsBg - an array of values to find within \a this array.
4606 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4607 * the last value of \a valsBg is \a valsEnd[ -1 ].
4608 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4609 * array using decrRef() as it is no more needed.
4610 * \throw If \a this->getNumberOfComponents() != 1.
4612 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
4614 if(getNumberOfComponents()!=1)
4615 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
4616 std::set<int> vals2(valsBg,valsEnd);
4617 const int *cptr(getConstPointer());
4618 std::vector<int> res;
4619 int nbOfTuples(getNumberOfTuples());
4620 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4621 for(int i=0;i<nbOfTuples;i++,cptr++)
4622 if(vals2.find(*cptr)!=vals2.end())
4623 ret->pushBackSilent(i);
4628 * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
4629 * equal to any of given values.
4630 * \param [in] valsBg - an array of values to ignore within \a this array.
4631 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4632 * the last value of \a valsBg is \a valsEnd[ -1 ].
4633 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4634 * array using decrRef() as it is no more needed.
4635 * \throw If \a this->getNumberOfComponents() != 1.
4637 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
4639 if(getNumberOfComponents()!=1)
4640 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
4641 std::set<int> vals2(valsBg,valsEnd);
4642 const int *cptr=getConstPointer();
4643 std::vector<int> res;
4644 int nbOfTuples=getNumberOfTuples();
4645 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4646 for(int i=0;i<nbOfTuples;i++,cptr++)
4647 if(vals2.find(*cptr)==vals2.end())
4648 ret->pushBackSilent(i);
4653 * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
4654 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4655 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4656 * If any the tuple id is returned. If not -1 is returned.
4658 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4659 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4661 * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
4662 * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
4664 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
4667 int nbOfCompo=getNumberOfComponents();
4669 throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
4670 if(nbOfCompo!=(int)tupl.size())
4672 std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
4673 throw INTERP_KERNEL::Exception(oss.str().c_str());
4675 const int *cptr=getConstPointer();
4676 std::size_t nbOfVals=getNbOfElems();
4677 for(const int *work=cptr;work!=cptr+nbOfVals;)
4679 work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
4680 if(work!=cptr+nbOfVals)
4682 if(std::distance(cptr,work)%nbOfCompo!=0)
4685 return std::distance(cptr,work)/nbOfCompo;
4692 * This method searches the sequence specified in input parameter \b vals in \b this.
4693 * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
4694 * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
4695 * \sa DataArrayInt::findIdFirstEqualTuple
4697 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
4700 int nbOfCompo=getNumberOfComponents();
4702 throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
4703 const int *cptr=getConstPointer();
4704 std::size_t nbOfVals=getNbOfElems();
4705 const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
4706 if(loc!=cptr+nbOfVals)
4707 return std::distance(cptr,loc);
4712 * This method expects to be called when number of components of this is equal to one.
4713 * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
4714 * If not any tuple contains \b value -1 is returned.
4715 * \sa DataArrayInt::presenceOfValue
4717 int DataArrayInt::findIdFirstEqual(int value) const
4720 if(getNumberOfComponents()!=1)
4721 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4722 const int *cptr=getConstPointer();
4723 int nbOfTuples=getNumberOfTuples();
4724 const int *ret=std::find(cptr,cptr+nbOfTuples,value);
4725 if(ret!=cptr+nbOfTuples)
4726 return std::distance(cptr,ret);
4731 * This method expects to be called when number of components of this is equal to one.
4732 * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
4733 * If not any tuple contains one of the values contained in 'vals' -1 is returned.
4734 * \sa DataArrayInt::presenceOfValue
4736 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
4739 if(getNumberOfComponents()!=1)
4740 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4741 std::set<int> vals2(vals.begin(),vals.end());
4742 const int *cptr=getConstPointer();
4743 int nbOfTuples=getNumberOfTuples();
4744 for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
4745 if(vals2.find(*w)!=vals2.end())
4746 return std::distance(cptr,w);
4751 * This method returns the number of values in \a this that are equals to input parameter \a value.
4752 * This method only works for single component array.
4754 * \return a value in [ 0, \c this->getNumberOfTuples() )
4756 * \throw If \a this is not allocated
4759 int DataArrayInt::count(int value) const
4763 if(getNumberOfComponents()!=1)
4764 throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4765 const int *vals=begin();
4766 int nbOfTuples=getNumberOfTuples();
4767 for(int i=0;i<nbOfTuples;i++,vals++)
4774 * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
4775 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4776 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4777 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4778 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4779 * \sa DataArrayInt::findIdFirstEqualTuple
4781 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
4783 return findIdFirstEqualTuple(tupl)!=-1;
4788 * Returns \a true if a given value is present within \a this one-dimensional array.
4789 * \param [in] value - the value to find within \a this array.
4790 * \return bool - \a true in case if \a value is present within \a this array.
4791 * \throw If \a this is not allocated.
4792 * \throw If \a this->getNumberOfComponents() != 1.
4793 * \sa findIdFirstEqual()
4795 bool DataArrayInt::presenceOfValue(int value) const
4797 return findIdFirstEqual(value)!=-1;
4801 * This method expects to be called when number of components of this is equal to one.
4802 * This method returns true if it exists a tuple so that the value is contained in \b vals.
4803 * If not any tuple contains one of the values contained in 'vals' false is returned.
4804 * \sa DataArrayInt::findIdFirstEqual
4806 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
4808 return findIdFirstEqual(vals)!=-1;
4812 * Accumulates values of each component of \a this array.
4813 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
4814 * by the caller, that is filled by this method with sum value for each
4816 * \throw If \a this is not allocated.
4818 void DataArrayInt::accumulate(int *res) const
4821 const int *ptr=getConstPointer();
4822 int nbTuple=getNumberOfTuples();
4823 int nbComps=getNumberOfComponents();
4824 std::fill(res,res+nbComps,0);
4825 for(int i=0;i<nbTuple;i++)
4826 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
4829 int DataArrayInt::accumulate(int compId) const
4832 const int *ptr=getConstPointer();
4833 int nbTuple=getNumberOfTuples();
4834 int nbComps=getNumberOfComponents();
4835 if(compId<0 || compId>=nbComps)
4836 throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
4838 for(int i=0;i<nbTuple;i++)
4839 ret+=ptr[i*nbComps+compId];
4844 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
4845 * The returned array will have same number of components than \a this and number of tuples equal to
4846 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
4848 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
4850 * \param [in] bgOfIndex - begin (included) of the input index array.
4851 * \param [in] endOfIndex - end (excluded) of the input index array.
4852 * \return DataArrayInt * - the new instance having the same number of components than \a this.
4854 * \throw If bgOfIndex or end is NULL.
4855 * \throw If input index array is not ascendingly sorted.
4856 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
4857 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
4859 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
4861 if(!bgOfIndex || !endOfIndex)
4862 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
4864 int nbCompo=getNumberOfComponents();
4865 int nbOfTuples=getNumberOfTuples();
4866 int sz=(int)std::distance(bgOfIndex,endOfIndex);
4868 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
4870 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
4871 const int *w=bgOfIndex;
4872 if(*w<0 || *w>=nbOfTuples)
4873 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
4874 const int *srcPt=begin()+(*w)*nbCompo;
4875 int *tmp=ret->getPointer();
4876 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
4878 std::fill(tmp,tmp+nbCompo,0);
4881 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
4883 if(j>=0 && j<nbOfTuples)
4884 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
4887 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
4888 throw INTERP_KERNEL::Exception(oss.str().c_str());
4894 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
4895 throw INTERP_KERNEL::Exception(oss.str().c_str());
4898 ret->copyStringInfoFrom(*this);
4903 * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
4904 * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
4905 * offsetA2</em> and (2)
4906 * the number of component in the result array is same as that of each of given arrays.
4907 * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
4908 * Info on components is copied from the first of the given arrays. Number of components
4909 * in the given arrays must be the same.
4910 * \param [in] a1 - an array to include in the result array.
4911 * \param [in] a2 - another array to include in the result array.
4912 * \param [in] offsetA2 - number of tuples of \a a2 to skip.
4913 * \return DataArrayInt * - the new instance of DataArrayInt.
4914 * The caller is to delete this result array using decrRef() as it is no more
4916 * \throw If either \a a1 or \a a2 is NULL.
4917 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4919 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
4922 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
4923 std::size_t nbOfComp(a1->getNumberOfComponents());
4924 if(nbOfComp!=a2->getNumberOfComponents())
4925 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
4926 std::size_t nbOfTuple1(a1->getNumberOfTuples()),nbOfTuple2(a2->getNumberOfTuples());
4927 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4928 ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
4929 int *pt=std::copy(a1->begin(),a1->end(),ret->getPointer());
4930 std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
4931 ret->copyStringInfoFrom(*a1);
4936 * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
4937 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4938 * the number of component in the result array is same as that of each of given arrays.
4939 * Info on components is copied from the first of the given arrays. Number of components
4940 * in the given arrays must be the same.
4941 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
4942 * not the object itself.
4943 * \param [in] arr - a sequence of arrays to include in the result array.
4944 * \return DataArrayInt * - the new instance of DataArrayInt.
4945 * The caller is to delete this result array using decrRef() as it is no more
4947 * \throw If all arrays within \a arr are NULL.
4948 * \throw If getNumberOfComponents() of arrays within \a arr.
4950 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
4952 std::vector<const DataArrayInt *> a;
4953 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4957 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
4958 std::vector<const DataArrayInt *>::const_iterator it=a.begin();
4959 std::size_t nbOfComp((*it)->getNumberOfComponents()),nbt((*it++)->getNumberOfTuples());
4960 for(int i=1;it!=a.end();it++,i++)
4962 if((*it)->getNumberOfComponents()!=nbOfComp)
4963 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
4964 nbt+=(*it)->getNumberOfTuples();
4966 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4967 ret->alloc(nbt,nbOfComp);
4968 int *pt=ret->getPointer();
4969 for(it=a.begin();it!=a.end();it++)
4970 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4971 ret->copyStringInfoFrom(*(a[0]));
4976 * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
4977 * A packed index array is an allocated array with one component, and at least one tuple. The first element
4978 * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
4979 * This method is useful for users that want to aggregate a pair of DataArrayInt representing an indexed data (typically nodal connectivity index in unstructured meshes.
4981 * \return DataArrayInt * - a new object to be managed by the caller.
4983 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
4986 for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
4990 (*it4)->checkAllocated();
4991 if((*it4)->getNumberOfComponents()!=1)
4993 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
4994 throw INTERP_KERNEL::Exception(oss.str().c_str());
4996 int nbTupl=(*it4)->getNumberOfTuples();
4999 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5000 throw INTERP_KERNEL::Exception(oss.str().c_str());
5002 if((*it4)->front()!=0)
5004 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
5005 throw INTERP_KERNEL::Exception(oss.str().c_str());
5011 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
5012 throw INTERP_KERNEL::Exception(oss.str().c_str());
5016 throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
5017 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5018 ret->alloc(retSz,1);
5019 int *pt=ret->getPointer(); *pt++=0;
5020 for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
5021 pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
5022 ret->copyStringInfoFrom(*(arrs[0]));
5027 * Returns in a single walk in \a this the min value and the max value in \a this.
5028 * \a this is expected to be single component array.
5030 * \param [out] minValue - the min value in \a this.
5031 * \param [out] maxValue - the max value in \a this.
5033 * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5035 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
5038 if(getNumberOfComponents()!=1)
5039 throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5040 int nbTuples(getNumberOfTuples());
5041 const int *pt(begin());
5042 minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
5043 for(int i=0;i<nbTuples;i++,pt++)
5053 * Modify all elements of \a this array, so that
5054 * an element _x_ becomes \f$ numerator / x \f$.
5055 * \warning If an exception is thrown because of presence of 0 element in \a this
5056 * array, all elements processed before detection of the zero element remain
5058 * \param [in] numerator - the numerator used to modify array elements.
5059 * \throw If \a this is not allocated.
5060 * \throw If there is an element equal to 0 in \a this array.
5062 void DataArrayInt::applyInv(int numerator)
5065 int *ptr=getPointer();
5066 std::size_t nbOfElems=getNbOfElems();
5067 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5071 *ptr=numerator/(*ptr);
5075 std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5077 throw INTERP_KERNEL::Exception(oss.str().c_str());
5084 * Modify all elements of \a this array, so that
5085 * an element _x_ becomes \f$ x / val \f$.
5086 * \param [in] val - the denominator used to modify array elements.
5087 * \throw If \a this is not allocated.
5088 * \throw If \a val == 0.
5090 void DataArrayInt::applyDivideBy(int val)
5093 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5095 int *ptr=getPointer();
5096 std::size_t nbOfElems=getNbOfElems();
5097 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
5102 * Modify all elements of \a this array, so that
5103 * an element _x_ becomes <em> x % val </em>.
5104 * \param [in] val - the divisor used to modify array elements.
5105 * \throw If \a this is not allocated.
5106 * \throw If \a val <= 0.
5108 void DataArrayInt::applyModulus(int val)
5111 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5113 int *ptr=getPointer();
5114 std::size_t nbOfElems=getNbOfElems();
5115 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
5120 * This method works only on data array with one component.
5121 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5122 * this[*id] in [\b vmin,\b vmax)
5124 * \param [in] vmin begin of range. This value is included in range (included).
5125 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5126 * \return a newly allocated data array that the caller should deal with.
5128 * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5130 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
5132 InRange<int> ir(vmin,vmax);
5133 MCAuto<DataArrayInt> ret(findIdsAdv(ir));
5138 * This method works only on data array with one component.
5139 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5140 * this[*id] \b not in [\b vmin,\b vmax)
5142 * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5143 * \param [in] vmax end of range. This value is included in range (included).
5144 * \return a newly allocated data array that the caller should deal with.
5146 * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5148 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
5150 NotInRange<int> nir(vmin,vmax);
5151 MCAuto<DataArrayInt> ret(findIdsAdv(nir));
5156 * This method works only on data array with one component.
5157 * 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.
5159 * \param [in] vmin begin of range. This value is included in range (included).
5160 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5161 * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5162 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
5165 if(getNumberOfComponents()!=1)
5166 throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5167 int nbOfTuples=getNumberOfTuples();
5169 const int *cptr=getConstPointer();
5170 for(int i=0;i<nbOfTuples;i++,cptr++)
5172 if(*cptr>=vmin && *cptr<vmax)
5173 { ret=ret && *cptr==i; }
5176 std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5177 throw INTERP_KERNEL::Exception(oss.str().c_str());
5184 * Modify all elements of \a this array, so that
5185 * an element _x_ becomes <em> val % x </em>.
5186 * \warning If an exception is thrown because of presence of an element <= 0 in \a this
5187 * array, all elements processed before detection of the zero element remain
5189 * \param [in] val - the divident used to modify array elements.
5190 * \throw If \a this is not allocated.
5191 * \throw If there is an element equal to or less than 0 in \a this array.
5193 void DataArrayInt::applyRModulus(int val)
5196 int *ptr=getPointer();
5197 std::size_t nbOfElems=getNbOfElems();
5198 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5206 std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5208 throw INTERP_KERNEL::Exception(oss.str().c_str());
5215 * Modify all elements of \a this array, so that
5216 * an element _x_ becomes <em> val ^ x </em>.
5217 * \param [in] val - the value used to apply pow on all array elements.
5218 * \throw If \a this is not allocated.
5219 * \throw If \a val < 0.
5221 void DataArrayInt::applyPow(int val)
5225 throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5226 int *ptr=getPointer();
5227 std::size_t nbOfElems=getNbOfElems();
5230 std::fill(ptr,ptr+nbOfElems,1);
5233 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5236 for(int j=0;j<val;j++)
5244 * Modify all elements of \a this array, so that
5245 * an element _x_ becomes \f$ val ^ x \f$.
5246 * \param [in] val - the value used to apply pow on all array elements.
5247 * \throw If \a this is not allocated.
5248 * \throw If there is an element < 0 in \a this array.
5249 * \warning If an exception is thrown because of presence of 0 element in \a this
5250 * array, all elements processed before detection of the zero element remain
5253 void DataArrayInt::applyRPow(int val)
5256 int *ptr=getPointer();
5257 std::size_t nbOfElems=getNbOfElems();
5258 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5263 for(int j=0;j<*ptr;j++)
5269 std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5271 throw INTERP_KERNEL::Exception(oss.str().c_str());
5278 * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
5279 * The i-th item of the result array is an ID of a set of elements belonging to a
5280 * unique set of groups, which the i-th element is a part of. This set of elements
5281 * belonging to a unique set of groups is called \a family, so the result array contains
5282 * IDs of families each element belongs to.
5284 * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
5285 * then there are 3 families:
5286 * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
5287 * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
5288 * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
5289 * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
5290 * stands for the element #3 which is in none of groups.
5292 * \param [in] groups - sequence of groups of element IDs.
5293 * \param [in] newNb - total number of elements; it must be more than max ID of element
5295 * \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
5296 * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
5297 * each element with ID from range [0, \a newNb ) belongs to. The caller is to
5298 * delete this array using decrRef() as it is no more needed.
5299 * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
5301 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
5303 std::vector<const DataArrayInt *> groups2;
5304 for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
5306 groups2.push_back(*it4);
5307 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5308 ret->alloc(newNb,1);
5309 int *retPtr=ret->getPointer();
5310 std::fill(retPtr,retPtr+newNb,0);
5312 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
5314 const int *ptr=(*iter)->getConstPointer();
5315 std::size_t nbOfElem=(*iter)->getNbOfElems();
5317 for(int j=0;j<sfid;j++)
5320 for(std::size_t i=0;i<nbOfElem;i++)
5322 if(ptr[i]>=0 && ptr[i]<newNb)
5324 if(retPtr[ptr[i]]==j)
5332 std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
5334 throw INTERP_KERNEL::Exception(oss.str().c_str());
5341 fidsOfGroups.clear();
5342 fidsOfGroups.resize(groups2.size());
5344 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
5347 const int *ptr=(*iter)->getConstPointer();
5348 std::size_t nbOfElem=(*iter)->getNbOfElems();
5349 for(const int *p=ptr;p!=ptr+nbOfElem;p++)
5350 tmp.insert(retPtr[*p]);
5351 fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
5357 * Returns a new DataArrayInt which contains all elements of given one-dimensional
5358 * arrays. The result array does not contain any duplicates and its values
5359 * are sorted in ascending order.
5360 * \param [in] arr - sequence of DataArrayInt's to unite.
5361 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5362 * array using decrRef() as it is no more needed.
5363 * \throw If any \a arr[i] is not allocated.
5364 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5366 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
5368 std::vector<const DataArrayInt *> a;
5369 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5372 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5374 (*it)->checkAllocated();
5375 if((*it)->getNumberOfComponents()!=1)
5376 throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
5380 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5382 const int *pt=(*it)->getConstPointer();
5383 int nbOfTuples=(*it)->getNumberOfTuples();
5384 r.insert(pt,pt+nbOfTuples);
5386 DataArrayInt *ret=DataArrayInt::New();
5387 ret->alloc((int)r.size(),1);
5388 std::copy(r.begin(),r.end(),ret->getPointer());
5393 * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
5394 * arrays. The result array does not contain any duplicates and its values
5395 * are sorted in ascending order.
5396 * \param [in] arr - sequence of DataArrayInt's to intersect.
5397 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5398 * array using decrRef() as it is no more needed.
5399 * \throw If any \a arr[i] is not allocated.
5400 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5402 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
5404 std::vector<const DataArrayInt *> a;
5405 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5408 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5410 (*it)->checkAllocated();
5411 if((*it)->getNumberOfComponents()!=1)
5412 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
5416 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5418 const int *pt=(*it)->getConstPointer();
5419 int nbOfTuples=(*it)->getNumberOfTuples();
5420 std::set<int> s1(pt,pt+nbOfTuples);
5424 std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
5430 DataArrayInt *ret(DataArrayInt::New());
5431 ret->alloc((int)r.size(),1);
5432 std::copy(r.begin(),r.end(),ret->getPointer());
5437 namespace MEDCouplingImpl
5442 OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
5443 void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
5452 OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
5453 void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
5462 * This method returns the list of ids in ascending mode so that v[id]==true.
5464 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
5466 int sz((int)std::count(v.begin(),v.end(),true));
5467 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5468 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
5473 * This method returns the list of ids in ascending mode so that v[id]==false.
5475 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
5477 int sz((int)std::count(v.begin(),v.end(),false));
5478 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5479 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
5484 * This method allows to put a vector of vector of integer into a more compact data structure (skyline).
5485 * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
5487 * \param [in] v the input data structure to be translate into skyline format.
5488 * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
5489 * \param [out] dataIndex the second element of the skyline format.
5491 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
5493 int sz((int)v.size());
5494 MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
5495 ret1->alloc(sz+1,1);
5496 int *pt(ret1->getPointer()); *pt=0;
5497 for(int i=0;i<sz;i++,pt++)
5498 pt[1]=pt[0]+(int)v[i].size();
5499 ret0->alloc(ret1->back(),1);
5500 pt=ret0->getPointer();
5501 for(int i=0;i<sz;i++)
5502 pt=std::copy(v[i].begin(),v[i].end(),pt);
5503 data=ret0.retn(); dataIndex=ret1.retn();
5507 * Returns a new DataArrayInt which contains a complement of elements of \a this
5508 * one-dimensional array. I.e. the result array contains all elements from the range [0,
5509 * \a nbOfElement) not present in \a this array.
5510 * \param [in] nbOfElement - maximal size of the result array.
5511 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5512 * array using decrRef() as it is no more needed.
5513 * \throw If \a this is not allocated.
5514 * \throw If \a this->getNumberOfComponents() != 1.
5515 * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
5518 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
5521 if(getNumberOfComponents()!=1)
5522 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
5523 std::vector<bool> tmp(nbOfElement);
5524 const int *pt=getConstPointer();
5525 int nbOfTuples=getNumberOfTuples();
5526 for(const int *w=pt;w!=pt+nbOfTuples;w++)
5527 if(*w>=0 && *w<nbOfElement)
5530 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
5531 int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
5532 DataArrayInt *ret=DataArrayInt::New();
5533 ret->alloc(nbOfRetVal,1);
5535 int *retPtr=ret->getPointer();
5536 for(int i=0;i<nbOfElement;i++)
5543 * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
5544 * from an \a other one-dimensional array.
5545 * \param [in] other - a DataArrayInt containing elements not to include in the result array.
5546 * \return DataArrayInt * - a new instance of DataArrayInt with one component. The
5547 * caller is to delete this array using decrRef() as it is no more needed.
5548 * \throw If \a other is NULL.
5549 * \throw If \a other is not allocated.
5550 * \throw If \a other->getNumberOfComponents() != 1.
5551 * \throw If \a this is not allocated.
5552 * \throw If \a this->getNumberOfComponents() != 1.
5553 * \sa DataArrayInt::buildSubstractionOptimized()
5555 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
5558 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
5560 other->checkAllocated();
5561 if(getNumberOfComponents()!=1)
5562 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
5563 if(other->getNumberOfComponents()!=1)
5564 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
5565 const int *pt=getConstPointer();
5566 int nbOfTuples=getNumberOfTuples();
5567 std::set<int> s1(pt,pt+nbOfTuples);
5568 pt=other->getConstPointer();
5569 nbOfTuples=other->getNumberOfTuples();
5570 std::set<int> s2(pt,pt+nbOfTuples);
5572 std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
5573 DataArrayInt *ret=DataArrayInt::New();
5574 ret->alloc((int)r.size(),1);
5575 std::copy(r.begin(),r.end(),ret->getPointer());
5580 * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
5581 * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
5583 * \param [in] other an array with one component and expected to be sorted ascendingly.
5584 * \ret list of ids in \a this but not in \a other.
5585 * \sa DataArrayInt::buildSubstraction
5587 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
5589 static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
5590 if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
5591 checkAllocated(); other->checkAllocated();
5592 if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5593 if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5594 const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
5595 const int *work1(pt1Bg),*work2(pt2Bg);
5596 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5597 for(;work1!=pt1End;work1++)
5599 if(work2!=pt2End && *work1==*work2)
5602 ret->pushBackSilent(*work1);
5609 * Returns a new DataArrayInt which contains all elements of \a this and a given
5610 * one-dimensional arrays. The result array does not contain any duplicates
5611 * and its values are sorted in ascending order.
5612 * \param [in] other - an array to unite with \a this one.
5613 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5614 * array using decrRef() as it is no more needed.
5615 * \throw If \a this or \a other is not allocated.
5616 * \throw If \a this->getNumberOfComponents() != 1.
5617 * \throw If \a other->getNumberOfComponents() != 1.
5619 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
5621 std::vector<const DataArrayInt *>arrs(2);
5622 arrs[0]=this; arrs[1]=other;
5623 return BuildUnion(arrs);
5628 * Returns a new DataArrayInt which contains elements present in both \a this and a given
5629 * one-dimensional arrays. The result array does not contain any duplicates
5630 * and its values are sorted in ascending order.
5631 * \param [in] other - an array to intersect with \a this one.
5632 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5633 * array using decrRef() as it is no more needed.
5634 * \throw If \a this or \a other is not allocated.
5635 * \throw If \a this->getNumberOfComponents() != 1.
5636 * \throw If \a other->getNumberOfComponents() != 1.
5638 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
5640 std::vector<const DataArrayInt *>arrs(2);
5641 arrs[0]=this; arrs[1]=other;
5642 return BuildIntersection(arrs);
5646 * This method can be applied on allocated with one component DataArrayInt instance.
5647 * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
5648 * Example : if \a this contains [1,2,2,3,3,3,3,4,5,5,7,7,7,19] the returned array will contain [1,2,3,4,5,7,19]
5650 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5651 * \throw if \a this is not allocated or if \a this has not exactly one component.
5652 * \sa DataArrayInt::buildUniqueNotSorted
5654 DataArrayInt *DataArrayInt::buildUnique() const
5657 if(getNumberOfComponents()!=1)
5658 throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
5659 int nbOfTuples=getNumberOfTuples();
5660 MCAuto<DataArrayInt> tmp=deepCopy();
5661 int *data=tmp->getPointer();
5662 int *last=std::unique(data,data+nbOfTuples);
5663 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5664 ret->alloc(std::distance(data,last),1);
5665 std::copy(data,last,ret->getPointer());
5670 * This method can be applied on allocated with one component DataArrayInt instance.
5671 * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
5673 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5675 * \throw if \a this is not allocated or if \a this has not exactly one component.
5677 * \sa DataArrayInt::buildUnique
5679 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
5682 if(getNumberOfComponents()!=1)
5683 throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
5685 getMinMaxValues(minVal,maxVal);
5686 std::vector<bool> b(maxVal-minVal+1,false);
5687 const int *ptBg(begin()),*endBg(end());
5688 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5689 for(const int *pt=ptBg;pt!=endBg;pt++)
5693 ret->pushBackSilent(*pt);
5697 ret->copyStringInfoFrom(*this);
5702 * Returns a new DataArrayInt which contains size of every of groups described by \a this
5703 * "index" array. Such "index" array is returned for example by
5704 * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
5705 * "MEDCouplingUMesh::buildDescendingConnectivity" and
5706 * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
5707 * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
5708 * This method performs the reverse operation of DataArrayInt::computeOffsetsFull.
5709 * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
5710 * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
5711 * The caller is to delete this array using decrRef() as it is no more needed.
5712 * \throw If \a this is not allocated.
5713 * \throw If \a this->getNumberOfComponents() != 1.
5714 * \throw If \a this->getNumberOfTuples() < 2.
5717 * - this contains [1,3,6,7,7,9,15]
5718 * - result array contains [2,3,1,0,2,6],
5719 * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
5721 * \sa DataArrayInt::computeOffsetsFull
5723 DataArrayInt *DataArrayInt::deltaShiftIndex() const
5726 if(getNumberOfComponents()!=1)
5727 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
5728 int nbOfTuples=getNumberOfTuples();
5730 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
5731 const int *ptr=getConstPointer();
5732 DataArrayInt *ret=DataArrayInt::New();
5733 ret->alloc(nbOfTuples-1,1);
5734 int *out=ret->getPointer();
5735 std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
5740 * Modifies \a this one-dimensional array so that value of each element \a x
5741 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5742 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
5743 * and components remains the same.<br>
5744 * This method is useful for allToAllV in MPI with contiguous policy. This method
5745 * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
5747 * \throw If \a this is not allocated.
5748 * \throw If \a this->getNumberOfComponents() != 1.
5751 * - Before \a this contains [3,5,1,2,0,8]
5752 * - After \a this contains [0,3,8,9,11,11]<br>
5753 * Note that the last element 19 = 11 + 8 is missing because size of \a this
5754 * array is retained and thus there is no space to store the last element.
5756 void DataArrayInt::computeOffsets()
5759 if(getNumberOfComponents()!=1)
5760 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
5761 int nbOfTuples=getNumberOfTuples();
5764 int *work=getPointer();
5767 for(int i=1;i<nbOfTuples;i++)
5770 work[i]=work[i-1]+tmp;
5778 * Modifies \a this one-dimensional array so that value of each element \a x
5779 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5780 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
5781 * components remains the same and number of tuples is inceamented by one.<br>
5782 * This method is useful for allToAllV in MPI with contiguous policy. This method
5783 * differs from computeOffsets() in that the number of tuples is changed by this one.
5784 * This method performs the reverse operation of DataArrayInt::deltaShiftIndex.
5785 * \throw If \a this is not allocated.
5786 * \throw If \a this->getNumberOfComponents() != 1.
5789 * - Before \a this contains [3,5,1,2,0,8]
5790 * - After \a this contains [0,3,8,9,11,11,19]<br>
5791 * \sa DataArrayInt::deltaShiftIndex
5793 void DataArrayInt::computeOffsetsFull()
5796 if(getNumberOfComponents()!=1)
5797 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
5798 int nbOfTuples=getNumberOfTuples();
5799 int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
5800 const int *work=getConstPointer();
5802 for(int i=0;i<nbOfTuples;i++)
5803 ret[i+1]=work[i]+ret[i];
5804 useArray(ret,true,DeallocType::C_DEALLOC,nbOfTuples+1,1);
5809 * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
5810 * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
5811 * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
5812 * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
5813 * filling completely one of the ranges in \a this.
5815 * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
5816 * \param [out] rangeIdsFetched the range ids fetched
5817 * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
5818 * \a idsInInputListThatFetch is a part of input \a listOfIds.
5820 * \sa DataArrayInt::computeOffsetsFull
5823 * - \a this : [0,3,7,9,15,18]
5824 * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
5825 * - \a rangeIdsFetched result array: [0,2,4]
5826 * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
5827 * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
5830 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
5833 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
5834 listOfIds->checkAllocated(); checkAllocated();
5835 if(listOfIds->getNumberOfComponents()!=1)
5836 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
5837 if(getNumberOfComponents()!=1)
5838 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
5839 MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
5840 MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
5841 const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
5842 const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
5843 while(tupPtr!=tupEnd && offPtr!=offEnd)
5845 if(*tupPtr==*offPtr)
5848 while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
5851 ret0->pushBackSilent((int)std::distance(offBg,offPtr));
5852 ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
5857 { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
5859 rangeIdsFetched=ret0.retn();
5860 idsInInputListThatFetch=ret1.retn();
5864 * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
5865 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
5866 * "index" array of a "iota" array, thus, whose each element gives an index of a group
5867 * beginning within the "iota" array. And \a this is a one-dimensional array
5868 * considered as a selector of groups described by \a offsets to include into the result array.
5869 * \throw If \a offsets is NULL.
5870 * \throw If \a offsets is not allocated.
5871 * \throw If \a offsets->getNumberOfComponents() != 1.
5872 * \throw If \a offsets is not monotonically increasing.
5873 * \throw If \a this is not allocated.
5874 * \throw If \a this->getNumberOfComponents() != 1.
5875 * \throw If any element of \a this is not a valid index for \a offsets array.
5878 * - \a this: [0,2,3]
5879 * - \a offsets: [0,3,6,10,14,20]
5880 * - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
5881 * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
5882 * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) +
5883 * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) +
5884 * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
5886 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
5889 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
5891 if(getNumberOfComponents()!=1)
5892 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
5893 offsets->checkAllocated();
5894 if(offsets->getNumberOfComponents()!=1)
5895 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
5896 int othNbTuples=offsets->getNumberOfTuples()-1;
5897 int nbOfTuples=getNumberOfTuples();
5898 int retNbOftuples=0;
5899 const int *work=getConstPointer();
5900 const int *offPtr=offsets->getConstPointer();
5901 for(int i=0;i<nbOfTuples;i++)
5904 if(val>=0 && val<othNbTuples)
5906 int delta=offPtr[val+1]-offPtr[val];
5908 retNbOftuples+=delta;
5911 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
5912 throw INTERP_KERNEL::Exception(oss.str().c_str());
5917 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
5918 oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
5919 throw INTERP_KERNEL::Exception(oss.str().c_str());
5922 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5923 ret->alloc(retNbOftuples,1);
5924 int *retPtr=ret->getPointer();
5925 for(int i=0;i<nbOfTuples;i++)
5928 int start=offPtr[val];
5929 int off=offPtr[val+1]-start;
5930 for(int j=0;j<off;j++,retPtr++)
5937 * Returns a new DataArrayInt whose contents is computed using \a this that must be a
5938 * scaled array (monotonically increasing).
5939 from that of \a this and \a
5940 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
5941 * "index" array of a "iota" array, thus, whose each element gives an index of a group
5942 * beginning within the "iota" array. And \a this is a one-dimensional array
5943 * considered as a selector of groups described by \a offsets to include into the result array.
5944 * \throw If \a is NULL.
5945 * \throw If \a this is not allocated.
5946 * \throw If \a this->getNumberOfComponents() != 1.
5947 * \throw If \a this->getNumberOfTuples() == 0.
5948 * \throw If \a this is not monotonically increasing.
5949 * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
5952 * - \a bg , \a stop and \a step : (0,5,2)
5953 * - \a this: [0,3,6,10,14,20]
5954 * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
5956 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
5959 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
5960 if(getNumberOfComponents()!=1)
5961 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
5962 int nbOfTuples(getNumberOfTuples());
5964 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
5965 const int *ids(begin());
5966 int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
5967 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
5969 if(pos>=0 && pos<nbOfTuples-1)
5971 int delta(ids[pos+1]-ids[pos]);
5975 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
5976 throw INTERP_KERNEL::Exception(oss.str().c_str());
5981 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";
5982 throw INTERP_KERNEL::Exception(oss.str().c_str());
5985 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5986 int *retPtr(ret->getPointer());
5988 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
5990 int delta(ids[pos+1]-ids[pos]);
5991 for(int j=0;j<delta;j++,retPtr++)
5998 * Given in input ranges \a ranges, it returns a newly allocated DataArrayInt instance having one component and the same number of tuples than \a this.
5999 * For each tuple at place **i** in \a this it tells which is the first range in \a ranges that contains value \c this->getIJ(i,0) and put the result
6000 * in tuple **i** of returned DataArrayInt.
6001 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6003 * For example if \a this contains : [1,24,7,8,10,17] and \a ranges contains [(0,3),(3,8),(8,15),(15,22),(22,30)]
6004 * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6006 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6007 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6008 * \throw If offsets is a null pointer or does not have 2 components or if \a this is not allocated or \a this do not have exactly one component. To finish an exception
6009 * is thrown if no ranges in \a ranges contains value in \a this.
6011 * \sa DataArrayInt::findIdInRangeForEachTuple
6013 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
6016 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6017 if(ranges->getNumberOfComponents()!=2)
6018 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6020 if(getNumberOfComponents()!=1)
6021 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6022 int nbTuples=getNumberOfTuples();
6023 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6024 int nbOfRanges=ranges->getNumberOfTuples();
6025 const int *rangesPtr=ranges->getConstPointer();
6026 int *retPtr=ret->getPointer();
6027 const int *inPtr=getConstPointer();
6028 for(int i=0;i<nbTuples;i++,retPtr++)
6032 for(int j=0;j<nbOfRanges && !found;j++)
6033 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6034 { *retPtr=j; found=true; }
6039 std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6040 throw INTERP_KERNEL::Exception(oss.str().c_str());
6047 * Given in input ranges \a ranges, it returns a newly allocated DataArrayInt instance having one component and the same number of tuples than \a this.
6048 * For each tuple at place **i** in \a this it tells which is the sub position of the first range in \a ranges that contains value \c this->getIJ(i,0) and put the result
6049 * in tuple **i** of returned DataArrayInt.
6050 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6052 * For example if \a this contains : [1,24,7,8,10,17] and \a ranges contains [(0,3),(3,8),(8,15),(15,22),(22,30)]
6053 * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6054 * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6056 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6057 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6058 * \throw If offsets is a null pointer or does not have 2 components or if \a this is not allocated or \a this do not have exactly one component. To finish an exception
6059 * is thrown if no ranges in \a ranges contains value in \a this.
6060 * \sa DataArrayInt::findRangeIdForEachTuple
6062 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
6065 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6066 if(ranges->getNumberOfComponents()!=2)
6067 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6069 if(getNumberOfComponents()!=1)
6070 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6071 int nbTuples=getNumberOfTuples();
6072 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6073 int nbOfRanges=ranges->getNumberOfTuples();
6074 const int *rangesPtr=ranges->getConstPointer();
6075 int *retPtr=ret->getPointer();
6076 const int *inPtr=getConstPointer();
6077 for(int i=0;i<nbTuples;i++,retPtr++)
6081 for(int j=0;j<nbOfRanges && !found;j++)
6082 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6083 { *retPtr=val-rangesPtr[2*j]; found=true; }
6088 std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6089 throw INTERP_KERNEL::Exception(oss.str().c_str());
6096 * \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).
6097 * 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).
6098 * 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 !
6099 * If this method has correctly worked, \a this will be able to be considered as a linked list.
6100 * This method does nothing if number of tuples is lower of equal to 1.
6102 * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internally the connectivity without any coordinates consideration.
6104 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
6106 void DataArrayInt::sortEachPairToMakeALinkedList()
6109 if(getNumberOfComponents()!=2)
6110 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6111 int nbOfTuples(getNumberOfTuples());
6114 int *conn(getPointer());
6115 for(int i=1;i<nbOfTuples;i++,conn+=2)
6119 if(conn[2]==conn[3])
6121 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6122 throw INTERP_KERNEL::Exception(oss.str().c_str());
6124 if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6125 std::swap(conn[2],conn[3]);
6126 //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6127 if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6129 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6130 throw INTERP_KERNEL::Exception(oss.str().c_str());
6135 if(conn[0]==conn[1] || conn[2]==conn[3])
6136 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6139 s.insert(conn,conn+4);
6141 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6142 if(std::count(conn,conn+4,conn[0])==2)
6147 if(conn[2]==conn[0])
6151 std::copy(tmp,tmp+4,conn);
6154 {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6155 if(conn[1]==conn[3])
6156 std::swap(conn[2],conn[3]);
6163 * \a this is expected to be a correctly linked list of pairs.
6165 * \sa DataArrayInt::sortEachPairToMakeALinkedList
6167 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
6170 checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6171 int nbTuples(getNumberOfTuples());
6173 throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6174 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
6175 const int *thisPtr(begin());
6176 int *retPtr(ret->getPointer());
6177 retPtr[0]=thisPtr[0];
6178 for(int i=0;i<nbTuples;i++)
6180 retPtr[i+1]=thisPtr[2*i+1];
6182 if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6184 std::ostringstream oss; oss << "DataArrayInt::fromLinkedListOfPairToList : this is not a proper linked list of pair. The link is broken between tuple #" << i << " and tuple #" << i+1 << " ! Call sortEachPairToMakeALinkedList ?";
6185 throw INTERP_KERNEL::Exception(oss.str());
6192 * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6193 * But the number of components can be different from one.
6194 * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6196 DataArrayInt *DataArrayInt::getDifferentValues() const
6200 ret.insert(begin(),end());
6201 MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
6202 std::copy(ret.begin(),ret.end(),ret2->getPointer());
6207 * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6208 * them it tells which tuple id have this id.
6209 * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6210 * This method returns two arrays having same size.
6211 * The instances of DataArrayInt in the returned vector have be specially allocated and computed by this method. Each of them should be dealt by the caller of this method.
6212 * Example : if this is equal to [1,0,1,2,0,2,2,-3,2] -> differentIds=[-3,0,1,2] and returned array will be equal to [[7],[1,4],[0,2],[3,5,6,8]]
6214 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
6217 if(getNumberOfComponents()!=1)
6218 throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6220 std::map<int,int> m,m2,m3;
6221 for(const int *w=begin();w!=end();w++)
6223 differentIds.resize(m.size());
6224 std::vector<DataArrayInt *> ret(m.size());
6225 std::vector<int *> retPtr(m.size());
6226 for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
6229 ret[id]=DataArrayInt::New();
6230 ret[id]->alloc((*it).second,1);
6231 retPtr[id]=ret[id]->getPointer();
6232 differentIds[id]=(*it).first;
6235 for(const int *w=begin();w!=end();w++,id++)
6237 retPtr[m2[*w]][m3[*w]++]=id;
6243 * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6244 * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6246 * \param [in] nbOfSlices - number of slices expected.
6247 * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6249 * \sa DataArray::GetSlice
6250 * \throw If \a this is not allocated or not with exactly one component.
6251 * \throw If an element in \a this if < 0.
6253 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
6255 if(!isAllocated() || getNumberOfComponents()!=1)
6256 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6258 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6259 int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
6260 int sumPerSlc(sum/nbOfSlices),pos(0);
6261 const int *w(begin());
6262 std::vector< std::pair<int,int> > ret(nbOfSlices);
6263 for(int i=0;i<nbOfSlices;i++)
6265 std::pair<int,int> p(pos,-1);
6267 while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6271 p.second=nbOfTuples;
6278 * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6280 * 1. The arrays have same number of tuples and components. Then each value of
6281 * the result array (_a_) is a division of the corresponding values of \a a1 and
6282 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6283 * 2. The arrays have same number of tuples and one array, say _a2_, has one
6285 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6286 * 3. The arrays have same number of components and one array, say _a2_, has one
6288 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6290 * Info on components is copied either from the first array (in the first case) or from
6291 * the array with maximal number of elements (getNbOfElems()).
6292 * \warning No check of division by zero is performed!
6293 * \param [in] a1 - a dividend array.
6294 * \param [in] a2 - a divisor array.
6295 * \return DataArrayInt * - the new instance of DataArrayInt.
6296 * The caller is to delete this result array using decrRef() as it is no more
6298 * \throw If either \a a1 or \a a2 is NULL.
6299 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6300 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6301 * none of them has number of tuples or components equal to 1.
6303 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
6306 throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6307 int nbOfTuple1=a1->getNumberOfTuples();
6308 int nbOfTuple2=a2->getNumberOfTuples();
6309 int nbOfComp1=a1->getNumberOfComponents();
6310 int nbOfComp2=a2->getNumberOfComponents();
6311 if(nbOfTuple2==nbOfTuple1)
6313 if(nbOfComp1==nbOfComp2)
6315 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6316 ret->alloc(nbOfTuple2,nbOfComp1);
6317 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
6318 ret->copyStringInfoFrom(*a1);
6321 else if(nbOfComp2==1)
6323 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6324 ret->alloc(nbOfTuple1,nbOfComp1);
6325 const int *a2Ptr=a2->getConstPointer();
6326 const int *a1Ptr=a1->getConstPointer();
6327 int *res=ret->getPointer();
6328 for(int i=0;i<nbOfTuple1;i++)
6329 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
6330 ret->copyStringInfoFrom(*a1);
6335 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6339 else if(nbOfTuple2==1)
6341 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6342 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6343 ret->alloc(nbOfTuple1,nbOfComp1);
6344 const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6345 int *pt=ret->getPointer();
6346 for(int i=0;i<nbOfTuple1;i++)
6347 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
6348 ret->copyStringInfoFrom(*a1);
6353 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
6359 * Modify \a this array so that each value becomes a modulus of division of this value by
6360 * a value of another DataArrayInt. There are 3 valid cases.
6361 * 1. The arrays have same number of tuples and components. Then each value of
6362 * \a this array is divided by the corresponding value of \a other one, i.e.:
6363 * _a_ [ i, j ] %= _other_ [ i, j ].
6364 * 2. The arrays have same number of tuples and \a other array has one component. Then
6365 * _a_ [ i, j ] %= _other_ [ i, 0 ].
6366 * 3. The arrays have same number of components and \a other array has one tuple. Then
6367 * _a_ [ i, j ] %= _a2_ [ 0, j ].
6369 * \warning No check of division by zero is performed!
6370 * \param [in] other - a divisor array.
6371 * \throw If \a other is NULL.
6372 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
6373 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
6374 * \a other has number of both tuples and components not equal to 1.
6376 void DataArrayInt::modulusEqual(const DataArrayInt *other)
6379 throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
6380 const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
6381 checkAllocated(); other->checkAllocated();
6382 int nbOfTuple=getNumberOfTuples();
6383 int nbOfTuple2=other->getNumberOfTuples();
6384 int nbOfComp=getNumberOfComponents();
6385 int nbOfComp2=other->getNumberOfComponents();
6386 if(nbOfTuple==nbOfTuple2)
6388 if(nbOfComp==nbOfComp2)
6390 std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
6392 else if(nbOfComp2==1)
6394 if(nbOfComp2==nbOfComp)
6396 int *ptr=getPointer();
6397 const int *ptrc=other->getConstPointer();
6398 for(int i=0;i<nbOfTuple;i++)
6399 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
6402 throw INTERP_KERNEL::Exception(msg);
6405 throw INTERP_KERNEL::Exception(msg);
6407 else if(nbOfTuple2==1)
6409 int *ptr=getPointer();
6410 const int *ptrc=other->getConstPointer();
6411 for(int i=0;i<nbOfTuple;i++)
6412 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
6415 throw INTERP_KERNEL::Exception(msg);
6420 * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
6423 * \param [in] a1 - an array to pow up.
6424 * \param [in] a2 - another array to sum up.
6425 * \return DataArrayInt * - the new instance of DataArrayInt.
6426 * The caller is to delete this result array using decrRef() as it is no more
6428 * \throw If either \a a1 or \a a2 is NULL.
6429 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6430 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
6431 * \throw If there is a negative value in \a a2.
6433 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
6436 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
6437 int nbOfTuple=a1->getNumberOfTuples();
6438 int nbOfTuple2=a2->getNumberOfTuples();
6439 int nbOfComp=a1->getNumberOfComponents();
6440 int nbOfComp2=a2->getNumberOfComponents();
6441 if(nbOfTuple!=nbOfTuple2)
6442 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
6443 if(nbOfComp!=1 || nbOfComp2!=1)
6444 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
6445 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
6446 const int *ptr1(a1->begin()),*ptr2(a2->begin());
6447 int *ptr=ret->getPointer();
6448 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
6453 for(int j=0;j<*ptr2;j++)
6459 std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
6460 throw INTERP_KERNEL::Exception(oss.str().c_str());
6467 * Apply pow on values of another DataArrayInt to values of \a this one.
6469 * \param [in] other - an array to pow to \a this one.
6470 * \throw If \a other is NULL.
6471 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
6472 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
6473 * \throw If there is a negative value in \a other.
6475 void DataArrayInt::powEqual(const DataArrayInt *other)
6478 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
6479 int nbOfTuple=getNumberOfTuples();
6480 int nbOfTuple2=other->getNumberOfTuples();
6481 int nbOfComp=getNumberOfComponents();
6482 int nbOfComp2=other->getNumberOfComponents();
6483 if(nbOfTuple!=nbOfTuple2)
6484 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
6485 if(nbOfComp!=1 || nbOfComp2!=1)
6486 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
6487 int *ptr=getPointer();
6488 const int *ptrc=other->begin();
6489 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
6494 for(int j=0;j<*ptrc;j++)
6500 std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
6501 throw INTERP_KERNEL::Exception(oss.str().c_str());
6508 * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
6509 * This map, if applied to \a start array, would make it sorted. For example, if
6510 * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
6511 * [5,6,0,3,2,7,1,4].
6512 * \param [in] start - pointer to the first element of the array for which the
6513 * permutation map is computed.
6514 * \param [in] end - pointer specifying the end of the array \a start, so that
6515 * the last value of \a start is \a end[ -1 ].
6516 * \return int * - the result permutation array that the caller is to delete as it is no
6518 * \throw If there are equal values in the input array.
6520 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
6522 std::size_t sz=std::distance(start,end);
6523 int *ret=(int *)malloc(sz*sizeof(int));
6524 int *work=new int[sz];
6525 std::copy(start,end,work);
6526 std::sort(work,work+sz);
6527 if(std::unique(work,work+sz)!=work+sz)
6531 throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
6533 std::map<int,int> m;
6534 for(int *workPt=work;workPt!=work+sz;workPt++)
6535 m[*workPt]=(int)std::distance(work,workPt);
6537 for(const int *iter=start;iter!=end;iter++,iter2++)
6544 * Returns a new DataArrayInt containing an arithmetic progression
6545 * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step )
6547 * \param [in] begin - the start value of the result sequence.
6548 * \param [in] end - limiting value, so that every value of the result array is less than
6550 * \param [in] step - specifies the increment or decrement.
6551 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6552 * array using decrRef() as it is no more needed.
6553 * \throw If \a step == 0.
6554 * \throw If \a end < \a begin && \a step > 0.
6555 * \throw If \a end > \a begin && \a step < 0.
6557 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
6559 int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
6560 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6561 ret->alloc(nbOfTuples,1);
6562 int *ptr=ret->getPointer();
6565 for(int i=begin;i<end;i+=step,ptr++)
6570 for(int i=begin;i>end;i+=step,ptr++)
6577 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6580 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
6585 tinyInfo[0]=getNumberOfTuples();
6586 tinyInfo[1]=getNumberOfComponents();
6596 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6599 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
6603 int nbOfCompo=getNumberOfComponents();
6604 tinyInfo.resize(nbOfCompo+1);
6605 tinyInfo[0]=getName();
6606 for(int i=0;i<nbOfCompo;i++)
6607 tinyInfo[i+1]=getInfoOnComponent(i);
6612 tinyInfo[0]=getName();
6617 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6618 * This method returns if a feeding is needed.
6620 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
6622 int nbOfTuple=tinyInfoI[0];
6623 int nbOfComp=tinyInfoI[1];
6624 if(nbOfTuple!=-1 || nbOfComp!=-1)
6626 alloc(nbOfTuple,nbOfComp);
6633 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6634 * This method returns if a feeding is needed.
6636 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
6638 setName(tinyInfoS[0]);
6641 int nbOfCompo=tinyInfoI[1];
6642 for(int i=0;i<nbOfCompo;i++)
6643 setInfoOnComponent(i,tinyInfoS[i+1]);
6647 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
6651 DataArrayInt32Tuple::DataArrayInt32Tuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
6655 std::string DataArrayIntTuple::repr() const
6657 std::ostringstream oss; oss << "(";
6658 for(int i=0;i<_nb_of_compo-1;i++)
6659 oss << _pt[i] << ", ";
6660 oss << _pt[_nb_of_compo-1] << ")";
6664 int DataArrayIntTuple::intValue() const
6666 return this->zeValue();
6670 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
6671 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
6672 * This method throws an INTERP_KERNEL::Exception is it is impossible to match sizes of \b this that is too say \b nbOfCompo=this->_nb_of_elem and \bnbOfTuples==1 or
6673 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
6675 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
6677 return this->buildDA(nbOfTuples,nbOfCompo);
6680 DataArrayInt64 *DataArrayInt64::deepCopy() const
6682 return new DataArrayInt64(*this);