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