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