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::DataArrayTuple<int>;
57 template class MEDCoupling::DataArrayTuple<double>;
58 template class MEDCoupling::DataArrayTuple<float>;
60 template<int SPACEDIM>
61 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
63 const double *coordsPtr=getConstPointer();
64 BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
65 std::vector<bool> isDone(nbNodes);
66 for(int i=0;i<nbNodes;i++)
70 std::vector<int> intersectingElems;
71 myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
72 if(intersectingElems.size()>1)
74 std::vector<int> commonNodes;
75 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
79 commonNodes.push_back(*it);
82 if(!commonNodes.empty())
84 cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
86 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
93 template<int SPACEDIM>
94 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
95 DataArrayInt *c, DataArrayInt *cI)
97 for(int i=0;i<nbOfTuples;i++)
99 std::vector<int> intersectingElems;
100 myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
101 std::vector<int> commonNodes;
102 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
103 commonNodes.push_back(*it);
104 cI->pushBackSilent(cI->back()+(int)commonNodes.size());
105 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
109 template<int SPACEDIM>
110 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
112 double distOpt(dist);
113 const double *p(pos);
115 for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
120 double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
121 if(ret!=std::numeric_limits<double>::max())
123 distOpt=std::max(ret,1e-4);
128 { distOpt=2*distOpt; continue; }
133 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
136 throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
139 return nbOfShift%nbOfTuples;
145 return nbOfTuples-tmp;
149 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
151 std::size_t sz1=_name.capacity();
152 std::size_t sz2=_info_on_compo.capacity();
154 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
155 sz3+=(*it).capacity();
159 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
161 return std::vector<const BigMemoryObject *>();
165 * Sets the attribute \a _name of \a this array.
166 * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
167 * \param [in] name - new array name
169 void DataArray::setName(const std::string& name)
175 * Copies textual data from an \a other DataArray. The copied data are
176 * - the name attribute,
177 * - the information of components.
179 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
181 * \param [in] other - another instance of DataArray to copy the textual data from.
182 * \throw If number of components of \a this array differs from that of the \a other.
184 void DataArray::copyStringInfoFrom(const DataArray& other)
186 if(_info_on_compo.size()!=other._info_on_compo.size())
187 throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
189 _info_on_compo=other._info_on_compo;
192 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
194 int nbOfCompoOth=other.getNumberOfComponents();
195 std::size_t newNbOfCompo=compoIds.size();
196 for(std::size_t i=0;i<newNbOfCompo;i++)
197 if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
199 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
200 throw INTERP_KERNEL::Exception(oss.str().c_str());
202 for(std::size_t i=0;i<newNbOfCompo;i++)
203 setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
206 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
208 std::size_t nbOfCompo(getNumberOfComponents());
209 std::size_t partOfCompoToSet=compoIds.size();
210 if(partOfCompoToSet!=other.getNumberOfComponents())
211 throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
212 for(std::size_t i=0;i<partOfCompoToSet;i++)
213 if(compoIds[i]>=(int)nbOfCompo || compoIds[i]<0)
215 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
216 throw INTERP_KERNEL::Exception(oss.str().c_str());
218 for(std::size_t i=0;i<partOfCompoToSet;i++)
219 setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
222 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
224 std::ostringstream oss;
225 if(_name!=other._name)
227 oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
231 if(_info_on_compo!=other._info_on_compo)
233 oss << "Components DataArray mismatch : \nThis components=";
234 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
235 oss << "\"" << *it << "\",";
236 oss << "\nOther components=";
237 for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
238 oss << "\"" << *it << "\",";
246 * Compares textual information of \a this DataArray with that of an \a other one.
247 * The compared data are
248 * - the name attribute,
249 * - the information of components.
251 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
252 * \param [in] other - another instance of DataArray to compare the textual data of.
253 * \return bool - \a true if the textual information is same, \a false else.
255 bool DataArray::areInfoEquals(const DataArray& other) const
258 return areInfoEqualsIfNotWhy(other,tmp);
261 void DataArray::reprWithoutNameStream(std::ostream& stream) const
263 stream << "Number of components : "<< getNumberOfComponents() << "\n";
264 stream << "Info of these components : ";
265 for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
266 stream << "\"" << *iter << "\" ";
270 std::string DataArray::cppRepr(const std::string& varName) const
272 std::ostringstream ret;
273 reprCppStream(varName,ret);
278 * Sets information on all components. To know more on format of this information
279 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
280 * \param [in] info - a vector of strings.
281 * \throw If size of \a info differs from the number of components of \a this.
283 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
285 if(getNumberOfComponents()!=info.size())
287 std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
288 throw INTERP_KERNEL::Exception(oss.str().c_str());
294 * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
295 * type of \a this and \a aBase.
297 * \throw If \a aBase and \a this do not have the same type.
299 * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
301 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
304 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
305 DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
306 DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
307 DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
308 const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
309 const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
310 const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
313 this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
318 this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
323 this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
326 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
329 std::vector<std::string> DataArray::getVarsOnComponent() const
331 int nbOfCompo=(int)_info_on_compo.size();
332 std::vector<std::string> ret(nbOfCompo);
333 for(int i=0;i<nbOfCompo;i++)
334 ret[i]=getVarOnComponent(i);
338 std::vector<std::string> DataArray::getUnitsOnComponent() const
340 int nbOfCompo=(int)_info_on_compo.size();
341 std::vector<std::string> ret(nbOfCompo);
342 for(int i=0;i<nbOfCompo;i++)
343 ret[i]=getUnitOnComponent(i);
348 * Returns information on a component specified by an index.
349 * To know more on format of this information
350 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
351 * \param [in] i - the index (zero based) of the component of interest.
352 * \return std::string - a string containing the information on \a i-th component.
353 * \throw If \a i is not a valid component index.
355 std::string DataArray::getInfoOnComponent(int i) const
357 if(i<(int)_info_on_compo.size() && i>=0)
358 return _info_on_compo[i];
361 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();
362 throw INTERP_KERNEL::Exception(oss.str().c_str());
367 * Returns the var part of the full information of the \a i-th component.
368 * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
369 * \c getVarOnComponent(0) returns "SIGXY".
370 * If a unit part of information is not detected by presence of
371 * two square brackets, then the full information is returned.
372 * To read more about the component information format, see
373 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
374 * \param [in] i - the index (zero based) of the component of interest.
375 * \return std::string - a string containing the var information, or the full info.
376 * \throw If \a i is not a valid component index.
378 std::string DataArray::getVarOnComponent(int i) const
380 if(i<(int)_info_on_compo.size() && i>=0)
382 return GetVarNameFromInfo(_info_on_compo[i]);
386 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();
387 throw INTERP_KERNEL::Exception(oss.str().c_str());
392 * Returns the unit part of the full information of the \a i-th component.
393 * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
394 * \c getUnitOnComponent(0) returns " N/m^2".
395 * If a unit part of information is not detected by presence of
396 * two square brackets, then an empty string is returned.
397 * To read more about the component information format, see
398 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
399 * \param [in] i - the index (zero based) of the component of interest.
400 * \return std::string - a string containing the unit information, if any, or "".
401 * \throw If \a i is not a valid component index.
403 std::string DataArray::getUnitOnComponent(int i) const
405 if(i<(int)_info_on_compo.size() && i>=0)
407 return GetUnitFromInfo(_info_on_compo[i]);
411 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();
412 throw INTERP_KERNEL::Exception(oss.str().c_str());
417 * Returns the var part of the full component information.
418 * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
419 * If a unit part of information is not detected by presence of
420 * two square brackets, then the whole \a info is returned.
421 * To read more about the component information format, see
422 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
423 * \param [in] info - the full component information.
424 * \return std::string - a string containing only var information, or the \a info.
426 std::string DataArray::GetVarNameFromInfo(const std::string& info)
428 std::size_t p1=info.find_last_of('[');
429 std::size_t p2=info.find_last_of(']');
430 if(p1==std::string::npos || p2==std::string::npos)
435 return std::string();
436 std::size_t p3=info.find_last_not_of(' ',p1-1);
437 return info.substr(0,p3+1);
441 * Returns the unit part of the full component information.
442 * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
443 * If a unit part of information is not detected by presence of
444 * two square brackets, then an empty string is returned.
445 * To read more about the component information format, see
446 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
447 * \param [in] info - the full component information.
448 * \return std::string - a string containing only unit information, if any, or "".
450 std::string DataArray::GetUnitFromInfo(const std::string& info)
452 std::size_t p1=info.find_last_of('[');
453 std::size_t p2=info.find_last_of(']');
454 if(p1==std::string::npos || p2==std::string::npos)
455 return std::string();
457 return std::string();
458 return info.substr(p1+1,p2-p1-1);
462 * This method put in info format the result of the merge of \a var and \a unit.
463 * The standard format for that is "var [unit]".
464 * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
466 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
468 std::ostringstream oss;
469 oss << var << " [" << unit << "]";
473 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
478 return std::string("AX_CART");
480 return std::string("AX_CYL");
482 return std::string("AX_SPHER");
484 throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
489 * Returns a new DataArray by concatenating all given arrays, so that (1) the number
490 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
491 * the number of component in the result array is same as that of each of given arrays.
492 * Info on components is copied from the first of the given arrays. Number of components
493 * in the given arrays must be the same.
494 * \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
495 * \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
496 * The caller is to delete this result array using decrRef() as it is no more
498 * \throw If all arrays within \a arrs are NULL.
499 * \throw If all not null arrays in \a arrs have not the same type.
500 * \throw If getNumberOfComponents() of arrays within \a arrs.
502 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
504 std::vector<const DataArray *> arr2;
505 for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
509 throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
510 std::vector<const DataArrayDouble *> arrd;
511 std::vector<const DataArrayInt *> arri;
512 std::vector<const DataArrayChar *> arrc;
513 for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
515 const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
517 { arrd.push_back(a); continue; }
518 const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
520 { arri.push_back(b); continue; }
521 const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
523 { arrc.push_back(c); continue; }
524 throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
526 if(arr2.size()==arrd.size())
527 return DataArrayDouble::Aggregate(arrd);
528 if(arr2.size()==arri.size())
529 return DataArrayInt::Aggregate(arri);
530 if(arr2.size()==arrc.size())
531 return DataArrayChar::Aggregate(arrc);
532 throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
536 * Sets information on a component specified by an index.
537 * To know more on format of this information
538 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
539 * \warning Don't pass NULL as \a info!
540 * \param [in] i - the index (zero based) of the component of interest.
541 * \param [in] info - the string containing the information.
542 * \throw If \a i is not a valid component index.
544 void DataArray::setInfoOnComponent(int i, const std::string& info)
546 if(i<(int)_info_on_compo.size() && i>=0)
547 _info_on_compo[i]=info;
550 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();
551 throw INTERP_KERNEL::Exception(oss.str().c_str());
556 * Sets information on all components. This method can change number of components
557 * at certain conditions; if the conditions are not respected, an exception is thrown.
558 * The number of components can be changed in \a this only if \a this is not allocated.
559 * The condition of number of components must not be changed.
561 * To know more on format of the component information see
562 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
563 * \param [in] info - a vector of component infos.
564 * \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
566 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
568 if(getNumberOfComponents()!=info.size())
574 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 !";
575 throw INTERP_KERNEL::Exception(oss.str().c_str());
582 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
584 if((int)getNumberOfTuples()!=nbOfTuples)
586 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << nbOfTuples << " having " << getNumberOfTuples() << " !";
587 throw INTERP_KERNEL::Exception(oss.str().c_str());
591 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
593 if((int)getNumberOfComponents()!=nbOfCompo)
595 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
596 throw INTERP_KERNEL::Exception(oss.str().c_str());
600 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
602 if(getNbOfElems()!=nbOfElems)
604 std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
605 throw INTERP_KERNEL::Exception(oss.str().c_str());
609 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
611 if(getNumberOfTuples()!=other.getNumberOfTuples())
613 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
614 throw INTERP_KERNEL::Exception(oss.str().c_str());
616 if(getNumberOfComponents()!=other.getNumberOfComponents())
618 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
619 throw INTERP_KERNEL::Exception(oss.str().c_str());
623 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
625 checkNbOfTuples(nbOfTuples,msg);
626 checkNbOfComps(nbOfCompo,msg);
630 * Simply this method checks that \b value is in [0,\b ref).
632 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
634 if(value<0 || value>=ref)
636 std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg << " ! Expected in range [0," << ref << "[ having " << value << " !";
637 throw INTERP_KERNEL::Exception(oss.str().c_str());
642 * This method checks that [\b start, \b end) is compliant with ref length \b value.
643 * typically start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
645 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
647 if(start<0 || start>=value)
649 if(value!=start || end!=start)
651 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
652 throw INTERP_KERNEL::Exception(oss.str().c_str());
655 if(end<0 || end>value)
657 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected end " << end << " of input range, in [0," << value << "] !";
658 throw INTERP_KERNEL::Exception(oss.str().c_str());
662 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
664 if(value<0 || value>ref)
666 std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
667 throw INTERP_KERNEL::Exception(oss.str().c_str());
672 * 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,
673 * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
675 * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
677 * \param [in] start - the start of the input slice of the whole work to perform split into slices.
678 * \param [in] stop - the stop of the input slice of the whole work to perform split into slices.
679 * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform split into slices.
680 * \param [in] sliceId - the slice id considered
681 * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
682 * \param [out] startSlice - the start of the slice considered
683 * \param [out] stopSlice - the stop of the slice consided
685 * \throw If \a step == 0
686 * \throw If \a nbOfSlices not > 0
687 * \throw If \a sliceId not in [0,nbOfSlices)
689 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
693 std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
694 throw INTERP_KERNEL::Exception(oss.str().c_str());
696 if(sliceId<0 || sliceId>=nbOfSlices)
698 std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
699 throw INTERP_KERNEL::Exception(oss.str().c_str());
701 int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
702 int minNbOfElemsPerSlice=nbElems/nbOfSlices;
703 startSlice=start+minNbOfElemsPerSlice*step*sliceId;
704 if(sliceId<nbOfSlices-1)
705 stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
710 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
714 std::ostringstream oss; oss << msg << " : end before begin !";
715 throw INTERP_KERNEL::Exception(oss.str().c_str());
721 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
722 throw INTERP_KERNEL::Exception(oss.str().c_str());
724 return (end-1-begin)/step+1;
727 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
730 throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
731 if(end<begin && step>0)
733 std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
734 throw INTERP_KERNEL::Exception(oss.str().c_str());
736 if(begin<end && step<0)
738 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
739 throw INTERP_KERNEL::Exception(oss.str().c_str());
742 return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
747 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
753 if(begin<=value && value<end)
755 if((value-begin)%step==0)
756 return (value-begin)/step;
765 if(begin>=value && value>end)
767 if((begin-value)%(-step)==0)
768 return (begin-value)/(-step);
781 * Returns a new instance of DataArrayDouble. The caller is to delete this array
782 * using decrRef() as it is no more needed.
784 DataArrayDouble *DataArrayDouble::New()
786 return new DataArrayDouble;
790 * Returns the only one value in \a this, if and only if number of elements
791 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
792 * \return double - the sole value stored in \a this array.
793 * \throw If at least one of conditions stated above is not fulfilled.
795 double DataArrayDouble::doubleValue() const
799 if(getNbOfElems()==1)
801 return *getConstPointer();
804 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
807 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
811 * Returns a full copy of \a this. For more info on copying data arrays see
812 * \ref MEDCouplingArrayBasicsCopyDeep.
813 * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
814 * delete this array using decrRef() as it is no more needed.
816 DataArrayDouble *DataArrayDouble::deepCopy() const
818 return new DataArrayDouble(*this);
822 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
823 * with at least absolute difference value of |\a eps| at each step.
824 * If not an exception is thrown.
825 * \param [in] increasing - if \a true, the array values should be increasing.
826 * \param [in] eps - minimal absolute difference between the neighbor values at which
827 * the values are considered different.
828 * \throw If sequence of values is not strictly monotonic in agreement with \a
830 * \throw If \a this->getNumberOfComponents() != 1.
831 * \throw If \a this is not allocated.
833 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
835 if(!isMonotonic(increasing,eps))
838 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
840 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
845 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
846 * with at least absolute difference value of |\a eps| at each step.
847 * \param [in] increasing - if \a true, array values should be increasing.
848 * \param [in] eps - minimal absolute difference between the neighbor values at which
849 * the values are considered different.
850 * \return bool - \a true if values change in accordance with \a increasing arg.
851 * \throw If \a this->getNumberOfComponents() != 1.
852 * \throw If \a this is not allocated.
854 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
857 if(getNumberOfComponents()!=1)
858 throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
859 int nbOfElements=getNumberOfTuples();
860 const double *ptr=getConstPointer();
864 double absEps=fabs(eps);
867 for(int i=1;i<nbOfElements;i++)
869 if(ptr[i]<(ref+absEps))
877 for(int i=1;i<nbOfElements;i++)
879 if(ptr[i]>(ref-absEps))
888 * Returns a textual and human readable representation of \a this instance of
889 * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
890 * \return std::string - text describing \a this DataArrayDouble.
892 * \sa reprNotTooLong, reprZip
894 std::string DataArrayDouble::repr() const
896 std::ostringstream ret;
901 std::string DataArrayDouble::reprZip() const
903 std::ostringstream ret;
908 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
910 static const char SPACE[4]={' ',' ',' ',' '};
912 std::string idt(indent,' ');
914 ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
916 bool areAllEmpty(true);
917 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
921 for(std::size_t i=0;i<_info_on_compo.size();i++)
922 ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
926 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
927 INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
929 // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
930 for(const double *src=begin();src!=end();src++,pt++)
932 const char *data(reinterpret_cast<const char *>((float *)tmp));
933 std::size_t sz(getNbOfElems()*sizeof(float));
934 byteArr->insertAtTheEnd(data,data+sz);
935 byteArr->insertAtTheEnd(SPACE,SPACE+4);
939 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
940 std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
942 ofs << std::endl << idt << "</DataArray>\n";
945 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
947 int nbTuples(getNumberOfTuples()),nbComp(getNumberOfComponents());
948 const double *data(getConstPointer());
949 stream.precision(17);
950 stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
951 if(nbTuples*nbComp>=1)
953 stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
954 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
955 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
956 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
959 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
960 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
964 * Method that gives a quick overvien of \a this for python.
966 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
968 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
969 stream << "DataArrayDouble C++ instance at " << this << ". ";
972 int nbOfCompo=(int)_info_on_compo.size();
975 int nbOfTuples=getNumberOfTuples();
976 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
977 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
980 stream << "Number of components : 0.";
983 stream << "*** No data allocated ****";
986 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
988 const double *data=begin();
989 int nbOfTuples=getNumberOfTuples();
990 int nbOfCompo=(int)_info_on_compo.size();
991 std::ostringstream oss2; oss2 << "[";
993 std::string oss2Str(oss2.str());
994 bool isFinished=true;
995 for(int i=0;i<nbOfTuples && isFinished;i++)
1000 for(int j=0;j<nbOfCompo;j++,data++)
1003 if(j!=nbOfCompo-1) oss2 << ", ";
1009 if(i!=nbOfTuples-1) oss2 << ", ";
1010 std::string oss3Str(oss2.str());
1011 if(oss3Str.length()<maxNbOfByteInRepr)
1023 * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1024 * mismatch is given.
1026 * \param [in] other the instance to be compared with \a this
1027 * \param [in] prec the precision to compare numeric data of the arrays.
1028 * \param [out] reason In case of inequality returns the reason.
1029 * \sa DataArrayDouble::isEqual
1031 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1033 if(!areInfoEqualsIfNotWhy(other,reason))
1035 return _mem.isEqual(other._mem,prec,reason);
1039 * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1040 * \ref MEDCouplingArrayBasicsCompare.
1041 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1042 * \param [in] prec - precision value to compare numeric data of the arrays.
1043 * \return bool - \a true if the two arrays are equal, \a false else.
1045 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1048 return isEqualIfNotWhy(other,prec,tmp);
1052 * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1053 * \ref MEDCouplingArrayBasicsCompare.
1054 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1055 * \param [in] prec - precision value to compare numeric data of the arrays.
1056 * \return bool - \a true if the values of two arrays are equal, \a false else.
1058 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1061 return _mem.isEqual(other._mem,prec,tmp);
1065 * This method checks that all tuples in \a other are in \a this.
1066 * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1067 * 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.
1069 * \param [in] other - the array having the same number of components than \a this.
1070 * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1071 * \sa DataArrayDouble::findCommonTuples
1073 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1076 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1077 checkAllocated(); other->checkAllocated();
1078 if(getNumberOfComponents()!=other->getNumberOfComponents())
1079 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1080 MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1081 DataArrayInt *c=0,*ci=0;
1082 a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1083 MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1084 int newNbOfTuples=-1;
1085 MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1086 MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1087 tupleIds=ret1.retn();
1088 return newNbOfTuples==getNumberOfTuples();
1092 * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1093 * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1094 * distance separating two points is computed with the infinite norm.
1096 * Indices of coincident tuples are stored in output arrays.
1097 * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1099 * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1100 * MEDCouplingUMesh::mergeNodes().
1101 * \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1102 * considered not coincident.
1103 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1104 * tuples have id strictly lower than \a limitTupleId then they are not returned.
1105 * \param [out] comm - the array holding ids (== indices) of coincident tuples.
1106 * \a comm->getNumberOfComponents() == 1.
1107 * \a comm->getNumberOfTuples() == \a commIndex->back().
1108 * \param [out] commIndex - the array dividing all indices stored in \a comm into
1109 * groups of (indices of) coincident tuples. Its every value is a tuple
1110 * index where a next group of tuples begins. For example the second
1111 * group of tuples in \a comm is described by following range of indices:
1112 * [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1113 * gives the number of groups of coincident tuples.
1114 * \throw If \a this is not allocated.
1115 * \throw If the number of components is not in [1,2,3,4].
1117 * \if ENABLE_EXAMPLES
1118 * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1120 * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example".
1122 * \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1124 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1127 int nbOfCompo=getNumberOfComponents();
1128 if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1129 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1131 int nbOfTuples=getNumberOfTuples();
1133 MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1137 findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1140 findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1143 findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1146 findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1149 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1152 commIndex=cI.retn();
1156 * This methods returns the minimal distance between the two set of points \a this and \a other.
1157 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1158 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1160 * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1161 * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1162 * \return the minimal distance between the two set of points \a this and \a other.
1163 * \sa DataArrayDouble::findClosestTupleId
1165 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1167 MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1168 int nbOfCompo(getNumberOfComponents());
1169 int otherNbTuples(other->getNumberOfTuples());
1170 const double *thisPt(begin()),*otherPt(other->begin());
1171 const int *part1Pt(part1->begin());
1172 double ret=std::numeric_limits<double>::max();
1173 for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1176 for(int j=0;j<nbOfCompo;j++)
1177 tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1179 { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1185 * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1186 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1187 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1189 * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1190 * \sa DataArrayDouble::minimalDistanceTo
1192 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1195 throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1196 checkAllocated(); other->checkAllocated();
1197 std::size_t nbOfCompo(getNumberOfComponents());
1198 if(nbOfCompo!=other->getNumberOfComponents())
1200 std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1201 oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1202 throw INTERP_KERNEL::Exception(oss.str().c_str());
1204 int nbOfTuples=other->getNumberOfTuples();
1205 int thisNbOfTuples=getNumberOfTuples();
1206 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1208 getMinMaxPerComponent(bounds);
1213 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1214 double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1215 double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1216 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1217 FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1222 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1223 double delta=std::max(xDelta,yDelta);
1224 double characSize=sqrt(delta/(double)thisNbOfTuples);
1225 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1226 FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1231 double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1232 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1233 FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1237 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1243 * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1244 * 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
1245 * how many bounding boxes in \a otherBBoxFrmt.
1246 * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1248 * \param [in] otherBBoxFrmt - It is an array .
1249 * \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.
1250 * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1251 * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1252 * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1254 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1257 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1258 if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1259 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1260 std::size_t nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1261 if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1263 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1264 throw INTERP_KERNEL::Exception(oss.str().c_str());
1268 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1269 throw INTERP_KERNEL::Exception(oss.str().c_str());
1271 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1272 const double *thisBBPtr(begin());
1273 int *retPtr(ret->getPointer());
1278 BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1279 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1280 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1285 BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1286 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1287 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1292 BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1293 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1294 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1298 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1305 * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1306 * considered as coordinates of a point in getNumberOfComponents()-dimensional
1307 * space. The distance between tuples is computed using norm2. If several tuples are
1308 * not far each from other than \a prec, only one of them remains in the result
1309 * array. The order of tuples in the result array is same as in \a this one except
1310 * that coincident tuples are excluded.
1311 * \param [in] prec - minimal absolute distance between two tuples at which they are
1312 * considered not coincident.
1313 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1314 * tuples have id strictly lower than \a limitTupleId then they are not excluded.
1315 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1316 * is to delete using decrRef() as it is no more needed.
1317 * \throw If \a this is not allocated.
1318 * \throw If the number of components is not in [1,2,3,4].
1320 * \if ENABLE_EXAMPLES
1321 * \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1324 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1327 DataArrayInt *c0=0,*cI0=0;
1328 findCommonTuples(prec,limitTupleId,c0,cI0);
1329 MCAuto<DataArrayInt> c(c0),cI(cI0);
1330 int newNbOfTuples=-1;
1331 MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1332 return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1336 * Copy all components in a specified order from another DataArrayDouble.
1337 * Both numerical and textual data is copied. The number of tuples in \a this and
1338 * the other array can be different.
1339 * \param [in] a - the array to copy data from.
1340 * \param [in] compoIds - sequence of zero based indices of components, data of which is
1342 * \throw If \a a is NULL.
1343 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1344 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1346 * \if ENABLE_EXAMPLES
1347 * \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1350 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1353 throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1355 copyPartOfStringInfoFrom2(compoIds,*a);
1356 std::size_t partOfCompoSz=compoIds.size();
1357 int nbOfCompo=getNumberOfComponents();
1358 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1359 const double *ac=a->getConstPointer();
1360 double *nc=getPointer();
1361 for(int i=0;i<nbOfTuples;i++)
1362 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1363 nc[nbOfCompo*i+compoIds[j]]=*ac;
1367 * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1369 * \throw If zero is found in \a this array.
1371 void DataArrayDouble::checkNoNullValues() const
1373 const double *tmp=getConstPointer();
1374 std::size_t nbOfElems=getNbOfElems();
1375 const double *where=std::find(tmp,tmp+nbOfElems,0.);
1376 if(where!=tmp+nbOfElems)
1377 throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1381 * Computes minimal and maximal value in each component. An output array is filled
1382 * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1383 * enough memory before calling this method.
1384 * \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1385 * It is filled as follows:<br>
1386 * \a bounds[0] = \c min_of_component_0 <br>
1387 * \a bounds[1] = \c max_of_component_0 <br>
1388 * \a bounds[2] = \c min_of_component_1 <br>
1389 * \a bounds[3] = \c max_of_component_1 <br>
1392 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1395 int dim=getNumberOfComponents();
1396 for (int idim=0; idim<dim; idim++)
1398 bounds[idim*2]=std::numeric_limits<double>::max();
1399 bounds[idim*2+1]=-std::numeric_limits<double>::max();
1401 const double *ptr=getConstPointer();
1402 int nbOfTuples=getNumberOfTuples();
1403 for(int i=0;i<nbOfTuples;i++)
1405 for(int idim=0;idim<dim;idim++)
1407 if(bounds[idim*2]>ptr[i*dim+idim])
1409 bounds[idim*2]=ptr[i*dim+idim];
1411 if(bounds[idim*2+1]<ptr[i*dim+idim])
1413 bounds[idim*2+1]=ptr[i*dim+idim];
1420 * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1421 * to store both the min and max per component of each tuples.
1422 * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1424 * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1426 * \throw If \a this is not allocated yet.
1428 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1431 const double *dataPtr=getConstPointer();
1432 int nbOfCompo=getNumberOfComponents();
1433 int nbTuples=getNumberOfTuples();
1434 MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1435 bbox->alloc(nbTuples,2*nbOfCompo);
1436 double *bboxPtr=bbox->getPointer();
1437 for(int i=0;i<nbTuples;i++)
1439 for(int j=0;j<nbOfCompo;j++)
1441 bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1442 bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1449 * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1450 * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1452 * \param [in] other a DataArrayDouble having same number of components than \a this.
1453 * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1454 * \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.
1455 * \a cI allows to extract information in \a c.
1456 * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1458 * \throw In case of:
1459 * - \a this is not allocated
1460 * - \a other is not allocated or null
1461 * - \a this and \a other do not have the same number of components
1462 * - if number of components of \a this is not in [1,2,3]
1464 * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1466 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1469 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1471 other->checkAllocated();
1472 int nbOfCompo=getNumberOfComponents();
1473 int otherNbOfCompo=other->getNumberOfComponents();
1474 if(nbOfCompo!=otherNbOfCompo)
1475 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1476 int nbOfTuplesOther=other->getNumberOfTuples();
1477 MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1482 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1483 FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1488 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1489 FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1494 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1495 FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1499 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1501 c=cArr.retn(); cI=cIArr.retn();
1505 * 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
1506 * around origin of 'radius' 1.
1508 * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1510 void DataArrayDouble::recenterForMaxPrecision(double eps)
1513 int dim=getNumberOfComponents();
1514 std::vector<double> bounds(2*dim);
1515 getMinMaxPerComponent(&bounds[0]);
1516 for(int i=0;i<dim;i++)
1518 double delta=bounds[2*i+1]-bounds[2*i];
1519 double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1521 applyLin(1./delta,-offset/delta,i);
1523 applyLin(1.,-offset,i);
1528 * Returns the maximal value and all its locations within \a this one-dimensional array.
1529 * \param [out] tupleIds - a new instance of DataArrayInt containing indices of
1530 * tuples holding the maximal value. The caller is to delete it using
1531 * decrRef() as it is no more needed.
1532 * \return double - the maximal value among all values of \a this array.
1533 * \throw If \a this->getNumberOfComponents() != 1
1534 * \throw If \a this->getNumberOfTuples() < 1
1536 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1540 double ret=getMaxValue(tmp);
1541 tupleIds=findIdsInRange(ret,ret);
1546 * Returns the minimal value and all its locations within \a this one-dimensional array.
1547 * \param [out] tupleIds - a new instance of DataArrayInt containing indices of
1548 * tuples holding the minimal value. The caller is to delete it using
1549 * decrRef() as it is no more needed.
1550 * \return double - the minimal value among all values of \a this array.
1551 * \throw If \a this->getNumberOfComponents() != 1
1552 * \throw If \a this->getNumberOfTuples() < 1
1554 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1558 double ret=getMinValue(tmp);
1559 tupleIds=findIdsInRange(ret,ret);
1564 * 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.
1565 * This method only works for single component array.
1567 * \return a value in [ 0, \c this->getNumberOfTuples() )
1569 * \throw If \a this is not allocated
1572 int DataArrayDouble::count(double value, double eps) const
1576 if(getNumberOfComponents()!=1)
1577 throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1578 const double *vals=begin();
1579 int nbOfTuples=getNumberOfTuples();
1580 for(int i=0;i<nbOfTuples;i++,vals++)
1581 if(fabs(*vals-value)<=eps)
1587 * Returns the average value of \a this one-dimensional array.
1588 * \return double - the average value over all values of \a this array.
1589 * \throw If \a this->getNumberOfComponents() != 1
1590 * \throw If \a this->getNumberOfTuples() < 1
1592 double DataArrayDouble::getAverageValue() const
1594 if(getNumberOfComponents()!=1)
1595 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1596 int nbOfTuples=getNumberOfTuples();
1598 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1599 const double *vals=getConstPointer();
1600 double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1601 return ret/nbOfTuples;
1605 * Returns the Euclidean norm of the vector defined by \a this array.
1606 * \return double - the value of the Euclidean norm, i.e.
1607 * the square root of the inner product of vector.
1608 * \throw If \a this is not allocated.
1610 double DataArrayDouble::norm2() const
1614 std::size_t nbOfElems=getNbOfElems();
1615 const double *pt=getConstPointer();
1616 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1622 * Returns the maximum norm of the vector defined by \a this array.
1623 * This method works even if the number of components is different from one.
1624 * If the number of elements in \a this is 0, -1. is returned.
1625 * \return double - the value of the maximum norm, i.e.
1626 * the maximal absolute value among values of \a this array (whatever its number of components).
1627 * \throw If \a this is not allocated.
1629 double DataArrayDouble::normMax() const
1633 std::size_t nbOfElems(getNbOfElems());
1634 const double *pt(getConstPointer());
1635 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1637 double val(std::abs(*pt));
1645 * Returns the maximum norm of for each component of \a this array.
1646 * If the number of elements in \a this is 0, -1. is returned.
1647 * \param [out] res - pointer to an array of result values, of size at least \a
1648 * this->getNumberOfComponents(), that is to be allocated by the caller.
1649 * \throw If \a this is not allocated.
1651 void DataArrayDouble::normMaxPerComponent(double * res) const
1654 std::size_t nbOfTuples(getNumberOfTuples());
1655 int nbOfCompos(getNumberOfComponents());
1656 std::fill(res, res+nbOfCompos, -1.0);
1657 const double *pt(getConstPointer());
1658 for(std::size_t i=0;i<nbOfTuples;i++)
1659 for (int j=0; j<nbOfCompos; j++, pt++)
1661 double val(std::abs(*pt));
1669 * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1670 * This method works even if the number of components is different from one.
1671 * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1672 * \return double - the value of the minimum norm, i.e.
1673 * the minimal absolute value among values of \a this array (whatever its number of components).
1674 * \throw If \a this is not allocated.
1676 double DataArrayDouble::normMin() const
1679 double ret(std::numeric_limits<double>::max());
1680 std::size_t nbOfElems(getNbOfElems());
1681 const double *pt(getConstPointer());
1682 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1684 double val(std::abs(*pt));
1692 * Accumulates values of each component of \a this array.
1693 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
1694 * by the caller, that is filled by this method with sum value for each
1696 * \throw If \a this is not allocated.
1698 void DataArrayDouble::accumulate(double *res) const
1701 const double *ptr=getConstPointer();
1702 int nbTuple=getNumberOfTuples();
1703 int nbComps=getNumberOfComponents();
1704 std::fill(res,res+nbComps,0.);
1705 for(int i=0;i<nbTuple;i++)
1706 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1710 * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1711 * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1714 * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1715 * \a tupleEnd. If not an exception will be thrown.
1717 * \param [in] tupleBg start pointer (included) of input external tuple
1718 * \param [in] tupleEnd end pointer (not included) of input external tuple
1719 * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1720 * \return the min distance.
1721 * \sa MEDCouplingUMesh::distanceToPoint
1723 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1726 int nbTuple=getNumberOfTuples();
1727 int nbComps=getNumberOfComponents();
1728 if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1729 { 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()); }
1731 throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1732 double ret0=std::numeric_limits<double>::max();
1734 const double *work=getConstPointer();
1735 for(int i=0;i<nbTuple;i++)
1738 for(int j=0;j<nbComps;j++,work++)
1739 val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1743 { ret0=val; tupleId=i; }
1749 * Accumulate values of the given component of \a this array.
1750 * \param [in] compId - the index of the component of interest.
1751 * \return double - a sum value of \a compId-th component.
1752 * \throw If \a this is not allocated.
1753 * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1756 double DataArrayDouble::accumulate(int compId) const
1759 const double *ptr=getConstPointer();
1760 int nbTuple=getNumberOfTuples();
1761 int nbComps=getNumberOfComponents();
1762 if(compId<0 || compId>=nbComps)
1763 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1765 for(int i=0;i<nbTuple;i++)
1766 ret+=ptr[i*nbComps+compId];
1771 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1772 * The returned array will have same number of components than \a this and number of tuples equal to
1773 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1775 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1776 * 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.
1778 * \param [in] bgOfIndex - begin (included) of the input index array.
1779 * \param [in] endOfIndex - end (excluded) of the input index array.
1780 * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1782 * \throw If bgOfIndex or end is NULL.
1783 * \throw If input index array is not ascendingly sorted.
1784 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1785 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1787 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1789 if(!bgOfIndex || !endOfIndex)
1790 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1792 int nbCompo=getNumberOfComponents();
1793 int nbOfTuples=getNumberOfTuples();
1794 int sz=(int)std::distance(bgOfIndex,endOfIndex);
1796 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1798 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1799 const int *w=bgOfIndex;
1800 if(*w<0 || *w>=nbOfTuples)
1801 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1802 const double *srcPt=begin()+(*w)*nbCompo;
1803 double *tmp=ret->getPointer();
1804 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1806 std::fill(tmp,tmp+nbCompo,0.);
1809 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1811 if(j>=0 && j<nbOfTuples)
1812 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1815 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
1816 throw INTERP_KERNEL::Exception(oss.str().c_str());
1822 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
1823 throw INTERP_KERNEL::Exception(oss.str().c_str());
1826 ret->copyStringInfoFrom(*this);
1831 * 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.
1832 * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
1833 * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
1835 * \return DataArrayDouble - A newly built array containing cum sum of \a this.
1837 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
1840 checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
1841 int nbOfTuple(getNumberOfTuples());
1842 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
1843 double *ptr(ret->getPointer());
1845 const double *thisPtr(begin());
1846 for(int i=0;i<nbOfTuple;i++)
1847 ptr[i+1]=ptr[i]+thisPtr[i];
1852 * Converts each 2D point defined by the tuple of \a this array from the Polar to the
1853 * Cartesian coordinate system. The two components of the tuple of \a this array are
1854 * considered to contain (1) radius and (2) angle of the point in the Polar CS.
1855 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1856 * contains X and Y coordinates of the point in the Cartesian CS. The caller
1857 * is to delete this array using decrRef() as it is no more needed. The array
1858 * does not contain any textual info on components.
1859 * \throw If \a this->getNumberOfComponents() != 2.
1860 * \sa fromCartToPolar
1862 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
1865 int nbOfComp(getNumberOfComponents());
1867 throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
1868 int nbOfTuple(getNumberOfTuples());
1869 DataArrayDouble *ret(DataArrayDouble::New());
1870 ret->alloc(nbOfTuple,2);
1871 double *w(ret->getPointer());
1872 const double *wIn(getConstPointer());
1873 for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
1875 w[0]=wIn[0]*cos(wIn[1]);
1876 w[1]=wIn[0]*sin(wIn[1]);
1882 * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
1883 * the Cartesian coordinate system. The three components of the tuple of \a this array
1884 * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
1885 * the Cylindrical CS.
1886 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1887 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1888 * on the third component is copied from \a this array. The caller
1889 * is to delete this array using decrRef() as it is no more needed.
1890 * \throw If \a this->getNumberOfComponents() != 3.
1893 DataArrayDouble *DataArrayDouble::fromCylToCart() const
1896 int nbOfComp(getNumberOfComponents());
1898 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
1899 int nbOfTuple(getNumberOfTuples());
1900 DataArrayDouble *ret(DataArrayDouble::New());
1901 ret->alloc(getNumberOfTuples(),3);
1902 double *w(ret->getPointer());
1903 const double *wIn(getConstPointer());
1904 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1906 w[0]=wIn[0]*cos(wIn[1]);
1907 w[1]=wIn[0]*sin(wIn[1]);
1910 ret->setInfoOnComponent(2,getInfoOnComponent(2));
1915 * Converts each 3D point defined by the tuple of \a this array from the Spherical to
1916 * the Cartesian coordinate system. The three components of the tuple of \a this array
1917 * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
1918 * point in the Cylindrical CS.
1919 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1920 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1921 * on the third component is copied from \a this array. The caller
1922 * is to delete this array using decrRef() as it is no more needed.
1923 * \throw If \a this->getNumberOfComponents() != 3.
1924 * \sa fromCartToSpher
1926 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
1929 int nbOfComp(getNumberOfComponents());
1931 throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
1932 int nbOfTuple(getNumberOfTuples());
1933 DataArrayDouble *ret(DataArrayDouble::New());
1934 ret->alloc(getNumberOfTuples(),3);
1935 double *w(ret->getPointer());
1936 const double *wIn(getConstPointer());
1937 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1939 w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
1940 w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
1941 w[2]=wIn[0]*cos(wIn[1]);
1947 * 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.
1948 * 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.
1949 * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
1951 * \param [in] atOfThis - The axis type of \a this.
1952 * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
1954 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
1957 int nbOfComp(getNumberOfComponents());
1958 MCAuto<DataArrayDouble> ret;
1966 ret=fromCylToCart();
1971 ret=fromPolarToCart();
1975 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1979 ret=fromSpherToCart();
1984 ret=fromPolarToCart();
1988 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1990 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
1992 ret->copyStringInfoFrom(*this);
1997 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
1998 * This method expects that \a this has exactly 2 components.
1999 * \sa fromPolarToCart
2001 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
2003 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2005 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2007 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
2008 ret->alloc(nbTuples,2);
2009 double *retPtr(ret->getPointer());
2010 const double *ptr(begin());
2011 for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
2013 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2014 retPtr[1]=atan2(ptr[1],ptr[0]);
2020 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2021 * This method expects that \a this has exactly 3 components.
2024 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2026 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2028 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2030 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2031 ret->alloc(nbTuples,3);
2032 double *retPtr(ret->getPointer());
2033 const double *ptr(begin());
2034 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2036 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2037 retPtr[1]=atan2(ptr[1],ptr[0]);
2044 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2045 * \sa fromSpherToCart
2047 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2049 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2051 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2053 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2054 ret->alloc(nbTuples,3);
2055 double *retPtr(ret->getPointer());
2056 const double *ptr(begin());
2057 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2059 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2060 retPtr[1]=acos(ptr[2]/retPtr[0]);
2061 retPtr[2]=atan2(ptr[1],ptr[0]);
2067 * 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.
2068 * This method expects that \a this has exactly 3 components.
2069 * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2071 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2074 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2075 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2076 checkAllocated(); coords->checkAllocated();
2077 std::size_t nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2079 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2080 if(coords->getNumberOfComponents()!=3)
2081 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2082 if(coords->getNumberOfTuples()!=nbTuples)
2083 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2084 ret->alloc(nbTuples,nbOfComp);
2085 double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2087 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2088 double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2089 const double *coo(coords->begin()),*vectField(begin());
2090 std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2091 for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2093 std::transform(coo,coo+3,center,Ur,std::minus<double>());
2094 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];
2095 double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2096 std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2097 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];
2098 retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2099 retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2100 retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2102 ret->copyStringInfoFrom(*this);
2107 * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2108 * array containing 6 components.
2109 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2110 * is calculated from the tuple <em>(t)</em> of \a this array as follows:
2111 * \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2112 * The caller is to delete this result array using decrRef() as it is no more needed.
2113 * \throw If \a this->getNumberOfComponents() != 6.
2115 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2118 int nbOfComp(getNumberOfComponents());
2120 throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2121 DataArrayDouble *ret=DataArrayDouble::New();
2122 int nbOfTuple=getNumberOfTuples();
2123 ret->alloc(nbOfTuple,1);
2124 const double *src=getConstPointer();
2125 double *dest=ret->getPointer();
2126 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2127 *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];
2132 * Computes the determinant of every square matrix defined by the tuple of \a this
2133 * array, which contains either 4, 6 or 9 components. The case of 6 components
2134 * corresponds to that of the upper triangular matrix.
2135 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2136 * is the determinant of matrix of the corresponding tuple of \a this array.
2137 * The caller is to delete this result array using decrRef() as it is no more
2139 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2141 DataArrayDouble *DataArrayDouble::determinant() const
2144 DataArrayDouble *ret=DataArrayDouble::New();
2145 int nbOfTuple=getNumberOfTuples();
2146 ret->alloc(nbOfTuple,1);
2147 const double *src=getConstPointer();
2148 double *dest=ret->getPointer();
2149 switch(getNumberOfComponents())
2152 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2153 *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];
2156 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2157 *dest=src[0]*src[3]-src[1]*src[2];
2160 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2161 *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];
2165 throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2170 * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2171 * \a this array, which contains 6 components.
2172 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2173 * components, whose each tuple contains the eigenvalues of the matrix of
2174 * corresponding tuple of \a this array.
2175 * The caller is to delete this result array using decrRef() as it is no more
2177 * \throw If \a this->getNumberOfComponents() != 6.
2179 DataArrayDouble *DataArrayDouble::eigenValues() const
2182 int nbOfComp=getNumberOfComponents();
2184 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2185 DataArrayDouble *ret=DataArrayDouble::New();
2186 int nbOfTuple=getNumberOfTuples();
2187 ret->alloc(nbOfTuple,3);
2188 const double *src=getConstPointer();
2189 double *dest=ret->getPointer();
2190 for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2191 INTERP_KERNEL::computeEigenValues6(src,dest);
2196 * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2197 * \a this array, which contains 6 components.
2198 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2199 * components, whose each tuple contains 3 eigenvectors of the matrix of
2200 * corresponding tuple of \a this array.
2201 * The caller is to delete this result array using decrRef() as it is no more
2203 * \throw If \a this->getNumberOfComponents() != 6.
2205 DataArrayDouble *DataArrayDouble::eigenVectors() const
2208 int nbOfComp=getNumberOfComponents();
2210 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2211 DataArrayDouble *ret=DataArrayDouble::New();
2212 int nbOfTuple=getNumberOfTuples();
2213 ret->alloc(nbOfTuple,9);
2214 const double *src=getConstPointer();
2215 double *dest=ret->getPointer();
2216 for(int i=0;i<nbOfTuple;i++,src+=6)
2219 INTERP_KERNEL::computeEigenValues6(src,tmp);
2220 for(int j=0;j<3;j++,dest+=3)
2221 INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2227 * Computes the inverse matrix of every matrix defined by the tuple of \a this
2228 * array, which contains either 4, 6 or 9 components. The case of 6 components
2229 * corresponds to that of the upper triangular matrix.
2230 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2231 * same number of components as \a this one, whose each tuple is the inverse
2232 * matrix of the matrix of corresponding tuple of \a this array.
2233 * The caller is to delete this result array using decrRef() as it is no more
2235 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2237 DataArrayDouble *DataArrayDouble::inverse() const
2240 int nbOfComp=getNumberOfComponents();
2241 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2242 throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2243 DataArrayDouble *ret=DataArrayDouble::New();
2244 int nbOfTuple=getNumberOfTuples();
2245 ret->alloc(nbOfTuple,nbOfComp);
2246 const double *src=getConstPointer();
2247 double *dest=ret->getPointer();
2249 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2251 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];
2252 dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2253 dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2254 dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2255 dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2256 dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2257 dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2259 else if(nbOfComp==4)
2260 for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2262 double det=src[0]*src[3]-src[1]*src[2];
2264 dest[1]=-src[1]/det;
2265 dest[2]=-src[2]/det;
2269 for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2271 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];
2272 dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2273 dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2274 dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2275 dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2276 dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2277 dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2278 dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2279 dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2280 dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2286 * Computes the trace of every matrix defined by the tuple of \a this
2287 * array, which contains either 4, 6 or 9 components. The case of 6 components
2288 * corresponds to that of the upper triangular matrix.
2289 * \return DataArrayDouble * - the new instance of DataArrayDouble containing
2290 * 1 component, whose each tuple is the trace of
2291 * the matrix of corresponding tuple of \a this array.
2292 * The caller is to delete this result array using decrRef() as it is no more
2294 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2296 DataArrayDouble *DataArrayDouble::trace() const
2299 int nbOfComp=getNumberOfComponents();
2300 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2301 throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2302 DataArrayDouble *ret=DataArrayDouble::New();
2303 int nbOfTuple=getNumberOfTuples();
2304 ret->alloc(nbOfTuple,1);
2305 const double *src=getConstPointer();
2306 double *dest=ret->getPointer();
2308 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2309 *dest=src[0]+src[1]+src[2];
2310 else if(nbOfComp==4)
2311 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2312 *dest=src[0]+src[3];
2314 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2315 *dest=src[0]+src[4]+src[8];
2320 * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2321 * \a this array, which contains 6 components.
2322 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2323 * same number of components and tuples as \a this array.
2324 * The caller is to delete this result array using decrRef() as it is no more
2326 * \throw If \a this->getNumberOfComponents() != 6.
2328 DataArrayDouble *DataArrayDouble::deviator() const
2331 int nbOfComp=getNumberOfComponents();
2333 throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2334 DataArrayDouble *ret=DataArrayDouble::New();
2335 int nbOfTuple=getNumberOfTuples();
2336 ret->alloc(nbOfTuple,6);
2337 const double *src=getConstPointer();
2338 double *dest=ret->getPointer();
2339 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2341 double tr=(src[0]+src[1]+src[2])/3.;
2353 * Computes the magnitude of every vector defined by the tuple of
2355 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2356 * same number of tuples as \a this array and one component.
2357 * The caller is to delete this result array using decrRef() as it is no more
2359 * \throw If \a this is not allocated.
2361 DataArrayDouble *DataArrayDouble::magnitude() const
2364 int nbOfComp=getNumberOfComponents();
2365 DataArrayDouble *ret=DataArrayDouble::New();
2366 int nbOfTuple=getNumberOfTuples();
2367 ret->alloc(nbOfTuple,1);
2368 const double *src=getConstPointer();
2369 double *dest=ret->getPointer();
2370 for(int i=0;i<nbOfTuple;i++,dest++)
2373 for(int j=0;j<nbOfComp;j++,src++)
2381 * Computes the maximal value within every tuple of \a this array.
2382 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2383 * same number of tuples as \a this array and one component.
2384 * The caller is to delete this result array using decrRef() as it is no more
2386 * \throw If \a this is not allocated.
2387 * \sa DataArrayDouble::maxPerTupleWithCompoId
2389 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2392 int nbOfComp=getNumberOfComponents();
2393 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2394 int nbOfTuple=getNumberOfTuples();
2395 ret->alloc(nbOfTuple,1);
2396 const double *src=getConstPointer();
2397 double *dest=ret->getPointer();
2398 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2399 *dest=*std::max_element(src,src+nbOfComp);
2404 * Computes the maximal value within every tuple of \a this array and it returns the first component
2405 * id for each tuple that corresponds to the maximal value within the tuple.
2407 * \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2408 * same number of tuples and only one component.
2409 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2410 * same number of tuples as \a this array and one component.
2411 * The caller is to delete this result array using decrRef() as it is no more
2413 * \throw If \a this is not allocated.
2414 * \sa DataArrayDouble::maxPerTuple
2416 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2419 int nbOfComp=getNumberOfComponents();
2420 MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2421 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2422 int nbOfTuple=getNumberOfTuples();
2423 ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2424 const double *src=getConstPointer();
2425 double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2426 for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2428 const double *loc=std::max_element(src,src+nbOfComp);
2430 *dest1=(int)std::distance(src,loc);
2432 compoIdOfMaxPerTuple=ret1.retn();
2437 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2438 * \n This returned array contains the euclidian distance for each tuple in \a this.
2439 * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2440 * \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)
2442 * \warning use this method with care because it can leads to big amount of consumed memory !
2444 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2446 * \throw If \a this is not allocated.
2448 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2450 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2453 int nbOfComp=getNumberOfComponents();
2454 int nbOfTuples=getNumberOfTuples();
2455 const double *inData=getConstPointer();
2456 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2457 ret->alloc(nbOfTuples*nbOfTuples,1);
2458 double *outData=ret->getPointer();
2459 for(int i=0;i<nbOfTuples;i++)
2461 outData[i*nbOfTuples+i]=0.;
2462 for(int j=i+1;j<nbOfTuples;j++)
2465 for(int k=0;k<nbOfComp;k++)
2466 { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2468 outData[i*nbOfTuples+j]=dist;
2469 outData[j*nbOfTuples+i]=dist;
2476 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2477 * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this.
2478 * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2479 * \n Output rectangular matrix is sorted along rows.
2480 * \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)
2482 * \warning use this method with care because it can leads to big amount of consumed memory !
2484 * \param [in] other DataArrayDouble instance having same number of components than \a this.
2485 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2487 * \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.
2489 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2491 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2494 throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2496 other->checkAllocated();
2497 int nbOfComp=getNumberOfComponents();
2498 int otherNbOfComp=other->getNumberOfComponents();
2499 if(nbOfComp!=otherNbOfComp)
2501 std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2502 throw INTERP_KERNEL::Exception(oss.str().c_str());
2504 int nbOfTuples=getNumberOfTuples();
2505 int otherNbOfTuples=other->getNumberOfTuples();
2506 const double *inData=getConstPointer();
2507 const double *inDataOther=other->getConstPointer();
2508 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2509 ret->alloc(otherNbOfTuples*nbOfTuples,1);
2510 double *outData=ret->getPointer();
2511 for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2513 for(int j=0;j<nbOfTuples;j++)
2516 for(int k=0;k<nbOfComp;k++)
2517 { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2519 outData[i*nbOfTuples+j]=dist;
2526 * This method expects that \a this stores 3 tuples containing 2 components each.
2527 * Each of this tuples represent a point into 2D space.
2528 * 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).
2529 * 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[.
2531 * \throw If \a this is not allocated.
2532 * \throw If \a this has not 3 tuples of 2 components
2533 * \throw If tuples/points in \a this are aligned
2535 void DataArrayDouble::asArcOfCircle(double center[2], double& radius, double& ang) const
2538 INTERP_KERNEL::QuadraticPlanarPrecision arcPrec(1e-14);
2539 if(getNumberOfTuples()!=3 && getNumberOfComponents()!=2)
2540 throw INTERP_KERNEL::Exception("DataArrayDouble::asArcCircle : this method expects");
2541 const double *pt(begin());
2542 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]));
2544 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::EdgeLin> e1(new INTERP_KERNEL::EdgeLin(n0,n2)),e2(new INTERP_KERNEL::EdgeLin(n2,n1));
2545 INTERP_KERNEL::SegSegIntersector inters(*e1,*e2);
2546 bool colinearity(inters.areColinears());
2548 throw INTERP_KERNEL::Exception("DataArrayDouble::asArcOfCircle : 3 points in this have been detected as colinear !");
2550 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::EdgeArcCircle> ret(new INTERP_KERNEL::EdgeArcCircle(n0,n2,n1));
2551 const double *c(ret->getCenter());
2552 center[0]=c[0]; center[1]=c[1];
2553 radius=ret->getRadius();
2554 ang=ret->getAngle();
2558 * Sorts value within every tuple of \a this array.
2559 * \param [in] asc - if \a true, the values are sorted in ascending order, else,
2560 * in descending order.
2561 * \throw If \a this is not allocated.
2563 void DataArrayDouble::sortPerTuple(bool asc)
2566 double *pt=getPointer();
2567 int nbOfTuple=getNumberOfTuples();
2568 int nbOfComp=getNumberOfComponents();
2570 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2571 std::sort(pt,pt+nbOfComp);
2573 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2574 std::sort(pt,pt+nbOfComp,std::greater<double>());
2579 * Modify all elements of \a this array, so that
2580 * an element _x_ becomes \f$ numerator / x \f$.
2581 * \warning If an exception is thrown because of presence of 0.0 element in \a this
2582 * array, all elements processed before detection of the zero element remain
2584 * \param [in] numerator - the numerator used to modify array elements.
2585 * \throw If \a this is not allocated.
2586 * \throw If there is an element equal to 0.0 in \a this array.
2588 void DataArrayDouble::applyInv(double numerator)
2591 double *ptr=getPointer();
2592 std::size_t nbOfElems=getNbOfElems();
2593 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2595 if(std::abs(*ptr)>std::numeric_limits<double>::min())
2597 *ptr=numerator/(*ptr);
2601 std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2603 throw INTERP_KERNEL::Exception(oss.str().c_str());
2610 * Modify all elements of \a this array, so that
2611 * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2612 * all values in \a this have to be >= 0 if val is \b not integer.
2613 * \param [in] val - the value used to apply pow on all array elements.
2614 * \throw If \a this is not allocated.
2615 * \warning If an exception is thrown because of presence of 0 element in \a this
2616 * array and \a val is \b not integer, all elements processed before detection of the zero element remain
2619 void DataArrayDouble::applyPow(double val)
2622 double *ptr=getPointer();
2623 std::size_t nbOfElems=getNbOfElems();
2625 bool isInt=((double)val2)==val;
2628 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2634 std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2635 throw INTERP_KERNEL::Exception(oss.str().c_str());
2641 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2642 *ptr=pow(*ptr,val2);
2648 * Modify all elements of \a this array, so that
2649 * an element _x_ becomes \f$ val ^ x \f$.
2650 * \param [in] val - the value used to apply pow on all array elements.
2651 * \throw If \a this is not allocated.
2652 * \throw If \a val < 0.
2653 * \warning If an exception is thrown because of presence of 0 element in \a this
2654 * array, all elements processed before detection of the zero element remain
2657 void DataArrayDouble::applyRPow(double val)
2661 throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2662 double *ptr=getPointer();
2663 std::size_t nbOfElems=getNbOfElems();
2664 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2670 * Returns a new DataArrayDouble created from \a this one by applying \a
2671 * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2672 * For more info see \ref MEDCouplingArrayApplyFunc
2673 * \param [in] nbOfComp - number of components in the result array.
2674 * \param [in] func - the \a FunctionToEvaluate declared as
2675 * \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res),
2676 * where \a pos points to the first component of a tuple of \a this array
2677 * and \a res points to the first component of a tuple of the result array.
2678 * Note that length (number of components) of \a pos can differ from
2680 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2681 * same number of tuples as \a this array.
2682 * The caller is to delete this result array using decrRef() as it is no more
2684 * \throw If \a this is not allocated.
2685 * \throw If \a func returns \a false.
2687 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2690 DataArrayDouble *newArr=DataArrayDouble::New();
2691 int nbOfTuples=getNumberOfTuples();
2692 int oldNbOfComp=getNumberOfComponents();
2693 newArr->alloc(nbOfTuples,nbOfComp);
2694 const double *ptr=getConstPointer();
2695 double *ptrToFill=newArr->getPointer();
2696 for(int i=0;i<nbOfTuples;i++)
2698 if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2700 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2701 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2702 oss << ") : Evaluation of function failed !";
2704 throw INTERP_KERNEL::Exception(oss.str().c_str());
2711 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2712 * tuple of \a this array. Textual data is not copied.
2713 * For more info see \ref MEDCouplingArrayApplyFunc1.
2714 * \param [in] nbOfComp - number of components in the result array.
2715 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2716 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2717 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2718 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2719 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2720 * same number of tuples as \a this array and \a nbOfComp components.
2721 * The caller is to delete this result array using decrRef() as it is no more
2723 * \throw If \a this is not allocated.
2724 * \throw If computing \a func fails.
2726 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2728 INTERP_KERNEL::ExprParser expr(func);
2730 std::set<std::string> vars;
2731 expr.getTrueSetOfVars(vars);
2732 std::vector<std::string> varsV(vars.begin(),vars.end());
2733 return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2737 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2738 * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2739 * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2741 * For more info see \ref MEDCouplingArrayApplyFunc0.
2742 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2743 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2744 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2745 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2746 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2747 * same number of tuples and components as \a this array.
2748 * The caller is to delete this result array using decrRef() as it is no more
2750 * \sa applyFuncOnThis
2751 * \throw If \a this is not allocated.
2752 * \throw If computing \a func fails.
2754 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
2756 int nbOfComp(getNumberOfComponents());
2758 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
2760 int nbOfTuples(getNumberOfTuples());
2761 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2762 newArr->alloc(nbOfTuples,nbOfComp);
2763 INTERP_KERNEL::ExprParser expr(func);
2765 std::set<std::string> vars;
2766 expr.getTrueSetOfVars(vars);
2767 if((int)vars.size()>1)
2769 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 : ";
2770 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2771 throw INTERP_KERNEL::Exception(oss.str().c_str());
2775 expr.prepareFastEvaluator();
2776 newArr->rearrange(1);
2777 newArr->fillWithValue(expr.evaluateDouble());
2778 newArr->rearrange(nbOfComp);
2779 return newArr.retn();
2781 std::vector<std::string> vars2(vars.begin(),vars.end());
2782 double buff,*ptrToFill(newArr->getPointer());
2783 const double *ptr(begin());
2784 std::vector<double> stck;
2785 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2786 expr.prepareFastEvaluator();
2789 for(int i=0;i<nbOfTuples;i++)
2791 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2794 expr.evaluateDoubleInternal(stck);
2795 *ptrToFill=stck.back();
2802 for(int i=0;i<nbOfTuples;i++)
2804 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2809 expr.evaluateDoubleInternalSafe(stck);
2811 catch(INTERP_KERNEL::Exception& e)
2813 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2815 oss << ") : Evaluation of function failed !" << e.what();
2816 throw INTERP_KERNEL::Exception(oss.str().c_str());
2818 *ptrToFill=stck.back();
2823 return newArr.retn();
2827 * This method is a non const method that modify the array in \a this.
2828 * This method only works on one component array. It means that function \a func must
2829 * contain at most one variable.
2830 * This method is a specialization of applyFunc method with one parameter on one component array.
2832 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2833 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2834 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2835 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2839 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
2841 int nbOfComp(getNumberOfComponents());
2843 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
2845 int nbOfTuples(getNumberOfTuples());
2846 INTERP_KERNEL::ExprParser expr(func);
2848 std::set<std::string> vars;
2849 expr.getTrueSetOfVars(vars);
2850 if((int)vars.size()>1)
2852 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 : ";
2853 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2854 throw INTERP_KERNEL::Exception(oss.str().c_str());
2858 expr.prepareFastEvaluator();
2859 std::vector<std::string> compInfo(getInfoOnComponents());
2861 fillWithValue(expr.evaluateDouble());
2862 rearrange(nbOfComp);
2863 setInfoOnComponents(compInfo);
2866 std::vector<std::string> vars2(vars.begin(),vars.end());
2867 double buff,*ptrToFill(getPointer());
2868 const double *ptr(begin());
2869 std::vector<double> stck;
2870 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2871 expr.prepareFastEvaluator();
2874 for(int i=0;i<nbOfTuples;i++)
2876 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2879 expr.evaluateDoubleInternal(stck);
2880 *ptrToFill=stck.back();
2887 for(int i=0;i<nbOfTuples;i++)
2889 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2894 expr.evaluateDoubleInternalSafe(stck);
2896 catch(INTERP_KERNEL::Exception& e)
2898 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2900 oss << ") : Evaluation of function failed !" << e.what();
2901 throw INTERP_KERNEL::Exception(oss.str().c_str());
2903 *ptrToFill=stck.back();
2911 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2912 * tuple of \a this array. Textual data is not copied.
2913 * For more info see \ref MEDCouplingArrayApplyFunc2.
2914 * \param [in] nbOfComp - number of components in the result array.
2915 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2916 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2917 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2918 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2919 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2920 * same number of tuples as \a this array.
2921 * The caller is to delete this result array using decrRef() as it is no more
2923 * \throw If \a this is not allocated.
2924 * \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
2925 * \throw If computing \a func fails.
2927 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
2929 return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
2933 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2934 * tuple of \a this array. Textual data is not copied.
2935 * For more info see \ref MEDCouplingArrayApplyFunc3.
2936 * \param [in] nbOfComp - number of components in the result array.
2937 * \param [in] varsOrder - sequence of vars defining their order.
2938 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2939 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2940 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2941 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2942 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2943 * same number of tuples as \a this array.
2944 * The caller is to delete this result array using decrRef() as it is no more
2946 * \throw If \a this is not allocated.
2947 * \throw If \a func contains vars not in \a varsOrder.
2948 * \throw If computing \a func fails.
2950 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
2953 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
2954 std::vector<std::string> varsOrder2(varsOrder);
2955 int oldNbOfComp(getNumberOfComponents());
2956 for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
2957 varsOrder2.push_back(std::string());
2959 int nbOfTuples(getNumberOfTuples());
2960 INTERP_KERNEL::ExprParser expr(func);
2962 std::set<std::string> vars;
2963 expr.getTrueSetOfVars(vars);
2964 if((int)vars.size()>oldNbOfComp)
2966 std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
2967 oss << vars.size() << " variables : ";
2968 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2969 throw INTERP_KERNEL::Exception(oss.str().c_str());
2971 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2972 newArr->alloc(nbOfTuples,nbOfComp);
2973 INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
2974 double *buffPtr(buff),*ptrToFill;
2975 std::vector<double> stck;
2976 for(int iComp=0;iComp<nbOfComp;iComp++)
2978 expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
2979 expr.prepareFastEvaluator();
2980 const double *ptr(getConstPointer());
2981 ptrToFill=newArr->getPointer()+iComp;
2984 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2986 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2987 expr.evaluateDoubleInternal(stck);
2988 *ptrToFill=stck.back();
2994 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2996 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2999 expr.evaluateDoubleInternalSafe(stck);
3000 *ptrToFill=stck.back();
3003 catch(INTERP_KERNEL::Exception& e)
3005 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3006 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3007 oss << ") : Evaluation of function failed !" << e.what();
3008 throw INTERP_KERNEL::Exception(oss.str().c_str());
3013 return newArr.retn();
3016 void DataArrayDouble::applyFuncFast32(const std::string& func)
3019 INTERP_KERNEL::ExprParser expr(func);
3021 char *funcStr=expr.compileX86();
3023 *((void **)&funcPtr)=funcStr;//he he...
3025 double *ptr=getPointer();
3026 int nbOfComp=getNumberOfComponents();
3027 int nbOfTuples=getNumberOfTuples();
3028 int nbOfElems=nbOfTuples*nbOfComp;
3029 for(int i=0;i<nbOfElems;i++,ptr++)
3034 void DataArrayDouble::applyFuncFast64(const std::string& func)
3037 INTERP_KERNEL::ExprParser expr(func);
3039 char *funcStr=expr.compileX86_64();
3041 *((void **)&funcPtr)=funcStr;//he he...
3043 double *ptr=getPointer();
3044 int nbOfComp=getNumberOfComponents();
3045 int nbOfTuples=getNumberOfTuples();
3046 int nbOfElems=nbOfTuples*nbOfComp;
3047 for(int i=0;i<nbOfElems;i++,ptr++)
3053 * \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.
3055 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3058 if(getNumberOfComponents()!=3)
3059 throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3060 int nbTuples(getNumberOfTuples());
3061 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3062 ret->alloc(nbTuples,3);
3063 Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3067 DataArrayDoubleIterator *DataArrayDouble::iterator()
3069 return new DataArrayDoubleIterator(this);
3073 * Returns a new DataArrayInt containing indices of tuples of \a this one-dimensional
3074 * array whose values are within a given range. Textual data is not copied.
3075 * \param [in] vmin - a lowest acceptable value (included).
3076 * \param [in] vmax - a greatest acceptable value (included).
3077 * \return DataArrayInt * - the new instance of DataArrayInt.
3078 * The caller is to delete this result array using decrRef() as it is no more
3080 * \throw If \a this->getNumberOfComponents() != 1.
3082 * \sa DataArrayDouble::findIdsNotInRange
3084 * \if ENABLE_EXAMPLES
3085 * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3086 * \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3089 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3092 if(getNumberOfComponents()!=1)
3093 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3094 const double *cptr(begin());
3095 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3096 int nbOfTuples(getNumberOfTuples());
3097 for(int i=0;i<nbOfTuples;i++,cptr++)
3098 if(*cptr>=vmin && *cptr<=vmax)
3099 ret->pushBackSilent(i);
3104 * Returns a new DataArrayInt containing indices of tuples of \a this one-dimensional
3105 * array whose values are not within a given range. Textual data is not copied.
3106 * \param [in] vmin - a lowest not acceptable value (excluded).
3107 * \param [in] vmax - a greatest not acceptable value (excluded).
3108 * \return DataArrayInt * - the new instance of DataArrayInt.
3109 * The caller is to delete this result array using decrRef() as it is no more
3111 * \throw If \a this->getNumberOfComponents() != 1.
3113 * \sa DataArrayDouble::findIdsInRange
3115 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3118 if(getNumberOfComponents()!=1)
3119 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3120 const double *cptr(begin());
3121 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3122 int nbOfTuples(getNumberOfTuples());
3123 for(int i=0;i<nbOfTuples;i++,cptr++)
3124 if(*cptr<vmin || *cptr>vmax)
3125 ret->pushBackSilent(i);
3130 * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3131 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3132 * the number of component in the result array is same as that of each of given arrays.
3133 * Info on components is copied from the first of the given arrays. Number of components
3134 * in the given arrays must be the same.
3135 * \param [in] a1 - an array to include in the result array.
3136 * \param [in] a2 - another array to include in the result array.
3137 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3138 * The caller is to delete this result array using decrRef() as it is no more
3140 * \throw If both \a a1 and \a a2 are NULL.
3141 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3143 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3145 std::vector<const DataArrayDouble *> tmp(2);
3146 tmp[0]=a1; tmp[1]=a2;
3147 return Aggregate(tmp);
3151 * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3152 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3153 * the number of component in the result array is same as that of each of given arrays.
3154 * Info on components is copied from the first of the given arrays. Number of components
3155 * in the given arrays must be the same.
3156 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3157 * not the object itself.
3158 * \param [in] arr - a sequence of arrays to include in the result array.
3159 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3160 * The caller is to delete this result array using decrRef() as it is no more
3162 * \throw If all arrays within \a arr are NULL.
3163 * \throw If getNumberOfComponents() of arrays within \a arr.
3165 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3167 std::vector<const DataArrayDouble *> a;
3168 for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3172 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3173 std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3174 std::size_t nbOfComp((*it)->getNumberOfComponents());
3175 int nbt=(*it++)->getNumberOfTuples();
3176 for(int i=1;it!=a.end();it++,i++)
3178 if((*it)->getNumberOfComponents()!=nbOfComp)
3179 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3180 nbt+=(*it)->getNumberOfTuples();
3182 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3183 ret->alloc(nbt,nbOfComp);
3184 double *pt=ret->getPointer();
3185 for(it=a.begin();it!=a.end();it++)
3186 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3187 ret->copyStringInfoFrom(*(a[0]));
3192 * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3193 * the i-th tuple of the result array is a sum of products of j-th components of i-th
3194 * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3195 * Info on components and name is copied from the first of the given arrays.
3196 * Number of tuples and components in the given arrays must be the same.
3197 * \param [in] a1 - a given array.
3198 * \param [in] a2 - another given array.
3199 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3200 * The caller is to delete this result array using decrRef() as it is no more
3202 * \throw If either \a a1 or \a a2 is NULL.
3203 * \throw If any given array is not allocated.
3204 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3205 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3207 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3210 throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3211 a1->checkAllocated();
3212 a2->checkAllocated();
3213 std::size_t nbOfComp(a1->getNumberOfComponents());
3214 if(nbOfComp!=a2->getNumberOfComponents())
3215 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3216 std::size_t nbOfTuple(a1->getNumberOfTuples());
3217 if(nbOfTuple!=a2->getNumberOfTuples())
3218 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3219 DataArrayDouble *ret=DataArrayDouble::New();
3220 ret->alloc(nbOfTuple,1);
3221 double *retPtr=ret->getPointer();
3222 const double *a1Ptr=a1->begin(),*a2Ptr(a2->begin());
3223 for(std::size_t i=0;i<nbOfTuple;i++)
3226 for(std::size_t j=0;j<nbOfComp;j++)
3227 sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3230 ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3231 ret->setName(a1->getName());
3236 * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3237 * the i-th tuple of the result array contains 3 components of a vector which is a cross
3238 * product of two vectors defined by the i-th tuples of given arrays.
3239 * Info on components is copied from the first of the given arrays.
3240 * Number of tuples in the given arrays must be the same.
3241 * Number of components in the given arrays must be 3.
3242 * \param [in] a1 - a given array.
3243 * \param [in] a2 - another given array.
3244 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3245 * The caller is to delete this result array using decrRef() as it is no more
3247 * \throw If either \a a1 or \a a2 is NULL.
3248 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3249 * \throw If \a a1->getNumberOfComponents() != 3
3250 * \throw If \a a2->getNumberOfComponents() != 3
3252 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3255 throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3256 std::size_t nbOfComp(a1->getNumberOfComponents());
3257 if(nbOfComp!=a2->getNumberOfComponents())
3258 throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3260 throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3261 std::size_t nbOfTuple(a1->getNumberOfTuples());
3262 if(nbOfTuple!=a2->getNumberOfTuples())
3263 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3264 DataArrayDouble *ret=DataArrayDouble::New();
3265 ret->alloc(nbOfTuple,3);
3266 double *retPtr=ret->getPointer();
3267 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3268 for(std::size_t i=0;i<nbOfTuple;i++)
3270 retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3271 retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3272 retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3274 ret->copyStringInfoFrom(*a1);
3279 * Returns a new DataArrayDouble containing maximal values of two given arrays.
3280 * Info on components is copied from the first of the given arrays.
3281 * Number of tuples and components in the given arrays must be the same.
3282 * \param [in] a1 - an array to compare values with another one.
3283 * \param [in] a2 - another array to compare values with the first one.
3284 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3285 * The caller is to delete this result array using decrRef() as it is no more
3287 * \throw If either \a a1 or \a a2 is NULL.
3288 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3289 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3291 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3294 throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3295 std::size_t nbOfComp(a1->getNumberOfComponents());
3296 if(nbOfComp!=a2->getNumberOfComponents())
3297 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3298 std::size_t nbOfTuple(a1->getNumberOfTuples());
3299 if(nbOfTuple!=a2->getNumberOfTuples())
3300 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3301 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3302 ret->alloc(nbOfTuple,nbOfComp);
3303 double *retPtr(ret->getPointer());
3304 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3305 std::size_t nbElem(nbOfTuple*nbOfComp);
3306 for(std::size_t i=0;i<nbElem;i++)
3307 retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3308 ret->copyStringInfoFrom(*a1);
3313 * Returns a new DataArrayDouble containing minimal values of two given arrays.
3314 * Info on components is copied from the first of the given arrays.
3315 * Number of tuples and components in the given arrays must be the same.
3316 * \param [in] a1 - an array to compare values with another one.
3317 * \param [in] a2 - another array to compare values with the first one.
3318 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3319 * The caller is to delete this result array using decrRef() as it is no more
3321 * \throw If either \a a1 or \a a2 is NULL.
3322 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3323 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3325 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3328 throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3329 std::size_t nbOfComp(a1->getNumberOfComponents());
3330 if(nbOfComp!=a2->getNumberOfComponents())
3331 throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3332 std::size_t nbOfTuple(a1->getNumberOfTuples());
3333 if(nbOfTuple!=a2->getNumberOfTuples())
3334 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3335 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3336 ret->alloc(nbOfTuple,nbOfComp);
3337 double *retPtr(ret->getPointer());
3338 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3339 std::size_t nbElem(nbOfTuple*nbOfComp);
3340 for(std::size_t i=0;i<nbElem;i++)
3341 retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3342 ret->copyStringInfoFrom(*a1);
3347 * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
3350 * \param [in] a1 - an array to pow up.
3351 * \param [in] a2 - another array to sum up.
3352 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3353 * The caller is to delete this result array using decrRef() as it is no more
3355 * \throw If either \a a1 or \a a2 is NULL.
3356 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3357 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
3358 * \throw If there is a negative value in \a a1.
3360 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
3363 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
3364 int nbOfTuple=a1->getNumberOfTuples();
3365 int nbOfTuple2=a2->getNumberOfTuples();
3366 int nbOfComp=a1->getNumberOfComponents();
3367 int nbOfComp2=a2->getNumberOfComponents();
3368 if(nbOfTuple!=nbOfTuple2)
3369 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
3370 if(nbOfComp!=1 || nbOfComp2!=1)
3371 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
3372 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
3373 const double *ptr1(a1->begin()),*ptr2(a2->begin());
3374 double *ptr=ret->getPointer();
3375 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
3379 *ptr=pow(*ptr1,*ptr2);
3383 std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
3384 throw INTERP_KERNEL::Exception(oss.str().c_str());
3391 * Apply pow on values of another DataArrayDouble to values of \a this one.
3393 * \param [in] other - an array to pow to \a this one.
3394 * \throw If \a other is NULL.
3395 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
3396 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
3397 * \throw If there is a negative value in \a this.
3399 void DataArrayDouble::powEqual(const DataArrayDouble *other)
3402 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
3403 int nbOfTuple=getNumberOfTuples();
3404 int nbOfTuple2=other->getNumberOfTuples();
3405 int nbOfComp=getNumberOfComponents();
3406 int nbOfComp2=other->getNumberOfComponents();
3407 if(nbOfTuple!=nbOfTuple2)
3408 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
3409 if(nbOfComp!=1 || nbOfComp2!=1)
3410 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
3411 double *ptr=getPointer();
3412 const double *ptrc=other->begin();
3413 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
3416 *ptr=pow(*ptr,*ptrc);
3419 std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
3420 throw INTERP_KERNEL::Exception(oss.str().c_str());
3427 * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
3428 * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
3429 * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
3431 * \throw if \a this is not allocated.
3432 * \throw if \a this has not exactly one component.
3434 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
3437 if(getNumberOfComponents()!=1)
3438 throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
3439 int nbt(getNumberOfTuples());
3440 std::vector<bool> ret(nbt);
3441 const double *pt(begin());
3442 for(int i=0;i<nbt;i++)
3446 else if(fabs(pt[i]-1.)<eps)
3450 std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
3451 throw INTERP_KERNEL::Exception(oss.str().c_str());
3458 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3461 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
3466 tinyInfo[0]=getNumberOfTuples();
3467 tinyInfo[1]=getNumberOfComponents();
3477 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3480 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
3484 int nbOfCompo=getNumberOfComponents();
3485 tinyInfo.resize(nbOfCompo+1);
3486 tinyInfo[0]=getName();
3487 for(int i=0;i<nbOfCompo;i++)
3488 tinyInfo[i+1]=getInfoOnComponent(i);
3493 tinyInfo[0]=getName();
3498 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3499 * This method returns if a feeding is needed.
3501 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
3503 int nbOfTuple=tinyInfoI[0];
3504 int nbOfComp=tinyInfoI[1];
3505 if(nbOfTuple!=-1 || nbOfComp!=-1)
3507 alloc(nbOfTuple,nbOfComp);
3514 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3516 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
3518 setName(tinyInfoS[0]);
3521 int nbOfCompo=getNumberOfComponents();
3522 for(int i=0;i<nbOfCompo;i++)
3523 setInfoOnComponent(i,tinyInfoS[i+1]);
3528 * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
3529 * around an axe ( \a center, \a vect) and with angle \a angle.
3531 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3533 if(!center || !vect)
3534 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
3535 double sina(sin(angle));
3536 double cosa(cos(angle));
3537 double vectorNorm[3];
3539 double matrixTmp[9];
3540 double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
3541 if(norm<std::numeric_limits<double>::min())
3542 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
3543 std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
3544 //rotation matrix computation
3545 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;
3546 matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
3547 matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
3548 matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
3549 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
3550 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3551 matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
3552 matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
3553 matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
3554 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
3555 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3556 //rotation matrix computed.
3558 for(int i=0; i<nbNodes; i++)
3560 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
3561 coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
3562 coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
3563 coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
3567 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
3569 double matrix[9],matrix2[9],matrix3[9];
3570 double vect[3],crossVect[3];
3571 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3572 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3573 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3574 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3575 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3576 matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
3577 matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
3578 matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
3579 matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
3580 matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
3581 matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
3582 for(int i=0;i<3;i++)
3583 for(int j=0;j<3;j++)
3586 for(int k=0;k<3;k++)
3587 val+=matrix[3*i+k]*matrix2[3*k+j];
3590 //rotation matrix computed.
3592 for(int i=0; i<nbNodes; i++)
3594 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
3595 coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
3596 coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
3597 coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
3601 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
3603 double vect[3],crossVect[3];
3604 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3605 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3606 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3607 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3608 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3609 baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
3610 baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
3611 baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
3615 * \param [in] seg2 : coordinates of input seg2 expected to have spacedim==2
3616 * \param [in] tri3 : coordinates of input tri3 also expected to have spacedim==2
3617 * \param [out] coeffs : the result of integration normalized to 1. along \a seg2 inside tri3 sorted by the node id of \a tri3
3618 * \param [out] length : the length of seg2. That is too say the length of integration
3620 void DataArrayDouble::ComputeIntegralOfSeg2IntoTri3(const double seg2[4], const double tri3[6], double coeffs[3], double& length)
3622 length=INTERP_KERNEL::norme_vecteur(seg2,seg2+2);
3624 INTERP_KERNEL::mid_of_seg2(seg2,seg2+2,mid);
3625 INTERP_KERNEL::barycentric_coords<2>(tri3,mid,coeffs); // integral along seg2 is equal to value at the center of SEG2 !
3629 * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
3630 * around the center point \a center and with angle \a angle.
3632 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3634 double cosa=cos(angle);
3635 double sina=sin(angle);
3637 matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
3639 for(int i=0; i<nbNodes; i++)
3641 std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
3642 coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
3643 coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
3647 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
3651 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
3656 std::string DataArrayDoubleTuple::repr() const
3658 std::ostringstream oss; oss.precision(17); oss << "(";
3659 for(int i=0;i<_nb_of_compo-1;i++)
3660 oss << _pt[i] << ", ";
3661 oss << _pt[_nb_of_compo-1] << ")";
3665 double DataArrayDoubleTuple::doubleValue() const
3667 return this->zeValue();
3671 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
3672 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
3673 * 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
3674 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
3676 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
3678 return this->buildDA(nbOfTuples,nbOfCompo);
3682 * Returns a new instance of DataArrayInt. The caller is to delete this array
3683 * using decrRef() as it is no more needed.
3685 DataArrayInt *DataArrayInt::New()
3687 return new DataArrayInt;
3691 * Returns the only one value in \a this, if and only if number of elements
3692 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3693 * \return double - the sole value stored in \a this array.
3694 * \throw If at least one of conditions stated above is not fulfilled.
3696 int DataArrayInt::intValue() const
3700 if(getNbOfElems()==1)
3702 return *getConstPointer();
3705 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3708 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3712 * Returns an integer value characterizing \a this array, which is useful for a quick
3713 * comparison of many instances of DataArrayInt.
3714 * \return int - the hash value.
3715 * \throw If \a this is not allocated.
3717 int DataArrayInt::getHashCode() const
3720 std::size_t nbOfElems=getNbOfElems();
3721 int ret=nbOfElems*65536;
3726 const int *pt=begin();
3727 for(std::size_t i=0;i<nbOfElems;i+=delta)
3728 ret0+=pt[i] & 0x1FFF;
3733 * Returns a full copy of \a this. For more info on copying data arrays see
3734 * \ref MEDCouplingArrayBasicsCopyDeep.
3735 * \return DataArrayInt * - a new instance of DataArrayInt.
3737 DataArrayInt32 *DataArrayInt32::deepCopy() const
3739 return new DataArrayInt32(*this);
3743 * Returns a textual and human readable representation of \a this instance of
3744 * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
3745 * \return std::string - text describing \a this DataArrayInt.
3747 * \sa reprNotTooLong, reprZip
3749 std::string DataArrayInt::repr() const
3751 std::ostringstream ret;
3756 std::string DataArrayInt::reprZip() const
3758 std::ostringstream ret;
3763 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
3765 static const char SPACE[4]={' ',' ',' ',' '};
3767 std::string idt(indent,' ');
3768 ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
3771 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
3772 if(std::string(type)=="Int32")
3774 const char *data(reinterpret_cast<const char *>(begin()));
3775 std::size_t sz(getNbOfElems()*sizeof(int));
3776 byteArr->insertAtTheEnd(data,data+sz);
3777 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3779 else if(std::string(type)=="Int8")
3781 INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
3782 std::copy(begin(),end(),(char *)tmp);
3783 byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
3784 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3786 else if(std::string(type)=="UInt8")
3788 INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
3789 std::copy(begin(),end(),(unsigned char *)tmp);
3790 byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
3791 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3794 throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
3798 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
3799 std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
3801 ofs << std::endl << idt << "</DataArray>\n";
3804 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
3806 int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
3807 const int *data=getConstPointer();
3808 stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
3809 if(nbTuples*nbComp>=1)
3811 stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
3812 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
3813 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
3814 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
3817 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
3818 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
3822 * Method that gives a quick overvien of \a this for python.
3824 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
3826 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
3827 stream << "DataArrayInt C++ instance at " << this << ". ";
3830 int nbOfCompo=(int)_info_on_compo.size();
3833 int nbOfTuples=getNumberOfTuples();
3834 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
3835 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
3838 stream << "Number of components : 0.";
3841 stream << "*** No data allocated ****";
3844 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
3846 const int *data=begin();
3847 int nbOfTuples=getNumberOfTuples();
3848 int nbOfCompo=(int)_info_on_compo.size();
3849 std::ostringstream oss2; oss2 << "[";
3850 std::string oss2Str(oss2.str());
3851 bool isFinished=true;
3852 for(int i=0;i<nbOfTuples && isFinished;i++)
3857 for(int j=0;j<nbOfCompo;j++,data++)
3860 if(j!=nbOfCompo-1) oss2 << ", ";
3866 if(i!=nbOfTuples-1) oss2 << ", ";
3867 std::string oss3Str(oss2.str());
3868 if(oss3Str.length()<maxNbOfByteInRepr)
3880 * Computes distribution of values of \a this one-dimensional array between given value
3881 * ranges (casts). This method is typically useful for entity number splitting by types,
3883 * \warning The values contained in \a arrBg should be sorted ascendently. No
3884 * check of this is be done. If not, the result is not warranted.
3885 * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
3886 * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
3887 * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
3888 * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
3889 * should be more than every value in \a this array.
3890 * \param [in] arrEnd - specifies the end of the array \a arrBg, so that
3891 * the last value of \a arrBg is \a arrEnd[ -1 ].
3892 * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
3893 * (same number of tuples and components), the caller is to delete
3894 * using decrRef() as it is no more needed.
3895 * This array contains indices of ranges for every value of \a this array. I.e.
3896 * the i-th value of \a castArr gives the index of range the i-th value of \a this
3897 * belongs to. Or, in other words, this parameter contains for each tuple in \a
3898 * this in which cast it holds.
3899 * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
3900 * array, the caller is to delete using decrRef() as it is no more needed.
3901 * This array contains ranks of values of \a this array within ranges
3902 * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
3903 * the i-th value of \a this array within the \a castArr[ i ]-th range, to which
3904 * the i-th value of \a this belongs to. Or, in other words, this param contains
3905 * for each tuple its rank inside its cast. The rank is computed as difference
3906 * between the value and the lowest value of range.
3907 * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
3908 * ranges (casts) to which at least one value of \a this array belongs.
3909 * Or, in other words, this param contains the casts that \a this contains.
3910 * The caller is to delete this array using decrRef() as it is no more needed.
3912 * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
3913 * the output of this method will be :
3914 * - \a castArr : [1,1,0,0,0,1,1,0,1]
3915 * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
3916 * - \a castsPresent : [0,1]
3918 * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
3919 * range #1 and its rank within this range is 2; etc.
3921 * \throw If \a this->getNumberOfComponents() != 1.
3922 * \throw If \a arrEnd - arrBg < 2.
3923 * \throw If any value of \a this is not less than \a arrEnd[-1].
3925 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
3926 DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
3929 if(getNumberOfComponents()!=1)
3930 throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3931 int nbOfTuples=getNumberOfTuples();
3932 std::size_t nbOfCast=std::distance(arrBg,arrEnd);
3934 throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
3936 const int *work=getConstPointer();
3937 typedef std::reverse_iterator<const int *> rintstart;
3938 rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
3939 rintstart end2(arrBg);
3940 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
3941 MCAuto<DataArrayInt> ret2=DataArrayInt::New();
3942 MCAuto<DataArrayInt> ret3=DataArrayInt::New();
3943 ret1->alloc(nbOfTuples,1);
3944 ret2->alloc(nbOfTuples,1);
3945 int *ret1Ptr=ret1->getPointer();
3946 int *ret2Ptr=ret2->getPointer();
3947 std::set<std::size_t> castsDetected;
3948 for(int i=0;i<nbOfTuples;i++)
3950 rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
3951 std::size_t pos=std::distance(bg,res);
3952 std::size_t pos2=nbOfCast-pos;
3955 ret1Ptr[i]=(int)pos2;
3956 ret2Ptr[i]=work[i]-arrBg[pos2];
3957 castsDetected.insert(pos2);
3961 std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
3962 throw INTERP_KERNEL::Exception(oss.str().c_str());
3965 ret3->alloc((int)castsDetected.size(),1);
3966 std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
3967 castArr=ret1.retn();
3968 rankInsideCast=ret2.retn();
3969 castsPresent=ret3.retn();
3973 * 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 ).
3974 * 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 ).
3975 * This method works only if \a this is allocated and single component. If not an exception will be thrown.
3977 * \param [out] strt - the start of the range (included) if true is returned.
3978 * \param [out] sttoopp - the end of the range (not included) if true is returned.
3979 * \param [out] stteepp - the step of the range if true is returned.
3980 * \return the verdict of the check.
3982 * \sa DataArray::GetNumberOfItemGivenBES
3984 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
3987 if(getNumberOfComponents()!=1)
3988 throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
3989 int nbTuples(getNumberOfTuples());
3991 { strt=0; sttoopp=0; stteepp=1; return true; }
3992 const int *pt(begin());
3995 { sttoopp=strt+1; stteepp=1; return true; }
3996 strt=*pt; sttoopp=pt[nbTuples-1];
4002 int a(sttoopp-1-strt),tmp(strt);
4003 if(a%(nbTuples-1)!=0)
4005 stteepp=a/(nbTuples-1);
4006 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
4014 int a(strt-sttoopp-1),tmp(strt);
4015 if(a%(nbTuples-1)!=0)
4017 stteepp=-(a/(nbTuples-1));
4018 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
4027 * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4028 * i.e. a current value is used as in index to get a new value from \a indArrBg.
4029 * \param [in] indArrBg - pointer to the first element of array of new values to assign
4031 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4032 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4033 * \throw If \a this->getNumberOfComponents() != 1
4034 * \throw If any value of \a this can't be used as a valid index for
4035 * [\a indArrBg, \a indArrEnd).
4037 * \sa changeValue, findIdForEach
4039 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4041 this->checkAllocated();
4042 if(this->getNumberOfComponents()!=1)
4043 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4044 int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4045 for(int i=0;i<nbOfTuples;i++,pt++)
4047 if(*pt>=0 && *pt<nbElemsIn)
4051 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4052 throw INTERP_KERNEL::Exception(oss.str());
4055 this->declareAsNew();
4058 void DataArrayInt::transformWithIndArr(const MapKeyVal<int>& m)
4060 this->checkAllocated();
4061 if(this->getNumberOfComponents()!=1)
4062 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4063 const std::map<int,int>& dat(m.data());
4064 int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4065 for(int i=0;i<nbOfTuples;i++,pt++)
4067 std::map<int,int>::const_iterator it(dat.find(*pt));
4072 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !";
4073 throw INTERP_KERNEL::Exception(oss.str());
4076 this->declareAsNew();
4080 * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from
4081 * values of \a this (\a a) and the given (\a indArr) arrays as follows:
4082 * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
4083 * new value in place \a indArr[ \a v ] is i.
4084 * \param [in] indArrBg - the array holding indices within the result array to assign
4085 * indices of values of \a this array pointing to values of \a indArrBg.
4086 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4087 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4088 * \return DataArrayInt * - the new instance of DataArrayInt.
4089 * The caller is to delete this result array using decrRef() as it is no more
4091 * \throw If \a this->getNumberOfComponents() != 1.
4092 * \throw If any value of \a this array is not a valid index for \a indArrBg array.
4093 * \throw If any value of \a indArrBg is not a valid index for \a this array.
4095 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
4098 if(getNumberOfComponents()!=1)
4099 throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4100 int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
4101 int nbOfTuples=getNumberOfTuples();
4102 const int *pt=getConstPointer();
4103 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4104 ret->alloc(nbOfTuples,1);
4105 ret->fillWithValue(-1);
4106 int *tmp=ret->getPointer();
4107 for(int i=0;i<nbOfTuples;i++,pt++)
4109 if(*pt>=0 && *pt<nbElemsIn)
4111 int pos=indArrBg[*pt];
4112 if(pos>=0 && pos<nbOfTuples)
4116 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
4117 throw INTERP_KERNEL::Exception(oss.str().c_str());
4122 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
4123 throw INTERP_KERNEL::Exception(oss.str().c_str());
4130 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4131 * from values of \a this array, which is supposed to contain a renumbering map in
4132 * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
4133 * To know how to use the renumbering maps see \ref numbering.
4134 * \param [in] newNbOfElem - the number of tuples in the result array.
4135 * \return DataArrayInt * - the new instance of DataArrayInt.
4136 * The caller is to delete this result array using decrRef() as it is no more
4139 * \if ENABLE_EXAMPLES
4140 * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
4141 * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
4144 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
4146 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4147 ret->alloc(newNbOfElem,1);
4148 int nbOfOldNodes(this->getNumberOfTuples());
4149 const int *old2New(begin());
4150 int *pt(ret->getPointer());
4151 for(int i=0;i!=nbOfOldNodes;i++)
4153 int newp(old2New[i]);
4156 if(newp>=0 && newp<newNbOfElem)
4160 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4161 throw INTERP_KERNEL::Exception(oss.str().c_str());
4169 * This method is similar to DataArrayInt::invertArrayO2N2N2O except that
4170 * 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]
4172 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
4174 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4175 ret->alloc(newNbOfElem,1);
4176 int nbOfOldNodes=getNumberOfTuples();
4177 const int *old2New=getConstPointer();
4178 int *pt=ret->getPointer();
4179 for(int i=nbOfOldNodes-1;i>=0;i--)
4181 int newp(old2New[i]);
4184 if(newp>=0 && newp<newNbOfElem)
4188 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4189 throw INTERP_KERNEL::Exception(oss.str().c_str());
4197 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4198 * from values of \a this array, which is supposed to contain a renumbering map in
4199 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4200 * To know how to use the renumbering maps see \ref numbering.
4201 * \param [in] newNbOfElem - the number of tuples in the result array.
4202 * \return DataArrayInt * - the new instance of DataArrayInt.
4203 * The caller is to delete this result array using decrRef() as it is no more
4206 * \if ENABLE_EXAMPLES
4207 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4209 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4210 * \sa invertArrayN2O2O2NOptimized
4213 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
4216 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4217 ret->alloc(oldNbOfElem,1);
4218 const int *new2Old=getConstPointer();
4219 int *pt=ret->getPointer();
4220 std::fill(pt,pt+oldNbOfElem,-1);
4221 int nbOfNewElems=getNumberOfTuples();
4222 for(int i=0;i<nbOfNewElems;i++)
4225 if(v>=0 && v<oldNbOfElem)
4229 std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
4230 throw INTERP_KERNEL::Exception(oss.str().c_str());
4237 * Creates a map, whose contents are computed
4238 * from values of \a this array, which is supposed to contain a renumbering map in
4239 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4240 * To know how to use the renumbering maps see \ref numbering.
4241 * \param [in] newNbOfElem - the number of tuples in the result array.
4242 * \return MapII - the new instance of Map.
4244 * \if ENABLE_EXAMPLES
4245 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4247 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4248 * \sa invertArrayN2O2O2N, giveN2OOptimized, MEDCouplingPointSet::renumberNodesInConn
4251 MCAuto< MapKeyVal<int> > DataArrayInt32::invertArrayN2O2O2NOptimized() const
4254 if(getNumberOfComponents()!=1)
4255 throw INTERP_KERNEL::Exception("DataArrayInt32::invertArrayN2O2O2NOptimized : single component expected !");
4256 MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4257 std::map<int,int>& m(ret->data());
4258 const int *new2Old(begin());
4259 std::size_t nbOfNewElems(this->getNumberOfTuples());
4260 for(std::size_t i=0;i<nbOfNewElems;i++)
4269 * Creates a map, whose contents are computed
4270 * from values of \a this array, which is supposed to contain a renumbering map in
4271 * "New to Old" mode. The result array contains a renumbering map in "New to Old" mode as C++ map for performance reasons.
4273 * \sa invertArrayN2O2O2NOptimized, MEDCouplingPointSet::renumberNodesInConn
4275 MCAuto< MapKeyVal<int> > DataArrayInt32::giveN2OOptimized() const
4278 if(getNumberOfComponents()!=1)
4279 throw INTERP_KERNEL::Exception("DataArrayInt32::giveN2OOptimized : single component expected !");
4280 MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4281 std::map<int,int>& m(ret->data());
4282 const int *new2Old(begin());
4283 std::size_t nbOfNewElems(this->getNumberOfTuples());
4284 for(std::size_t i=0;i<nbOfNewElems;i++)
4293 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4294 * This map, if applied to \a this array, would make it sorted. For example, if
4295 * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4296 * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4297 * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4298 * This method is useful for renumbering (in MED file for example). For more info
4299 * on renumbering see \ref numbering.
4300 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4301 * array using decrRef() as it is no more needed.
4302 * \throw If \a this is not allocated.
4303 * \throw If \a this->getNumberOfComponents() != 1.
4304 * \throw If there are equal values in \a this array.
4306 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
4309 if(getNumberOfComponents()!=1)
4310 throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4311 int nbTuples=getNumberOfTuples();
4312 const int *pt=getConstPointer();
4313 int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
4314 DataArrayInt *ret=DataArrayInt::New();
4315 ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
4320 * 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
4321 * input array \a ids2.
4322 * \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.
4323 * 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
4325 * In case of success both assertion will be true (no throw) :
4326 * \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
4327 * \c ret->transformWithIndArr(ids2)->isEqual(ids1)
4330 * - \a ids1 : [3,1,103,4,6,10,-7,205]
4331 * - \a ids2 : [-7,1,205,10,6,3,103,4]
4332 * - \a return is : [5,1,6,7,4,3,0,2] because ids2[5]==ids1[0], ids2[1]==ids1[1], ids2[6]==ids1[2]...
4334 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4335 * array using decrRef() as it is no more needed.
4336 * \throw If either ids1 or ids2 is null not allocated or not with one components.
4338 * \sa DataArrayInt32::findIdForEach
4340 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
4343 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
4344 if(!ids1->isAllocated() || !ids2->isAllocated())
4345 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
4346 if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
4347 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
4348 if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
4350 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 !";
4351 throw INTERP_KERNEL::Exception(oss.str().c_str());
4353 MCAuto<DataArrayInt> p1(ids1->deepCopy());
4354 MCAuto<DataArrayInt> p2(ids2->deepCopy());
4355 p1->sort(true); p2->sort(true);
4356 if(!p1->isEqualWithoutConsideringStr(*p2))
4357 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
4358 p1=ids1->checkAndPreparePermutation();
4359 p2=ids2->checkAndPreparePermutation();
4360 p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
4361 p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
4366 * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4367 * onto a set of values of size \a targetNb (\a B). The surjective function is
4368 * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4369 * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4370 * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4371 * The first of out arrays returns indices of elements of \a this array, grouped by their
4372 * place in the set \a B. The second out array is the index of the first one; it shows how
4373 * many elements of \a A are mapped into each element of \a B. <br>
4375 * mapping and its usage in renumbering see \ref numbering. <br>
4377 * - \a this: [0,3,2,3,2,2,1,2]
4379 * - \a arr: [0, 6, 2,4,5,7, 1,3]
4380 * - \a arrI: [0,1,2,6,8]
4382 * This result means: <br>
4383 * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4384 * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4385 * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4386 * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] :
4387 * \a arrI[ 2+1 ]]); <br> etc.
4388 * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4389 * than the maximal value of \a A.
4390 * \param [out] arr - a new instance of DataArrayInt returning indices of
4391 * elements of \a this, grouped by their place in the set \a B. The caller is to delete
4392 * this array using decrRef() as it is no more needed.
4393 * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4394 * elements of \a this. The caller is to delete this array using decrRef() as it
4395 * is no more needed.
4396 * \throw If \a this is not allocated.
4397 * \throw If \a this->getNumberOfComponents() != 1.
4398 * \throw If any value in \a this is more or equal to \a targetNb.
4400 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
4403 if(getNumberOfComponents()!=1)
4404 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4405 int nbOfTuples=getNumberOfTuples();
4406 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4407 MCAuto<DataArrayInt> retI(DataArrayInt::New());
4408 retI->alloc(targetNb+1,1);
4409 const int *input=getConstPointer();
4410 std::vector< std::vector<int> > tmp(targetNb);
4411 for(int i=0;i<nbOfTuples;i++)
4414 if(tmp2>=0 && tmp2<targetNb)
4415 tmp[tmp2].push_back(i);
4418 std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4419 throw INTERP_KERNEL::Exception(oss.str().c_str());
4422 int *retIPtr=retI->getPointer();
4424 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4425 retIPtr[1]=retIPtr[0]+(int)((*it1).size());
4426 if(nbOfTuples!=retI->getIJ(targetNb,0))
4427 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4428 ret->alloc(nbOfTuples,1);
4429 int *retPtr=ret->getPointer();
4430 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4431 retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4438 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
4439 * from a zip representation of a surjective format (returned e.g. by
4440 * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
4441 * for example). The result array minimizes the permutation. <br>
4442 * For more info on renumbering see \ref numbering. <br>
4444 * - \a nbOfOldTuples: 10
4445 * - \a arr : [0,3, 5,7,9]
4446 * - \a arrIBg : [0,2,5]
4447 * - \a newNbOfTuples: 7
4448 * - result array : [0,1,2,0,3,4,5,4,6,4]
4450 * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
4451 * \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
4452 * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
4453 * (indices of) equal values. Its every element (except the last one) points to
4454 * the first element of a group of equal values.
4455 * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
4456 * arrIBg is \a arrIEnd[ -1 ].
4457 * \param [out] newNbOfTuples - number of tuples after surjection application.
4458 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4459 * array using decrRef() as it is no more needed.
4460 * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
4462 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
4464 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4465 ret->alloc(nbOfOldTuples,1);
4466 int *pt=ret->getPointer();
4467 std::fill(pt,pt+nbOfOldTuples,-1);
4468 int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
4469 const int *cIPtr=arrIBg;
4470 for(int i=0;i<nbOfGrps;i++)
4471 pt[arr[cIPtr[i]]]=-(i+2);
4473 for(int iNode=0;iNode<nbOfOldTuples;iNode++)
4481 int grpId=-(pt[iNode]+2);
4482 for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
4484 if(arr[j]>=0 && arr[j]<nbOfOldTuples)
4488 std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
4489 throw INTERP_KERNEL::Exception(oss.str().c_str());
4496 newNbOfTuples=newNb;
4501 * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4502 * which if applied to \a this array would make it sorted ascendingly.
4503 * For more info on renumbering see \ref numbering. <br>
4505 * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4506 * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4507 * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2]
4509 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4510 * array using decrRef() as it is no more needed.
4511 * \throw If \a this is not allocated.
4512 * \throw If \a this->getNumberOfComponents() != 1.
4514 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
4517 if(getNumberOfComponents()!=1)
4518 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4519 int nbOfTuples=getNumberOfTuples();
4520 const int *pt=getConstPointer();
4521 std::map<int,int> m;
4522 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4523 ret->alloc(nbOfTuples,1);
4524 int *opt=ret->getPointer();
4525 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4528 std::map<int,int>::iterator it=m.find(val);
4537 m.insert(std::pair<int,int>(val,1));
4541 for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
4543 int vt=(*it).second;
4547 pt=getConstPointer();
4548 opt=ret->getPointer();
4549 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4556 * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4557 * iota(). This method is particularly useful for DataArrayInt instances that represent
4558 * a renumbering array, to check if there is a real need in renumbering.
4559 * This method checks than \a this can be considered as an identity mapping
4560 * of a set having \a sizeExpected elements into itself.
4562 * \param [in] sizeExpected - The number of elements expected.
4563 * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4564 * \throw If \a this is not allocated.
4565 * \throw If \a this->getNumberOfComponents() != 1.
4567 bool DataArrayInt::isIota(int sizeExpected) const
4570 if(getNumberOfComponents()!=1)
4572 int nbOfTuples(getNumberOfTuples());
4573 if(nbOfTuples!=sizeExpected)
4575 const int *pt=getConstPointer();
4576 for(int i=0;i<nbOfTuples;i++,pt++)
4583 * Checks if all values in \a this array are equal to \a val.
4584 * \param [in] val - value to check equality of array values to.
4585 * \return bool - \a true if all values are \a val.
4586 * \throw If \a this is not allocated.
4587 * \throw If \a this->getNumberOfComponents() != 1
4588 * \sa DataArrayInt::checkUniformAndGuess
4590 bool DataArrayInt::isUniform(int val) const
4593 if(getNumberOfComponents()!=1)
4594 throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4595 const int *w(begin()),*end2(end());
4603 * This method checks that \a this is uniform. If not and exception will be thrown.
4604 * In case of uniformity the corresponding value is returned.
4606 * \return int - the unique value contained in this
4607 * \throw If \a this is not allocated.
4608 * \throw If \a this->getNumberOfComponents() != 1
4609 * \throw If \a this is not uniform.
4610 * \sa DataArrayInt::isUniform
4612 int DataArrayInt::checkUniformAndGuess() const
4615 if(getNumberOfComponents()!=1)
4616 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4618 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
4619 const int *w(begin()),*end2(end());
4623 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
4628 * Checks if all values in \a this array are unique.
4629 * \return bool - \a true if condition above is true
4630 * \throw If \a this is not allocated.
4631 * \throw If \a this->getNumberOfComponents() != 1
4633 bool DataArrayInt::hasUniqueValues() const
4636 if(getNumberOfComponents()!=1)
4637 throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4638 std::size_t nbOfTuples(getNumberOfTuples());
4639 std::set<int> s(begin(),end()); // in C++11, should use unordered_set (O(1) complexity)
4640 if (s.size() != nbOfTuples)
4646 * Copy all components in a specified order from another DataArrayInt.
4647 * The specified components become the first ones in \a this array.
4648 * Both numerical and textual data is copied. The number of tuples in \a this and
4649 * the other array can be different.
4650 * \param [in] a - the array to copy data from.
4651 * \param [in] compoIds - sequence of zero based indices of components, data of which is
4653 * \throw If \a a is NULL.
4654 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
4655 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
4657 * \if ENABLE_EXAMPLES
4658 * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
4661 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
4664 throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
4666 a->checkAllocated();
4667 copyPartOfStringInfoFrom2(compoIds,*a);
4668 std::size_t partOfCompoSz=compoIds.size();
4669 int nbOfCompo=getNumberOfComponents();
4670 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
4671 const int *ac=a->getConstPointer();
4672 int *nc=getPointer();
4673 for(int i=0;i<nbOfTuples;i++)
4674 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
4675 nc[nbOfCompo*i+compoIds[j]]=*ac;
4678 DataArrayIntIterator *DataArrayInt::iterator()
4680 return new DataArrayIntIterator(this);
4684 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
4685 * given one. The ids are sorted in the ascending order.
4686 * \param [in] val - the value to find within \a this.
4687 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4688 * array using decrRef() as it is no more needed.
4689 * \throw If \a this is not allocated.
4690 * \throw If \a this->getNumberOfComponents() != 1.
4691 * \sa DataArrayInt::findIdsEqualTuple
4693 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
4696 if(getNumberOfComponents()!=1)
4697 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
4698 const int *cptr(getConstPointer());
4699 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4700 int nbOfTuples=getNumberOfTuples();
4701 for(int i=0;i<nbOfTuples;i++,cptr++)
4703 ret->pushBackSilent(i);
4708 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
4709 * equal to a given one.
4710 * \param [in] val - the value to ignore within \a this.
4711 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4712 * array using decrRef() as it is no more needed.
4713 * \throw If \a this is not allocated.
4714 * \throw If \a this->getNumberOfComponents() != 1.
4716 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
4719 if(getNumberOfComponents()!=1)
4720 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
4721 const int *cptr(getConstPointer());
4722 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4723 int nbOfTuples=getNumberOfTuples();
4724 for(int i=0;i<nbOfTuples;i++,cptr++)
4726 ret->pushBackSilent(i);
4731 * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
4732 * This method is an extension of DataArrayInt::findIdsEqual method.
4734 * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
4735 * \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
4736 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4737 * array using decrRef() as it is no more needed.
4738 * \throw If \a this is not allocated.
4739 * \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
4740 * \throw If \a this->getNumberOfComponents() is equal to 0.
4741 * \sa DataArrayInt::findIdsEqual
4743 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
4745 std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
4747 if(getNumberOfComponents()!=nbOfCompoExp)
4749 std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
4750 throw INTERP_KERNEL::Exception(oss.str().c_str());
4753 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
4754 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4755 const int *bg(begin()),*end2(end()),*work(begin());
4758 work=std::search(work,end2,tupleBg,tupleEnd);
4761 std::size_t pos(std::distance(bg,work));
4762 if(pos%nbOfCompoExp==0)
4763 ret->pushBackSilent(pos/nbOfCompoExp);
4771 * This method finds for each element \a ELT in [valsBg,valsEnd) elements in \a this equal to it. Associated to ELT
4772 * this method will return the tuple id of last element found. If there is no element in \a this equal to ELT
4773 * an exception will be thrown.
4775 * In case of success this[ret]==vals. Samely ret->transformWithIndArr(this->begin(),this->end())==vals.
4776 * Where \a vals is the [valsBg,valsEnd) array and \a ret the array returned by this method.
4777 * This method can be seen as an extension of FindPermutationFromFirstToSecond.
4780 * - \a this: [17,27,2,10,-4,3,12,27,16]
4781 * - \a val : [3,16,-4,27,17]
4782 * - result: [5,8,4,7,0]
4784 * \return - An array of size std::distance(valsBg,valsEnd)
4786 * \sa DataArrayInt32::FindPermutationFromFirstToSecond
4788 MCAuto<DataArrayInt32> DataArrayInt32::findIdForEach(const int *valsBg, const int *valsEnd) const
4790 MCAuto<DataArrayInt32> ret(DataArrayInt32::New());
4791 std::size_t nbOfTuplesOut(std::distance(valsBg,valsEnd));
4792 ret->alloc(nbOfTuplesOut,1);
4793 MCAuto< MapKeyVal<int> > zeMap(invertArrayN2O2O2NOptimized());
4794 const std::map<int,int>& dat(zeMap->data());
4795 int *ptToFeed(ret->getPointer());
4796 for(const int *pt=valsBg;pt!=valsEnd;pt++)
4798 std::map<int,int>::const_iterator it(dat.find(*pt));
4800 *ptToFeed++=(*it).second;
4803 std::ostringstream oss; oss << "DataArrayInt32::findIdForEach : error for element at place " << std::distance(valsBg,pt);
4804 oss << " of input array value is " << *pt << " which is not in this !";
4805 throw INTERP_KERNEL::Exception(oss.str());
4812 * Assigns \a newValue to all elements holding \a oldValue within \a this
4813 * one-dimensional array.
4814 * \param [in] oldValue - the value to replace.
4815 * \param [in] newValue - the value to assign.
4816 * \return int - number of replacements performed.
4817 * \throw If \a this is not allocated.
4818 * \throw If \a this->getNumberOfComponents() != 1.
4820 int DataArrayInt::changeValue(int oldValue, int newValue)
4823 if(getNumberOfComponents()!=1)
4824 throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
4825 if(oldValue==newValue)
4827 int *start(getPointer()),*end2(start+getNbOfElems());
4829 for(int *val=start;val!=end2;val++)
4843 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
4844 * one of given values.
4845 * \param [in] valsBg - an array of values to find within \a this array.
4846 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4847 * the last value of \a valsBg is \a valsEnd[ -1 ].
4848 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4849 * array using decrRef() as it is no more needed.
4850 * \throw If \a this->getNumberOfComponents() != 1.
4852 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
4854 if(getNumberOfComponents()!=1)
4855 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
4856 std::set<int> vals2(valsBg,valsEnd);
4857 const int *cptr(getConstPointer());
4858 std::vector<int> res;
4859 int nbOfTuples(getNumberOfTuples());
4860 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4861 for(int i=0;i<nbOfTuples;i++,cptr++)
4862 if(vals2.find(*cptr)!=vals2.end())
4863 ret->pushBackSilent(i);
4868 * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
4869 * equal to any of given values.
4870 * \param [in] valsBg - an array of values to ignore within \a this array.
4871 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4872 * the last value of \a valsBg is \a valsEnd[ -1 ].
4873 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4874 * array using decrRef() as it is no more needed.
4875 * \throw If \a this->getNumberOfComponents() != 1.
4877 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
4879 if(getNumberOfComponents()!=1)
4880 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
4881 std::set<int> vals2(valsBg,valsEnd);
4882 const int *cptr=getConstPointer();
4883 std::vector<int> res;
4884 int nbOfTuples=getNumberOfTuples();
4885 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4886 for(int i=0;i<nbOfTuples;i++,cptr++)
4887 if(vals2.find(*cptr)==vals2.end())
4888 ret->pushBackSilent(i);
4893 * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
4894 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4895 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4896 * If any the tuple id is returned. If not -1 is returned.
4898 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4899 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4901 * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
4902 * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
4904 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
4907 int nbOfCompo=getNumberOfComponents();
4909 throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
4910 if(nbOfCompo!=(int)tupl.size())
4912 std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
4913 throw INTERP_KERNEL::Exception(oss.str().c_str());
4915 const int *cptr=getConstPointer();
4916 std::size_t nbOfVals=getNbOfElems();
4917 for(const int *work=cptr;work!=cptr+nbOfVals;)
4919 work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
4920 if(work!=cptr+nbOfVals)
4922 if(std::distance(cptr,work)%nbOfCompo!=0)
4925 return std::distance(cptr,work)/nbOfCompo;
4932 * This method searches the sequence specified in input parameter \b vals in \b this.
4933 * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
4934 * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
4935 * \sa DataArrayInt::findIdFirstEqualTuple
4937 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
4940 int nbOfCompo=getNumberOfComponents();
4942 throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
4943 const int *cptr=getConstPointer();
4944 std::size_t nbOfVals=getNbOfElems();
4945 const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
4946 if(loc!=cptr+nbOfVals)
4947 return std::distance(cptr,loc);
4952 * This method expects to be called when number of components of this is equal to one.
4953 * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
4954 * If not any tuple contains \b value -1 is returned.
4955 * \sa DataArrayInt::presenceOfValue
4957 int DataArrayInt::findIdFirstEqual(int value) const
4960 if(getNumberOfComponents()!=1)
4961 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4962 const int *cptr=getConstPointer();
4963 int nbOfTuples=getNumberOfTuples();
4964 const int *ret=std::find(cptr,cptr+nbOfTuples,value);
4965 if(ret!=cptr+nbOfTuples)
4966 return std::distance(cptr,ret);
4971 * This method expects to be called when number of components of this is equal to one.
4972 * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
4973 * If not any tuple contains one of the values contained in 'vals' -1 is returned.
4974 * \sa DataArrayInt::presenceOfValue
4976 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
4979 if(getNumberOfComponents()!=1)
4980 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4981 std::set<int> vals2(vals.begin(),vals.end());
4982 const int *cptr=getConstPointer();
4983 int nbOfTuples=getNumberOfTuples();
4984 for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
4985 if(vals2.find(*w)!=vals2.end())
4986 return std::distance(cptr,w);
4991 * This method returns the number of values in \a this that are equals to input parameter \a value.
4992 * This method only works for single component array.
4994 * \return a value in [ 0, \c this->getNumberOfTuples() )
4996 * \throw If \a this is not allocated
4999 int DataArrayInt::count(int value) const
5003 if(getNumberOfComponents()!=1)
5004 throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5005 const int *vals=begin();
5006 int nbOfTuples=getNumberOfTuples();
5007 for(int i=0;i<nbOfTuples;i++,vals++)
5014 * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
5015 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5016 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5017 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5018 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5019 * \sa DataArrayInt::findIdFirstEqualTuple
5021 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
5023 return findIdFirstEqualTuple(tupl)!=-1;
5028 * Returns \a true if a given value is present within \a this one-dimensional array.
5029 * \param [in] value - the value to find within \a this array.
5030 * \return bool - \a true in case if \a value is present within \a this array.
5031 * \throw If \a this is not allocated.
5032 * \throw If \a this->getNumberOfComponents() != 1.
5033 * \sa findIdFirstEqual()
5035 bool DataArrayInt::presenceOfValue(int value) const
5037 return findIdFirstEqual(value)!=-1;
5041 * This method expects to be called when number of components of this is equal to one.
5042 * This method returns true if it exists a tuple so that the value is contained in \b vals.
5043 * If not any tuple contains one of the values contained in 'vals' false is returned.
5044 * \sa DataArrayInt::findIdFirstEqual
5046 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
5048 return findIdFirstEqual(vals)!=-1;
5052 * Accumulates values of each component of \a this array.
5053 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
5054 * by the caller, that is filled by this method with sum value for each
5056 * \throw If \a this is not allocated.
5058 void DataArrayInt::accumulate(int *res) const
5061 const int *ptr=getConstPointer();
5062 int nbTuple=getNumberOfTuples();
5063 int nbComps=getNumberOfComponents();
5064 std::fill(res,res+nbComps,0);
5065 for(int i=0;i<nbTuple;i++)
5066 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
5069 int DataArrayInt::accumulate(int compId) const
5072 const int *ptr=getConstPointer();
5073 int nbTuple=getNumberOfTuples();
5074 int nbComps=getNumberOfComponents();
5075 if(compId<0 || compId>=nbComps)
5076 throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
5078 for(int i=0;i<nbTuple;i++)
5079 ret+=ptr[i*nbComps+compId];
5084 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
5085 * The returned array will have same number of components than \a this and number of tuples equal to
5086 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
5088 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
5090 * \param [in] bgOfIndex - begin (included) of the input index array.
5091 * \param [in] endOfIndex - end (excluded) of the input index array.
5092 * \return DataArrayInt * - the new instance having the same number of components than \a this.
5094 * \throw If bgOfIndex or end is NULL.
5095 * \throw If input index array is not ascendingly sorted.
5096 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
5097 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
5099 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
5101 if(!bgOfIndex || !endOfIndex)
5102 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
5104 int nbCompo=getNumberOfComponents();
5105 int nbOfTuples=getNumberOfTuples();
5106 int sz=(int)std::distance(bgOfIndex,endOfIndex);
5108 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
5110 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
5111 const int *w=bgOfIndex;
5112 if(*w<0 || *w>=nbOfTuples)
5113 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
5114 const int *srcPt=begin()+(*w)*nbCompo;
5115 int *tmp=ret->getPointer();
5116 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
5118 std::fill(tmp,tmp+nbCompo,0);
5121 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
5123 if(j>=0 && j<nbOfTuples)
5124 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
5127 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
5128 throw INTERP_KERNEL::Exception(oss.str().c_str());
5134 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
5135 throw INTERP_KERNEL::Exception(oss.str().c_str());
5138 ret->copyStringInfoFrom(*this);
5143 * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
5144 * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
5145 * offsetA2</em> and (2)
5146 * the number of component in the result array is same as that of each of given arrays.
5147 * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
5148 * Info on components is copied from the first of the given arrays. Number of components
5149 * in the given arrays must be the same.
5150 * \param [in] a1 - an array to include in the result array.
5151 * \param [in] a2 - another array to include in the result array.
5152 * \param [in] offsetA2 - number of tuples of \a a2 to skip.
5153 * \return DataArrayInt * - the new instance of DataArrayInt.
5154 * The caller is to delete this result array using decrRef() as it is no more
5156 * \throw If either \a a1 or \a a2 is NULL.
5157 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
5159 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
5162 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
5163 std::size_t nbOfComp(a1->getNumberOfComponents());
5164 if(nbOfComp!=a2->getNumberOfComponents())
5165 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
5166 std::size_t nbOfTuple1(a1->getNumberOfTuples()),nbOfTuple2(a2->getNumberOfTuples());
5167 MCAuto<DataArrayInt> ret(DataArrayInt::New());
5168 ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
5169 int *pt=std::copy(a1->begin(),a1->end(),ret->getPointer());
5170 std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
5171 ret->copyStringInfoFrom(*a1);
5176 * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
5177 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
5178 * the number of component in the result array is same as that of each of given arrays.
5179 * Info on components is copied from the first of the given arrays. Number of components
5180 * in the given arrays must be the same.
5181 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
5182 * not the object itself.
5183 * \param [in] arr - a sequence of arrays to include in the result array.
5184 * \return DataArrayInt * - the new instance of DataArrayInt.
5185 * The caller is to delete this result array using decrRef() as it is no more
5187 * \throw If all arrays within \a arr are NULL.
5188 * \throw If getNumberOfComponents() of arrays within \a arr.
5190 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
5192 std::vector<const DataArrayInt *> a;
5193 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5197 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
5198 std::vector<const DataArrayInt *>::const_iterator it=a.begin();
5199 std::size_t nbOfComp((*it)->getNumberOfComponents()),nbt((*it++)->getNumberOfTuples());
5200 for(int i=1;it!=a.end();it++,i++)
5202 if((*it)->getNumberOfComponents()!=nbOfComp)
5203 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
5204 nbt+=(*it)->getNumberOfTuples();
5206 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5207 ret->alloc(nbt,nbOfComp);
5208 int *pt=ret->getPointer();
5209 for(it=a.begin();it!=a.end();it++)
5210 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
5211 ret->copyStringInfoFrom(*(a[0]));
5216 * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
5217 * A packed index array is an allocated array with one component, and at least one tuple. The first element
5218 * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
5219 * 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.
5221 * \return DataArrayInt * - a new object to be managed by the caller.
5223 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
5226 for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
5230 (*it4)->checkAllocated();
5231 if((*it4)->getNumberOfComponents()!=1)
5233 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5234 throw INTERP_KERNEL::Exception(oss.str().c_str());
5236 int nbTupl=(*it4)->getNumberOfTuples();
5239 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5240 throw INTERP_KERNEL::Exception(oss.str().c_str());
5242 if((*it4)->front()!=0)
5244 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
5245 throw INTERP_KERNEL::Exception(oss.str().c_str());
5251 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
5252 throw INTERP_KERNEL::Exception(oss.str().c_str());
5256 throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
5257 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5258 ret->alloc(retSz,1);
5259 int *pt=ret->getPointer(); *pt++=0;
5260 for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
5261 pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
5262 ret->copyStringInfoFrom(*(arrs[0]));
5267 * Returns in a single walk in \a this the min value and the max value in \a this.
5268 * \a this is expected to be single component array.
5270 * \param [out] minValue - the min value in \a this.
5271 * \param [out] maxValue - the max value in \a this.
5273 * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5275 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
5278 if(getNumberOfComponents()!=1)
5279 throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5280 int nbTuples(getNumberOfTuples());
5281 const int *pt(begin());
5282 minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
5283 for(int i=0;i<nbTuples;i++,pt++)
5293 * Modify all elements of \a this array, so that
5294 * an element _x_ becomes \f$ numerator / x \f$.
5295 * \warning If an exception is thrown because of presence of 0 element in \a this
5296 * array, all elements processed before detection of the zero element remain
5298 * \param [in] numerator - the numerator used to modify array elements.
5299 * \throw If \a this is not allocated.
5300 * \throw If there is an element equal to 0 in \a this array.
5302 void DataArrayInt::applyInv(int numerator)
5305 int *ptr=getPointer();
5306 std::size_t nbOfElems=getNbOfElems();
5307 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5311 *ptr=numerator/(*ptr);
5315 std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5317 throw INTERP_KERNEL::Exception(oss.str().c_str());
5324 * Modify all elements of \a this array, so that
5325 * an element _x_ becomes \f$ x / val \f$.
5326 * \param [in] val - the denominator used to modify array elements.
5327 * \throw If \a this is not allocated.
5328 * \throw If \a val == 0.
5330 void DataArrayInt::applyDivideBy(int val)
5333 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5335 int *ptr=getPointer();
5336 std::size_t nbOfElems=getNbOfElems();
5337 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
5342 * Modify all elements of \a this array, so that
5343 * an element _x_ becomes <em> x % val </em>.
5344 * \param [in] val - the divisor used to modify array elements.
5345 * \throw If \a this is not allocated.
5346 * \throw If \a val <= 0.
5348 void DataArrayInt::applyModulus(int val)
5351 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5353 int *ptr=getPointer();
5354 std::size_t nbOfElems=getNbOfElems();
5355 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
5360 * This method works only on data array with one component.
5361 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5362 * this[*id] in [\b vmin,\b vmax)
5364 * \param [in] vmin begin of range. This value is included in range (included).
5365 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5366 * \return a newly allocated data array that the caller should deal with.
5368 * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5370 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
5372 InRange<int> ir(vmin,vmax);
5373 MCAuto<DataArrayInt> ret(findIdsAdv(ir));
5378 * This method works only on data array with one component.
5379 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5380 * this[*id] \b not in [\b vmin,\b vmax)
5382 * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5383 * \param [in] vmax end of range. This value is included in range (included).
5384 * \return a newly allocated data array that the caller should deal with.
5386 * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5388 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
5390 NotInRange<int> nir(vmin,vmax);
5391 MCAuto<DataArrayInt> ret(findIdsAdv(nir));
5396 * This method works only on data array with one component.
5397 * 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.
5399 * \param [in] vmin begin of range. This value is included in range (included).
5400 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5401 * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5402 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
5405 if(getNumberOfComponents()!=1)
5406 throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5407 int nbOfTuples=getNumberOfTuples();
5409 const int *cptr=getConstPointer();
5410 for(int i=0;i<nbOfTuples;i++,cptr++)
5412 if(*cptr>=vmin && *cptr<vmax)
5413 { ret=ret && *cptr==i; }
5416 std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5417 throw INTERP_KERNEL::Exception(oss.str().c_str());
5424 * Modify all elements of \a this array, so that
5425 * an element _x_ becomes <em> val % x </em>.
5426 * \warning If an exception is thrown because of presence of an element <= 0 in \a this
5427 * array, all elements processed before detection of the zero element remain
5429 * \param [in] val - the divident used to modify array elements.
5430 * \throw If \a this is not allocated.
5431 * \throw If there is an element equal to or less than 0 in \a this array.
5433 void DataArrayInt::applyRModulus(int val)
5436 int *ptr=getPointer();
5437 std::size_t nbOfElems=getNbOfElems();
5438 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5446 std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5448 throw INTERP_KERNEL::Exception(oss.str().c_str());
5455 * Modify all elements of \a this array, so that
5456 * an element _x_ becomes <em> val ^ x </em>.
5457 * \param [in] val - the value used to apply pow on all array elements.
5458 * \throw If \a this is not allocated.
5459 * \throw If \a val < 0.
5461 void DataArrayInt::applyPow(int val)
5465 throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5466 int *ptr=getPointer();
5467 std::size_t nbOfElems=getNbOfElems();
5470 std::fill(ptr,ptr+nbOfElems,1);
5473 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5476 for(int j=0;j<val;j++)
5484 * Modify all elements of \a this array, so that
5485 * an element _x_ becomes \f$ val ^ x \f$.
5486 * \param [in] val - the value used to apply pow on all array elements.
5487 * \throw If \a this is not allocated.
5488 * \throw If there is an element < 0 in \a this array.
5489 * \warning If an exception is thrown because of presence of 0 element in \a this
5490 * array, all elements processed before detection of the zero element remain
5493 void DataArrayInt::applyRPow(int val)
5496 int *ptr=getPointer();
5497 std::size_t nbOfElems=getNbOfElems();
5498 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5503 for(int j=0;j<*ptr;j++)
5509 std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5511 throw INTERP_KERNEL::Exception(oss.str().c_str());
5518 * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
5519 * The i-th item of the result array is an ID of a set of elements belonging to a
5520 * unique set of groups, which the i-th element is a part of. This set of elements
5521 * belonging to a unique set of groups is called \a family, so the result array contains
5522 * IDs of families each element belongs to.
5524 * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
5525 * then there are 3 families:
5526 * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
5527 * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
5528 * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
5529 * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
5530 * stands for the element #3 which is in none of groups.
5532 * \param [in] groups - sequence of groups of element IDs.
5533 * \param [in] newNb - total number of elements; it must be more than max ID of element
5535 * \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
5536 * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
5537 * each element with ID from range [0, \a newNb ) belongs to. The caller is to
5538 * delete this array using decrRef() as it is no more needed.
5539 * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
5541 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
5543 std::vector<const DataArrayInt *> groups2;
5544 for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
5546 groups2.push_back(*it4);
5547 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5548 ret->alloc(newNb,1);
5549 int *retPtr=ret->getPointer();
5550 std::fill(retPtr,retPtr+newNb,0);
5552 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
5554 const int *ptr=(*iter)->getConstPointer();
5555 std::size_t nbOfElem=(*iter)->getNbOfElems();
5557 for(int j=0;j<sfid;j++)
5560 for(std::size_t i=0;i<nbOfElem;i++)
5562 if(ptr[i]>=0 && ptr[i]<newNb)
5564 if(retPtr[ptr[i]]==j)
5572 std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
5574 throw INTERP_KERNEL::Exception(oss.str().c_str());
5581 fidsOfGroups.clear();
5582 fidsOfGroups.resize(groups2.size());
5584 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
5587 const int *ptr=(*iter)->getConstPointer();
5588 std::size_t nbOfElem=(*iter)->getNbOfElems();
5589 for(const int *p=ptr;p!=ptr+nbOfElem;p++)
5590 tmp.insert(retPtr[*p]);
5591 fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
5597 * Returns a new DataArrayInt which contains all elements of given one-dimensional
5598 * arrays. The result array does not contain any duplicates and its values
5599 * are sorted in ascending order.
5600 * \param [in] arr - sequence of DataArrayInt's to unite.
5601 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5602 * array using decrRef() as it is no more needed.
5603 * \throw If any \a arr[i] is not allocated.
5604 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5606 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
5608 std::vector<const DataArrayInt *> a;
5609 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5612 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5614 (*it)->checkAllocated();
5615 if((*it)->getNumberOfComponents()!=1)
5616 throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
5620 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5622 const int *pt=(*it)->getConstPointer();
5623 int nbOfTuples=(*it)->getNumberOfTuples();
5624 r.insert(pt,pt+nbOfTuples);
5626 DataArrayInt *ret=DataArrayInt::New();
5627 ret->alloc((int)r.size(),1);
5628 std::copy(r.begin(),r.end(),ret->getPointer());
5633 * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
5634 * arrays. The result array does not contain any duplicates and its values
5635 * are sorted in ascending order.
5636 * \param [in] arr - sequence of DataArrayInt's to intersect.
5637 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5638 * array using decrRef() as it is no more needed.
5639 * \throw If any \a arr[i] is not allocated.
5640 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5642 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
5644 std::vector<const DataArrayInt *> a;
5645 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5648 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5650 (*it)->checkAllocated();
5651 if((*it)->getNumberOfComponents()!=1)
5652 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
5656 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5658 const int *pt=(*it)->getConstPointer();
5659 int nbOfTuples=(*it)->getNumberOfTuples();
5660 std::set<int> s1(pt,pt+nbOfTuples);
5664 std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
5670 DataArrayInt *ret(DataArrayInt::New());
5671 ret->alloc((int)r.size(),1);
5672 std::copy(r.begin(),r.end(),ret->getPointer());
5677 namespace MEDCouplingImpl
5682 OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
5683 void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
5692 OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
5693 void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
5702 * This method returns the list of ids in ascending mode so that v[id]==true.
5704 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
5706 int sz((int)std::count(v.begin(),v.end(),true));
5707 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5708 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
5713 * This method returns the list of ids in ascending mode so that v[id]==false.
5715 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
5717 int sz((int)std::count(v.begin(),v.end(),false));
5718 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5719 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
5724 * This method allows to put a vector of vector of integer into a more compact data structure (skyline).
5725 * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
5727 * \param [in] v the input data structure to be translate into skyline format.
5728 * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
5729 * \param [out] dataIndex the second element of the skyline format.
5731 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
5733 int sz((int)v.size());
5734 MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
5735 ret1->alloc(sz+1,1);
5736 int *pt(ret1->getPointer()); *pt=0;
5737 for(int i=0;i<sz;i++,pt++)
5738 pt[1]=pt[0]+(int)v[i].size();
5739 ret0->alloc(ret1->back(),1);
5740 pt=ret0->getPointer();
5741 for(int i=0;i<sz;i++)
5742 pt=std::copy(v[i].begin(),v[i].end(),pt);
5743 data=ret0.retn(); dataIndex=ret1.retn();
5747 * Returns a new DataArrayInt which contains a complement of elements of \a this
5748 * one-dimensional array. I.e. the result array contains all elements from the range [0,
5749 * \a nbOfElement) not present in \a this array.
5750 * \param [in] nbOfElement - maximal size of the result array.
5751 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5752 * array using decrRef() as it is no more needed.
5753 * \throw If \a this is not allocated.
5754 * \throw If \a this->getNumberOfComponents() != 1.
5755 * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
5758 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
5761 if(getNumberOfComponents()!=1)
5762 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
5763 std::vector<bool> tmp(nbOfElement);
5764 const int *pt=getConstPointer();
5765 int nbOfTuples=getNumberOfTuples();
5766 for(const int *w=pt;w!=pt+nbOfTuples;w++)
5767 if(*w>=0 && *w<nbOfElement)
5770 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
5771 int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
5772 DataArrayInt *ret=DataArrayInt::New();
5773 ret->alloc(nbOfRetVal,1);
5775 int *retPtr=ret->getPointer();
5776 for(int i=0;i<nbOfElement;i++)
5783 * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
5784 * from an \a other one-dimensional array.
5785 * \param [in] other - a DataArrayInt containing elements not to include in the result array.
5786 * \return DataArrayInt * - a new instance of DataArrayInt with one component. The
5787 * caller is to delete this array using decrRef() as it is no more needed.
5788 * \throw If \a other is NULL.
5789 * \throw If \a other is not allocated.
5790 * \throw If \a other->getNumberOfComponents() != 1.
5791 * \throw If \a this is not allocated.
5792 * \throw If \a this->getNumberOfComponents() != 1.
5793 * \sa DataArrayInt::buildSubstractionOptimized()
5795 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
5798 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
5800 other->checkAllocated();
5801 if(getNumberOfComponents()!=1)
5802 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
5803 if(other->getNumberOfComponents()!=1)
5804 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
5805 const int *pt=getConstPointer();
5806 int nbOfTuples=getNumberOfTuples();
5807 std::set<int> s1(pt,pt+nbOfTuples);
5808 pt=other->getConstPointer();
5809 nbOfTuples=other->getNumberOfTuples();
5810 std::set<int> s2(pt,pt+nbOfTuples);
5812 std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
5813 DataArrayInt *ret=DataArrayInt::New();
5814 ret->alloc((int)r.size(),1);
5815 std::copy(r.begin(),r.end(),ret->getPointer());
5820 * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
5821 * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
5823 * \param [in] other an array with one component and expected to be sorted ascendingly.
5824 * \ret list of ids in \a this but not in \a other.
5825 * \sa DataArrayInt::buildSubstraction
5827 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
5829 static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
5830 if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
5831 checkAllocated(); other->checkAllocated();
5832 if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5833 if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5834 const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
5835 const int *work1(pt1Bg),*work2(pt2Bg);
5836 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5837 for(;work1!=pt1End;work1++)
5839 if(work2!=pt2End && *work1==*work2)
5842 ret->pushBackSilent(*work1);
5849 * Returns a new DataArrayInt which contains all elements of \a this and a given
5850 * one-dimensional arrays. The result array does not contain any duplicates
5851 * and its values are sorted in ascending order.
5852 * \param [in] other - an array to unite with \a this one.
5853 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5854 * array using decrRef() as it is no more needed.
5855 * \throw If \a this or \a other is not allocated.
5856 * \throw If \a this->getNumberOfComponents() != 1.
5857 * \throw If \a other->getNumberOfComponents() != 1.
5859 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
5861 std::vector<const DataArrayInt *>arrs(2);
5862 arrs[0]=this; arrs[1]=other;
5863 return BuildUnion(arrs);
5868 * Returns a new DataArrayInt which contains elements present in both \a this and a given
5869 * one-dimensional arrays. The result array does not contain any duplicates
5870 * and its values are sorted in ascending order.
5871 * \param [in] other - an array to intersect with \a this one.
5872 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5873 * array using decrRef() as it is no more needed.
5874 * \throw If \a this or \a other is not allocated.
5875 * \throw If \a this->getNumberOfComponents() != 1.
5876 * \throw If \a other->getNumberOfComponents() != 1.
5878 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
5880 std::vector<const DataArrayInt *>arrs(2);
5881 arrs[0]=this; arrs[1]=other;
5882 return BuildIntersection(arrs);
5886 * This method can be applied on allocated with one component DataArrayInt instance.
5887 * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
5888 * 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]
5890 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5891 * \throw if \a this is not allocated or if \a this has not exactly one component.
5892 * \sa DataArrayInt::buildUniqueNotSorted
5894 DataArrayInt *DataArrayInt::buildUnique() const
5897 if(getNumberOfComponents()!=1)
5898 throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
5899 int nbOfTuples=getNumberOfTuples();
5900 MCAuto<DataArrayInt> tmp=deepCopy();
5901 int *data=tmp->getPointer();
5902 int *last=std::unique(data,data+nbOfTuples);
5903 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5904 ret->alloc(std::distance(data,last),1);
5905 std::copy(data,last,ret->getPointer());
5910 * This method can be applied on allocated with one component DataArrayInt instance.
5911 * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
5913 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5915 * \throw if \a this is not allocated or if \a this has not exactly one component.
5917 * \sa DataArrayInt::buildUnique
5919 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
5922 if(getNumberOfComponents()!=1)
5923 throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
5925 getMinMaxValues(minVal,maxVal);
5926 std::vector<bool> b(maxVal-minVal+1,false);
5927 const int *ptBg(begin()),*endBg(end());
5928 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5929 for(const int *pt=ptBg;pt!=endBg;pt++)
5933 ret->pushBackSilent(*pt);
5937 ret->copyStringInfoFrom(*this);
5942 * Returns a new DataArrayInt which contains size of every of groups described by \a this
5943 * "index" array. Such "index" array is returned for example by
5944 * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
5945 * "MEDCouplingUMesh::buildDescendingConnectivity" and
5946 * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
5947 * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
5948 * This method performs the reverse operation of DataArrayInt::computeOffsetsFull.
5949 * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
5950 * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
5951 * The caller is to delete this array using decrRef() as it is no more needed.
5952 * \throw If \a this is not allocated.
5953 * \throw If \a this->getNumberOfComponents() != 1.
5954 * \throw If \a this->getNumberOfTuples() < 2.
5957 * - this contains [1,3,6,7,7,9,15]
5958 * - result array contains [2,3,1,0,2,6],
5959 * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
5961 * \sa DataArrayInt::computeOffsetsFull
5963 DataArrayInt *DataArrayInt::deltaShiftIndex() const
5966 if(getNumberOfComponents()!=1)
5967 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
5968 int nbOfTuples=getNumberOfTuples();
5970 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
5971 const int *ptr=getConstPointer();
5972 DataArrayInt *ret=DataArrayInt::New();
5973 ret->alloc(nbOfTuples-1,1);
5974 int *out=ret->getPointer();
5975 std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
5980 * Modifies \a this one-dimensional array so that value of each element \a x
5981 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5982 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
5983 * and components remains the same.<br>
5984 * This method is useful for allToAllV in MPI with contiguous policy. This method
5985 * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
5987 * \throw If \a this is not allocated.
5988 * \throw If \a this->getNumberOfComponents() != 1.
5991 * - Before \a this contains [3,5,1,2,0,8]
5992 * - After \a this contains [0,3,8,9,11,11]<br>
5993 * Note that the last element 19 = 11 + 8 is missing because size of \a this
5994 * array is retained and thus there is no space to store the last element.
5996 void DataArrayInt::computeOffsets()
5999 if(getNumberOfComponents()!=1)
6000 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
6001 int nbOfTuples=getNumberOfTuples();
6004 int *work=getPointer();
6007 for(int i=1;i<nbOfTuples;i++)
6010 work[i]=work[i-1]+tmp;
6018 * Modifies \a this one-dimensional array so that value of each element \a x
6019 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
6020 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
6021 * components remains the same and number of tuples is inceamented by one.<br>
6022 * This method is useful for allToAllV in MPI with contiguous policy. This method
6023 * differs from computeOffsets() in that the number of tuples is changed by this one.
6024 * This method performs the reverse operation of DataArrayInt::deltaShiftIndex.
6025 * \throw If \a this is not allocated.
6026 * \throw If \a this->getNumberOfComponents() != 1.
6029 * - Before \a this contains [3,5,1,2,0,8]
6030 * - After \a this contains [0,3,8,9,11,11,19]<br>
6031 * \sa DataArrayInt::deltaShiftIndex
6033 void DataArrayInt::computeOffsetsFull()
6036 if(getNumberOfComponents()!=1)
6037 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
6038 int nbOfTuples=getNumberOfTuples();
6039 int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
6040 const int *work=getConstPointer();
6042 for(int i=0;i<nbOfTuples;i++)
6043 ret[i+1]=work[i]+ret[i];
6044 useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
6049 * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
6050 * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
6051 * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
6052 * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
6053 * filling completely one of the ranges in \a this.
6055 * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
6056 * \param [out] rangeIdsFetched the range ids fetched
6057 * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
6058 * \a idsInInputListThatFetch is a part of input \a listOfIds.
6060 * \sa DataArrayInt::computeOffsetsFull
6063 * - \a this : [0,3,7,9,15,18]
6064 * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
6065 * - \a rangeIdsFetched result array: [0,2,4]
6066 * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
6067 * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
6070 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
6073 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
6074 listOfIds->checkAllocated(); checkAllocated();
6075 if(listOfIds->getNumberOfComponents()!=1)
6076 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
6077 if(getNumberOfComponents()!=1)
6078 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
6079 MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
6080 MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
6081 const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
6082 const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
6083 while(tupPtr!=tupEnd && offPtr!=offEnd)
6085 if(*tupPtr==*offPtr)
6088 while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
6091 ret0->pushBackSilent((int)std::distance(offBg,offPtr));
6092 ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
6097 { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
6099 rangeIdsFetched=ret0.retn();
6100 idsInInputListThatFetch=ret1.retn();
6104 * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
6105 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6106 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6107 * beginning within the "iota" array. And \a this is a one-dimensional array
6108 * considered as a selector of groups described by \a offsets to include into the result array.
6109 * \throw If \a offsets is NULL.
6110 * \throw If \a offsets is not allocated.
6111 * \throw If \a offsets->getNumberOfComponents() != 1.
6112 * \throw If \a offsets is not monotonically increasing.
6113 * \throw If \a this is not allocated.
6114 * \throw If \a this->getNumberOfComponents() != 1.
6115 * \throw If any element of \a this is not a valid index for \a offsets array.
6118 * - \a this: [0,2,3]
6119 * - \a offsets: [0,3,6,10,14,20]
6120 * - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
6121 * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
6122 * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) +
6123 * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) +
6124 * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
6126 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
6129 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
6131 if(getNumberOfComponents()!=1)
6132 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
6133 offsets->checkAllocated();
6134 if(offsets->getNumberOfComponents()!=1)
6135 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
6136 int othNbTuples=offsets->getNumberOfTuples()-1;
6137 int nbOfTuples=getNumberOfTuples();
6138 int retNbOftuples=0;
6139 const int *work=getConstPointer();
6140 const int *offPtr=offsets->getConstPointer();
6141 for(int i=0;i<nbOfTuples;i++)
6144 if(val>=0 && val<othNbTuples)
6146 int delta=offPtr[val+1]-offPtr[val];
6148 retNbOftuples+=delta;
6151 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
6152 throw INTERP_KERNEL::Exception(oss.str().c_str());
6157 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
6158 oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
6159 throw INTERP_KERNEL::Exception(oss.str().c_str());
6162 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6163 ret->alloc(retNbOftuples,1);
6164 int *retPtr=ret->getPointer();
6165 for(int i=0;i<nbOfTuples;i++)
6168 int start=offPtr[val];
6169 int off=offPtr[val+1]-start;
6170 for(int j=0;j<off;j++,retPtr++)
6177 * Returns a new DataArrayInt whose contents is computed using \a this that must be a
6178 * scaled array (monotonically increasing).
6179 from that of \a this and \a
6180 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6181 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6182 * beginning within the "iota" array. And \a this is a one-dimensional array
6183 * considered as a selector of groups described by \a offsets to include into the result array.
6184 * \throw If \a is NULL.
6185 * \throw If \a this is not allocated.
6186 * \throw If \a this->getNumberOfComponents() != 1.
6187 * \throw If \a this->getNumberOfTuples() == 0.
6188 * \throw If \a this is not monotonically increasing.
6189 * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
6192 * - \a bg , \a stop and \a step : (0,5,2)
6193 * - \a this: [0,3,6,10,14,20]
6194 * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
6196 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
6199 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
6200 if(getNumberOfComponents()!=1)
6201 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
6202 int nbOfTuples(getNumberOfTuples());
6204 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
6205 const int *ids(begin());
6206 int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
6207 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6209 if(pos>=0 && pos<nbOfTuples-1)
6211 int delta(ids[pos+1]-ids[pos]);
6215 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
6216 throw INTERP_KERNEL::Exception(oss.str().c_str());
6221 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";
6222 throw INTERP_KERNEL::Exception(oss.str().c_str());
6225 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6226 int *retPtr(ret->getPointer());
6228 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6230 int delta(ids[pos+1]-ids[pos]);
6231 for(int j=0;j<delta;j++,retPtr++)
6238 * 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.
6239 * 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
6240 * in tuple **i** of returned DataArrayInt.
6241 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6243 * 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)]
6244 * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6246 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6247 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6248 * \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
6249 * is thrown if no ranges in \a ranges contains value in \a this.
6251 * \sa DataArrayInt::findIdInRangeForEachTuple
6253 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
6256 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6257 if(ranges->getNumberOfComponents()!=2)
6258 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6260 if(getNumberOfComponents()!=1)
6261 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6262 int nbTuples=getNumberOfTuples();
6263 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6264 int nbOfRanges=ranges->getNumberOfTuples();
6265 const int *rangesPtr=ranges->getConstPointer();
6266 int *retPtr=ret->getPointer();
6267 const int *inPtr=getConstPointer();
6268 for(int i=0;i<nbTuples;i++,retPtr++)
6272 for(int j=0;j<nbOfRanges && !found;j++)
6273 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6274 { *retPtr=j; found=true; }
6279 std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6280 throw INTERP_KERNEL::Exception(oss.str().c_str());
6287 * 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.
6288 * 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
6289 * in tuple **i** of returned DataArrayInt.
6290 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6292 * 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)]
6293 * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6294 * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6296 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6297 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6298 * \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
6299 * is thrown if no ranges in \a ranges contains value in \a this.
6300 * \sa DataArrayInt::findRangeIdForEachTuple
6302 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
6305 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6306 if(ranges->getNumberOfComponents()!=2)
6307 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6309 if(getNumberOfComponents()!=1)
6310 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6311 int nbTuples=getNumberOfTuples();
6312 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6313 int nbOfRanges=ranges->getNumberOfTuples();
6314 const int *rangesPtr=ranges->getConstPointer();
6315 int *retPtr=ret->getPointer();
6316 const int *inPtr=getConstPointer();
6317 for(int i=0;i<nbTuples;i++,retPtr++)
6321 for(int j=0;j<nbOfRanges && !found;j++)
6322 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6323 { *retPtr=val-rangesPtr[2*j]; found=true; }
6328 std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6329 throw INTERP_KERNEL::Exception(oss.str().c_str());
6336 * \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).
6337 * 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).
6338 * 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 !
6339 * If this method has correctly worked, \a this will be able to be considered as a linked list.
6340 * This method does nothing if number of tuples is lower of equal to 1.
6342 * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internally the connectibity without any coordinates consideration.
6344 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
6346 void DataArrayInt::sortEachPairToMakeALinkedList()
6349 if(getNumberOfComponents()!=2)
6350 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6351 int nbOfTuples(getNumberOfTuples());
6354 int *conn(getPointer());
6355 for(int i=1;i<nbOfTuples;i++,conn+=2)
6359 if(conn[2]==conn[3])
6361 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6362 throw INTERP_KERNEL::Exception(oss.str().c_str());
6364 if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6365 std::swap(conn[2],conn[3]);
6366 //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6367 if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6369 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6370 throw INTERP_KERNEL::Exception(oss.str().c_str());
6375 if(conn[0]==conn[1] || conn[2]==conn[3])
6376 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6379 s.insert(conn,conn+4);
6381 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6382 if(std::count(conn,conn+4,conn[0])==2)
6387 if(conn[2]==conn[0])
6391 std::copy(tmp,tmp+4,conn);
6394 {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6395 if(conn[1]==conn[3])
6396 std::swap(conn[2],conn[3]);
6403 * \a this is expected to be a correctly linked list of pairs.
6405 * \sa DataArrayInt::sortEachPairToMakeALinkedList
6407 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
6410 checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6411 int nbTuples(getNumberOfTuples());
6413 throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6414 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
6415 const int *thisPtr(begin());
6416 int *retPtr(ret->getPointer());
6417 retPtr[0]=thisPtr[0];
6418 for(int i=0;i<nbTuples;i++)
6420 retPtr[i+1]=thisPtr[2*i+1];
6422 if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6424 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 ?";
6425 throw INTERP_KERNEL::Exception(oss.str());
6432 * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6433 * But the number of components can be different from one.
6434 * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6436 DataArrayInt *DataArrayInt::getDifferentValues() const
6440 ret.insert(begin(),end());
6441 MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
6442 std::copy(ret.begin(),ret.end(),ret2->getPointer());
6447 * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6448 * them it tells which tuple id have this id.
6449 * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6450 * This method returns two arrays having same size.
6451 * 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.
6452 * 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]]
6454 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
6457 if(getNumberOfComponents()!=1)
6458 throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6460 std::map<int,int> m,m2,m3;
6461 for(const int *w=begin();w!=end();w++)
6463 differentIds.resize(m.size());
6464 std::vector<DataArrayInt *> ret(m.size());
6465 std::vector<int *> retPtr(m.size());
6466 for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
6469 ret[id]=DataArrayInt::New();
6470 ret[id]->alloc((*it).second,1);
6471 retPtr[id]=ret[id]->getPointer();
6472 differentIds[id]=(*it).first;
6475 for(const int *w=begin();w!=end();w++,id++)
6477 retPtr[m2[*w]][m3[*w]++]=id;
6483 * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6484 * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6486 * \param [in] nbOfSlices - number of slices expected.
6487 * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6489 * \sa DataArray::GetSlice
6490 * \throw If \a this is not allocated or not with exactly one component.
6491 * \throw If an element in \a this if < 0.
6493 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
6495 if(!isAllocated() || getNumberOfComponents()!=1)
6496 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6498 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6499 int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
6500 int sumPerSlc(sum/nbOfSlices),pos(0);
6501 const int *w(begin());
6502 std::vector< std::pair<int,int> > ret(nbOfSlices);
6503 for(int i=0;i<nbOfSlices;i++)
6505 std::pair<int,int> p(pos,-1);
6507 while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6511 p.second=nbOfTuples;
6518 * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6520 * 1. The arrays have same number of tuples and components. Then each value of
6521 * the result array (_a_) is a division of the corresponding values of \a a1 and
6522 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6523 * 2. The arrays have same number of tuples and one array, say _a2_, has one
6525 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6526 * 3. The arrays have same number of components and one array, say _a2_, has one
6528 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6530 * Info on components is copied either from the first array (in the first case) or from
6531 * the array with maximal number of elements (getNbOfElems()).
6532 * \warning No check of division by zero is performed!
6533 * \param [in] a1 - a dividend array.
6534 * \param [in] a2 - a divisor array.
6535 * \return DataArrayInt * - the new instance of DataArrayInt.
6536 * The caller is to delete this result array using decrRef() as it is no more
6538 * \throw If either \a a1 or \a a2 is NULL.
6539 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6540 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6541 * none of them has number of tuples or components equal to 1.
6543 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
6546 throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6547 int nbOfTuple1=a1->getNumberOfTuples();
6548 int nbOfTuple2=a2->getNumberOfTuples();
6549 int nbOfComp1=a1->getNumberOfComponents();
6550 int nbOfComp2=a2->getNumberOfComponents();
6551 if(nbOfTuple2==nbOfTuple1)
6553 if(nbOfComp1==nbOfComp2)
6555 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6556 ret->alloc(nbOfTuple2,nbOfComp1);
6557 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
6558 ret->copyStringInfoFrom(*a1);
6561 else if(nbOfComp2==1)
6563 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6564 ret->alloc(nbOfTuple1,nbOfComp1);
6565 const int *a2Ptr=a2->getConstPointer();
6566 const int *a1Ptr=a1->getConstPointer();
6567 int *res=ret->getPointer();
6568 for(int i=0;i<nbOfTuple1;i++)
6569 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
6570 ret->copyStringInfoFrom(*a1);
6575 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6579 else if(nbOfTuple2==1)
6581 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6582 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6583 ret->alloc(nbOfTuple1,nbOfComp1);
6584 const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6585 int *pt=ret->getPointer();
6586 for(int i=0;i<nbOfTuple1;i++)
6587 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
6588 ret->copyStringInfoFrom(*a1);
6593 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
6599 * Modify \a this array so that each value becomes a modulus of division of this value by
6600 * a value of another DataArrayInt. There are 3 valid cases.
6601 * 1. The arrays have same number of tuples and components. Then each value of
6602 * \a this array is divided by the corresponding value of \a other one, i.e.:
6603 * _a_ [ i, j ] %= _other_ [ i, j ].
6604 * 2. The arrays have same number of tuples and \a other array has one component. Then
6605 * _a_ [ i, j ] %= _other_ [ i, 0 ].
6606 * 3. The arrays have same number of components and \a other array has one tuple. Then
6607 * _a_ [ i, j ] %= _a2_ [ 0, j ].
6609 * \warning No check of division by zero is performed!
6610 * \param [in] other - a divisor array.
6611 * \throw If \a other is NULL.
6612 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
6613 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
6614 * \a other has number of both tuples and components not equal to 1.
6616 void DataArrayInt::modulusEqual(const DataArrayInt *other)
6619 throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
6620 const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
6621 checkAllocated(); other->checkAllocated();
6622 int nbOfTuple=getNumberOfTuples();
6623 int nbOfTuple2=other->getNumberOfTuples();
6624 int nbOfComp=getNumberOfComponents();
6625 int nbOfComp2=other->getNumberOfComponents();
6626 if(nbOfTuple==nbOfTuple2)
6628 if(nbOfComp==nbOfComp2)
6630 std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
6632 else if(nbOfComp2==1)
6634 if(nbOfComp2==nbOfComp)
6636 int *ptr=getPointer();
6637 const int *ptrc=other->getConstPointer();
6638 for(int i=0;i<nbOfTuple;i++)
6639 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
6642 throw INTERP_KERNEL::Exception(msg);
6645 throw INTERP_KERNEL::Exception(msg);
6647 else if(nbOfTuple2==1)
6649 int *ptr=getPointer();
6650 const int *ptrc=other->getConstPointer();
6651 for(int i=0;i<nbOfTuple;i++)
6652 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
6655 throw INTERP_KERNEL::Exception(msg);
6660 * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
6663 * \param [in] a1 - an array to pow up.
6664 * \param [in] a2 - another array to sum up.
6665 * \return DataArrayInt * - the new instance of DataArrayInt.
6666 * The caller is to delete this result array using decrRef() as it is no more
6668 * \throw If either \a a1 or \a a2 is NULL.
6669 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6670 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
6671 * \throw If there is a negative value in \a a2.
6673 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
6676 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
6677 int nbOfTuple=a1->getNumberOfTuples();
6678 int nbOfTuple2=a2->getNumberOfTuples();
6679 int nbOfComp=a1->getNumberOfComponents();
6680 int nbOfComp2=a2->getNumberOfComponents();
6681 if(nbOfTuple!=nbOfTuple2)
6682 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
6683 if(nbOfComp!=1 || nbOfComp2!=1)
6684 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
6685 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
6686 const int *ptr1(a1->begin()),*ptr2(a2->begin());
6687 int *ptr=ret->getPointer();
6688 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
6693 for(int j=0;j<*ptr2;j++)
6699 std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
6700 throw INTERP_KERNEL::Exception(oss.str().c_str());
6707 * Apply pow on values of another DataArrayInt to values of \a this one.
6709 * \param [in] other - an array to pow to \a this one.
6710 * \throw If \a other is NULL.
6711 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
6712 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
6713 * \throw If there is a negative value in \a other.
6715 void DataArrayInt::powEqual(const DataArrayInt *other)
6718 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
6719 int nbOfTuple=getNumberOfTuples();
6720 int nbOfTuple2=other->getNumberOfTuples();
6721 int nbOfComp=getNumberOfComponents();
6722 int nbOfComp2=other->getNumberOfComponents();
6723 if(nbOfTuple!=nbOfTuple2)
6724 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
6725 if(nbOfComp!=1 || nbOfComp2!=1)
6726 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
6727 int *ptr=getPointer();
6728 const int *ptrc=other->begin();
6729 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
6734 for(int j=0;j<*ptrc;j++)
6740 std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
6741 throw INTERP_KERNEL::Exception(oss.str().c_str());
6748 * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
6749 * This map, if applied to \a start array, would make it sorted. For example, if
6750 * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
6751 * [5,6,0,3,2,7,1,4].
6752 * \param [in] start - pointer to the first element of the array for which the
6753 * permutation map is computed.
6754 * \param [in] end - pointer specifying the end of the array \a start, so that
6755 * the last value of \a start is \a end[ -1 ].
6756 * \return int * - the result permutation array that the caller is to delete as it is no
6758 * \throw If there are equal values in the input array.
6760 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
6762 std::size_t sz=std::distance(start,end);
6763 int *ret=(int *)malloc(sz*sizeof(int));
6764 int *work=new int[sz];
6765 std::copy(start,end,work);
6766 std::sort(work,work+sz);
6767 if(std::unique(work,work+sz)!=work+sz)
6771 throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
6773 std::map<int,int> m;
6774 for(int *workPt=work;workPt!=work+sz;workPt++)
6775 m[*workPt]=(int)std::distance(work,workPt);
6777 for(const int *iter=start;iter!=end;iter++,iter2++)
6784 * Returns a new DataArrayInt containing an arithmetic progression
6785 * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step )
6787 * \param [in] begin - the start value of the result sequence.
6788 * \param [in] end - limiting value, so that every value of the result array is less than
6790 * \param [in] step - specifies the increment or decrement.
6791 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6792 * array using decrRef() as it is no more needed.
6793 * \throw If \a step == 0.
6794 * \throw If \a end < \a begin && \a step > 0.
6795 * \throw If \a end > \a begin && \a step < 0.
6797 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
6799 int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
6800 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6801 ret->alloc(nbOfTuples,1);
6802 int *ptr=ret->getPointer();
6805 for(int i=begin;i<end;i+=step,ptr++)
6810 for(int i=begin;i>end;i+=step,ptr++)
6817 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6820 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
6825 tinyInfo[0]=getNumberOfTuples();
6826 tinyInfo[1]=getNumberOfComponents();
6836 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6839 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
6843 int nbOfCompo=getNumberOfComponents();
6844 tinyInfo.resize(nbOfCompo+1);
6845 tinyInfo[0]=getName();
6846 for(int i=0;i<nbOfCompo;i++)
6847 tinyInfo[i+1]=getInfoOnComponent(i);
6852 tinyInfo[0]=getName();
6857 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6858 * This method returns if a feeding is needed.
6860 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
6862 int nbOfTuple=tinyInfoI[0];
6863 int nbOfComp=tinyInfoI[1];
6864 if(nbOfTuple!=-1 || nbOfComp!=-1)
6866 alloc(nbOfTuple,nbOfComp);
6873 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6874 * This method returns if a feeding is needed.
6876 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
6878 setName(tinyInfoS[0]);
6881 int nbOfCompo=tinyInfoI[1];
6882 for(int i=0;i<nbOfCompo;i++)
6883 setInfoOnComponent(i,tinyInfoS[i+1]);
6887 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
6891 DataArrayInt32Tuple::DataArrayInt32Tuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
6895 std::string DataArrayIntTuple::repr() const
6897 std::ostringstream oss; oss << "(";
6898 for(int i=0;i<_nb_of_compo-1;i++)
6899 oss << _pt[i] << ", ";
6900 oss << _pt[_nb_of_compo-1] << ")";
6904 int DataArrayIntTuple::intValue() const
6906 return this->zeValue();
6910 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
6911 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
6912 * 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
6913 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
6915 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
6917 return this->buildDA(nbOfTuples,nbOfCompo);