Salome HOME
Intel17 portability.
[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 minimum norm (absolute value) of the vector defined by \a this array.
1649  * This method works even if the number of components is different from one.
1650  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1651  *  \return double - the value of the minimum norm, i.e.
1652  *          the minimal absolute value among values of \a this array (whatever its number of components).
1653  *  \throw If \a this is not allocated.
1654  */
1655 double DataArrayDouble::normMin() const
1656 {
1657   checkAllocated();
1658   double ret(std::numeric_limits<double>::max());
1659   std::size_t nbOfElems(getNbOfElems());
1660   const double *pt(getConstPointer());
1661   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1662     {
1663       double val(std::abs(*pt));
1664       if(val<ret)
1665         ret=val;
1666     }
1667   return ret;
1668 }
1669
1670 /*!
1671  * Accumulates values of each component of \a this array.
1672  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
1673  *         by the caller, that is filled by this method with sum value for each
1674  *         component.
1675  *  \throw If \a this is not allocated.
1676  */
1677 void DataArrayDouble::accumulate(double *res) const
1678 {
1679   checkAllocated();
1680   const double *ptr=getConstPointer();
1681   int nbTuple=getNumberOfTuples();
1682   int nbComps=getNumberOfComponents();
1683   std::fill(res,res+nbComps,0.);
1684   for(int i=0;i<nbTuple;i++)
1685     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1686 }
1687
1688 /*!
1689  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1690  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1691  *
1692  *
1693  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1694  * \a tupleEnd. If not an exception will be thrown.
1695  *
1696  * \param [in] tupleBg start pointer (included) of input external tuple
1697  * \param [in] tupleEnd end pointer (not included) of input external tuple
1698  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1699  * \return the min distance.
1700  * \sa MEDCouplingUMesh::distanceToPoint
1701  */
1702 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1703 {
1704   checkAllocated();
1705   int nbTuple=getNumberOfTuples();
1706   int nbComps=getNumberOfComponents();
1707   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1708     { 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()); }
1709   if(nbTuple==0)
1710     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1711   double ret0=std::numeric_limits<double>::max();
1712   tupleId=-1;
1713   const double *work=getConstPointer();
1714   for(int i=0;i<nbTuple;i++)
1715     {
1716       double val=0.;
1717       for(int j=0;j<nbComps;j++,work++) 
1718         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1719       if(val>=ret0)
1720         continue;
1721       else
1722         { ret0=val; tupleId=i; }
1723     }
1724   return sqrt(ret0);
1725 }
1726
1727 /*!
1728  * Accumulate values of the given component of \a this array.
1729  *  \param [in] compId - the index of the component of interest.
1730  *  \return double - a sum value of \a compId-th component.
1731  *  \throw If \a this is not allocated.
1732  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1733  *         not respected.
1734  */
1735 double DataArrayDouble::accumulate(int compId) const
1736 {
1737   checkAllocated();
1738   const double *ptr=getConstPointer();
1739   int nbTuple=getNumberOfTuples();
1740   int nbComps=getNumberOfComponents();
1741   if(compId<0 || compId>=nbComps)
1742     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1743   double ret=0.;
1744   for(int i=0;i<nbTuple;i++)
1745     ret+=ptr[i*nbComps+compId];
1746   return ret;
1747 }
1748
1749 /*!
1750  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1751  * The returned array will have same number of components than \a this and number of tuples equal to
1752  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1753  *
1754  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1755  * 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.
1756  *
1757  * \param [in] bgOfIndex - begin (included) of the input index array.
1758  * \param [in] endOfIndex - end (excluded) of the input index array.
1759  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1760  * 
1761  * \throw If bgOfIndex or end is NULL.
1762  * \throw If input index array is not ascendingly sorted.
1763  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1764  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1765  */
1766 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1767 {
1768   if(!bgOfIndex || !endOfIndex)
1769     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1770   checkAllocated();
1771   int nbCompo=getNumberOfComponents();
1772   int nbOfTuples=getNumberOfTuples();
1773   int sz=(int)std::distance(bgOfIndex,endOfIndex);
1774   if(sz<1)
1775     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1776   sz--;
1777   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1778   const int *w=bgOfIndex;
1779   if(*w<0 || *w>=nbOfTuples)
1780     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1781   const double *srcPt=begin()+(*w)*nbCompo;
1782   double *tmp=ret->getPointer();
1783   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1784     {
1785       std::fill(tmp,tmp+nbCompo,0.);
1786       if(w[1]>=w[0])
1787         {
1788           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1789             {
1790               if(j>=0 && j<nbOfTuples)
1791                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1792               else
1793                 {
1794                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
1795                   throw INTERP_KERNEL::Exception(oss.str().c_str());
1796                 }
1797             }
1798         }
1799       else
1800         {
1801           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
1802           throw INTERP_KERNEL::Exception(oss.str().c_str());
1803         }
1804     }
1805   ret->copyStringInfoFrom(*this);
1806   return ret.retn();
1807 }
1808
1809 /*!
1810  * 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.
1811  * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
1812  * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
1813  *
1814  * \return DataArrayDouble - A newly built array containing cum sum of \a this.
1815  */
1816 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
1817 {
1818   checkAllocated();
1819   checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
1820   int nbOfTuple(getNumberOfTuples());
1821   MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
1822   double *ptr(ret->getPointer());
1823   ptr[0]=0.;
1824   const double *thisPtr(begin());
1825   for(int i=0;i<nbOfTuple;i++)
1826     ptr[i+1]=ptr[i]+thisPtr[i];
1827   return ret;
1828 }
1829
1830 /*!
1831  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
1832  * Cartesian coordinate system. The two components of the tuple of \a this array are 
1833  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
1834  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1835  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
1836  *          is to delete this array using decrRef() as it is no more needed. The array
1837  *          does not contain any textual info on components.
1838  *  \throw If \a this->getNumberOfComponents() != 2.
1839  * \sa fromCartToPolar
1840  */
1841 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
1842 {
1843   checkAllocated();
1844   int nbOfComp(getNumberOfComponents());
1845   if(nbOfComp!=2)
1846     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
1847   int nbOfTuple(getNumberOfTuples());
1848   DataArrayDouble *ret(DataArrayDouble::New());
1849   ret->alloc(nbOfTuple,2);
1850   double *w(ret->getPointer());
1851   const double *wIn(getConstPointer());
1852   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
1853     {
1854       w[0]=wIn[0]*cos(wIn[1]);
1855       w[1]=wIn[0]*sin(wIn[1]);
1856     }
1857   return ret;
1858 }
1859
1860 /*!
1861  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
1862  * the Cartesian coordinate system. The three components of the tuple of \a this array 
1863  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
1864  * the Cylindrical CS.
1865  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1866  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1867  *          on the third component is copied from \a this array. The caller
1868  *          is to delete this array using decrRef() as it is no more needed. 
1869  *  \throw If \a this->getNumberOfComponents() != 3.
1870  * \sa fromCartToCyl
1871  */
1872 DataArrayDouble *DataArrayDouble::fromCylToCart() const
1873 {
1874   checkAllocated();
1875   int nbOfComp(getNumberOfComponents());
1876   if(nbOfComp!=3)
1877     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
1878   int nbOfTuple(getNumberOfTuples());
1879   DataArrayDouble *ret(DataArrayDouble::New());
1880   ret->alloc(getNumberOfTuples(),3);
1881   double *w(ret->getPointer());
1882   const double *wIn(getConstPointer());
1883   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1884     {
1885       w[0]=wIn[0]*cos(wIn[1]);
1886       w[1]=wIn[0]*sin(wIn[1]);
1887       w[2]=wIn[2];
1888     }
1889   ret->setInfoOnComponent(2,getInfoOnComponent(2));
1890   return ret;
1891 }
1892
1893 /*!
1894  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
1895  * the Cartesian coordinate system. The three components of the tuple of \a this array 
1896  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
1897  * point in the Cylindrical CS.
1898  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1899  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1900  *          on the third component is copied from \a this array. The caller
1901  *          is to delete this array using decrRef() as it is no more needed.
1902  *  \throw If \a this->getNumberOfComponents() != 3.
1903  * \sa fromCartToSpher
1904  */
1905 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
1906 {
1907   checkAllocated();
1908   int nbOfComp(getNumberOfComponents());
1909   if(nbOfComp!=3)
1910     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
1911   int nbOfTuple(getNumberOfTuples());
1912   DataArrayDouble *ret(DataArrayDouble::New());
1913   ret->alloc(getNumberOfTuples(),3);
1914   double *w(ret->getPointer());
1915   const double *wIn(getConstPointer());
1916   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1917     {
1918       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
1919       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
1920       w[2]=wIn[0]*cos(wIn[1]);
1921     }
1922   return ret;
1923 }
1924
1925 /*!
1926  * 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.
1927  * 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.
1928  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
1929  *
1930  * \param [in] atOfThis - The axis type of \a this.
1931  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
1932  */
1933 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
1934 {
1935   checkAllocated();
1936   int nbOfComp(getNumberOfComponents());
1937   MCAuto<DataArrayDouble> ret;
1938   switch(atOfThis)
1939     {
1940     case AX_CART:
1941       ret=deepCopy();
1942     case AX_CYL:
1943       if(nbOfComp==3)
1944         {
1945           ret=fromCylToCart();
1946           break;
1947         }
1948       if(nbOfComp==2)
1949         {
1950           ret=fromPolarToCart();
1951           break;
1952         }
1953       else
1954         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1955     case AX_SPHER:
1956       if(nbOfComp==3)
1957         {
1958           ret=fromSpherToCart();
1959           break;
1960         }
1961       if(nbOfComp==2)
1962         {
1963           ret=fromPolarToCart();
1964           break;
1965         }
1966       else
1967         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1968     default:
1969       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
1970     }
1971   ret->copyStringInfoFrom(*this);
1972   return ret.retn();
1973 }
1974
1975 /*!
1976  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
1977  * This method expects that \a this has exactly 2 components.
1978  * \sa fromPolarToCart
1979  */
1980 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
1981 {
1982   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
1983   checkAllocated();
1984   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
1985   if(nbOfComp!=2)
1986     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
1987   ret->alloc(nbTuples,2);
1988   double *retPtr(ret->getPointer());
1989   const double *ptr(begin());
1990   for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
1991     {
1992       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
1993       retPtr[1]=atan2(ptr[1],ptr[0]);
1994     }
1995   return ret.retn();
1996 }
1997
1998 /*!
1999  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2000  * This method expects that \a this has exactly 3 components.
2001  * \sa fromCylToCart
2002  */
2003 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2004 {
2005   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2006   checkAllocated();
2007   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2008   if(nbOfComp!=3)
2009     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2010   ret->alloc(nbTuples,3);
2011   double *retPtr(ret->getPointer());
2012   const double *ptr(begin());
2013   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2014     {
2015       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2016       retPtr[1]=atan2(ptr[1],ptr[0]);
2017       retPtr[2]=ptr[2];
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 spherical coordinates.
2024  * \sa fromSpherToCart
2025  */
2026 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2027 {
2028   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2029   checkAllocated();
2030   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2031   if(nbOfComp!=3)
2032     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2033   ret->alloc(nbTuples,3);
2034   double *retPtr(ret->getPointer());
2035   const double *ptr(begin());
2036   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2037     {
2038       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2039       retPtr[1]=acos(ptr[2]/retPtr[0]);
2040       retPtr[2]=atan2(ptr[1],ptr[0]);
2041     }
2042   return ret.retn();
2043 }
2044
2045 /*!
2046  * 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.
2047  * This method expects that \a this has exactly 3 components.
2048  * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2049  */
2050 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2051 {
2052   if(!coords)
2053     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2054   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2055   checkAllocated(); coords->checkAllocated();
2056   std::size_t nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2057   if(nbOfComp!=3)
2058     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2059   if(coords->getNumberOfComponents()!=3)
2060     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2061   if(coords->getNumberOfTuples()!=nbTuples)
2062     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2063   ret->alloc(nbTuples,nbOfComp);
2064   double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2065   if(magOfVect<1e-12)
2066     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2067   double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2068   const double *coo(coords->begin()),*vectField(begin());
2069   std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2070   for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2071     {
2072       std::transform(coo,coo+3,center,Ur,std::minus<double>());
2073       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];
2074       double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2075       std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2076       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];
2077       retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2078       retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2079       retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2080     }
2081   ret->copyStringInfoFrom(*this);
2082   return ret.retn();
2083 }
2084
2085 /*!
2086  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2087  * array containing 6 components.
2088  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2089  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
2090  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2091  *         The caller is to delete this result array using decrRef() as it is no more needed. 
2092  *  \throw If \a this->getNumberOfComponents() != 6.
2093  */
2094 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2095 {
2096   checkAllocated();
2097   int nbOfComp(getNumberOfComponents());
2098   if(nbOfComp!=6)
2099     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2100   DataArrayDouble *ret=DataArrayDouble::New();
2101   int nbOfTuple=getNumberOfTuples();
2102   ret->alloc(nbOfTuple,1);
2103   const double *src=getConstPointer();
2104   double *dest=ret->getPointer();
2105   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2106     *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];
2107   return ret;
2108 }
2109
2110 /*!
2111  * Computes the determinant of every square matrix defined by the tuple of \a this
2112  * array, which contains either 4, 6 or 9 components. The case of 6 components
2113  * corresponds to that of the upper triangular matrix.
2114  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2115  *          is the determinant of matrix of the corresponding tuple of \a this array.
2116  *          The caller is to delete this result array using decrRef() as it is no more
2117  *          needed. 
2118  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2119  */
2120 DataArrayDouble *DataArrayDouble::determinant() const
2121 {
2122   checkAllocated();
2123   DataArrayDouble *ret=DataArrayDouble::New();
2124   int nbOfTuple=getNumberOfTuples();
2125   ret->alloc(nbOfTuple,1);
2126   const double *src=getConstPointer();
2127   double *dest=ret->getPointer();
2128   switch(getNumberOfComponents())
2129   {
2130     case 6:
2131       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2132         *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];
2133       return ret;
2134     case 4:
2135       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2136         *dest=src[0]*src[3]-src[1]*src[2];
2137       return ret;
2138     case 9:
2139       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2140         *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];
2141       return ret;
2142     default:
2143       ret->decrRef();
2144       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2145   }
2146 }
2147
2148 /*!
2149  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2150  * \a this array, which contains 6 components.
2151  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2152  *          components, whose each tuple contains the eigenvalues of the matrix of
2153  *          corresponding tuple of \a this array. 
2154  *          The caller is to delete this result array using decrRef() as it is no more
2155  *          needed. 
2156  *  \throw If \a this->getNumberOfComponents() != 6.
2157  */
2158 DataArrayDouble *DataArrayDouble::eigenValues() const
2159 {
2160   checkAllocated();
2161   int nbOfComp=getNumberOfComponents();
2162   if(nbOfComp!=6)
2163     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2164   DataArrayDouble *ret=DataArrayDouble::New();
2165   int nbOfTuple=getNumberOfTuples();
2166   ret->alloc(nbOfTuple,3);
2167   const double *src=getConstPointer();
2168   double *dest=ret->getPointer();
2169   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2170     INTERP_KERNEL::computeEigenValues6(src,dest);
2171   return ret;
2172 }
2173
2174 /*!
2175  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2176  * \a this array, which contains 6 components.
2177  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2178  *          components, whose each tuple contains 3 eigenvectors of the matrix of
2179  *          corresponding tuple of \a this array.
2180  *          The caller is to delete this result array using decrRef() as it is no more
2181  *          needed.
2182  *  \throw If \a this->getNumberOfComponents() != 6.
2183  */
2184 DataArrayDouble *DataArrayDouble::eigenVectors() const
2185 {
2186   checkAllocated();
2187   int nbOfComp=getNumberOfComponents();
2188   if(nbOfComp!=6)
2189     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2190   DataArrayDouble *ret=DataArrayDouble::New();
2191   int nbOfTuple=getNumberOfTuples();
2192   ret->alloc(nbOfTuple,9);
2193   const double *src=getConstPointer();
2194   double *dest=ret->getPointer();
2195   for(int i=0;i<nbOfTuple;i++,src+=6)
2196     {
2197       double tmp[3];
2198       INTERP_KERNEL::computeEigenValues6(src,tmp);
2199       for(int j=0;j<3;j++,dest+=3)
2200         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2201     }
2202   return ret;
2203 }
2204
2205 /*!
2206  * Computes the inverse matrix of every matrix defined by the tuple of \a this
2207  * array, which contains either 4, 6 or 9 components. The case of 6 components
2208  * corresponds to that of the upper triangular matrix.
2209  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2210  *          same number of components as \a this one, whose each tuple is the inverse
2211  *          matrix of the matrix of corresponding tuple of \a this array. 
2212  *          The caller is to delete this result array using decrRef() as it is no more
2213  *          needed. 
2214  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2215  */
2216 DataArrayDouble *DataArrayDouble::inverse() const
2217 {
2218   checkAllocated();
2219   int nbOfComp=getNumberOfComponents();
2220   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2221     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2222   DataArrayDouble *ret=DataArrayDouble::New();
2223   int nbOfTuple=getNumberOfTuples();
2224   ret->alloc(nbOfTuple,nbOfComp);
2225   const double *src=getConstPointer();
2226   double *dest=ret->getPointer();
2227   if(nbOfComp==6)
2228     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2229       {
2230         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];
2231         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2232         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2233         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2234         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2235         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2236         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2237       }
2238   else if(nbOfComp==4)
2239     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2240       {
2241         double det=src[0]*src[3]-src[1]*src[2];
2242         dest[0]=src[3]/det;
2243         dest[1]=-src[1]/det;
2244         dest[2]=-src[2]/det;
2245         dest[3]=src[0]/det;
2246       }
2247   else
2248     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2249       {
2250         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];
2251         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2252         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2253         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2254         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2255         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2256         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2257         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2258         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2259         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2260       }
2261   return ret;
2262 }
2263
2264 /*!
2265  * Computes the trace of every matrix defined by the tuple of \a this
2266  * array, which contains either 4, 6 or 9 components. The case of 6 components
2267  * corresponds to that of the upper triangular matrix.
2268  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
2269  *          1 component, whose each tuple is the trace of
2270  *          the matrix of corresponding tuple of \a this array. 
2271  *          The caller is to delete this result array using decrRef() as it is no more
2272  *          needed. 
2273  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2274  */
2275 DataArrayDouble *DataArrayDouble::trace() const
2276 {
2277   checkAllocated();
2278   int nbOfComp=getNumberOfComponents();
2279   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2280     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2281   DataArrayDouble *ret=DataArrayDouble::New();
2282   int nbOfTuple=getNumberOfTuples();
2283   ret->alloc(nbOfTuple,1);
2284   const double *src=getConstPointer();
2285   double *dest=ret->getPointer();
2286   if(nbOfComp==6)
2287     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2288       *dest=src[0]+src[1]+src[2];
2289   else if(nbOfComp==4)
2290     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2291       *dest=src[0]+src[3];
2292   else
2293     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2294       *dest=src[0]+src[4]+src[8];
2295   return ret;
2296 }
2297
2298 /*!
2299  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2300  * \a this array, which contains 6 components.
2301  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2302  *          same number of components and tuples as \a this array.
2303  *          The caller is to delete this result array using decrRef() as it is no more
2304  *          needed.
2305  *  \throw If \a this->getNumberOfComponents() != 6.
2306  */
2307 DataArrayDouble *DataArrayDouble::deviator() const
2308 {
2309   checkAllocated();
2310   int nbOfComp=getNumberOfComponents();
2311   if(nbOfComp!=6)
2312     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2313   DataArrayDouble *ret=DataArrayDouble::New();
2314   int nbOfTuple=getNumberOfTuples();
2315   ret->alloc(nbOfTuple,6);
2316   const double *src=getConstPointer();
2317   double *dest=ret->getPointer();
2318   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2319     {
2320       double tr=(src[0]+src[1]+src[2])/3.;
2321       dest[0]=src[0]-tr;
2322       dest[1]=src[1]-tr;
2323       dest[2]=src[2]-tr;
2324       dest[3]=src[3];
2325       dest[4]=src[4];
2326       dest[5]=src[5];
2327     }
2328   return ret;
2329 }
2330
2331 /*!
2332  * Computes the magnitude of every vector defined by the tuple of
2333  * \a this array.
2334  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2335  *          same number of tuples as \a this array and one component.
2336  *          The caller is to delete this result array using decrRef() as it is no more
2337  *          needed.
2338  *  \throw If \a this is not allocated.
2339  */
2340 DataArrayDouble *DataArrayDouble::magnitude() const
2341 {
2342   checkAllocated();
2343   int nbOfComp=getNumberOfComponents();
2344   DataArrayDouble *ret=DataArrayDouble::New();
2345   int nbOfTuple=getNumberOfTuples();
2346   ret->alloc(nbOfTuple,1);
2347   const double *src=getConstPointer();
2348   double *dest=ret->getPointer();
2349   for(int i=0;i<nbOfTuple;i++,dest++)
2350     {
2351       double sum=0.;
2352       for(int j=0;j<nbOfComp;j++,src++)
2353         sum+=(*src)*(*src);
2354       *dest=sqrt(sum);
2355     }
2356   return ret;
2357 }
2358
2359 /*!
2360  * Computes the maximal value within every tuple of \a this array.
2361  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2362  *          same number of tuples as \a this array and one component.
2363  *          The caller is to delete this result array using decrRef() as it is no more
2364  *          needed.
2365  *  \throw If \a this is not allocated.
2366  *  \sa DataArrayDouble::maxPerTupleWithCompoId
2367  */
2368 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2369 {
2370   checkAllocated();
2371   int nbOfComp=getNumberOfComponents();
2372   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2373   int nbOfTuple=getNumberOfTuples();
2374   ret->alloc(nbOfTuple,1);
2375   const double *src=getConstPointer();
2376   double *dest=ret->getPointer();
2377   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2378     *dest=*std::max_element(src,src+nbOfComp);
2379   return ret.retn();
2380 }
2381
2382 /*!
2383  * Computes the maximal value within every tuple of \a this array and it returns the first component
2384  * id for each tuple that corresponds to the maximal value within the tuple.
2385  * 
2386  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2387  *          same number of tuples and only one component.
2388  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2389  *          same number of tuples as \a this array and one component.
2390  *          The caller is to delete this result array using decrRef() as it is no more
2391  *          needed.
2392  *  \throw If \a this is not allocated.
2393  *  \sa DataArrayDouble::maxPerTuple
2394  */
2395 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2396 {
2397   checkAllocated();
2398   int nbOfComp=getNumberOfComponents();
2399   MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2400   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2401   int nbOfTuple=getNumberOfTuples();
2402   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2403   const double *src=getConstPointer();
2404   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2405   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2406     {
2407       const double *loc=std::max_element(src,src+nbOfComp);
2408       *dest=*loc;
2409       *dest1=(int)std::distance(src,loc);
2410     }
2411   compoIdOfMaxPerTuple=ret1.retn();
2412   return ret0.retn();
2413 }
2414
2415 /*!
2416  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2417  * \n This returned array contains the euclidian distance for each tuple in \a this. 
2418  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2419  * \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)
2420  *
2421  * \warning use this method with care because it can leads to big amount of consumed memory !
2422  * 
2423  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2424  *
2425  * \throw If \a this is not allocated.
2426  *
2427  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2428  */
2429 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2430 {
2431   checkAllocated();
2432   int nbOfComp=getNumberOfComponents();
2433   int nbOfTuples=getNumberOfTuples();
2434   const double *inData=getConstPointer();
2435   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2436   ret->alloc(nbOfTuples*nbOfTuples,1);
2437   double *outData=ret->getPointer();
2438   for(int i=0;i<nbOfTuples;i++)
2439     {
2440       outData[i*nbOfTuples+i]=0.;
2441       for(int j=i+1;j<nbOfTuples;j++)
2442         {
2443           double dist=0.;
2444           for(int k=0;k<nbOfComp;k++)
2445             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2446           dist=sqrt(dist);
2447           outData[i*nbOfTuples+j]=dist;
2448           outData[j*nbOfTuples+i]=dist;
2449         }
2450     }
2451   return ret.retn();
2452 }
2453
2454 /*!
2455  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2456  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
2457  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2458  * \n Output rectangular matrix is sorted along rows.
2459  * \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)
2460  *
2461  * \warning use this method with care because it can leads to big amount of consumed memory !
2462  * 
2463  * \param [in] other DataArrayDouble instance having same number of components than \a this.
2464  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2465  *
2466  * \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.
2467  *
2468  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2469  */
2470 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2471 {
2472   if(!other)
2473     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2474   checkAllocated();
2475   other->checkAllocated();
2476   int nbOfComp=getNumberOfComponents();
2477   int otherNbOfComp=other->getNumberOfComponents();
2478   if(nbOfComp!=otherNbOfComp)
2479     {
2480       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2481       throw INTERP_KERNEL::Exception(oss.str().c_str());
2482     }
2483   int nbOfTuples=getNumberOfTuples();
2484   int otherNbOfTuples=other->getNumberOfTuples();
2485   const double *inData=getConstPointer();
2486   const double *inDataOther=other->getConstPointer();
2487   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2488   ret->alloc(otherNbOfTuples*nbOfTuples,1);
2489   double *outData=ret->getPointer();
2490   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2491     {
2492       for(int j=0;j<nbOfTuples;j++)
2493         {
2494           double dist=0.;
2495           for(int k=0;k<nbOfComp;k++)
2496             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2497           dist=sqrt(dist);
2498           outData[i*nbOfTuples+j]=dist;
2499         }
2500     }
2501   return ret.retn();
2502 }
2503
2504 /*!
2505  * This method expects that \a this stores 3 tuples containing 2 components each.
2506  * Each of this tuples represent a point into 2D space.
2507  * 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).
2508  * 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[.
2509  *  
2510  *  \throw If \a this is not allocated.
2511  *  \throw If \a this has not 3 tuples of 2 components
2512  *  \throw If tuples/points in \a this are aligned
2513  */
2514 void DataArrayDouble::asArcOfCircle(double center[2], double& radius, double& ang) const
2515 {
2516   checkAllocated();
2517   INTERP_KERNEL::QuadraticPlanarPrecision arcPrec(1e-14);
2518   if(getNumberOfTuples()!=3 && getNumberOfComponents()!=2)
2519     throw INTERP_KERNEL::Exception("DataArrayDouble::asArcCircle : this method expects");
2520   const double *pt(begin());
2521   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]));
2522   {
2523     INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::EdgeLin> e1(new INTERP_KERNEL::EdgeLin(n0,n2)),e2(new INTERP_KERNEL::EdgeLin(n2,n1));
2524     INTERP_KERNEL::SegSegIntersector inters(*e1,*e2);
2525     bool colinearity(inters.areColinears());
2526     if(colinearity)
2527       throw INTERP_KERNEL::Exception("DataArrayDouble::asArcOfCircle : 3 points in this have been detected as colinear !");
2528   }
2529   INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::EdgeArcCircle> ret(new INTERP_KERNEL::EdgeArcCircle(n0,n2,n1));
2530   const double *c(ret->getCenter());
2531   center[0]=c[0]; center[1]=c[1];
2532   radius=ret->getRadius();
2533   ang=ret->getAngle();
2534 }
2535
2536 /*!
2537  * Sorts value within every tuple of \a this array.
2538  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
2539  *              in descending order.
2540  *  \throw If \a this is not allocated.
2541  */
2542 void DataArrayDouble::sortPerTuple(bool asc)
2543 {
2544   checkAllocated();
2545   double *pt=getPointer();
2546   int nbOfTuple=getNumberOfTuples();
2547   int nbOfComp=getNumberOfComponents();
2548   if(asc)
2549     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2550       std::sort(pt,pt+nbOfComp);
2551   else
2552     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2553       std::sort(pt,pt+nbOfComp,std::greater<double>());
2554   declareAsNew();
2555 }
2556
2557 /*!
2558  * Modify all elements of \a this array, so that
2559  * an element _x_ becomes \f$ numerator / x \f$.
2560  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
2561  *           array, all elements processed before detection of the zero element remain
2562  *           modified.
2563  *  \param [in] numerator - the numerator used to modify array elements.
2564  *  \throw If \a this is not allocated.
2565  *  \throw If there is an element equal to 0.0 in \a this array.
2566  */
2567 void DataArrayDouble::applyInv(double numerator)
2568 {
2569   checkAllocated();
2570   double *ptr=getPointer();
2571   std::size_t nbOfElems=getNbOfElems();
2572   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2573     {
2574       if(std::abs(*ptr)>std::numeric_limits<double>::min())
2575         {
2576           *ptr=numerator/(*ptr);
2577         }
2578       else
2579         {
2580           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2581           oss << " !";
2582           throw INTERP_KERNEL::Exception(oss.str().c_str());
2583         }
2584     }
2585   declareAsNew();
2586 }
2587
2588 /*!
2589  * Modify all elements of \a this array, so that
2590  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2591  * all values in \a this have to be >= 0 if val is \b not integer.
2592  *  \param [in] val - the value used to apply pow on all array elements.
2593  *  \throw If \a this is not allocated.
2594  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2595  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
2596  *           modified.
2597  */
2598 void DataArrayDouble::applyPow(double val)
2599 {
2600   checkAllocated();
2601   double *ptr=getPointer();
2602   std::size_t nbOfElems=getNbOfElems();
2603   int val2=(int)val;
2604   bool isInt=((double)val2)==val;
2605   if(!isInt)
2606     {
2607       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2608         {
2609           if(*ptr>=0)
2610             *ptr=pow(*ptr,val);
2611           else
2612             {
2613               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2614               throw INTERP_KERNEL::Exception(oss.str().c_str());
2615             }
2616         }
2617     }
2618   else
2619     {
2620       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2621         *ptr=pow(*ptr,val2);
2622     }
2623   declareAsNew();
2624 }
2625
2626 /*!
2627  * Modify all elements of \a this array, so that
2628  * an element _x_ becomes \f$ val ^ x \f$.
2629  *  \param [in] val - the value used to apply pow on all array elements.
2630  *  \throw If \a this is not allocated.
2631  *  \throw If \a val < 0.
2632  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2633  *           array, all elements processed before detection of the zero element remain
2634  *           modified.
2635  */
2636 void DataArrayDouble::applyRPow(double val)
2637 {
2638   checkAllocated();
2639   if(val<0.)
2640     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2641   double *ptr=getPointer();
2642   std::size_t nbOfElems=getNbOfElems();
2643   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2644     *ptr=pow(val,*ptr);
2645   declareAsNew();
2646 }
2647
2648 /*!
2649  * Returns a new DataArrayDouble created from \a this one by applying \a
2650  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2651  * For more info see \ref MEDCouplingArrayApplyFunc
2652  *  \param [in] nbOfComp - number of components in the result array.
2653  *  \param [in] func - the \a FunctionToEvaluate declared as 
2654  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
2655  *              where \a pos points to the first component of a tuple of \a this array
2656  *              and \a res points to the first component of a tuple of the result array.
2657  *              Note that length (number of components) of \a pos can differ from
2658  *              that of \a res.
2659  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2660  *          same number of tuples as \a this array.
2661  *          The caller is to delete this result array using decrRef() as it is no more
2662  *          needed.
2663  *  \throw If \a this is not allocated.
2664  *  \throw If \a func returns \a false.
2665  */
2666 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2667 {
2668   checkAllocated();
2669   DataArrayDouble *newArr=DataArrayDouble::New();
2670   int nbOfTuples=getNumberOfTuples();
2671   int oldNbOfComp=getNumberOfComponents();
2672   newArr->alloc(nbOfTuples,nbOfComp);
2673   const double *ptr=getConstPointer();
2674   double *ptrToFill=newArr->getPointer();
2675   for(int i=0;i<nbOfTuples;i++)
2676     {
2677       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2678         {
2679           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2680           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2681           oss << ") : Evaluation of function failed !";
2682           newArr->decrRef();
2683           throw INTERP_KERNEL::Exception(oss.str().c_str());
2684         }
2685     }
2686   return newArr;
2687 }
2688
2689 /*!
2690  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2691  * tuple of \a this array. Textual data is not copied.
2692  * For more info see \ref MEDCouplingArrayApplyFunc1.
2693  *  \param [in] nbOfComp - number of components in the result array.
2694  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2695  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2696  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2697  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2698  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2699  *          same number of tuples as \a this array and \a nbOfComp components.
2700  *          The caller is to delete this result array using decrRef() as it is no more
2701  *          needed.
2702  *  \throw If \a this is not allocated.
2703  *  \throw If computing \a func fails.
2704  */
2705 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2706 {
2707   INTERP_KERNEL::ExprParser expr(func);
2708   expr.parse();
2709   std::set<std::string> vars;
2710   expr.getTrueSetOfVars(vars);
2711   std::vector<std::string> varsV(vars.begin(),vars.end());
2712   return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2713 }
2714
2715 /*!
2716  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2717  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2718  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2719  *
2720  * For more info see \ref MEDCouplingArrayApplyFunc0.
2721  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2722  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2723  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2724  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
2725  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2726  *          same number of tuples and components as \a this array.
2727  *          The caller is to delete this result array using decrRef() as it is no more
2728  *          needed.
2729  *  \sa applyFuncOnThis
2730  *  \throw If \a this is not allocated.
2731  *  \throw If computing \a func fails.
2732  */
2733 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
2734 {
2735   int nbOfComp(getNumberOfComponents());
2736   if(nbOfComp<=0)
2737     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
2738   checkAllocated();
2739   int nbOfTuples(getNumberOfTuples());
2740   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2741   newArr->alloc(nbOfTuples,nbOfComp);
2742   INTERP_KERNEL::ExprParser expr(func);
2743   expr.parse();
2744   std::set<std::string> vars;
2745   expr.getTrueSetOfVars(vars);
2746   if((int)vars.size()>1)
2747     {
2748       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 : ";
2749       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2750       throw INTERP_KERNEL::Exception(oss.str().c_str());
2751     }
2752   if(vars.empty())
2753     {
2754       expr.prepareFastEvaluator();
2755       newArr->rearrange(1);
2756       newArr->fillWithValue(expr.evaluateDouble());
2757       newArr->rearrange(nbOfComp);
2758       return newArr.retn();
2759     }
2760   std::vector<std::string> vars2(vars.begin(),vars.end());
2761   double buff,*ptrToFill(newArr->getPointer());
2762   const double *ptr(begin());
2763   std::vector<double> stck;
2764   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2765   expr.prepareFastEvaluator();
2766   if(!isSafe)
2767     {
2768       for(int i=0;i<nbOfTuples;i++)
2769         {
2770           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2771             {
2772               buff=*ptr;
2773               expr.evaluateDoubleInternal(stck);
2774               *ptrToFill=stck.back();
2775               stck.pop_back();
2776             }
2777         }
2778     }
2779   else
2780     {
2781       for(int i=0;i<nbOfTuples;i++)
2782         {
2783           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2784             {
2785               buff=*ptr;
2786               try
2787               {
2788                   expr.evaluateDoubleInternalSafe(stck);
2789               }
2790               catch(INTERP_KERNEL::Exception& e)
2791               {
2792                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2793                   oss << buff;
2794                   oss << ") : Evaluation of function failed !" << e.what();
2795                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2796               }
2797               *ptrToFill=stck.back();
2798               stck.pop_back();
2799             }
2800         }
2801     }
2802   return newArr.retn();
2803 }
2804
2805 /*!
2806  * This method is a non const method that modify the array in \a this.
2807  * This method only works on one component array. It means that function \a func must
2808  * contain at most one variable.
2809  * This method is a specialization of applyFunc method with one parameter on one component array.
2810  *
2811  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2812  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2813  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2814  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2815  *
2816  * \sa applyFunc
2817  */
2818 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
2819 {
2820   int nbOfComp(getNumberOfComponents());
2821   if(nbOfComp<=0)
2822     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
2823   checkAllocated();
2824   int nbOfTuples(getNumberOfTuples());
2825   INTERP_KERNEL::ExprParser expr(func);
2826   expr.parse();
2827   std::set<std::string> vars;
2828   expr.getTrueSetOfVars(vars);
2829   if((int)vars.size()>1)
2830     {
2831       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 : ";
2832       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2833       throw INTERP_KERNEL::Exception(oss.str().c_str());
2834     }
2835   if(vars.empty())
2836     {
2837       expr.prepareFastEvaluator();
2838       std::vector<std::string> compInfo(getInfoOnComponents());
2839       rearrange(1);
2840       fillWithValue(expr.evaluateDouble());
2841       rearrange(nbOfComp);
2842       setInfoOnComponents(compInfo);
2843       return ;
2844     }
2845   std::vector<std::string> vars2(vars.begin(),vars.end());
2846   double buff,*ptrToFill(getPointer());
2847   const double *ptr(begin());
2848   std::vector<double> stck;
2849   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2850   expr.prepareFastEvaluator();
2851   if(!isSafe)
2852     {
2853       for(int i=0;i<nbOfTuples;i++)
2854         {
2855           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2856             {
2857               buff=*ptr;
2858               expr.evaluateDoubleInternal(stck);
2859               *ptrToFill=stck.back();
2860               stck.pop_back();
2861             }
2862         }
2863     }
2864   else
2865     {
2866       for(int i=0;i<nbOfTuples;i++)
2867         {
2868           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2869             {
2870               buff=*ptr;
2871               try
2872               {
2873                   expr.evaluateDoubleInternalSafe(stck);
2874               }
2875               catch(INTERP_KERNEL::Exception& e)
2876               {
2877                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2878                   oss << buff;
2879                   oss << ") : Evaluation of function failed !" << e.what();
2880                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2881               }
2882               *ptrToFill=stck.back();
2883               stck.pop_back();
2884             }
2885         }
2886     }
2887 }
2888
2889 /*!
2890  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2891  * tuple of \a this array. Textual data is not copied.
2892  * For more info see \ref MEDCouplingArrayApplyFunc2.
2893  *  \param [in] nbOfComp - number of components in the result array.
2894  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2895  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2896  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2897  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2898  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2899  *          same number of tuples as \a this array.
2900  *          The caller is to delete this result array using decrRef() as it is no more
2901  *          needed.
2902  *  \throw If \a this is not allocated.
2903  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
2904  *  \throw If computing \a func fails.
2905  */
2906 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
2907 {
2908   return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
2909 }
2910
2911 /*!
2912  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2913  * tuple of \a this array. Textual data is not copied.
2914  * For more info see \ref MEDCouplingArrayApplyFunc3.
2915  *  \param [in] nbOfComp - number of components in the result array.
2916  *  \param [in] varsOrder - sequence of vars defining their order.
2917  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2918  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2919  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2920  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2921  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2922  *          same number of tuples as \a this array.
2923  *          The caller is to delete this result array using decrRef() as it is no more
2924  *          needed.
2925  *  \throw If \a this is not allocated.
2926  *  \throw If \a func contains vars not in \a varsOrder.
2927  *  \throw If computing \a func fails.
2928  */
2929 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
2930 {
2931   if(nbOfComp<=0)
2932     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
2933   std::vector<std::string> varsOrder2(varsOrder);
2934   int oldNbOfComp(getNumberOfComponents());
2935   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
2936     varsOrder2.push_back(std::string());
2937   checkAllocated();
2938   int nbOfTuples(getNumberOfTuples());
2939   INTERP_KERNEL::ExprParser expr(func);
2940   expr.parse();
2941   std::set<std::string> vars;
2942   expr.getTrueSetOfVars(vars);
2943   if((int)vars.size()>oldNbOfComp)
2944     {
2945       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
2946       oss << vars.size() << " variables : ";
2947       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2948       throw INTERP_KERNEL::Exception(oss.str().c_str());
2949     }
2950   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2951   newArr->alloc(nbOfTuples,nbOfComp);
2952   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
2953   double *buffPtr(buff),*ptrToFill;
2954   std::vector<double> stck;
2955   for(int iComp=0;iComp<nbOfComp;iComp++)
2956     {
2957       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
2958       expr.prepareFastEvaluator();
2959       const double *ptr(getConstPointer());
2960       ptrToFill=newArr->getPointer()+iComp;
2961       if(!isSafe)
2962         {
2963           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2964             {
2965               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2966               expr.evaluateDoubleInternal(stck);
2967               *ptrToFill=stck.back();
2968               stck.pop_back();
2969             }
2970         }
2971       else
2972         {
2973           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2974             {
2975               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2976               try
2977               {
2978                   expr.evaluateDoubleInternalSafe(stck);
2979                   *ptrToFill=stck.back();
2980                   stck.pop_back();
2981               }
2982               catch(INTERP_KERNEL::Exception& e)
2983               {
2984                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2985                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2986                   oss << ") : Evaluation of function failed !" << e.what();
2987                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2988               }
2989             }
2990         }
2991     }
2992   return newArr.retn();
2993 }
2994
2995 void DataArrayDouble::applyFuncFast32(const std::string& func)
2996 {
2997   checkAllocated();
2998   INTERP_KERNEL::ExprParser expr(func);
2999   expr.parse();
3000   char *funcStr=expr.compileX86();
3001   MYFUNCPTR funcPtr;
3002   *((void **)&funcPtr)=funcStr;//he he...
3003   //
3004   double *ptr=getPointer();
3005   int nbOfComp=getNumberOfComponents();
3006   int nbOfTuples=getNumberOfTuples();
3007   int nbOfElems=nbOfTuples*nbOfComp;
3008   for(int i=0;i<nbOfElems;i++,ptr++)
3009     *ptr=funcPtr(*ptr);
3010   declareAsNew();
3011 }
3012
3013 void DataArrayDouble::applyFuncFast64(const std::string& func)
3014 {
3015   checkAllocated();
3016   INTERP_KERNEL::ExprParser expr(func);
3017   expr.parse();
3018   char *funcStr=expr.compileX86_64();
3019   MYFUNCPTR funcPtr;
3020   *((void **)&funcPtr)=funcStr;//he he...
3021   //
3022   double *ptr=getPointer();
3023   int nbOfComp=getNumberOfComponents();
3024   int nbOfTuples=getNumberOfTuples();
3025   int nbOfElems=nbOfTuples*nbOfComp;
3026   for(int i=0;i<nbOfElems;i++,ptr++)
3027     *ptr=funcPtr(*ptr);
3028   declareAsNew();
3029 }
3030
3031 /*!
3032  * \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.
3033  */
3034 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3035 {
3036   checkAllocated();
3037   if(getNumberOfComponents()!=3)
3038     throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3039   int nbTuples(getNumberOfTuples());
3040   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3041   ret->alloc(nbTuples,3);
3042   Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3043   return ret;
3044 }
3045
3046 DataArrayDoubleIterator *DataArrayDouble::iterator()
3047 {
3048   return new DataArrayDoubleIterator(this);
3049 }
3050
3051 /*!
3052  * Returns a new DataArrayInt containing indices of tuples of \a this one-dimensional
3053  * array whose values are within a given range. Textual data is not copied.
3054  *  \param [in] vmin - a lowest acceptable value (included).
3055  *  \param [in] vmax - a greatest acceptable value (included).
3056  *  \return DataArrayInt * - the new instance of DataArrayInt.
3057  *          The caller is to delete this result array using decrRef() as it is no more
3058  *          needed.
3059  *  \throw If \a this->getNumberOfComponents() != 1.
3060  *
3061  *  \sa DataArrayDouble::findIdsNotInRange
3062  *
3063  *  \if ENABLE_EXAMPLES
3064  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3065  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3066  *  \endif
3067  */
3068 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3069 {
3070   checkAllocated();
3071   if(getNumberOfComponents()!=1)
3072     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3073   const double *cptr(begin());
3074   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3075   int nbOfTuples(getNumberOfTuples());
3076   for(int i=0;i<nbOfTuples;i++,cptr++)
3077     if(*cptr>=vmin && *cptr<=vmax)
3078       ret->pushBackSilent(i);
3079   return ret.retn();
3080 }
3081
3082 /*!
3083  * Returns a new DataArrayInt containing indices of tuples of \a this one-dimensional
3084  * array whose values are not within a given range. Textual data is not copied.
3085  *  \param [in] vmin - a lowest not acceptable value (excluded).
3086  *  \param [in] vmax - a greatest not acceptable value (excluded).
3087  *  \return DataArrayInt * - the new instance of DataArrayInt.
3088  *          The caller is to delete this result array using decrRef() as it is no more
3089  *          needed.
3090  *  \throw If \a this->getNumberOfComponents() != 1.
3091  *
3092  *  \sa DataArrayDouble::findIdsInRange
3093  */
3094 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3095 {
3096   checkAllocated();
3097   if(getNumberOfComponents()!=1)
3098     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3099   const double *cptr(begin());
3100   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3101   int nbOfTuples(getNumberOfTuples());
3102   for(int i=0;i<nbOfTuples;i++,cptr++)
3103     if(*cptr<vmin || *cptr>vmax)
3104       ret->pushBackSilent(i);
3105   return ret.retn();
3106 }
3107
3108 /*!
3109  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3110  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3111  * the number of component in the result array is same as that of each of given arrays.
3112  * Info on components is copied from the first of the given arrays. Number of components
3113  * in the given arrays must be  the same.
3114  *  \param [in] a1 - an array to include in the result array.
3115  *  \param [in] a2 - another array to include in the result array.
3116  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3117  *          The caller is to delete this result array using decrRef() as it is no more
3118  *          needed.
3119  *  \throw If both \a a1 and \a a2 are NULL.
3120  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3121  */
3122 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3123 {
3124   std::vector<const DataArrayDouble *> tmp(2);
3125   tmp[0]=a1; tmp[1]=a2;
3126   return Aggregate(tmp);
3127 }
3128
3129 /*!
3130  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3131  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3132  * the number of component in the result array is same as that of each of given arrays.
3133  * Info on components is copied from the first of the given arrays. Number of components
3134  * in the given arrays must be  the same.
3135  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3136  * not the object itself.
3137  *  \param [in] arr - a sequence of arrays to include in the result array.
3138  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3139  *          The caller is to delete this result array using decrRef() as it is no more
3140  *          needed.
3141  *  \throw If all arrays within \a arr are NULL.
3142  *  \throw If getNumberOfComponents() of arrays within \a arr.
3143  */
3144 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3145 {
3146   std::vector<const DataArrayDouble *> a;
3147   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3148     if(*it4)
3149       a.push_back(*it4);
3150   if(a.empty())
3151     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3152   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3153   std::size_t nbOfComp((*it)->getNumberOfComponents());
3154   int nbt=(*it++)->getNumberOfTuples();
3155   for(int i=1;it!=a.end();it++,i++)
3156     {
3157       if((*it)->getNumberOfComponents()!=nbOfComp)
3158         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3159       nbt+=(*it)->getNumberOfTuples();
3160     }
3161   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3162   ret->alloc(nbt,nbOfComp);
3163   double *pt=ret->getPointer();
3164   for(it=a.begin();it!=a.end();it++)
3165     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3166   ret->copyStringInfoFrom(*(a[0]));
3167   return ret.retn();
3168 }
3169
3170 /*!
3171  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3172  * the i-th tuple of the result array is a sum of products of j-th components of i-th
3173  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3174  * Info on components and name is copied from the first of the given arrays.
3175  * Number of tuples and components in the given arrays must be the same.
3176  *  \param [in] a1 - a given array.
3177  *  \param [in] a2 - another given array.
3178  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3179  *          The caller is to delete this result array using decrRef() as it is no more
3180  *          needed.
3181  *  \throw If either \a a1 or \a a2 is NULL.
3182  *  \throw If any given array is not allocated.
3183  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3184  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3185  */
3186 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3187 {
3188   if(!a1 || !a2)
3189     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3190   a1->checkAllocated();
3191   a2->checkAllocated();
3192   std::size_t nbOfComp(a1->getNumberOfComponents());
3193   if(nbOfComp!=a2->getNumberOfComponents())
3194     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3195   std::size_t nbOfTuple(a1->getNumberOfTuples());
3196   if(nbOfTuple!=a2->getNumberOfTuples())
3197     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3198   DataArrayDouble *ret=DataArrayDouble::New();
3199   ret->alloc(nbOfTuple,1);
3200   double *retPtr=ret->getPointer();
3201   const double *a1Ptr=a1->begin(),*a2Ptr(a2->begin());
3202   for(std::size_t i=0;i<nbOfTuple;i++)
3203     {
3204       double sum=0.;
3205       for(std::size_t j=0;j<nbOfComp;j++)
3206         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3207       retPtr[i]=sum;
3208     }
3209   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3210   ret->setName(a1->getName());
3211   return ret;
3212 }
3213
3214 /*!
3215  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3216  * the i-th tuple of the result array contains 3 components of a vector which is a cross
3217  * product of two vectors defined by the i-th tuples of given arrays.
3218  * Info on components is copied from the first of the given arrays.
3219  * Number of tuples in the given arrays must be the same.
3220  * Number of components in the given arrays must be 3.
3221  *  \param [in] a1 - a given array.
3222  *  \param [in] a2 - another given array.
3223  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3224  *          The caller is to delete this result array using decrRef() as it is no more
3225  *          needed.
3226  *  \throw If either \a a1 or \a a2 is NULL.
3227  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3228  *  \throw If \a a1->getNumberOfComponents() != 3
3229  *  \throw If \a a2->getNumberOfComponents() != 3
3230  */
3231 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3232 {
3233   if(!a1 || !a2)
3234     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3235   std::size_t nbOfComp(a1->getNumberOfComponents());
3236   if(nbOfComp!=a2->getNumberOfComponents())
3237     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3238   if(nbOfComp!=3)
3239     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3240   std::size_t nbOfTuple(a1->getNumberOfTuples());
3241   if(nbOfTuple!=a2->getNumberOfTuples())
3242     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3243   DataArrayDouble *ret=DataArrayDouble::New();
3244   ret->alloc(nbOfTuple,3);
3245   double *retPtr=ret->getPointer();
3246   const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3247   for(std::size_t i=0;i<nbOfTuple;i++)
3248     {
3249       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3250       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3251       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3252     }
3253   ret->copyStringInfoFrom(*a1);
3254   return ret;
3255 }
3256
3257 /*!
3258  * Returns a new DataArrayDouble containing maximal values of two given arrays.
3259  * Info on components is copied from the first of the given arrays.
3260  * Number of tuples and components in the given arrays must be the same.
3261  *  \param [in] a1 - an array to compare values with another one.
3262  *  \param [in] a2 - another array to compare values with the first one.
3263  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3264  *          The caller is to delete this result array using decrRef() as it is no more
3265  *          needed.
3266  *  \throw If either \a a1 or \a a2 is NULL.
3267  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3268  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3269  */
3270 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3271 {
3272   if(!a1 || !a2)
3273     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3274   std::size_t nbOfComp(a1->getNumberOfComponents());
3275   if(nbOfComp!=a2->getNumberOfComponents())
3276     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3277   std::size_t nbOfTuple(a1->getNumberOfTuples());
3278   if(nbOfTuple!=a2->getNumberOfTuples())
3279     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3280   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3281   ret->alloc(nbOfTuple,nbOfComp);
3282   double *retPtr(ret->getPointer());
3283   const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3284   std::size_t nbElem(nbOfTuple*nbOfComp);
3285   for(std::size_t i=0;i<nbElem;i++)
3286     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3287   ret->copyStringInfoFrom(*a1);
3288   return ret.retn();
3289 }
3290
3291 /*!
3292  * Returns a new DataArrayDouble containing minimal values of two given arrays.
3293  * Info on components is copied from the first of the given arrays.
3294  * Number of tuples and components in the given arrays must be the same.
3295  *  \param [in] a1 - an array to compare values with another one.
3296  *  \param [in] a2 - another array to compare values with the first one.
3297  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3298  *          The caller is to delete this result array using decrRef() as it is no more
3299  *          needed.
3300  *  \throw If either \a a1 or \a a2 is NULL.
3301  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3302  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3303  */
3304 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3305 {
3306   if(!a1 || !a2)
3307     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3308   std::size_t nbOfComp(a1->getNumberOfComponents());
3309   if(nbOfComp!=a2->getNumberOfComponents())
3310     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3311   std::size_t nbOfTuple(a1->getNumberOfTuples());
3312   if(nbOfTuple!=a2->getNumberOfTuples())
3313     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3314   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3315   ret->alloc(nbOfTuple,nbOfComp);
3316   double *retPtr(ret->getPointer());
3317   const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3318   std::size_t nbElem(nbOfTuple*nbOfComp);
3319   for(std::size_t i=0;i<nbElem;i++)
3320     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3321   ret->copyStringInfoFrom(*a1);
3322   return ret.retn();
3323 }
3324
3325 /*!
3326  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
3327  * valid cases.
3328  *
3329  *  \param [in] a1 - an array to pow up.
3330  *  \param [in] a2 - another array to sum up.
3331  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3332  *          The caller is to delete this result array using decrRef() as it is no more
3333  *          needed.
3334  *  \throw If either \a a1 or \a a2 is NULL.
3335  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3336  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
3337  *  \throw If there is a negative value in \a a1.
3338  */
3339 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
3340 {
3341   if(!a1 || !a2)
3342     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
3343   int nbOfTuple=a1->getNumberOfTuples();
3344   int nbOfTuple2=a2->getNumberOfTuples();
3345   int nbOfComp=a1->getNumberOfComponents();
3346   int nbOfComp2=a2->getNumberOfComponents();
3347   if(nbOfTuple!=nbOfTuple2)
3348     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
3349   if(nbOfComp!=1 || nbOfComp2!=1)
3350     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
3351   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
3352   const double *ptr1(a1->begin()),*ptr2(a2->begin());
3353   double *ptr=ret->getPointer();
3354   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
3355     {
3356       if(*ptr1>=0)
3357         {
3358           *ptr=pow(*ptr1,*ptr2);
3359         }
3360       else
3361         {
3362           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
3363           throw INTERP_KERNEL::Exception(oss.str().c_str());
3364         }
3365     }
3366   return ret.retn();
3367 }
3368
3369 /*!
3370  * Apply pow on values of another DataArrayDouble to values of \a this one.
3371  *
3372  *  \param [in] other - an array to pow to \a this one.
3373  *  \throw If \a other is NULL.
3374  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
3375  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
3376  *  \throw If there is a negative value in \a this.
3377  */
3378 void DataArrayDouble::powEqual(const DataArrayDouble *other)
3379 {
3380   if(!other)
3381     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
3382   int nbOfTuple=getNumberOfTuples();
3383   int nbOfTuple2=other->getNumberOfTuples();
3384   int nbOfComp=getNumberOfComponents();
3385   int nbOfComp2=other->getNumberOfComponents();
3386   if(nbOfTuple!=nbOfTuple2)
3387     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
3388   if(nbOfComp!=1 || nbOfComp2!=1)
3389     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
3390   double *ptr=getPointer();
3391   const double *ptrc=other->begin();
3392   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
3393     {
3394       if(*ptr>=0)
3395         *ptr=pow(*ptr,*ptrc);
3396       else
3397         {
3398           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
3399           throw INTERP_KERNEL::Exception(oss.str().c_str());
3400         }
3401     }
3402   declareAsNew();
3403 }
3404
3405 /*!
3406  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
3407  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
3408  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
3409  *
3410  * \throw if \a this is not allocated.
3411  * \throw if \a this has not exactly one component.
3412  */
3413 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
3414 {
3415   checkAllocated();
3416   if(getNumberOfComponents()!=1)
3417     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
3418   int nbt(getNumberOfTuples());
3419   std::vector<bool> ret(nbt);
3420   const double *pt(begin());
3421   for(int i=0;i<nbt;i++)
3422     {
3423       if(fabs(pt[i])<eps)
3424         ret[i]=false;
3425       else if(fabs(pt[i]-1.)<eps)
3426         ret[i]=true;
3427       else
3428         {
3429           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
3430           throw INTERP_KERNEL::Exception(oss.str().c_str());
3431         }
3432     }
3433   return ret;
3434 }
3435
3436 /*!
3437  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3438  * Server side.
3439  */
3440 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
3441 {
3442   tinyInfo.resize(2);
3443   if(isAllocated())
3444     {
3445       tinyInfo[0]=getNumberOfTuples();
3446       tinyInfo[1]=getNumberOfComponents();
3447     }
3448   else
3449     {
3450       tinyInfo[0]=-1;
3451       tinyInfo[1]=-1;
3452     }
3453 }
3454
3455 /*!
3456  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3457  * Server side.
3458  */
3459 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
3460 {
3461   if(isAllocated())
3462     {
3463       int nbOfCompo=getNumberOfComponents();
3464       tinyInfo.resize(nbOfCompo+1);
3465       tinyInfo[0]=getName();
3466       for(int i=0;i<nbOfCompo;i++)
3467         tinyInfo[i+1]=getInfoOnComponent(i);
3468     }
3469   else
3470     {
3471       tinyInfo.resize(1);
3472       tinyInfo[0]=getName();
3473     }
3474 }
3475
3476 /*!
3477  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3478  * This method returns if a feeding is needed.
3479  */
3480 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
3481 {
3482   int nbOfTuple=tinyInfoI[0];
3483   int nbOfComp=tinyInfoI[1];
3484   if(nbOfTuple!=-1 || nbOfComp!=-1)
3485     {
3486       alloc(nbOfTuple,nbOfComp);
3487       return true;
3488     }
3489   return false;
3490 }
3491
3492 /*!
3493  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3494  */
3495 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
3496 {
3497   setName(tinyInfoS[0]);
3498   if(isAllocated())
3499     {
3500       int nbOfCompo=getNumberOfComponents();
3501       for(int i=0;i<nbOfCompo;i++)
3502         setInfoOnComponent(i,tinyInfoS[i+1]);
3503     }
3504 }
3505
3506 /*!
3507  * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
3508  * around an axe ( \a center, \a vect) and with angle \a angle.
3509  */
3510 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3511 {
3512   if(!center || !vect)
3513     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
3514   double sina(sin(angle));
3515   double cosa(cos(angle));
3516   double vectorNorm[3];
3517   double matrix[9];
3518   double matrixTmp[9];
3519   double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
3520   if(norm<std::numeric_limits<double>::min())
3521     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
3522   std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
3523   //rotation matrix computation
3524   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;
3525   matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
3526   matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
3527   matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
3528   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
3529   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3530   matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
3531   matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
3532   matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
3533   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
3534   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3535   //rotation matrix computed.
3536   double tmp[3];
3537   for(int i=0; i<nbNodes; i++)
3538     {
3539       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
3540       coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
3541       coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
3542       coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
3543     }
3544 }
3545
3546 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
3547 {
3548   double matrix[9],matrix2[9],matrix3[9];
3549   double vect[3],crossVect[3];
3550   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3551   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3552   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3553   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3554   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3555   matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
3556   matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
3557   matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
3558   matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
3559   matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
3560   matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
3561   for(int i=0;i<3;i++)
3562     for(int j=0;j<3;j++)
3563       {
3564         double val(0.);
3565         for(int k=0;k<3;k++)
3566           val+=matrix[3*i+k]*matrix2[3*k+j];
3567         matrix3[3*i+j]=val;
3568       }
3569   //rotation matrix computed.
3570   double tmp[3];
3571   for(int i=0; i<nbNodes; i++)
3572     {
3573       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
3574       coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
3575       coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
3576       coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
3577     }
3578 }
3579
3580 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
3581 {
3582   double vect[3],crossVect[3];
3583   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3584   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3585   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3586   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3587   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3588   baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
3589   baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
3590   baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
3591 }
3592
3593 /*!
3594  * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
3595  * around the center point \a center and with angle \a angle.
3596  */
3597 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3598 {
3599   double cosa=cos(angle);
3600   double sina=sin(angle);
3601   double matrix[4];
3602   matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
3603   double tmp[2];
3604   for(int i=0; i<nbNodes; i++)
3605     {
3606       std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
3607       coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
3608       coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
3609     }
3610 }
3611
3612 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
3613 {
3614 }
3615
3616 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
3617 {
3618 }
3619
3620
3621 std::string DataArrayDoubleTuple::repr() const
3622 {
3623   std::ostringstream oss; oss.precision(17); oss << "(";
3624   for(int i=0;i<_nb_of_compo-1;i++)
3625     oss << _pt[i] << ", ";
3626   oss << _pt[_nb_of_compo-1] << ")";
3627   return oss.str();
3628 }
3629
3630 double DataArrayDoubleTuple::doubleValue() const
3631 {
3632   return this->zeValue();
3633 }
3634
3635 /*!
3636  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
3637  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
3638  * 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
3639  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
3640  */
3641 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
3642 {
3643   return this->buildDA(nbOfTuples,nbOfCompo);
3644 }
3645
3646 /*!
3647  * Returns a new instance of DataArrayInt. The caller is to delete this array
3648  * using decrRef() as it is no more needed. 
3649  */
3650 DataArrayInt *DataArrayInt::New()
3651 {
3652   return new DataArrayInt;
3653 }
3654
3655 /*!
3656  * Returns the only one value in \a this, if and only if number of elements
3657  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3658  *  \return double - the sole value stored in \a this array.
3659  *  \throw If at least one of conditions stated above is not fulfilled.
3660  */
3661 int DataArrayInt::intValue() const
3662 {
3663   if(isAllocated())
3664     {
3665       if(getNbOfElems()==1)
3666         {
3667           return *getConstPointer();
3668         }
3669       else
3670         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3671     }
3672   else
3673     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3674 }
3675
3676 /*!
3677  * Returns an integer value characterizing \a this array, which is useful for a quick
3678  * comparison of many instances of DataArrayInt.
3679  *  \return int - the hash value.
3680  *  \throw If \a this is not allocated.
3681  */
3682 int DataArrayInt::getHashCode() const
3683 {
3684   checkAllocated();
3685   std::size_t nbOfElems=getNbOfElems();
3686   int ret=nbOfElems*65536;
3687   int delta=3;
3688   if(nbOfElems>48)
3689     delta=nbOfElems/8;
3690   int ret0=0;
3691   const int *pt=begin();
3692   for(std::size_t i=0;i<nbOfElems;i+=delta)
3693     ret0+=pt[i] & 0x1FFF;
3694   return ret+ret0;
3695 }
3696
3697 /*!
3698  * Returns a full copy of \a this. For more info on copying data arrays see
3699  * \ref MEDCouplingArrayBasicsCopyDeep.
3700  *  \return DataArrayInt * - a new instance of DataArrayInt.
3701  */
3702 DataArrayInt32 *DataArrayInt32::deepCopy() const
3703 {
3704   return new DataArrayInt32(*this);
3705 }
3706
3707 /*!
3708  * Returns a textual and human readable representation of \a this instance of
3709  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
3710  * \return std::string - text describing \a this DataArrayInt.
3711  * 
3712  * \sa reprNotTooLong, reprZip
3713  */
3714 std::string DataArrayInt::repr() const
3715 {
3716   std::ostringstream ret;
3717   reprStream(ret);
3718   return ret.str();
3719 }
3720
3721 std::string DataArrayInt::reprZip() const
3722 {
3723   std::ostringstream ret;
3724   reprZipStream(ret);
3725   return ret.str();
3726 }
3727
3728 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
3729 {
3730   static const char SPACE[4]={' ',' ',' ',' '};
3731   checkAllocated();
3732   std::string idt(indent,' ');
3733   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
3734   if(byteArr)
3735     {
3736       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
3737       if(std::string(type)=="Int32")
3738         {
3739           const char *data(reinterpret_cast<const char *>(begin()));
3740           std::size_t sz(getNbOfElems()*sizeof(int));
3741           byteArr->insertAtTheEnd(data,data+sz);
3742           byteArr->insertAtTheEnd(SPACE,SPACE+4);
3743         }
3744       else if(std::string(type)=="Int8")
3745         {
3746           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
3747           std::copy(begin(),end(),(char *)tmp);
3748           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
3749           byteArr->insertAtTheEnd(SPACE,SPACE+4);
3750         }
3751       else if(std::string(type)=="UInt8")
3752         {
3753           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
3754           std::copy(begin(),end(),(unsigned char *)tmp);
3755           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
3756           byteArr->insertAtTheEnd(SPACE,SPACE+4);
3757         }
3758       else
3759         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
3760     }
3761   else
3762     {
3763       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
3764       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
3765     }
3766   ofs << std::endl << idt << "</DataArray>\n";
3767 }
3768
3769 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
3770 {
3771   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
3772   const int *data=getConstPointer();
3773   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
3774   if(nbTuples*nbComp>=1)
3775     {
3776       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
3777       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
3778       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
3779       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
3780     }
3781   else
3782     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
3783   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
3784 }
3785
3786 /*!
3787  * Method that gives a quick overvien of \a this for python.
3788  */
3789 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
3790 {
3791   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
3792   stream << "DataArrayInt C++ instance at " << this << ". ";
3793   if(isAllocated())
3794     {
3795       int nbOfCompo=(int)_info_on_compo.size();
3796       if(nbOfCompo>=1)
3797         {
3798           int nbOfTuples=getNumberOfTuples();
3799           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
3800           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
3801         }
3802       else
3803         stream << "Number of components : 0.";
3804     }
3805   else
3806     stream << "*** No data allocated ****";
3807 }
3808
3809 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
3810 {
3811   const int *data=begin();
3812   int nbOfTuples=getNumberOfTuples();
3813   int nbOfCompo=(int)_info_on_compo.size();
3814   std::ostringstream oss2; oss2 << "[";
3815   std::string oss2Str(oss2.str());
3816   bool isFinished=true;
3817   for(int i=0;i<nbOfTuples && isFinished;i++)
3818     {
3819       if(nbOfCompo>1)
3820         {
3821           oss2 << "(";
3822           for(int j=0;j<nbOfCompo;j++,data++)
3823             {
3824               oss2 << *data;
3825               if(j!=nbOfCompo-1) oss2 << ", ";
3826             }
3827           oss2 << ")";
3828         }
3829       else
3830         oss2 << *data++;
3831       if(i!=nbOfTuples-1) oss2 << ", ";
3832       std::string oss3Str(oss2.str());
3833       if(oss3Str.length()<maxNbOfByteInRepr)
3834         oss2Str=oss3Str;
3835       else
3836         isFinished=false;
3837     }
3838   stream << oss2Str;
3839   if(!isFinished)
3840     stream << "... ";
3841   stream << "]";
3842 }
3843
3844 /*!
3845  * Computes distribution of values of \a this one-dimensional array between given value
3846  * ranges (casts). This method is typically useful for entity number splitting by types,
3847  * for example. 
3848  *  \warning The values contained in \a arrBg should be sorted ascendently. No
3849  *           check of this is be done. If not, the result is not warranted. 
3850  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
3851  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
3852  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
3853  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
3854  *         should be more than every value in \a this array.
3855  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
3856  *              the last value of \a arrBg is \a arrEnd[ -1 ].
3857  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
3858  *         (same number of tuples and components), the caller is to delete 
3859  *         using decrRef() as it is no more needed.
3860  *         This array contains indices of ranges for every value of \a this array. I.e.
3861  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
3862  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
3863  *         this in which cast it holds.
3864  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
3865  *         array, the caller is to delete using decrRef() as it is no more needed.
3866  *         This array contains ranks of values of \a this array within ranges
3867  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
3868  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
3869  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
3870  *         for each tuple its rank inside its cast. The rank is computed as difference
3871  *         between the value and the lowest value of range.
3872  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
3873  *         ranges (casts) to which at least one value of \a this array belongs.
3874  *         Or, in other words, this param contains the casts that \a this contains.
3875  *         The caller is to delete this array using decrRef() as it is no more needed.
3876  *
3877  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
3878  *            the output of this method will be : 
3879  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
3880  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
3881  * - \a castsPresent  : [0,1]
3882  *
3883  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
3884  * range #1 and its rank within this range is 2; etc.
3885  *
3886  *  \throw If \a this->getNumberOfComponents() != 1.
3887  *  \throw If \a arrEnd - arrBg < 2.
3888  *  \throw If any value of \a this is not less than \a arrEnd[-1].
3889  */
3890 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
3891                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
3892 {
3893   checkAllocated();
3894   if(getNumberOfComponents()!=1)
3895     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3896   int nbOfTuples=getNumberOfTuples();
3897   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
3898   if(nbOfCast<2)
3899     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
3900   nbOfCast--;
3901   const int *work=getConstPointer();
3902   typedef std::reverse_iterator<const int *> rintstart;
3903   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
3904   rintstart end2(arrBg);
3905   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
3906   MCAuto<DataArrayInt> ret2=DataArrayInt::New();
3907   MCAuto<DataArrayInt> ret3=DataArrayInt::New();
3908   ret1->alloc(nbOfTuples,1);
3909   ret2->alloc(nbOfTuples,1);
3910   int *ret1Ptr=ret1->getPointer();
3911   int *ret2Ptr=ret2->getPointer();
3912   std::set<std::size_t> castsDetected;
3913   for(int i=0;i<nbOfTuples;i++)
3914     {
3915       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
3916       std::size_t pos=std::distance(bg,res);
3917       std::size_t pos2=nbOfCast-pos;
3918       if(pos2<nbOfCast)
3919         {
3920           ret1Ptr[i]=(int)pos2;
3921           ret2Ptr[i]=work[i]-arrBg[pos2];
3922           castsDetected.insert(pos2);
3923         }
3924       else
3925         {
3926           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
3927           throw INTERP_KERNEL::Exception(oss.str().c_str());
3928         }
3929     }
3930   ret3->alloc((int)castsDetected.size(),1);
3931   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
3932   castArr=ret1.retn();
3933   rankInsideCast=ret2.retn();
3934   castsPresent=ret3.retn();
3935 }
3936
3937 /*!
3938  * 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 ).
3939  * 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 ).
3940  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
3941  *
3942  * \param [out] strt - the start of the range (included) if true is returned.
3943  * \param [out] sttoopp - the end of the range (not included) if true is returned.
3944  * \param [out] stteepp - the step of the range if true is returned.
3945  * \return the verdict of the check.
3946  *
3947  * \sa DataArray::GetNumberOfItemGivenBES
3948  */
3949 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
3950 {
3951   checkAllocated();
3952   if(getNumberOfComponents()!=1)
3953     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
3954   int nbTuples(getNumberOfTuples());
3955   if(nbTuples==0)
3956     { strt=0; sttoopp=0; stteepp=1; return true; }
3957   const int *pt(begin());
3958   strt=*pt; 
3959   if(nbTuples==1)
3960     { sttoopp=strt+1; stteepp=1; return true; }
3961   strt=*pt; sttoopp=pt[nbTuples-1];
3962   if(strt==sttoopp)
3963     return false;
3964   if(sttoopp>strt)
3965     {
3966       sttoopp++;
3967       int a(sttoopp-1-strt),tmp(strt);
3968       if(a%(nbTuples-1)!=0)
3969         return false;
3970       stteepp=a/(nbTuples-1);
3971       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
3972         if(pt[i]!=tmp)
3973           return false;
3974       return true;
3975     }
3976   else
3977     {
3978       sttoopp--;
3979       int a(strt-sttoopp-1),tmp(strt);
3980       if(a%(nbTuples-1)!=0)
3981         return false;
3982       stteepp=-(a/(nbTuples-1));
3983       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
3984         if(pt[i]!=tmp)
3985           return false;
3986       return true;
3987     }
3988 }
3989
3990
3991 /*!
3992  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
3993  * i.e. a current value is used as in index to get a new value from \a indArrBg.
3994  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
3995  *         to \a this array.
3996  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
3997  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
3998  *  \throw If \a this->getNumberOfComponents() != 1
3999  *  \throw If any value of \a this can't be used as a valid index for 
4000  *         [\a indArrBg, \a indArrEnd).
4001  *
4002  *  \sa changeValue, findIdForEach
4003  */
4004 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4005 {
4006   this->checkAllocated();
4007   if(this->getNumberOfComponents()!=1)
4008     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4009   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4010   for(int i=0;i<nbOfTuples;i++,pt++)
4011     {
4012       if(*pt>=0 && *pt<nbElemsIn)
4013         *pt=indArrBg[*pt];
4014       else
4015         {
4016           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4017           throw INTERP_KERNEL::Exception(oss.str());
4018         }
4019     }
4020   this->declareAsNew();
4021 }
4022
4023 void DataArrayInt::transformWithIndArr(const MapKeyVal<int>& m)
4024 {
4025   this->checkAllocated();
4026   if(this->getNumberOfComponents()!=1)
4027     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4028   const std::map<int,int>& dat(m.data());
4029   int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4030   for(int i=0;i<nbOfTuples;i++,pt++)
4031     {
4032       std::map<int,int>::const_iterator it(dat.find(*pt));
4033       if(it!=dat.end())
4034         *pt=(*it).second;
4035       else
4036         {
4037           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !";
4038           throw INTERP_KERNEL::Exception(oss.str());
4039         }
4040     }
4041   this->declareAsNew();
4042 }
4043
4044 /*!
4045  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
4046  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
4047  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
4048  * new value in place \a indArr[ \a v ] is i.
4049  *  \param [in] indArrBg - the array holding indices within the result array to assign
4050  *         indices of values of \a this array pointing to values of \a indArrBg.
4051  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4052  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
4053  *  \return DataArrayInt * - the new instance of DataArrayInt.
4054  *          The caller is to delete this result array using decrRef() as it is no more
4055  *          needed.
4056  *  \throw If \a this->getNumberOfComponents() != 1.
4057  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
4058  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
4059  */
4060 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
4061 {
4062   checkAllocated();
4063   if(getNumberOfComponents()!=1)
4064     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4065   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
4066   int nbOfTuples=getNumberOfTuples();
4067   const int *pt=getConstPointer();
4068   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4069   ret->alloc(nbOfTuples,1);
4070   ret->fillWithValue(-1);
4071   int *tmp=ret->getPointer();
4072   for(int i=0;i<nbOfTuples;i++,pt++)
4073     {
4074       if(*pt>=0 && *pt<nbElemsIn)
4075         {
4076           int pos=indArrBg[*pt];
4077           if(pos>=0 && pos<nbOfTuples)
4078             tmp[pos]=i;
4079           else
4080             {
4081               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
4082               throw INTERP_KERNEL::Exception(oss.str().c_str());
4083             }
4084         }
4085       else
4086         {
4087           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
4088           throw INTERP_KERNEL::Exception(oss.str().c_str());
4089         }
4090     }
4091   return ret.retn();
4092 }
4093
4094 /*!
4095  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4096  * from values of \a this array, which is supposed to contain a renumbering map in 
4097  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
4098  * To know how to use the renumbering maps see \ref numbering.
4099  *  \param [in] newNbOfElem - the number of tuples in the result array.
4100  *  \return DataArrayInt * - the new instance of DataArrayInt.
4101  *          The caller is to delete this result array using decrRef() as it is no more
4102  *          needed.
4103  * 
4104  *  \if ENABLE_EXAMPLES
4105  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
4106  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
4107  *  \endif
4108  */
4109 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
4110 {
4111   MCAuto<DataArrayInt> ret(DataArrayInt::New());
4112   ret->alloc(newNbOfElem,1);
4113   int nbOfOldNodes(this->getNumberOfTuples());
4114   const int *old2New(begin());
4115   int *pt(ret->getPointer());
4116   for(int i=0;i!=nbOfOldNodes;i++)
4117     {
4118       int newp(old2New[i]);
4119       if(newp!=-1)
4120         {
4121           if(newp>=0 && newp<newNbOfElem)
4122             pt[newp]=i;
4123           else
4124             {
4125               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4126               throw INTERP_KERNEL::Exception(oss.str().c_str());
4127             }
4128         }
4129     }
4130   return ret.retn();
4131 }
4132
4133 /*!
4134  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
4135  * 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]
4136  */
4137 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
4138 {
4139   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4140   ret->alloc(newNbOfElem,1);
4141   int nbOfOldNodes=getNumberOfTuples();
4142   const int *old2New=getConstPointer();
4143   int *pt=ret->getPointer();
4144   for(int i=nbOfOldNodes-1;i>=0;i--)
4145     {
4146       int newp(old2New[i]);
4147       if(newp!=-1)
4148         {
4149           if(newp>=0 && newp<newNbOfElem)
4150             pt[newp]=i;
4151           else
4152             {
4153               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4154               throw INTERP_KERNEL::Exception(oss.str().c_str());
4155             }
4156         }
4157     }
4158   return ret.retn();
4159 }
4160
4161 /*!
4162  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4163  * from values of \a this array, which is supposed to contain a renumbering map in 
4164  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4165  * To know how to use the renumbering maps see \ref numbering.
4166  *  \param [in] newNbOfElem - the number of tuples in the result array.
4167  *  \return DataArrayInt * - the new instance of DataArrayInt.
4168  *          The caller is to delete this result array using decrRef() as it is no more
4169  *          needed.
4170  * 
4171  *  \if ENABLE_EXAMPLES
4172  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4173  *
4174  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4175  *  \sa invertArrayN2O2O2NOptimized
4176  *  \endif
4177  */
4178 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
4179 {
4180   checkAllocated();
4181   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4182   ret->alloc(oldNbOfElem,1);
4183   const int *new2Old=getConstPointer();
4184   int *pt=ret->getPointer();
4185   std::fill(pt,pt+oldNbOfElem,-1);
4186   int nbOfNewElems=getNumberOfTuples();
4187   for(int i=0;i<nbOfNewElems;i++)
4188     {
4189       int v(new2Old[i]);
4190       if(v>=0 && v<oldNbOfElem)
4191         pt[v]=i;
4192       else
4193         {
4194           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
4195           throw INTERP_KERNEL::Exception(oss.str().c_str());
4196         }
4197     }
4198   return ret.retn();
4199 }
4200
4201 /*!
4202  * Creates a map, whose contents are computed
4203  * from values of \a this array, which is supposed to contain a renumbering map in 
4204  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4205  * To know how to use the renumbering maps see \ref numbering.
4206  *  \param [in] newNbOfElem - the number of tuples in the result array.
4207  *  \return MapII  - the new instance of Map.
4208  * 
4209  *  \if ENABLE_EXAMPLES
4210  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4211  *
4212  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4213  *  \sa invertArrayN2O2O2N
4214  *  \endif
4215  */
4216 MCAuto< MapKeyVal<int> > DataArrayInt32::invertArrayN2O2O2NOptimized() const
4217 {
4218   checkAllocated();
4219   if(getNumberOfComponents()!=1)
4220     throw INTERP_KERNEL::Exception("DataArrayInt32::invertArrayN2O2O2NOptimized : single component expected !");
4221   MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4222   std::map<int,int>& m(ret->data());
4223   const int *new2Old(begin());
4224   std::size_t nbOfNewElems(this->getNumberOfTuples());
4225   for(std::size_t i=0;i<nbOfNewElems;i++)
4226     {
4227       int v(new2Old[i]);
4228       m[v]=i;
4229     }
4230   return ret;
4231 }
4232
4233 /*!
4234  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4235  * This map, if applied to \a this array, would make it sorted. For example, if
4236  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4237  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4238  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4239  * This method is useful for renumbering (in MED file for example). For more info
4240  * on renumbering see \ref numbering.
4241  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4242  *          array using decrRef() as it is no more needed.
4243  *  \throw If \a this is not allocated.
4244  *  \throw If \a this->getNumberOfComponents() != 1.
4245  *  \throw If there are equal values in \a this array.
4246  */
4247 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
4248 {
4249   checkAllocated();
4250   if(getNumberOfComponents()!=1)
4251     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4252   int nbTuples=getNumberOfTuples();
4253   const int *pt=getConstPointer();
4254   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
4255   DataArrayInt *ret=DataArrayInt::New();
4256   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
4257   return ret;
4258 }
4259
4260 /*!
4261  * 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
4262  * input array \a ids2.
4263  * \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.
4264  * 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
4265  * inversely.
4266  * In case of success both assertion will be true (no throw) :
4267  * \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
4268  * \c ret->transformWithIndArr(ids2)->isEqual(ids1)
4269  *
4270  * \b Example:
4271  * - \a ids1 : [3,1,103,4,6,10,-7,205]
4272  * - \a ids2 : [-7,1,205,10,6,3,103,4]
4273  * - \a return is : [5,1,6,7,4,3,0,2] because ids2[5]==ids1[0], ids2[1]==ids1[1], ids2[6]==ids1[2]...
4274  *
4275  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4276  *          array using decrRef() as it is no more needed.
4277  * \throw If either ids1 or ids2 is null not allocated or not with one components.
4278  * 
4279  * \sa DataArrayInt32::findIdForEach
4280  */
4281 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
4282 {
4283   if(!ids1 || !ids2)
4284     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
4285   if(!ids1->isAllocated() || !ids2->isAllocated())
4286     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
4287   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
4288     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
4289   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
4290     {
4291       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 !";
4292       throw INTERP_KERNEL::Exception(oss.str().c_str());
4293     }
4294   MCAuto<DataArrayInt> p1(ids1->deepCopy());
4295   MCAuto<DataArrayInt> p2(ids2->deepCopy());
4296   p1->sort(true); p2->sort(true);
4297   if(!p1->isEqualWithoutConsideringStr(*p2))
4298     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
4299   p1=ids1->checkAndPreparePermutation();
4300   p2=ids2->checkAndPreparePermutation();
4301   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
4302   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
4303   return p2.retn();
4304 }
4305
4306 /*!
4307  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4308  * onto a set of values of size \a targetNb (\a B). The surjective function is 
4309  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4310  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4311  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4312  * The first of out arrays returns indices of elements of \a this array, grouped by their
4313  * place in the set \a B. The second out array is the index of the first one; it shows how
4314  * many elements of \a A are mapped into each element of \a B. <br>
4315  * For more info on
4316  * mapping and its usage in renumbering see \ref numbering. <br>
4317  * \b Example:
4318  * - \a this: [0,3,2,3,2,2,1,2]
4319  * - \a targetNb: 4
4320  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
4321  * - \a arrI: [0,1,2,6,8]
4322  *
4323  * This result means: <br>
4324  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4325  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4326  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4327  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
4328  * \a arrI[ 2+1 ]]); <br> etc.
4329  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4330  *         than the maximal value of \a A.
4331  *  \param [out] arr - a new instance of DataArrayInt returning indices of
4332  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
4333  *         this array using decrRef() as it is no more needed.
4334  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4335  *         elements of \a this. The caller is to delete this array using decrRef() as it
4336  *         is no more needed.
4337  *  \throw If \a this is not allocated.
4338  *  \throw If \a this->getNumberOfComponents() != 1.
4339  *  \throw If any value in \a this is more or equal to \a targetNb.
4340  */
4341 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
4342 {
4343   checkAllocated();
4344   if(getNumberOfComponents()!=1)
4345     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4346   int nbOfTuples=getNumberOfTuples();
4347   MCAuto<DataArrayInt> ret(DataArrayInt::New());
4348   MCAuto<DataArrayInt> retI(DataArrayInt::New());
4349   retI->alloc(targetNb+1,1);
4350   const int *input=getConstPointer();
4351   std::vector< std::vector<int> > tmp(targetNb);
4352   for(int i=0;i<nbOfTuples;i++)
4353     {
4354       int tmp2=input[i];
4355       if(tmp2>=0 && tmp2<targetNb)
4356         tmp[tmp2].push_back(i);
4357       else
4358         {
4359           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4360           throw INTERP_KERNEL::Exception(oss.str().c_str());
4361         }
4362     }
4363   int *retIPtr=retI->getPointer();
4364   *retIPtr=0;
4365   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4366     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
4367   if(nbOfTuples!=retI->getIJ(targetNb,0))
4368     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4369   ret->alloc(nbOfTuples,1);
4370   int *retPtr=ret->getPointer();
4371   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4372     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4373   arr=ret.retn();
4374   arrI=retI.retn();
4375 }
4376
4377
4378 /*!
4379  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
4380  * from a zip representation of a surjective format (returned e.g. by
4381  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
4382  * for example). The result array minimizes the permutation. <br>
4383  * For more info on renumbering see \ref numbering. <br>
4384  * \b Example: <br>
4385  * - \a nbOfOldTuples: 10 
4386  * - \a arr          : [0,3, 5,7,9]
4387  * - \a arrIBg       : [0,2,5]
4388  * - \a newNbOfTuples: 7
4389  * - result array    : [0,1,2,0,3,4,5,4,6,4]
4390  *
4391  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
4392  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
4393  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
4394  *         (indices of) equal values. Its every element (except the last one) points to
4395  *         the first element of a group of equal values.
4396  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
4397  *          arrIBg is \a arrIEnd[ -1 ].
4398  *  \param [out] newNbOfTuples - number of tuples after surjection application.
4399  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4400  *          array using decrRef() as it is no more needed.
4401  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
4402  */
4403 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
4404 {
4405   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4406   ret->alloc(nbOfOldTuples,1);
4407   int *pt=ret->getPointer();
4408   std::fill(pt,pt+nbOfOldTuples,-1);
4409   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
4410   const int *cIPtr=arrIBg;
4411   for(int i=0;i<nbOfGrps;i++)
4412     pt[arr[cIPtr[i]]]=-(i+2);
4413   int newNb=0;
4414   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
4415     {
4416       if(pt[iNode]<0)
4417         {
4418           if(pt[iNode]==-1)
4419             pt[iNode]=newNb++;
4420           else
4421             {
4422               int grpId=-(pt[iNode]+2);
4423               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
4424                 {
4425                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
4426                     pt[arr[j]]=newNb;
4427                   else
4428                     {
4429                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
4430                       throw INTERP_KERNEL::Exception(oss.str().c_str());
4431                     }
4432                 }
4433               newNb++;
4434             }
4435         }
4436     }
4437   newNbOfTuples=newNb;
4438   return ret.retn();
4439 }
4440
4441 /*!
4442  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4443  * which if applied to \a this array would make it sorted ascendingly.
4444  * For more info on renumbering see \ref numbering. <br>
4445  * \b Example: <br>
4446  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4447  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4448  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
4449  *
4450  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4451  *          array using decrRef() as it is no more needed.
4452  *  \throw If \a this is not allocated.
4453  *  \throw If \a this->getNumberOfComponents() != 1.
4454  */
4455 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
4456 {
4457   checkAllocated();
4458   if(getNumberOfComponents()!=1)
4459     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4460   int nbOfTuples=getNumberOfTuples();
4461   const int *pt=getConstPointer();
4462   std::map<int,int> m;
4463   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4464   ret->alloc(nbOfTuples,1);
4465   int *opt=ret->getPointer();
4466   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4467     {
4468       int val=*pt;
4469       std::map<int,int>::iterator it=m.find(val);
4470       if(it!=m.end())
4471         {
4472           *opt=(*it).second;
4473           (*it).second++;
4474         }
4475       else
4476         {
4477           *opt=0;
4478           m.insert(std::pair<int,int>(val,1));
4479         }
4480     }
4481   int sum=0;
4482   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
4483     {
4484       int vt=(*it).second;
4485       (*it).second=sum;
4486       sum+=vt;
4487     }
4488   pt=getConstPointer();
4489   opt=ret->getPointer();
4490   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4491     *opt+=m[*pt];
4492   //
4493   return ret.retn();
4494 }
4495
4496 /*!
4497  * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4498  * iota(). This method is particularly useful for DataArrayInt instances that represent
4499  * a renumbering array, to check if there is a real need in renumbering.
4500  * This method checks than \a this can be considered as an identity mapping
4501  * of a set having \a sizeExpected elements into itself.
4502  *
4503  *  \param [in] sizeExpected - The number of elements expected.
4504  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4505  *  \throw If \a this is not allocated.
4506  *  \throw If \a this->getNumberOfComponents() != 1.
4507  */
4508 bool DataArrayInt::isIota(int sizeExpected) const
4509 {
4510   checkAllocated();
4511   if(getNumberOfComponents()!=1)
4512     return false;
4513   int nbOfTuples(getNumberOfTuples());
4514   if(nbOfTuples!=sizeExpected)
4515     return false;
4516   const int *pt=getConstPointer();
4517   for(int i=0;i<nbOfTuples;i++,pt++)
4518     if(*pt!=i)
4519       return false;
4520   return true;
4521 }
4522
4523 /*!
4524  * Checks if all values in \a this array are equal to \a val.
4525  *  \param [in] val - value to check equality of array values to.
4526  *  \return bool - \a true if all values are \a val.
4527  *  \throw If \a this is not allocated.
4528  *  \throw If \a this->getNumberOfComponents() != 1
4529  *  \sa DataArrayInt::checkUniformAndGuess
4530  */
4531 bool DataArrayInt::isUniform(int val) const
4532 {
4533   checkAllocated();
4534   if(getNumberOfComponents()!=1)
4535     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4536   const int *w(begin()),*end2(end());
4537   for(;w!=end2;w++)
4538     if(*w!=val)
4539       return false;
4540   return true;
4541 }
4542
4543 /*!
4544  * This method checks that \a this is uniform. If not and exception will be thrown.
4545  * In case of uniformity the corresponding value is returned.
4546  *
4547  * \return int - the unique value contained in this
4548  * \throw If \a this is not allocated.
4549  * \throw If \a this->getNumberOfComponents() != 1
4550  * \throw If \a this is not uniform.
4551  * \sa DataArrayInt::isUniform
4552  */
4553 int DataArrayInt::checkUniformAndGuess() const
4554 {
4555   checkAllocated();
4556   if(getNumberOfComponents()!=1)
4557     throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4558   if(empty())
4559     throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
4560   const int *w(begin()),*end2(end());
4561   int ret(*w);
4562   for(;w!=end2;w++)
4563     if(*w!=ret)
4564       throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
4565   return ret;
4566 }
4567
4568 /*!
4569  * Checks if all values in \a this array are unique.
4570  *  \return bool - \a true if condition above is true
4571  *  \throw If \a this is not allocated.
4572  *  \throw If \a this->getNumberOfComponents() != 1
4573  */
4574 bool DataArrayInt::hasUniqueValues() const
4575 {
4576   checkAllocated();
4577   if(getNumberOfComponents()!=1)
4578     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4579   std::size_t nbOfTuples(getNumberOfTuples());
4580   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
4581   if (s.size() != nbOfTuples)
4582     return false;
4583   return true;
4584 }
4585
4586 /*!
4587  * Copy all components in a specified order from another DataArrayInt.
4588  * The specified components become the first ones in \a this array.
4589  * Both numerical and textual data is copied. The number of tuples in \a this and
4590  * the other array can be different.
4591  *  \param [in] a - the array to copy data from.
4592  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
4593  *              to be copied.
4594  *  \throw If \a a is NULL.
4595  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
4596  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
4597  *
4598  *  \if ENABLE_EXAMPLES
4599  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
4600  *  \endif
4601  */
4602 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
4603 {
4604   if(!a)
4605     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
4606   checkAllocated();
4607   a->checkAllocated();
4608   copyPartOfStringInfoFrom2(compoIds,*a);
4609   std::size_t partOfCompoSz=compoIds.size();
4610   int nbOfCompo=getNumberOfComponents();
4611   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
4612   const int *ac=a->getConstPointer();
4613   int *nc=getPointer();
4614   for(int i=0;i<nbOfTuples;i++)
4615     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
4616       nc[nbOfCompo*i+compoIds[j]]=*ac;
4617 }
4618
4619 DataArrayIntIterator *DataArrayInt::iterator()
4620 {
4621   return new DataArrayIntIterator(this);
4622 }
4623
4624 /*!
4625  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
4626  * given one. The ids are sorted in the ascending order.
4627  *  \param [in] val - the value to find within \a this.
4628  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4629  *          array using decrRef() as it is no more needed.
4630  *  \throw If \a this is not allocated.
4631  *  \throw If \a this->getNumberOfComponents() != 1.
4632  *  \sa DataArrayInt::findIdsEqualTuple
4633  */
4634 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
4635 {
4636   checkAllocated();
4637   if(getNumberOfComponents()!=1)
4638     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
4639   const int *cptr(getConstPointer());
4640   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4641   int nbOfTuples=getNumberOfTuples();
4642   for(int i=0;i<nbOfTuples;i++,cptr++)
4643     if(*cptr==val)
4644       ret->pushBackSilent(i);
4645   return ret.retn();
4646 }
4647
4648 /*!
4649  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
4650  * equal to a given one. 
4651  *  \param [in] val - the value to ignore within \a this.
4652  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4653  *          array using decrRef() as it is no more needed.
4654  *  \throw If \a this is not allocated.
4655  *  \throw If \a this->getNumberOfComponents() != 1.
4656  */
4657 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
4658 {
4659   checkAllocated();
4660   if(getNumberOfComponents()!=1)
4661     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
4662   const int *cptr(getConstPointer());
4663   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4664   int nbOfTuples=getNumberOfTuples();
4665   for(int i=0;i<nbOfTuples;i++,cptr++)
4666     if(*cptr!=val)
4667       ret->pushBackSilent(i);
4668   return ret.retn();
4669 }
4670
4671 /*!
4672  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
4673  * This method is an extension of  DataArrayInt::findIdsEqual method.
4674  *
4675  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
4676  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
4677  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4678  *          array using decrRef() as it is no more needed.
4679  *  \throw If \a this is not allocated.
4680  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
4681  * \throw If \a this->getNumberOfComponents() is equal to 0.
4682  * \sa DataArrayInt::findIdsEqual
4683  */
4684 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
4685 {
4686   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
4687   checkAllocated();
4688   if(getNumberOfComponents()!=nbOfCompoExp)
4689     {
4690       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
4691       throw INTERP_KERNEL::Exception(oss.str().c_str());
4692     }
4693   if(nbOfCompoExp==0)
4694     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
4695   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4696   const int *bg(begin()),*end2(end()),*work(begin());
4697   while(work!=end2)
4698     {
4699       work=std::search(work,end2,tupleBg,tupleEnd);
4700       if(work!=end2)
4701         {
4702           std::size_t pos(std::distance(bg,work));
4703           if(pos%nbOfCompoExp==0)
4704             ret->pushBackSilent(pos/nbOfCompoExp);
4705           work++;
4706         }
4707     }
4708   return ret.retn();
4709 }
4710
4711 /*!
4712  * This method finds for each element \a ELT in [valsBg,valsEnd) elements in \a this equal to it. Associated to ELT
4713  * this method will return the tuple id of last element found. If there is no element in \a this equal to ELT
4714  * an exception will be thrown.
4715  *
4716  * In case of success this[ret]==vals. Samely ret->transformWithIndArr(this->begin(),this->end())==vals.
4717  * Where \a vals is the [valsBg,valsEnd) array and \a ret the array returned by this method.
4718  * This method can be seen as an extension of FindPermutationFromFirstToSecond.
4719  * <br>
4720  * \b Example: <br>
4721  * - \a this: [17,27,2,10,-4,3,12,27,16]
4722  * - \a val : [3,16,-4,27,17]
4723  * - result: [5,8,4,7,0]
4724  *
4725  * \return - An array of size std::distance(valsBg,valsEnd)
4726  *
4727  * \sa DataArrayInt32::FindPermutationFromFirstToSecond
4728  */
4729 MCAuto<DataArrayInt32> DataArrayInt32::findIdForEach(const int *valsBg, const int *valsEnd) const
4730 {
4731   MCAuto<DataArrayInt32> ret(DataArrayInt32::New());
4732   std::size_t nbOfTuplesOut(std::distance(valsBg,valsEnd));
4733   ret->alloc(nbOfTuplesOut,1);
4734   MCAuto< MapKeyVal<int> > zeMap(invertArrayN2O2O2NOptimized());
4735   const std::map<int,int>& dat(zeMap->data());
4736   int *ptToFeed(ret->getPointer());
4737   for(const int *pt=valsBg;pt!=valsEnd;pt++)
4738     {
4739       std::map<int,int>::const_iterator it(dat.find(*pt));
4740       if(it!=dat.end())
4741         *ptToFeed++=(*it).second;
4742       else
4743         {
4744           std::ostringstream oss; oss << "DataArrayInt32::findIdForEach : error for element at place " << std::distance(valsBg,pt);
4745           oss << " of input array value is " << *pt << " which is not in this !";
4746           throw INTERP_KERNEL::Exception(oss.str());
4747         }
4748     }
4749   return ret;
4750 }
4751
4752 /*!
4753  * Assigns \a newValue to all elements holding \a oldValue within \a this
4754  * one-dimensional array.
4755  *  \param [in] oldValue - the value to replace.
4756  *  \param [in] newValue - the value to assign.
4757  *  \return int - number of replacements performed.
4758  *  \throw If \a this is not allocated.
4759  *  \throw If \a this->getNumberOfComponents() != 1.
4760  */
4761 int DataArrayInt::changeValue(int oldValue, int newValue)
4762 {
4763   checkAllocated();
4764   if(getNumberOfComponents()!=1)
4765     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
4766   if(oldValue==newValue)
4767     return 0;
4768   int *start(getPointer()),*end2(start+getNbOfElems());
4769   int ret(0);
4770   for(int *val=start;val!=end2;val++)
4771     {
4772       if(*val==oldValue)
4773         {
4774           *val=newValue;
4775           ret++;
4776         }
4777     }
4778   if(ret>0)
4779     declareAsNew();
4780   return ret;
4781 }
4782
4783 /*!
4784  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
4785  * one of given values.
4786  *  \param [in] valsBg - an array of values to find within \a this array.
4787  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4788  *              the last value of \a valsBg is \a valsEnd[ -1 ].
4789  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4790  *          array using decrRef() as it is no more needed.
4791  *  \throw If \a this->getNumberOfComponents() != 1.
4792  */
4793 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
4794 {
4795   if(getNumberOfComponents()!=1)
4796     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
4797   std::set<int> vals2(valsBg,valsEnd);
4798   const int *cptr(getConstPointer());
4799   std::vector<int> res;
4800   int nbOfTuples(getNumberOfTuples());
4801   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4802   for(int i=0;i<nbOfTuples;i++,cptr++)
4803     if(vals2.find(*cptr)!=vals2.end())
4804       ret->pushBackSilent(i);
4805   return ret.retn();
4806 }
4807
4808 /*!
4809  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
4810  * equal to any of given values.
4811  *  \param [in] valsBg - an array of values to ignore within \a this array.
4812  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4813  *              the last value of \a valsBg is \a valsEnd[ -1 ].
4814  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4815  *          array using decrRef() as it is no more needed.
4816  *  \throw If \a this->getNumberOfComponents() != 1.
4817  */
4818 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
4819 {
4820   if(getNumberOfComponents()!=1)
4821     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
4822   std::set<int> vals2(valsBg,valsEnd);
4823   const int *cptr=getConstPointer();
4824   std::vector<int> res;
4825   int nbOfTuples=getNumberOfTuples();
4826   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4827   for(int i=0;i<nbOfTuples;i++,cptr++)
4828     if(vals2.find(*cptr)==vals2.end())
4829       ret->pushBackSilent(i);
4830   return ret.retn();
4831 }
4832
4833 /*!
4834  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
4835  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4836  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4837  * If any the tuple id is returned. If not -1 is returned.
4838  * 
4839  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4840  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4841  *
4842  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
4843  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
4844  */
4845 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
4846 {
4847   checkAllocated();
4848   int nbOfCompo=getNumberOfComponents();
4849   if(nbOfCompo==0)
4850     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
4851   if(nbOfCompo!=(int)tupl.size())
4852     {
4853       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
4854       throw INTERP_KERNEL::Exception(oss.str().c_str());
4855     }
4856   const int *cptr=getConstPointer();
4857   std::size_t nbOfVals=getNbOfElems();
4858   for(const int *work=cptr;work!=cptr+nbOfVals;)
4859     {
4860       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
4861       if(work!=cptr+nbOfVals)
4862         {
4863           if(std::distance(cptr,work)%nbOfCompo!=0)
4864             work++;
4865           else
4866             return std::distance(cptr,work)/nbOfCompo;
4867         }
4868     }
4869   return -1;
4870 }
4871
4872 /*!
4873  * This method searches the sequence specified in input parameter \b vals in \b this.
4874  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
4875  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
4876  * \sa DataArrayInt::findIdFirstEqualTuple
4877  */
4878 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
4879 {
4880   checkAllocated();
4881   int nbOfCompo=getNumberOfComponents();
4882   if(nbOfCompo!=1)
4883     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
4884   const int *cptr=getConstPointer();
4885   std::size_t nbOfVals=getNbOfElems();
4886   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
4887   if(loc!=cptr+nbOfVals)
4888     return std::distance(cptr,loc);
4889   return -1;
4890 }
4891
4892 /*!
4893  * This method expects to be called when number of components of this is equal to one.
4894  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
4895  * If not any tuple contains \b value -1 is returned.
4896  * \sa DataArrayInt::presenceOfValue
4897  */
4898 int DataArrayInt::findIdFirstEqual(int value) const
4899 {
4900   checkAllocated();
4901   if(getNumberOfComponents()!=1)
4902     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4903   const int *cptr=getConstPointer();
4904   int nbOfTuples=getNumberOfTuples();
4905   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
4906   if(ret!=cptr+nbOfTuples)
4907     return std::distance(cptr,ret);
4908   return -1;
4909 }
4910
4911 /*!
4912  * This method expects to be called when number of components of this is equal to one.
4913  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
4914  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
4915  * \sa DataArrayInt::presenceOfValue
4916  */
4917 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
4918 {
4919   checkAllocated();
4920   if(getNumberOfComponents()!=1)
4921     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4922   std::set<int> vals2(vals.begin(),vals.end());
4923   const int *cptr=getConstPointer();
4924   int nbOfTuples=getNumberOfTuples();
4925   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
4926     if(vals2.find(*w)!=vals2.end())
4927       return std::distance(cptr,w);
4928   return -1;
4929 }
4930
4931 /*!
4932  * This method returns the number of values in \a this that are equals to input parameter \a value.
4933  * This method only works for single component array.
4934  *
4935  * \return a value in [ 0, \c this->getNumberOfTuples() )
4936  *
4937  * \throw If \a this is not allocated
4938  *
4939  */
4940 int DataArrayInt::count(int value) const
4941 {
4942   int ret=0;
4943   checkAllocated();
4944   if(getNumberOfComponents()!=1)
4945     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4946   const int *vals=begin();
4947   int nbOfTuples=getNumberOfTuples();
4948   for(int i=0;i<nbOfTuples;i++,vals++)
4949     if(*vals==value)
4950       ret++;
4951   return ret;
4952 }
4953
4954 /*!
4955  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
4956  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4957  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4958  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4959  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4960  * \sa DataArrayInt::findIdFirstEqualTuple
4961  */
4962 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
4963 {
4964   return findIdFirstEqualTuple(tupl)!=-1;
4965 }
4966
4967
4968 /*!
4969  * Returns \a true if a given value is present within \a this one-dimensional array.
4970  *  \param [in] value - the value to find within \a this array.
4971  *  \return bool - \a true in case if \a value is present within \a this array.
4972  *  \throw If \a this is not allocated.
4973  *  \throw If \a this->getNumberOfComponents() != 1.
4974  *  \sa findIdFirstEqual()
4975  */
4976 bool DataArrayInt::presenceOfValue(int value) const
4977 {
4978   return findIdFirstEqual(value)!=-1;
4979 }
4980
4981 /*!
4982  * This method expects to be called when number of components of this is equal to one.
4983  * This method returns true if it exists a tuple so that the value is contained in \b vals.
4984  * If not any tuple contains one of the values contained in 'vals' false is returned.
4985  * \sa DataArrayInt::findIdFirstEqual
4986  */
4987 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
4988 {
4989   return findIdFirstEqual(vals)!=-1;
4990 }
4991
4992 /*!
4993  * Accumulates values of each component of \a this array.
4994  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
4995  *         by the caller, that is filled by this method with sum value for each
4996  *         component.
4997  *  \throw If \a this is not allocated.
4998  */
4999 void DataArrayInt::accumulate(int *res) const
5000 {
5001   checkAllocated();
5002   const int *ptr=getConstPointer();
5003   int nbTuple=getNumberOfTuples();
5004   int nbComps=getNumberOfComponents();
5005   std::fill(res,res+nbComps,0);
5006   for(int i=0;i<nbTuple;i++)
5007     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
5008 }
5009
5010 int DataArrayInt::accumulate(int compId) const
5011 {
5012   checkAllocated();
5013   const int *ptr=getConstPointer();
5014   int nbTuple=getNumberOfTuples();
5015   int nbComps=getNumberOfComponents();
5016   if(compId<0 || compId>=nbComps)
5017     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
5018   int ret=0;
5019   for(int i=0;i<nbTuple;i++)
5020     ret+=ptr[i*nbComps+compId];
5021   return ret;
5022 }
5023
5024 /*!
5025  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
5026  * The returned array will have same number of components than \a this and number of tuples equal to
5027  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
5028  *
5029  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
5030  *
5031  * \param [in] bgOfIndex - begin (included) of the input index array.
5032  * \param [in] endOfIndex - end (excluded) of the input index array.
5033  * \return DataArrayInt * - the new instance having the same number of components than \a this.
5034  * 
5035  * \throw If bgOfIndex or end is NULL.
5036  * \throw If input index array is not ascendingly sorted.
5037  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
5038  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
5039  */
5040 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
5041 {
5042   if(!bgOfIndex || !endOfIndex)
5043     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
5044   checkAllocated();
5045   int nbCompo=getNumberOfComponents();
5046   int nbOfTuples=getNumberOfTuples();
5047   int sz=(int)std::distance(bgOfIndex,endOfIndex);
5048   if(sz<1)
5049     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
5050   sz--;
5051   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
5052   const int *w=bgOfIndex;
5053   if(*w<0 || *w>=nbOfTuples)
5054     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
5055   const int *srcPt=begin()+(*w)*nbCompo;
5056   int *tmp=ret->getPointer();
5057   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
5058     {
5059       std::fill(tmp,tmp+nbCompo,0);
5060       if(w[1]>=w[0])
5061         {
5062           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
5063             {
5064               if(j>=0 && j<nbOfTuples)
5065                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
5066               else
5067                 {
5068                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
5069                   throw INTERP_KERNEL::Exception(oss.str().c_str());
5070                 }
5071             }
5072         }
5073       else
5074         {
5075           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
5076           throw INTERP_KERNEL::Exception(oss.str().c_str());
5077         }
5078     }
5079   ret->copyStringInfoFrom(*this);
5080   return ret.retn();
5081 }
5082
5083 /*!
5084  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
5085  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
5086  * offsetA2</em> and (2)
5087  * the number of component in the result array is same as that of each of given arrays.
5088  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
5089  * Info on components is copied from the first of the given arrays. Number of components
5090  * in the given arrays must be the same.
5091  *  \param [in] a1 - an array to include in the result array.
5092  *  \param [in] a2 - another array to include in the result array.
5093  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
5094  *  \return DataArrayInt * - the new instance of DataArrayInt.
5095  *          The caller is to delete this result array using decrRef() as it is no more
5096  *          needed.
5097  *  \throw If either \a a1 or \a a2 is NULL.
5098  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
5099  */
5100 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
5101 {
5102   if(!a1 || !a2)
5103     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
5104   std::size_t nbOfComp(a1->getNumberOfComponents());
5105   if(nbOfComp!=a2->getNumberOfComponents())
5106     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
5107   std::size_t nbOfTuple1(a1->getNumberOfTuples()),nbOfTuple2(a2->getNumberOfTuples());
5108   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5109   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
5110   int *pt=std::copy(a1->begin(),a1->end(),ret->getPointer());
5111   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
5112   ret->copyStringInfoFrom(*a1);
5113   return ret.retn();
5114 }
5115
5116 /*!
5117  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
5118  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
5119  * the number of component in the result array is same as that of each of given arrays.
5120  * Info on components is copied from the first of the given arrays. Number of components
5121  * in the given arrays must be  the same.
5122  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
5123  * not the object itself.
5124  *  \param [in] arr - a sequence of arrays to include in the result array.
5125  *  \return DataArrayInt * - the new instance of DataArrayInt.
5126  *          The caller is to delete this result array using decrRef() as it is no more
5127  *          needed.
5128  *  \throw If all arrays within \a arr are NULL.
5129  *  \throw If getNumberOfComponents() of arrays within \a arr.
5130  */
5131 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
5132 {
5133   std::vector<const DataArrayInt *> a;
5134   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5135     if(*it4)
5136       a.push_back(*it4);
5137   if(a.empty())
5138     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
5139   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
5140   std::size_t nbOfComp((*it)->getNumberOfComponents()),nbt((*it++)->getNumberOfTuples());
5141   for(int i=1;it!=a.end();it++,i++)
5142     {
5143       if((*it)->getNumberOfComponents()!=nbOfComp)
5144         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
5145       nbt+=(*it)->getNumberOfTuples();
5146     }
5147   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5148   ret->alloc(nbt,nbOfComp);
5149   int *pt=ret->getPointer();
5150   for(it=a.begin();it!=a.end();it++)
5151     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
5152   ret->copyStringInfoFrom(*(a[0]));
5153   return ret.retn();
5154 }
5155
5156 /*!
5157  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
5158  * A packed index array is an allocated array with one component, and at least one tuple. The first element
5159  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
5160  * 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.
5161  * 
5162  * \return DataArrayInt * - a new object to be managed by the caller.
5163  */
5164 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
5165 {
5166   int retSz=1;
5167   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
5168     {
5169       if(*it4)
5170         {
5171           (*it4)->checkAllocated();
5172           if((*it4)->getNumberOfComponents()!=1)
5173             {
5174               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5175               throw INTERP_KERNEL::Exception(oss.str().c_str());
5176             }
5177           int nbTupl=(*it4)->getNumberOfTuples();
5178           if(nbTupl<1)
5179             {
5180               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5181               throw INTERP_KERNEL::Exception(oss.str().c_str());
5182             }
5183           if((*it4)->front()!=0)
5184             {
5185               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
5186               throw INTERP_KERNEL::Exception(oss.str().c_str());
5187             }
5188           retSz+=nbTupl-1;
5189         }
5190       else
5191         {
5192           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
5193           throw INTERP_KERNEL::Exception(oss.str().c_str());
5194         }
5195     }
5196   if(arrs.empty())
5197     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
5198   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5199   ret->alloc(retSz,1);
5200   int *pt=ret->getPointer(); *pt++=0;
5201   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
5202     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
5203   ret->copyStringInfoFrom(*(arrs[0]));
5204   return ret.retn();
5205 }
5206
5207 /*!
5208  * Returns in a single walk in \a this the min value and the max value in \a this.
5209  * \a this is expected to be single component array.
5210  *
5211  * \param [out] minValue - the min value in \a this.
5212  * \param [out] maxValue - the max value in \a this.
5213  *
5214  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5215  */
5216 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
5217 {
5218   checkAllocated();
5219   if(getNumberOfComponents()!=1)
5220     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5221   int nbTuples(getNumberOfTuples());
5222   const int *pt(begin());
5223   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
5224   for(int i=0;i<nbTuples;i++,pt++)
5225     {
5226       if(*pt<minValue)
5227         minValue=*pt;
5228       if(*pt>maxValue)
5229         maxValue=*pt;
5230     }
5231 }
5232
5233 /*!
5234  * Modify all elements of \a this array, so that
5235  * an element _x_ becomes \f$ numerator / x \f$.
5236  *  \warning If an exception is thrown because of presence of 0 element in \a this 
5237  *           array, all elements processed before detection of the zero element remain
5238  *           modified.
5239  *  \param [in] numerator - the numerator used to modify array elements.
5240  *  \throw If \a this is not allocated.
5241  *  \throw If there is an element equal to 0 in \a this array.
5242  */
5243 void DataArrayInt::applyInv(int numerator)
5244 {
5245   checkAllocated();
5246   int *ptr=getPointer();
5247   std::size_t nbOfElems=getNbOfElems();
5248   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5249     {
5250       if(*ptr!=0)
5251         {
5252           *ptr=numerator/(*ptr);
5253         }
5254       else
5255         {
5256           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5257           oss << " !";
5258           throw INTERP_KERNEL::Exception(oss.str().c_str());
5259         }
5260     }
5261   declareAsNew();
5262 }
5263
5264 /*!
5265  * Modify all elements of \a this array, so that
5266  * an element _x_ becomes \f$ x / val \f$.
5267  *  \param [in] val - the denominator used to modify array elements.
5268  *  \throw If \a this is not allocated.
5269  *  \throw If \a val == 0.
5270  */
5271 void DataArrayInt::applyDivideBy(int val)
5272 {
5273   if(val==0)
5274     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5275   checkAllocated();
5276   int *ptr=getPointer();
5277   std::size_t nbOfElems=getNbOfElems();
5278   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
5279   declareAsNew();
5280 }
5281
5282 /*!
5283  * Modify all elements of \a this array, so that
5284  * an element _x_ becomes  <em> x % val </em>.
5285  *  \param [in] val - the divisor used to modify array elements.
5286  *  \throw If \a this is not allocated.
5287  *  \throw If \a val <= 0.
5288  */
5289 void DataArrayInt::applyModulus(int val)
5290 {
5291   if(val<=0)
5292     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5293   checkAllocated();
5294   int *ptr=getPointer();
5295   std::size_t nbOfElems=getNbOfElems();
5296   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
5297   declareAsNew();
5298 }
5299
5300 /*!
5301  * This method works only on data array with one component.
5302  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5303  * this[*id] in [\b vmin,\b vmax)
5304  * 
5305  * \param [in] vmin begin of range. This value is included in range (included).
5306  * \param [in] vmax end of range. This value is \b not included in range (excluded).
5307  * \return a newly allocated data array that the caller should deal with.
5308  *
5309  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5310  */
5311 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
5312 {
5313   InRange<int> ir(vmin,vmax);
5314   MCAuto<DataArrayInt> ret(findIdsAdv(ir));
5315   return ret.retn();
5316 }
5317
5318 /*!
5319  * This method works only on data array with one component.
5320  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5321  * this[*id] \b not in [\b vmin,\b vmax)
5322  * 
5323  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5324  * \param [in] vmax end of range. This value is included in range (included).
5325  * \return a newly allocated data array that the caller should deal with.
5326  * 
5327  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5328  */
5329 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
5330 {
5331   NotInRange<int> nir(vmin,vmax);
5332   MCAuto<DataArrayInt> ret(findIdsAdv(nir));
5333   return ret.retn();
5334 }
5335
5336 /*!
5337  * This method works only on data array with one component.
5338  * 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.
5339  * 
5340  * \param [in] vmin begin of range. This value is included in range (included).
5341  * \param [in] vmax end of range. This value is \b not included in range (excluded).
5342  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5343 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
5344 {
5345   checkAllocated();
5346   if(getNumberOfComponents()!=1)
5347     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5348   int nbOfTuples=getNumberOfTuples();
5349   bool ret=true;
5350   const int *cptr=getConstPointer();
5351   for(int i=0;i<nbOfTuples;i++,cptr++)
5352     {
5353       if(*cptr>=vmin && *cptr<vmax)
5354         { ret=ret && *cptr==i; }
5355       else
5356         {
5357           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5358           throw INTERP_KERNEL::Exception(oss.str().c_str());
5359         }
5360     }
5361   return ret;
5362 }
5363
5364 /*!
5365  * Modify all elements of \a this array, so that
5366  * an element _x_ becomes <em> val % x </em>.
5367  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
5368  *           array, all elements processed before detection of the zero element remain
5369  *           modified.
5370  *  \param [in] val - the divident used to modify array elements.
5371  *  \throw If \a this is not allocated.
5372  *  \throw If there is an element equal to or less than 0 in \a this array.
5373  */
5374 void DataArrayInt::applyRModulus(int val)
5375 {
5376   checkAllocated();
5377   int *ptr=getPointer();
5378   std::size_t nbOfElems=getNbOfElems();
5379   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5380     {
5381       if(*ptr>0)
5382         {
5383           *ptr=val%(*ptr);
5384         }
5385       else
5386         {
5387           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5388           oss << " !";
5389           throw INTERP_KERNEL::Exception(oss.str().c_str());
5390         }
5391     }
5392   declareAsNew();
5393 }
5394
5395 /*!
5396  * Modify all elements of \a this array, so that
5397  * an element _x_ becomes <em> val ^ x </em>.
5398  *  \param [in] val - the value used to apply pow on all array elements.
5399  *  \throw If \a this is not allocated.
5400  *  \throw If \a val < 0.
5401  */
5402 void DataArrayInt::applyPow(int val)
5403 {
5404   checkAllocated();
5405   if(val<0)
5406     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5407   int *ptr=getPointer();
5408   std::size_t nbOfElems=getNbOfElems();
5409   if(val==0)
5410     {
5411       std::fill(ptr,ptr+nbOfElems,1);
5412       return ;
5413     }
5414   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5415     {
5416       int tmp=1;
5417       for(int j=0;j<val;j++)
5418         tmp*=*ptr;
5419       *ptr=tmp;
5420     }
5421   declareAsNew();
5422 }
5423
5424 /*!
5425  * Modify all elements of \a this array, so that
5426  * an element _x_ becomes \f$ val ^ x \f$.
5427  *  \param [in] val - the value used to apply pow on all array elements.
5428  *  \throw If \a this is not allocated.
5429  *  \throw If there is an element < 0 in \a this array.
5430  *  \warning If an exception is thrown because of presence of 0 element in \a this 
5431  *           array, all elements processed before detection of the zero element remain
5432  *           modified.
5433  */
5434 void DataArrayInt::applyRPow(int val)
5435 {
5436   checkAllocated();
5437   int *ptr=getPointer();
5438   std::size_t nbOfElems=getNbOfElems();
5439   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5440     {
5441       if(*ptr>=0)
5442         {
5443           int tmp=1;
5444           for(int j=0;j<*ptr;j++)
5445             tmp*=val;
5446           *ptr=tmp;
5447         }
5448       else
5449         {
5450           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5451           oss << " !";
5452           throw INTERP_KERNEL::Exception(oss.str().c_str());
5453         }
5454     }
5455   declareAsNew();
5456 }
5457
5458 /*!
5459  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
5460  * The i-th item of the result array is an ID of a set of elements belonging to a
5461  * unique set of groups, which the i-th element is a part of. This set of elements
5462  * belonging to a unique set of groups is called \a family, so the result array contains
5463  * IDs of families each element belongs to.
5464  *
5465  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
5466  * then there are 3 families:
5467  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
5468  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
5469  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
5470  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
5471  * stands for the element #3 which is in none of groups.
5472  *
5473  *  \param [in] groups - sequence of groups of element IDs.
5474  *  \param [in] newNb - total number of elements; it must be more than max ID of element
5475  *         in \a groups.
5476  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
5477  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
5478  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
5479  *         delete this array using decrRef() as it is no more needed.
5480  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
5481  */
5482 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
5483 {
5484   std::vector<const DataArrayInt *> groups2;
5485   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
5486     if(*it4)
5487       groups2.push_back(*it4);
5488   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5489   ret->alloc(newNb,1);
5490   int *retPtr=ret->getPointer();
5491   std::fill(retPtr,retPtr+newNb,0);
5492   int fid=1;
5493   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
5494     {
5495       const int *ptr=(*iter)->getConstPointer();
5496       std::size_t nbOfElem=(*iter)->getNbOfElems();
5497       int sfid=fid;
5498       for(int j=0;j<sfid;j++)
5499         {
5500           bool found=false;
5501           for(std::size_t i=0;i<nbOfElem;i++)
5502             {
5503               if(ptr[i]>=0 && ptr[i]<newNb)
5504                 {
5505                   if(retPtr[ptr[i]]==j)
5506                     {
5507                       retPtr[ptr[i]]=fid;
5508                       found=true;
5509                     }
5510                 }
5511               else
5512                 {
5513                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
5514                   oss << ") !";
5515                   throw INTERP_KERNEL::Exception(oss.str().c_str());
5516                 }
5517             }
5518           if(found)
5519             fid++;
5520         }
5521     }
5522   fidsOfGroups.clear();
5523   fidsOfGroups.resize(groups2.size());
5524   int grId=0;
5525   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
5526     {
5527       std::set<int> tmp;
5528       const int *ptr=(*iter)->getConstPointer();
5529       std::size_t nbOfElem=(*iter)->getNbOfElems();
5530       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
5531         tmp.insert(retPtr[*p]);
5532       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
5533     }
5534   return ret.retn();
5535 }
5536
5537 /*!
5538  * Returns a new DataArrayInt which contains all elements of given one-dimensional
5539  * arrays. The result array does not contain any duplicates and its values
5540  * are sorted in ascending order.
5541  *  \param [in] arr - sequence of DataArrayInt's to unite.
5542  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5543  *         array using decrRef() as it is no more needed.
5544  *  \throw If any \a arr[i] is not allocated.
5545  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
5546  */
5547 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
5548 {
5549   std::vector<const DataArrayInt *> a;
5550   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5551     if(*it4)
5552       a.push_back(*it4);
5553   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5554     {
5555       (*it)->checkAllocated();
5556       if((*it)->getNumberOfComponents()!=1)
5557         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
5558     }
5559   //
5560   std::set<int> r;
5561   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5562     {
5563       const int *pt=(*it)->getConstPointer();
5564       int nbOfTuples=(*it)->getNumberOfTuples();
5565       r.insert(pt,pt+nbOfTuples);
5566     }
5567   DataArrayInt *ret=DataArrayInt::New();
5568   ret->alloc((int)r.size(),1);
5569   std::copy(r.begin(),r.end(),ret->getPointer());
5570   return ret;
5571 }
5572
5573 /*!
5574  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
5575  * arrays. The result array does not contain any duplicates and its values
5576  * are sorted in ascending order.
5577  *  \param [in] arr - sequence of DataArrayInt's to intersect.
5578  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5579  *         array using decrRef() as it is no more needed.
5580  *  \throw If any \a arr[i] is not allocated.
5581  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
5582  */
5583 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
5584 {
5585   std::vector<const DataArrayInt *> a;
5586   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5587     if(*it4)
5588       a.push_back(*it4);
5589   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5590     {
5591       (*it)->checkAllocated();
5592       if((*it)->getNumberOfComponents()!=1)
5593         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
5594     }
5595   //
5596   std::set<int> r;
5597   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5598     {
5599       const int *pt=(*it)->getConstPointer();
5600       int nbOfTuples=(*it)->getNumberOfTuples();
5601       std::set<int> s1(pt,pt+nbOfTuples);
5602       if(it!=a.begin())
5603         {
5604           std::set<int> r2;
5605           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
5606           r=r2;
5607         }
5608       else
5609         r=s1;
5610     }
5611   DataArrayInt *ret(DataArrayInt::New());
5612   ret->alloc((int)r.size(),1);
5613   std::copy(r.begin(),r.end(),ret->getPointer());
5614   return ret;
5615 }
5616
5617 /// @cond INTERNAL
5618 namespace MEDCouplingImpl
5619 {
5620   class OpSwitchedOn
5621   {
5622   public:
5623     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
5624     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
5625   private:
5626     int *_pt;
5627     int _cnt;
5628   };
5629
5630   class OpSwitchedOff
5631   {
5632   public:
5633     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
5634     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
5635   private:
5636     int *_pt;
5637     int _cnt;
5638   };
5639 }
5640 /// @endcond
5641
5642 /*!
5643  * This method returns the list of ids in ascending mode so that v[id]==true.
5644  */
5645 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
5646 {
5647   int sz((int)std::count(v.begin(),v.end(),true));
5648   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5649   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
5650   return ret.retn();
5651 }
5652
5653 /*!
5654  * This method returns the list of ids in ascending mode so that v[id]==false.
5655  */
5656 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
5657 {
5658   int sz((int)std::count(v.begin(),v.end(),false));
5659   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5660   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
5661   return ret.retn();
5662 }
5663
5664 /*!
5665  * This method allows to put a vector of vector of integer into a more compact data structure (skyline). 
5666  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
5667  *
5668  * \param [in] v the input data structure to be translate into skyline format.
5669  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
5670  * \param [out] dataIndex the second element of the skyline format.
5671  */
5672 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
5673 {
5674   int sz((int)v.size());
5675   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
5676   ret1->alloc(sz+1,1);
5677   int *pt(ret1->getPointer()); *pt=0;
5678   for(int i=0;i<sz;i++,pt++)
5679     pt[1]=pt[0]+(int)v[i].size();
5680   ret0->alloc(ret1->back(),1);
5681   pt=ret0->getPointer();
5682   for(int i=0;i<sz;i++)
5683     pt=std::copy(v[i].begin(),v[i].end(),pt);
5684   data=ret0.retn(); dataIndex=ret1.retn();
5685 }
5686
5687 /*!
5688  * Returns a new DataArrayInt which contains a complement of elements of \a this
5689  * one-dimensional array. I.e. the result array contains all elements from the range [0,
5690  * \a nbOfElement) not present in \a this array.
5691  *  \param [in] nbOfElement - maximal size of the result array.
5692  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5693  *         array using decrRef() as it is no more needed.
5694  *  \throw If \a this is not allocated.
5695  *  \throw If \a this->getNumberOfComponents() != 1.
5696  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
5697  *         nbOfElement ).
5698  */
5699 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
5700 {
5701   checkAllocated();
5702   if(getNumberOfComponents()!=1)
5703     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
5704   std::vector<bool> tmp(nbOfElement);
5705   const int *pt=getConstPointer();
5706   int nbOfTuples=getNumberOfTuples();
5707   for(const int *w=pt;w!=pt+nbOfTuples;w++)
5708     if(*w>=0 && *w<nbOfElement)
5709       tmp[*w]=true;
5710     else
5711       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
5712   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
5713   DataArrayInt *ret=DataArrayInt::New();
5714   ret->alloc(nbOfRetVal,1);
5715   int j=0;
5716   int *retPtr=ret->getPointer();
5717   for(int i=0;i<nbOfElement;i++)
5718     if(!tmp[i])
5719       retPtr[j++]=i;
5720   return ret;
5721 }
5722
5723 /*!
5724  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
5725  * from an \a other one-dimensional array.
5726  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
5727  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
5728  *         caller is to delete this array using decrRef() as it is no more needed.
5729  *  \throw If \a other is NULL.
5730  *  \throw If \a other is not allocated.
5731  *  \throw If \a other->getNumberOfComponents() != 1.
5732  *  \throw If \a this is not allocated.
5733  *  \throw If \a this->getNumberOfComponents() != 1.
5734  *  \sa DataArrayInt::buildSubstractionOptimized()
5735  */
5736 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
5737 {
5738   if(!other)
5739     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
5740   checkAllocated();
5741   other->checkAllocated();
5742   if(getNumberOfComponents()!=1)
5743     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
5744   if(other->getNumberOfComponents()!=1)
5745     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
5746   const int *pt=getConstPointer();
5747   int nbOfTuples=getNumberOfTuples();
5748   std::set<int> s1(pt,pt+nbOfTuples);
5749   pt=other->getConstPointer();
5750   nbOfTuples=other->getNumberOfTuples();
5751   std::set<int> s2(pt,pt+nbOfTuples);
5752   std::vector<int> r;
5753   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
5754   DataArrayInt *ret=DataArrayInt::New();
5755   ret->alloc((int)r.size(),1);
5756   std::copy(r.begin(),r.end(),ret->getPointer());
5757   return ret;
5758 }
5759
5760 /*!
5761  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
5762  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
5763  * 
5764  * \param [in] other an array with one component and expected to be sorted ascendingly.
5765  * \ret list of ids in \a this but not in \a other.
5766  * \sa DataArrayInt::buildSubstraction
5767  */
5768 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
5769 {
5770   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
5771   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
5772   checkAllocated(); other->checkAllocated();
5773   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5774   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5775   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
5776   const int *work1(pt1Bg),*work2(pt2Bg);
5777   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5778   for(;work1!=pt1End;work1++)
5779     {
5780       if(work2!=pt2End && *work1==*work2)
5781         work2++;
5782       else
5783         ret->pushBackSilent(*work1);
5784     }
5785   return ret.retn();
5786 }
5787
5788
5789 /*!
5790  * Returns a new DataArrayInt which contains all elements of \a this and a given
5791  * one-dimensional arrays. The result array does not contain any duplicates
5792  * and its values are sorted in ascending order.
5793  *  \param [in] other - an array to unite with \a this one.
5794  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5795  *         array using decrRef() as it is no more needed.
5796  *  \throw If \a this or \a other is not allocated.
5797  *  \throw If \a this->getNumberOfComponents() != 1.
5798  *  \throw If \a other->getNumberOfComponents() != 1.
5799  */
5800 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
5801 {
5802   std::vector<const DataArrayInt *>arrs(2);
5803   arrs[0]=this; arrs[1]=other;
5804   return BuildUnion(arrs);
5805 }
5806
5807
5808 /*!
5809  * Returns a new DataArrayInt which contains elements present in both \a this and a given
5810  * one-dimensional arrays. The result array does not contain any duplicates
5811  * and its values are sorted in ascending order.
5812  *  \param [in] other - an array to intersect with \a this one.
5813  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5814  *         array using decrRef() as it is no more needed.
5815  *  \throw If \a this or \a other is not allocated.
5816  *  \throw If \a this->getNumberOfComponents() != 1.
5817  *  \throw If \a other->getNumberOfComponents() != 1.
5818  */
5819 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
5820 {
5821   std::vector<const DataArrayInt *>arrs(2);
5822   arrs[0]=this; arrs[1]=other;
5823   return BuildIntersection(arrs);
5824 }
5825
5826 /*!
5827  * This method can be applied on allocated with one component DataArrayInt instance.
5828  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
5829  * 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]
5830  * 
5831  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5832  * \throw if \a this is not allocated or if \a this has not exactly one component.
5833  * \sa DataArrayInt::buildUniqueNotSorted
5834  */
5835 DataArrayInt *DataArrayInt::buildUnique() const
5836 {
5837   checkAllocated();
5838   if(getNumberOfComponents()!=1)
5839     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
5840   int nbOfTuples=getNumberOfTuples();
5841   MCAuto<DataArrayInt> tmp=deepCopy();
5842   int *data=tmp->getPointer();
5843   int *last=std::unique(data,data+nbOfTuples);
5844   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5845   ret->alloc(std::distance(data,last),1);
5846   std::copy(data,last,ret->getPointer());
5847   return ret.retn();
5848 }
5849
5850 /*!
5851  * This method can be applied on allocated with one component DataArrayInt instance.
5852  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
5853  *
5854  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5855  *
5856  * \throw if \a this is not allocated or if \a this has not exactly one component.
5857  *
5858  * \sa DataArrayInt::buildUnique
5859  */
5860 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
5861 {
5862   checkAllocated();
5863     if(getNumberOfComponents()!=1)
5864       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
5865   int minVal,maxVal;
5866   getMinMaxValues(minVal,maxVal);
5867   std::vector<bool> b(maxVal-minVal+1,false);
5868   const int *ptBg(begin()),*endBg(end());
5869   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5870   for(const int *pt=ptBg;pt!=endBg;pt++)
5871     {
5872       if(!b[*pt-minVal])
5873         {
5874           ret->pushBackSilent(*pt);
5875           b[*pt-minVal]=true;
5876         }
5877     }
5878   ret->copyStringInfoFrom(*this);
5879   return ret.retn();
5880 }
5881
5882 /*!
5883  * Returns a new DataArrayInt which contains size of every of groups described by \a this
5884  * "index" array. Such "index" array is returned for example by 
5885  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
5886  * "MEDCouplingUMesh::buildDescendingConnectivity" and
5887  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
5888  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
5889  * This method performs the reverse operation of DataArrayInt::computeOffsetsFull.
5890  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
5891  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
5892  *          The caller is to delete this array using decrRef() as it is no more needed. 
5893  *  \throw If \a this is not allocated.
5894  *  \throw If \a this->getNumberOfComponents() != 1.
5895  *  \throw If \a this->getNumberOfTuples() < 2.
5896  *
5897  *  \b Example: <br> 
5898  *         - this contains [1,3,6,7,7,9,15]
5899  *         - result array contains [2,3,1,0,2,6],
5900  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
5901  *
5902  * \sa DataArrayInt::computeOffsetsFull
5903  */
5904 DataArrayInt *DataArrayInt::deltaShiftIndex() const
5905 {
5906   checkAllocated();
5907   if(getNumberOfComponents()!=1)
5908     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
5909   int nbOfTuples=getNumberOfTuples();
5910   if(nbOfTuples<2)
5911     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
5912   const int *ptr=getConstPointer();
5913   DataArrayInt *ret=DataArrayInt::New();
5914   ret->alloc(nbOfTuples-1,1);
5915   int *out=ret->getPointer();
5916   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
5917   return ret;
5918 }
5919
5920 /*!
5921  * Modifies \a this one-dimensional array so that value of each element \a x
5922  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5923  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
5924  * and components remains the same.<br>
5925  * This method is useful for allToAllV in MPI with contiguous policy. This method
5926  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
5927  * this one.
5928  *  \throw If \a this is not allocated.
5929  *  \throw If \a this->getNumberOfComponents() != 1.
5930  *
5931  *  \b Example: <br>
5932  *          - Before \a this contains [3,5,1,2,0,8]
5933  *          - After \a this contains  [0,3,8,9,11,11]<br>
5934  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
5935  *          array is retained and thus there is no space to store the last element.
5936  */
5937 void DataArrayInt::computeOffsets()
5938 {
5939   checkAllocated();
5940   if(getNumberOfComponents()!=1)
5941     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
5942   int nbOfTuples=getNumberOfTuples();
5943   if(nbOfTuples==0)
5944     return ;
5945   int *work=getPointer();
5946   int tmp=work[0];
5947   work[0]=0;
5948   for(int i=1;i<nbOfTuples;i++)
5949     {
5950       int tmp2=work[i];
5951       work[i]=work[i-1]+tmp;
5952       tmp=tmp2;
5953     }
5954   declareAsNew();
5955 }
5956
5957
5958 /*!
5959  * Modifies \a this one-dimensional array so that value of each element \a x
5960  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5961  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
5962  * components remains the same and number of tuples is inceamented by one.<br>
5963  * This method is useful for allToAllV in MPI with contiguous policy. This method
5964  * differs from computeOffsets() in that the number of tuples is changed by this one.
5965  * This method performs the reverse operation of DataArrayInt::deltaShiftIndex.
5966  *  \throw If \a this is not allocated.
5967  *  \throw If \a this->getNumberOfComponents() != 1.
5968  *
5969  *  \b Example: <br>
5970  *          - Before \a this contains [3,5,1,2,0,8]
5971  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
5972  * \sa DataArrayInt::deltaShiftIndex
5973  */
5974 void DataArrayInt::computeOffsetsFull()
5975 {
5976   checkAllocated();
5977   if(getNumberOfComponents()!=1)
5978     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
5979   int nbOfTuples=getNumberOfTuples();
5980   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
5981   const int *work=getConstPointer();
5982   ret[0]=0;
5983   for(int i=0;i<nbOfTuples;i++)
5984     ret[i+1]=work[i]+ret[i];
5985   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
5986   declareAsNew();
5987 }
5988
5989 /*!
5990  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
5991  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
5992  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
5993  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
5994  * filling completely one of the ranges in \a this.
5995  *
5996  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
5997  * \param [out] rangeIdsFetched the range ids fetched
5998  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
5999  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
6000  *
6001  * \sa DataArrayInt::computeOffsetsFull
6002  *
6003  *  \b Example: <br>
6004  *          - \a this : [0,3,7,9,15,18]
6005  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
6006  *          - \a rangeIdsFetched result array: [0,2,4]
6007  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
6008  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
6009  * <br>
6010  */
6011 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
6012 {
6013   if(!listOfIds)
6014     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
6015   listOfIds->checkAllocated(); checkAllocated();
6016   if(listOfIds->getNumberOfComponents()!=1)
6017     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
6018   if(getNumberOfComponents()!=1)
6019     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
6020   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
6021   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
6022   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
6023   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
6024   while(tupPtr!=tupEnd && offPtr!=offEnd)
6025     {
6026       if(*tupPtr==*offPtr)
6027         {
6028           int i=offPtr[0];
6029           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
6030           if(i==offPtr[1])
6031             {
6032               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
6033               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
6034               offPtr++;
6035             }
6036         }
6037       else
6038         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
6039     }
6040   rangeIdsFetched=ret0.retn();
6041   idsInInputListThatFetch=ret1.retn();
6042 }
6043
6044 /*!
6045  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
6046  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6047  * "index" array of a "iota" array, thus, whose each element gives an index of a group
6048  * beginning within the "iota" array. And \a this is a one-dimensional array
6049  * considered as a selector of groups described by \a offsets to include into the result array.
6050  *  \throw If \a offsets is NULL.
6051  *  \throw If \a offsets is not allocated.
6052  *  \throw If \a offsets->getNumberOfComponents() != 1.
6053  *  \throw If \a offsets is not monotonically increasing.
6054  *  \throw If \a this is not allocated.
6055  *  \throw If \a this->getNumberOfComponents() != 1.
6056  *  \throw If any element of \a this is not a valid index for \a offsets array.
6057  *
6058  *  \b Example: <br>
6059  *          - \a this: [0,2,3]
6060  *          - \a offsets: [0,3,6,10,14,20]
6061  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
6062  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
6063  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
6064  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
6065  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
6066  */
6067 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
6068 {
6069   if(!offsets)
6070     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
6071   checkAllocated();
6072   if(getNumberOfComponents()!=1)
6073     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
6074   offsets->checkAllocated();
6075   if(offsets->getNumberOfComponents()!=1)
6076     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
6077   int othNbTuples=offsets->getNumberOfTuples()-1;
6078   int nbOfTuples=getNumberOfTuples();
6079   int retNbOftuples=0;
6080   const int *work=getConstPointer();
6081   const int *offPtr=offsets->getConstPointer();
6082   for(int i=0;i<nbOfTuples;i++)
6083     {
6084       int val=work[i];
6085       if(val>=0 && val<othNbTuples)
6086         {
6087           int delta=offPtr[val+1]-offPtr[val];
6088           if(delta>=0)
6089             retNbOftuples+=delta;
6090           else
6091             {
6092               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
6093               throw INTERP_KERNEL::Exception(oss.str().c_str());
6094             }
6095         }
6096       else
6097         {
6098           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
6099           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
6100           throw INTERP_KERNEL::Exception(oss.str().c_str());
6101         }
6102     }
6103   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6104   ret->alloc(retNbOftuples,1);
6105   int *retPtr=ret->getPointer();
6106   for(int i=0;i<nbOfTuples;i++)
6107     {
6108       int val=work[i];
6109       int start=offPtr[val];
6110       int off=offPtr[val+1]-start;
6111       for(int j=0;j<off;j++,retPtr++)
6112         *retPtr=start+j;
6113     }
6114   return ret.retn();
6115 }
6116
6117 /*!
6118  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
6119  * scaled array (monotonically increasing).
6120 from that of \a this and \a
6121  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6122  * "index" array of a "iota" array, thus, whose each element gives an index of a group
6123  * beginning within the "iota" array. And \a this is a one-dimensional array
6124  * considered as a selector of groups described by \a offsets to include into the result array.
6125  *  \throw If \a  is NULL.
6126  *  \throw If \a this is not allocated.
6127  *  \throw If \a this->getNumberOfComponents() != 1.
6128  *  \throw If \a this->getNumberOfTuples() == 0.
6129  *  \throw If \a this is not monotonically increasing.
6130  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
6131  *
6132  *  \b Example: <br>
6133  *          - \a bg , \a stop and \a step : (0,5,2)
6134  *          - \a this: [0,3,6,10,14,20]
6135  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
6136  */
6137 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
6138 {
6139   if(!isAllocated())
6140     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
6141   if(getNumberOfComponents()!=1)
6142     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
6143   int nbOfTuples(getNumberOfTuples());
6144   if(nbOfTuples==0)
6145     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
6146   const int *ids(begin());
6147   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
6148   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6149     {
6150       if(pos>=0 && pos<nbOfTuples-1)
6151         {
6152           int delta(ids[pos+1]-ids[pos]);
6153           sz+=delta;
6154           if(delta<0)
6155             {
6156               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
6157               throw INTERP_KERNEL::Exception(oss.str().c_str());
6158             }          
6159         }
6160       else
6161         {
6162           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
6163           throw INTERP_KERNEL::Exception(oss.str().c_str());
6164         }
6165     }
6166   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6167   int *retPtr(ret->getPointer());
6168   pos=bg;
6169   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6170     {
6171       int delta(ids[pos+1]-ids[pos]);
6172       for(int j=0;j<delta;j++,retPtr++)
6173         *retPtr=pos;
6174     }
6175   return ret.retn();
6176 }
6177
6178 /*!
6179  * 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.
6180  * 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
6181  * in tuple **i** of returned DataArrayInt.
6182  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6183  *
6184  * 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)]
6185  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6186  * 
6187  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6188  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6189  * \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
6190  *        is thrown if no ranges in \a ranges contains value in \a this.
6191  * 
6192  * \sa DataArrayInt::findIdInRangeForEachTuple
6193  */
6194 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
6195 {
6196   if(!ranges)
6197     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6198   if(ranges->getNumberOfComponents()!=2)
6199     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6200   checkAllocated();
6201   if(getNumberOfComponents()!=1)
6202     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6203   int nbTuples=getNumberOfTuples();
6204   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6205   int nbOfRanges=ranges->getNumberOfTuples();
6206   const int *rangesPtr=ranges->getConstPointer();
6207   int *retPtr=ret->getPointer();
6208   const int *inPtr=getConstPointer();
6209   for(int i=0;i<nbTuples;i++,retPtr++)
6210     {
6211       int val=inPtr[i];
6212       bool found=false;
6213       for(int j=0;j<nbOfRanges && !found;j++)
6214         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6215           { *retPtr=j; found=true; }
6216       if(found)
6217         continue;
6218       else
6219         {
6220           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6221           throw INTERP_KERNEL::Exception(oss.str().c_str());
6222         }
6223     }
6224   return ret.retn();
6225 }
6226
6227 /*!
6228  * 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.
6229  * 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
6230  * in tuple **i** of returned DataArrayInt.
6231  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6232  *
6233  * 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)]
6234  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6235  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6236  * 
6237  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6238  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6239  * \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
6240  *        is thrown if no ranges in \a ranges contains value in \a this.
6241  * \sa DataArrayInt::findRangeIdForEachTuple
6242  */
6243 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
6244 {
6245   if(!ranges)
6246     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6247   if(ranges->getNumberOfComponents()!=2)
6248     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6249   checkAllocated();
6250   if(getNumberOfComponents()!=1)
6251     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6252   int nbTuples=getNumberOfTuples();
6253   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6254   int nbOfRanges=ranges->getNumberOfTuples();
6255   const int *rangesPtr=ranges->getConstPointer();
6256   int *retPtr=ret->getPointer();
6257   const int *inPtr=getConstPointer();
6258   for(int i=0;i<nbTuples;i++,retPtr++)
6259     {
6260       int val=inPtr[i];
6261       bool found=false;
6262       for(int j=0;j<nbOfRanges && !found;j++)
6263         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6264           { *retPtr=val-rangesPtr[2*j]; found=true; }
6265       if(found)
6266         continue;
6267       else
6268         {
6269           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6270           throw INTERP_KERNEL::Exception(oss.str().c_str());
6271         }
6272     }
6273   return ret.retn();
6274 }
6275
6276 /*!
6277  * \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).
6278  * 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).
6279  * 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 !
6280  * If this method has correctly worked, \a this will be able to be considered as a linked list.
6281  * This method does nothing if number of tuples is lower of equal to 1.
6282  *
6283  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internally the connectibity without any coordinates consideration.
6284  *
6285  * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
6286  */
6287 void DataArrayInt::sortEachPairToMakeALinkedList()
6288 {
6289   checkAllocated();
6290   if(getNumberOfComponents()!=2)
6291     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6292   int nbOfTuples(getNumberOfTuples());
6293   if(nbOfTuples<=1)
6294     return ;
6295   int *conn(getPointer());
6296   for(int i=1;i<nbOfTuples;i++,conn+=2)
6297     {
6298       if(i>1)
6299         {
6300           if(conn[2]==conn[3])
6301             {
6302               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6303               throw INTERP_KERNEL::Exception(oss.str().c_str());
6304             }
6305           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6306             std::swap(conn[2],conn[3]);
6307           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6308           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6309             {
6310               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6311               throw INTERP_KERNEL::Exception(oss.str().c_str());
6312             }
6313         }
6314       else
6315         {
6316           if(conn[0]==conn[1] || conn[2]==conn[3])
6317             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6318           int tmp[4];
6319           std::set<int> s;
6320           s.insert(conn,conn+4);
6321           if(s.size()!=3)
6322             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6323           if(std::count(conn,conn+4,conn[0])==2)
6324             {
6325               tmp[0]=conn[1];
6326               tmp[1]=conn[0];
6327               tmp[2]=conn[0];
6328               if(conn[2]==conn[0])
6329                 { tmp[3]=conn[3]; }
6330               else
6331                 { tmp[3]=conn[2];}
6332               std::copy(tmp,tmp+4,conn);
6333             }
6334           else
6335             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6336               if(conn[1]==conn[3])
6337                 std::swap(conn[2],conn[3]);
6338             }
6339         }
6340     }
6341 }
6342
6343 /*!
6344  * \a this is expected to be a correctly linked list of pairs.
6345  * 
6346  * \sa DataArrayInt::sortEachPairToMakeALinkedList
6347  */
6348 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
6349 {
6350   checkAllocated();
6351   checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6352   int nbTuples(getNumberOfTuples());
6353   if(nbTuples<1)
6354     throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6355   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
6356   const int *thisPtr(begin());
6357   int *retPtr(ret->getPointer());
6358   retPtr[0]=thisPtr[0];
6359   for(int i=0;i<nbTuples;i++)
6360     {
6361       retPtr[i+1]=thisPtr[2*i+1];
6362       if(i<nbTuples-1)
6363         if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6364           {
6365             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 ?";
6366             throw INTERP_KERNEL::Exception(oss.str());
6367           }
6368     }
6369   return ret;
6370 }
6371
6372 /*!
6373  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6374  * But the number of components can be different from one.
6375  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6376  */
6377 DataArrayInt *DataArrayInt::getDifferentValues() const
6378 {
6379   checkAllocated();
6380   std::set<int> ret;
6381   ret.insert(begin(),end());
6382   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
6383   std::copy(ret.begin(),ret.end(),ret2->getPointer());
6384   return ret2.retn();
6385 }
6386
6387 /*!
6388  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6389  * them it tells which tuple id have this id.
6390  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6391  * This method returns two arrays having same size.
6392  * 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.
6393  * 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]]
6394  */
6395 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
6396 {
6397   checkAllocated();
6398   if(getNumberOfComponents()!=1)
6399     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6400   int id=0;
6401   std::map<int,int> m,m2,m3;
6402   for(const int *w=begin();w!=end();w++)
6403     m[*w]++;
6404   differentIds.resize(m.size());
6405   std::vector<DataArrayInt *> ret(m.size());
6406   std::vector<int *> retPtr(m.size());
6407   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
6408     {
6409       m2[(*it).first]=id;
6410       ret[id]=DataArrayInt::New();
6411       ret[id]->alloc((*it).second,1);
6412       retPtr[id]=ret[id]->getPointer();
6413       differentIds[id]=(*it).first;
6414     }
6415   id=0;
6416   for(const int *w=begin();w!=end();w++,id++)
6417     {
6418       retPtr[m2[*w]][m3[*w]++]=id;
6419     }
6420   return ret;
6421 }
6422
6423 /*!
6424  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6425  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6426  *
6427  * \param [in] nbOfSlices - number of slices expected.
6428  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6429  * 
6430  * \sa DataArray::GetSlice
6431  * \throw If \a this is not allocated or not with exactly one component.
6432  * \throw If an element in \a this if < 0.
6433  */
6434 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
6435 {
6436   if(!isAllocated() || getNumberOfComponents()!=1)
6437     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6438   if(nbOfSlices<=0)
6439     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6440   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
6441   int sumPerSlc(sum/nbOfSlices),pos(0);
6442   const int *w(begin());
6443   std::vector< std::pair<int,int> > ret(nbOfSlices);
6444   for(int i=0;i<nbOfSlices;i++)
6445     {
6446       std::pair<int,int> p(pos,-1);
6447       int locSum(0);
6448       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6449       if(i!=nbOfSlices-1)
6450         p.second=pos;
6451       else
6452         p.second=nbOfTuples;
6453       ret[i]=p;
6454     }
6455   return ret;
6456 }
6457
6458 /*!
6459  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6460  * valid cases.
6461  * 1.  The arrays have same number of tuples and components. Then each value of
6462  *   the result array (_a_) is a division of the corresponding values of \a a1 and
6463  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6464  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
6465  *   component. Then
6466  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6467  * 3.  The arrays have same number of components and one array, say _a2_, has one
6468  *   tuple. Then
6469  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6470  *
6471  * Info on components is copied either from the first array (in the first case) or from
6472  * the array with maximal number of elements (getNbOfElems()).
6473  *  \warning No check of division by zero is performed!
6474  *  \param [in] a1 - a dividend array.
6475  *  \param [in] a2 - a divisor array.
6476  *  \return DataArrayInt * - the new instance of DataArrayInt.
6477  *          The caller is to delete this result array using decrRef() as it is no more
6478  *          needed.
6479  *  \throw If either \a a1 or \a a2 is NULL.
6480  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6481  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6482  *         none of them has number of tuples or components equal to 1.
6483  */
6484 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
6485 {
6486   if(!a1 || !a2)
6487     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6488   int nbOfTuple1=a1->getNumberOfTuples();
6489   int nbOfTuple2=a2->getNumberOfTuples();
6490   int nbOfComp1=a1->getNumberOfComponents();
6491   int nbOfComp2=a2->getNumberOfComponents();
6492   if(nbOfTuple2==nbOfTuple1)
6493     {
6494       if(nbOfComp1==nbOfComp2)
6495         {
6496           MCAuto<DataArrayInt> ret=DataArrayInt::New();
6497           ret->alloc(nbOfTuple2,nbOfComp1);
6498           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
6499           ret->copyStringInfoFrom(*a1);
6500           return ret.retn();
6501         }
6502       else if(nbOfComp2==1)
6503         {
6504           MCAuto<DataArrayInt> ret=DataArrayInt::New();
6505           ret->alloc(nbOfTuple1,nbOfComp1);
6506           const int *a2Ptr=a2->getConstPointer();
6507           const int *a1Ptr=a1->getConstPointer();
6508           int *res=ret->getPointer();
6509           for(int i=0;i<nbOfTuple1;i++)
6510             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
6511           ret->copyStringInfoFrom(*a1);
6512           return ret.retn();
6513         }
6514       else
6515         {
6516           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6517           return 0;
6518         }
6519     }
6520   else if(nbOfTuple2==1)
6521     {
6522       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6523       MCAuto<DataArrayInt> ret=DataArrayInt::New();
6524       ret->alloc(nbOfTuple1,nbOfComp1);
6525       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6526       int *pt=ret->getPointer();
6527       for(int i=0;i<nbOfTuple1;i++)
6528         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
6529       ret->copyStringInfoFrom(*a1);
6530       return ret.retn();
6531     }
6532   else
6533     {
6534       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
6535       return 0;
6536     }
6537 }
6538
6539 /*!
6540  * Modify \a this array so that each value becomes a modulus of division of this value by
6541  * a value of another DataArrayInt. There are 3 valid cases.
6542  * 1.  The arrays have same number of tuples and components. Then each value of
6543  *    \a this array is divided by the corresponding value of \a other one, i.e.:
6544  *   _a_ [ i, j ] %= _other_ [ i, j ].
6545  * 2.  The arrays have same number of tuples and \a other array has one component. Then
6546  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
6547  * 3.  The arrays have same number of components and \a other array has one tuple. Then
6548  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
6549  *
6550  *  \warning No check of division by zero is performed!
6551  *  \param [in] other - a divisor array.
6552  *  \throw If \a other is NULL.
6553  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
6554  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
6555  *         \a other has number of both tuples and components not equal to 1.
6556  */
6557 void DataArrayInt::modulusEqual(const DataArrayInt *other)
6558 {
6559   if(!other)
6560     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
6561   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
6562   checkAllocated(); other->checkAllocated();
6563   int nbOfTuple=getNumberOfTuples();
6564   int nbOfTuple2=other->getNumberOfTuples();
6565   int nbOfComp=getNumberOfComponents();
6566   int nbOfComp2=other->getNumberOfComponents();
6567   if(nbOfTuple==nbOfTuple2)
6568     {
6569       if(nbOfComp==nbOfComp2)
6570         {
6571           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
6572         }
6573       else if(nbOfComp2==1)
6574         {
6575           if(nbOfComp2==nbOfComp)
6576             {
6577               int *ptr=getPointer();
6578               const int *ptrc=other->getConstPointer();
6579               for(int i=0;i<nbOfTuple;i++)
6580                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
6581             }
6582           else
6583             throw INTERP_KERNEL::Exception(msg);
6584         }
6585       else
6586         throw INTERP_KERNEL::Exception(msg);
6587     }
6588   else if(nbOfTuple2==1)
6589     {
6590       int *ptr=getPointer();
6591       const int *ptrc=other->getConstPointer();
6592       for(int i=0;i<nbOfTuple;i++)
6593         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
6594     }
6595   else
6596     throw INTERP_KERNEL::Exception(msg);
6597   declareAsNew();
6598 }
6599
6600 /*!
6601  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
6602  * valid cases.
6603  *
6604  *  \param [in] a1 - an array to pow up.
6605  *  \param [in] a2 - another array to sum up.
6606  *  \return DataArrayInt * - the new instance of DataArrayInt.
6607  *          The caller is to delete this result array using decrRef() as it is no more
6608  *          needed.
6609  *  \throw If either \a a1 or \a a2 is NULL.
6610  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6611  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
6612  *  \throw If there is a negative value in \a a2.
6613  */
6614 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
6615 {
6616   if(!a1 || !a2)
6617     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
6618   int nbOfTuple=a1->getNumberOfTuples();
6619   int nbOfTuple2=a2->getNumberOfTuples();
6620   int nbOfComp=a1->getNumberOfComponents();
6621   int nbOfComp2=a2->getNumberOfComponents();
6622   if(nbOfTuple!=nbOfTuple2)
6623     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
6624   if(nbOfComp!=1 || nbOfComp2!=1)
6625     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
6626   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
6627   const int *ptr1(a1->begin()),*ptr2(a2->begin());
6628   int *ptr=ret->getPointer();
6629   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
6630     {
6631       if(*ptr2>=0)
6632         {
6633           int tmp=1;
6634           for(int j=0;j<*ptr2;j++)
6635             tmp*=*ptr1;
6636           *ptr=tmp;
6637         }
6638       else
6639         {
6640           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
6641           throw INTERP_KERNEL::Exception(oss.str().c_str());
6642         }
6643     }
6644   return ret.retn();
6645 }
6646
6647 /*!
6648  * Apply pow on values of another DataArrayInt to values of \a this one.
6649  *
6650  *  \param [in] other - an array to pow to \a this one.
6651  *  \throw If \a other is NULL.
6652  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
6653  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
6654  *  \throw If there is a negative value in \a other.
6655  */
6656 void DataArrayInt::powEqual(const DataArrayInt *other)
6657 {
6658   if(!other)
6659     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
6660   int nbOfTuple=getNumberOfTuples();
6661   int nbOfTuple2=other->getNumberOfTuples();
6662   int nbOfComp=getNumberOfComponents();
6663   int nbOfComp2=other->getNumberOfComponents();
6664   if(nbOfTuple!=nbOfTuple2)
6665     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
6666   if(nbOfComp!=1 || nbOfComp2!=1)
6667     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
6668   int *ptr=getPointer();
6669   const int *ptrc=other->begin();
6670   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
6671     {
6672       if(*ptrc>=0)
6673         {
6674           int tmp=1;
6675           for(int j=0;j<*ptrc;j++)
6676             tmp*=*ptr;
6677           *ptr=tmp;
6678         }
6679       else
6680         {
6681           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
6682           throw INTERP_KERNEL::Exception(oss.str().c_str());
6683         }
6684     }
6685   declareAsNew();
6686 }
6687
6688 /*!
6689  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
6690  * This map, if applied to \a start array, would make it sorted. For example, if
6691  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
6692  * [5,6,0,3,2,7,1,4].
6693  *  \param [in] start - pointer to the first element of the array for which the
6694  *         permutation map is computed.
6695  *  \param [in] end - pointer specifying the end of the array \a start, so that
6696  *         the last value of \a start is \a end[ -1 ].
6697  *  \return int * - the result permutation array that the caller is to delete as it is no
6698  *         more needed.
6699  *  \throw If there are equal values in the input array.
6700  */
6701 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
6702 {
6703   std::size_t sz=std::distance(start,end);
6704   int *ret=(int *)malloc(sz*sizeof(int));
6705   int *work=new int[sz];
6706   std::copy(start,end,work);
6707   std::sort(work,work+sz);
6708   if(std::unique(work,work+sz)!=work+sz)
6709     {
6710       delete [] work;
6711       free(ret);
6712       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
6713     }
6714   std::map<int,int> m;
6715   for(int *workPt=work;workPt!=work+sz;workPt++)
6716     m[*workPt]=(int)std::distance(work,workPt);
6717   int *iter2=ret;
6718   for(const int *iter=start;iter!=end;iter++,iter2++)
6719     *iter2=m[*iter];
6720   delete [] work;
6721   return ret;
6722 }
6723
6724 /*!
6725  * Returns a new DataArrayInt containing an arithmetic progression
6726  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
6727  * function.
6728  *  \param [in] begin - the start value of the result sequence.
6729  *  \param [in] end - limiting value, so that every value of the result array is less than
6730  *              \a end.
6731  *  \param [in] step - specifies the increment or decrement.
6732  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6733  *          array using decrRef() as it is no more needed.
6734  *  \throw If \a step == 0.
6735  *  \throw If \a end < \a begin && \a step > 0.
6736  *  \throw If \a end > \a begin && \a step < 0.
6737  */
6738 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
6739 {
6740   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
6741   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6742   ret->alloc(nbOfTuples,1);
6743   int *ptr=ret->getPointer();
6744   if(step>0)
6745     {
6746       for(int i=begin;i<end;i+=step,ptr++)
6747         *ptr=i;
6748     }
6749   else
6750     {
6751       for(int i=begin;i>end;i+=step,ptr++)
6752         *ptr=i;
6753     }
6754   return ret.retn();
6755 }
6756
6757 /*!
6758  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6759  * Server side.
6760  */
6761 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
6762 {
6763   tinyInfo.resize(2);
6764   if(isAllocated())
6765     {
6766       tinyInfo[0]=getNumberOfTuples();
6767       tinyInfo[1]=getNumberOfComponents();
6768     }
6769   else
6770     {
6771       tinyInfo[0]=-1;
6772       tinyInfo[1]=-1;
6773     }
6774 }
6775
6776 /*!
6777  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6778  * Server side.
6779  */
6780 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
6781 {
6782   if(isAllocated())
6783     {
6784       int nbOfCompo=getNumberOfComponents();
6785       tinyInfo.resize(nbOfCompo+1);
6786       tinyInfo[0]=getName();
6787       for(int i=0;i<nbOfCompo;i++)
6788         tinyInfo[i+1]=getInfoOnComponent(i);
6789     }
6790   else
6791     {
6792       tinyInfo.resize(1);
6793       tinyInfo[0]=getName();
6794     }
6795 }
6796
6797 /*!
6798  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6799  * This method returns if a feeding is needed.
6800  */
6801 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
6802 {
6803   int nbOfTuple=tinyInfoI[0];
6804   int nbOfComp=tinyInfoI[1];
6805   if(nbOfTuple!=-1 || nbOfComp!=-1)
6806     {
6807       alloc(nbOfTuple,nbOfComp);
6808       return true;
6809     }
6810   return false;
6811 }
6812
6813 /*!
6814  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6815  * This method returns if a feeding is needed.
6816  */
6817 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
6818 {
6819   setName(tinyInfoS[0]);
6820   if(isAllocated())
6821     {
6822       int nbOfCompo=tinyInfoI[1];
6823       for(int i=0;i<nbOfCompo;i++)
6824         setInfoOnComponent(i,tinyInfoS[i+1]);
6825     }
6826 }
6827
6828 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
6829 {
6830 }
6831
6832 DataArrayInt32Tuple::DataArrayInt32Tuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
6833 {
6834 }
6835
6836 std::string DataArrayIntTuple::repr() const
6837 {
6838   std::ostringstream oss; oss << "(";
6839   for(int i=0;i<_nb_of_compo-1;i++)
6840     oss << _pt[i] << ", ";
6841   oss << _pt[_nb_of_compo-1] << ")";
6842   return oss.str();
6843 }
6844
6845 int DataArrayIntTuple::intValue() const
6846 {
6847   return this->zeValue();
6848 }
6849
6850 /*!
6851  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
6852  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
6853  * 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
6854  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
6855  */
6856 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
6857 {
6858   return this->buildDA(nbOfTuples,nbOfCompo);
6859 }