Salome HOME
- MEDLoader ReadField is now dealing int32, float64 and float32
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (EDF R&D)
20
21 #include "MEDCouplingMemArray.txx"
22
23 #include "BBTree.txx"
24 #include "GenMathFormulae.hxx"
25 #include "InterpKernelAutoPtr.hxx"
26 #include "InterpKernelExprParser.hxx"
27
28 #include "InterpKernelAutoPtr.hxx"
29 #include "InterpKernelGeo2DEdgeArcCircle.hxx"
30 #include "InterpKernelAutoPtr.hxx"
31 #include "InterpKernelGeo2DNode.hxx"
32 #include "InterpKernelGeo2DEdgeLin.hxx"
33
34 #include <set>
35 #include <cmath>
36 #include <limits>
37 #include <numeric>
38 #include <algorithm>
39 #include <functional>
40
41 typedef double (*MYFUNCPTR)(double);
42
43 using namespace MEDCoupling;
44
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
57 // [ABN] : Newest Intel compilers need this:
58 template Traits<Int32>::ArrayType* MEDCoupling::DataArrayTuple<Int32>::buildDA(int, int) const;
59 template Traits<double>::ArrayType* MEDCoupling::DataArrayTuple<double>::buildDA(int, int) const;
60 template Traits<float>::ArrayType* MEDCoupling::DataArrayTuple<float>::buildDA(int, int) const;
61
62
63 template<int SPACEDIM>
64 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
65 {
66   const double *coordsPtr=getConstPointer();
67   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
68   std::vector<bool> isDone(nbNodes);
69   for(int i=0;i<nbNodes;i++)
70     {
71       if(!isDone[i])
72         {
73           std::vector<int> intersectingElems;
74           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
75           if(intersectingElems.size()>1)
76             {
77               std::vector<int> commonNodes;
78               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
79                 if(*it!=i)
80                   if(*it>=limitNodeId)
81                     {
82                       commonNodes.push_back(*it);
83                       isDone[*it]=true;
84                     }
85               if(!commonNodes.empty())
86                 {
87                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
88                   c->pushBackSilent(i);
89                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
90                 }
91             }
92         }
93     }
94 }
95
96 template<int SPACEDIM>
97 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
98                                                 DataArrayInt *c, DataArrayInt *cI)
99 {
100   for(int i=0;i<nbOfTuples;i++)
101     {
102       std::vector<int> intersectingElems;
103       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
104       std::vector<int> commonNodes;
105       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
106         commonNodes.push_back(*it);
107       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
108       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
109     }
110 }
111
112 template<int SPACEDIM>
113 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
114 {
115   double distOpt(dist);
116   const double *p(pos);
117   int *r(res);
118   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
119     {
120       while(true)
121         {
122           int elem=-1;
123           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
124           if(ret!=std::numeric_limits<double>::max())
125             {
126               distOpt=std::max(ret,1e-4);
127               *r=elem;
128               break;
129             }
130           else
131             { distOpt=2*distOpt; continue; }
132         }
133     }
134 }
135
136 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
137 {
138   if(nbOfTuples<=0)
139     throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
140   if(nbOfShift>=0)
141     {
142       return nbOfShift%nbOfTuples;
143     }
144   else
145     {
146       int tmp(-nbOfShift);
147       tmp=tmp%nbOfTuples;
148       return nbOfTuples-tmp;
149     }
150 }
151
152 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
153 {
154   std::size_t sz1=_name.capacity();
155   std::size_t sz2=_info_on_compo.capacity();
156   std::size_t sz3=0;
157   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
158     sz3+=(*it).capacity();
159   return sz1+sz2+sz3;
160 }
161
162 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
163 {
164   return std::vector<const BigMemoryObject *>();
165 }
166
167 /*!
168  * Sets the attribute \a _name of \a this array.
169  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
170  *  \param [in] name - new array name
171  */
172 void DataArray::setName(const std::string& name)
173 {
174   _name=name;
175 }
176
177 /*!
178  * Copies textual data from an \a other DataArray. The copied data are
179  * - the name attribute,
180  * - the information of components.
181  *
182  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
183  *
184  *  \param [in] other - another instance of DataArray to copy the textual data from.
185  *  \throw If number of components of \a this array differs from that of the \a other.
186  */
187 void DataArray::copyStringInfoFrom(const DataArray& other)
188 {
189   if(_info_on_compo.size()!=other._info_on_compo.size())
190     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
191   _name=other._name;
192   _info_on_compo=other._info_on_compo;
193 }
194
195 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
196 {
197   int nbOfCompoOth=other.getNumberOfComponents();
198   std::size_t newNbOfCompo=compoIds.size();
199   for(std::size_t i=0;i<newNbOfCompo;i++)
200     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
201       {
202         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
203         throw INTERP_KERNEL::Exception(oss.str().c_str());
204       }
205   for(std::size_t i=0;i<newNbOfCompo;i++)
206     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
207 }
208
209 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
210 {
211   std::size_t nbOfCompo(getNumberOfComponents());
212   std::size_t partOfCompoToSet=compoIds.size();
213   if(partOfCompoToSet!=other.getNumberOfComponents())
214     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
215   for(std::size_t i=0;i<partOfCompoToSet;i++)
216     if(compoIds[i]>=(int)nbOfCompo || compoIds[i]<0)
217       {
218         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
219         throw INTERP_KERNEL::Exception(oss.str().c_str());
220       }
221   for(std::size_t i=0;i<partOfCompoToSet;i++)
222     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
223 }
224
225 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
226 {
227   std::ostringstream oss;
228   if(_name!=other._name)
229     {
230       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
231       reason=oss.str();
232       return false;
233     }
234   if(_info_on_compo!=other._info_on_compo)
235     {
236       oss << "Components DataArray mismatch : \nThis components=";
237       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
238         oss << "\"" << *it << "\",";
239       oss << "\nOther components=";
240       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
241         oss << "\"" << *it << "\",";
242       reason=oss.str();
243       return false;
244     }
245   return true;
246 }
247
248 /*!
249  * Compares textual information of \a this DataArray with that of an \a other one.
250  * The compared data are
251  * - the name attribute,
252  * - the information of components.
253  *
254  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
255  *  \param [in] other - another instance of DataArray to compare the textual data of.
256  *  \return bool - \a true if the textual information is same, \a false else.
257  */
258 bool DataArray::areInfoEquals(const DataArray& other) const
259 {
260   std::string tmp;
261   return areInfoEqualsIfNotWhy(other,tmp);
262 }
263
264 void DataArray::reprWithoutNameStream(std::ostream& stream) const
265 {
266   stream << "Number of components : "<< getNumberOfComponents() << "\n";
267   stream << "Info of these components : ";
268   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
269     stream << "\"" << *iter << "\"   ";
270   stream << "\n";
271 }
272
273 std::string DataArray::cppRepr(const std::string& varName) const
274 {
275   std::ostringstream ret;
276   reprCppStream(varName,ret);
277   return ret.str();
278 }
279
280 /*!
281  * Sets information on all components. To know more on format of this information
282  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
283  *  \param [in] info - a vector of strings.
284  *  \throw If size of \a info differs from the number of components of \a this.
285  */
286 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
287 {
288   if(getNumberOfComponents()!=info.size())
289     {
290       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
291       throw INTERP_KERNEL::Exception(oss.str().c_str());
292     }
293   _info_on_compo=info;
294 }
295
296 /*!
297  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
298  * type of \a this and \a aBase.
299  *
300  * \throw If \a aBase and \a this do not have the same type.
301  *
302  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
303  */
304 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
305 {
306   if(!aBase)
307     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
308   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
309   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
310   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
311   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
312   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
313   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
314   if(this1 && a1)
315     {
316       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
317       return ;
318     }
319   if(this2 && a2)
320     {
321       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
322       return ;
323     }
324   if(this3 && a3)
325     {
326       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
327       return ;
328     }
329   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
330 }
331
332 std::vector<std::string> DataArray::getVarsOnComponent() const
333 {
334   int nbOfCompo=(int)_info_on_compo.size();
335   std::vector<std::string> ret(nbOfCompo);
336   for(int i=0;i<nbOfCompo;i++)
337     ret[i]=getVarOnComponent(i);
338   return ret;
339 }
340
341 std::vector<std::string> DataArray::getUnitsOnComponent() const
342 {
343   int nbOfCompo=(int)_info_on_compo.size();
344   std::vector<std::string> ret(nbOfCompo);
345   for(int i=0;i<nbOfCompo;i++)
346     ret[i]=getUnitOnComponent(i);
347   return ret;
348 }
349
350 /*!
351  * Returns information on a component specified by an index.
352  * To know more on format of this information
353  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
354  *  \param [in] i - the index (zero based) of the component of interest.
355  *  \return std::string - a string containing the information on \a i-th component.
356  *  \throw If \a i is not a valid component index.
357  */
358 std::string DataArray::getInfoOnComponent(int i) const
359 {
360   if(i<(int)_info_on_compo.size() && i>=0)
361     return _info_on_compo[i];
362   else
363     {
364       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();
365       throw INTERP_KERNEL::Exception(oss.str().c_str());
366     }
367 }
368
369 /*!
370  * Returns the var part of the full information of the \a i-th component.
371  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
372  * \c getVarOnComponent(0) returns "SIGXY".
373  * If a unit part of information is not detected by presence of
374  * two square brackets, then the full information is returned.
375  * To read more about the component information format, see
376  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
377  *  \param [in] i - the index (zero based) of the component of interest.
378  *  \return std::string - a string containing the var information, or the full info.
379  *  \throw If \a i is not a valid component index.
380  */
381 std::string DataArray::getVarOnComponent(int i) const
382 {
383   if(i<(int)_info_on_compo.size() && i>=0)
384     {
385       return GetVarNameFromInfo(_info_on_compo[i]);
386     }
387   else
388     {
389       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();
390       throw INTERP_KERNEL::Exception(oss.str().c_str());
391     }
392 }
393
394 /*!
395  * Returns the unit part of the full information of the \a i-th component.
396  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
397  * \c getUnitOnComponent(0) returns " N/m^2".
398  * If a unit part of information is not detected by presence of
399  * two square brackets, then an empty string is returned.
400  * To read more about the component information format, see
401  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
402  *  \param [in] i - the index (zero based) of the component of interest.
403  *  \return std::string - a string containing the unit information, if any, or "".
404  *  \throw If \a i is not a valid component index.
405  */
406 std::string DataArray::getUnitOnComponent(int i) const
407 {
408   if(i<(int)_info_on_compo.size() && i>=0)
409     {
410       return GetUnitFromInfo(_info_on_compo[i]);
411     }
412   else
413     {
414       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();
415       throw INTERP_KERNEL::Exception(oss.str().c_str());
416     }
417 }
418
419 /*!
420  * Returns the var part of the full component information.
421  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
422  * If a unit part of information is not detected by presence of
423  * two square brackets, then the whole \a info is returned.
424  * To read more about the component information format, see
425  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
426  *  \param [in] info - the full component information.
427  *  \return std::string - a string containing only var information, or the \a info.
428  */
429 std::string DataArray::GetVarNameFromInfo(const std::string& info)
430 {
431   std::size_t p1=info.find_last_of('[');
432   std::size_t p2=info.find_last_of(']');
433   if(p1==std::string::npos || p2==std::string::npos)
434     return info;
435   if(p1>p2)
436     return info;
437   if(p1==0)
438     return std::string();
439   std::size_t p3=info.find_last_not_of(' ',p1-1);
440   return info.substr(0,p3+1);
441 }
442
443 /*!
444  * Returns the unit part of the full component information.
445  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
446  * If a unit part of information is not detected by presence of
447  * two square brackets, then an empty string is returned.
448  * To read more about the component information format, see
449  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
450  *  \param [in] info - the full component information.
451  *  \return std::string - a string containing only unit information, if any, or "".
452  */
453 std::string DataArray::GetUnitFromInfo(const std::string& info)
454 {
455   std::size_t p1=info.find_last_of('[');
456   std::size_t p2=info.find_last_of(']');
457   if(p1==std::string::npos || p2==std::string::npos)
458     return std::string();
459   if(p1>p2)
460     return std::string();
461   return info.substr(p1+1,p2-p1-1);
462 }
463
464 /*!
465  * This method put in info format the result of the merge of \a var and \a unit.
466  * The standard format for that is "var [unit]".
467  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
468  */
469 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
470 {
471   std::ostringstream oss;
472   oss << var << " [" << unit << "]";
473   return oss.str();
474 }
475
476 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
477 {
478   switch(at)
479     {
480     case AX_CART:
481       return std::string("AX_CART");
482     case AX_CYL:
483       return std::string("AX_CYL");
484     case AX_SPHER:
485       return std::string("AX_SPHER");
486     default:
487       throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
488     }
489 }
490
491 /*!
492  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
493  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
494  * the number of component in the result array is same as that of each of given arrays.
495  * Info on components is copied from the first of the given arrays. Number of components
496  * in the given arrays must be  the same.
497  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
498  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
499  *          The caller is to delete this result array using decrRef() as it is no more
500  *          needed.
501  *  \throw If all arrays within \a arrs are NULL.
502  *  \throw If all not null arrays in \a arrs have not the same type.
503  *  \throw If getNumberOfComponents() of arrays within \a arrs.
504  */
505 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
506 {
507   std::vector<const DataArray *> arr2;
508   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
509     if(*it)
510       arr2.push_back(*it);
511   if(arr2.empty())
512     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
513   std::vector<const DataArrayDouble *> arrd;
514   std::vector<const DataArrayInt *> arri;
515   std::vector<const DataArrayChar *> arrc;
516   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
517     {
518       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
519       if(a)
520         { arrd.push_back(a); continue; }
521       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
522       if(b)
523         { arri.push_back(b); continue; }
524       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
525       if(c)
526         { arrc.push_back(c); continue; }
527       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
528     }
529   if(arr2.size()==arrd.size())
530     return DataArrayDouble::Aggregate(arrd);
531   if(arr2.size()==arri.size())
532     return DataArrayInt::Aggregate(arri);
533   if(arr2.size()==arrc.size())
534     return DataArrayChar::Aggregate(arrc);
535   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
536 }
537
538 /*!
539  * Sets information on a component specified by an index.
540  * To know more on format of this information
541  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
542  *  \warning Don't pass NULL as \a info!
543  *  \param [in] i - the index (zero based) of the component of interest.
544  *  \param [in] info - the string containing the information.
545  *  \throw If \a i is not a valid component index.
546  */
547 void DataArray::setInfoOnComponent(int i, const std::string& info)
548 {
549   if(i<(int)_info_on_compo.size() && i>=0)
550     _info_on_compo[i]=info;
551   else
552     {
553       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();
554       throw INTERP_KERNEL::Exception(oss.str().c_str());
555     }
556 }
557
558 /*!
559  * Sets information on all components. This method can change number of components
560  * at certain conditions; if the conditions are not respected, an exception is thrown.
561  * The number of components can be changed in \a this only if \a this is not allocated.
562  * The condition of number of components must not be changed.
563  *
564  * To know more on format of the component information see
565  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
566  *  \param [in] info - a vector of component infos.
567  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
568  */
569 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
570 {
571   if(getNumberOfComponents()!=info.size())
572     {
573       if(!isAllocated())
574         _info_on_compo=info;
575       else
576         {
577           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 !";
578           throw INTERP_KERNEL::Exception(oss.str().c_str());
579         }
580     }
581   else
582     _info_on_compo=info;
583 }
584
585 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
586 {
587   if((int)getNumberOfTuples()!=nbOfTuples)
588     {
589       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
590       throw INTERP_KERNEL::Exception(oss.str().c_str());
591     }
592 }
593
594 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
595 {
596   if((int)getNumberOfComponents()!=nbOfCompo)
597     {
598       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
599       throw INTERP_KERNEL::Exception(oss.str().c_str());
600     }
601 }
602
603 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
604 {
605   if(getNbOfElems()!=nbOfElems)
606     {
607       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
608       throw INTERP_KERNEL::Exception(oss.str().c_str());
609     }
610 }
611
612 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
613 {
614   if(getNumberOfTuples()!=other.getNumberOfTuples())
615     {
616       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
617       throw INTERP_KERNEL::Exception(oss.str().c_str());
618     }
619   if(getNumberOfComponents()!=other.getNumberOfComponents())
620     {
621       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
622       throw INTERP_KERNEL::Exception(oss.str().c_str());
623     }
624 }
625
626 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
627 {
628   checkNbOfTuples(nbOfTuples,msg);
629   checkNbOfComps(nbOfCompo,msg);
630 }
631
632 /*!
633  * Simply this method checks that \b value is in [0,\b ref).
634  */
635 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
636 {
637   if(value<0 || value>=ref)
638     {
639       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
640       throw INTERP_KERNEL::Exception(oss.str().c_str());
641     }
642 }
643
644 /*!
645  * This method checks that [\b start, \b end) is compliant with ref length \b value.
646  * typically start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
647  */
648 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
649 {
650   if(start<0 || start>=value)
651     {
652       if(value!=start || end!=start)
653         {
654           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
655           throw INTERP_KERNEL::Exception(oss.str().c_str());
656         }
657     }
658   if(end<0 || end>value)
659     {
660       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
661       throw INTERP_KERNEL::Exception(oss.str().c_str());
662     }
663 }
664
665 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
666 {
667   if(value<0 || value>ref)
668     {
669       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
670       throw INTERP_KERNEL::Exception(oss.str().c_str());
671     }
672 }
673
674 /*!
675  * 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, 
676  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
677  *
678  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
679  *
680  * \param [in] start - the start of the input slice of the whole work to perform split into slices.
681  * \param [in] stop - the stop of the input slice of the whole work to perform split into slices.
682  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform split into slices.
683  * \param [in] sliceId - the slice id considered
684  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
685  * \param [out] startSlice - the start of the slice considered
686  * \param [out] stopSlice - the stop of the slice consided
687  * 
688  * \throw If \a step == 0
689  * \throw If \a nbOfSlices not > 0
690  * \throw If \a sliceId not in [0,nbOfSlices)
691  */
692 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
693 {
694   if(nbOfSlices<=0)
695     {
696       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
697       throw INTERP_KERNEL::Exception(oss.str().c_str());
698     }
699   if(sliceId<0 || sliceId>=nbOfSlices)
700     {
701       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
702       throw INTERP_KERNEL::Exception(oss.str().c_str());
703     }
704   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
705   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
706   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
707   if(sliceId<nbOfSlices-1)
708     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
709   else
710     stopSlice=stop;
711 }
712
713 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
714 {
715   if(end<begin)
716     {
717       std::ostringstream oss; oss << msg << " : end before begin !";
718       throw INTERP_KERNEL::Exception(oss.str().c_str());
719     }
720   if(end==begin)
721     return 0;
722   if(step<=0)
723     {
724       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
725       throw INTERP_KERNEL::Exception(oss.str().c_str());
726     }
727   return (end-1-begin)/step+1;
728 }
729
730 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
731 {
732   if(step==0)
733     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
734   if(end<begin && step>0)
735     {
736       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
737       throw INTERP_KERNEL::Exception(oss.str().c_str());
738     }
739   if(begin<end && step<0)
740     {
741       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
742       throw INTERP_KERNEL::Exception(oss.str().c_str());
743     }
744   if(begin!=end)
745     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
746   else
747     return 0;
748 }
749
750 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
751 {
752   if(step!=0)
753     {
754       if(step>0)
755         {
756           if(begin<=value && value<end)
757             {
758               if((value-begin)%step==0)
759                 return (value-begin)/step;
760               else
761                 return -1;
762             }
763           else
764             return -1;
765         }
766       else
767         {
768           if(begin>=value && value>end)
769             {
770               if((begin-value)%(-step)==0)
771                 return (begin-value)/(-step);
772               else
773                 return -1;
774             }
775           else
776             return -1;
777         }
778     }
779   else
780     return -1;
781 }
782
783 /*!
784  * Returns a new instance of DataArrayDouble. The caller is to delete this array
785  * using decrRef() as it is no more needed. 
786  */
787 DataArrayDouble *DataArrayDouble::New()
788 {
789   return new DataArrayDouble;
790 }
791
792 /*!
793  * Returns the only one value in \a this, if and only if number of elements
794  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
795  *  \return double - the sole value stored in \a this array.
796  *  \throw If at least one of conditions stated above is not fulfilled.
797  */
798 double DataArrayDouble::doubleValue() const
799 {
800   if(isAllocated())
801     {
802       if(getNbOfElems()==1)
803         {
804           return *getConstPointer();
805         }
806       else
807         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
808     }
809   else
810     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
811 }
812
813 /*!
814  * Returns a full copy of \a this. For more info on copying data arrays see
815  * \ref MEDCouplingArrayBasicsCopyDeep.
816  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
817  *          delete this array using decrRef() as it is no more needed. 
818  */
819 DataArrayDouble *DataArrayDouble::deepCopy() const
820 {
821   return new DataArrayDouble(*this);
822 }
823
824 /*!
825  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
826  * with at least absolute difference value of |\a eps| at each step.
827  * If not an exception is thrown.
828  *  \param [in] increasing - if \a true, the array values should be increasing.
829  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
830  *                    the values are considered different.
831  *  \throw If sequence of values is not strictly monotonic in agreement with \a
832  *         increasing arg.
833  *  \throw If \a this->getNumberOfComponents() != 1.
834  *  \throw If \a this is not allocated.
835  */
836 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
837 {
838   if(!isMonotonic(increasing,eps))
839     {
840       if (increasing)
841         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
842       else
843         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
844     }
845 }
846
847 /*!
848  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
849  * with at least absolute difference value of |\a eps| at each step.
850  *  \param [in] increasing - if \a true, array values should be increasing.
851  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
852  *                    the values are considered different.
853  *  \return bool - \a true if values change in accordance with \a increasing arg.
854  *  \throw If \a this->getNumberOfComponents() != 1.
855  *  \throw If \a this is not allocated.
856  */
857 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
858 {
859   checkAllocated();
860   if(getNumberOfComponents()!=1)
861     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
862   int nbOfElements=getNumberOfTuples();
863   const double *ptr=getConstPointer();
864   if(nbOfElements==0)
865     return true;
866   double ref=ptr[0];
867   double absEps=fabs(eps);
868   if(increasing)
869     {
870       for(int i=1;i<nbOfElements;i++)
871         {
872           if(ptr[i]<(ref+absEps))
873             return false;
874           ref=ptr[i];
875         }
876       return true;
877     }
878   else
879     {
880       for(int i=1;i<nbOfElements;i++)
881         {
882           if(ptr[i]>(ref-absEps))
883             return false;
884           ref=ptr[i];
885         }
886       return true;
887     }
888 }
889
890 /*!
891  * Returns a textual and human readable representation of \a this instance of
892  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
893  * \return std::string - text describing \a this DataArrayDouble.
894  *
895  * \sa reprNotTooLong, reprZip
896  */
897 std::string DataArrayDouble::repr() const
898 {
899   std::ostringstream ret;
900   reprStream(ret);
901   return ret.str();
902 }
903
904 std::string DataArrayDouble::reprZip() const
905 {
906   std::ostringstream ret;
907   reprZipStream(ret);
908   return ret.str();
909 }
910
911 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
912 {
913   static const char SPACE[4]={' ',' ',' ',' '};
914   checkAllocated();
915   std::string idt(indent,' ');
916   ofs.precision(17);
917   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
918   //
919   bool areAllEmpty(true);
920   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
921     if(!(*it).empty())
922       areAllEmpty=false;
923   if(!areAllEmpty)
924     for(std::size_t i=0;i<_info_on_compo.size();i++)
925       ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
926   //
927   if(byteArr)
928     {
929       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
930       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
931       float *pt(tmp);
932       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
933       for(const double *src=begin();src!=end();src++,pt++)
934         *pt=float(*src);
935       const char *data(reinterpret_cast<const char *>((float *)tmp));
936       std::size_t sz(getNbOfElems()*sizeof(float));
937       byteArr->insertAtTheEnd(data,data+sz);
938       byteArr->insertAtTheEnd(SPACE,SPACE+4);
939     }
940   else
941     {
942       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
943       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
944     }
945   ofs << std::endl << idt << "</DataArray>\n";
946 }
947
948 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
949 {
950   int nbTuples(getNumberOfTuples()),nbComp(getNumberOfComponents());
951   const double *data(getConstPointer());
952   stream.precision(17);
953   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
954   if(nbTuples*nbComp>=1)
955     {
956       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
957       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
958       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
959       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
960     }
961   else
962     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
963   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
964 }
965
966 /*!
967  * Method that gives a quick overvien of \a this for python.
968  */
969 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
970 {
971   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
972   stream << "DataArrayDouble C++ instance at " << this << ". ";
973   if(isAllocated())
974     {
975       int nbOfCompo=(int)_info_on_compo.size();
976       if(nbOfCompo>=1)
977         {
978           int nbOfTuples=getNumberOfTuples();
979           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
980           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
981         }
982       else
983         stream << "Number of components : 0.";
984     }
985   else
986     stream << "*** No data allocated ****";
987 }
988
989 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
990 {
991   const double *data=begin();
992   int nbOfTuples=getNumberOfTuples();
993   int nbOfCompo=(int)_info_on_compo.size();
994   std::ostringstream oss2; oss2 << "[";
995   oss2.precision(17);
996   std::string oss2Str(oss2.str());
997   bool isFinished=true;
998   for(int i=0;i<nbOfTuples && isFinished;i++)
999     {
1000       if(nbOfCompo>1)
1001         {
1002           oss2 << "(";
1003           for(int j=0;j<nbOfCompo;j++,data++)
1004             {
1005               oss2 << *data;
1006               if(j!=nbOfCompo-1) oss2 << ", ";
1007             }
1008           oss2 << ")";
1009         }
1010       else
1011         oss2 << *data++;
1012       if(i!=nbOfTuples-1) oss2 << ", ";
1013       std::string oss3Str(oss2.str());
1014       if(oss3Str.length()<maxNbOfByteInRepr)
1015         oss2Str=oss3Str;
1016       else
1017         isFinished=false;
1018     }
1019   stream << oss2Str;
1020   if(!isFinished)
1021     stream << "... ";
1022   stream << "]";
1023 }
1024
1025 /*!
1026  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1027  * mismatch is given.
1028  * 
1029  * \param [in] other the instance to be compared with \a this
1030  * \param [in] prec the precision to compare numeric data of the arrays.
1031  * \param [out] reason In case of inequality returns the reason.
1032  * \sa DataArrayDouble::isEqual
1033  */
1034 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1035 {
1036   if(!areInfoEqualsIfNotWhy(other,reason))
1037     return false;
1038   return _mem.isEqual(other._mem,prec,reason);
1039 }
1040
1041 /*!
1042  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1043  * \ref MEDCouplingArrayBasicsCompare.
1044  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1045  *  \param [in] prec - precision value to compare numeric data of the arrays.
1046  *  \return bool - \a true if the two arrays are equal, \a false else.
1047  */
1048 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1049 {
1050   std::string tmp;
1051   return isEqualIfNotWhy(other,prec,tmp);
1052 }
1053
1054 /*!
1055  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1056  * \ref MEDCouplingArrayBasicsCompare.
1057  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1058  *  \param [in] prec - precision value to compare numeric data of the arrays.
1059  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1060  */
1061 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1062 {
1063   std::string tmp;
1064   return _mem.isEqual(other._mem,prec,tmp);
1065 }
1066
1067 /*!
1068  * This method checks that all tuples in \a other are in \a this.
1069  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1070  * 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.
1071  *
1072  * \param [in] other - the array having the same number of components than \a this.
1073  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1074  * \sa DataArrayDouble::findCommonTuples
1075  */
1076 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1077 {
1078   if(!other)
1079     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1080   checkAllocated(); other->checkAllocated();
1081   if(getNumberOfComponents()!=other->getNumberOfComponents())
1082     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1083   MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1084   DataArrayInt *c=0,*ci=0;
1085   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1086   MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1087   int newNbOfTuples=-1;
1088   MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1089   MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1090   tupleIds=ret1.retn();
1091   return newNbOfTuples==getNumberOfTuples();
1092 }
1093
1094 /*!
1095  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1096  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1097  * distance separating two points is computed with the infinite norm.
1098  *
1099  * Indices of coincident tuples are stored in output arrays.
1100  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1101  *
1102  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1103  * MEDCouplingUMesh::mergeNodes().
1104  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1105  *              considered not coincident.
1106  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1107  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1108  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1109  *               \a comm->getNumberOfComponents() == 1. 
1110  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1111  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1112  *               groups of (indices of) coincident tuples. Its every value is a tuple
1113  *               index where a next group of tuples begins. For example the second
1114  *               group of tuples in \a comm is described by following range of indices:
1115  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1116  *               gives the number of groups of coincident tuples.
1117  *  \throw If \a this is not allocated.
1118  *  \throw If the number of components is not in [1,2,3,4].
1119  *
1120  *  \if ENABLE_EXAMPLES
1121  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1122  *
1123  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1124  *  \endif
1125  *  \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1126  */
1127 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1128 {
1129   checkAllocated();
1130   int nbOfCompo=getNumberOfComponents();
1131   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1132     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1133
1134   int nbOfTuples=getNumberOfTuples();
1135   //
1136   MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1137   switch(nbOfCompo)
1138   {
1139     case 4:
1140       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1141       break;
1142     case 3:
1143       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1144       break;
1145     case 2:
1146       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1147       break;
1148     case 1:
1149       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1150       break;
1151     default:
1152       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1153   }
1154   comm=c.retn();
1155   commIndex=cI.retn();
1156 }
1157
1158 /*!
1159  * This methods returns the minimal distance between the two set of points \a this and \a other.
1160  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1161  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1162  *
1163  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1164  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1165  * \return the minimal distance between the two set of points \a this and \a other.
1166  * \sa DataArrayDouble::findClosestTupleId
1167  */
1168 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1169 {
1170   MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1171   int nbOfCompo(getNumberOfComponents());
1172   int otherNbTuples(other->getNumberOfTuples());
1173   const double *thisPt(begin()),*otherPt(other->begin());
1174   const int *part1Pt(part1->begin());
1175   double ret=std::numeric_limits<double>::max();
1176   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1177     {
1178       double tmp(0.);
1179       for(int j=0;j<nbOfCompo;j++)
1180         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1181       if(tmp<ret)
1182         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1183     }
1184   return sqrt(ret);
1185 }
1186
1187 /*!
1188  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1189  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1190  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1191  *
1192  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1193  * \sa DataArrayDouble::minimalDistanceTo
1194  */
1195 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1196 {
1197   if(!other)
1198     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1199   checkAllocated(); other->checkAllocated();
1200   std::size_t nbOfCompo(getNumberOfComponents());
1201   if(nbOfCompo!=other->getNumberOfComponents())
1202     {
1203       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1204       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1205       throw INTERP_KERNEL::Exception(oss.str().c_str());
1206     }
1207   int nbOfTuples=other->getNumberOfTuples();
1208   int thisNbOfTuples=getNumberOfTuples();
1209   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1210   double bounds[6];
1211   getMinMaxPerComponent(bounds);
1212   switch(nbOfCompo)
1213   {
1214     case 3:
1215       {
1216         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1217         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1218         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1219         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1220         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1221         break;
1222       }
1223     case 2:
1224       {
1225         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1226         double delta=std::max(xDelta,yDelta);
1227         double characSize=sqrt(delta/(double)thisNbOfTuples);
1228         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1229         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1230         break;
1231       }
1232     case 1:
1233       {
1234         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1235         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1236         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1237         break;
1238       }
1239     default:
1240       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1241   }
1242   return ret.retn();
1243 }
1244
1245 /*!
1246  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1247  * 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
1248  * how many bounding boxes in \a otherBBoxFrmt.
1249  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1250  *
1251  * \param [in] otherBBoxFrmt - It is an array .
1252  * \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.
1253  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1254  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1255  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1256  */
1257 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1258 {
1259   if(!otherBBoxFrmt)
1260     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1261   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1262     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1263   std::size_t nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1264   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1265     {
1266       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1267       throw INTERP_KERNEL::Exception(oss.str().c_str());
1268     }
1269   if(nbOfComp%2!=0)
1270     {
1271       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1272       throw INTERP_KERNEL::Exception(oss.str().c_str());
1273     }
1274   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1275   const double *thisBBPtr(begin());
1276   int *retPtr(ret->getPointer());
1277   switch(nbOfComp/2)
1278   {
1279     case 3:
1280       {
1281         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1282         for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1283           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1284         break;
1285       }
1286     case 2:
1287       {
1288         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1289         for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1290           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1291         break;
1292       }
1293     case 1:
1294       {
1295         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1296         for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1297           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1298         break;
1299       }
1300     default:
1301       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1302   }
1303
1304   return ret.retn();
1305 }
1306
1307 /*!
1308  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1309  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1310  * space. The distance between tuples is computed using norm2. If several tuples are
1311  * not far each from other than \a prec, only one of them remains in the result
1312  * array. The order of tuples in the result array is same as in \a this one except
1313  * that coincident tuples are excluded.
1314  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1315  *              considered not coincident.
1316  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1317  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
1318  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1319  *          is to delete using decrRef() as it is no more needed.
1320  *  \throw If \a this is not allocated.
1321  *  \throw If the number of components is not in [1,2,3,4].
1322  *
1323  *  \if ENABLE_EXAMPLES
1324  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1325  *  \endif
1326  */
1327 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1328 {
1329   checkAllocated();
1330   DataArrayInt *c0=0,*cI0=0;
1331   findCommonTuples(prec,limitTupleId,c0,cI0);
1332   MCAuto<DataArrayInt> c(c0),cI(cI0);
1333   int newNbOfTuples=-1;
1334   MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1335   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1336 }
1337
1338 /*!
1339  * Copy all components in a specified order from another DataArrayDouble.
1340  * Both numerical and textual data is copied. The number of tuples in \a this and
1341  * the other array can be different.
1342  *  \param [in] a - the array to copy data from.
1343  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1344  *              to be copied.
1345  *  \throw If \a a is NULL.
1346  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1347  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1348  *
1349  *  \if ENABLE_EXAMPLES
1350  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1351  *  \endif
1352  */
1353 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1354 {
1355   if(!a)
1356     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1357   checkAllocated();
1358   copyPartOfStringInfoFrom2(compoIds,*a);
1359   std::size_t partOfCompoSz=compoIds.size();
1360   int nbOfCompo=getNumberOfComponents();
1361   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1362   const double *ac=a->getConstPointer();
1363   double *nc=getPointer();
1364   for(int i=0;i<nbOfTuples;i++)
1365     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1366       nc[nbOfCompo*i+compoIds[j]]=*ac;
1367 }
1368
1369 /*!
1370  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1371  * is thrown.
1372  * \throw If zero is found in \a this array.
1373  */
1374 void DataArrayDouble::checkNoNullValues() const
1375 {
1376   const double *tmp=getConstPointer();
1377   std::size_t nbOfElems=getNbOfElems();
1378   const double *where=std::find(tmp,tmp+nbOfElems,0.);
1379   if(where!=tmp+nbOfElems)
1380     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1381 }
1382
1383 /*!
1384  * Computes minimal and maximal value in each component. An output array is filled
1385  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1386  * enough memory before calling this method.
1387  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1388  *               It is filled as follows:<br>
1389  *               \a bounds[0] = \c min_of_component_0 <br>
1390  *               \a bounds[1] = \c max_of_component_0 <br>
1391  *               \a bounds[2] = \c min_of_component_1 <br>
1392  *               \a bounds[3] = \c max_of_component_1 <br>
1393  *               ...
1394  */
1395 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1396 {
1397   checkAllocated();
1398   int dim=getNumberOfComponents();
1399   for (int idim=0; idim<dim; idim++)
1400     {
1401       bounds[idim*2]=std::numeric_limits<double>::max();
1402       bounds[idim*2+1]=-std::numeric_limits<double>::max();
1403     } 
1404   const double *ptr=getConstPointer();
1405   int nbOfTuples=getNumberOfTuples();
1406   for(int i=0;i<nbOfTuples;i++)
1407     {
1408       for(int idim=0;idim<dim;idim++)
1409         {
1410           if(bounds[idim*2]>ptr[i*dim+idim])
1411             {
1412               bounds[idim*2]=ptr[i*dim+idim];
1413             }
1414           if(bounds[idim*2+1]<ptr[i*dim+idim])
1415             {
1416               bounds[idim*2+1]=ptr[i*dim+idim];
1417             }
1418         }
1419     }
1420 }
1421
1422 /*!
1423  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1424  * to store both the min and max per component of each tuples. 
1425  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1426  *
1427  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1428  *
1429  * \throw If \a this is not allocated yet.
1430  */
1431 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1432 {
1433   checkAllocated();
1434   const double *dataPtr=getConstPointer();
1435   int nbOfCompo=getNumberOfComponents();
1436   int nbTuples=getNumberOfTuples();
1437   MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1438   bbox->alloc(nbTuples,2*nbOfCompo);
1439   double *bboxPtr=bbox->getPointer();
1440   for(int i=0;i<nbTuples;i++)
1441     {
1442       for(int j=0;j<nbOfCompo;j++)
1443         {
1444           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1445           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1446         }
1447     }
1448   return bbox.retn();
1449 }
1450
1451 /*!
1452  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1453  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1454  * 
1455  * \param [in] other a DataArrayDouble having same number of components than \a this.
1456  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1457  * \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.
1458  *             \a cI allows to extract information in \a c.
1459  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1460  *
1461  * \throw In case of:
1462  *  - \a this is not allocated
1463  *  - \a other is not allocated or null
1464  *  - \a this and \a other do not have the same number of components
1465  *  - if number of components of \a this is not in [1,2,3]
1466  *
1467  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1468  */
1469 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1470 {
1471   if(!other)
1472     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1473   checkAllocated();
1474   other->checkAllocated();
1475   int nbOfCompo=getNumberOfComponents();
1476   int otherNbOfCompo=other->getNumberOfComponents();
1477   if(nbOfCompo!=otherNbOfCompo)
1478     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1479   int nbOfTuplesOther=other->getNumberOfTuples();
1480   MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1481   switch(nbOfCompo)
1482   {
1483     case 3:
1484       {
1485         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1486         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1487         break;
1488       }
1489     case 2:
1490       {
1491         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1492         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1493         break;
1494       }
1495     case 1:
1496       {
1497         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1498         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1499         break;
1500       }
1501     default:
1502       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1503   }
1504   c=cArr.retn(); cI=cIArr.retn();
1505 }
1506
1507 /*!
1508  * 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
1509  * around origin of 'radius' 1.
1510  * 
1511  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1512  */
1513 void DataArrayDouble::recenterForMaxPrecision(double eps)
1514 {
1515   checkAllocated();
1516   int dim=getNumberOfComponents();
1517   std::vector<double> bounds(2*dim);
1518   getMinMaxPerComponent(&bounds[0]);
1519   for(int i=0;i<dim;i++)
1520     {
1521       double delta=bounds[2*i+1]-bounds[2*i];
1522       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1523       if(delta>eps)
1524         applyLin(1./delta,-offset/delta,i);
1525       else
1526         applyLin(1.,-offset,i);
1527     }
1528 }
1529
1530 /*!
1531  * Returns the maximal value and all its locations within \a this one-dimensional array.
1532  *  \param [out] tupleIds - a new instance of DataArrayInt containing indices of
1533  *               tuples holding the maximal value. The caller is to delete it using
1534  *               decrRef() as it is no more needed.
1535  *  \return double - the maximal value among all values of \a this array.
1536  *  \throw If \a this->getNumberOfComponents() != 1
1537  *  \throw If \a this->getNumberOfTuples() < 1
1538  */
1539 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1540 {
1541   int tmp;
1542   tupleIds=0;
1543   double ret=getMaxValue(tmp);
1544   tupleIds=findIdsInRange(ret,ret);
1545   return ret;
1546 }
1547
1548 /*!
1549  * Returns the minimal value and all its locations within \a this one-dimensional array.
1550  *  \param [out] tupleIds - a new instance of DataArrayInt containing indices of
1551  *               tuples holding the minimal value. The caller is to delete it using
1552  *               decrRef() as it is no more needed.
1553  *  \return double - the minimal value among all values of \a this array.
1554  *  \throw If \a this->getNumberOfComponents() != 1
1555  *  \throw If \a this->getNumberOfTuples() < 1
1556  */
1557 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1558 {
1559   int tmp;
1560   tupleIds=0;
1561   double ret=getMinValue(tmp);
1562   tupleIds=findIdsInRange(ret,ret);
1563   return ret;
1564 }
1565
1566 /*!
1567  * 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.
1568  * This method only works for single component array.
1569  *
1570  * \return a value in [ 0, \c this->getNumberOfTuples() )
1571  *
1572  * \throw If \a this is not allocated
1573  *
1574  */
1575 int DataArrayDouble::count(double value, double eps) const
1576 {
1577   int ret=0;
1578   checkAllocated();
1579   if(getNumberOfComponents()!=1)
1580     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1581   const double *vals=begin();
1582   int nbOfTuples=getNumberOfTuples();
1583   for(int i=0;i<nbOfTuples;i++,vals++)
1584     if(fabs(*vals-value)<=eps)
1585       ret++;
1586   return ret;
1587 }
1588
1589 /*!
1590  * Returns the average value of \a this one-dimensional array.
1591  *  \return double - the average value over all values of \a this array.
1592  *  \throw If \a this->getNumberOfComponents() != 1
1593  *  \throw If \a this->getNumberOfTuples() < 1
1594  */
1595 double DataArrayDouble::getAverageValue() const
1596 {
1597   if(getNumberOfComponents()!=1)
1598     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1599   int nbOfTuples=getNumberOfTuples();
1600   if(nbOfTuples<=0)
1601     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1602   const double *vals=getConstPointer();
1603   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1604   return ret/nbOfTuples;
1605 }
1606
1607 /*!
1608  * Returns the Euclidean norm of the vector defined by \a this array.
1609  *  \return double - the value of the Euclidean norm, i.e.
1610  *          the square root of the inner product of vector.
1611  *  \throw If \a this is not allocated.
1612  */
1613 double DataArrayDouble::norm2() const
1614 {
1615   checkAllocated();
1616   double ret=0.;
1617   std::size_t nbOfElems=getNbOfElems();
1618   const double *pt=getConstPointer();
1619   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1620     ret+=(*pt)*(*pt);
1621   return sqrt(ret);
1622 }
1623
1624 /*!
1625  * Returns the maximum norm of the vector defined by \a this array.
1626  * This method works even if the number of components is different from one.
1627  * If the number of elements in \a this is 0, -1. is returned.
1628  *  \return double - the value of the maximum norm, i.e.
1629  *          the maximal absolute value among values of \a this array (whatever its number of components).
1630  *  \throw If \a this is not allocated.
1631  */
1632 double DataArrayDouble::normMax() const
1633 {
1634   checkAllocated();
1635   double ret(-1.);
1636   std::size_t nbOfElems(getNbOfElems());
1637   const double *pt(getConstPointer());
1638   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1639     {
1640       double val(std::abs(*pt));
1641       if(val>ret)
1642         ret=val;
1643     }
1644   return ret;
1645 }
1646
1647 /*!
1648  * Returns the maximum norm of for each component of \a this array.
1649  * If the number of elements in \a this is 0, -1. is returned.
1650 *  \param [out] res - pointer to an array of result values, of size at least \a
1651  *         this->getNumberOfComponents(), that is to be allocated by the caller.
1652  *  \throw If \a this is not allocated.
1653  */
1654 void DataArrayDouble::normMaxPerComponent(double * res) const
1655 {
1656   checkAllocated();
1657   std::size_t nbOfTuples(getNumberOfTuples());
1658   int nbOfCompos(getNumberOfComponents());
1659   std::fill(res, res+nbOfCompos, -1.0);
1660   const double *pt(getConstPointer());
1661   for(std::size_t i=0;i<nbOfTuples;i++)
1662     for (int j=0; j<nbOfCompos; j++, pt++)
1663       {
1664         double val(std::abs(*pt));
1665         if(val>res[j])
1666           res[j]=val;
1667       }
1668 }
1669
1670
1671 /*!
1672  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1673  * This method works even if the number of components is different from one.
1674  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1675  *  \return double - the value of the minimum norm, i.e.
1676  *          the minimal absolute value among values of \a this array (whatever its number of components).
1677  *  \throw If \a this is not allocated.
1678  */
1679 double DataArrayDouble::normMin() const
1680 {
1681   checkAllocated();
1682   double ret(std::numeric_limits<double>::max());
1683   std::size_t nbOfElems(getNbOfElems());
1684   const double *pt(getConstPointer());
1685   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1686     {
1687       double val(std::abs(*pt));
1688       if(val<ret)
1689         ret=val;
1690     }
1691   return ret;
1692 }
1693
1694 /*!
1695  * Accumulates values of each component of \a this array.
1696  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
1697  *         by the caller, that is filled by this method with sum value for each
1698  *         component.
1699  *  \throw If \a this is not allocated.
1700  */
1701 void DataArrayDouble::accumulate(double *res) const
1702 {
1703   checkAllocated();
1704   const double *ptr=getConstPointer();
1705   int nbTuple=getNumberOfTuples();
1706   int nbComps=getNumberOfComponents();
1707   std::fill(res,res+nbComps,0.);
1708   for(int i=0;i<nbTuple;i++)
1709     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1710 }
1711
1712 /*!
1713  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1714  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1715  *
1716  *
1717  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1718  * \a tupleEnd. If not an exception will be thrown.
1719  *
1720  * \param [in] tupleBg start pointer (included) of input external tuple
1721  * \param [in] tupleEnd end pointer (not included) of input external tuple
1722  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1723  * \return the min distance.
1724  * \sa MEDCouplingUMesh::distanceToPoint
1725  */
1726 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1727 {
1728   checkAllocated();
1729   int nbTuple=getNumberOfTuples();
1730   int nbComps=getNumberOfComponents();
1731   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1732     { 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()); }
1733   if(nbTuple==0)
1734     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1735   double ret0=std::numeric_limits<double>::max();
1736   tupleId=-1;
1737   const double *work=getConstPointer();
1738   for(int i=0;i<nbTuple;i++)
1739     {
1740       double val=0.;
1741       for(int j=0;j<nbComps;j++,work++) 
1742         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1743       if(val>=ret0)
1744         continue;
1745       else
1746         { ret0=val; tupleId=i; }
1747     }
1748   return sqrt(ret0);
1749 }
1750
1751 /*!
1752  * Accumulate values of the given component of \a this array.
1753  *  \param [in] compId - the index of the component of interest.
1754  *  \return double - a sum value of \a compId-th component.
1755  *  \throw If \a this is not allocated.
1756  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1757  *         not respected.
1758  */
1759 double DataArrayDouble::accumulate(int compId) const
1760 {
1761   checkAllocated();
1762   const double *ptr=getConstPointer();
1763   int nbTuple=getNumberOfTuples();
1764   int nbComps=getNumberOfComponents();
1765   if(compId<0 || compId>=nbComps)
1766     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1767   double ret=0.;
1768   for(int i=0;i<nbTuple;i++)
1769     ret+=ptr[i*nbComps+compId];
1770   return ret;
1771 }
1772
1773 /*!
1774  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1775  * The returned array will have same number of components than \a this and number of tuples equal to
1776  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1777  *
1778  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1779  * 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.
1780  *
1781  * \param [in] bgOfIndex - begin (included) of the input index array.
1782  * \param [in] endOfIndex - end (excluded) of the input index array.
1783  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1784  * 
1785  * \throw If bgOfIndex or end is NULL.
1786  * \throw If input index array is not ascendingly sorted.
1787  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1788  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1789  */
1790 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1791 {
1792   if(!bgOfIndex || !endOfIndex)
1793     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1794   checkAllocated();
1795   int nbCompo=getNumberOfComponents();
1796   int nbOfTuples=getNumberOfTuples();
1797   int sz=(int)std::distance(bgOfIndex,endOfIndex);
1798   if(sz<1)
1799     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1800   sz--;
1801   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1802   const int *w=bgOfIndex;
1803   if(*w<0 || *w>=nbOfTuples)
1804     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1805   const double *srcPt=begin()+(*w)*nbCompo;
1806   double *tmp=ret->getPointer();
1807   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1808     {
1809       std::fill(tmp,tmp+nbCompo,0.);
1810       if(w[1]>=w[0])
1811         {
1812           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1813             {
1814               if(j>=0 && j<nbOfTuples)
1815                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1816               else
1817                 {
1818                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
1819                   throw INTERP_KERNEL::Exception(oss.str().c_str());
1820                 }
1821             }
1822         }
1823       else
1824         {
1825           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
1826           throw INTERP_KERNEL::Exception(oss.str().c_str());
1827         }
1828     }
1829   ret->copyStringInfoFrom(*this);
1830   return ret.retn();
1831 }
1832
1833 /*!
1834  * 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.
1835  * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
1836  * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
1837  *
1838  * \return DataArrayDouble - A newly built array containing cum sum of \a this.
1839  */
1840 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
1841 {
1842   checkAllocated();
1843   checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
1844   int nbOfTuple(getNumberOfTuples());
1845   MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
1846   double *ptr(ret->getPointer());
1847   ptr[0]=0.;
1848   const double *thisPtr(begin());
1849   for(int i=0;i<nbOfTuple;i++)
1850     ptr[i+1]=ptr[i]+thisPtr[i];
1851   return ret;
1852 }
1853
1854 /*!
1855  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
1856  * Cartesian coordinate system. The two components of the tuple of \a this array are 
1857  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
1858  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1859  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
1860  *          is to delete this array using decrRef() as it is no more needed. The array
1861  *          does not contain any textual info on components.
1862  *  \throw If \a this->getNumberOfComponents() != 2.
1863  * \sa fromCartToPolar
1864  */
1865 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
1866 {
1867   checkAllocated();
1868   int nbOfComp(getNumberOfComponents());
1869   if(nbOfComp!=2)
1870     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
1871   int nbOfTuple(getNumberOfTuples());
1872   DataArrayDouble *ret(DataArrayDouble::New());
1873   ret->alloc(nbOfTuple,2);
1874   double *w(ret->getPointer());
1875   const double *wIn(getConstPointer());
1876   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
1877     {
1878       w[0]=wIn[0]*cos(wIn[1]);
1879       w[1]=wIn[0]*sin(wIn[1]);
1880     }
1881   return ret;
1882 }
1883
1884 /*!
1885  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
1886  * the Cartesian coordinate system. The three components of the tuple of \a this array 
1887  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
1888  * the Cylindrical CS.
1889  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1890  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1891  *          on the third component is copied from \a this array. The caller
1892  *          is to delete this array using decrRef() as it is no more needed. 
1893  *  \throw If \a this->getNumberOfComponents() != 3.
1894  * \sa fromCartToCyl
1895  */
1896 DataArrayDouble *DataArrayDouble::fromCylToCart() const
1897 {
1898   checkAllocated();
1899   int nbOfComp(getNumberOfComponents());
1900   if(nbOfComp!=3)
1901     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
1902   int nbOfTuple(getNumberOfTuples());
1903   DataArrayDouble *ret(DataArrayDouble::New());
1904   ret->alloc(getNumberOfTuples(),3);
1905   double *w(ret->getPointer());
1906   const double *wIn(getConstPointer());
1907   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1908     {
1909       w[0]=wIn[0]*cos(wIn[1]);
1910       w[1]=wIn[0]*sin(wIn[1]);
1911       w[2]=wIn[2];
1912     }
1913   ret->setInfoOnComponent(2,getInfoOnComponent(2));
1914   return ret;
1915 }
1916
1917 /*!
1918  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
1919  * the Cartesian coordinate system. The three components of the tuple of \a this array 
1920  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
1921  * point in the Cylindrical CS.
1922  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1923  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1924  *          on the third component is copied from \a this array. The caller
1925  *          is to delete this array using decrRef() as it is no more needed.
1926  *  \throw If \a this->getNumberOfComponents() != 3.
1927  * \sa fromCartToSpher
1928  */
1929 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
1930 {
1931   checkAllocated();
1932   int nbOfComp(getNumberOfComponents());
1933   if(nbOfComp!=3)
1934     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
1935   int nbOfTuple(getNumberOfTuples());
1936   DataArrayDouble *ret(DataArrayDouble::New());
1937   ret->alloc(getNumberOfTuples(),3);
1938   double *w(ret->getPointer());
1939   const double *wIn(getConstPointer());
1940   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1941     {
1942       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
1943       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
1944       w[2]=wIn[0]*cos(wIn[1]);
1945     }
1946   return ret;
1947 }
1948
1949 /*!
1950  * 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.
1951  * 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.
1952  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
1953  *
1954  * \param [in] atOfThis - The axis type of \a this.
1955  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
1956  */
1957 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
1958 {
1959   checkAllocated();
1960   int nbOfComp(getNumberOfComponents());
1961   MCAuto<DataArrayDouble> ret;
1962   switch(atOfThis)
1963     {
1964     case AX_CART:
1965       ret=deepCopy();
1966     case AX_CYL:
1967       if(nbOfComp==3)
1968         {
1969           ret=fromCylToCart();
1970           break;
1971         }
1972       if(nbOfComp==2)
1973         {
1974           ret=fromPolarToCart();
1975           break;
1976         }
1977       else
1978         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1979     case AX_SPHER:
1980       if(nbOfComp==3)
1981         {
1982           ret=fromSpherToCart();
1983           break;
1984         }
1985       if(nbOfComp==2)
1986         {
1987           ret=fromPolarToCart();
1988           break;
1989         }
1990       else
1991         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1992     default:
1993       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
1994     }
1995   ret->copyStringInfoFrom(*this);
1996   return ret.retn();
1997 }
1998
1999 /*!
2000  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
2001  * This method expects that \a this has exactly 2 components.
2002  * \sa fromPolarToCart
2003  */
2004 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
2005 {
2006   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2007   checkAllocated();
2008   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2009   if(nbOfComp!=2)
2010     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
2011   ret->alloc(nbTuples,2);
2012   double *retPtr(ret->getPointer());
2013   const double *ptr(begin());
2014   for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
2015     {
2016       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2017       retPtr[1]=atan2(ptr[1],ptr[0]);
2018     }
2019   return ret.retn();
2020 }
2021
2022 /*!
2023  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2024  * This method expects that \a this has exactly 3 components.
2025  * \sa fromCylToCart
2026  */
2027 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2028 {
2029   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2030   checkAllocated();
2031   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2032   if(nbOfComp!=3)
2033     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2034   ret->alloc(nbTuples,3);
2035   double *retPtr(ret->getPointer());
2036   const double *ptr(begin());
2037   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2038     {
2039       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2040       retPtr[1]=atan2(ptr[1],ptr[0]);
2041       retPtr[2]=ptr[2];
2042     }
2043   return ret.retn();
2044 }
2045
2046 /*!
2047  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2048  * \sa fromSpherToCart
2049  */
2050 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2051 {
2052   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2053   checkAllocated();
2054   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2055   if(nbOfComp!=3)
2056     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2057   ret->alloc(nbTuples,3);
2058   double *retPtr(ret->getPointer());
2059   const double *ptr(begin());
2060   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2061     {
2062       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2063       retPtr[1]=acos(ptr[2]/retPtr[0]);
2064       retPtr[2]=atan2(ptr[1],ptr[0]);
2065     }
2066   return ret.retn();
2067 }
2068
2069 /*!
2070  * 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.
2071  * This method expects that \a this has exactly 3 components.
2072  * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2073  */
2074 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2075 {
2076   if(!coords)
2077     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2078   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2079   checkAllocated(); coords->checkAllocated();
2080   std::size_t nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2081   if(nbOfComp!=3)
2082     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2083   if(coords->getNumberOfComponents()!=3)
2084     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2085   if(coords->getNumberOfTuples()!=nbTuples)
2086     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2087   ret->alloc(nbTuples,nbOfComp);
2088   double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2089   if(magOfVect<1e-12)
2090     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2091   double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2092   const double *coo(coords->begin()),*vectField(begin());
2093   std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2094   for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2095     {
2096       std::transform(coo,coo+3,center,Ur,std::minus<double>());
2097       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];
2098       double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2099       std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2100       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];
2101       retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2102       retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2103       retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2104     }
2105   ret->copyStringInfoFrom(*this);
2106   return ret.retn();
2107 }
2108
2109 /*!
2110  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2111  * array containing 6 components.
2112  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2113  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
2114  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2115  *         The caller is to delete this result array using decrRef() as it is no more needed. 
2116  *  \throw If \a this->getNumberOfComponents() != 6.
2117  */
2118 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2119 {
2120   checkAllocated();
2121   int nbOfComp(getNumberOfComponents());
2122   if(nbOfComp!=6)
2123     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2124   DataArrayDouble *ret=DataArrayDouble::New();
2125   int nbOfTuple=getNumberOfTuples();
2126   ret->alloc(nbOfTuple,1);
2127   const double *src=getConstPointer();
2128   double *dest=ret->getPointer();
2129   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2130     *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];
2131   return ret;
2132 }
2133
2134 /*!
2135  * Computes the determinant of every square matrix defined by the tuple of \a this
2136  * array, which contains either 4, 6 or 9 components. The case of 6 components
2137  * corresponds to that of the upper triangular matrix.
2138  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2139  *          is the determinant of matrix of the corresponding tuple of \a this array.
2140  *          The caller is to delete this result array using decrRef() as it is no more
2141  *          needed. 
2142  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2143  */
2144 DataArrayDouble *DataArrayDouble::determinant() const
2145 {
2146   checkAllocated();
2147   DataArrayDouble *ret=DataArrayDouble::New();
2148   int nbOfTuple=getNumberOfTuples();
2149   ret->alloc(nbOfTuple,1);
2150   const double *src=getConstPointer();
2151   double *dest=ret->getPointer();
2152   switch(getNumberOfComponents())
2153   {
2154     case 6:
2155       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2156         *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];
2157       return ret;
2158     case 4:
2159       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2160         *dest=src[0]*src[3]-src[1]*src[2];
2161       return ret;
2162     case 9:
2163       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2164         *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       return ret;
2166     default:
2167       ret->decrRef();
2168       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2169   }
2170 }
2171
2172 /*!
2173  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2174  * \a this array, which contains 6 components.
2175  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2176  *          components, whose each tuple contains the eigenvalues of the matrix of
2177  *          corresponding tuple of \a this array. 
2178  *          The caller is to delete this result array using decrRef() as it is no more
2179  *          needed. 
2180  *  \throw If \a this->getNumberOfComponents() != 6.
2181  */
2182 DataArrayDouble *DataArrayDouble::eigenValues() const
2183 {
2184   checkAllocated();
2185   int nbOfComp=getNumberOfComponents();
2186   if(nbOfComp!=6)
2187     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2188   DataArrayDouble *ret=DataArrayDouble::New();
2189   int nbOfTuple=getNumberOfTuples();
2190   ret->alloc(nbOfTuple,3);
2191   const double *src=getConstPointer();
2192   double *dest=ret->getPointer();
2193   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2194     INTERP_KERNEL::computeEigenValues6(src,dest);
2195   return ret;
2196 }
2197
2198 /*!
2199  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2200  * \a this array, which contains 6 components.
2201  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2202  *          components, whose each tuple contains 3 eigenvectors of the matrix of
2203  *          corresponding tuple of \a this array.
2204  *          The caller is to delete this result array using decrRef() as it is no more
2205  *          needed.
2206  *  \throw If \a this->getNumberOfComponents() != 6.
2207  */
2208 DataArrayDouble *DataArrayDouble::eigenVectors() const
2209 {
2210   checkAllocated();
2211   int nbOfComp=getNumberOfComponents();
2212   if(nbOfComp!=6)
2213     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2214   DataArrayDouble *ret=DataArrayDouble::New();
2215   int nbOfTuple=getNumberOfTuples();
2216   ret->alloc(nbOfTuple,9);
2217   const double *src=getConstPointer();
2218   double *dest=ret->getPointer();
2219   for(int i=0;i<nbOfTuple;i++,src+=6)
2220     {
2221       double tmp[3];
2222       INTERP_KERNEL::computeEigenValues6(src,tmp);
2223       for(int j=0;j<3;j++,dest+=3)
2224         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2225     }
2226   return ret;
2227 }
2228
2229 /*!
2230  * Computes the inverse matrix of every matrix defined by the tuple of \a this
2231  * array, which contains either 4, 6 or 9 components. The case of 6 components
2232  * corresponds to that of the upper triangular matrix.
2233  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2234  *          same number of components as \a this one, whose each tuple is the inverse
2235  *          matrix of the matrix of corresponding tuple of \a this array. 
2236  *          The caller is to delete this result array using decrRef() as it is no more
2237  *          needed. 
2238  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2239  */
2240 DataArrayDouble *DataArrayDouble::inverse() const
2241 {
2242   checkAllocated();
2243   int nbOfComp=getNumberOfComponents();
2244   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2245     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2246   DataArrayDouble *ret=DataArrayDouble::New();
2247   int nbOfTuple=getNumberOfTuples();
2248   ret->alloc(nbOfTuple,nbOfComp);
2249   const double *src=getConstPointer();
2250   double *dest=ret->getPointer();
2251   if(nbOfComp==6)
2252     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2253       {
2254         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];
2255         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2256         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2257         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2258         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2259         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2260         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2261       }
2262   else if(nbOfComp==4)
2263     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2264       {
2265         double det=src[0]*src[3]-src[1]*src[2];
2266         dest[0]=src[3]/det;
2267         dest[1]=-src[1]/det;
2268         dest[2]=-src[2]/det;
2269         dest[3]=src[0]/det;
2270       }
2271   else
2272     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2273       {
2274         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];
2275         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2276         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2277         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2278         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2279         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2280         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2281         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2282         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2283         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2284       }
2285   return ret;
2286 }
2287
2288 /*!
2289  * Computes the trace of every matrix defined by the tuple of \a this
2290  * array, which contains either 4, 6 or 9 components. The case of 6 components
2291  * corresponds to that of the upper triangular matrix.
2292  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
2293  *          1 component, whose each tuple is the trace of
2294  *          the matrix of corresponding tuple of \a this array. 
2295  *          The caller is to delete this result array using decrRef() as it is no more
2296  *          needed. 
2297  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2298  */
2299 DataArrayDouble *DataArrayDouble::trace() const
2300 {
2301   checkAllocated();
2302   int nbOfComp=getNumberOfComponents();
2303   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2304     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2305   DataArrayDouble *ret=DataArrayDouble::New();
2306   int nbOfTuple=getNumberOfTuples();
2307   ret->alloc(nbOfTuple,1);
2308   const double *src=getConstPointer();
2309   double *dest=ret->getPointer();
2310   if(nbOfComp==6)
2311     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2312       *dest=src[0]+src[1]+src[2];
2313   else if(nbOfComp==4)
2314     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2315       *dest=src[0]+src[3];
2316   else
2317     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2318       *dest=src[0]+src[4]+src[8];
2319   return ret;
2320 }
2321
2322 /*!
2323  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2324  * \a this array, which contains 6 components.
2325  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2326  *          same number of components and tuples as \a this array.
2327  *          The caller is to delete this result array using decrRef() as it is no more
2328  *          needed.
2329  *  \throw If \a this->getNumberOfComponents() != 6.
2330  */
2331 DataArrayDouble *DataArrayDouble::deviator() const
2332 {
2333   checkAllocated();
2334   int nbOfComp=getNumberOfComponents();
2335   if(nbOfComp!=6)
2336     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2337   DataArrayDouble *ret=DataArrayDouble::New();
2338   int nbOfTuple=getNumberOfTuples();
2339   ret->alloc(nbOfTuple,6);
2340   const double *src=getConstPointer();
2341   double *dest=ret->getPointer();
2342   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2343     {
2344       double tr=(src[0]+src[1]+src[2])/3.;
2345       dest[0]=src[0]-tr;
2346       dest[1]=src[1]-tr;
2347       dest[2]=src[2]-tr;
2348       dest[3]=src[3];
2349       dest[4]=src[4];
2350       dest[5]=src[5];
2351     }
2352   return ret;
2353 }
2354
2355 /*!
2356  * Computes the magnitude of every vector defined by the tuple of
2357  * \a this array.
2358  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2359  *          same number of tuples as \a this array and one component.
2360  *          The caller is to delete this result array using decrRef() as it is no more
2361  *          needed.
2362  *  \throw If \a this is not allocated.
2363  */
2364 DataArrayDouble *DataArrayDouble::magnitude() const
2365 {
2366   checkAllocated();
2367   int nbOfComp=getNumberOfComponents();
2368   DataArrayDouble *ret=DataArrayDouble::New();
2369   int nbOfTuple=getNumberOfTuples();
2370   ret->alloc(nbOfTuple,1);
2371   const double *src=getConstPointer();
2372   double *dest=ret->getPointer();
2373   for(int i=0;i<nbOfTuple;i++,dest++)
2374     {
2375       double sum=0.;
2376       for(int j=0;j<nbOfComp;j++,src++)
2377         sum+=(*src)*(*src);
2378       *dest=sqrt(sum);
2379     }
2380   return ret;
2381 }
2382
2383 /*!
2384  * Computes the maximal value within every tuple of \a this array.
2385  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2386  *          same number of tuples as \a this array and one component.
2387  *          The caller is to delete this result array using decrRef() as it is no more
2388  *          needed.
2389  *  \throw If \a this is not allocated.
2390  *  \sa DataArrayDouble::maxPerTupleWithCompoId
2391  */
2392 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2393 {
2394   checkAllocated();
2395   int nbOfComp=getNumberOfComponents();
2396   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2397   int nbOfTuple=getNumberOfTuples();
2398   ret->alloc(nbOfTuple,1);
2399   const double *src=getConstPointer();
2400   double *dest=ret->getPointer();
2401   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2402     *dest=*std::max_element(src,src+nbOfComp);
2403   return ret.retn();
2404 }
2405
2406 /*!
2407  * Computes the maximal value within every tuple of \a this array and it returns the first component
2408  * id for each tuple that corresponds to the maximal value within the tuple.
2409  * 
2410  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2411  *          same number of tuples and only one component.
2412  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2413  *          same number of tuples as \a this array and one component.
2414  *          The caller is to delete this result array using decrRef() as it is no more
2415  *          needed.
2416  *  \throw If \a this is not allocated.
2417  *  \sa DataArrayDouble::maxPerTuple
2418  */
2419 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2420 {
2421   checkAllocated();
2422   int nbOfComp=getNumberOfComponents();
2423   MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2424   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2425   int nbOfTuple=getNumberOfTuples();
2426   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2427   const double *src=getConstPointer();
2428   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2429   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2430     {
2431       const double *loc=std::max_element(src,src+nbOfComp);
2432       *dest=*loc;
2433       *dest1=(int)std::distance(src,loc);
2434     }
2435   compoIdOfMaxPerTuple=ret1.retn();
2436   return ret0.retn();
2437 }
2438
2439 /*!
2440  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2441  * \n This returned array contains the euclidian distance for each tuple in \a this. 
2442  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2443  * \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)
2444  *
2445  * \warning use this method with care because it can leads to big amount of consumed memory !
2446  * 
2447  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2448  *
2449  * \throw If \a this is not allocated.
2450  *
2451  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2452  */
2453 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2454 {
2455   checkAllocated();
2456   int nbOfComp=getNumberOfComponents();
2457   int nbOfTuples=getNumberOfTuples();
2458   const double *inData=getConstPointer();
2459   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2460   ret->alloc(nbOfTuples*nbOfTuples,1);
2461   double *outData=ret->getPointer();
2462   for(int i=0;i<nbOfTuples;i++)
2463     {
2464       outData[i*nbOfTuples+i]=0.;
2465       for(int j=i+1;j<nbOfTuples;j++)
2466         {
2467           double dist=0.;
2468           for(int k=0;k<nbOfComp;k++)
2469             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2470           dist=sqrt(dist);
2471           outData[i*nbOfTuples+j]=dist;
2472           outData[j*nbOfTuples+i]=dist;
2473         }
2474     }
2475   return ret.retn();
2476 }
2477
2478 /*!
2479  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2480  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
2481  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2482  * \n Output rectangular matrix is sorted along rows.
2483  * \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)
2484  *
2485  * \warning use this method with care because it can leads to big amount of consumed memory !
2486  * 
2487  * \param [in] other DataArrayDouble instance having same number of components than \a this.
2488  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2489  *
2490  * \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.
2491  *
2492  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2493  */
2494 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2495 {
2496   if(!other)
2497     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2498   checkAllocated();
2499   other->checkAllocated();
2500   int nbOfComp=getNumberOfComponents();
2501   int otherNbOfComp=other->getNumberOfComponents();
2502   if(nbOfComp!=otherNbOfComp)
2503     {
2504       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2505       throw INTERP_KERNEL::Exception(oss.str().c_str());
2506     }
2507   int nbOfTuples=getNumberOfTuples();
2508   int otherNbOfTuples=other->getNumberOfTuples();
2509   const double *inData=getConstPointer();
2510   const double *inDataOther=other->getConstPointer();
2511   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2512   ret->alloc(otherNbOfTuples*nbOfTuples,1);
2513   double *outData=ret->getPointer();
2514   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2515     {
2516       for(int j=0;j<nbOfTuples;j++)
2517         {
2518           double dist=0.;
2519           for(int k=0;k<nbOfComp;k++)
2520             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2521           dist=sqrt(dist);
2522           outData[i*nbOfTuples+j]=dist;
2523         }
2524     }
2525   return ret.retn();
2526 }
2527
2528 /*!
2529  * This method expects that \a this stores 3 tuples containing 2 components each.
2530  * Each of this tuples represent a point into 2D space.
2531  * 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).
2532  * 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[.
2533  *  
2534  *  \throw If \a this is not allocated.
2535  *  \throw If \a this has not 3 tuples of 2 components
2536  *  \throw If tuples/points in \a this are aligned
2537  */
2538 void DataArrayDouble::asArcOfCircle(double center[2], double& radius, double& ang) const
2539 {
2540   checkAllocated();
2541   INTERP_KERNEL::QuadraticPlanarPrecision arcPrec(1e-14);
2542   if(getNumberOfTuples()!=3 && getNumberOfComponents()!=2)
2543     throw INTERP_KERNEL::Exception("DataArrayDouble::asArcCircle : this method expects");
2544   const double *pt(begin());
2545   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]));
2546   {
2547     INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::EdgeLin> e1(new INTERP_KERNEL::EdgeLin(n0,n2)),e2(new INTERP_KERNEL::EdgeLin(n2,n1));
2548     INTERP_KERNEL::SegSegIntersector inters(*e1,*e2);
2549     bool colinearity(inters.areColinears());
2550     if(colinearity)
2551       throw INTERP_KERNEL::Exception("DataArrayDouble::asArcOfCircle : 3 points in this have been detected as colinear !");
2552   }
2553   INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::EdgeArcCircle> ret(new INTERP_KERNEL::EdgeArcCircle(n0,n2,n1));
2554   const double *c(ret->getCenter());
2555   center[0]=c[0]; center[1]=c[1];
2556   radius=ret->getRadius();
2557   ang=ret->getAngle();
2558 }
2559
2560 /*!
2561  * Sorts value within every tuple of \a this array.
2562  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
2563  *              in descending order.
2564  *  \throw If \a this is not allocated.
2565  */
2566 void DataArrayDouble::sortPerTuple(bool asc)
2567 {
2568   checkAllocated();
2569   double *pt=getPointer();
2570   int nbOfTuple=getNumberOfTuples();
2571   int nbOfComp=getNumberOfComponents();
2572   if(asc)
2573     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2574       std::sort(pt,pt+nbOfComp);
2575   else
2576     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2577       std::sort(pt,pt+nbOfComp,std::greater<double>());
2578   declareAsNew();
2579 }
2580
2581 /*!
2582  * Modify all elements of \a this array, so that
2583  * an element _x_ becomes \f$ numerator / x \f$.
2584  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
2585  *           array, all elements processed before detection of the zero element remain
2586  *           modified.
2587  *  \param [in] numerator - the numerator used to modify array elements.
2588  *  \throw If \a this is not allocated.
2589  *  \throw If there is an element equal to 0.0 in \a this array.
2590  */
2591 void DataArrayDouble::applyInv(double numerator)
2592 {
2593   checkAllocated();
2594   double *ptr=getPointer();
2595   std::size_t nbOfElems=getNbOfElems();
2596   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2597     {
2598       if(std::abs(*ptr)>std::numeric_limits<double>::min())
2599         {
2600           *ptr=numerator/(*ptr);
2601         }
2602       else
2603         {
2604           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2605           oss << " !";
2606           throw INTERP_KERNEL::Exception(oss.str().c_str());
2607         }
2608     }
2609   declareAsNew();
2610 }
2611
2612 /*!
2613  * Modify all elements of \a this array, so that
2614  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2615  * all values in \a this have to be >= 0 if val is \b not integer.
2616  *  \param [in] val - the value used to apply pow on all array elements.
2617  *  \throw If \a this is not allocated.
2618  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2619  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
2620  *           modified.
2621  */
2622 void DataArrayDouble::applyPow(double val)
2623 {
2624   checkAllocated();
2625   double *ptr=getPointer();
2626   std::size_t nbOfElems=getNbOfElems();
2627   int val2=(int)val;
2628   bool isInt=((double)val2)==val;
2629   if(!isInt)
2630     {
2631       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2632         {
2633           if(*ptr>=0)
2634             *ptr=pow(*ptr,val);
2635           else
2636             {
2637               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2638               throw INTERP_KERNEL::Exception(oss.str().c_str());
2639             }
2640         }
2641     }
2642   else
2643     {
2644       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2645         *ptr=pow(*ptr,val2);
2646     }
2647   declareAsNew();
2648 }
2649
2650 /*!
2651  * Modify all elements of \a this array, so that
2652  * an element _x_ becomes \f$ val ^ x \f$.
2653  *  \param [in] val - the value used to apply pow on all array elements.
2654  *  \throw If \a this is not allocated.
2655  *  \throw If \a val < 0.
2656  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2657  *           array, all elements processed before detection of the zero element remain
2658  *           modified.
2659  */
2660 void DataArrayDouble::applyRPow(double val)
2661 {
2662   checkAllocated();
2663   if(val<0.)
2664     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2665   double *ptr=getPointer();
2666   std::size_t nbOfElems=getNbOfElems();
2667   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2668     *ptr=pow(val,*ptr);
2669   declareAsNew();
2670 }
2671
2672 /*!
2673  * Returns a new DataArrayDouble created from \a this one by applying \a
2674  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2675  * For more info see \ref MEDCouplingArrayApplyFunc
2676  *  \param [in] nbOfComp - number of components in the result array.
2677  *  \param [in] func - the \a FunctionToEvaluate declared as 
2678  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
2679  *              where \a pos points to the first component of a tuple of \a this array
2680  *              and \a res points to the first component of a tuple of the result array.
2681  *              Note that length (number of components) of \a pos can differ from
2682  *              that of \a res.
2683  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2684  *          same number of tuples as \a this array.
2685  *          The caller is to delete this result array using decrRef() as it is no more
2686  *          needed.
2687  *  \throw If \a this is not allocated.
2688  *  \throw If \a func returns \a false.
2689  */
2690 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2691 {
2692   checkAllocated();
2693   DataArrayDouble *newArr=DataArrayDouble::New();
2694   int nbOfTuples=getNumberOfTuples();
2695   int oldNbOfComp=getNumberOfComponents();
2696   newArr->alloc(nbOfTuples,nbOfComp);
2697   const double *ptr=getConstPointer();
2698   double *ptrToFill=newArr->getPointer();
2699   for(int i=0;i<nbOfTuples;i++)
2700     {
2701       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2702         {
2703           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2704           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2705           oss << ") : Evaluation of function failed !";
2706           newArr->decrRef();
2707           throw INTERP_KERNEL::Exception(oss.str().c_str());
2708         }
2709     }
2710   return newArr;
2711 }
2712
2713 /*!
2714  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2715  * tuple of \a this array. Textual data is not copied.
2716  * For more info see \ref MEDCouplingArrayApplyFunc1.
2717  *  \param [in] nbOfComp - number of components in the result array.
2718  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2719  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2720  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2721  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2722  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2723  *          same number of tuples as \a this array and \a nbOfComp components.
2724  *          The caller is to delete this result array using decrRef() as it is no more
2725  *          needed.
2726  *  \throw If \a this is not allocated.
2727  *  \throw If computing \a func fails.
2728  */
2729 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2730 {
2731   INTERP_KERNEL::ExprParser expr(func);
2732   expr.parse();
2733   std::set<std::string> vars;
2734   expr.getTrueSetOfVars(vars);
2735   std::vector<std::string> varsV(vars.begin(),vars.end());
2736   return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2737 }
2738
2739 /*!
2740  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2741  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2742  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2743  *
2744  * For more info see \ref MEDCouplingArrayApplyFunc0.
2745  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2746  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2747  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2748  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
2749  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2750  *          same number of tuples and components as \a this array.
2751  *          The caller is to delete this result array using decrRef() as it is no more
2752  *          needed.
2753  *  \sa applyFuncOnThis
2754  *  \throw If \a this is not allocated.
2755  *  \throw If computing \a func fails.
2756  */
2757 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
2758 {
2759   int nbOfComp(getNumberOfComponents());
2760   if(nbOfComp<=0)
2761     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
2762   checkAllocated();
2763   int nbOfTuples(getNumberOfTuples());
2764   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2765   newArr->alloc(nbOfTuples,nbOfComp);
2766   INTERP_KERNEL::ExprParser expr(func);
2767   expr.parse();
2768   std::set<std::string> vars;
2769   expr.getTrueSetOfVars(vars);
2770   if((int)vars.size()>1)
2771     {
2772       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 : ";
2773       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2774       throw INTERP_KERNEL::Exception(oss.str().c_str());
2775     }
2776   if(vars.empty())
2777     {
2778       expr.prepareFastEvaluator();
2779       newArr->rearrange(1);
2780       newArr->fillWithValue(expr.evaluateDouble());
2781       newArr->rearrange(nbOfComp);
2782       return newArr.retn();
2783     }
2784   std::vector<std::string> vars2(vars.begin(),vars.end());
2785   double buff,*ptrToFill(newArr->getPointer());
2786   const double *ptr(begin());
2787   std::vector<double> stck;
2788   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2789   expr.prepareFastEvaluator();
2790   if(!isSafe)
2791     {
2792       for(int i=0;i<nbOfTuples;i++)
2793         {
2794           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2795             {
2796               buff=*ptr;
2797               expr.evaluateDoubleInternal(stck);
2798               *ptrToFill=stck.back();
2799               stck.pop_back();
2800             }
2801         }
2802     }
2803   else
2804     {
2805       for(int i=0;i<nbOfTuples;i++)
2806         {
2807           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2808             {
2809               buff=*ptr;
2810               try
2811               {
2812                   expr.evaluateDoubleInternalSafe(stck);
2813               }
2814               catch(INTERP_KERNEL::Exception& e)
2815               {
2816                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2817                   oss << buff;
2818                   oss << ") : Evaluation of function failed !" << e.what();
2819                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2820               }
2821               *ptrToFill=stck.back();
2822               stck.pop_back();
2823             }
2824         }
2825     }
2826   return newArr.retn();
2827 }
2828
2829 /*!
2830  * This method is a non const method that modify the array in \a this.
2831  * This method only works on one component array. It means that function \a func must
2832  * contain at most one variable.
2833  * This method is a specialization of applyFunc method with one parameter on one component array.
2834  *
2835  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2836  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2837  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2838  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2839  *
2840  * \sa applyFunc
2841  */
2842 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
2843 {
2844   int nbOfComp(getNumberOfComponents());
2845   if(nbOfComp<=0)
2846     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
2847   checkAllocated();
2848   int nbOfTuples(getNumberOfTuples());
2849   INTERP_KERNEL::ExprParser expr(func);
2850   expr.parse();
2851   std::set<std::string> vars;
2852   expr.getTrueSetOfVars(vars);
2853   if((int)vars.size()>1)
2854     {
2855       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 : ";
2856       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2857       throw INTERP_KERNEL::Exception(oss.str().c_str());
2858     }
2859   if(vars.empty())
2860     {
2861       expr.prepareFastEvaluator();
2862       std::vector<std::string> compInfo(getInfoOnComponents());
2863       rearrange(1);
2864       fillWithValue(expr.evaluateDouble());
2865       rearrange(nbOfComp);
2866       setInfoOnComponents(compInfo);
2867       return ;
2868     }
2869   std::vector<std::string> vars2(vars.begin(),vars.end());
2870   double buff,*ptrToFill(getPointer());
2871   const double *ptr(begin());
2872   std::vector<double> stck;
2873   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2874   expr.prepareFastEvaluator();
2875   if(!isSafe)
2876     {
2877       for(int i=0;i<nbOfTuples;i++)
2878         {
2879           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2880             {
2881               buff=*ptr;
2882               expr.evaluateDoubleInternal(stck);
2883               *ptrToFill=stck.back();
2884               stck.pop_back();
2885             }
2886         }
2887     }
2888   else
2889     {
2890       for(int i=0;i<nbOfTuples;i++)
2891         {
2892           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2893             {
2894               buff=*ptr;
2895               try
2896               {
2897                   expr.evaluateDoubleInternalSafe(stck);
2898               }
2899               catch(INTERP_KERNEL::Exception& e)
2900               {
2901                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2902                   oss << buff;
2903                   oss << ") : Evaluation of function failed !" << e.what();
2904                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2905               }
2906               *ptrToFill=stck.back();
2907               stck.pop_back();
2908             }
2909         }
2910     }
2911 }
2912
2913 /*!
2914  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2915  * tuple of \a this array. Textual data is not copied.
2916  * For more info see \ref MEDCouplingArrayApplyFunc2.
2917  *  \param [in] nbOfComp - number of components in the result array.
2918  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2919  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2920  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2921  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2922  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2923  *          same number of tuples as \a this array.
2924  *          The caller is to delete this result array using decrRef() as it is no more
2925  *          needed.
2926  *  \throw If \a this is not allocated.
2927  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
2928  *  \throw If computing \a func fails.
2929  */
2930 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
2931 {
2932   return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
2933 }
2934
2935 /*!
2936  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2937  * tuple of \a this array. Textual data is not copied.
2938  * For more info see \ref MEDCouplingArrayApplyFunc3.
2939  *  \param [in] nbOfComp - number of components in the result array.
2940  *  \param [in] varsOrder - sequence of vars defining their order.
2941  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2942  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2943  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2944  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2945  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2946  *          same number of tuples as \a this array.
2947  *          The caller is to delete this result array using decrRef() as it is no more
2948  *          needed.
2949  *  \throw If \a this is not allocated.
2950  *  \throw If \a func contains vars not in \a varsOrder.
2951  *  \throw If computing \a func fails.
2952  */
2953 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
2954 {
2955   if(nbOfComp<=0)
2956     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
2957   std::vector<std::string> varsOrder2(varsOrder);
2958   int oldNbOfComp(getNumberOfComponents());
2959   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
2960     varsOrder2.push_back(std::string());
2961   checkAllocated();
2962   int nbOfTuples(getNumberOfTuples());
2963   INTERP_KERNEL::ExprParser expr(func);
2964   expr.parse();
2965   std::set<std::string> vars;
2966   expr.getTrueSetOfVars(vars);
2967   if((int)vars.size()>oldNbOfComp)
2968     {
2969       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
2970       oss << vars.size() << " variables : ";
2971       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2972       throw INTERP_KERNEL::Exception(oss.str().c_str());
2973     }
2974   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2975   newArr->alloc(nbOfTuples,nbOfComp);
2976   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
2977   double *buffPtr(buff),*ptrToFill;
2978   std::vector<double> stck;
2979   for(int iComp=0;iComp<nbOfComp;iComp++)
2980     {
2981       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
2982       expr.prepareFastEvaluator();
2983       const double *ptr(getConstPointer());
2984       ptrToFill=newArr->getPointer()+iComp;
2985       if(!isSafe)
2986         {
2987           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2988             {
2989               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2990               expr.evaluateDoubleInternal(stck);
2991               *ptrToFill=stck.back();
2992               stck.pop_back();
2993             }
2994         }
2995       else
2996         {
2997           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2998             {
2999               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3000               try
3001               {
3002                   expr.evaluateDoubleInternalSafe(stck);
3003                   *ptrToFill=stck.back();
3004                   stck.pop_back();
3005               }
3006               catch(INTERP_KERNEL::Exception& e)
3007               {
3008                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3009                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3010                   oss << ") : Evaluation of function failed !" << e.what();
3011                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3012               }
3013             }
3014         }
3015     }
3016   return newArr.retn();
3017 }
3018
3019 void DataArrayDouble::applyFuncFast32(const std::string& func)
3020 {
3021   checkAllocated();
3022   INTERP_KERNEL::ExprParser expr(func);
3023   expr.parse();
3024   char *funcStr=expr.compileX86();
3025   MYFUNCPTR funcPtr;
3026   *((void **)&funcPtr)=funcStr;//he he...
3027   //
3028   double *ptr=getPointer();
3029   int nbOfComp=getNumberOfComponents();
3030   int nbOfTuples=getNumberOfTuples();
3031   int nbOfElems=nbOfTuples*nbOfComp;
3032   for(int i=0;i<nbOfElems;i++,ptr++)
3033     *ptr=funcPtr(*ptr);
3034   declareAsNew();
3035 }
3036
3037 void DataArrayDouble::applyFuncFast64(const std::string& func)
3038 {
3039   checkAllocated();
3040   INTERP_KERNEL::ExprParser expr(func);
3041   expr.parse();
3042   char *funcStr=expr.compileX86_64();
3043   MYFUNCPTR funcPtr;
3044   *((void **)&funcPtr)=funcStr;//he he...
3045   //
3046   double *ptr=getPointer();
3047   int nbOfComp=getNumberOfComponents();
3048   int nbOfTuples=getNumberOfTuples();
3049   int nbOfElems=nbOfTuples*nbOfComp;
3050   for(int i=0;i<nbOfElems;i++,ptr++)
3051     *ptr=funcPtr(*ptr);
3052   declareAsNew();
3053 }
3054
3055 /*!
3056  * \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.
3057  */
3058 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3059 {
3060   checkAllocated();
3061   if(getNumberOfComponents()!=3)
3062     throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3063   int nbTuples(getNumberOfTuples());
3064   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3065   ret->alloc(nbTuples,3);
3066   Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3067   return ret;
3068 }
3069
3070 DataArrayDoubleIterator *DataArrayDouble::iterator()
3071 {
3072   return new DataArrayDoubleIterator(this);
3073 }
3074
3075 /*!
3076  * Returns a new DataArrayInt containing indices of tuples of \a this one-dimensional
3077  * array whose values are within a given range. Textual data is not copied.
3078  *  \param [in] vmin - a lowest acceptable value (included).
3079  *  \param [in] vmax - a greatest acceptable value (included).
3080  *  \return DataArrayInt * - the new instance of DataArrayInt.
3081  *          The caller is to delete this result array using decrRef() as it is no more
3082  *          needed.
3083  *  \throw If \a this->getNumberOfComponents() != 1.
3084  *
3085  *  \sa DataArrayDouble::findIdsNotInRange
3086  *
3087  *  \if ENABLE_EXAMPLES
3088  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3089  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3090  *  \endif
3091  */
3092 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3093 {
3094   checkAllocated();
3095   if(getNumberOfComponents()!=1)
3096     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3097   const double *cptr(begin());
3098   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3099   int nbOfTuples(getNumberOfTuples());
3100   for(int i=0;i<nbOfTuples;i++,cptr++)
3101     if(*cptr>=vmin && *cptr<=vmax)
3102       ret->pushBackSilent(i);
3103   return ret.retn();
3104 }
3105
3106 /*!
3107  * Returns a new DataArrayInt containing indices of tuples of \a this one-dimensional
3108  * array whose values are not within a given range. Textual data is not copied.
3109  *  \param [in] vmin - a lowest not acceptable value (excluded).
3110  *  \param [in] vmax - a greatest not acceptable value (excluded).
3111  *  \return DataArrayInt * - the new instance of DataArrayInt.
3112  *          The caller is to delete this result array using decrRef() as it is no more
3113  *          needed.
3114  *  \throw If \a this->getNumberOfComponents() != 1.
3115  *
3116  *  \sa DataArrayDouble::findIdsInRange
3117  */
3118 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3119 {
3120   checkAllocated();
3121   if(getNumberOfComponents()!=1)
3122     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3123   const double *cptr(begin());
3124   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3125   int nbOfTuples(getNumberOfTuples());
3126   for(int i=0;i<nbOfTuples;i++,cptr++)
3127     if(*cptr<vmin || *cptr>vmax)
3128       ret->pushBackSilent(i);
3129   return ret.retn();
3130 }
3131
3132 /*!
3133  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3134  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3135  * the number of component in the result array is same as that of each of given arrays.
3136  * Info on components is copied from the first of the given arrays. Number of components
3137  * in the given arrays must be  the same.
3138  *  \param [in] a1 - an array to include in the result array.
3139  *  \param [in] a2 - another array to include in the result array.
3140  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3141  *          The caller is to delete this result array using decrRef() as it is no more
3142  *          needed.
3143  *  \throw If both \a a1 and \a a2 are NULL.
3144  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3145  */
3146 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3147 {
3148   std::vector<const DataArrayDouble *> tmp(2);
3149   tmp[0]=a1; tmp[1]=a2;
3150   return Aggregate(tmp);
3151 }
3152
3153 /*!
3154  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3155  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3156  * the number of component in the result array is same as that of each of given arrays.
3157  * Info on components is copied from the first of the given arrays. Number of components
3158  * in the given arrays must be  the same.
3159  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3160  * not the object itself.
3161  *  \param [in] arr - a sequence of arrays to include in the result array.
3162  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3163  *          The caller is to delete this result array using decrRef() as it is no more
3164  *          needed.
3165  *  \throw If all arrays within \a arr are NULL.
3166  *  \throw If getNumberOfComponents() of arrays within \a arr.
3167  */
3168 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3169 {
3170   std::vector<const DataArrayDouble *> a;
3171   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3172     if(*it4)
3173       a.push_back(*it4);
3174   if(a.empty())
3175     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3176   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3177   std::size_t nbOfComp((*it)->getNumberOfComponents());
3178   int nbt=(*it++)->getNumberOfTuples();
3179   for(int i=1;it!=a.end();it++,i++)
3180     {
3181       if((*it)->getNumberOfComponents()!=nbOfComp)
3182         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3183       nbt+=(*it)->getNumberOfTuples();
3184     }
3185   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3186   ret->alloc(nbt,nbOfComp);
3187   double *pt=ret->getPointer();
3188   for(it=a.begin();it!=a.end();it++)
3189     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3190   ret->copyStringInfoFrom(*(a[0]));
3191   return ret.retn();
3192 }
3193
3194 /*!
3195  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3196  * the i-th tuple of the result array is a sum of products of j-th components of i-th
3197  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3198  * Info on components and name is copied from the first of the given arrays.
3199  * Number of tuples and components in the given arrays must be the same.
3200  *  \param [in] a1 - a given array.
3201  *  \param [in] a2 - another given array.
3202  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3203  *          The caller is to delete this result array using decrRef() as it is no more
3204  *          needed.
3205  *  \throw If either \a a1 or \a a2 is NULL.
3206  *  \throw If any given array is not allocated.
3207  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3208  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3209  */
3210 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3211 {
3212   if(!a1 || !a2)
3213     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3214   a1->checkAllocated();
3215   a2->checkAllocated();
3216   std::size_t nbOfComp(a1->getNumberOfComponents());
3217   if(nbOfComp!=a2->getNumberOfComponents())
3218     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3219   std::size_t nbOfTuple(a1->getNumberOfTuples());
3220   if(nbOfTuple!=a2->getNumberOfTuples())
3221     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3222   DataArrayDouble *ret=DataArrayDouble::New();
3223   ret->alloc(nbOfTuple,1);
3224   double *retPtr=ret->getPointer();
3225   const double *a1Ptr=a1->begin(),*a2Ptr(a2->begin());
3226   for(std::size_t i=0;i<nbOfTuple;i++)
3227     {
3228       double sum=0.;
3229       for(std::size_t j=0;j<nbOfComp;j++)
3230         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3231       retPtr[i]=sum;
3232     }
3233   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3234   ret->setName(a1->getName());
3235   return ret;
3236 }
3237
3238 /*!
3239  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3240  * the i-th tuple of the result array contains 3 components of a vector which is a cross
3241  * product of two vectors defined by the i-th tuples of given arrays.
3242  * Info on components is copied from the first of the given arrays.
3243  * Number of tuples in the given arrays must be the same.
3244  * Number of components in the given arrays must be 3.
3245  *  \param [in] a1 - a given array.
3246  *  \param [in] a2 - another given array.
3247  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3248  *          The caller is to delete this result array using decrRef() as it is no more
3249  *          needed.
3250  *  \throw If either \a a1 or \a a2 is NULL.
3251  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3252  *  \throw If \a a1->getNumberOfComponents() != 3
3253  *  \throw If \a a2->getNumberOfComponents() != 3
3254  */
3255 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3256 {
3257   if(!a1 || !a2)
3258     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3259   std::size_t nbOfComp(a1->getNumberOfComponents());
3260   if(nbOfComp!=a2->getNumberOfComponents())
3261     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3262   if(nbOfComp!=3)
3263     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3264   std::size_t nbOfTuple(a1->getNumberOfTuples());
3265   if(nbOfTuple!=a2->getNumberOfTuples())
3266     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3267   DataArrayDouble *ret=DataArrayDouble::New();
3268   ret->alloc(nbOfTuple,3);
3269   double *retPtr=ret->getPointer();
3270   const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3271   for(std::size_t i=0;i<nbOfTuple;i++)
3272     {
3273       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3274       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3275       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3276     }
3277   ret->copyStringInfoFrom(*a1);
3278   return ret;
3279 }
3280
3281 /*!
3282  * Returns a new DataArrayDouble containing maximal values of two given arrays.
3283  * Info on components is copied from the first of the given arrays.
3284  * Number of tuples and components in the given arrays must be the same.
3285  *  \param [in] a1 - an array to compare values with another one.
3286  *  \param [in] a2 - another array to compare values with the first one.
3287  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3288  *          The caller is to delete this result array using decrRef() as it is no more
3289  *          needed.
3290  *  \throw If either \a a1 or \a a2 is NULL.
3291  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3292  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3293  */
3294 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3295 {
3296   if(!a1 || !a2)
3297     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3298   std::size_t nbOfComp(a1->getNumberOfComponents());
3299   if(nbOfComp!=a2->getNumberOfComponents())
3300     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3301   std::size_t nbOfTuple(a1->getNumberOfTuples());
3302   if(nbOfTuple!=a2->getNumberOfTuples())
3303     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3304   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3305   ret->alloc(nbOfTuple,nbOfComp);
3306   double *retPtr(ret->getPointer());
3307   const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3308   std::size_t nbElem(nbOfTuple*nbOfComp);
3309   for(std::size_t i=0;i<nbElem;i++)
3310     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3311   ret->copyStringInfoFrom(*a1);
3312   return ret.retn();
3313 }
3314
3315 /*!
3316  * Returns a new DataArrayDouble containing minimal values of two given arrays.
3317  * Info on components is copied from the first of the given arrays.
3318  * Number of tuples and components in the given arrays must be the same.
3319  *  \param [in] a1 - an array to compare values with another one.
3320  *  \param [in] a2 - another array to compare values with the first one.
3321  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3322  *          The caller is to delete this result array using decrRef() as it is no more
3323  *          needed.
3324  *  \throw If either \a a1 or \a a2 is NULL.
3325  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3326  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3327  */
3328 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3329 {
3330   if(!a1 || !a2)
3331     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3332   std::size_t nbOfComp(a1->getNumberOfComponents());
3333   if(nbOfComp!=a2->getNumberOfComponents())
3334     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3335   std::size_t nbOfTuple(a1->getNumberOfTuples());
3336   if(nbOfTuple!=a2->getNumberOfTuples())
3337     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3338   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3339   ret->alloc(nbOfTuple,nbOfComp);
3340   double *retPtr(ret->getPointer());
3341   const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3342   std::size_t nbElem(nbOfTuple*nbOfComp);
3343   for(std::size_t i=0;i<nbElem;i++)
3344     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3345   ret->copyStringInfoFrom(*a1);
3346   return ret.retn();
3347 }
3348
3349 /*!
3350  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
3351  * valid cases.
3352  *
3353  *  \param [in] a1 - an array to pow up.
3354  *  \param [in] a2 - another array to sum up.
3355  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3356  *          The caller is to delete this result array using decrRef() as it is no more
3357  *          needed.
3358  *  \throw If either \a a1 or \a a2 is NULL.
3359  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3360  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
3361  *  \throw If there is a negative value in \a a1.
3362  */
3363 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
3364 {
3365   if(!a1 || !a2)
3366     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
3367   int nbOfTuple=a1->getNumberOfTuples();
3368   int nbOfTuple2=a2->getNumberOfTuples();
3369   int nbOfComp=a1->getNumberOfComponents();
3370   int nbOfComp2=a2->getNumberOfComponents();
3371   if(nbOfTuple!=nbOfTuple2)
3372     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
3373   if(nbOfComp!=1 || nbOfComp2!=1)
3374     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
3375   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
3376   const double *ptr1(a1->begin()),*ptr2(a2->begin());
3377   double *ptr=ret->getPointer();
3378   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
3379     {
3380       if(*ptr1>=0)
3381         {
3382           *ptr=pow(*ptr1,*ptr2);
3383         }
3384       else
3385         {
3386           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
3387           throw INTERP_KERNEL::Exception(oss.str().c_str());
3388         }
3389     }
3390   return ret.retn();
3391 }
3392
3393 /*!
3394  * Apply pow on values of another DataArrayDouble to values of \a this one.
3395  *
3396  *  \param [in] other - an array to pow to \a this one.
3397  *  \throw If \a other is NULL.
3398  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
3399  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
3400  *  \throw If there is a negative value in \a this.
3401  */
3402 void DataArrayDouble::powEqual(const DataArrayDouble *other)
3403 {
3404   if(!other)
3405     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
3406   int nbOfTuple=getNumberOfTuples();
3407   int nbOfTuple2=other->getNumberOfTuples();
3408   int nbOfComp=getNumberOfComponents();
3409   int nbOfComp2=other->getNumberOfComponents();
3410   if(nbOfTuple!=nbOfTuple2)
3411     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
3412   if(nbOfComp!=1 || nbOfComp2!=1)
3413     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
3414   double *ptr=getPointer();
3415   const double *ptrc=other->begin();
3416   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
3417     {
3418       if(*ptr>=0)
3419         *ptr=pow(*ptr,*ptrc);
3420       else
3421         {
3422           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
3423           throw INTERP_KERNEL::Exception(oss.str().c_str());
3424         }
3425     }
3426   declareAsNew();
3427 }
3428
3429 /*!
3430  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
3431  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
3432  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
3433  *
3434  * \throw if \a this is not allocated.
3435  * \throw if \a this has not exactly one component.
3436  */
3437 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
3438 {
3439   checkAllocated();
3440   if(getNumberOfComponents()!=1)
3441     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
3442   int nbt(getNumberOfTuples());
3443   std::vector<bool> ret(nbt);
3444   const double *pt(begin());
3445   for(int i=0;i<nbt;i++)
3446     {
3447       if(fabs(pt[i])<eps)
3448         ret[i]=false;
3449       else if(fabs(pt[i]-1.)<eps)
3450         ret[i]=true;
3451       else
3452         {
3453           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
3454           throw INTERP_KERNEL::Exception(oss.str().c_str());
3455         }
3456     }
3457   return ret;
3458 }
3459
3460 /*!
3461  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3462  * Server side.
3463  */
3464 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
3465 {
3466   tinyInfo.resize(2);
3467   if(isAllocated())
3468     {
3469       tinyInfo[0]=getNumberOfTuples();
3470       tinyInfo[1]=getNumberOfComponents();
3471     }
3472   else
3473     {
3474       tinyInfo[0]=-1;
3475       tinyInfo[1]=-1;
3476     }
3477 }
3478
3479 /*!
3480  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3481  * Server side.
3482  */
3483 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
3484 {
3485   if(isAllocated())
3486     {
3487       int nbOfCompo=getNumberOfComponents();
3488       tinyInfo.resize(nbOfCompo+1);
3489       tinyInfo[0]=getName();
3490       for(int i=0;i<nbOfCompo;i++)
3491         tinyInfo[i+1]=getInfoOnComponent(i);
3492     }
3493   else
3494     {
3495       tinyInfo.resize(1);
3496       tinyInfo[0]=getName();
3497     }
3498 }
3499
3500 /*!
3501  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3502  * This method returns if a feeding is needed.
3503  */
3504 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
3505 {
3506   int nbOfTuple=tinyInfoI[0];
3507   int nbOfComp=tinyInfoI[1];
3508   if(nbOfTuple!=-1 || nbOfComp!=-1)
3509     {
3510       alloc(nbOfTuple,nbOfComp);
3511       return true;
3512     }
3513   return false;
3514 }
3515
3516 /*!
3517  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3518  */
3519 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
3520 {
3521   setName(tinyInfoS[0]);
3522   if(isAllocated())
3523     {
3524       int nbOfCompo=getNumberOfComponents();
3525       for(int i=0;i<nbOfCompo;i++)
3526         setInfoOnComponent(i,tinyInfoS[i+1]);
3527     }
3528 }
3529
3530 /*!
3531  * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
3532  * around an axe ( \a center, \a vect) and with angle \a angle.
3533  */
3534 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3535 {
3536   if(!center || !vect)
3537     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
3538   double sina(sin(angle));
3539   double cosa(cos(angle));
3540   double vectorNorm[3];
3541   double matrix[9];
3542   double matrixTmp[9];
3543   double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
3544   if(norm<std::numeric_limits<double>::min())
3545     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
3546   std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
3547   //rotation matrix computation
3548   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;
3549   matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
3550   matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
3551   matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
3552   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
3553   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3554   matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
3555   matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
3556   matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
3557   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
3558   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3559   //rotation matrix computed.
3560   double tmp[3];
3561   for(int i=0; i<nbNodes; i++)
3562     {
3563       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
3564       coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
3565       coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
3566       coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
3567     }
3568 }
3569
3570 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
3571 {
3572   double matrix[9],matrix2[9],matrix3[9];
3573   double vect[3],crossVect[3];
3574   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3575   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3576   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3577   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3578   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3579   matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
3580   matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
3581   matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
3582   matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
3583   matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
3584   matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
3585   for(int i=0;i<3;i++)
3586     for(int j=0;j<3;j++)
3587       {
3588         double val(0.);
3589         for(int k=0;k<3;k++)
3590           val+=matrix[3*i+k]*matrix2[3*k+j];
3591         matrix3[3*i+j]=val;
3592       }
3593   //rotation matrix computed.
3594   double tmp[3];
3595   for(int i=0; i<nbNodes; i++)
3596     {
3597       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
3598       coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
3599       coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
3600       coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
3601     }
3602 }
3603
3604 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
3605 {
3606   double vect[3],crossVect[3];
3607   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3608   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3609   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3610   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3611   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3612   baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
3613   baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
3614   baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
3615 }
3616
3617 /*!
3618  * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
3619  * around the center point \a center and with angle \a angle.
3620  */
3621 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3622 {
3623   double cosa=cos(angle);
3624   double sina=sin(angle);
3625   double matrix[4];
3626   matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
3627   double tmp[2];
3628   for(int i=0; i<nbNodes; i++)
3629     {
3630       std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
3631       coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
3632       coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
3633     }
3634 }
3635
3636 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
3637 {
3638 }
3639
3640 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
3641 {
3642 }
3643
3644
3645 std::string DataArrayDoubleTuple::repr() const
3646 {
3647   std::ostringstream oss; oss.precision(17); oss << "(";
3648   for(int i=0;i<_nb_of_compo-1;i++)
3649     oss << _pt[i] << ", ";
3650   oss << _pt[_nb_of_compo-1] << ")";
3651   return oss.str();
3652 }
3653
3654 double DataArrayDoubleTuple::doubleValue() const
3655 {
3656   return this->zeValue();
3657 }
3658
3659 /*!
3660  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
3661  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
3662  * 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
3663  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
3664  */
3665 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
3666 {
3667   return this->buildDA(nbOfTuples,nbOfCompo);
3668 }
3669
3670 /*!
3671  * Returns a new instance of DataArrayInt. The caller is to delete this array
3672  * using decrRef() as it is no more needed. 
3673  */
3674 DataArrayInt *DataArrayInt::New()
3675 {
3676   return new DataArrayInt;
3677 }
3678
3679 /*!
3680  * Returns the only one value in \a this, if and only if number of elements
3681  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3682  *  \return double - the sole value stored in \a this array.
3683  *  \throw If at least one of conditions stated above is not fulfilled.
3684  */
3685 int DataArrayInt::intValue() const
3686 {
3687   if(isAllocated())
3688     {
3689       if(getNbOfElems()==1)
3690         {
3691           return *getConstPointer();
3692         }
3693       else
3694         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3695     }
3696   else
3697     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3698 }
3699
3700 /*!
3701  * Returns an integer value characterizing \a this array, which is useful for a quick
3702  * comparison of many instances of DataArrayInt.
3703  *  \return int - the hash value.
3704  *  \throw If \a this is not allocated.
3705  */
3706 int DataArrayInt::getHashCode() const
3707 {
3708   checkAllocated();
3709   std::size_t nbOfElems=getNbOfElems();
3710   int ret=nbOfElems*65536;
3711   int delta=3;
3712   if(nbOfElems>48)
3713     delta=nbOfElems/8;
3714   int ret0=0;
3715   const int *pt=begin();
3716   for(std::size_t i=0;i<nbOfElems;i+=delta)
3717     ret0+=pt[i] & 0x1FFF;
3718   return ret+ret0;
3719 }
3720
3721 /*!
3722  * Returns a full copy of \a this. For more info on copying data arrays see
3723  * \ref MEDCouplingArrayBasicsCopyDeep.
3724  *  \return DataArrayInt * - a new instance of DataArrayInt.
3725  */
3726 DataArrayInt32 *DataArrayInt32::deepCopy() const
3727 {
3728   return new DataArrayInt32(*this);
3729 }
3730
3731 /*!
3732  * Returns a textual and human readable representation of \a this instance of
3733  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
3734  * \return std::string - text describing \a this DataArrayInt.
3735  * 
3736  * \sa reprNotTooLong, reprZip
3737  */
3738 std::string DataArrayInt::repr() const
3739 {
3740   std::ostringstream ret;
3741   reprStream(ret);
3742   return ret.str();
3743 }
3744
3745 std::string DataArrayInt::reprZip() const
3746 {
3747   std::ostringstream ret;
3748   reprZipStream(ret);
3749   return ret.str();
3750 }
3751
3752 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
3753 {
3754   static const char SPACE[4]={' ',' ',' ',' '};
3755   checkAllocated();
3756   std::string idt(indent,' ');
3757   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
3758   if(byteArr)
3759     {
3760       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
3761       if(std::string(type)=="Int32")
3762         {
3763           const char *data(reinterpret_cast<const char *>(begin()));
3764           std::size_t sz(getNbOfElems()*sizeof(int));
3765           byteArr->insertAtTheEnd(data,data+sz);
3766           byteArr->insertAtTheEnd(SPACE,SPACE+4);
3767         }
3768       else if(std::string(type)=="Int8")
3769         {
3770           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
3771           std::copy(begin(),end(),(char *)tmp);
3772           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
3773           byteArr->insertAtTheEnd(SPACE,SPACE+4);
3774         }
3775       else if(std::string(type)=="UInt8")
3776         {
3777           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
3778           std::copy(begin(),end(),(unsigned char *)tmp);
3779           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
3780           byteArr->insertAtTheEnd(SPACE,SPACE+4);
3781         }
3782       else
3783         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
3784     }
3785   else
3786     {
3787       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
3788       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
3789     }
3790   ofs << std::endl << idt << "</DataArray>\n";
3791 }
3792
3793 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
3794 {
3795   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
3796   const int *data=getConstPointer();
3797   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
3798   if(nbTuples*nbComp>=1)
3799     {
3800       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
3801       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
3802       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
3803       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
3804     }
3805   else
3806     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
3807   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
3808 }
3809
3810 /*!
3811  * Method that gives a quick overvien of \a this for python.
3812  */
3813 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
3814 {
3815   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
3816   stream << "DataArrayInt C++ instance at " << this << ". ";
3817   if(isAllocated())
3818     {
3819       int nbOfCompo=(int)_info_on_compo.size();
3820       if(nbOfCompo>=1)
3821         {
3822           int nbOfTuples=getNumberOfTuples();
3823           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
3824           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
3825         }
3826       else
3827         stream << "Number of components : 0.";
3828     }
3829   else
3830     stream << "*** No data allocated ****";
3831 }
3832
3833 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
3834 {
3835   const int *data=begin();
3836   int nbOfTuples=getNumberOfTuples();
3837   int nbOfCompo=(int)_info_on_compo.size();
3838   std::ostringstream oss2; oss2 << "[";
3839   std::string oss2Str(oss2.str());
3840   bool isFinished=true;
3841   for(int i=0;i<nbOfTuples && isFinished;i++)
3842     {
3843       if(nbOfCompo>1)
3844         {
3845           oss2 << "(";
3846           for(int j=0;j<nbOfCompo;j++,data++)
3847             {
3848               oss2 << *data;
3849               if(j!=nbOfCompo-1) oss2 << ", ";
3850             }
3851           oss2 << ")";
3852         }
3853       else
3854         oss2 << *data++;
3855       if(i!=nbOfTuples-1) oss2 << ", ";
3856       std::string oss3Str(oss2.str());
3857       if(oss3Str.length()<maxNbOfByteInRepr)
3858         oss2Str=oss3Str;
3859       else
3860         isFinished=false;
3861     }
3862   stream << oss2Str;
3863   if(!isFinished)
3864     stream << "... ";
3865   stream << "]";
3866 }
3867
3868 /*!
3869  * Computes distribution of values of \a this one-dimensional array between given value
3870  * ranges (casts). This method is typically useful for entity number splitting by types,
3871  * for example. 
3872  *  \warning The values contained in \a arrBg should be sorted ascendently. No
3873  *           check of this is be done. If not, the result is not warranted. 
3874  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
3875  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
3876  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
3877  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
3878  *         should be more than every value in \a this array.
3879  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
3880  *              the last value of \a arrBg is \a arrEnd[ -1 ].
3881  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
3882  *         (same number of tuples and components), the caller is to delete 
3883  *         using decrRef() as it is no more needed.
3884  *         This array contains indices of ranges for every value of \a this array. I.e.
3885  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
3886  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
3887  *         this in which cast it holds.
3888  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
3889  *         array, the caller is to delete using decrRef() as it is no more needed.
3890  *         This array contains ranks of values of \a this array within ranges
3891  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
3892  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
3893  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
3894  *         for each tuple its rank inside its cast. The rank is computed as difference
3895  *         between the value and the lowest value of range.
3896  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
3897  *         ranges (casts) to which at least one value of \a this array belongs.
3898  *         Or, in other words, this param contains the casts that \a this contains.
3899  *         The caller is to delete this array using decrRef() as it is no more needed.
3900  *
3901  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
3902  *            the output of this method will be : 
3903  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
3904  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
3905  * - \a castsPresent  : [0,1]
3906  *
3907  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
3908  * range #1 and its rank within this range is 2; etc.
3909  *
3910  *  \throw If \a this->getNumberOfComponents() != 1.
3911  *  \throw If \a arrEnd - arrBg < 2.
3912  *  \throw If any value of \a this is not less than \a arrEnd[-1].
3913  */
3914 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
3915                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
3916 {
3917   checkAllocated();
3918   if(getNumberOfComponents()!=1)
3919     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3920   int nbOfTuples=getNumberOfTuples();
3921   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
3922   if(nbOfCast<2)
3923     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
3924   nbOfCast--;
3925   const int *work=getConstPointer();
3926   typedef std::reverse_iterator<const int *> rintstart;
3927   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
3928   rintstart end2(arrBg);
3929   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
3930   MCAuto<DataArrayInt> ret2=DataArrayInt::New();
3931   MCAuto<DataArrayInt> ret3=DataArrayInt::New();
3932   ret1->alloc(nbOfTuples,1);
3933   ret2->alloc(nbOfTuples,1);
3934   int *ret1Ptr=ret1->getPointer();
3935   int *ret2Ptr=ret2->getPointer();
3936   std::set<std::size_t> castsDetected;
3937   for(int i=0;i<nbOfTuples;i++)
3938     {
3939       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
3940       std::size_t pos=std::distance(bg,res);
3941       std::size_t pos2=nbOfCast-pos;
3942       if(pos2<nbOfCast)
3943         {
3944           ret1Ptr[i]=(int)pos2;
3945           ret2Ptr[i]=work[i]-arrBg[pos2];
3946           castsDetected.insert(pos2);
3947         }
3948       else
3949         {
3950           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
3951           throw INTERP_KERNEL::Exception(oss.str().c_str());
3952         }
3953     }
3954   ret3->alloc((int)castsDetected.size(),1);
3955   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
3956   castArr=ret1.retn();
3957   rankInsideCast=ret2.retn();
3958   castsPresent=ret3.retn();
3959 }
3960
3961 /*!
3962  * 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 ).
3963  * 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 ).
3964  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
3965  *
3966  * \param [out] strt - the start of the range (included) if true is returned.
3967  * \param [out] sttoopp - the end of the range (not included) if true is returned.
3968  * \param [out] stteepp - the step of the range if true is returned.
3969  * \return the verdict of the check.
3970  *
3971  * \sa DataArray::GetNumberOfItemGivenBES
3972  */
3973 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
3974 {
3975   checkAllocated();
3976   if(getNumberOfComponents()!=1)
3977     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
3978   int nbTuples(getNumberOfTuples());
3979   if(nbTuples==0)
3980     { strt=0; sttoopp=0; stteepp=1; return true; }
3981   const int *pt(begin());
3982   strt=*pt; 
3983   if(nbTuples==1)
3984     { sttoopp=strt+1; stteepp=1; return true; }
3985   strt=*pt; sttoopp=pt[nbTuples-1];
3986   if(strt==sttoopp)
3987     return false;
3988   if(sttoopp>strt)
3989     {
3990       sttoopp++;
3991       int a(sttoopp-1-strt),tmp(strt);
3992       if(a%(nbTuples-1)!=0)
3993         return false;
3994       stteepp=a/(nbTuples-1);
3995       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
3996         if(pt[i]!=tmp)
3997           return false;
3998       return true;
3999     }
4000   else
4001     {
4002       sttoopp--;
4003       int a(strt-sttoopp-1),tmp(strt);
4004       if(a%(nbTuples-1)!=0)
4005         return false;
4006       stteepp=-(a/(nbTuples-1));
4007       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
4008         if(pt[i]!=tmp)
4009           return false;
4010       return true;
4011     }
4012 }
4013
4014
4015 /*!
4016  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4017  * i.e. a current value is used as in index to get a new value from \a indArrBg.
4018  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
4019  *         to \a this array.
4020  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4021  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
4022  *  \throw If \a this->getNumberOfComponents() != 1
4023  *  \throw If any value of \a this can't be used as a valid index for 
4024  *         [\a indArrBg, \a indArrEnd).
4025  *
4026  *  \sa changeValue, findIdForEach
4027  */
4028 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4029 {
4030   this->checkAllocated();
4031   if(this->getNumberOfComponents()!=1)
4032     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4033   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4034   for(int i=0;i<nbOfTuples;i++,pt++)
4035     {
4036       if(*pt>=0 && *pt<nbElemsIn)
4037         *pt=indArrBg[*pt];
4038       else
4039         {
4040           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4041           throw INTERP_KERNEL::Exception(oss.str());
4042         }
4043     }
4044   this->declareAsNew();
4045 }
4046
4047 void DataArrayInt::transformWithIndArr(const MapKeyVal<int>& m)
4048 {
4049   this->checkAllocated();
4050   if(this->getNumberOfComponents()!=1)
4051     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4052   const std::map<int,int>& dat(m.data());
4053   int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4054   for(int i=0;i<nbOfTuples;i++,pt++)
4055     {
4056       std::map<int,int>::const_iterator it(dat.find(*pt));
4057       if(it!=dat.end())
4058         *pt=(*it).second;
4059       else
4060         {
4061           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !";
4062           throw INTERP_KERNEL::Exception(oss.str());
4063         }
4064     }
4065   this->declareAsNew();
4066 }
4067
4068 /*!
4069  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
4070  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
4071  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
4072  * new value in place \a indArr[ \a v ] is i.
4073  *  \param [in] indArrBg - the array holding indices within the result array to assign
4074  *         indices of values of \a this array pointing to values of \a indArrBg.
4075  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4076  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
4077  *  \return DataArrayInt * - the new instance of DataArrayInt.
4078  *          The caller is to delete this result array using decrRef() as it is no more
4079  *          needed.
4080  *  \throw If \a this->getNumberOfComponents() != 1.
4081  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
4082  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
4083  */
4084 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
4085 {
4086   checkAllocated();
4087   if(getNumberOfComponents()!=1)
4088     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4089   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
4090   int nbOfTuples=getNumberOfTuples();
4091   const int *pt=getConstPointer();
4092   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4093   ret->alloc(nbOfTuples,1);
4094   ret->fillWithValue(-1);
4095   int *tmp=ret->getPointer();
4096   for(int i=0;i<nbOfTuples;i++,pt++)
4097     {
4098       if(*pt>=0 && *pt<nbElemsIn)
4099         {
4100           int pos=indArrBg[*pt];
4101           if(pos>=0 && pos<nbOfTuples)
4102             tmp[pos]=i;
4103           else
4104             {
4105               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
4106               throw INTERP_KERNEL::Exception(oss.str().c_str());
4107             }
4108         }
4109       else
4110         {
4111           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
4112           throw INTERP_KERNEL::Exception(oss.str().c_str());
4113         }
4114     }
4115   return ret.retn();
4116 }
4117
4118 /*!
4119  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4120  * from values of \a this array, which is supposed to contain a renumbering map in 
4121  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
4122  * To know how to use the renumbering maps see \ref numbering.
4123  *  \param [in] newNbOfElem - the number of tuples in the result array.
4124  *  \return DataArrayInt * - the new instance of DataArrayInt.
4125  *          The caller is to delete this result array using decrRef() as it is no more
4126  *          needed.
4127  * 
4128  *  \if ENABLE_EXAMPLES
4129  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
4130  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
4131  *  \endif
4132  */
4133 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
4134 {
4135   MCAuto<DataArrayInt> ret(DataArrayInt::New());
4136   ret->alloc(newNbOfElem,1);
4137   int nbOfOldNodes(this->getNumberOfTuples());
4138   const int *old2New(begin());
4139   int *pt(ret->getPointer());
4140   for(int i=0;i!=nbOfOldNodes;i++)
4141     {
4142       int newp(old2New[i]);
4143       if(newp!=-1)
4144         {
4145           if(newp>=0 && newp<newNbOfElem)
4146             pt[newp]=i;
4147           else
4148             {
4149               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4150               throw INTERP_KERNEL::Exception(oss.str().c_str());
4151             }
4152         }
4153     }
4154   return ret.retn();
4155 }
4156
4157 /*!
4158  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
4159  * 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]
4160  */
4161 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
4162 {
4163   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4164   ret->alloc(newNbOfElem,1);
4165   int nbOfOldNodes=getNumberOfTuples();
4166   const int *old2New=getConstPointer();
4167   int *pt=ret->getPointer();
4168   for(int i=nbOfOldNodes-1;i>=0;i--)
4169     {
4170       int newp(old2New[i]);
4171       if(newp!=-1)
4172         {
4173           if(newp>=0 && newp<newNbOfElem)
4174             pt[newp]=i;
4175           else
4176             {
4177               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4178               throw INTERP_KERNEL::Exception(oss.str().c_str());
4179             }
4180         }
4181     }
4182   return ret.retn();
4183 }
4184
4185 /*!
4186  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4187  * from values of \a this array, which is supposed to contain a renumbering map in 
4188  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4189  * To know how to use the renumbering maps see \ref numbering.
4190  *  \param [in] newNbOfElem - the number of tuples in the result array.
4191  *  \return DataArrayInt * - the new instance of DataArrayInt.
4192  *          The caller is to delete this result array using decrRef() as it is no more
4193  *          needed.
4194  * 
4195  *  \if ENABLE_EXAMPLES
4196  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4197  *
4198  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4199  *  \sa invertArrayN2O2O2NOptimized
4200  *  \endif
4201  */
4202 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
4203 {
4204   checkAllocated();
4205   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4206   ret->alloc(oldNbOfElem,1);
4207   const int *new2Old=getConstPointer();
4208   int *pt=ret->getPointer();
4209   std::fill(pt,pt+oldNbOfElem,-1);
4210   int nbOfNewElems=getNumberOfTuples();
4211   for(int i=0;i<nbOfNewElems;i++)
4212     {
4213       int v(new2Old[i]);
4214       if(v>=0 && v<oldNbOfElem)
4215         pt[v]=i;
4216       else
4217         {
4218           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
4219           throw INTERP_KERNEL::Exception(oss.str().c_str());
4220         }
4221     }
4222   return ret.retn();
4223 }
4224
4225 /*!
4226  * Creates a map, whose contents are computed
4227  * from values of \a this array, which is supposed to contain a renumbering map in 
4228  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4229  * To know how to use the renumbering maps see \ref numbering.
4230  *  \param [in] newNbOfElem - the number of tuples in the result array.
4231  *  \return MapII  - the new instance of Map.
4232  * 
4233  *  \if ENABLE_EXAMPLES
4234  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4235  *
4236  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4237  *  \sa invertArrayN2O2O2N, giveN2OOptimized, MEDCouplingPointSet::renumberNodesInConn
4238  *  \endif
4239  */
4240 MCAuto< MapKeyVal<int> > DataArrayInt32::invertArrayN2O2O2NOptimized() const
4241 {
4242   checkAllocated();
4243   if(getNumberOfComponents()!=1)
4244     throw INTERP_KERNEL::Exception("DataArrayInt32::invertArrayN2O2O2NOptimized : single component expected !");
4245   MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4246   std::map<int,int>& m(ret->data());
4247   const int *new2Old(begin());
4248   std::size_t nbOfNewElems(this->getNumberOfTuples());
4249   for(std::size_t i=0;i<nbOfNewElems;i++)
4250     {
4251       int v(new2Old[i]);
4252       m[v]=i;
4253     }
4254   return ret;
4255 }
4256
4257 /*!
4258  * Creates a map, whose contents are computed
4259  * from values of \a this array, which is supposed to contain a renumbering map in 
4260  * "New to Old" mode. The result array contains a renumbering map in "New to Old" mode as C++ map for performance reasons.
4261  *
4262  * \sa invertArrayN2O2O2NOptimized, MEDCouplingPointSet::renumberNodesInConn
4263  */
4264 MCAuto< MapKeyVal<int> > DataArrayInt32::giveN2OOptimized() const
4265 {
4266   checkAllocated();
4267   if(getNumberOfComponents()!=1)
4268     throw INTERP_KERNEL::Exception("DataArrayInt32::giveN2OOptimized : single component expected !");
4269   MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4270   std::map<int,int>& m(ret->data());
4271   const int *new2Old(begin());
4272   std::size_t nbOfNewElems(this->getNumberOfTuples());
4273   for(std::size_t i=0;i<nbOfNewElems;i++)
4274     {
4275       int v(new2Old[i]);
4276       m[i]=v;
4277     }
4278   return ret;
4279 }
4280
4281 /*!
4282  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4283  * This map, if applied to \a this array, would make it sorted. For example, if
4284  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4285  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4286  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4287  * This method is useful for renumbering (in MED file for example). For more info
4288  * on renumbering see \ref numbering.
4289  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4290  *          array using decrRef() as it is no more needed.
4291  *  \throw If \a this is not allocated.
4292  *  \throw If \a this->getNumberOfComponents() != 1.
4293  *  \throw If there are equal values in \a this array.
4294  */
4295 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
4296 {
4297   checkAllocated();
4298   if(getNumberOfComponents()!=1)
4299     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4300   int nbTuples=getNumberOfTuples();
4301   const int *pt=getConstPointer();
4302   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
4303   DataArrayInt *ret=DataArrayInt::New();
4304   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
4305   return ret;
4306 }
4307
4308 /*!
4309  * 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
4310  * input array \a ids2.
4311  * \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.
4312  * 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
4313  * inversely.
4314  * In case of success both assertion will be true (no throw) :
4315  * \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
4316  * \c ret->transformWithIndArr(ids2)->isEqual(ids1)
4317  *
4318  * \b Example:
4319  * - \a ids1 : [3,1,103,4,6,10,-7,205]
4320  * - \a ids2 : [-7,1,205,10,6,3,103,4]
4321  * - \a return is : [5,1,6,7,4,3,0,2] because ids2[5]==ids1[0], ids2[1]==ids1[1], ids2[6]==ids1[2]...
4322  *
4323  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4324  *          array using decrRef() as it is no more needed.
4325  * \throw If either ids1 or ids2 is null not allocated or not with one components.
4326  * 
4327  * \sa DataArrayInt32::findIdForEach
4328  */
4329 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
4330 {
4331   if(!ids1 || !ids2)
4332     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
4333   if(!ids1->isAllocated() || !ids2->isAllocated())
4334     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
4335   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
4336     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
4337   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
4338     {
4339       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 !";
4340       throw INTERP_KERNEL::Exception(oss.str().c_str());
4341     }
4342   MCAuto<DataArrayInt> p1(ids1->deepCopy());
4343   MCAuto<DataArrayInt> p2(ids2->deepCopy());
4344   p1->sort(true); p2->sort(true);
4345   if(!p1->isEqualWithoutConsideringStr(*p2))
4346     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
4347   p1=ids1->checkAndPreparePermutation();
4348   p2=ids2->checkAndPreparePermutation();
4349   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
4350   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
4351   return p2.retn();
4352 }
4353
4354 /*!
4355  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4356  * onto a set of values of size \a targetNb (\a B). The surjective function is 
4357  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4358  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4359  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4360  * The first of out arrays returns indices of elements of \a this array, grouped by their
4361  * place in the set \a B. The second out array is the index of the first one; it shows how
4362  * many elements of \a A are mapped into each element of \a B. <br>
4363  * For more info on
4364  * mapping and its usage in renumbering see \ref numbering. <br>
4365  * \b Example:
4366  * - \a this: [0,3,2,3,2,2,1,2]
4367  * - \a targetNb: 4
4368  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
4369  * - \a arrI: [0,1,2,6,8]
4370  *
4371  * This result means: <br>
4372  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4373  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4374  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4375  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
4376  * \a arrI[ 2+1 ]]); <br> etc.
4377  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4378  *         than the maximal value of \a A.
4379  *  \param [out] arr - a new instance of DataArrayInt returning indices of
4380  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
4381  *         this array using decrRef() as it is no more needed.
4382  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4383  *         elements of \a this. The caller is to delete this array using decrRef() as it
4384  *         is no more needed.
4385  *  \throw If \a this is not allocated.
4386  *  \throw If \a this->getNumberOfComponents() != 1.
4387  *  \throw If any value in \a this is more or equal to \a targetNb.
4388  */
4389 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
4390 {
4391   checkAllocated();
4392   if(getNumberOfComponents()!=1)
4393     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4394   int nbOfTuples=getNumberOfTuples();
4395   MCAuto<DataArrayInt> ret(DataArrayInt::New());
4396   MCAuto<DataArrayInt> retI(DataArrayInt::New());
4397   retI->alloc(targetNb+1,1);
4398   const int *input=getConstPointer();
4399   std::vector< std::vector<int> > tmp(targetNb);
4400   for(int i=0;i<nbOfTuples;i++)
4401     {
4402       int tmp2=input[i];
4403       if(tmp2>=0 && tmp2<targetNb)
4404         tmp[tmp2].push_back(i);
4405       else
4406         {
4407           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4408           throw INTERP_KERNEL::Exception(oss.str().c_str());
4409         }
4410     }
4411   int *retIPtr=retI->getPointer();
4412   *retIPtr=0;
4413   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4414     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
4415   if(nbOfTuples!=retI->getIJ(targetNb,0))
4416     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4417   ret->alloc(nbOfTuples,1);
4418   int *retPtr=ret->getPointer();
4419   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4420     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4421   arr=ret.retn();
4422   arrI=retI.retn();
4423 }
4424
4425
4426 /*!
4427  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
4428  * from a zip representation of a surjective format (returned e.g. by
4429  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
4430  * for example). The result array minimizes the permutation. <br>
4431  * For more info on renumbering see \ref numbering. <br>
4432  * \b Example: <br>
4433  * - \a nbOfOldTuples: 10 
4434  * - \a arr          : [0,3, 5,7,9]
4435  * - \a arrIBg       : [0,2,5]
4436  * - \a newNbOfTuples: 7
4437  * - result array    : [0,1,2,0,3,4,5,4,6,4]
4438  *
4439  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
4440  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
4441  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
4442  *         (indices of) equal values. Its every element (except the last one) points to
4443  *         the first element of a group of equal values.
4444  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
4445  *          arrIBg is \a arrIEnd[ -1 ].
4446  *  \param [out] newNbOfTuples - number of tuples after surjection application.
4447  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4448  *          array using decrRef() as it is no more needed.
4449  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
4450  */
4451 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
4452 {
4453   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4454   ret->alloc(nbOfOldTuples,1);
4455   int *pt=ret->getPointer();
4456   std::fill(pt,pt+nbOfOldTuples,-1);
4457   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
4458   const int *cIPtr=arrIBg;
4459   for(int i=0;i<nbOfGrps;i++)
4460     pt[arr[cIPtr[i]]]=-(i+2);
4461   int newNb=0;
4462   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
4463     {
4464       if(pt[iNode]<0)
4465         {
4466           if(pt[iNode]==-1)
4467             pt[iNode]=newNb++;
4468           else
4469             {
4470               int grpId=-(pt[iNode]+2);
4471               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
4472                 {
4473                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
4474                     pt[arr[j]]=newNb;
4475                   else
4476                     {
4477                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
4478                       throw INTERP_KERNEL::Exception(oss.str().c_str());
4479                     }
4480                 }
4481               newNb++;
4482             }
4483         }
4484     }
4485   newNbOfTuples=newNb;
4486   return ret.retn();
4487 }
4488
4489 /*!
4490  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4491  * which if applied to \a this array would make it sorted ascendingly.
4492  * For more info on renumbering see \ref numbering. <br>
4493  * \b Example: <br>
4494  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4495  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4496  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
4497  *
4498  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4499  *          array using decrRef() as it is no more needed.
4500  *  \throw If \a this is not allocated.
4501  *  \throw If \a this->getNumberOfComponents() != 1.
4502  */
4503 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
4504 {
4505   checkAllocated();
4506   if(getNumberOfComponents()!=1)
4507     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4508   int nbOfTuples=getNumberOfTuples();
4509   const int *pt=getConstPointer();
4510   std::map<int,int> m;
4511   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4512   ret->alloc(nbOfTuples,1);
4513   int *opt=ret->getPointer();
4514   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4515     {
4516       int val=*pt;
4517       std::map<int,int>::iterator it=m.find(val);
4518       if(it!=m.end())
4519         {
4520           *opt=(*it).second;
4521           (*it).second++;
4522         }
4523       else
4524         {
4525           *opt=0;
4526           m.insert(std::pair<int,int>(val,1));
4527         }
4528     }
4529   int sum=0;
4530   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
4531     {
4532       int vt=(*it).second;
4533       (*it).second=sum;
4534       sum+=vt;
4535     }
4536   pt=getConstPointer();
4537   opt=ret->getPointer();
4538   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4539     *opt+=m[*pt];
4540   //
4541   return ret.retn();
4542 }
4543
4544 /*!
4545  * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4546  * iota(). This method is particularly useful for DataArrayInt instances that represent
4547  * a renumbering array, to check if there is a real need in renumbering.
4548  * This method checks than \a this can be considered as an identity mapping
4549  * of a set having \a sizeExpected elements into itself.
4550  *
4551  *  \param [in] sizeExpected - The number of elements expected.
4552  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4553  *  \throw If \a this is not allocated.
4554  *  \throw If \a this->getNumberOfComponents() != 1.
4555  */
4556 bool DataArrayInt::isIota(int sizeExpected) const
4557 {
4558   checkAllocated();
4559   if(getNumberOfComponents()!=1)
4560     return false;
4561   int nbOfTuples(getNumberOfTuples());
4562   if(nbOfTuples!=sizeExpected)
4563     return false;
4564   const int *pt=getConstPointer();
4565   for(int i=0;i<nbOfTuples;i++,pt++)
4566     if(*pt!=i)
4567       return false;
4568   return true;
4569 }
4570
4571 /*!
4572  * Checks if all values in \a this array are equal to \a val.
4573  *  \param [in] val - value to check equality of array values to.
4574  *  \return bool - \a true if all values are \a val.
4575  *  \throw If \a this is not allocated.
4576  *  \throw If \a this->getNumberOfComponents() != 1
4577  *  \sa DataArrayInt::checkUniformAndGuess
4578  */
4579 bool DataArrayInt::isUniform(int val) const
4580 {
4581   checkAllocated();
4582   if(getNumberOfComponents()!=1)
4583     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4584   const int *w(begin()),*end2(end());
4585   for(;w!=end2;w++)
4586     if(*w!=val)
4587       return false;
4588   return true;
4589 }
4590
4591 /*!
4592  * This method checks that \a this is uniform. If not and exception will be thrown.
4593  * In case of uniformity the corresponding value is returned.
4594  *
4595  * \return int - the unique value contained in this
4596  * \throw If \a this is not allocated.
4597  * \throw If \a this->getNumberOfComponents() != 1
4598  * \throw If \a this is not uniform.
4599  * \sa DataArrayInt::isUniform
4600  */
4601 int DataArrayInt::checkUniformAndGuess() const
4602 {
4603   checkAllocated();
4604   if(getNumberOfComponents()!=1)
4605     throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4606   if(empty())
4607     throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
4608   const int *w(begin()),*end2(end());
4609   int ret(*w);
4610   for(;w!=end2;w++)
4611     if(*w!=ret)
4612       throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
4613   return ret;
4614 }
4615
4616 /*!
4617  * Checks if all values in \a this array are unique.
4618  *  \return bool - \a true if condition above is true
4619  *  \throw If \a this is not allocated.
4620  *  \throw If \a this->getNumberOfComponents() != 1
4621  */
4622 bool DataArrayInt::hasUniqueValues() const
4623 {
4624   checkAllocated();
4625   if(getNumberOfComponents()!=1)
4626     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4627   std::size_t nbOfTuples(getNumberOfTuples());
4628   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
4629   if (s.size() != nbOfTuples)
4630     return false;
4631   return true;
4632 }
4633
4634 /*!
4635  * Copy all components in a specified order from another DataArrayInt.
4636  * The specified components become the first ones in \a this array.
4637  * Both numerical and textual data is copied. The number of tuples in \a this and
4638  * the other array can be different.
4639  *  \param [in] a - the array to copy data from.
4640  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
4641  *              to be copied.
4642  *  \throw If \a a is NULL.
4643  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
4644  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
4645  *
4646  *  \if ENABLE_EXAMPLES
4647  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
4648  *  \endif
4649  */
4650 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
4651 {
4652   if(!a)
4653     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
4654   checkAllocated();
4655   a->checkAllocated();
4656   copyPartOfStringInfoFrom2(compoIds,*a);
4657   std::size_t partOfCompoSz=compoIds.size();
4658   int nbOfCompo=getNumberOfComponents();
4659   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
4660   const int *ac=a->getConstPointer();
4661   int *nc=getPointer();
4662   for(int i=0;i<nbOfTuples;i++)
4663     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
4664       nc[nbOfCompo*i+compoIds[j]]=*ac;
4665 }
4666
4667 DataArrayIntIterator *DataArrayInt::iterator()
4668 {
4669   return new DataArrayIntIterator(this);
4670 }
4671
4672 /*!
4673  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
4674  * given one. The ids are sorted in the ascending order.
4675  *  \param [in] val - the value to find within \a this.
4676  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4677  *          array using decrRef() as it is no more needed.
4678  *  \throw If \a this is not allocated.
4679  *  \throw If \a this->getNumberOfComponents() != 1.
4680  *  \sa DataArrayInt::findIdsEqualTuple
4681  */
4682 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
4683 {
4684   checkAllocated();
4685   if(getNumberOfComponents()!=1)
4686     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
4687   const int *cptr(getConstPointer());
4688   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4689   int nbOfTuples=getNumberOfTuples();
4690   for(int i=0;i<nbOfTuples;i++,cptr++)
4691     if(*cptr==val)
4692       ret->pushBackSilent(i);
4693   return ret.retn();
4694 }
4695
4696 /*!
4697  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
4698  * equal to a given one. 
4699  *  \param [in] val - the value to ignore within \a this.
4700  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4701  *          array using decrRef() as it is no more needed.
4702  *  \throw If \a this is not allocated.
4703  *  \throw If \a this->getNumberOfComponents() != 1.
4704  */
4705 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
4706 {
4707   checkAllocated();
4708   if(getNumberOfComponents()!=1)
4709     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
4710   const int *cptr(getConstPointer());
4711   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4712   int nbOfTuples=getNumberOfTuples();
4713   for(int i=0;i<nbOfTuples;i++,cptr++)
4714     if(*cptr!=val)
4715       ret->pushBackSilent(i);
4716   return ret.retn();
4717 }
4718
4719 /*!
4720  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
4721  * This method is an extension of  DataArrayInt::findIdsEqual method.
4722  *
4723  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
4724  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
4725  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4726  *          array using decrRef() as it is no more needed.
4727  *  \throw If \a this is not allocated.
4728  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
4729  * \throw If \a this->getNumberOfComponents() is equal to 0.
4730  * \sa DataArrayInt::findIdsEqual
4731  */
4732 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
4733 {
4734   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
4735   checkAllocated();
4736   if(getNumberOfComponents()!=nbOfCompoExp)
4737     {
4738       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
4739       throw INTERP_KERNEL::Exception(oss.str().c_str());
4740     }
4741   if(nbOfCompoExp==0)
4742     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
4743   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4744   const int *bg(begin()),*end2(end()),*work(begin());
4745   while(work!=end2)
4746     {
4747       work=std::search(work,end2,tupleBg,tupleEnd);
4748       if(work!=end2)
4749         {
4750           std::size_t pos(std::distance(bg,work));
4751           if(pos%nbOfCompoExp==0)
4752             ret->pushBackSilent(pos/nbOfCompoExp);
4753           work++;
4754         }
4755     }
4756   return ret.retn();
4757 }
4758
4759 /*!
4760  * This method finds for each element \a ELT in [valsBg,valsEnd) elements in \a this equal to it. Associated to ELT
4761  * this method will return the tuple id of last element found. If there is no element in \a this equal to ELT
4762  * an exception will be thrown.
4763  *
4764  * In case of success this[ret]==vals. Samely ret->transformWithIndArr(this->begin(),this->end())==vals.
4765  * Where \a vals is the [valsBg,valsEnd) array and \a ret the array returned by this method.
4766  * This method can be seen as an extension of FindPermutationFromFirstToSecond.
4767  * <br>
4768  * \b Example: <br>
4769  * - \a this: [17,27,2,10,-4,3,12,27,16]
4770  * - \a val : [3,16,-4,27,17]
4771  * - result: [5,8,4,7,0]
4772  *
4773  * \return - An array of size std::distance(valsBg,valsEnd)
4774  *
4775  * \sa DataArrayInt32::FindPermutationFromFirstToSecond
4776  */
4777 MCAuto<DataArrayInt32> DataArrayInt32::findIdForEach(const int *valsBg, const int *valsEnd) const
4778 {
4779   MCAuto<DataArrayInt32> ret(DataArrayInt32::New());
4780   std::size_t nbOfTuplesOut(std::distance(valsBg,valsEnd));
4781   ret->alloc(nbOfTuplesOut,1);
4782   MCAuto< MapKeyVal<int> > zeMap(invertArrayN2O2O2NOptimized());
4783   const std::map<int,int>& dat(zeMap->data());
4784   int *ptToFeed(ret->getPointer());
4785   for(const int *pt=valsBg;pt!=valsEnd;pt++)
4786     {
4787       std::map<int,int>::const_iterator it(dat.find(*pt));
4788       if(it!=dat.end())
4789         *ptToFeed++=(*it).second;
4790       else
4791         {
4792           std::ostringstream oss; oss << "DataArrayInt32::findIdForEach : error for element at place " << std::distance(valsBg,pt);
4793           oss << " of input array value is " << *pt << " which is not in this !";
4794           throw INTERP_KERNEL::Exception(oss.str());
4795         }
4796     }
4797   return ret;
4798 }
4799
4800 /*!
4801  * Assigns \a newValue to all elements holding \a oldValue within \a this
4802  * one-dimensional array.
4803  *  \param [in] oldValue - the value to replace.
4804  *  \param [in] newValue - the value to assign.
4805  *  \return int - number of replacements performed.
4806  *  \throw If \a this is not allocated.
4807  *  \throw If \a this->getNumberOfComponents() != 1.
4808  */
4809 int DataArrayInt::changeValue(int oldValue, int newValue)
4810 {
4811   checkAllocated();
4812   if(getNumberOfComponents()!=1)
4813     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
4814   if(oldValue==newValue)
4815     return 0;
4816   int *start(getPointer()),*end2(start+getNbOfElems());
4817   int ret(0);
4818   for(int *val=start;val!=end2;val++)
4819     {
4820       if(*val==oldValue)
4821         {
4822           *val=newValue;
4823           ret++;
4824         }
4825     }
4826   if(ret>0)
4827     declareAsNew();
4828   return ret;
4829 }
4830
4831 /*!
4832  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
4833  * one of given values.
4834  *  \param [in] valsBg - an array of values to find within \a this array.
4835  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4836  *              the last value of \a valsBg is \a valsEnd[ -1 ].
4837  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4838  *          array using decrRef() as it is no more needed.
4839  *  \throw If \a this->getNumberOfComponents() != 1.
4840  */
4841 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
4842 {
4843   if(getNumberOfComponents()!=1)
4844     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
4845   std::set<int> vals2(valsBg,valsEnd);
4846   const int *cptr(getConstPointer());
4847   std::vector<int> res;
4848   int nbOfTuples(getNumberOfTuples());
4849   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4850   for(int i=0;i<nbOfTuples;i++,cptr++)
4851     if(vals2.find(*cptr)!=vals2.end())
4852       ret->pushBackSilent(i);
4853   return ret.retn();
4854 }
4855
4856 /*!
4857  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
4858  * equal to any of given values.
4859  *  \param [in] valsBg - an array of values to ignore within \a this array.
4860  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4861  *              the last value of \a valsBg is \a valsEnd[ -1 ].
4862  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4863  *          array using decrRef() as it is no more needed.
4864  *  \throw If \a this->getNumberOfComponents() != 1.
4865  */
4866 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
4867 {
4868   if(getNumberOfComponents()!=1)
4869     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
4870   std::set<int> vals2(valsBg,valsEnd);
4871   const int *cptr=getConstPointer();
4872   std::vector<int> res;
4873   int nbOfTuples=getNumberOfTuples();
4874   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4875   for(int i=0;i<nbOfTuples;i++,cptr++)
4876     if(vals2.find(*cptr)==vals2.end())
4877       ret->pushBackSilent(i);
4878   return ret.retn();
4879 }
4880
4881 /*!
4882  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
4883  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4884  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4885  * If any the tuple id is returned. If not -1 is returned.
4886  * 
4887  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4888  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4889  *
4890  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
4891  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
4892  */
4893 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
4894 {
4895   checkAllocated();
4896   int nbOfCompo=getNumberOfComponents();
4897   if(nbOfCompo==0)
4898     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
4899   if(nbOfCompo!=(int)tupl.size())
4900     {
4901       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
4902       throw INTERP_KERNEL::Exception(oss.str().c_str());
4903     }
4904   const int *cptr=getConstPointer();
4905   std::size_t nbOfVals=getNbOfElems();
4906   for(const int *work=cptr;work!=cptr+nbOfVals;)
4907     {
4908       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
4909       if(work!=cptr+nbOfVals)
4910         {
4911           if(std::distance(cptr,work)%nbOfCompo!=0)
4912             work++;
4913           else
4914             return std::distance(cptr,work)/nbOfCompo;
4915         }
4916     }
4917   return -1;
4918 }
4919
4920 /*!
4921  * This method searches the sequence specified in input parameter \b vals in \b this.
4922  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
4923  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
4924  * \sa DataArrayInt::findIdFirstEqualTuple
4925  */
4926 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
4927 {
4928   checkAllocated();
4929   int nbOfCompo=getNumberOfComponents();
4930   if(nbOfCompo!=1)
4931     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
4932   const int *cptr=getConstPointer();
4933   std::size_t nbOfVals=getNbOfElems();
4934   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
4935   if(loc!=cptr+nbOfVals)
4936     return std::distance(cptr,loc);
4937   return -1;
4938 }
4939
4940 /*!
4941  * This method expects to be called when number of components of this is equal to one.
4942  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
4943  * If not any tuple contains \b value -1 is returned.
4944  * \sa DataArrayInt::presenceOfValue
4945  */
4946 int DataArrayInt::findIdFirstEqual(int value) const
4947 {
4948   checkAllocated();
4949   if(getNumberOfComponents()!=1)
4950     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4951   const int *cptr=getConstPointer();
4952   int nbOfTuples=getNumberOfTuples();
4953   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
4954   if(ret!=cptr+nbOfTuples)
4955     return std::distance(cptr,ret);
4956   return -1;
4957 }
4958
4959 /*!
4960  * This method expects to be called when number of components of this is equal to one.
4961  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
4962  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
4963  * \sa DataArrayInt::presenceOfValue
4964  */
4965 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
4966 {
4967   checkAllocated();
4968   if(getNumberOfComponents()!=1)
4969     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4970   std::set<int> vals2(vals.begin(),vals.end());
4971   const int *cptr=getConstPointer();
4972   int nbOfTuples=getNumberOfTuples();
4973   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
4974     if(vals2.find(*w)!=vals2.end())
4975       return std::distance(cptr,w);
4976   return -1;
4977 }
4978
4979 /*!
4980  * This method returns the number of values in \a this that are equals to input parameter \a value.
4981  * This method only works for single component array.
4982  *
4983  * \return a value in [ 0, \c this->getNumberOfTuples() )
4984  *
4985  * \throw If \a this is not allocated
4986  *
4987  */
4988 int DataArrayInt::count(int value) const
4989 {
4990   int ret=0;
4991   checkAllocated();
4992   if(getNumberOfComponents()!=1)
4993     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4994   const int *vals=begin();
4995   int nbOfTuples=getNumberOfTuples();
4996   for(int i=0;i<nbOfTuples;i++,vals++)
4997     if(*vals==value)
4998       ret++;
4999   return ret;
5000 }
5001
5002 /*!
5003  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
5004  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5005  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5006  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5007  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5008  * \sa DataArrayInt::findIdFirstEqualTuple
5009  */
5010 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
5011 {
5012   return findIdFirstEqualTuple(tupl)!=-1;
5013 }
5014
5015
5016 /*!
5017  * Returns \a true if a given value is present within \a this one-dimensional array.
5018  *  \param [in] value - the value to find within \a this array.
5019  *  \return bool - \a true in case if \a value is present within \a this array.
5020  *  \throw If \a this is not allocated.
5021  *  \throw If \a this->getNumberOfComponents() != 1.
5022  *  \sa findIdFirstEqual()
5023  */
5024 bool DataArrayInt::presenceOfValue(int value) const
5025 {
5026   return findIdFirstEqual(value)!=-1;
5027 }
5028
5029 /*!
5030  * This method expects to be called when number of components of this is equal to one.
5031  * This method returns true if it exists a tuple so that the value is contained in \b vals.
5032  * If not any tuple contains one of the values contained in 'vals' false is returned.
5033  * \sa DataArrayInt::findIdFirstEqual
5034  */
5035 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
5036 {
5037   return findIdFirstEqual(vals)!=-1;
5038 }
5039
5040 /*!
5041  * Accumulates values of each component of \a this array.
5042  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
5043  *         by the caller, that is filled by this method with sum value for each
5044  *         component.
5045  *  \throw If \a this is not allocated.
5046  */
5047 void DataArrayInt::accumulate(int *res) const
5048 {
5049   checkAllocated();
5050   const int *ptr=getConstPointer();
5051   int nbTuple=getNumberOfTuples();
5052   int nbComps=getNumberOfComponents();
5053   std::fill(res,res+nbComps,0);
5054   for(int i=0;i<nbTuple;i++)
5055     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
5056 }
5057
5058 int DataArrayInt::accumulate(int compId) const
5059 {
5060   checkAllocated();
5061   const int *ptr=getConstPointer();
5062   int nbTuple=getNumberOfTuples();
5063   int nbComps=getNumberOfComponents();
5064   if(compId<0 || compId>=nbComps)
5065     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
5066   int ret=0;
5067   for(int i=0;i<nbTuple;i++)
5068     ret+=ptr[i*nbComps+compId];
5069   return ret;
5070 }
5071
5072 /*!
5073  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
5074  * The returned array will have same number of components than \a this and number of tuples equal to
5075  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
5076  *
5077  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
5078  *
5079  * \param [in] bgOfIndex - begin (included) of the input index array.
5080  * \param [in] endOfIndex - end (excluded) of the input index array.
5081  * \return DataArrayInt * - the new instance having the same number of components than \a this.
5082  * 
5083  * \throw If bgOfIndex or end is NULL.
5084  * \throw If input index array is not ascendingly sorted.
5085  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
5086  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
5087  */
5088 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
5089 {
5090   if(!bgOfIndex || !endOfIndex)
5091     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
5092   checkAllocated();
5093   int nbCompo=getNumberOfComponents();
5094   int nbOfTuples=getNumberOfTuples();
5095   int sz=(int)std::distance(bgOfIndex,endOfIndex);
5096   if(sz<1)
5097     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
5098   sz--;
5099   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
5100   const int *w=bgOfIndex;
5101   if(*w<0 || *w>=nbOfTuples)
5102     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
5103   const int *srcPt=begin()+(*w)*nbCompo;
5104   int *tmp=ret->getPointer();
5105   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
5106     {
5107       std::fill(tmp,tmp+nbCompo,0);
5108       if(w[1]>=w[0])
5109         {
5110           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
5111             {
5112               if(j>=0 && j<nbOfTuples)
5113                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
5114               else
5115                 {
5116                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
5117                   throw INTERP_KERNEL::Exception(oss.str().c_str());
5118                 }
5119             }
5120         }
5121       else
5122         {
5123           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
5124           throw INTERP_KERNEL::Exception(oss.str().c_str());
5125         }
5126     }
5127   ret->copyStringInfoFrom(*this);
5128   return ret.retn();
5129 }
5130
5131 /*!
5132  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
5133  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
5134  * offsetA2</em> and (2)
5135  * the number of component in the result array is same as that of each of given arrays.
5136  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
5137  * Info on components is copied from the first of the given arrays. Number of components
5138  * in the given arrays must be the same.
5139  *  \param [in] a1 - an array to include in the result array.
5140  *  \param [in] a2 - another array to include in the result array.
5141  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
5142  *  \return DataArrayInt * - the new instance of DataArrayInt.
5143  *          The caller is to delete this result array using decrRef() as it is no more
5144  *          needed.
5145  *  \throw If either \a a1 or \a a2 is NULL.
5146  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
5147  */
5148 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
5149 {
5150   if(!a1 || !a2)
5151     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
5152   std::size_t nbOfComp(a1->getNumberOfComponents());
5153   if(nbOfComp!=a2->getNumberOfComponents())
5154     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
5155   std::size_t nbOfTuple1(a1->getNumberOfTuples()),nbOfTuple2(a2->getNumberOfTuples());
5156   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5157   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
5158   int *pt=std::copy(a1->begin(),a1->end(),ret->getPointer());
5159   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
5160   ret->copyStringInfoFrom(*a1);
5161   return ret.retn();
5162 }
5163
5164 /*!
5165  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
5166  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
5167  * the number of component in the result array is same as that of each of given arrays.
5168  * Info on components is copied from the first of the given arrays. Number of components
5169  * in the given arrays must be  the same.
5170  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
5171  * not the object itself.
5172  *  \param [in] arr - a sequence of arrays to include in the result array.
5173  *  \return DataArrayInt * - the new instance of DataArrayInt.
5174  *          The caller is to delete this result array using decrRef() as it is no more
5175  *          needed.
5176  *  \throw If all arrays within \a arr are NULL.
5177  *  \throw If getNumberOfComponents() of arrays within \a arr.
5178  */
5179 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
5180 {
5181   std::vector<const DataArrayInt *> a;
5182   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5183     if(*it4)
5184       a.push_back(*it4);
5185   if(a.empty())
5186     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
5187   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
5188   std::size_t nbOfComp((*it)->getNumberOfComponents()),nbt((*it++)->getNumberOfTuples());
5189   for(int i=1;it!=a.end();it++,i++)
5190     {
5191       if((*it)->getNumberOfComponents()!=nbOfComp)
5192         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
5193       nbt+=(*it)->getNumberOfTuples();
5194     }
5195   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5196   ret->alloc(nbt,nbOfComp);
5197   int *pt=ret->getPointer();
5198   for(it=a.begin();it!=a.end();it++)
5199     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
5200   ret->copyStringInfoFrom(*(a[0]));
5201   return ret.retn();
5202 }
5203
5204 /*!
5205  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
5206  * A packed index array is an allocated array with one component, and at least one tuple. The first element
5207  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
5208  * 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.
5209  * 
5210  * \return DataArrayInt * - a new object to be managed by the caller.
5211  */
5212 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
5213 {
5214   int retSz=1;
5215   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
5216     {
5217       if(*it4)
5218         {
5219           (*it4)->checkAllocated();
5220           if((*it4)->getNumberOfComponents()!=1)
5221             {
5222               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5223               throw INTERP_KERNEL::Exception(oss.str().c_str());
5224             }
5225           int nbTupl=(*it4)->getNumberOfTuples();
5226           if(nbTupl<1)
5227             {
5228               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5229               throw INTERP_KERNEL::Exception(oss.str().c_str());
5230             }
5231           if((*it4)->front()!=0)
5232             {
5233               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
5234               throw INTERP_KERNEL::Exception(oss.str().c_str());
5235             }
5236           retSz+=nbTupl-1;
5237         }
5238       else
5239         {
5240           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
5241           throw INTERP_KERNEL::Exception(oss.str().c_str());
5242         }
5243     }
5244   if(arrs.empty())
5245     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
5246   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5247   ret->alloc(retSz,1);
5248   int *pt=ret->getPointer(); *pt++=0;
5249   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
5250     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
5251   ret->copyStringInfoFrom(*(arrs[0]));
5252   return ret.retn();
5253 }
5254
5255 /*!
5256  * Returns in a single walk in \a this the min value and the max value in \a this.
5257  * \a this is expected to be single component array.
5258  *
5259  * \param [out] minValue - the min value in \a this.
5260  * \param [out] maxValue - the max value in \a this.
5261  *
5262  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5263  */
5264 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
5265 {
5266   checkAllocated();
5267   if(getNumberOfComponents()!=1)
5268     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5269   int nbTuples(getNumberOfTuples());
5270   const int *pt(begin());
5271   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
5272   for(int i=0;i<nbTuples;i++,pt++)
5273     {
5274       if(*pt<minValue)
5275         minValue=*pt;
5276       if(*pt>maxValue)
5277         maxValue=*pt;
5278     }
5279 }
5280
5281 /*!
5282  * Modify all elements of \a this array, so that
5283  * an element _x_ becomes \f$ numerator / x \f$.
5284  *  \warning If an exception is thrown because of presence of 0 element in \a this 
5285  *           array, all elements processed before detection of the zero element remain
5286  *           modified.
5287  *  \param [in] numerator - the numerator used to modify array elements.
5288  *  \throw If \a this is not allocated.
5289  *  \throw If there is an element equal to 0 in \a this array.
5290  */
5291 void DataArrayInt::applyInv(int numerator)
5292 {
5293   checkAllocated();
5294   int *ptr=getPointer();
5295   std::size_t nbOfElems=getNbOfElems();
5296   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5297     {
5298       if(*ptr!=0)
5299         {
5300           *ptr=numerator/(*ptr);
5301         }
5302       else
5303         {
5304           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5305           oss << " !";
5306           throw INTERP_KERNEL::Exception(oss.str().c_str());
5307         }
5308     }
5309   declareAsNew();
5310 }
5311
5312 /*!
5313  * Modify all elements of \a this array, so that
5314  * an element _x_ becomes \f$ x / val \f$.
5315  *  \param [in] val - the denominator used to modify array elements.
5316  *  \throw If \a this is not allocated.
5317  *  \throw If \a val == 0.
5318  */
5319 void DataArrayInt::applyDivideBy(int val)
5320 {
5321   if(val==0)
5322     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5323   checkAllocated();
5324   int *ptr=getPointer();
5325   std::size_t nbOfElems=getNbOfElems();
5326   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
5327   declareAsNew();
5328 }
5329
5330 /*!
5331  * Modify all elements of \a this array, so that
5332  * an element _x_ becomes  <em> x % val </em>.
5333  *  \param [in] val - the divisor used to modify array elements.
5334  *  \throw If \a this is not allocated.
5335  *  \throw If \a val <= 0.
5336  */
5337 void DataArrayInt::applyModulus(int val)
5338 {
5339   if(val<=0)
5340     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5341   checkAllocated();
5342   int *ptr=getPointer();
5343   std::size_t nbOfElems=getNbOfElems();
5344   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
5345   declareAsNew();
5346 }
5347
5348 /*!
5349  * This method works only on data array with one component.
5350  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5351  * this[*id] in [\b vmin,\b vmax)
5352  * 
5353  * \param [in] vmin begin of range. This value is included in range (included).
5354  * \param [in] vmax end of range. This value is \b not included in range (excluded).
5355  * \return a newly allocated data array that the caller should deal with.
5356  *
5357  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5358  */
5359 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
5360 {
5361   InRange<int> ir(vmin,vmax);
5362   MCAuto<DataArrayInt> ret(findIdsAdv(ir));
5363   return ret.retn();
5364 }
5365
5366 /*!
5367  * This method works only on data array with one component.
5368  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5369  * this[*id] \b not in [\b vmin,\b vmax)
5370  * 
5371  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5372  * \param [in] vmax end of range. This value is included in range (included).
5373  * \return a newly allocated data array that the caller should deal with.
5374  * 
5375  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5376  */
5377 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
5378 {
5379   NotInRange<int> nir(vmin,vmax);
5380   MCAuto<DataArrayInt> ret(findIdsAdv(nir));
5381   return ret.retn();
5382 }
5383
5384 /*!
5385  * This method works only on data array with one component.
5386  * 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.
5387  * 
5388  * \param [in] vmin begin of range. This value is included in range (included).
5389  * \param [in] vmax end of range. This value is \b not included in range (excluded).
5390  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5391 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
5392 {
5393   checkAllocated();
5394   if(getNumberOfComponents()!=1)
5395     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5396   int nbOfTuples=getNumberOfTuples();
5397   bool ret=true;
5398   const int *cptr=getConstPointer();
5399   for(int i=0;i<nbOfTuples;i++,cptr++)
5400     {
5401       if(*cptr>=vmin && *cptr<vmax)
5402         { ret=ret && *cptr==i; }
5403       else
5404         {
5405           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5406           throw INTERP_KERNEL::Exception(oss.str().c_str());
5407         }
5408     }
5409   return ret;
5410 }
5411
5412 /*!
5413  * Modify all elements of \a this array, so that
5414  * an element _x_ becomes <em> val % x </em>.
5415  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
5416  *           array, all elements processed before detection of the zero element remain
5417  *           modified.
5418  *  \param [in] val - the divident used to modify array elements.
5419  *  \throw If \a this is not allocated.
5420  *  \throw If there is an element equal to or less than 0 in \a this array.
5421  */
5422 void DataArrayInt::applyRModulus(int val)
5423 {
5424   checkAllocated();
5425   int *ptr=getPointer();
5426   std::size_t nbOfElems=getNbOfElems();
5427   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5428     {
5429       if(*ptr>0)
5430         {
5431           *ptr=val%(*ptr);
5432         }
5433       else
5434         {
5435           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5436           oss << " !";
5437           throw INTERP_KERNEL::Exception(oss.str().c_str());
5438         }
5439     }
5440   declareAsNew();
5441 }
5442
5443 /*!
5444  * Modify all elements of \a this array, so that
5445  * an element _x_ becomes <em> val ^ x </em>.
5446  *  \param [in] val - the value used to apply pow on all array elements.
5447  *  \throw If \a this is not allocated.
5448  *  \throw If \a val < 0.
5449  */
5450 void DataArrayInt::applyPow(int val)
5451 {
5452   checkAllocated();
5453   if(val<0)
5454     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5455   int *ptr=getPointer();
5456   std::size_t nbOfElems=getNbOfElems();
5457   if(val==0)
5458     {
5459       std::fill(ptr,ptr+nbOfElems,1);
5460       return ;
5461     }
5462   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5463     {
5464       int tmp=1;
5465       for(int j=0;j<val;j++)
5466         tmp*=*ptr;
5467       *ptr=tmp;
5468     }
5469   declareAsNew();
5470 }
5471
5472 /*!
5473  * Modify all elements of \a this array, so that
5474  * an element _x_ becomes \f$ val ^ x \f$.
5475  *  \param [in] val - the value used to apply pow on all array elements.
5476  *  \throw If \a this is not allocated.
5477  *  \throw If there is an element < 0 in \a this array.
5478  *  \warning If an exception is thrown because of presence of 0 element in \a this 
5479  *           array, all elements processed before detection of the zero element remain
5480  *           modified.
5481  */
5482 void DataArrayInt::applyRPow(int val)
5483 {
5484   checkAllocated();
5485   int *ptr=getPointer();
5486   std::size_t nbOfElems=getNbOfElems();
5487   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5488     {
5489       if(*ptr>=0)
5490         {
5491           int tmp=1;
5492           for(int j=0;j<*ptr;j++)
5493             tmp*=val;
5494           *ptr=tmp;
5495         }
5496       else
5497         {
5498           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5499           oss << " !";
5500           throw INTERP_KERNEL::Exception(oss.str().c_str());
5501         }
5502     }
5503   declareAsNew();
5504 }
5505
5506 /*!
5507  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
5508  * The i-th item of the result array is an ID of a set of elements belonging to a
5509  * unique set of groups, which the i-th element is a part of. This set of elements
5510  * belonging to a unique set of groups is called \a family, so the result array contains
5511  * IDs of families each element belongs to.
5512  *
5513  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
5514  * then there are 3 families:
5515  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
5516  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
5517  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
5518  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
5519  * stands for the element #3 which is in none of groups.
5520  *
5521  *  \param [in] groups - sequence of groups of element IDs.
5522  *  \param [in] newNb - total number of elements; it must be more than max ID of element
5523  *         in \a groups.
5524  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
5525  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
5526  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
5527  *         delete this array using decrRef() as it is no more needed.
5528  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
5529  */
5530 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
5531 {
5532   std::vector<const DataArrayInt *> groups2;
5533   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
5534     if(*it4)
5535       groups2.push_back(*it4);
5536   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5537   ret->alloc(newNb,1);
5538   int *retPtr=ret->getPointer();
5539   std::fill(retPtr,retPtr+newNb,0);
5540   int fid=1;
5541   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
5542     {
5543       const int *ptr=(*iter)->getConstPointer();
5544       std::size_t nbOfElem=(*iter)->getNbOfElems();
5545       int sfid=fid;
5546       for(int j=0;j<sfid;j++)
5547         {
5548           bool found=false;
5549           for(std::size_t i=0;i<nbOfElem;i++)
5550             {
5551               if(ptr[i]>=0 && ptr[i]<newNb)
5552                 {
5553                   if(retPtr[ptr[i]]==j)
5554                     {
5555                       retPtr[ptr[i]]=fid;
5556                       found=true;
5557                     }
5558                 }
5559               else
5560                 {
5561                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
5562                   oss << ") !";
5563                   throw INTERP_KERNEL::Exception(oss.str().c_str());
5564                 }
5565             }
5566           if(found)
5567             fid++;
5568         }
5569     }
5570   fidsOfGroups.clear();
5571   fidsOfGroups.resize(groups2.size());
5572   int grId=0;
5573   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
5574     {
5575       std::set<int> tmp;
5576       const int *ptr=(*iter)->getConstPointer();
5577       std::size_t nbOfElem=(*iter)->getNbOfElems();
5578       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
5579         tmp.insert(retPtr[*p]);
5580       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
5581     }
5582   return ret.retn();
5583 }
5584
5585 /*!
5586  * Returns a new DataArrayInt which contains all elements of given one-dimensional
5587  * arrays. The result array does not contain any duplicates and its values
5588  * are sorted in ascending order.
5589  *  \param [in] arr - sequence of DataArrayInt's to unite.
5590  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5591  *         array using decrRef() as it is no more needed.
5592  *  \throw If any \a arr[i] is not allocated.
5593  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
5594  */
5595 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
5596 {
5597   std::vector<const DataArrayInt *> a;
5598   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5599     if(*it4)
5600       a.push_back(*it4);
5601   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5602     {
5603       (*it)->checkAllocated();
5604       if((*it)->getNumberOfComponents()!=1)
5605         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
5606     }
5607   //
5608   std::set<int> r;
5609   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5610     {
5611       const int *pt=(*it)->getConstPointer();
5612       int nbOfTuples=(*it)->getNumberOfTuples();
5613       r.insert(pt,pt+nbOfTuples);
5614     }
5615   DataArrayInt *ret=DataArrayInt::New();
5616   ret->alloc((int)r.size(),1);
5617   std::copy(r.begin(),r.end(),ret->getPointer());
5618   return ret;
5619 }
5620
5621 /*!
5622  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
5623  * arrays. The result array does not contain any duplicates and its values
5624  * are sorted in ascending order.
5625  *  \param [in] arr - sequence of DataArrayInt's to intersect.
5626  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5627  *         array using decrRef() as it is no more needed.
5628  *  \throw If any \a arr[i] is not allocated.
5629  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
5630  */
5631 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
5632 {
5633   std::vector<const DataArrayInt *> a;
5634   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5635     if(*it4)
5636       a.push_back(*it4);
5637   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5638     {
5639       (*it)->checkAllocated();
5640       if((*it)->getNumberOfComponents()!=1)
5641         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
5642     }
5643   //
5644   std::set<int> r;
5645   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5646     {
5647       const int *pt=(*it)->getConstPointer();
5648       int nbOfTuples=(*it)->getNumberOfTuples();
5649       std::set<int> s1(pt,pt+nbOfTuples);
5650       if(it!=a.begin())
5651         {
5652           std::set<int> r2;
5653           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
5654           r=r2;
5655         }
5656       else
5657         r=s1;
5658     }
5659   DataArrayInt *ret(DataArrayInt::New());
5660   ret->alloc((int)r.size(),1);
5661   std::copy(r.begin(),r.end(),ret->getPointer());
5662   return ret;
5663 }
5664
5665 /// @cond INTERNAL
5666 namespace MEDCouplingImpl
5667 {
5668   class OpSwitchedOn
5669   {
5670   public:
5671     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
5672     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
5673   private:
5674     int *_pt;
5675     int _cnt;
5676   };
5677
5678   class OpSwitchedOff
5679   {
5680   public:
5681     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
5682     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
5683   private:
5684     int *_pt;
5685     int _cnt;
5686   };
5687 }
5688 /// @endcond
5689
5690 /*!
5691  * This method returns the list of ids in ascending mode so that v[id]==true.
5692  */
5693 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
5694 {
5695   int sz((int)std::count(v.begin(),v.end(),true));
5696   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5697   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
5698   return ret.retn();
5699 }
5700
5701 /*!
5702  * This method returns the list of ids in ascending mode so that v[id]==false.
5703  */
5704 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
5705 {
5706   int sz((int)std::count(v.begin(),v.end(),false));
5707   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5708   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
5709   return ret.retn();
5710 }
5711
5712 /*!
5713  * This method allows to put a vector of vector of integer into a more compact data structure (skyline). 
5714  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
5715  *
5716  * \param [in] v the input data structure to be translate into skyline format.
5717  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
5718  * \param [out] dataIndex the second element of the skyline format.
5719  */
5720 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
5721 {
5722   int sz((int)v.size());
5723   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
5724   ret1->alloc(sz+1,1);
5725   int *pt(ret1->getPointer()); *pt=0;
5726   for(int i=0;i<sz;i++,pt++)
5727     pt[1]=pt[0]+(int)v[i].size();
5728   ret0->alloc(ret1->back(),1);
5729   pt=ret0->getPointer();
5730   for(int i=0;i<sz;i++)
5731     pt=std::copy(v[i].begin(),v[i].end(),pt);
5732   data=ret0.retn(); dataIndex=ret1.retn();
5733 }
5734
5735 /*!
5736  * Returns a new DataArrayInt which contains a complement of elements of \a this
5737  * one-dimensional array. I.e. the result array contains all elements from the range [0,
5738  * \a nbOfElement) not present in \a this array.
5739  *  \param [in] nbOfElement - maximal size of the result array.
5740  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5741  *         array using decrRef() as it is no more needed.
5742  *  \throw If \a this is not allocated.
5743  *  \throw If \a this->getNumberOfComponents() != 1.
5744  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
5745  *         nbOfElement ).
5746  */
5747 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
5748 {
5749   checkAllocated();
5750   if(getNumberOfComponents()!=1)
5751     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
5752   std::vector<bool> tmp(nbOfElement);
5753   const int *pt=getConstPointer();
5754   int nbOfTuples=getNumberOfTuples();
5755   for(const int *w=pt;w!=pt+nbOfTuples;w++)
5756     if(*w>=0 && *w<nbOfElement)
5757       tmp[*w]=true;
5758     else
5759       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
5760   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
5761   DataArrayInt *ret=DataArrayInt::New();
5762   ret->alloc(nbOfRetVal,1);
5763   int j=0;
5764   int *retPtr=ret->getPointer();
5765   for(int i=0;i<nbOfElement;i++)
5766     if(!tmp[i])
5767       retPtr[j++]=i;
5768   return ret;
5769 }
5770
5771 /*!
5772  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
5773  * from an \a other one-dimensional array.
5774  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
5775  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
5776  *         caller is to delete this array using decrRef() as it is no more needed.
5777  *  \throw If \a other is NULL.
5778  *  \throw If \a other is not allocated.
5779  *  \throw If \a other->getNumberOfComponents() != 1.
5780  *  \throw If \a this is not allocated.
5781  *  \throw If \a this->getNumberOfComponents() != 1.
5782  *  \sa DataArrayInt::buildSubstractionOptimized()
5783  */
5784 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
5785 {
5786   if(!other)
5787     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
5788   checkAllocated();
5789   other->checkAllocated();
5790   if(getNumberOfComponents()!=1)
5791     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
5792   if(other->getNumberOfComponents()!=1)
5793     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
5794   const int *pt=getConstPointer();
5795   int nbOfTuples=getNumberOfTuples();
5796   std::set<int> s1(pt,pt+nbOfTuples);
5797   pt=other->getConstPointer();
5798   nbOfTuples=other->getNumberOfTuples();
5799   std::set<int> s2(pt,pt+nbOfTuples);
5800   std::vector<int> r;
5801   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
5802   DataArrayInt *ret=DataArrayInt::New();
5803   ret->alloc((int)r.size(),1);
5804   std::copy(r.begin(),r.end(),ret->getPointer());
5805   return ret;
5806 }
5807
5808 /*!
5809  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
5810  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
5811  * 
5812  * \param [in] other an array with one component and expected to be sorted ascendingly.
5813  * \ret list of ids in \a this but not in \a other.
5814  * \sa DataArrayInt::buildSubstraction
5815  */
5816 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
5817 {
5818   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
5819   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
5820   checkAllocated(); other->checkAllocated();
5821   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5822   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5823   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
5824   const int *work1(pt1Bg),*work2(pt2Bg);
5825   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5826   for(;work1!=pt1End;work1++)
5827     {
5828       if(work2!=pt2End && *work1==*work2)
5829         work2++;
5830       else
5831         ret->pushBackSilent(*work1);
5832     }
5833   return ret.retn();
5834 }
5835
5836
5837 /*!
5838  * Returns a new DataArrayInt which contains all elements of \a this and a given
5839  * one-dimensional arrays. The result array does not contain any duplicates
5840  * and its values are sorted in ascending order.
5841  *  \param [in] other - an array to unite with \a this one.
5842  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5843  *         array using decrRef() as it is no more needed.
5844  *  \throw If \a this or \a other is not allocated.
5845  *  \throw If \a this->getNumberOfComponents() != 1.
5846  *  \throw If \a other->getNumberOfComponents() != 1.
5847  */
5848 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
5849 {
5850   std::vector<const DataArrayInt *>arrs(2);
5851   arrs[0]=this; arrs[1]=other;
5852   return BuildUnion(arrs);
5853 }
5854
5855
5856 /*!
5857  * Returns a new DataArrayInt which contains elements present in both \a this and a given
5858  * one-dimensional arrays. The result array does not contain any duplicates
5859  * and its values are sorted in ascending order.
5860  *  \param [in] other - an array to intersect with \a this one.
5861  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5862  *         array using decrRef() as it is no more needed.
5863  *  \throw If \a this or \a other is not allocated.
5864  *  \throw If \a this->getNumberOfComponents() != 1.
5865  *  \throw If \a other->getNumberOfComponents() != 1.
5866  */
5867 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
5868 {
5869   std::vector<const DataArrayInt *>arrs(2);
5870   arrs[0]=this; arrs[1]=other;
5871   return BuildIntersection(arrs);
5872 }
5873
5874 /*!
5875  * This method can be applied on allocated with one component DataArrayInt instance.
5876  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
5877  * 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]
5878  * 
5879  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5880  * \throw if \a this is not allocated or if \a this has not exactly one component.
5881  * \sa DataArrayInt::buildUniqueNotSorted
5882  */
5883 DataArrayInt *DataArrayInt::buildUnique() const
5884 {
5885   checkAllocated();
5886   if(getNumberOfComponents()!=1)
5887     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
5888   int nbOfTuples=getNumberOfTuples();
5889   MCAuto<DataArrayInt> tmp=deepCopy();
5890   int *data=tmp->getPointer();
5891   int *last=std::unique(data,data+nbOfTuples);
5892   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5893   ret->alloc(std::distance(data,last),1);
5894   std::copy(data,last,ret->getPointer());
5895   return ret.retn();
5896 }
5897
5898 /*!
5899  * This method can be applied on allocated with one component DataArrayInt instance.
5900  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
5901  *
5902  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5903  *
5904  * \throw if \a this is not allocated or if \a this has not exactly one component.
5905  *
5906  * \sa DataArrayInt::buildUnique
5907  */
5908 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
5909 {
5910   checkAllocated();
5911     if(getNumberOfComponents()!=1)
5912       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
5913   int minVal,maxVal;
5914   getMinMaxValues(minVal,maxVal);
5915   std::vector<bool> b(maxVal-minVal+1,false);
5916   const int *ptBg(begin()),*endBg(end());
5917   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5918   for(const int *pt=ptBg;pt!=endBg;pt++)
5919     {
5920       if(!b[*pt-minVal])
5921         {
5922           ret->pushBackSilent(*pt);
5923           b[*pt-minVal]=true;
5924         }
5925     }
5926   ret->copyStringInfoFrom(*this);
5927   return ret.retn();
5928 }
5929
5930 /*!
5931  * Returns a new DataArrayInt which contains size of every of groups described by \a this
5932  * "index" array. Such "index" array is returned for example by 
5933  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
5934  * "MEDCouplingUMesh::buildDescendingConnectivity" and
5935  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
5936  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
5937  * This method performs the reverse operation of DataArrayInt::computeOffsetsFull.
5938  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
5939  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
5940  *          The caller is to delete this array using decrRef() as it is no more needed. 
5941  *  \throw If \a this is not allocated.
5942  *  \throw If \a this->getNumberOfComponents() != 1.
5943  *  \throw If \a this->getNumberOfTuples() < 2.
5944  *
5945  *  \b Example: <br> 
5946  *         - this contains [1,3,6,7,7,9,15]
5947  *         - result array contains [2,3,1,0,2,6],
5948  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
5949  *
5950  * \sa DataArrayInt::computeOffsetsFull
5951  */
5952 DataArrayInt *DataArrayInt::deltaShiftIndex() const
5953 {
5954   checkAllocated();
5955   if(getNumberOfComponents()!=1)
5956     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
5957   int nbOfTuples=getNumberOfTuples();
5958   if(nbOfTuples<2)
5959     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
5960   const int *ptr=getConstPointer();
5961   DataArrayInt *ret=DataArrayInt::New();
5962   ret->alloc(nbOfTuples-1,1);
5963   int *out=ret->getPointer();
5964   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
5965   return ret;
5966 }
5967
5968 /*!
5969  * Modifies \a this one-dimensional array so that value of each element \a x
5970  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5971  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
5972  * and components remains the same.<br>
5973  * This method is useful for allToAllV in MPI with contiguous policy. This method
5974  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
5975  * this one.
5976  *  \throw If \a this is not allocated.
5977  *  \throw If \a this->getNumberOfComponents() != 1.
5978  *
5979  *  \b Example: <br>
5980  *          - Before \a this contains [3,5,1,2,0,8]
5981  *          - After \a this contains  [0,3,8,9,11,11]<br>
5982  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
5983  *          array is retained and thus there is no space to store the last element.
5984  */
5985 void DataArrayInt::computeOffsets()
5986 {
5987   checkAllocated();
5988   if(getNumberOfComponents()!=1)
5989     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
5990   int nbOfTuples=getNumberOfTuples();
5991   if(nbOfTuples==0)
5992     return ;
5993   int *work=getPointer();
5994   int tmp=work[0];
5995   work[0]=0;
5996   for(int i=1;i<nbOfTuples;i++)
5997     {
5998       int tmp2=work[i];
5999       work[i]=work[i-1]+tmp;
6000       tmp=tmp2;
6001     }
6002   declareAsNew();
6003 }
6004
6005
6006 /*!
6007  * Modifies \a this one-dimensional array so that value of each element \a x
6008  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
6009  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
6010  * components remains the same and number of tuples is inceamented by one.<br>
6011  * This method is useful for allToAllV in MPI with contiguous policy. This method
6012  * differs from computeOffsets() in that the number of tuples is changed by this one.
6013  * This method performs the reverse operation of DataArrayInt::deltaShiftIndex.
6014  *  \throw If \a this is not allocated.
6015  *  \throw If \a this->getNumberOfComponents() != 1.
6016  *
6017  *  \b Example: <br>
6018  *          - Before \a this contains [3,5,1,2,0,8]
6019  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
6020  * \sa DataArrayInt::deltaShiftIndex
6021  */
6022 void DataArrayInt::computeOffsetsFull()
6023 {
6024   checkAllocated();
6025   if(getNumberOfComponents()!=1)
6026     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
6027   int nbOfTuples=getNumberOfTuples();
6028   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
6029   const int *work=getConstPointer();
6030   ret[0]=0;
6031   for(int i=0;i<nbOfTuples;i++)
6032     ret[i+1]=work[i]+ret[i];
6033   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
6034   declareAsNew();
6035 }
6036
6037 /*!
6038  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
6039  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
6040  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
6041  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
6042  * filling completely one of the ranges in \a this.
6043  *
6044  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
6045  * \param [out] rangeIdsFetched the range ids fetched
6046  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
6047  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
6048  *
6049  * \sa DataArrayInt::computeOffsetsFull
6050  *
6051  *  \b Example: <br>
6052  *          - \a this : [0,3,7,9,15,18]
6053  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
6054  *          - \a rangeIdsFetched result array: [0,2,4]
6055  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
6056  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
6057  * <br>
6058  */
6059 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
6060 {
6061   if(!listOfIds)
6062     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
6063   listOfIds->checkAllocated(); checkAllocated();
6064   if(listOfIds->getNumberOfComponents()!=1)
6065     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
6066   if(getNumberOfComponents()!=1)
6067     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
6068   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
6069   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
6070   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
6071   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
6072   while(tupPtr!=tupEnd && offPtr!=offEnd)
6073     {
6074       if(*tupPtr==*offPtr)
6075         {
6076           int i=offPtr[0];
6077           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
6078           if(i==offPtr[1])
6079             {
6080               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
6081               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
6082               offPtr++;
6083             }
6084         }
6085       else
6086         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
6087     }
6088   rangeIdsFetched=ret0.retn();
6089   idsInInputListThatFetch=ret1.retn();
6090 }
6091
6092 /*!
6093  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
6094  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6095  * "index" array of a "iota" array, thus, whose each element gives an index of a group
6096  * beginning within the "iota" array. And \a this is a one-dimensional array
6097  * considered as a selector of groups described by \a offsets to include into the result array.
6098  *  \throw If \a offsets is NULL.
6099  *  \throw If \a offsets is not allocated.
6100  *  \throw If \a offsets->getNumberOfComponents() != 1.
6101  *  \throw If \a offsets is not monotonically increasing.
6102  *  \throw If \a this is not allocated.
6103  *  \throw If \a this->getNumberOfComponents() != 1.
6104  *  \throw If any element of \a this is not a valid index for \a offsets array.
6105  *
6106  *  \b Example: <br>
6107  *          - \a this: [0,2,3]
6108  *          - \a offsets: [0,3,6,10,14,20]
6109  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
6110  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
6111  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
6112  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
6113  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
6114  */
6115 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
6116 {
6117   if(!offsets)
6118     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
6119   checkAllocated();
6120   if(getNumberOfComponents()!=1)
6121     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
6122   offsets->checkAllocated();
6123   if(offsets->getNumberOfComponents()!=1)
6124     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
6125   int othNbTuples=offsets->getNumberOfTuples()-1;
6126   int nbOfTuples=getNumberOfTuples();
6127   int retNbOftuples=0;
6128   const int *work=getConstPointer();
6129   const int *offPtr=offsets->getConstPointer();
6130   for(int i=0;i<nbOfTuples;i++)
6131     {
6132       int val=work[i];
6133       if(val>=0 && val<othNbTuples)
6134         {
6135           int delta=offPtr[val+1]-offPtr[val];
6136           if(delta>=0)
6137             retNbOftuples+=delta;
6138           else
6139             {
6140               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
6141               throw INTERP_KERNEL::Exception(oss.str().c_str());
6142             }
6143         }
6144       else
6145         {
6146           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
6147           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
6148           throw INTERP_KERNEL::Exception(oss.str().c_str());
6149         }
6150     }
6151   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6152   ret->alloc(retNbOftuples,1);
6153   int *retPtr=ret->getPointer();
6154   for(int i=0;i<nbOfTuples;i++)
6155     {
6156       int val=work[i];
6157       int start=offPtr[val];
6158       int off=offPtr[val+1]-start;
6159       for(int j=0;j<off;j++,retPtr++)
6160         *retPtr=start+j;
6161     }
6162   return ret.retn();
6163 }
6164
6165 /*!
6166  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
6167  * scaled array (monotonically increasing).
6168 from that of \a this and \a
6169  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6170  * "index" array of a "iota" array, thus, whose each element gives an index of a group
6171  * beginning within the "iota" array. And \a this is a one-dimensional array
6172  * considered as a selector of groups described by \a offsets to include into the result array.
6173  *  \throw If \a  is NULL.
6174  *  \throw If \a this is not allocated.
6175  *  \throw If \a this->getNumberOfComponents() != 1.
6176  *  \throw If \a this->getNumberOfTuples() == 0.
6177  *  \throw If \a this is not monotonically increasing.
6178  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
6179  *
6180  *  \b Example: <br>
6181  *          - \a bg , \a stop and \a step : (0,5,2)
6182  *          - \a this: [0,3,6,10,14,20]
6183  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
6184  */
6185 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
6186 {
6187   if(!isAllocated())
6188     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
6189   if(getNumberOfComponents()!=1)
6190     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
6191   int nbOfTuples(getNumberOfTuples());
6192   if(nbOfTuples==0)
6193     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
6194   const int *ids(begin());
6195   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
6196   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6197     {
6198       if(pos>=0 && pos<nbOfTuples-1)
6199         {
6200           int delta(ids[pos+1]-ids[pos]);
6201           sz+=delta;
6202           if(delta<0)
6203             {
6204               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
6205               throw INTERP_KERNEL::Exception(oss.str().c_str());
6206             }          
6207         }
6208       else
6209         {
6210           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
6211           throw INTERP_KERNEL::Exception(oss.str().c_str());
6212         }
6213     }
6214   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6215   int *retPtr(ret->getPointer());
6216   pos=bg;
6217   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6218     {
6219       int delta(ids[pos+1]-ids[pos]);
6220       for(int j=0;j<delta;j++,retPtr++)
6221         *retPtr=pos;
6222     }
6223   return ret.retn();
6224 }
6225
6226 /*!
6227  * 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.
6228  * 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
6229  * in tuple **i** of returned DataArrayInt.
6230  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6231  *
6232  * 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)]
6233  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6234  * 
6235  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6236  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6237  * \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
6238  *        is thrown if no ranges in \a ranges contains value in \a this.
6239  * 
6240  * \sa DataArrayInt::findIdInRangeForEachTuple
6241  */
6242 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
6243 {
6244   if(!ranges)
6245     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6246   if(ranges->getNumberOfComponents()!=2)
6247     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6248   checkAllocated();
6249   if(getNumberOfComponents()!=1)
6250     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6251   int nbTuples=getNumberOfTuples();
6252   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6253   int nbOfRanges=ranges->getNumberOfTuples();
6254   const int *rangesPtr=ranges->getConstPointer();
6255   int *retPtr=ret->getPointer();
6256   const int *inPtr=getConstPointer();
6257   for(int i=0;i<nbTuples;i++,retPtr++)
6258     {
6259       int val=inPtr[i];
6260       bool found=false;
6261       for(int j=0;j<nbOfRanges && !found;j++)
6262         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6263           { *retPtr=j; found=true; }
6264       if(found)
6265         continue;
6266       else
6267         {
6268           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6269           throw INTERP_KERNEL::Exception(oss.str().c_str());
6270         }
6271     }
6272   return ret.retn();
6273 }
6274
6275 /*!
6276  * 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.
6277  * 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
6278  * in tuple **i** of returned DataArrayInt.
6279  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6280  *
6281  * 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)]
6282  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6283  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6284  * 
6285  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6286  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6287  * \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
6288  *        is thrown if no ranges in \a ranges contains value in \a this.
6289  * \sa DataArrayInt::findRangeIdForEachTuple
6290  */
6291 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
6292 {
6293   if(!ranges)
6294     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6295   if(ranges->getNumberOfComponents()!=2)
6296     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6297   checkAllocated();
6298   if(getNumberOfComponents()!=1)
6299     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6300   int nbTuples=getNumberOfTuples();
6301   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6302   int nbOfRanges=ranges->getNumberOfTuples();
6303   const int *rangesPtr=ranges->getConstPointer();
6304   int *retPtr=ret->getPointer();
6305   const int *inPtr=getConstPointer();
6306   for(int i=0;i<nbTuples;i++,retPtr++)
6307     {
6308       int val=inPtr[i];
6309       bool found=false;
6310       for(int j=0;j<nbOfRanges && !found;j++)
6311         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6312           { *retPtr=val-rangesPtr[2*j]; found=true; }
6313       if(found)
6314         continue;
6315       else
6316         {
6317           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6318           throw INTERP_KERNEL::Exception(oss.str().c_str());
6319         }
6320     }
6321   return ret.retn();
6322 }
6323
6324 /*!
6325  * \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).
6326  * 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).
6327  * 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 !
6328  * If this method has correctly worked, \a this will be able to be considered as a linked list.
6329  * This method does nothing if number of tuples is lower of equal to 1.
6330  *
6331  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internally the connectibity without any coordinates consideration.
6332  *
6333  * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
6334  */
6335 void DataArrayInt::sortEachPairToMakeALinkedList()
6336 {
6337   checkAllocated();
6338   if(getNumberOfComponents()!=2)
6339     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6340   int nbOfTuples(getNumberOfTuples());
6341   if(nbOfTuples<=1)
6342     return ;
6343   int *conn(getPointer());
6344   for(int i=1;i<nbOfTuples;i++,conn+=2)
6345     {
6346       if(i>1)
6347         {
6348           if(conn[2]==conn[3])
6349             {
6350               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6351               throw INTERP_KERNEL::Exception(oss.str().c_str());
6352             }
6353           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6354             std::swap(conn[2],conn[3]);
6355           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6356           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6357             {
6358               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6359               throw INTERP_KERNEL::Exception(oss.str().c_str());
6360             }
6361         }
6362       else
6363         {
6364           if(conn[0]==conn[1] || conn[2]==conn[3])
6365             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6366           int tmp[4];
6367           std::set<int> s;
6368           s.insert(conn,conn+4);
6369           if(s.size()!=3)
6370             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6371           if(std::count(conn,conn+4,conn[0])==2)
6372             {
6373               tmp[0]=conn[1];
6374               tmp[1]=conn[0];
6375               tmp[2]=conn[0];
6376               if(conn[2]==conn[0])
6377                 { tmp[3]=conn[3]; }
6378               else
6379                 { tmp[3]=conn[2];}
6380               std::copy(tmp,tmp+4,conn);
6381             }
6382           else
6383             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6384               if(conn[1]==conn[3])
6385                 std::swap(conn[2],conn[3]);
6386             }
6387         }
6388     }
6389 }
6390
6391 /*!
6392  * \a this is expected to be a correctly linked list of pairs.
6393  * 
6394  * \sa DataArrayInt::sortEachPairToMakeALinkedList
6395  */
6396 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
6397 {
6398   checkAllocated();
6399   checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6400   int nbTuples(getNumberOfTuples());
6401   if(nbTuples<1)
6402     throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6403   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
6404   const int *thisPtr(begin());
6405   int *retPtr(ret->getPointer());
6406   retPtr[0]=thisPtr[0];
6407   for(int i=0;i<nbTuples;i++)
6408     {
6409       retPtr[i+1]=thisPtr[2*i+1];
6410       if(i<nbTuples-1)
6411         if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6412           {
6413             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 ?";
6414             throw INTERP_KERNEL::Exception(oss.str());
6415           }
6416     }
6417   return ret;
6418 }
6419
6420 /*!
6421  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6422  * But the number of components can be different from one.
6423  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6424  */
6425 DataArrayInt *DataArrayInt::getDifferentValues() const
6426 {
6427   checkAllocated();
6428   std::set<int> ret;
6429   ret.insert(begin(),end());
6430   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
6431   std::copy(ret.begin(),ret.end(),ret2->getPointer());
6432   return ret2.retn();
6433 }
6434
6435 /*!
6436  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6437  * them it tells which tuple id have this id.
6438  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6439  * This method returns two arrays having same size.
6440  * 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.
6441  * 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]]
6442  */
6443 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
6444 {
6445   checkAllocated();
6446   if(getNumberOfComponents()!=1)
6447     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6448   int id=0;
6449   std::map<int,int> m,m2,m3;
6450   for(const int *w=begin();w!=end();w++)
6451     m[*w]++;
6452   differentIds.resize(m.size());
6453   std::vector<DataArrayInt *> ret(m.size());
6454   std::vector<int *> retPtr(m.size());
6455   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
6456     {
6457       m2[(*it).first]=id;
6458       ret[id]=DataArrayInt::New();
6459       ret[id]->alloc((*it).second,1);
6460       retPtr[id]=ret[id]->getPointer();
6461       differentIds[id]=(*it).first;
6462     }
6463   id=0;
6464   for(const int *w=begin();w!=end();w++,id++)
6465     {
6466       retPtr[m2[*w]][m3[*w]++]=id;
6467     }
6468   return ret;
6469 }
6470
6471 /*!
6472  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6473  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6474  *
6475  * \param [in] nbOfSlices - number of slices expected.
6476  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6477  * 
6478  * \sa DataArray::GetSlice
6479  * \throw If \a this is not allocated or not with exactly one component.
6480  * \throw If an element in \a this if < 0.
6481  */
6482 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
6483 {
6484   if(!isAllocated() || getNumberOfComponents()!=1)
6485     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6486   if(nbOfSlices<=0)
6487     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6488   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
6489   int sumPerSlc(sum/nbOfSlices),pos(0);
6490   const int *w(begin());
6491   std::vector< std::pair<int,int> > ret(nbOfSlices);
6492   for(int i=0;i<nbOfSlices;i++)
6493     {
6494       std::pair<int,int> p(pos,-1);
6495       int locSum(0);
6496       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6497       if(i!=nbOfSlices-1)
6498         p.second=pos;
6499       else
6500         p.second=nbOfTuples;
6501       ret[i]=p;
6502     }
6503   return ret;
6504 }
6505
6506 /*!
6507  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6508  * valid cases.
6509  * 1.  The arrays have same number of tuples and components. Then each value of
6510  *   the result array (_a_) is a division of the corresponding values of \a a1 and
6511  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6512  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
6513  *   component. Then
6514  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6515  * 3.  The arrays have same number of components and one array, say _a2_, has one
6516  *   tuple. Then
6517  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6518  *
6519  * Info on components is copied either from the first array (in the first case) or from
6520  * the array with maximal number of elements (getNbOfElems()).
6521  *  \warning No check of division by zero is performed!
6522  *  \param [in] a1 - a dividend array.
6523  *  \param [in] a2 - a divisor array.
6524  *  \return DataArrayInt * - the new instance of DataArrayInt.
6525  *          The caller is to delete this result array using decrRef() as it is no more
6526  *          needed.
6527  *  \throw If either \a a1 or \a a2 is NULL.
6528  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6529  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6530  *         none of them has number of tuples or components equal to 1.
6531  */
6532 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
6533 {
6534   if(!a1 || !a2)
6535     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6536   int nbOfTuple1=a1->getNumberOfTuples();
6537   int nbOfTuple2=a2->getNumberOfTuples();
6538   int nbOfComp1=a1->getNumberOfComponents();
6539   int nbOfComp2=a2->getNumberOfComponents();
6540   if(nbOfTuple2==nbOfTuple1)
6541     {
6542       if(nbOfComp1==nbOfComp2)
6543         {
6544           MCAuto<DataArrayInt> ret=DataArrayInt::New();
6545           ret->alloc(nbOfTuple2,nbOfComp1);
6546           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
6547           ret->copyStringInfoFrom(*a1);
6548           return ret.retn();
6549         }
6550       else if(nbOfComp2==1)
6551         {
6552           MCAuto<DataArrayInt> ret=DataArrayInt::New();
6553           ret->alloc(nbOfTuple1,nbOfComp1);
6554           const int *a2Ptr=a2->getConstPointer();
6555           const int *a1Ptr=a1->getConstPointer();
6556           int *res=ret->getPointer();
6557           for(int i=0;i<nbOfTuple1;i++)
6558             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
6559           ret->copyStringInfoFrom(*a1);
6560           return ret.retn();
6561         }
6562       else
6563         {
6564           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6565           return 0;
6566         }
6567     }
6568   else if(nbOfTuple2==1)
6569     {
6570       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6571       MCAuto<DataArrayInt> ret=DataArrayInt::New();
6572       ret->alloc(nbOfTuple1,nbOfComp1);
6573       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6574       int *pt=ret->getPointer();
6575       for(int i=0;i<nbOfTuple1;i++)
6576         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
6577       ret->copyStringInfoFrom(*a1);
6578       return ret.retn();
6579     }
6580   else
6581     {
6582       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
6583       return 0;
6584     }
6585 }
6586
6587 /*!
6588  * Modify \a this array so that each value becomes a modulus of division of this value by
6589  * a value of another DataArrayInt. There are 3 valid cases.
6590  * 1.  The arrays have same number of tuples and components. Then each value of
6591  *    \a this array is divided by the corresponding value of \a other one, i.e.:
6592  *   _a_ [ i, j ] %= _other_ [ i, j ].
6593  * 2.  The arrays have same number of tuples and \a other array has one component. Then
6594  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
6595  * 3.  The arrays have same number of components and \a other array has one tuple. Then
6596  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
6597  *
6598  *  \warning No check of division by zero is performed!
6599  *  \param [in] other - a divisor array.
6600  *  \throw If \a other is NULL.
6601  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
6602  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
6603  *         \a other has number of both tuples and components not equal to 1.
6604  */
6605 void DataArrayInt::modulusEqual(const DataArrayInt *other)
6606 {
6607   if(!other)
6608     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
6609   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
6610   checkAllocated(); other->checkAllocated();
6611   int nbOfTuple=getNumberOfTuples();
6612   int nbOfTuple2=other->getNumberOfTuples();
6613   int nbOfComp=getNumberOfComponents();
6614   int nbOfComp2=other->getNumberOfComponents();
6615   if(nbOfTuple==nbOfTuple2)
6616     {
6617       if(nbOfComp==nbOfComp2)
6618         {
6619           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
6620         }
6621       else if(nbOfComp2==1)
6622         {
6623           if(nbOfComp2==nbOfComp)
6624             {
6625               int *ptr=getPointer();
6626               const int *ptrc=other->getConstPointer();
6627               for(int i=0;i<nbOfTuple;i++)
6628                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
6629             }
6630           else
6631             throw INTERP_KERNEL::Exception(msg);
6632         }
6633       else
6634         throw INTERP_KERNEL::Exception(msg);
6635     }
6636   else if(nbOfTuple2==1)
6637     {
6638       int *ptr=getPointer();
6639       const int *ptrc=other->getConstPointer();
6640       for(int i=0;i<nbOfTuple;i++)
6641         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
6642     }
6643   else
6644     throw INTERP_KERNEL::Exception(msg);
6645   declareAsNew();
6646 }
6647
6648 /*!
6649  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
6650  * valid cases.
6651  *
6652  *  \param [in] a1 - an array to pow up.
6653  *  \param [in] a2 - another array to sum up.
6654  *  \return DataArrayInt * - the new instance of DataArrayInt.
6655  *          The caller is to delete this result array using decrRef() as it is no more
6656  *          needed.
6657  *  \throw If either \a a1 or \a a2 is NULL.
6658  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6659  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
6660  *  \throw If there is a negative value in \a a2.
6661  */
6662 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
6663 {
6664   if(!a1 || !a2)
6665     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
6666   int nbOfTuple=a1->getNumberOfTuples();
6667   int nbOfTuple2=a2->getNumberOfTuples();
6668   int nbOfComp=a1->getNumberOfComponents();
6669   int nbOfComp2=a2->getNumberOfComponents();
6670   if(nbOfTuple!=nbOfTuple2)
6671     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
6672   if(nbOfComp!=1 || nbOfComp2!=1)
6673     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
6674   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
6675   const int *ptr1(a1->begin()),*ptr2(a2->begin());
6676   int *ptr=ret->getPointer();
6677   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
6678     {
6679       if(*ptr2>=0)
6680         {
6681           int tmp=1;
6682           for(int j=0;j<*ptr2;j++)
6683             tmp*=*ptr1;
6684           *ptr=tmp;
6685         }
6686       else
6687         {
6688           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
6689           throw INTERP_KERNEL::Exception(oss.str().c_str());
6690         }
6691     }
6692   return ret.retn();
6693 }
6694
6695 /*!
6696  * Apply pow on values of another DataArrayInt to values of \a this one.
6697  *
6698  *  \param [in] other - an array to pow to \a this one.
6699  *  \throw If \a other is NULL.
6700  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
6701  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
6702  *  \throw If there is a negative value in \a other.
6703  */
6704 void DataArrayInt::powEqual(const DataArrayInt *other)
6705 {
6706   if(!other)
6707     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
6708   int nbOfTuple=getNumberOfTuples();
6709   int nbOfTuple2=other->getNumberOfTuples();
6710   int nbOfComp=getNumberOfComponents();
6711   int nbOfComp2=other->getNumberOfComponents();
6712   if(nbOfTuple!=nbOfTuple2)
6713     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
6714   if(nbOfComp!=1 || nbOfComp2!=1)
6715     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
6716   int *ptr=getPointer();
6717   const int *ptrc=other->begin();
6718   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
6719     {
6720       if(*ptrc>=0)
6721         {
6722           int tmp=1;
6723           for(int j=0;j<*ptrc;j++)
6724             tmp*=*ptr;
6725           *ptr=tmp;
6726         }
6727       else
6728         {
6729           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
6730           throw INTERP_KERNEL::Exception(oss.str().c_str());
6731         }
6732     }
6733   declareAsNew();
6734 }
6735
6736 /*!
6737  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
6738  * This map, if applied to \a start array, would make it sorted. For example, if
6739  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
6740  * [5,6,0,3,2,7,1,4].
6741  *  \param [in] start - pointer to the first element of the array for which the
6742  *         permutation map is computed.
6743  *  \param [in] end - pointer specifying the end of the array \a start, so that
6744  *         the last value of \a start is \a end[ -1 ].
6745  *  \return int * - the result permutation array that the caller is to delete as it is no
6746  *         more needed.
6747  *  \throw If there are equal values in the input array.
6748  */
6749 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
6750 {
6751   std::size_t sz=std::distance(start,end);
6752   int *ret=(int *)malloc(sz*sizeof(int));
6753   int *work=new int[sz];
6754   std::copy(start,end,work);
6755   std::sort(work,work+sz);
6756   if(std::unique(work,work+sz)!=work+sz)
6757     {
6758       delete [] work;
6759       free(ret);
6760       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
6761     }
6762   std::map<int,int> m;
6763   for(int *workPt=work;workPt!=work+sz;workPt++)
6764     m[*workPt]=(int)std::distance(work,workPt);
6765   int *iter2=ret;
6766   for(const int *iter=start;iter!=end;iter++,iter2++)
6767     *iter2=m[*iter];
6768   delete [] work;
6769   return ret;
6770 }
6771
6772 /*!
6773  * Returns a new DataArrayInt containing an arithmetic progression
6774  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
6775  * function.
6776  *  \param [in] begin - the start value of the result sequence.
6777  *  \param [in] end - limiting value, so that every value of the result array is less than
6778  *              \a end.
6779  *  \param [in] step - specifies the increment or decrement.
6780  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6781  *          array using decrRef() as it is no more needed.
6782  *  \throw If \a step == 0.
6783  *  \throw If \a end < \a begin && \a step > 0.
6784  *  \throw If \a end > \a begin && \a step < 0.
6785  */
6786 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
6787 {
6788   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
6789   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6790   ret->alloc(nbOfTuples,1);
6791   int *ptr=ret->getPointer();
6792   if(step>0)
6793     {
6794       for(int i=begin;i<end;i+=step,ptr++)
6795         *ptr=i;
6796     }
6797   else
6798     {
6799       for(int i=begin;i>end;i+=step,ptr++)
6800         *ptr=i;
6801     }
6802   return ret.retn();
6803 }
6804
6805 /*!
6806  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6807  * Server side.
6808  */
6809 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
6810 {
6811   tinyInfo.resize(2);
6812   if(isAllocated())
6813     {
6814       tinyInfo[0]=getNumberOfTuples();
6815       tinyInfo[1]=getNumberOfComponents();
6816     }
6817   else
6818     {
6819       tinyInfo[0]=-1;
6820       tinyInfo[1]=-1;
6821     }
6822 }
6823
6824 /*!
6825  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6826  * Server side.
6827  */
6828 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
6829 {
6830   if(isAllocated())
6831     {
6832       int nbOfCompo=getNumberOfComponents();
6833       tinyInfo.resize(nbOfCompo+1);
6834       tinyInfo[0]=getName();
6835       for(int i=0;i<nbOfCompo;i++)
6836         tinyInfo[i+1]=getInfoOnComponent(i);
6837     }
6838   else
6839     {
6840       tinyInfo.resize(1);
6841       tinyInfo[0]=getName();
6842     }
6843 }
6844
6845 /*!
6846  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6847  * This method returns if a feeding is needed.
6848  */
6849 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
6850 {
6851   int nbOfTuple=tinyInfoI[0];
6852   int nbOfComp=tinyInfoI[1];
6853   if(nbOfTuple!=-1 || nbOfComp!=-1)
6854     {
6855       alloc(nbOfTuple,nbOfComp);
6856       return true;
6857     }
6858   return false;
6859 }
6860
6861 /*!
6862  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6863  * This method returns if a feeding is needed.
6864  */
6865 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
6866 {
6867   setName(tinyInfoS[0]);
6868   if(isAllocated())
6869     {
6870       int nbOfCompo=tinyInfoI[1];
6871       for(int i=0;i<nbOfCompo;i++)
6872         setInfoOnComponent(i,tinyInfoS[i+1]);
6873     }
6874 }
6875
6876 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
6877 {
6878 }
6879
6880 DataArrayInt32Tuple::DataArrayInt32Tuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
6881 {
6882 }
6883
6884 std::string DataArrayIntTuple::repr() const
6885 {
6886   std::ostringstream oss; oss << "(";
6887   for(int i=0;i<_nb_of_compo-1;i++)
6888     oss << _pt[i] << ", ";
6889   oss << _pt[_nb_of_compo-1] << ")";
6890   return oss.str();
6891 }
6892
6893 int DataArrayIntTuple::intValue() const
6894 {
6895   return this->zeValue();
6896 }
6897
6898 /*!
6899  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
6900  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
6901  * 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
6902  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
6903  */
6904 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
6905 {
6906   return this->buildDA(nbOfTuples,nbOfCompo);
6907 }