Salome HOME
c70eba32ec646ee8250d64ad6ffb37e3f58b3041
[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 DataArrayTemplate<int>;
40 template class DataArrayTemplate<double>;
41
42 template<int SPACEDIM>
43 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
44 {
45   const double *coordsPtr=getConstPointer();
46   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
47   std::vector<bool> isDone(nbNodes);
48   for(int i=0;i<nbNodes;i++)
49     {
50       if(!isDone[i])
51         {
52           std::vector<int> intersectingElems;
53           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
54           if(intersectingElems.size()>1)
55             {
56               std::vector<int> commonNodes;
57               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
58                 if(*it!=i)
59                   if(*it>=limitNodeId)
60                     {
61                       commonNodes.push_back(*it);
62                       isDone[*it]=true;
63                     }
64               if(!commonNodes.empty())
65                 {
66                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
67                   c->pushBackSilent(i);
68                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
69                 }
70             }
71         }
72     }
73 }
74
75 template<int SPACEDIM>
76 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
77                                                 DataArrayInt *c, DataArrayInt *cI)
78 {
79   for(int i=0;i<nbOfTuples;i++)
80     {
81       std::vector<int> intersectingElems;
82       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
83       std::vector<int> commonNodes;
84       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
85         commonNodes.push_back(*it);
86       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
87       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
88     }
89 }
90
91 template<int SPACEDIM>
92 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
93 {
94   double distOpt(dist);
95   const double *p(pos);
96   int *r(res);
97   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
98     {
99       while(true)
100         {
101           int elem=-1;
102           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
103           if(ret!=std::numeric_limits<double>::max())
104             {
105               distOpt=std::max(ret,1e-4);
106               *r=elem;
107               break;
108             }
109           else
110             { distOpt=2*distOpt; continue; }
111         }
112     }
113 }
114
115 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
116 {
117   std::size_t sz1=_name.capacity();
118   std::size_t sz2=_info_on_compo.capacity();
119   std::size_t sz3=0;
120   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
121     sz3+=(*it).capacity();
122   return sz1+sz2+sz3;
123 }
124
125 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
126 {
127   return std::vector<const BigMemoryObject *>();
128 }
129
130 /*!
131  * Sets the attribute \a _name of \a this array.
132  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
133  *  \param [in] name - new array name
134  */
135 void DataArray::setName(const std::string& name)
136 {
137   _name=name;
138 }
139
140 /*!
141  * Copies textual data from an \a other DataArray. The copied data are
142  * - the name attribute,
143  * - the information of components.
144  *
145  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
146  *
147  *  \param [in] other - another instance of DataArray to copy the textual data from.
148  *  \throw If number of components of \a this array differs from that of the \a other.
149  */
150 void DataArray::copyStringInfoFrom(const DataArray& other)
151 {
152   if(_info_on_compo.size()!=other._info_on_compo.size())
153     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
154   _name=other._name;
155   _info_on_compo=other._info_on_compo;
156 }
157
158 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
159 {
160   int nbOfCompoOth=other.getNumberOfComponents();
161   std::size_t newNbOfCompo=compoIds.size();
162   for(std::size_t i=0;i<newNbOfCompo;i++)
163     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
164       {
165         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
166         throw INTERP_KERNEL::Exception(oss.str().c_str());
167       }
168   for(std::size_t i=0;i<newNbOfCompo;i++)
169     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
170 }
171
172 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
173 {
174   int nbOfCompo=getNumberOfComponents();
175   std::size_t partOfCompoToSet=compoIds.size();
176   if((int)partOfCompoToSet!=other.getNumberOfComponents())
177     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
178   for(std::size_t i=0;i<partOfCompoToSet;i++)
179     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
180       {
181         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
182         throw INTERP_KERNEL::Exception(oss.str().c_str());
183       }
184   for(std::size_t i=0;i<partOfCompoToSet;i++)
185     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
186 }
187
188 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
189 {
190   std::ostringstream oss;
191   if(_name!=other._name)
192     {
193       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
194       reason=oss.str();
195       return false;
196     }
197   if(_info_on_compo!=other._info_on_compo)
198     {
199       oss << "Components DataArray mismatch : \nThis components=";
200       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
201         oss << "\"" << *it << "\",";
202       oss << "\nOther components=";
203       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
204         oss << "\"" << *it << "\",";
205       reason=oss.str();
206       return false;
207     }
208   return true;
209 }
210
211 /*!
212  * Compares textual information of \a this DataArray with that of an \a other one.
213  * The compared data are
214  * - the name attribute,
215  * - the information of components.
216  *
217  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
218  *  \param [in] other - another instance of DataArray to compare the textual data of.
219  *  \return bool - \a true if the textual information is same, \a false else.
220  */
221 bool DataArray::areInfoEquals(const DataArray& other) const
222 {
223   std::string tmp;
224   return areInfoEqualsIfNotWhy(other,tmp);
225 }
226
227 void DataArray::reprWithoutNameStream(std::ostream& stream) const
228 {
229   stream << "Number of components : "<< getNumberOfComponents() << "\n";
230   stream << "Info of these components : ";
231   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
232     stream << "\"" << *iter << "\"   ";
233   stream << "\n";
234 }
235
236 std::string DataArray::cppRepr(const std::string& varName) const
237 {
238   std::ostringstream ret;
239   reprCppStream(varName,ret);
240   return ret.str();
241 }
242
243 /*!
244  * Sets information on all components. To know more on format of this information
245  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
246  *  \param [in] info - a vector of strings.
247  *  \throw If size of \a info differs from the number of components of \a this.
248  */
249 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
250 {
251   if(getNumberOfComponents()!=(int)info.size())
252     {
253       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
254       throw INTERP_KERNEL::Exception(oss.str().c_str());
255     }
256   _info_on_compo=info;
257 }
258
259 /*!
260  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
261  * type of \a this and \a aBase.
262  *
263  * \throw If \a aBase and \a this do not have the same type.
264  *
265  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
266  */
267 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
268 {
269   if(!aBase)
270     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
271   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
272   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
273   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
274   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
275   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
276   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
277   if(this1 && a1)
278     {
279       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
280       return ;
281     }
282   if(this2 && a2)
283     {
284       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
285       return ;
286     }
287   if(this3 && a3)
288     {
289       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
290       return ;
291     }
292   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
293 }
294
295 std::vector<std::string> DataArray::getVarsOnComponent() const
296 {
297   int nbOfCompo=(int)_info_on_compo.size();
298   std::vector<std::string> ret(nbOfCompo);
299   for(int i=0;i<nbOfCompo;i++)
300     ret[i]=getVarOnComponent(i);
301   return ret;
302 }
303
304 std::vector<std::string> DataArray::getUnitsOnComponent() const
305 {
306   int nbOfCompo=(int)_info_on_compo.size();
307   std::vector<std::string> ret(nbOfCompo);
308   for(int i=0;i<nbOfCompo;i++)
309     ret[i]=getUnitOnComponent(i);
310   return ret;
311 }
312
313 /*!
314  * Returns information on a component specified by an index.
315  * To know more on format of this information
316  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
317  *  \param [in] i - the index (zero based) of the component of interest.
318  *  \return std::string - a string containing the information on \a i-th component.
319  *  \throw If \a i is not a valid component index.
320  */
321 std::string DataArray::getInfoOnComponent(int i) const
322 {
323   if(i<(int)_info_on_compo.size() && i>=0)
324     return _info_on_compo[i];
325   else
326     {
327       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();
328       throw INTERP_KERNEL::Exception(oss.str().c_str());
329     }
330 }
331
332 /*!
333  * Returns the var part of the full information of the \a i-th component.
334  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
335  * \c getVarOnComponent(0) returns "SIGXY".
336  * If a unit part of information is not detected by presence of
337  * two square brackets, then the full information is returned.
338  * To read more about the component information format, see
339  * \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 var information, or the full info.
342  *  \throw If \a i is not a valid component index.
343  */
344 std::string DataArray::getVarOnComponent(int i) const
345 {
346   if(i<(int)_info_on_compo.size() && i>=0)
347     {
348       return GetVarNameFromInfo(_info_on_compo[i]);
349     }
350   else
351     {
352       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();
353       throw INTERP_KERNEL::Exception(oss.str().c_str());
354     }
355 }
356
357 /*!
358  * Returns the unit part of the full information of the \a i-th component.
359  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
360  * \c getUnitOnComponent(0) returns " N/m^2".
361  * If a unit part of information is not detected by presence of
362  * two square brackets, then an empty string is returned.
363  * To read more about the component information format, see
364  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
365  *  \param [in] i - the index (zero based) of the component of interest.
366  *  \return std::string - a string containing the unit information, if any, or "".
367  *  \throw If \a i is not a valid component index.
368  */
369 std::string DataArray::getUnitOnComponent(int i) const
370 {
371   if(i<(int)_info_on_compo.size() && i>=0)
372     {
373       return GetUnitFromInfo(_info_on_compo[i]);
374     }
375   else
376     {
377       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();
378       throw INTERP_KERNEL::Exception(oss.str().c_str());
379     }
380 }
381
382 /*!
383  * Returns the var part of the full component information.
384  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
385  * If a unit part of information is not detected by presence of
386  * two square brackets, then the whole \a info is returned.
387  * To read more about the component information format, see
388  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
389  *  \param [in] info - the full component information.
390  *  \return std::string - a string containing only var information, or the \a info.
391  */
392 std::string DataArray::GetVarNameFromInfo(const std::string& info)
393 {
394   std::size_t p1=info.find_last_of('[');
395   std::size_t p2=info.find_last_of(']');
396   if(p1==std::string::npos || p2==std::string::npos)
397     return info;
398   if(p1>p2)
399     return info;
400   if(p1==0)
401     return std::string();
402   std::size_t p3=info.find_last_not_of(' ',p1-1);
403   return info.substr(0,p3+1);
404 }
405
406 /*!
407  * Returns the unit part of the full component information.
408  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
409  * If a unit part of information is not detected by presence of
410  * two square brackets, then an empty string is returned.
411  * To read more about the component information format, see
412  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
413  *  \param [in] info - the full component information.
414  *  \return std::string - a string containing only unit information, if any, or "".
415  */
416 std::string DataArray::GetUnitFromInfo(const std::string& info)
417 {
418   std::size_t p1=info.find_last_of('[');
419   std::size_t p2=info.find_last_of(']');
420   if(p1==std::string::npos || p2==std::string::npos)
421     return std::string();
422   if(p1>p2)
423     return std::string();
424   return info.substr(p1+1,p2-p1-1);
425 }
426
427 /*!
428  * This method put in info format the result of the merge of \a var and \a unit.
429  * The standard format for that is "var [unit]".
430  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
431  */
432 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
433 {
434   std::ostringstream oss;
435   oss << var << " [" << unit << "]";
436   return oss.str();
437 }
438
439 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
440 {
441   switch(at)
442     {
443     case AX_CART:
444       return std::string("AX_CART");
445     case AX_CYL:
446       return std::string("AX_CYL");
447     case AX_SPHER:
448       return std::string("AX_SPHER");
449     default:
450       throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
451     }
452 }
453
454 /*!
455  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
456  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
457  * the number of component in the result array is same as that of each of given arrays.
458  * Info on components is copied from the first of the given arrays. Number of components
459  * in the given arrays must be  the same.
460  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
461  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
462  *          The caller is to delete this result array using decrRef() as it is no more
463  *          needed.
464  *  \throw If all arrays within \a arrs are NULL.
465  *  \throw If all not null arrays in \a arrs have not the same type.
466  *  \throw If getNumberOfComponents() of arrays within \a arrs.
467  */
468 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
469 {
470   std::vector<const DataArray *> arr2;
471   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
472     if(*it)
473       arr2.push_back(*it);
474   if(arr2.empty())
475     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
476   std::vector<const DataArrayDouble *> arrd;
477   std::vector<const DataArrayInt *> arri;
478   std::vector<const DataArrayChar *> arrc;
479   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
480     {
481       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
482       if(a)
483         { arrd.push_back(a); continue; }
484       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
485       if(b)
486         { arri.push_back(b); continue; }
487       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
488       if(c)
489         { arrc.push_back(c); continue; }
490       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
491     }
492   if(arr2.size()==arrd.size())
493     return DataArrayDouble::Aggregate(arrd);
494   if(arr2.size()==arri.size())
495     return DataArrayInt::Aggregate(arri);
496   if(arr2.size()==arrc.size())
497     return DataArrayChar::Aggregate(arrc);
498   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
499 }
500
501 /*!
502  * Sets information on a component specified by an index.
503  * To know more on format of this information
504  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
505  *  \warning Don't pass NULL as \a info!
506  *  \param [in] i - the index (zero based) of the component of interest.
507  *  \param [in] info - the string containing the information.
508  *  \throw If \a i is not a valid component index.
509  */
510 void DataArray::setInfoOnComponent(int i, const std::string& info)
511 {
512   if(i<(int)_info_on_compo.size() && i>=0)
513     _info_on_compo[i]=info;
514   else
515     {
516       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();
517       throw INTERP_KERNEL::Exception(oss.str().c_str());
518     }
519 }
520
521 /*!
522  * Sets information on all components. This method can change number of components
523  * at certain conditions; if the conditions are not respected, an exception is thrown.
524  * The number of components can be changed in \a this only if \a this is not allocated.
525  * The condition of number of components must not be changed.
526  *
527  * To know more on format of the component information see
528  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
529  *  \param [in] info - a vector of component infos.
530  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
531  */
532 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
533 {
534   if(getNumberOfComponents()!=(int)info.size())
535     {
536       if(!isAllocated())
537         _info_on_compo=info;
538       else
539         {
540           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 !";
541           throw INTERP_KERNEL::Exception(oss.str().c_str());
542         }
543     }
544   else
545     _info_on_compo=info;
546 }
547
548 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
549 {
550   if(getNumberOfTuples()!=nbOfTuples)
551     {
552       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
553       throw INTERP_KERNEL::Exception(oss.str().c_str());
554     }
555 }
556
557 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
558 {
559   if(getNumberOfComponents()!=nbOfCompo)
560     {
561       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
562       throw INTERP_KERNEL::Exception(oss.str().c_str());
563     }
564 }
565
566 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
567 {
568   if(getNbOfElems()!=nbOfElems)
569     {
570       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
571       throw INTERP_KERNEL::Exception(oss.str().c_str());
572     }
573 }
574
575 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
576 {
577   if(getNumberOfTuples()!=other.getNumberOfTuples())
578     {
579       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
580       throw INTERP_KERNEL::Exception(oss.str().c_str());
581     }
582   if(getNumberOfComponents()!=other.getNumberOfComponents())
583     {
584       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
585       throw INTERP_KERNEL::Exception(oss.str().c_str());
586     }
587 }
588
589 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
590 {
591   checkNbOfTuples(nbOfTuples,msg);
592   checkNbOfComps(nbOfCompo,msg);
593 }
594
595 /*!
596  * Simply this method checks that \b value is in [0,\b ref).
597  */
598 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
599 {
600   if(value<0 || value>=ref)
601     {
602       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
603       throw INTERP_KERNEL::Exception(oss.str().c_str());
604     }
605 }
606
607 /*!
608  * This method checks that [\b start, \b end) is compliant with ref length \b value.
609  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
610  */
611 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
612 {
613   if(start<0 || start>=value)
614     {
615       if(value!=start || end!=start)
616         {
617           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
618           throw INTERP_KERNEL::Exception(oss.str().c_str());
619         }
620     }
621   if(end<0 || end>value)
622     {
623       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
624       throw INTERP_KERNEL::Exception(oss.str().c_str());
625     }
626 }
627
628 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
629 {
630   if(value<0 || value>ref)
631     {
632       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
633       throw INTERP_KERNEL::Exception(oss.str().c_str());
634     }
635 }
636
637 /*!
638  * 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, 
639  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
640  *
641  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
642  *
643  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
644  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
645  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
646  * \param [in] sliceId - the slice id considered
647  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
648  * \param [out] startSlice - the start of the slice considered
649  * \param [out] stopSlice - the stop of the slice consided
650  * 
651  * \throw If \a step == 0
652  * \throw If \a nbOfSlices not > 0
653  * \throw If \a sliceId not in [0,nbOfSlices)
654  */
655 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
656 {
657   if(nbOfSlices<=0)
658     {
659       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
660       throw INTERP_KERNEL::Exception(oss.str().c_str());
661     }
662   if(sliceId<0 || sliceId>=nbOfSlices)
663     {
664       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
665       throw INTERP_KERNEL::Exception(oss.str().c_str());
666     }
667   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
668   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
669   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
670   if(sliceId<nbOfSlices-1)
671     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
672   else
673     stopSlice=stop;
674 }
675
676 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
677 {
678   if(end<begin)
679     {
680       std::ostringstream oss; oss << msg << " : end before begin !";
681       throw INTERP_KERNEL::Exception(oss.str().c_str());
682     }
683   if(end==begin)
684     return 0;
685   if(step<=0)
686     {
687       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
688       throw INTERP_KERNEL::Exception(oss.str().c_str());
689     }
690   return (end-1-begin)/step+1;
691 }
692
693 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
694 {
695   if(step==0)
696     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
697   if(end<begin && step>0)
698     {
699       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
700       throw INTERP_KERNEL::Exception(oss.str().c_str());
701     }
702   if(begin<end && step<0)
703     {
704       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
705       throw INTERP_KERNEL::Exception(oss.str().c_str());
706     }
707   if(begin!=end)
708     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
709   else
710     return 0;
711 }
712
713 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
714 {
715   if(step!=0)
716     {
717       if(step>0)
718         {
719           if(begin<=value && value<end)
720             {
721               if((value-begin)%step==0)
722                 return (value-begin)/step;
723               else
724                 return -1;
725             }
726           else
727             return -1;
728         }
729       else
730         {
731           if(begin>=value && value>end)
732             {
733               if((begin-value)%(-step)==0)
734                 return (begin-value)/(-step);
735               else
736                 return -1;
737             }
738           else
739             return -1;
740         }
741     }
742   else
743     return -1;
744 }
745
746 /*!
747  * Returns a new instance of DataArrayDouble. The caller is to delete this array
748  * using decrRef() as it is no more needed. 
749  */
750 DataArrayDouble *DataArrayDouble::New()
751 {
752   return new DataArrayDouble;
753 }
754
755 /*!
756  * Returns the only one value in \a this, if and only if number of elements
757  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
758  *  \return double - the sole value stored in \a this array.
759  *  \throw If at least one of conditions stated above is not fulfilled.
760  */
761 double DataArrayDouble::doubleValue() const
762 {
763   if(isAllocated())
764     {
765       if(getNbOfElems()==1)
766         {
767           return *getConstPointer();
768         }
769       else
770         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
771     }
772   else
773     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
774 }
775
776 /*!
777  * Returns a full copy of \a this. For more info on copying data arrays see
778  * \ref MEDCouplingArrayBasicsCopyDeep.
779  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
780  *          delete this array using decrRef() as it is no more needed. 
781  */
782 DataArrayDouble *DataArrayDouble::deepCopy() const
783 {
784   return new DataArrayDouble(*this);
785 }
786
787 /*!
788  * Returns either a \a deep or \a shallow copy of this array. For more info see
789  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
790  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
791  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
792  *          == \a true) or \a this instance (if \a dCpy == \a false).
793  */
794 DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const
795 {
796   if(dCpy)
797     return deepCopy();
798   else
799     {
800       incrRef();
801       return const_cast<DataArrayDouble *>(this);
802     }
803 }
804
805 /*!
806  * Assign zero to all values in \a this array. To know more on filling arrays see
807  * \ref MEDCouplingArrayFill.
808  * \throw If \a this is not allocated.
809  */
810 void DataArrayDouble::fillWithZero()
811 {
812   fillWithValue(0.);
813 }
814
815 /*!
816  * Set all values in \a this array so that the i-th element equals to \a init + i
817  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
818  *  \param [in] init - value to assign to the first element of array.
819  *  \throw If \a this->getNumberOfComponents() != 1
820  *  \throw If \a this is not allocated.
821  */
822 void DataArrayDouble::iota(double init)
823 {
824   checkAllocated();
825   if(getNumberOfComponents()!=1)
826     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
827   double *ptr=getPointer();
828   int ntuples=getNumberOfTuples();
829   for(int i=0;i<ntuples;i++)
830     ptr[i]=init+double(i);
831   declareAsNew();
832 }
833
834 /*!
835  * Checks if all values in \a this array are equal to \a val at precision \a eps.
836  *  \param [in] val - value to check equality of array values to.
837  *  \param [in] eps - precision to check the equality.
838  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
839  *                 \a false else.
840  *  \throw If \a this->getNumberOfComponents() != 1
841  *  \throw If \a this is not allocated.
842  */
843 bool DataArrayDouble::isUniform(double val, double eps) const
844 {
845   checkAllocated();
846   if(getNumberOfComponents()!=1)
847     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
848   int nbOfTuples=getNumberOfTuples();
849   const double *w=getConstPointer();
850   const double *end2=w+nbOfTuples;
851   const double vmin=val-eps;
852   const double vmax=val+eps;
853   for(;w!=end2;w++)
854     if(*w<vmin || *w>vmax)
855       return false;
856   return true;
857 }
858
859 /*!
860  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
861  * with at least absolute difference value of |\a eps| at each step.
862  * If not an exception is thrown.
863  *  \param [in] increasing - if \a true, the array values should be increasing.
864  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
865  *                    the values are considered different.
866  *  \throw If sequence of values is not strictly monotonic in agreement with \a
867  *         increasing arg.
868  *  \throw If \a this->getNumberOfComponents() != 1.
869  *  \throw If \a this is not allocated.
870  */
871 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
872 {
873   if(!isMonotonic(increasing,eps))
874     {
875       if (increasing)
876         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
877       else
878         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
879     }
880 }
881
882 /*!
883  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
884  * with at least absolute difference value of |\a eps| at each step.
885  *  \param [in] increasing - if \a true, array values should be increasing.
886  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
887  *                    the values are considered different.
888  *  \return bool - \a true if values change in accordance with \a increasing arg.
889  *  \throw If \a this->getNumberOfComponents() != 1.
890  *  \throw If \a this is not allocated.
891  */
892 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
893 {
894   checkAllocated();
895   if(getNumberOfComponents()!=1)
896     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
897   int nbOfElements=getNumberOfTuples();
898   const double *ptr=getConstPointer();
899   if(nbOfElements==0)
900     return true;
901   double ref=ptr[0];
902   double absEps=fabs(eps);
903   if(increasing)
904     {
905       for(int i=1;i<nbOfElements;i++)
906         {
907           if(ptr[i]<(ref+absEps))
908             return false;
909           ref=ptr[i];
910         }
911       return true;
912     }
913   else
914     {
915       for(int i=1;i<nbOfElements;i++)
916         {
917           if(ptr[i]>(ref-absEps))
918             return false;
919           ref=ptr[i];
920         }
921       return true;
922     }
923 }
924
925 /*!
926  * Returns a textual and human readable representation of \a this instance of
927  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
928  * \return std::string - text describing \a this DataArrayDouble.
929  *
930  * \sa reprNotTooLong, reprZip
931  */
932 std::string DataArrayDouble::repr() const
933 {
934   std::ostringstream ret;
935   reprStream(ret);
936   return ret.str();
937 }
938
939 std::string DataArrayDouble::reprZip() const
940 {
941   std::ostringstream ret;
942   reprZipStream(ret);
943   return ret.str();
944 }
945
946 /*!
947  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
948  * printed out to avoid to consume too much space in interpretor.
949  * \sa repr
950  */
951 std::string DataArrayDouble::reprNotTooLong() const
952 {
953   std::ostringstream ret;
954   reprNotTooLongStream(ret);
955   return ret.str();
956 }
957
958 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
959 {
960   static const char SPACE[4]={' ',' ',' ',' '};
961   checkAllocated();
962   std::string idt(indent,' ');
963   ofs.precision(17);
964   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
965   //
966   bool areAllEmpty(true);
967   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
968     if(!(*it).empty())
969       areAllEmpty=false;
970   if(!areAllEmpty)
971     for(std::size_t i=0;i<_info_on_compo.size();i++)
972       ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
973   //
974   if(byteArr)
975     {
976       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
977       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
978       float *pt(tmp);
979       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
980       for(const double *src=begin();src!=end();src++,pt++)
981         *pt=float(*src);
982       const char *data(reinterpret_cast<const char *>((float *)tmp));
983       std::size_t sz(getNbOfElems()*sizeof(float));
984       byteArr->insertAtTheEnd(data,data+sz);
985       byteArr->insertAtTheEnd(SPACE,SPACE+4);
986     }
987   else
988     {
989       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
990       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
991     }
992   ofs << std::endl << idt << "</DataArray>\n";
993 }
994
995 void DataArrayDouble::reprStream(std::ostream& stream) const
996 {
997   stream << "Name of double array : \"" << _name << "\"\n";
998   reprWithoutNameStream(stream);
999 }
1000
1001 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1002 {
1003   stream << "Name of double array : \"" << _name << "\"\n";
1004   reprZipWithoutNameStream(stream);
1005 }
1006
1007 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
1008 {
1009   stream << "Name of double array : \"" << _name << "\"\n";
1010   reprNotTooLongWithoutNameStream(stream);
1011 }
1012
1013 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1014 {
1015   DataArray::reprWithoutNameStream(stream);
1016   stream.precision(17);
1017   _mem.repr(getNumberOfComponents(),stream);
1018 }
1019
1020 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1021 {
1022   DataArray::reprWithoutNameStream(stream);
1023   stream.precision(17);
1024   _mem.reprZip(getNumberOfComponents(),stream);
1025 }
1026
1027 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
1028 {
1029   DataArray::reprWithoutNameStream(stream);
1030   stream.precision(17);
1031   _mem.reprNotTooLong(getNumberOfComponents(),stream);
1032 }
1033
1034 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1035 {
1036   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1037   const double *data=getConstPointer();
1038   stream.precision(17);
1039   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1040   if(nbTuples*nbComp>=1)
1041     {
1042       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1043       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1044       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1045       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1046     }
1047   else
1048     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1049   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1050 }
1051
1052 /*!
1053  * Method that gives a quick overvien of \a this for python.
1054  */
1055 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1056 {
1057   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1058   stream << "DataArrayDouble C++ instance at " << this << ". ";
1059   if(isAllocated())
1060     {
1061       int nbOfCompo=(int)_info_on_compo.size();
1062       if(nbOfCompo>=1)
1063         {
1064           int nbOfTuples=getNumberOfTuples();
1065           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1066           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1067         }
1068       else
1069         stream << "Number of components : 0.";
1070     }
1071   else
1072     stream << "*** No data allocated ****";
1073 }
1074
1075 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1076 {
1077   const double *data=begin();
1078   int nbOfTuples=getNumberOfTuples();
1079   int nbOfCompo=(int)_info_on_compo.size();
1080   std::ostringstream oss2; oss2 << "[";
1081   oss2.precision(17);
1082   std::string oss2Str(oss2.str());
1083   bool isFinished=true;
1084   for(int i=0;i<nbOfTuples && isFinished;i++)
1085     {
1086       if(nbOfCompo>1)
1087         {
1088           oss2 << "(";
1089           for(int j=0;j<nbOfCompo;j++,data++)
1090             {
1091               oss2 << *data;
1092               if(j!=nbOfCompo-1) oss2 << ", ";
1093             }
1094           oss2 << ")";
1095         }
1096       else
1097         oss2 << *data++;
1098       if(i!=nbOfTuples-1) oss2 << ", ";
1099       std::string oss3Str(oss2.str());
1100       if(oss3Str.length()<maxNbOfByteInRepr)
1101         oss2Str=oss3Str;
1102       else
1103         isFinished=false;
1104     }
1105   stream << oss2Str;
1106   if(!isFinished)
1107     stream << "... ";
1108   stream << "]";
1109 }
1110
1111 /*!
1112  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1113  * mismatch is given.
1114  * 
1115  * \param [in] other the instance to be compared with \a this
1116  * \param [in] prec the precision to compare numeric data of the arrays.
1117  * \param [out] reason In case of inequality returns the reason.
1118  * \sa DataArrayDouble::isEqual
1119  */
1120 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1121 {
1122   if(!areInfoEqualsIfNotWhy(other,reason))
1123     return false;
1124   return _mem.isEqual(other._mem,prec,reason);
1125 }
1126
1127 /*!
1128  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1129  * \ref MEDCouplingArrayBasicsCompare.
1130  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1131  *  \param [in] prec - precision value to compare numeric data of the arrays.
1132  *  \return bool - \a true if the two arrays are equal, \a false else.
1133  */
1134 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1135 {
1136   std::string tmp;
1137   return isEqualIfNotWhy(other,prec,tmp);
1138 }
1139
1140 /*!
1141  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1142  * \ref MEDCouplingArrayBasicsCompare.
1143  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1144  *  \param [in] prec - precision value to compare numeric data of the arrays.
1145  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1146  */
1147 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1148 {
1149   std::string tmp;
1150   return _mem.isEqual(other._mem,prec,tmp);
1151 }
1152
1153 /*!
1154  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1155  * array to the new one.
1156  *  \return DataArrayInt * - the new instance of DataArrayInt.
1157  */
1158 DataArrayInt *DataArrayDouble::convertToIntArr() const
1159 {
1160   DataArrayInt *ret=DataArrayInt::New();
1161   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1162   int *dest=ret->getPointer();
1163   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1164   for(const double *src=begin();src!=end();src++,dest++)
1165     *dest=(int)*src;
1166   ret->copyStringInfoFrom(*this);
1167   return ret;
1168 }
1169
1170 /*!
1171  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1172  * arranged in memory. If \a this array holds 2 components of 3 values:
1173  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1174  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1175  *  \warning Do not confuse this method with transpose()!
1176  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1177  *          is to delete using decrRef() as it is no more needed.
1178  *  \throw If \a this is not allocated.
1179  */
1180 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1181 {
1182   if(_mem.isNull())
1183     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1184   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1185   DataArrayDouble *ret=DataArrayDouble::New();
1186   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1187   return ret;
1188 }
1189
1190 /*!
1191  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1192  * arranged in memory. If \a this array holds 2 components of 3 values:
1193  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1194  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1195  *  \warning Do not confuse this method with transpose()!
1196  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1197  *          is to delete using decrRef() as it is no more needed.
1198  *  \throw If \a this is not allocated.
1199  */
1200 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1201 {
1202   if(_mem.isNull())
1203     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1204   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1205   DataArrayDouble *ret=DataArrayDouble::New();
1206   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1207   return ret;
1208 }
1209
1210 /*!
1211  * Appends components of another array to components of \a this one, tuple by tuple.
1212  * So that the number of tuples of \a this array remains the same and the number of 
1213  * components increases.
1214  *  \param [in] other - the DataArrayDouble to append to \a this one.
1215  *  \throw If \a this is not allocated.
1216  *  \throw If \a this and \a other arrays have different number of tuples.
1217  *
1218  *  \if ENABLE_EXAMPLES
1219  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1220  *
1221  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1222  *  \endif
1223  */
1224 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1225 {
1226   checkAllocated();
1227   other->checkAllocated();
1228   int nbOfTuples=getNumberOfTuples();
1229   if(nbOfTuples!=other->getNumberOfTuples())
1230     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1231   int nbOfComp1=getNumberOfComponents();
1232   int nbOfComp2=other->getNumberOfComponents();
1233   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1234   double *w=newArr;
1235   const double *inp1=getConstPointer();
1236   const double *inp2=other->getConstPointer();
1237   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1238     {
1239       w=std::copy(inp1,inp1+nbOfComp1,w);
1240       w=std::copy(inp2,inp2+nbOfComp2,w);
1241     }
1242   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1243   std::vector<int> compIds(nbOfComp2);
1244   for(int i=0;i<nbOfComp2;i++)
1245     compIds[i]=nbOfComp1+i;
1246   copyPartOfStringInfoFrom2(compIds,*other);
1247 }
1248
1249 /*!
1250  * This method checks that all tuples in \a other are in \a this.
1251  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1252  * 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.
1253  *
1254  * \param [in] other - the array having the same number of components than \a this.
1255  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1256  * \sa DataArrayDouble::findCommonTuples
1257  */
1258 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1259 {
1260   if(!other)
1261     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1262   checkAllocated(); other->checkAllocated();
1263   if(getNumberOfComponents()!=other->getNumberOfComponents())
1264     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1265   MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1266   DataArrayInt *c=0,*ci=0;
1267   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1268   MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1269   int newNbOfTuples=-1;
1270   MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1271   MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1272   tupleIds=ret1.retn();
1273   return newNbOfTuples==getNumberOfTuples();
1274 }
1275
1276 /*!
1277  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1278  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1279  * distance separating two points is computed with the infinite norm.
1280  *
1281  * Indices of coincident tuples are stored in output arrays.
1282  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1283  *
1284  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1285  * MEDCouplingUMesh::mergeNodes().
1286  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1287  *              considered not coincident.
1288  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1289  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1290  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1291  *               \a comm->getNumberOfComponents() == 1. 
1292  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1293  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1294  *               groups of (indices of) coincident tuples. Its every value is a tuple
1295  *               index where a next group of tuples begins. For example the second
1296  *               group of tuples in \a comm is described by following range of indices:
1297  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1298  *               gives the number of groups of coincident tuples.
1299  *  \throw If \a this is not allocated.
1300  *  \throw If the number of components is not in [1,2,3,4].
1301  *
1302  *  \if ENABLE_EXAMPLES
1303  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1304  *
1305  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1306  *  \endif
1307  *  \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1308  */
1309 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1310 {
1311   checkAllocated();
1312   int nbOfCompo=getNumberOfComponents();
1313   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1314     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1315
1316   int nbOfTuples=getNumberOfTuples();
1317   //
1318   MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1319   switch(nbOfCompo)
1320   {
1321     case 4:
1322       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1323       break;
1324     case 3:
1325       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1326       break;
1327     case 2:
1328       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1329       break;
1330     case 1:
1331       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1332       break;
1333     default:
1334       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1335   }
1336   comm=c.retn();
1337   commIndex=cI.retn();
1338 }
1339
1340 /*!
1341  * 
1342  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1343  *             \a nbTimes  should be at least equal to 1.
1344  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1345  * \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.
1346  */
1347 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
1348 {
1349   checkAllocated();
1350   if(getNumberOfComponents()!=1)
1351     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1352   if(nbTimes<1)
1353     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1354   int nbTuples=getNumberOfTuples();
1355   const double *inPtr=getConstPointer();
1356   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1357   double *retPtr=ret->getPointer();
1358   for(int i=0;i<nbTuples;i++,inPtr++)
1359     {
1360       double val=*inPtr;
1361       for(int j=0;j<nbTimes;j++,retPtr++)
1362         *retPtr=val;
1363     }
1364   ret->copyStringInfoFrom(*this);
1365   return ret.retn();
1366 }
1367
1368 /*!
1369  * This methods returns the minimal distance between the two set of points \a this and \a other.
1370  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1371  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1372  *
1373  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1374  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1375  * \return the minimal distance between the two set of points \a this and \a other.
1376  * \sa DataArrayDouble::findClosestTupleId
1377  */
1378 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1379 {
1380   MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1381   int nbOfCompo(getNumberOfComponents());
1382   int otherNbTuples(other->getNumberOfTuples());
1383   const double *thisPt(begin()),*otherPt(other->begin());
1384   const int *part1Pt(part1->begin());
1385   double ret=std::numeric_limits<double>::max();
1386   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1387     {
1388       double tmp(0.);
1389       for(int j=0;j<nbOfCompo;j++)
1390         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1391       if(tmp<ret)
1392         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1393     }
1394   return sqrt(ret);
1395 }
1396
1397 /*!
1398  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1399  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1400  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1401  *
1402  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1403  * \sa DataArrayDouble::minimalDistanceTo
1404  */
1405 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1406 {
1407   if(!other)
1408     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1409   checkAllocated(); other->checkAllocated();
1410   int nbOfCompo=getNumberOfComponents();
1411   if(nbOfCompo!=other->getNumberOfComponents())
1412     {
1413       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1414       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1415       throw INTERP_KERNEL::Exception(oss.str().c_str());
1416     }
1417   int nbOfTuples=other->getNumberOfTuples();
1418   int thisNbOfTuples=getNumberOfTuples();
1419   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1420   double bounds[6];
1421   getMinMaxPerComponent(bounds);
1422   switch(nbOfCompo)
1423   {
1424     case 3:
1425       {
1426         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1427         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1428         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1429         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1430         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1431         break;
1432       }
1433     case 2:
1434       {
1435         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1436         double delta=std::max(xDelta,yDelta);
1437         double characSize=sqrt(delta/(double)thisNbOfTuples);
1438         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1439         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1440         break;
1441       }
1442     case 1:
1443       {
1444         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1445         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1446         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1447         break;
1448       }
1449     default:
1450       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1451   }
1452   return ret.retn();
1453 }
1454
1455 /*!
1456  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1457  * 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
1458  * how many bounding boxes in \a otherBBoxFrmt.
1459  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1460  *
1461  * \param [in] otherBBoxFrmt - It is an array .
1462  * \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.
1463  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1464  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1465  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1466  */
1467 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1468 {
1469   if(!otherBBoxFrmt)
1470     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1471   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1472     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1473   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1474   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1475     {
1476       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1477       throw INTERP_KERNEL::Exception(oss.str().c_str());
1478     }
1479   if(nbOfComp%2!=0)
1480     {
1481       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1482       throw INTERP_KERNEL::Exception(oss.str().c_str());
1483     }
1484   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1485   const double *thisBBPtr(begin());
1486   int *retPtr(ret->getPointer());
1487   switch(nbOfComp/2)
1488   {
1489     case 3:
1490       {
1491         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1492         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1493           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1494         break;
1495       }
1496     case 2:
1497       {
1498         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1499         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1500           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1501         break;
1502       }
1503     case 1:
1504       {
1505         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1506         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1507           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1508         break;
1509       }
1510     default:
1511       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1512   }
1513
1514   return ret.retn();
1515 }
1516
1517 /*!
1518  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1519  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1520  * space. The distance between tuples is computed using norm2. If several tuples are
1521  * not far each from other than \a prec, only one of them remains in the result
1522  * array. The order of tuples in the result array is same as in \a this one except
1523  * that coincident tuples are excluded.
1524  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1525  *              considered not coincident.
1526  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1527  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
1528  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1529  *          is to delete using decrRef() as it is no more needed.
1530  *  \throw If \a this is not allocated.
1531  *  \throw If the number of components is not in [1,2,3,4].
1532  *
1533  *  \if ENABLE_EXAMPLES
1534  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1535  *  \endif
1536  */
1537 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1538 {
1539   checkAllocated();
1540   DataArrayInt *c0=0,*cI0=0;
1541   findCommonTuples(prec,limitTupleId,c0,cI0);
1542   MCAuto<DataArrayInt> c(c0),cI(cI0);
1543   int newNbOfTuples=-1;
1544   MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1545   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1546 }
1547
1548 /*!
1549  * Copy all components in a specified order from another DataArrayDouble.
1550  * Both numerical and textual data is copied. The number of tuples in \a this and
1551  * the other array can be different.
1552  *  \param [in] a - the array to copy data from.
1553  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1554  *              to be copied.
1555  *  \throw If \a a is NULL.
1556  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1557  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1558  *
1559  *  \if ENABLE_EXAMPLES
1560  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1561  *  \endif
1562  */
1563 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1564 {
1565   if(!a)
1566     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1567   checkAllocated();
1568   copyPartOfStringInfoFrom2(compoIds,*a);
1569   std::size_t partOfCompoSz=compoIds.size();
1570   int nbOfCompo=getNumberOfComponents();
1571   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1572   const double *ac=a->getConstPointer();
1573   double *nc=getPointer();
1574   for(int i=0;i<nbOfTuples;i++)
1575     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1576       nc[nbOfCompo*i+compoIds[j]]=*ac;
1577 }
1578
1579 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
1580 {
1581   if(newArray!=arrayToSet)
1582     {
1583       if(arrayToSet)
1584         arrayToSet->decrRef();
1585       arrayToSet=newArray;
1586       if(arrayToSet)
1587         arrayToSet->incrRef();
1588     }
1589 }
1590
1591 void DataArrayDouble::aggregate(const DataArrayDouble *other)
1592 {
1593   if(!other)
1594     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !");
1595   if(getNumberOfComponents()!=other->getNumberOfComponents())
1596     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !");
1597   _mem.insertAtTheEnd(other->begin(),other->end());
1598 }
1599
1600 /*!
1601  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1602  * is thrown.
1603  * \throw If zero is found in \a this array.
1604  */
1605 void DataArrayDouble::checkNoNullValues() const
1606 {
1607   const double *tmp=getConstPointer();
1608   std::size_t nbOfElems=getNbOfElems();
1609   const double *where=std::find(tmp,tmp+nbOfElems,0.);
1610   if(where!=tmp+nbOfElems)
1611     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1612 }
1613
1614 /*!
1615  * Computes minimal and maximal value in each component. An output array is filled
1616  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1617  * enough memory before calling this method.
1618  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1619  *               It is filled as follows:<br>
1620  *               \a bounds[0] = \c min_of_component_0 <br>
1621  *               \a bounds[1] = \c max_of_component_0 <br>
1622  *               \a bounds[2] = \c min_of_component_1 <br>
1623  *               \a bounds[3] = \c max_of_component_1 <br>
1624  *               ...
1625  */
1626 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1627 {
1628   checkAllocated();
1629   int dim=getNumberOfComponents();
1630   for (int idim=0; idim<dim; idim++)
1631     {
1632       bounds[idim*2]=std::numeric_limits<double>::max();
1633       bounds[idim*2+1]=-std::numeric_limits<double>::max();
1634     } 
1635   const double *ptr=getConstPointer();
1636   int nbOfTuples=getNumberOfTuples();
1637   for(int i=0;i<nbOfTuples;i++)
1638     {
1639       for(int idim=0;idim<dim;idim++)
1640         {
1641           if(bounds[idim*2]>ptr[i*dim+idim])
1642             {
1643               bounds[idim*2]=ptr[i*dim+idim];
1644             }
1645           if(bounds[idim*2+1]<ptr[i*dim+idim])
1646             {
1647               bounds[idim*2+1]=ptr[i*dim+idim];
1648             }
1649         }
1650     }
1651 }
1652
1653 /*!
1654  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1655  * to store both the min and max per component of each tuples. 
1656  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1657  *
1658  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1659  *
1660  * \throw If \a this is not allocated yet.
1661  */
1662 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1663 {
1664   checkAllocated();
1665   const double *dataPtr=getConstPointer();
1666   int nbOfCompo=getNumberOfComponents();
1667   int nbTuples=getNumberOfTuples();
1668   MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1669   bbox->alloc(nbTuples,2*nbOfCompo);
1670   double *bboxPtr=bbox->getPointer();
1671   for(int i=0;i<nbTuples;i++)
1672     {
1673       for(int j=0;j<nbOfCompo;j++)
1674         {
1675           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1676           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1677         }
1678     }
1679   return bbox.retn();
1680 }
1681
1682 /*!
1683  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1684  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1685  * 
1686  * \param [in] other a DataArrayDouble having same number of components than \a this.
1687  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1688  * \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.
1689  *             \a cI allows to extract information in \a c.
1690  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1691  *
1692  * \throw In case of:
1693  *  - \a this is not allocated
1694  *  - \a other is not allocated or null
1695  *  - \a this and \a other do not have the same number of components
1696  *  - if number of components of \a this is not in [1,2,3]
1697  *
1698  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1699  */
1700 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1701 {
1702   if(!other)
1703     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1704   checkAllocated();
1705   other->checkAllocated();
1706   int nbOfCompo=getNumberOfComponents();
1707   int otherNbOfCompo=other->getNumberOfComponents();
1708   if(nbOfCompo!=otherNbOfCompo)
1709     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1710   int nbOfTuplesOther=other->getNumberOfTuples();
1711   MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1712   switch(nbOfCompo)
1713   {
1714     case 3:
1715       {
1716         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1717         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1718         break;
1719       }
1720     case 2:
1721       {
1722         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1723         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1724         break;
1725       }
1726     case 1:
1727       {
1728         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1729         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1730         break;
1731       }
1732     default:
1733       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1734   }
1735   c=cArr.retn(); cI=cIArr.retn();
1736 }
1737
1738 /*!
1739  * 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
1740  * around origin of 'radius' 1.
1741  * 
1742  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1743  */
1744 void DataArrayDouble::recenterForMaxPrecision(double eps)
1745 {
1746   checkAllocated();
1747   int dim=getNumberOfComponents();
1748   std::vector<double> bounds(2*dim);
1749   getMinMaxPerComponent(&bounds[0]);
1750   for(int i=0;i<dim;i++)
1751     {
1752       double delta=bounds[2*i+1]-bounds[2*i];
1753       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1754       if(delta>eps)
1755         applyLin(1./delta,-offset/delta,i);
1756       else
1757         applyLin(1.,-offset,i);
1758     }
1759 }
1760
1761 /*!
1762  * Returns the maximal value and all its locations within \a this one-dimensional array.
1763  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1764  *               tuples holding the maximal value. The caller is to delete it using
1765  *               decrRef() as it is no more needed.
1766  *  \return double - the maximal value among all values of \a this array.
1767  *  \throw If \a this->getNumberOfComponents() != 1
1768  *  \throw If \a this->getNumberOfTuples() < 1
1769  */
1770 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1771 {
1772   int tmp;
1773   tupleIds=0;
1774   double ret=getMaxValue(tmp);
1775   tupleIds=findIdsInRange(ret,ret);
1776   return ret;
1777 }
1778
1779 /*!
1780  * Returns the minimal value and all its locations within \a this one-dimensional array.
1781  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1782  *               tuples holding the minimal value. The caller is to delete it using
1783  *               decrRef() as it is no more needed.
1784  *  \return double - the minimal value among all values of \a this array.
1785  *  \throw If \a this->getNumberOfComponents() != 1
1786  *  \throw If \a this->getNumberOfTuples() < 1
1787  */
1788 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1789 {
1790   int tmp;
1791   tupleIds=0;
1792   double ret=getMinValue(tmp);
1793   tupleIds=findIdsInRange(ret,ret);
1794   return ret;
1795 }
1796
1797 /*!
1798  * 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.
1799  * This method only works for single component array.
1800  *
1801  * \return a value in [ 0, \c this->getNumberOfTuples() )
1802  *
1803  * \throw If \a this is not allocated
1804  *
1805  */
1806 int DataArrayDouble::count(double value, double eps) const
1807 {
1808   int ret=0;
1809   checkAllocated();
1810   if(getNumberOfComponents()!=1)
1811     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1812   const double *vals=begin();
1813   int nbOfTuples=getNumberOfTuples();
1814   for(int i=0;i<nbOfTuples;i++,vals++)
1815     if(fabs(*vals-value)<=eps)
1816       ret++;
1817   return ret;
1818 }
1819
1820 /*!
1821  * Returns the average value of \a this one-dimensional array.
1822  *  \return double - the average value over all values of \a this array.
1823  *  \throw If \a this->getNumberOfComponents() != 1
1824  *  \throw If \a this->getNumberOfTuples() < 1
1825  */
1826 double DataArrayDouble::getAverageValue() const
1827 {
1828   if(getNumberOfComponents()!=1)
1829     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1830   int nbOfTuples=getNumberOfTuples();
1831   if(nbOfTuples<=0)
1832     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1833   const double *vals=getConstPointer();
1834   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1835   return ret/nbOfTuples;
1836 }
1837
1838 /*!
1839  * Returns the Euclidean norm of the vector defined by \a this array.
1840  *  \return double - the value of the Euclidean norm, i.e.
1841  *          the square root of the inner product of vector.
1842  *  \throw If \a this is not allocated.
1843  */
1844 double DataArrayDouble::norm2() const
1845 {
1846   checkAllocated();
1847   double ret=0.;
1848   std::size_t nbOfElems=getNbOfElems();
1849   const double *pt=getConstPointer();
1850   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1851     ret+=(*pt)*(*pt);
1852   return sqrt(ret);
1853 }
1854
1855 /*!
1856  * Returns the maximum norm of the vector defined by \a this array.
1857  * This method works even if the number of components is diferent from one.
1858  * If the number of elements in \a this is 0, -1. is returned.
1859  *  \return double - the value of the maximum norm, i.e.
1860  *          the maximal absolute value among values of \a this array (whatever its number of components).
1861  *  \throw If \a this is not allocated.
1862  */
1863 double DataArrayDouble::normMax() const
1864 {
1865   checkAllocated();
1866   double ret(-1.);
1867   std::size_t nbOfElems(getNbOfElems());
1868   const double *pt(getConstPointer());
1869   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1870     {
1871       double val(std::abs(*pt));
1872       if(val>ret)
1873         ret=val;
1874     }
1875   return ret;
1876 }
1877
1878 /*!
1879  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1880  * This method works even if the number of components is diferent from one.
1881  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1882  *  \return double - the value of the minimum norm, i.e.
1883  *          the minimal absolute value among values of \a this array (whatever its number of components).
1884  *  \throw If \a this is not allocated.
1885  */
1886 double DataArrayDouble::normMin() const
1887 {
1888   checkAllocated();
1889   double ret(std::numeric_limits<double>::max());
1890   std::size_t nbOfElems(getNbOfElems());
1891   const double *pt(getConstPointer());
1892   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1893     {
1894       double val(std::abs(*pt));
1895       if(val<ret)
1896         ret=val;
1897     }
1898   return ret;
1899 }
1900
1901 /*!
1902  * Accumulates values of each component of \a this array.
1903  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
1904  *         by the caller, that is filled by this method with sum value for each
1905  *         component.
1906  *  \throw If \a this is not allocated.
1907  */
1908 void DataArrayDouble::accumulate(double *res) const
1909 {
1910   checkAllocated();
1911   const double *ptr=getConstPointer();
1912   int nbTuple=getNumberOfTuples();
1913   int nbComps=getNumberOfComponents();
1914   std::fill(res,res+nbComps,0.);
1915   for(int i=0;i<nbTuple;i++)
1916     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1917 }
1918
1919 /*!
1920  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1921  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1922  *
1923  *
1924  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1925  * \a tupleEnd. If not an exception will be thrown.
1926  *
1927  * \param [in] tupleBg start pointer (included) of input external tuple
1928  * \param [in] tupleEnd end pointer (not included) of input external tuple
1929  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1930  * \return the min distance.
1931  * \sa MEDCouplingUMesh::distanceToPoint
1932  */
1933 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1934 {
1935   checkAllocated();
1936   int nbTuple=getNumberOfTuples();
1937   int nbComps=getNumberOfComponents();
1938   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1939     { 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()); }
1940   if(nbTuple==0)
1941     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1942   double ret0=std::numeric_limits<double>::max();
1943   tupleId=-1;
1944   const double *work=getConstPointer();
1945   for(int i=0;i<nbTuple;i++)
1946     {
1947       double val=0.;
1948       for(int j=0;j<nbComps;j++,work++) 
1949         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1950       if(val>=ret0)
1951         continue;
1952       else
1953         { ret0=val; tupleId=i; }
1954     }
1955   return sqrt(ret0);
1956 }
1957
1958 /*!
1959  * Accumulate values of the given component of \a this array.
1960  *  \param [in] compId - the index of the component of interest.
1961  *  \return double - a sum value of \a compId-th component.
1962  *  \throw If \a this is not allocated.
1963  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1964  *         not respected.
1965  */
1966 double DataArrayDouble::accumulate(int compId) const
1967 {
1968   checkAllocated();
1969   const double *ptr=getConstPointer();
1970   int nbTuple=getNumberOfTuples();
1971   int nbComps=getNumberOfComponents();
1972   if(compId<0 || compId>=nbComps)
1973     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1974   double ret=0.;
1975   for(int i=0;i<nbTuple;i++)
1976     ret+=ptr[i*nbComps+compId];
1977   return ret;
1978 }
1979
1980 /*!
1981  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1982  * The returned array will have same number of components than \a this and number of tuples equal to
1983  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1984  *
1985  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1986  * 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.
1987  *
1988  * \param [in] bgOfIndex - begin (included) of the input index array.
1989  * \param [in] endOfIndex - end (excluded) of the input index array.
1990  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1991  * 
1992  * \throw If bgOfIndex or end is NULL.
1993  * \throw If input index array is not ascendingly sorted.
1994  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1995  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1996  */
1997 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1998 {
1999   if(!bgOfIndex || !endOfIndex)
2000     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
2001   checkAllocated();
2002   int nbCompo=getNumberOfComponents();
2003   int nbOfTuples=getNumberOfTuples();
2004   int sz=(int)std::distance(bgOfIndex,endOfIndex);
2005   if(sz<1)
2006     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
2007   sz--;
2008   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
2009   const int *w=bgOfIndex;
2010   if(*w<0 || *w>=nbOfTuples)
2011     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
2012   const double *srcPt=begin()+(*w)*nbCompo;
2013   double *tmp=ret->getPointer();
2014   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
2015     {
2016       std::fill(tmp,tmp+nbCompo,0.);
2017       if(w[1]>=w[0])
2018         {
2019           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
2020             {
2021               if(j>=0 && j<nbOfTuples)
2022                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
2023               else
2024                 {
2025                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
2026                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2027                 }
2028             }
2029         }
2030       else
2031         {
2032           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
2033           throw INTERP_KERNEL::Exception(oss.str().c_str());
2034         }
2035     }
2036   ret->copyStringInfoFrom(*this);
2037   return ret.retn();
2038 }
2039
2040 /*!
2041  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
2042  * Cartesian coordinate system. The two components of the tuple of \a this array are 
2043  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
2044  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2045  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
2046  *          is to delete this array using decrRef() as it is no more needed. The array
2047  *          does not contain any textual info on components.
2048  *  \throw If \a this->getNumberOfComponents() != 2.
2049  */
2050 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
2051 {
2052   checkAllocated();
2053   int nbOfComp(getNumberOfComponents());
2054   if(nbOfComp!=2)
2055     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
2056   int nbOfTuple(getNumberOfTuples());
2057   DataArrayDouble *ret(DataArrayDouble::New());
2058   ret->alloc(nbOfTuple,2);
2059   double *w(ret->getPointer());
2060   const double *wIn(getConstPointer());
2061   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
2062     {
2063       w[0]=wIn[0]*cos(wIn[1]);
2064       w[1]=wIn[0]*sin(wIn[1]);
2065     }
2066   return ret;
2067 }
2068
2069 /*!
2070  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
2071  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2072  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
2073  * the Cylindrical CS.
2074  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2075  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2076  *          on the third component is copied from \a this array. The caller
2077  *          is to delete this array using decrRef() as it is no more needed. 
2078  *  \throw If \a this->getNumberOfComponents() != 3.
2079  */
2080 DataArrayDouble *DataArrayDouble::fromCylToCart() const
2081 {
2082   checkAllocated();
2083   int nbOfComp(getNumberOfComponents());
2084   if(nbOfComp!=3)
2085     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
2086   int nbOfTuple(getNumberOfTuples());
2087   DataArrayDouble *ret(DataArrayDouble::New());
2088   ret->alloc(getNumberOfTuples(),3);
2089   double *w(ret->getPointer());
2090   const double *wIn(getConstPointer());
2091   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2092     {
2093       w[0]=wIn[0]*cos(wIn[1]);
2094       w[1]=wIn[0]*sin(wIn[1]);
2095       w[2]=wIn[2];
2096     }
2097   ret->setInfoOnComponent(2,getInfoOnComponent(2));
2098   return ret;
2099 }
2100
2101 /*!
2102  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
2103  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2104  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
2105  * point in the Cylindrical CS.
2106  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2107  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2108  *          on the third component is copied from \a this array. The caller
2109  *          is to delete this array using decrRef() as it is no more needed.
2110  *  \throw If \a this->getNumberOfComponents() != 3.
2111  */
2112 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
2113 {
2114   checkAllocated();
2115   int nbOfComp(getNumberOfComponents());
2116   if(nbOfComp!=3)
2117     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
2118   int nbOfTuple(getNumberOfTuples());
2119   DataArrayDouble *ret(DataArrayDouble::New());
2120   ret->alloc(getNumberOfTuples(),3);
2121   double *w(ret->getPointer());
2122   const double *wIn(getConstPointer());
2123   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2124     {
2125       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
2126       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
2127       w[2]=wIn[0]*cos(wIn[1]);
2128     }
2129   return ret;
2130 }
2131
2132 /*!
2133  * 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.
2134  * 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.
2135  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
2136  *
2137  * \param [in] atOfThis - The axis type of \a this.
2138  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
2139  */
2140 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
2141 {
2142   checkAllocated();
2143   int nbOfComp(getNumberOfComponents());
2144   MCAuto<DataArrayDouble> ret;
2145   switch(atOfThis)
2146     {
2147     case AX_CART:
2148       ret=deepCopy();
2149     case AX_CYL:
2150       if(nbOfComp==3)
2151         {
2152           ret=fromCylToCart();
2153           break;
2154         }
2155       if(nbOfComp==2)
2156         {
2157           ret=fromPolarToCart();
2158           break;
2159         }
2160       else
2161         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2162     case AX_SPHER:
2163       if(nbOfComp==3)
2164         {
2165           ret=fromSpherToCart();
2166           break;
2167         }
2168       if(nbOfComp==2)
2169         {
2170           ret=fromPolarToCart();
2171           break;
2172         }
2173       else
2174         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2175     default:
2176       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
2177     }
2178   ret->copyStringInfoFrom(*this);
2179   return ret.retn();
2180 }
2181
2182 /*!
2183  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2184  * array contating 6 components.
2185  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2186  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
2187  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2188  *         The caller is to delete this result array using decrRef() as it is no more needed. 
2189  *  \throw If \a this->getNumberOfComponents() != 6.
2190  */
2191 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2192 {
2193   checkAllocated();
2194   int nbOfComp(getNumberOfComponents());
2195   if(nbOfComp!=6)
2196     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2197   DataArrayDouble *ret=DataArrayDouble::New();
2198   int nbOfTuple=getNumberOfTuples();
2199   ret->alloc(nbOfTuple,1);
2200   const double *src=getConstPointer();
2201   double *dest=ret->getPointer();
2202   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2203     *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];
2204   return ret;
2205 }
2206
2207 /*!
2208  * Computes the determinant of every square matrix defined by the tuple of \a this
2209  * array, which contains either 4, 6 or 9 components. The case of 6 components
2210  * corresponds to that of the upper triangular matrix.
2211  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2212  *          is the determinant of matrix of the corresponding tuple of \a this array.
2213  *          The caller is to delete this result array using decrRef() as it is no more
2214  *          needed. 
2215  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2216  */
2217 DataArrayDouble *DataArrayDouble::determinant() const
2218 {
2219   checkAllocated();
2220   DataArrayDouble *ret=DataArrayDouble::New();
2221   int nbOfTuple=getNumberOfTuples();
2222   ret->alloc(nbOfTuple,1);
2223   const double *src=getConstPointer();
2224   double *dest=ret->getPointer();
2225   switch(getNumberOfComponents())
2226   {
2227     case 6:
2228       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2229         *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];
2230       return ret;
2231     case 4:
2232       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2233         *dest=src[0]*src[3]-src[1]*src[2];
2234       return ret;
2235     case 9:
2236       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2237         *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];
2238       return ret;
2239     default:
2240       ret->decrRef();
2241       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2242   }
2243 }
2244
2245 /*!
2246  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2247  * \a this array, which contains 6 components.
2248  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2249  *          components, whose each tuple contains the eigenvalues of the matrix of
2250  *          corresponding tuple of \a this array. 
2251  *          The caller is to delete this result array using decrRef() as it is no more
2252  *          needed. 
2253  *  \throw If \a this->getNumberOfComponents() != 6.
2254  */
2255 DataArrayDouble *DataArrayDouble::eigenValues() const
2256 {
2257   checkAllocated();
2258   int nbOfComp=getNumberOfComponents();
2259   if(nbOfComp!=6)
2260     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2261   DataArrayDouble *ret=DataArrayDouble::New();
2262   int nbOfTuple=getNumberOfTuples();
2263   ret->alloc(nbOfTuple,3);
2264   const double *src=getConstPointer();
2265   double *dest=ret->getPointer();
2266   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2267     INTERP_KERNEL::computeEigenValues6(src,dest);
2268   return ret;
2269 }
2270
2271 /*!
2272  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2273  * \a this array, which contains 6 components.
2274  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2275  *          components, whose each tuple contains 3 eigenvectors of the matrix of
2276  *          corresponding tuple of \a this array.
2277  *          The caller is to delete this result array using decrRef() as it is no more
2278  *          needed.
2279  *  \throw If \a this->getNumberOfComponents() != 6.
2280  */
2281 DataArrayDouble *DataArrayDouble::eigenVectors() const
2282 {
2283   checkAllocated();
2284   int nbOfComp=getNumberOfComponents();
2285   if(nbOfComp!=6)
2286     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2287   DataArrayDouble *ret=DataArrayDouble::New();
2288   int nbOfTuple=getNumberOfTuples();
2289   ret->alloc(nbOfTuple,9);
2290   const double *src=getConstPointer();
2291   double *dest=ret->getPointer();
2292   for(int i=0;i<nbOfTuple;i++,src+=6)
2293     {
2294       double tmp[3];
2295       INTERP_KERNEL::computeEigenValues6(src,tmp);
2296       for(int j=0;j<3;j++,dest+=3)
2297         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2298     }
2299   return ret;
2300 }
2301
2302 /*!
2303  * Computes the inverse matrix of every matrix defined by the tuple of \a this
2304  * array, which contains either 4, 6 or 9 components. The case of 6 components
2305  * corresponds to that of the upper triangular matrix.
2306  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2307  *          same number of components as \a this one, whose each tuple is the inverse
2308  *          matrix of the matrix of corresponding tuple of \a this array. 
2309  *          The caller is to delete this result array using decrRef() as it is no more
2310  *          needed. 
2311  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2312  */
2313 DataArrayDouble *DataArrayDouble::inverse() const
2314 {
2315   checkAllocated();
2316   int nbOfComp=getNumberOfComponents();
2317   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2318     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2319   DataArrayDouble *ret=DataArrayDouble::New();
2320   int nbOfTuple=getNumberOfTuples();
2321   ret->alloc(nbOfTuple,nbOfComp);
2322   const double *src=getConstPointer();
2323   double *dest=ret->getPointer();
2324   if(nbOfComp==6)
2325     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2326       {
2327         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];
2328         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2329         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2330         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2331         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2332         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2333         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2334       }
2335   else if(nbOfComp==4)
2336     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2337       {
2338         double det=src[0]*src[3]-src[1]*src[2];
2339         dest[0]=src[3]/det;
2340         dest[1]=-src[1]/det;
2341         dest[2]=-src[2]/det;
2342         dest[3]=src[0]/det;
2343       }
2344   else
2345     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2346       {
2347         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];
2348         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2349         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2350         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2351         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2352         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2353         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2354         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2355         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2356         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2357       }
2358   return ret;
2359 }
2360
2361 /*!
2362  * Computes the trace of every matrix defined by the tuple of \a this
2363  * array, which contains either 4, 6 or 9 components. The case of 6 components
2364  * corresponds to that of the upper triangular matrix.
2365  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
2366  *          1 component, whose each tuple is the trace of
2367  *          the matrix of corresponding tuple of \a this array. 
2368  *          The caller is to delete this result array using decrRef() as it is no more
2369  *          needed. 
2370  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2371  */
2372 DataArrayDouble *DataArrayDouble::trace() const
2373 {
2374   checkAllocated();
2375   int nbOfComp=getNumberOfComponents();
2376   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2377     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2378   DataArrayDouble *ret=DataArrayDouble::New();
2379   int nbOfTuple=getNumberOfTuples();
2380   ret->alloc(nbOfTuple,1);
2381   const double *src=getConstPointer();
2382   double *dest=ret->getPointer();
2383   if(nbOfComp==6)
2384     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2385       *dest=src[0]+src[1]+src[2];
2386   else if(nbOfComp==4)
2387     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2388       *dest=src[0]+src[3];
2389   else
2390     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2391       *dest=src[0]+src[4]+src[8];
2392   return ret;
2393 }
2394
2395 /*!
2396  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2397  * \a this array, which contains 6 components.
2398  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2399  *          same number of components and tuples as \a this array.
2400  *          The caller is to delete this result array using decrRef() as it is no more
2401  *          needed.
2402  *  \throw If \a this->getNumberOfComponents() != 6.
2403  */
2404 DataArrayDouble *DataArrayDouble::deviator() const
2405 {
2406   checkAllocated();
2407   int nbOfComp=getNumberOfComponents();
2408   if(nbOfComp!=6)
2409     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2410   DataArrayDouble *ret=DataArrayDouble::New();
2411   int nbOfTuple=getNumberOfTuples();
2412   ret->alloc(nbOfTuple,6);
2413   const double *src=getConstPointer();
2414   double *dest=ret->getPointer();
2415   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2416     {
2417       double tr=(src[0]+src[1]+src[2])/3.;
2418       dest[0]=src[0]-tr;
2419       dest[1]=src[1]-tr;
2420       dest[2]=src[2]-tr;
2421       dest[3]=src[3];
2422       dest[4]=src[4];
2423       dest[5]=src[5];
2424     }
2425   return ret;
2426 }
2427
2428 /*!
2429  * Computes the magnitude of every vector defined by the tuple of
2430  * \a this array.
2431  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2432  *          same number of tuples as \a this array and one component.
2433  *          The caller is to delete this result array using decrRef() as it is no more
2434  *          needed.
2435  *  \throw If \a this is not allocated.
2436  */
2437 DataArrayDouble *DataArrayDouble::magnitude() const
2438 {
2439   checkAllocated();
2440   int nbOfComp=getNumberOfComponents();
2441   DataArrayDouble *ret=DataArrayDouble::New();
2442   int nbOfTuple=getNumberOfTuples();
2443   ret->alloc(nbOfTuple,1);
2444   const double *src=getConstPointer();
2445   double *dest=ret->getPointer();
2446   for(int i=0;i<nbOfTuple;i++,dest++)
2447     {
2448       double sum=0.;
2449       for(int j=0;j<nbOfComp;j++,src++)
2450         sum+=(*src)*(*src);
2451       *dest=sqrt(sum);
2452     }
2453   return ret;
2454 }
2455
2456 /*!
2457  * Computes for each tuple the sum of number of components values in the tuple and return it.
2458  * 
2459  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2460  *          same number of tuples as \a this array and one component.
2461  *          The caller is to delete this result array using decrRef() as it is no more
2462  *          needed.
2463  *  \throw If \a this is not allocated.
2464  */
2465 DataArrayDouble *DataArrayDouble::sumPerTuple() const
2466 {
2467   checkAllocated();
2468   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2469   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2470   ret->alloc(nbOfTuple,1);
2471   const double *src(getConstPointer());
2472   double *dest(ret->getPointer());
2473   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2474     *dest=std::accumulate(src,src+nbOfComp,0.);
2475   return ret.retn();
2476 }
2477
2478 /*!
2479  * Computes the maximal value within every tuple of \a this array.
2480  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2481  *          same number of tuples as \a this array and one component.
2482  *          The caller is to delete this result array using decrRef() as it is no more
2483  *          needed.
2484  *  \throw If \a this is not allocated.
2485  *  \sa DataArrayDouble::maxPerTupleWithCompoId
2486  */
2487 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2488 {
2489   checkAllocated();
2490   int nbOfComp=getNumberOfComponents();
2491   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2492   int nbOfTuple=getNumberOfTuples();
2493   ret->alloc(nbOfTuple,1);
2494   const double *src=getConstPointer();
2495   double *dest=ret->getPointer();
2496   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2497     *dest=*std::max_element(src,src+nbOfComp);
2498   return ret.retn();
2499 }
2500
2501 /*!
2502  * Computes the maximal value within every tuple of \a this array and it returns the first component
2503  * id for each tuple that corresponds to the maximal value within the tuple.
2504  * 
2505  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2506  *          same number of tuples and only one component.
2507  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2508  *          same number of tuples as \a this array and one component.
2509  *          The caller is to delete this result array using decrRef() as it is no more
2510  *          needed.
2511  *  \throw If \a this is not allocated.
2512  *  \sa DataArrayDouble::maxPerTuple
2513  */
2514 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2515 {
2516   checkAllocated();
2517   int nbOfComp=getNumberOfComponents();
2518   MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2519   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2520   int nbOfTuple=getNumberOfTuples();
2521   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2522   const double *src=getConstPointer();
2523   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2524   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2525     {
2526       const double *loc=std::max_element(src,src+nbOfComp);
2527       *dest=*loc;
2528       *dest1=(int)std::distance(src,loc);
2529     }
2530   compoIdOfMaxPerTuple=ret1.retn();
2531   return ret0.retn();
2532 }
2533
2534 /*!
2535  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2536  * \n This returned array contains the euclidian distance for each tuple in \a this. 
2537  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2538  * \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)
2539  *
2540  * \warning use this method with care because it can leads to big amount of consumed memory !
2541  * 
2542  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2543  *
2544  * \throw If \a this is not allocated.
2545  *
2546  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2547  */
2548 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2549 {
2550   checkAllocated();
2551   int nbOfComp=getNumberOfComponents();
2552   int nbOfTuples=getNumberOfTuples();
2553   const double *inData=getConstPointer();
2554   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2555   ret->alloc(nbOfTuples*nbOfTuples,1);
2556   double *outData=ret->getPointer();
2557   for(int i=0;i<nbOfTuples;i++)
2558     {
2559       outData[i*nbOfTuples+i]=0.;
2560       for(int j=i+1;j<nbOfTuples;j++)
2561         {
2562           double dist=0.;
2563           for(int k=0;k<nbOfComp;k++)
2564             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2565           dist=sqrt(dist);
2566           outData[i*nbOfTuples+j]=dist;
2567           outData[j*nbOfTuples+i]=dist;
2568         }
2569     }
2570   return ret.retn();
2571 }
2572
2573 /*!
2574  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2575  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
2576  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2577  * \n Output rectangular matrix is sorted along rows.
2578  * \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)
2579  *
2580  * \warning use this method with care because it can leads to big amount of consumed memory !
2581  * 
2582  * \param [in] other DataArrayDouble instance having same number of components than \a this.
2583  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2584  *
2585  * \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.
2586  *
2587  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2588  */
2589 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2590 {
2591   if(!other)
2592     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2593   checkAllocated();
2594   other->checkAllocated();
2595   int nbOfComp=getNumberOfComponents();
2596   int otherNbOfComp=other->getNumberOfComponents();
2597   if(nbOfComp!=otherNbOfComp)
2598     {
2599       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2600       throw INTERP_KERNEL::Exception(oss.str().c_str());
2601     }
2602   int nbOfTuples=getNumberOfTuples();
2603   int otherNbOfTuples=other->getNumberOfTuples();
2604   const double *inData=getConstPointer();
2605   const double *inDataOther=other->getConstPointer();
2606   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2607   ret->alloc(otherNbOfTuples*nbOfTuples,1);
2608   double *outData=ret->getPointer();
2609   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2610     {
2611       for(int j=0;j<nbOfTuples;j++)
2612         {
2613           double dist=0.;
2614           for(int k=0;k<nbOfComp;k++)
2615             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2616           dist=sqrt(dist);
2617           outData[i*nbOfTuples+j]=dist;
2618         }
2619     }
2620   return ret.retn();
2621 }
2622
2623 /*!
2624  * Sorts value within every tuple of \a this array.
2625  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
2626  *              in descending order.
2627  *  \throw If \a this is not allocated.
2628  */
2629 void DataArrayDouble::sortPerTuple(bool asc)
2630 {
2631   checkAllocated();
2632   double *pt=getPointer();
2633   int nbOfTuple=getNumberOfTuples();
2634   int nbOfComp=getNumberOfComponents();
2635   if(asc)
2636     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2637       std::sort(pt,pt+nbOfComp);
2638   else
2639     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2640       std::sort(pt,pt+nbOfComp,std::greater<double>());
2641   declareAsNew();
2642 }
2643
2644 /*!
2645  * Converts every value of \a this array to its absolute value.
2646  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
2647  * should be called instead.
2648  *
2649  * \throw If \a this is not allocated.
2650  * \sa DataArrayDouble::computeAbs
2651  */
2652 void DataArrayDouble::abs()
2653 {
2654   checkAllocated();
2655   double *ptr(getPointer());
2656   std::size_t nbOfElems(getNbOfElems());
2657   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
2658   declareAsNew();
2659 }
2660
2661 /*!
2662  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
2663  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
2664  *
2665  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2666  *         same number of tuples and component as \a this array.
2667  *         The caller is to delete this result array using decrRef() as it is no more
2668  *         needed.
2669  * \throw If \a this is not allocated.
2670  * \sa DataArrayDouble::abs
2671  */
2672 DataArrayDouble *DataArrayDouble::computeAbs() const
2673 {
2674   checkAllocated();
2675   DataArrayDouble *newArr(DataArrayDouble::New());
2676   int nbOfTuples(getNumberOfTuples());
2677   int nbOfComp(getNumberOfComponents());
2678   newArr->alloc(nbOfTuples,nbOfComp);
2679   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
2680   newArr->copyStringInfoFrom(*this);
2681   return newArr;
2682 }
2683
2684 /*!
2685  * Apply a linear function to a given component of \a this array, so that
2686  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
2687  *  \param [in] a - the first coefficient of the function.
2688  *  \param [in] b - the second coefficient of the function.
2689  *  \param [in] compoId - the index of component to modify.
2690  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
2691  */
2692 void DataArrayDouble::applyLin(double a, double b, int compoId)
2693 {
2694   checkAllocated();
2695   double *ptr(getPointer()+compoId);
2696   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2697   if(compoId<0 || compoId>=nbOfComp)
2698     {
2699       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
2700       throw INTERP_KERNEL::Exception(oss.str().c_str());
2701     }
2702   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
2703     *ptr=a*(*ptr)+b;
2704   declareAsNew();
2705 }
2706
2707 /*!
2708  * Apply a linear function to all elements of \a this array, so that
2709  * an element _x_ becomes \f$ a * x + b \f$.
2710  *  \param [in] a - the first coefficient of the function.
2711  *  \param [in] b - the second coefficient of the function.
2712  *  \throw If \a this is not allocated.
2713  */
2714 void DataArrayDouble::applyLin(double a, double b)
2715 {
2716   checkAllocated();
2717   double *ptr=getPointer();
2718   std::size_t nbOfElems=getNbOfElems();
2719   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2720     *ptr=a*(*ptr)+b;
2721   declareAsNew();
2722 }
2723
2724 /*!
2725  * Modify all elements of \a this array, so that
2726  * an element _x_ becomes \f$ numerator / x \f$.
2727  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
2728  *           array, all elements processed before detection of the zero element remain
2729  *           modified.
2730  *  \param [in] numerator - the numerator used to modify array elements.
2731  *  \throw If \a this is not allocated.
2732  *  \throw If there is an element equal to 0.0 in \a this array.
2733  */
2734 void DataArrayDouble::applyInv(double numerator)
2735 {
2736   checkAllocated();
2737   double *ptr=getPointer();
2738   std::size_t nbOfElems=getNbOfElems();
2739   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2740     {
2741       if(std::abs(*ptr)>std::numeric_limits<double>::min())
2742         {
2743           *ptr=numerator/(*ptr);
2744         }
2745       else
2746         {
2747           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2748           oss << " !";
2749           throw INTERP_KERNEL::Exception(oss.str().c_str());
2750         }
2751     }
2752   declareAsNew();
2753 }
2754
2755 /*!
2756  * Returns a full copy of \a this array except that sign of all elements is reversed.
2757  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2758  *          same number of tuples and component as \a this array.
2759  *          The caller is to delete this result array using decrRef() as it is no more
2760  *          needed.
2761  *  \throw If \a this is not allocated.
2762  */
2763 DataArrayDouble *DataArrayDouble::negate() const
2764 {
2765   checkAllocated();
2766   DataArrayDouble *newArr=DataArrayDouble::New();
2767   int nbOfTuples=getNumberOfTuples();
2768   int nbOfComp=getNumberOfComponents();
2769   newArr->alloc(nbOfTuples,nbOfComp);
2770   const double *cptr=getConstPointer();
2771   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
2772   newArr->copyStringInfoFrom(*this);
2773   return newArr;
2774 }
2775
2776 /*!
2777  * Modify all elements of \a this array, so that
2778  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2779  * all values in \a this have to be >= 0 if val is \b not integer.
2780  *  \param [in] val - the value used to apply pow on all array elements.
2781  *  \throw If \a this is not allocated.
2782  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2783  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
2784  *           modified.
2785  */
2786 void DataArrayDouble::applyPow(double val)
2787 {
2788   checkAllocated();
2789   double *ptr=getPointer();
2790   std::size_t nbOfElems=getNbOfElems();
2791   int val2=(int)val;
2792   bool isInt=((double)val2)==val;
2793   if(!isInt)
2794     {
2795       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2796         {
2797           if(*ptr>=0)
2798             *ptr=pow(*ptr,val);
2799           else
2800             {
2801               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2802               throw INTERP_KERNEL::Exception(oss.str().c_str());
2803             }
2804         }
2805     }
2806   else
2807     {
2808       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2809         *ptr=pow(*ptr,val2);
2810     }
2811   declareAsNew();
2812 }
2813
2814 /*!
2815  * Modify all elements of \a this array, so that
2816  * an element _x_ becomes \f$ val ^ x \f$.
2817  *  \param [in] val - the value used to apply pow on all array elements.
2818  *  \throw If \a this is not allocated.
2819  *  \throw If \a val < 0.
2820  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2821  *           array, all elements processed before detection of the zero element remain
2822  *           modified.
2823  */
2824 void DataArrayDouble::applyRPow(double val)
2825 {
2826   checkAllocated();
2827   if(val<0.)
2828     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2829   double *ptr=getPointer();
2830   std::size_t nbOfElems=getNbOfElems();
2831   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2832     *ptr=pow(val,*ptr);
2833   declareAsNew();
2834 }
2835
2836 /*!
2837  * Returns a new DataArrayDouble created from \a this one by applying \a
2838  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2839  * For more info see \ref MEDCouplingArrayApplyFunc
2840  *  \param [in] nbOfComp - number of components in the result array.
2841  *  \param [in] func - the \a FunctionToEvaluate declared as 
2842  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
2843  *              where \a pos points to the first component of a tuple of \a this array
2844  *              and \a res points to the first component of a tuple of the result array.
2845  *              Note that length (number of components) of \a pos can differ from
2846  *              that of \a res.
2847  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2848  *          same number of tuples as \a this array.
2849  *          The caller is to delete this result array using decrRef() as it is no more
2850  *          needed.
2851  *  \throw If \a this is not allocated.
2852  *  \throw If \a func returns \a false.
2853  */
2854 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2855 {
2856   checkAllocated();
2857   DataArrayDouble *newArr=DataArrayDouble::New();
2858   int nbOfTuples=getNumberOfTuples();
2859   int oldNbOfComp=getNumberOfComponents();
2860   newArr->alloc(nbOfTuples,nbOfComp);
2861   const double *ptr=getConstPointer();
2862   double *ptrToFill=newArr->getPointer();
2863   for(int i=0;i<nbOfTuples;i++)
2864     {
2865       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2866         {
2867           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2868           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2869           oss << ") : Evaluation of function failed !";
2870           newArr->decrRef();
2871           throw INTERP_KERNEL::Exception(oss.str().c_str());
2872         }
2873     }
2874   return newArr;
2875 }
2876
2877 /*!
2878  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2879  * tuple of \a this array. Textual data is not copied.
2880  * For more info see \ref MEDCouplingArrayApplyFunc1.
2881  *  \param [in] nbOfComp - number of components in the result array.
2882  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2883  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2884  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2885  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2886  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2887  *          same number of tuples as \a this array and \a nbOfComp components.
2888  *          The caller is to delete this result array using decrRef() as it is no more
2889  *          needed.
2890  *  \throw If \a this is not allocated.
2891  *  \throw If computing \a func fails.
2892  */
2893 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2894 {
2895   INTERP_KERNEL::ExprParser expr(func);
2896   expr.parse();
2897   std::set<std::string> vars;
2898   expr.getTrueSetOfVars(vars);
2899   std::vector<std::string> varsV(vars.begin(),vars.end());
2900   return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2901 }
2902
2903 /*!
2904  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2905  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2906  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2907  *
2908  * For more info see \ref MEDCouplingArrayApplyFunc0.
2909  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2910  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2911  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2912  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
2913  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2914  *          same number of tuples and components as \a this array.
2915  *          The caller is to delete this result array using decrRef() as it is no more
2916  *          needed.
2917  *  \sa applyFuncOnThis
2918  *  \throw If \a this is not allocated.
2919  *  \throw If computing \a func fails.
2920  */
2921 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
2922 {
2923   int nbOfComp(getNumberOfComponents());
2924   if(nbOfComp<=0)
2925     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
2926   checkAllocated();
2927   int nbOfTuples(getNumberOfTuples());
2928   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2929   newArr->alloc(nbOfTuples,nbOfComp);
2930   INTERP_KERNEL::ExprParser expr(func);
2931   expr.parse();
2932   std::set<std::string> vars;
2933   expr.getTrueSetOfVars(vars);
2934   if((int)vars.size()>1)
2935     {
2936       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 : ";
2937       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2938       throw INTERP_KERNEL::Exception(oss.str().c_str());
2939     }
2940   if(vars.empty())
2941     {
2942       expr.prepareFastEvaluator();
2943       newArr->rearrange(1);
2944       newArr->fillWithValue(expr.evaluateDouble());
2945       newArr->rearrange(nbOfComp);
2946       return newArr.retn();
2947     }
2948   std::vector<std::string> vars2(vars.begin(),vars.end());
2949   double buff,*ptrToFill(newArr->getPointer());
2950   const double *ptr(begin());
2951   std::vector<double> stck;
2952   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2953   expr.prepareFastEvaluator();
2954   if(!isSafe)
2955     {
2956       for(int i=0;i<nbOfTuples;i++)
2957         {
2958           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2959             {
2960               buff=*ptr;
2961               expr.evaluateDoubleInternal(stck);
2962               *ptrToFill=stck.back();
2963               stck.pop_back();
2964             }
2965         }
2966     }
2967   else
2968     {
2969       for(int i=0;i<nbOfTuples;i++)
2970         {
2971           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2972             {
2973               buff=*ptr;
2974               try
2975               {
2976                   expr.evaluateDoubleInternalSafe(stck);
2977               }
2978               catch(INTERP_KERNEL::Exception& e)
2979               {
2980                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2981                   oss << buff;
2982                   oss << ") : Evaluation of function failed !" << e.what();
2983                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2984               }
2985               *ptrToFill=stck.back();
2986               stck.pop_back();
2987             }
2988         }
2989     }
2990   return newArr.retn();
2991 }
2992
2993 /*!
2994  * This method is a non const method that modify the array in \a this.
2995  * This method only works on one component array. It means that function \a func must
2996  * contain at most one variable.
2997  * This method is a specialization of applyFunc method with one parameter on one component array.
2998  *
2999  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3000  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3001  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3002  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3003  *
3004  * \sa applyFunc
3005  */
3006 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
3007 {
3008   int nbOfComp(getNumberOfComponents());
3009   if(nbOfComp<=0)
3010     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
3011   checkAllocated();
3012   int nbOfTuples(getNumberOfTuples());
3013   INTERP_KERNEL::ExprParser expr(func);
3014   expr.parse();
3015   std::set<std::string> vars;
3016   expr.getTrueSetOfVars(vars);
3017   if((int)vars.size()>1)
3018     {
3019       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 : ";
3020       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3021       throw INTERP_KERNEL::Exception(oss.str().c_str());
3022     }
3023   if(vars.empty())
3024     {
3025       expr.prepareFastEvaluator();
3026       std::vector<std::string> compInfo(getInfoOnComponents());
3027       rearrange(1);
3028       fillWithValue(expr.evaluateDouble());
3029       rearrange(nbOfComp);
3030       setInfoOnComponents(compInfo);
3031       return ;
3032     }
3033   std::vector<std::string> vars2(vars.begin(),vars.end());
3034   double buff,*ptrToFill(getPointer());
3035   const double *ptr(begin());
3036   std::vector<double> stck;
3037   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3038   expr.prepareFastEvaluator();
3039   if(!isSafe)
3040     {
3041       for(int i=0;i<nbOfTuples;i++)
3042         {
3043           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3044             {
3045               buff=*ptr;
3046               expr.evaluateDoubleInternal(stck);
3047               *ptrToFill=stck.back();
3048               stck.pop_back();
3049             }
3050         }
3051     }
3052   else
3053     {
3054       for(int i=0;i<nbOfTuples;i++)
3055         {
3056           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3057             {
3058               buff=*ptr;
3059               try
3060               {
3061                   expr.evaluateDoubleInternalSafe(stck);
3062               }
3063               catch(INTERP_KERNEL::Exception& e)
3064               {
3065                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3066                   oss << buff;
3067                   oss << ") : Evaluation of function failed !" << e.what();
3068                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3069               }
3070               *ptrToFill=stck.back();
3071               stck.pop_back();
3072             }
3073         }
3074     }
3075 }
3076
3077 /*!
3078  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3079  * tuple of \a this array. Textual data is not copied.
3080  * For more info see \ref MEDCouplingArrayApplyFunc2.
3081  *  \param [in] nbOfComp - number of components in the result array.
3082  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3083  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3084  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3085  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3086  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3087  *          same number of tuples as \a this array.
3088  *          The caller is to delete this result array using decrRef() as it is no more
3089  *          needed.
3090  *  \throw If \a this is not allocated.
3091  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
3092  *  \throw If computing \a func fails.
3093  */
3094 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
3095 {
3096   return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
3097 }
3098
3099 /*!
3100  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3101  * tuple of \a this array. Textual data is not copied.
3102  * For more info see \ref MEDCouplingArrayApplyFunc3.
3103  *  \param [in] nbOfComp - number of components in the result array.
3104  *  \param [in] varsOrder - sequence of vars defining their order.
3105  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3106  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3107  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3108  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3109  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3110  *          same number of tuples as \a this array.
3111  *          The caller is to delete this result array using decrRef() as it is no more
3112  *          needed.
3113  *  \throw If \a this is not allocated.
3114  *  \throw If \a func contains vars not in \a varsOrder.
3115  *  \throw If computing \a func fails.
3116  */
3117 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
3118 {
3119   if(nbOfComp<=0)
3120     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
3121   std::vector<std::string> varsOrder2(varsOrder);
3122   int oldNbOfComp(getNumberOfComponents());
3123   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
3124     varsOrder2.push_back(std::string());
3125   checkAllocated();
3126   int nbOfTuples(getNumberOfTuples());
3127   INTERP_KERNEL::ExprParser expr(func);
3128   expr.parse();
3129   std::set<std::string> vars;
3130   expr.getTrueSetOfVars(vars);
3131   if((int)vars.size()>oldNbOfComp)
3132     {
3133       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3134       oss << vars.size() << " variables : ";
3135       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3136       throw INTERP_KERNEL::Exception(oss.str().c_str());
3137     }
3138   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3139   newArr->alloc(nbOfTuples,nbOfComp);
3140   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
3141   double *buffPtr(buff),*ptrToFill;
3142   std::vector<double> stck;
3143   for(int iComp=0;iComp<nbOfComp;iComp++)
3144     {
3145       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
3146       expr.prepareFastEvaluator();
3147       const double *ptr(getConstPointer());
3148       ptrToFill=newArr->getPointer()+iComp;
3149       if(!isSafe)
3150         {
3151           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3152             {
3153               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3154               expr.evaluateDoubleInternal(stck);
3155               *ptrToFill=stck.back();
3156               stck.pop_back();
3157             }
3158         }
3159       else
3160         {
3161           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3162             {
3163               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3164               try
3165               {
3166                   expr.evaluateDoubleInternalSafe(stck);
3167                   *ptrToFill=stck.back();
3168                   stck.pop_back();
3169               }
3170               catch(INTERP_KERNEL::Exception& e)
3171               {
3172                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3173                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3174                   oss << ") : Evaluation of function failed !" << e.what();
3175                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3176               }
3177             }
3178         }
3179     }
3180   return newArr.retn();
3181 }
3182
3183 void DataArrayDouble::applyFuncFast32(const std::string& func)
3184 {
3185   checkAllocated();
3186   INTERP_KERNEL::ExprParser expr(func);
3187   expr.parse();
3188   char *funcStr=expr.compileX86();
3189   MYFUNCPTR funcPtr;
3190   *((void **)&funcPtr)=funcStr;//he he...
3191   //
3192   double *ptr=getPointer();
3193   int nbOfComp=getNumberOfComponents();
3194   int nbOfTuples=getNumberOfTuples();
3195   int nbOfElems=nbOfTuples*nbOfComp;
3196   for(int i=0;i<nbOfElems;i++,ptr++)
3197     *ptr=funcPtr(*ptr);
3198   declareAsNew();
3199 }
3200
3201 void DataArrayDouble::applyFuncFast64(const std::string& func)
3202 {
3203   checkAllocated();
3204   INTERP_KERNEL::ExprParser expr(func);
3205   expr.parse();
3206   char *funcStr=expr.compileX86_64();
3207   MYFUNCPTR funcPtr;
3208   *((void **)&funcPtr)=funcStr;//he he...
3209   //
3210   double *ptr=getPointer();
3211   int nbOfComp=getNumberOfComponents();
3212   int nbOfTuples=getNumberOfTuples();
3213   int nbOfElems=nbOfTuples*nbOfComp;
3214   for(int i=0;i<nbOfElems;i++,ptr++)
3215     *ptr=funcPtr(*ptr);
3216   declareAsNew();
3217 }
3218
3219 /*!
3220  * \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.
3221  */
3222 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3223 {
3224   checkAllocated();
3225   if(getNumberOfComponents()!=3)
3226     throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3227   int nbTuples(getNumberOfTuples());
3228   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3229   ret->alloc(nbTuples,3);
3230   Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3231   return ret;
3232 }
3233
3234 DataArrayDoubleIterator *DataArrayDouble::iterator()
3235 {
3236   return new DataArrayDoubleIterator(this);
3237 }
3238
3239 /*!
3240  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3241  * array whose values are within a given range. Textual data is not copied.
3242  *  \param [in] vmin - a lowest acceptable value (included).
3243  *  \param [in] vmax - a greatest acceptable value (included).
3244  *  \return DataArrayInt * - the new instance of DataArrayInt.
3245  *          The caller is to delete this result array using decrRef() as it is no more
3246  *          needed.
3247  *  \throw If \a this->getNumberOfComponents() != 1.
3248  *
3249  *  \sa DataArrayDouble::findIdsNotInRange
3250  *
3251  *  \if ENABLE_EXAMPLES
3252  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3253  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3254  *  \endif
3255  */
3256 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3257 {
3258   checkAllocated();
3259   if(getNumberOfComponents()!=1)
3260     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3261   const double *cptr(begin());
3262   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3263   int nbOfTuples(getNumberOfTuples());
3264   for(int i=0;i<nbOfTuples;i++,cptr++)
3265     if(*cptr>=vmin && *cptr<=vmax)
3266       ret->pushBackSilent(i);
3267   return ret.retn();
3268 }
3269
3270 /*!
3271  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3272  * array whose values are not within a given range. Textual data is not copied.
3273  *  \param [in] vmin - a lowest not acceptable value (excluded).
3274  *  \param [in] vmax - a greatest not acceptable value (excluded).
3275  *  \return DataArrayInt * - the new instance of DataArrayInt.
3276  *          The caller is to delete this result array using decrRef() as it is no more
3277  *          needed.
3278  *  \throw If \a this->getNumberOfComponents() != 1.
3279  *
3280  *  \sa DataArrayDouble::findIdsInRange
3281  */
3282 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3283 {
3284   checkAllocated();
3285   if(getNumberOfComponents()!=1)
3286     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3287   const double *cptr(begin());
3288   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3289   int nbOfTuples(getNumberOfTuples());
3290   for(int i=0;i<nbOfTuples;i++,cptr++)
3291     if(*cptr<vmin || *cptr>vmax)
3292       ret->pushBackSilent(i);
3293   return ret.retn();
3294 }
3295
3296 /*!
3297  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3298  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3299  * the number of component in the result array is same as that of each of given arrays.
3300  * Info on components is copied from the first of the given arrays. Number of components
3301  * in the given arrays must be  the same.
3302  *  \param [in] a1 - an array to include in the result array.
3303  *  \param [in] a2 - another array to include in the result array.
3304  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3305  *          The caller is to delete this result array using decrRef() as it is no more
3306  *          needed.
3307  *  \throw If both \a a1 and \a a2 are NULL.
3308  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3309  */
3310 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3311 {
3312   std::vector<const DataArrayDouble *> tmp(2);
3313   tmp[0]=a1; tmp[1]=a2;
3314   return Aggregate(tmp);
3315 }
3316
3317 /*!
3318  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3319  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3320  * the number of component in the result array is same as that of each of given arrays.
3321  * Info on components is copied from the first of the given arrays. Number of components
3322  * in the given arrays must be  the same.
3323  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3324  * not the object itself.
3325  *  \param [in] arr - a sequence of arrays to include in the result array.
3326  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3327  *          The caller is to delete this result array using decrRef() as it is no more
3328  *          needed.
3329  *  \throw If all arrays within \a arr are NULL.
3330  *  \throw If getNumberOfComponents() of arrays within \a arr.
3331  */
3332 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3333 {
3334   std::vector<const DataArrayDouble *> a;
3335   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3336     if(*it4)
3337       a.push_back(*it4);
3338   if(a.empty())
3339     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3340   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3341   int nbOfComp=(*it)->getNumberOfComponents();
3342   int nbt=(*it++)->getNumberOfTuples();
3343   for(int i=1;it!=a.end();it++,i++)
3344     {
3345       if((*it)->getNumberOfComponents()!=nbOfComp)
3346         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3347       nbt+=(*it)->getNumberOfTuples();
3348     }
3349   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3350   ret->alloc(nbt,nbOfComp);
3351   double *pt=ret->getPointer();
3352   for(it=a.begin();it!=a.end();it++)
3353     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3354   ret->copyStringInfoFrom(*(a[0]));
3355   return ret.retn();
3356 }
3357
3358 /*!
3359  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
3360  * of components in the result array is a sum of the number of components of given arrays
3361  * and (2) the number of tuples in the result array is same as that of each of given
3362  * arrays. In other words the i-th tuple of result array includes all components of
3363  * i-th tuples of all given arrays.
3364  * Number of tuples in the given arrays must be  the same.
3365  *  \param [in] a1 - an array to include in the result array.
3366  *  \param [in] a2 - another array to include in the result array.
3367  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3368  *          The caller is to delete this result array using decrRef() as it is no more
3369  *          needed.
3370  *  \throw If both \a a1 and \a a2 are NULL.
3371  *  \throw If any given array is not allocated.
3372  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3373  */
3374 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
3375 {
3376   std::vector<const DataArrayDouble *> arr(2);
3377   arr[0]=a1; arr[1]=a2;
3378   return Meld(arr);
3379 }
3380
3381 /*!
3382  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
3383  * of components in the result array is a sum of the number of components of given arrays
3384  * and (2) the number of tuples in the result array is same as that of each of given
3385  * arrays. In other words the i-th tuple of result array includes all components of
3386  * i-th tuples of all given arrays.
3387  * Number of tuples in the given arrays must be  the same.
3388  *  \param [in] arr - a sequence of arrays to include in the result array.
3389  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3390  *          The caller is to delete this result array using decrRef() as it is no more
3391  *          needed.
3392  *  \throw If all arrays within \a arr are NULL.
3393  *  \throw If any given array is not allocated.
3394  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
3395  */
3396 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
3397 {
3398   std::vector<const DataArrayDouble *> a;
3399   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3400     if(*it4)
3401       a.push_back(*it4);
3402   if(a.empty())
3403     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
3404   std::vector<const DataArrayDouble *>::const_iterator it;
3405   for(it=a.begin();it!=a.end();it++)
3406     (*it)->checkAllocated();
3407   it=a.begin();
3408   int nbOfTuples=(*it)->getNumberOfTuples();
3409   std::vector<int> nbc(a.size());
3410   std::vector<const double *> pts(a.size());
3411   nbc[0]=(*it)->getNumberOfComponents();
3412   pts[0]=(*it++)->getConstPointer();
3413   for(int i=1;it!=a.end();it++,i++)
3414     {
3415       if(nbOfTuples!=(*it)->getNumberOfTuples())
3416         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
3417       nbc[i]=(*it)->getNumberOfComponents();
3418       pts[i]=(*it)->getConstPointer();
3419     }
3420   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
3421   DataArrayDouble *ret=DataArrayDouble::New();
3422   ret->alloc(nbOfTuples,totalNbOfComp);
3423   double *retPtr=ret->getPointer();
3424   for(int i=0;i<nbOfTuples;i++)
3425     for(int j=0;j<(int)a.size();j++)
3426       {
3427         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
3428         pts[j]+=nbc[j];
3429       }
3430   int k=0;
3431   for(int i=0;i<(int)a.size();i++)
3432     for(int j=0;j<nbc[i];j++,k++)
3433       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
3434   return ret;
3435 }
3436
3437 /*!
3438  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3439  * the i-th tuple of the result array is a sum of products of j-th components of i-th
3440  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3441  * Info on components and name is copied from the first of the given arrays.
3442  * Number of tuples and components in the given arrays must be the same.
3443  *  \param [in] a1 - a given array.
3444  *  \param [in] a2 - another given array.
3445  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3446  *          The caller is to delete this result array using decrRef() as it is no more
3447  *          needed.
3448  *  \throw If either \a a1 or \a a2 is NULL.
3449  *  \throw If any given array is not allocated.
3450  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3451  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3452  */
3453 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3454 {
3455   if(!a1 || !a2)
3456     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3457   a1->checkAllocated();
3458   a2->checkAllocated();
3459   int nbOfComp=a1->getNumberOfComponents();
3460   if(nbOfComp!=a2->getNumberOfComponents())
3461     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3462   int nbOfTuple=a1->getNumberOfTuples();
3463   if(nbOfTuple!=a2->getNumberOfTuples())
3464     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3465   DataArrayDouble *ret=DataArrayDouble::New();
3466   ret->alloc(nbOfTuple,1);
3467   double *retPtr=ret->getPointer();
3468   const double *a1Ptr=a1->getConstPointer();
3469   const double *a2Ptr=a2->getConstPointer();
3470   for(int i=0;i<nbOfTuple;i++)
3471     {
3472       double sum=0.;
3473       for(int j=0;j<nbOfComp;j++)
3474         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3475       retPtr[i]=sum;
3476     }
3477   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3478   ret->setName(a1->getName());
3479   return ret;
3480 }
3481
3482 /*!
3483  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3484  * the i-th tuple of the result array contains 3 components of a vector which is a cross
3485  * product of two vectors defined by the i-th tuples of given arrays.
3486  * Info on components is copied from the first of the given arrays.
3487  * Number of tuples in the given arrays must be the same.
3488  * Number of components in the given arrays must be 3.
3489  *  \param [in] a1 - a given array.
3490  *  \param [in] a2 - another given array.
3491  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3492  *          The caller is to delete this result array using decrRef() as it is no more
3493  *          needed.
3494  *  \throw If either \a a1 or \a a2 is NULL.
3495  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3496  *  \throw If \a a1->getNumberOfComponents() != 3
3497  *  \throw If \a a2->getNumberOfComponents() != 3
3498  */
3499 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3500 {
3501   if(!a1 || !a2)
3502     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3503   int nbOfComp=a1->getNumberOfComponents();
3504   if(nbOfComp!=a2->getNumberOfComponents())
3505     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3506   if(nbOfComp!=3)
3507     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3508   int nbOfTuple=a1->getNumberOfTuples();
3509   if(nbOfTuple!=a2->getNumberOfTuples())
3510     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3511   DataArrayDouble *ret=DataArrayDouble::New();
3512   ret->alloc(nbOfTuple,3);
3513   double *retPtr=ret->getPointer();
3514   const double *a1Ptr=a1->getConstPointer();
3515   const double *a2Ptr=a2->getConstPointer();
3516   for(int i=0;i<nbOfTuple;i++)
3517     {
3518       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3519       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3520       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3521     }
3522   ret->copyStringInfoFrom(*a1);
3523   return ret;
3524 }
3525
3526 /*!
3527  * Returns a new DataArrayDouble containing maximal values of two given arrays.
3528  * Info on components is copied from the first of the given arrays.
3529  * Number of tuples and components in the given arrays must be the same.
3530  *  \param [in] a1 - an array to compare values with another one.
3531  *  \param [in] a2 - another array to compare values with the first one.
3532  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3533  *          The caller is to delete this result array using decrRef() as it is no more
3534  *          needed.
3535  *  \throw If either \a a1 or \a a2 is NULL.
3536  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3537  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3538  */
3539 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3540 {
3541   if(!a1 || !a2)
3542     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3543   int nbOfComp=a1->getNumberOfComponents();
3544   if(nbOfComp!=a2->getNumberOfComponents())
3545     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3546   int nbOfTuple=a1->getNumberOfTuples();
3547   if(nbOfTuple!=a2->getNumberOfTuples())
3548     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3549   DataArrayDouble *ret=DataArrayDouble::New();
3550   ret->alloc(nbOfTuple,nbOfComp);
3551   double *retPtr=ret->getPointer();
3552   const double *a1Ptr=a1->getConstPointer();
3553   const double *a2Ptr=a2->getConstPointer();
3554   int nbElem=nbOfTuple*nbOfComp;
3555   for(int i=0;i<nbElem;i++)
3556     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3557   ret->copyStringInfoFrom(*a1);
3558   return ret;
3559 }
3560
3561 /*!
3562  * Returns a new DataArrayDouble containing minimal values of two given arrays.
3563  * Info on components is copied from the first of the given arrays.
3564  * Number of tuples and components in the given arrays must be the same.
3565  *  \param [in] a1 - an array to compare values with another one.
3566  *  \param [in] a2 - another array to compare values with the first one.
3567  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3568  *          The caller is to delete this result array using decrRef() as it is no more
3569  *          needed.
3570  *  \throw If either \a a1 or \a a2 is NULL.
3571  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3572  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3573  */
3574 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3575 {
3576   if(!a1 || !a2)
3577     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3578   int nbOfComp=a1->getNumberOfComponents();
3579   if(nbOfComp!=a2->getNumberOfComponents())
3580     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3581   int nbOfTuple=a1->getNumberOfTuples();
3582   if(nbOfTuple!=a2->getNumberOfTuples())
3583     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3584   DataArrayDouble *ret=DataArrayDouble::New();
3585   ret->alloc(nbOfTuple,nbOfComp);
3586   double *retPtr=ret->getPointer();
3587   const double *a1Ptr=a1->getConstPointer();
3588   const double *a2Ptr=a2->getConstPointer();
3589   int nbElem=nbOfTuple*nbOfComp;
3590   for(int i=0;i<nbElem;i++)
3591     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3592   ret->copyStringInfoFrom(*a1);
3593   return ret;
3594 }
3595
3596 /*!
3597  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
3598  * valid cases.
3599  * 1.  The arrays have same number of tuples and components. Then each value of
3600  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
3601  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
3602  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3603  *   component. Then
3604  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
3605  * 3.  The arrays have same number of components and one array, say _a2_, has one
3606  *   tuple. Then
3607  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
3608  *
3609  * Info on components is copied either from the first array (in the first case) or from
3610  * the array with maximal number of elements (getNbOfElems()).
3611  *  \param [in] a1 - an array to sum up.
3612  *  \param [in] a2 - another array to sum up.
3613  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3614  *          The caller is to delete this result array using decrRef() as it is no more
3615  *          needed.
3616  *  \throw If either \a a1 or \a a2 is NULL.
3617  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3618  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3619  *         none of them has number of tuples or components equal to 1.
3620  */
3621 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
3622 {
3623   if(!a1 || !a2)
3624     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
3625   int nbOfTuple=a1->getNumberOfTuples();
3626   int nbOfTuple2=a2->getNumberOfTuples();
3627   int nbOfComp=a1->getNumberOfComponents();
3628   int nbOfComp2=a2->getNumberOfComponents();
3629   MCAuto<DataArrayDouble> ret=0;
3630   if(nbOfTuple==nbOfTuple2)
3631     {
3632       if(nbOfComp==nbOfComp2)
3633         {
3634           ret=DataArrayDouble::New();
3635           ret->alloc(nbOfTuple,nbOfComp);
3636           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
3637           ret->copyStringInfoFrom(*a1);
3638         }
3639       else
3640         {
3641           int nbOfCompMin,nbOfCompMax;
3642           const DataArrayDouble *aMin, *aMax;
3643           if(nbOfComp>nbOfComp2)
3644             {
3645               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
3646               aMin=a2; aMax=a1;
3647             }
3648           else
3649             {
3650               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
3651               aMin=a1; aMax=a2;
3652             }
3653           if(nbOfCompMin==1)
3654             {
3655               ret=DataArrayDouble::New();
3656               ret->alloc(nbOfTuple,nbOfCompMax);
3657               const double *aMinPtr=aMin->getConstPointer();
3658               const double *aMaxPtr=aMax->getConstPointer();
3659               double *res=ret->getPointer();
3660               for(int i=0;i<nbOfTuple;i++)
3661                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
3662               ret->copyStringInfoFrom(*aMax);
3663             }
3664           else
3665             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3666         }
3667     }
3668   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
3669     {
3670       if(nbOfComp==nbOfComp2)
3671         {
3672           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
3673           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
3674           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
3675           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
3676           ret=DataArrayDouble::New();
3677           ret->alloc(nbOfTupleMax,nbOfComp);
3678           double *res=ret->getPointer();
3679           for(int i=0;i<nbOfTupleMax;i++)
3680             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
3681           ret->copyStringInfoFrom(*aMax);
3682         }
3683       else
3684         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3685     }
3686   else
3687     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
3688   return ret.retn();
3689 }
3690
3691 /*!
3692  * Adds values of another DataArrayDouble to values of \a this one. There are 3
3693  * valid cases.
3694  * 1.  The arrays have same number of tuples and components. Then each value of
3695  *   \a other array is added to the corresponding value of \a this array, i.e.:
3696  *   _a_ [ i, j ] += _other_ [ i, j ].
3697  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3698  *   _a_ [ i, j ] += _other_ [ i, 0 ].
3699  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3700  *   _a_ [ i, j ] += _a2_ [ 0, j ].
3701  *
3702  *  \param [in] other - an array to add to \a this one.
3703  *  \throw If \a other is NULL.
3704  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3705  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3706  *         \a other has number of both tuples and components not equal to 1.
3707  */
3708 void DataArrayDouble::addEqual(const DataArrayDouble *other)
3709 {
3710   if(!other)
3711     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
3712   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
3713   checkAllocated();
3714   other->checkAllocated();
3715   int nbOfTuple=getNumberOfTuples();
3716   int nbOfTuple2=other->getNumberOfTuples();
3717   int nbOfComp=getNumberOfComponents();
3718   int nbOfComp2=other->getNumberOfComponents();
3719   if(nbOfTuple==nbOfTuple2)
3720     {
3721       if(nbOfComp==nbOfComp2)
3722         {
3723           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
3724         }
3725       else if(nbOfComp2==1)
3726         {
3727           double *ptr=getPointer();
3728           const double *ptrc=other->getConstPointer();
3729           for(int i=0;i<nbOfTuple;i++)
3730             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
3731         }
3732       else
3733         throw INTERP_KERNEL::Exception(msg);
3734     }
3735   else if(nbOfTuple2==1)
3736     {
3737       if(nbOfComp2==nbOfComp)
3738         {
3739           double *ptr=getPointer();
3740           const double *ptrc=other->getConstPointer();
3741           for(int i=0;i<nbOfTuple;i++)
3742             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
3743         }
3744       else
3745         throw INTERP_KERNEL::Exception(msg);
3746     }
3747   else
3748     throw INTERP_KERNEL::Exception(msg);
3749   declareAsNew();
3750 }
3751
3752 /*!
3753  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
3754  * valid cases.
3755  * 1.  The arrays have same number of tuples and components. Then each value of
3756  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
3757  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
3758  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3759  *   component. Then
3760  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
3761  * 3.  The arrays have same number of components and one array, say _a2_, has one
3762  *   tuple. Then
3763  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
3764  *
3765  * Info on components is copied either from the first array (in the first case) or from
3766  * the array with maximal number of elements (getNbOfElems()).
3767  *  \param [in] a1 - an array to subtract from.
3768  *  \param [in] a2 - an array to subtract.
3769  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3770  *          The caller is to delete this result array using decrRef() as it is no more
3771  *          needed.
3772  *  \throw If either \a a1 or \a a2 is NULL.
3773  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3774  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3775  *         none of them has number of tuples or components equal to 1.
3776  */
3777 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
3778 {
3779   if(!a1 || !a2)
3780     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
3781   int nbOfTuple1=a1->getNumberOfTuples();
3782   int nbOfTuple2=a2->getNumberOfTuples();
3783   int nbOfComp1=a1->getNumberOfComponents();
3784   int nbOfComp2=a2->getNumberOfComponents();
3785   if(nbOfTuple2==nbOfTuple1)
3786     {
3787       if(nbOfComp1==nbOfComp2)
3788         {
3789           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3790           ret->alloc(nbOfTuple2,nbOfComp1);
3791           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
3792           ret->copyStringInfoFrom(*a1);
3793           return ret.retn();
3794         }
3795       else if(nbOfComp2==1)
3796         {
3797           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3798           ret->alloc(nbOfTuple1,nbOfComp1);
3799           const double *a2Ptr=a2->getConstPointer();
3800           const double *a1Ptr=a1->getConstPointer();
3801           double *res=ret->getPointer();
3802           for(int i=0;i<nbOfTuple1;i++)
3803             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
3804           ret->copyStringInfoFrom(*a1);
3805           return ret.retn();
3806         }
3807       else
3808         {
3809           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3810           return 0;
3811         }
3812     }
3813   else if(nbOfTuple2==1)
3814     {
3815       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3816       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3817       ret->alloc(nbOfTuple1,nbOfComp1);
3818       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
3819       double *pt=ret->getPointer();
3820       for(int i=0;i<nbOfTuple1;i++)
3821         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
3822       ret->copyStringInfoFrom(*a1);
3823       return ret.retn();
3824     }
3825   else
3826     {
3827       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
3828       return 0;
3829     }
3830 }
3831
3832 /*!
3833  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
3834  * valid cases.
3835  * 1.  The arrays have same number of tuples and components. Then each value of
3836  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
3837  *   _a_ [ i, j ] -= _other_ [ i, j ].
3838  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3839  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
3840  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3841  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
3842  *
3843  *  \param [in] other - an array to subtract from \a this one.
3844  *  \throw If \a other is NULL.
3845  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3846  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3847  *         \a other has number of both tuples and components not equal to 1.
3848  */
3849 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
3850 {
3851   if(!other)
3852     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
3853   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
3854   checkAllocated();
3855   other->checkAllocated();
3856   int nbOfTuple=getNumberOfTuples();
3857   int nbOfTuple2=other->getNumberOfTuples();
3858   int nbOfComp=getNumberOfComponents();
3859   int nbOfComp2=other->getNumberOfComponents();
3860   if(nbOfTuple==nbOfTuple2)
3861     {
3862       if(nbOfComp==nbOfComp2)
3863         {
3864           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
3865         }
3866       else if(nbOfComp2==1)
3867         {
3868           double *ptr=getPointer();
3869           const double *ptrc=other->getConstPointer();
3870           for(int i=0;i<nbOfTuple;i++)
3871             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
3872         }
3873       else
3874         throw INTERP_KERNEL::Exception(msg);
3875     }
3876   else if(nbOfTuple2==1)
3877     {
3878       if(nbOfComp2==nbOfComp)
3879         {
3880           double *ptr=getPointer();
3881           const double *ptrc=other->getConstPointer();
3882           for(int i=0;i<nbOfTuple;i++)
3883             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
3884         }
3885       else
3886         throw INTERP_KERNEL::Exception(msg);
3887     }
3888   else
3889     throw INTERP_KERNEL::Exception(msg);
3890   declareAsNew();
3891 }
3892
3893 /*!
3894  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
3895  * valid cases.
3896  * 1.  The arrays have same number of tuples and components. Then each value of
3897  *   the result array (_a_) is a product of the corresponding values of \a a1 and
3898  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
3899  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3900  *   component. Then
3901  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
3902  * 3.  The arrays have same number of components and one array, say _a2_, has one
3903  *   tuple. Then
3904  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
3905  *
3906  * Info on components is copied either from the first array (in the first case) or from
3907  * the array with maximal number of elements (getNbOfElems()).
3908  *  \param [in] a1 - a factor array.
3909  *  \param [in] a2 - another factor array.
3910  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3911  *          The caller is to delete this result array using decrRef() as it is no more
3912  *          needed.
3913  *  \throw If either \a a1 or \a a2 is NULL.
3914  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3915  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3916  *         none of them has number of tuples or components equal to 1.
3917  */
3918 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
3919 {
3920   if(!a1 || !a2)
3921     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
3922   int nbOfTuple=a1->getNumberOfTuples();
3923   int nbOfTuple2=a2->getNumberOfTuples();
3924   int nbOfComp=a1->getNumberOfComponents();
3925   int nbOfComp2=a2->getNumberOfComponents();
3926   MCAuto<DataArrayDouble> ret=0;
3927   if(nbOfTuple==nbOfTuple2)
3928     {
3929       if(nbOfComp==nbOfComp2)
3930         {
3931           ret=DataArrayDouble::New();
3932           ret->alloc(nbOfTuple,nbOfComp);
3933           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
3934           ret->copyStringInfoFrom(*a1);
3935         }
3936       else
3937         {
3938           int nbOfCompMin,nbOfCompMax;
3939           const DataArrayDouble *aMin, *aMax;
3940           if(nbOfComp>nbOfComp2)
3941             {
3942               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
3943               aMin=a2; aMax=a1;
3944             }
3945           else
3946             {
3947               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
3948               aMin=a1; aMax=a2;
3949             }
3950           if(nbOfCompMin==1)
3951             {
3952               ret=DataArrayDouble::New();
3953               ret->alloc(nbOfTuple,nbOfCompMax);
3954               const double *aMinPtr=aMin->getConstPointer();
3955               const double *aMaxPtr=aMax->getConstPointer();
3956               double *res=ret->getPointer();
3957               for(int i=0;i<nbOfTuple;i++)
3958                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
3959               ret->copyStringInfoFrom(*aMax);
3960             }
3961           else
3962             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
3963         }
3964     }
3965   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
3966     {
3967       if(nbOfComp==nbOfComp2)
3968         {
3969           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
3970           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
3971           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
3972           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
3973           ret=DataArrayDouble::New();
3974           ret->alloc(nbOfTupleMax,nbOfComp);
3975           double *res=ret->getPointer();
3976           for(int i=0;i<nbOfTupleMax;i++)
3977             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
3978           ret->copyStringInfoFrom(*aMax);
3979         }
3980       else
3981         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
3982     }
3983   else
3984     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
3985   return ret.retn();
3986 }
3987
3988 /*!
3989  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
3990  * valid cases.
3991  * 1.  The arrays have same number of tuples and components. Then each value of
3992  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
3993  *   _this_ [ i, j ] *= _other_ [ i, j ].
3994  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3995  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
3996  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3997  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
3998  *
3999  *  \param [in] other - an array to multiply to \a this one.
4000  *  \throw If \a other is NULL.
4001  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4002  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4003  *         \a other has number of both tuples and components not equal to 1.
4004  */
4005 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
4006 {
4007   if(!other)
4008     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4009   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4010   checkAllocated();
4011   other->checkAllocated();
4012   int nbOfTuple=getNumberOfTuples();
4013   int nbOfTuple2=other->getNumberOfTuples();
4014   int nbOfComp=getNumberOfComponents();
4015   int nbOfComp2=other->getNumberOfComponents();
4016   if(nbOfTuple==nbOfTuple2)
4017     {
4018       if(nbOfComp==nbOfComp2)
4019         {
4020           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
4021         }
4022       else if(nbOfComp2==1)
4023         {
4024           double *ptr=getPointer();
4025           const double *ptrc=other->getConstPointer();
4026           for(int i=0;i<nbOfTuple;i++)
4027             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
4028         }
4029       else
4030         throw INTERP_KERNEL::Exception(msg);
4031     }
4032   else if(nbOfTuple2==1)
4033     {
4034       if(nbOfComp2==nbOfComp)
4035         {
4036           double *ptr=getPointer();
4037           const double *ptrc=other->getConstPointer();
4038           for(int i=0;i<nbOfTuple;i++)
4039             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
4040         }
4041       else
4042         throw INTERP_KERNEL::Exception(msg);
4043     }
4044   else
4045     throw INTERP_KERNEL::Exception(msg);
4046   declareAsNew();
4047 }
4048
4049 /*!
4050  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
4051  * valid cases.
4052  * 1.  The arrays have same number of tuples and components. Then each value of
4053  *   the result array (_a_) is a division of the corresponding values of \a a1 and
4054  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
4055  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4056  *   component. Then
4057  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
4058  * 3.  The arrays have same number of components and one array, say _a2_, has one
4059  *   tuple. Then
4060  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
4061  *
4062  * Info on components is copied either from the first array (in the first case) or from
4063  * the array with maximal number of elements (getNbOfElems()).
4064  *  \warning No check of division by zero is performed!
4065  *  \param [in] a1 - a numerator array.
4066  *  \param [in] a2 - a denominator array.
4067  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4068  *          The caller is to delete this result array using decrRef() as it is no more
4069  *          needed.
4070  *  \throw If either \a a1 or \a a2 is NULL.
4071  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4072  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4073  *         none of them has number of tuples or components equal to 1.
4074  */
4075 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
4076 {
4077   if(!a1 || !a2)
4078     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
4079   int nbOfTuple1=a1->getNumberOfTuples();
4080   int nbOfTuple2=a2->getNumberOfTuples();
4081   int nbOfComp1=a1->getNumberOfComponents();
4082   int nbOfComp2=a2->getNumberOfComponents();
4083   if(nbOfTuple2==nbOfTuple1)
4084     {
4085       if(nbOfComp1==nbOfComp2)
4086         {
4087           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4088           ret->alloc(nbOfTuple2,nbOfComp1);
4089           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
4090           ret->copyStringInfoFrom(*a1);
4091           return ret.retn();
4092         }
4093       else if(nbOfComp2==1)
4094         {
4095           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4096           ret->alloc(nbOfTuple1,nbOfComp1);
4097           const double *a2Ptr=a2->getConstPointer();
4098           const double *a1Ptr=a1->getConstPointer();
4099           double *res=ret->getPointer();
4100           for(int i=0;i<nbOfTuple1;i++)
4101             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
4102           ret->copyStringInfoFrom(*a1);
4103           return ret.retn();
4104         }
4105       else
4106         {
4107           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4108           return 0;
4109         }
4110     }
4111   else if(nbOfTuple2==1)
4112     {
4113       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4114       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4115       ret->alloc(nbOfTuple1,nbOfComp1);
4116       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4117       double *pt=ret->getPointer();
4118       for(int i=0;i<nbOfTuple1;i++)
4119         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
4120       ret->copyStringInfoFrom(*a1);
4121       return ret.retn();
4122     }
4123   else
4124     {
4125       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
4126       return 0;
4127     }
4128 }
4129
4130 /*!
4131  * Divide values of \a this array by values of another DataArrayDouble. There are 3
4132  * valid cases.
4133  * 1.  The arrays have same number of tuples and components. Then each value of
4134  *    \a this array is divided by the corresponding value of \a other one, i.e.:
4135  *   _a_ [ i, j ] /= _other_ [ i, j ].
4136  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4137  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
4138  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4139  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
4140  *
4141  *  \warning No check of division by zero is performed!
4142  *  \param [in] other - an array to divide \a this one by.
4143  *  \throw If \a other is NULL.
4144  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4145  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4146  *         \a other has number of both tuples and components not equal to 1.
4147  */
4148 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
4149 {
4150   if(!other)
4151     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
4152   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
4153   checkAllocated();
4154   other->checkAllocated();
4155   int nbOfTuple=getNumberOfTuples();
4156   int nbOfTuple2=other->getNumberOfTuples();
4157   int nbOfComp=getNumberOfComponents();
4158   int nbOfComp2=other->getNumberOfComponents();
4159   if(nbOfTuple==nbOfTuple2)
4160     {
4161       if(nbOfComp==nbOfComp2)
4162         {
4163           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
4164         }
4165       else if(nbOfComp2==1)
4166         {
4167           double *ptr=getPointer();
4168           const double *ptrc=other->getConstPointer();
4169           for(int i=0;i<nbOfTuple;i++)
4170             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
4171         }
4172       else
4173         throw INTERP_KERNEL::Exception(msg);
4174     }
4175   else if(nbOfTuple2==1)
4176     {
4177       if(nbOfComp2==nbOfComp)
4178         {
4179           double *ptr=getPointer();
4180           const double *ptrc=other->getConstPointer();
4181           for(int i=0;i<nbOfTuple;i++)
4182             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
4183         }
4184       else
4185         throw INTERP_KERNEL::Exception(msg);
4186     }
4187   else
4188     throw INTERP_KERNEL::Exception(msg);
4189   declareAsNew();
4190 }
4191
4192 /*!
4193  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
4194  * valid cases.
4195  *
4196  *  \param [in] a1 - an array to pow up.
4197  *  \param [in] a2 - another array to sum up.
4198  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4199  *          The caller is to delete this result array using decrRef() as it is no more
4200  *          needed.
4201  *  \throw If either \a a1 or \a a2 is NULL.
4202  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4203  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
4204  *  \throw If there is a negative value in \a a1.
4205  */
4206 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
4207 {
4208   if(!a1 || !a2)
4209     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
4210   int nbOfTuple=a1->getNumberOfTuples();
4211   int nbOfTuple2=a2->getNumberOfTuples();
4212   int nbOfComp=a1->getNumberOfComponents();
4213   int nbOfComp2=a2->getNumberOfComponents();
4214   if(nbOfTuple!=nbOfTuple2)
4215     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
4216   if(nbOfComp!=1 || nbOfComp2!=1)
4217     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
4218   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
4219   const double *ptr1(a1->begin()),*ptr2(a2->begin());
4220   double *ptr=ret->getPointer();
4221   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
4222     {
4223       if(*ptr1>=0)
4224         {
4225           *ptr=pow(*ptr1,*ptr2);
4226         }
4227       else
4228         {
4229           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
4230           throw INTERP_KERNEL::Exception(oss.str().c_str());
4231         }
4232     }
4233   return ret.retn();
4234 }
4235
4236 /*!
4237  * Apply pow on values of another DataArrayDouble to values of \a this one.
4238  *
4239  *  \param [in] other - an array to pow to \a this one.
4240  *  \throw If \a other is NULL.
4241  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
4242  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
4243  *  \throw If there is a negative value in \a this.
4244  */
4245 void DataArrayDouble::powEqual(const DataArrayDouble *other)
4246 {
4247   if(!other)
4248     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
4249   int nbOfTuple=getNumberOfTuples();
4250   int nbOfTuple2=other->getNumberOfTuples();
4251   int nbOfComp=getNumberOfComponents();
4252   int nbOfComp2=other->getNumberOfComponents();
4253   if(nbOfTuple!=nbOfTuple2)
4254     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
4255   if(nbOfComp!=1 || nbOfComp2!=1)
4256     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
4257   double *ptr=getPointer();
4258   const double *ptrc=other->begin();
4259   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
4260     {
4261       if(*ptr>=0)
4262         *ptr=pow(*ptr,*ptrc);
4263       else
4264         {
4265           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
4266           throw INTERP_KERNEL::Exception(oss.str().c_str());
4267         }
4268     }
4269   declareAsNew();
4270 }
4271
4272 /*!
4273  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
4274  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
4275  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
4276  *
4277  * \throw if \a this is not allocated.
4278  * \throw if \a this has not exactly one component.
4279  */
4280 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
4281 {
4282   checkAllocated();
4283   if(getNumberOfComponents()!=1)
4284     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
4285   int nbt(getNumberOfTuples());
4286   std::vector<bool> ret(nbt);
4287   const double *pt(begin());
4288   for(int i=0;i<nbt;i++)
4289     {
4290       if(fabs(pt[i])<eps)
4291         ret[i]=false;
4292       else if(fabs(pt[i]-1.)<eps)
4293         ret[i]=true;
4294       else
4295         {
4296           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
4297           throw INTERP_KERNEL::Exception(oss.str().c_str());
4298         }
4299     }
4300   return ret;
4301 }
4302
4303 /*!
4304  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4305  * Server side.
4306  */
4307 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
4308 {
4309   tinyInfo.resize(2);
4310   if(isAllocated())
4311     {
4312       tinyInfo[0]=getNumberOfTuples();
4313       tinyInfo[1]=getNumberOfComponents();
4314     }
4315   else
4316     {
4317       tinyInfo[0]=-1;
4318       tinyInfo[1]=-1;
4319     }
4320 }
4321
4322 /*!
4323  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4324  * Server side.
4325  */
4326 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
4327 {
4328   if(isAllocated())
4329     {
4330       int nbOfCompo=getNumberOfComponents();
4331       tinyInfo.resize(nbOfCompo+1);
4332       tinyInfo[0]=getName();
4333       for(int i=0;i<nbOfCompo;i++)
4334         tinyInfo[i+1]=getInfoOnComponent(i);
4335     }
4336   else
4337     {
4338       tinyInfo.resize(1);
4339       tinyInfo[0]=getName();
4340     }
4341 }
4342
4343 /*!
4344  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4345  * This method returns if a feeding is needed.
4346  */
4347 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
4348 {
4349   int nbOfTuple=tinyInfoI[0];
4350   int nbOfComp=tinyInfoI[1];
4351   if(nbOfTuple!=-1 || nbOfComp!=-1)
4352     {
4353       alloc(nbOfTuple,nbOfComp);
4354       return true;
4355     }
4356   return false;
4357 }
4358
4359 /*!
4360  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4361  */
4362 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
4363 {
4364   setName(tinyInfoS[0]);
4365   if(isAllocated())
4366     {
4367       int nbOfCompo=getNumberOfComponents();
4368       for(int i=0;i<nbOfCompo;i++)
4369         setInfoOnComponent(i,tinyInfoS[i+1]);
4370     }
4371 }
4372
4373 /*!
4374  * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
4375  * around an axe ( \a center, \a vect) and with angle \a angle.
4376  */
4377 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4378 {
4379   if(!center || !vect)
4380     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
4381   double sina(sin(angle));
4382   double cosa(cos(angle));
4383   double vectorNorm[3];
4384   double matrix[9];
4385   double matrixTmp[9];
4386   double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
4387   if(norm<std::numeric_limits<double>::min())
4388     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
4389   std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
4390   //rotation matrix computation
4391   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;
4392   matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
4393   matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
4394   matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
4395   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
4396   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4397   matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
4398   matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
4399   matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
4400   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
4401   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4402   //rotation matrix computed.
4403   double tmp[3];
4404   for(int i=0; i<nbNodes; i++)
4405     {
4406       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
4407       coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
4408       coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
4409       coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
4410     }
4411 }
4412
4413 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
4414 {
4415   double matrix[9],matrix2[9],matrix3[9];
4416   double vect[3],crossVect[3];
4417   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4418   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4419   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4420   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4421   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4422   matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
4423   matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
4424   matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
4425   matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
4426   matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
4427   matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
4428   for(int i=0;i<3;i++)
4429     for(int j=0;j<3;j++)
4430       {
4431         double val(0.);
4432         for(int k=0;k<3;k++)
4433           val+=matrix[3*i+k]*matrix2[3*k+j];
4434         matrix3[3*i+j]=val;
4435       }
4436   //rotation matrix computed.
4437   double tmp[3];
4438   for(int i=0; i<nbNodes; i++)
4439     {
4440       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
4441       coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
4442       coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
4443       coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
4444     }
4445 }
4446
4447 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
4448 {
4449   double vect[3],crossVect[3];
4450   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4451   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4452   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4453   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4454   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4455   baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
4456   baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
4457   baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
4458 }
4459
4460 /*!
4461  * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
4462  * around the center point \a center and with angle \a angle.
4463  */
4464 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4465 {
4466   double cosa=cos(angle);
4467   double sina=sin(angle);
4468   double matrix[4];
4469   matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
4470   double tmp[2];
4471   for(int i=0; i<nbNodes; i++)
4472     {
4473       std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
4474       coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
4475       coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
4476     }
4477 }
4478
4479 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
4480 {
4481   if(_da)
4482     {
4483       _da->incrRef();
4484       if(_da->isAllocated())
4485         {
4486           _nb_comp=da->getNumberOfComponents();
4487           _nb_tuple=da->getNumberOfTuples();
4488           _pt=da->getPointer();
4489         }
4490     }
4491 }
4492
4493 DataArrayDoubleIterator::~DataArrayDoubleIterator()
4494 {
4495   if(_da)
4496     _da->decrRef();
4497 }
4498
4499 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
4500 {
4501   if(_tuple_id<_nb_tuple)
4502     {
4503       _tuple_id++;
4504       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
4505       _pt+=_nb_comp;
4506       return ret;
4507     }
4508   else
4509     return 0;
4510 }
4511
4512 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
4513 {
4514 }
4515
4516
4517 std::string DataArrayDoubleTuple::repr() const
4518 {
4519   std::ostringstream oss; oss.precision(17); oss << "(";
4520   for(int i=0;i<_nb_of_compo-1;i++)
4521     oss << _pt[i] << ", ";
4522   oss << _pt[_nb_of_compo-1] << ")";
4523   return oss.str();
4524 }
4525
4526 double DataArrayDoubleTuple::doubleValue() const
4527 {
4528   if(_nb_of_compo==1)
4529     return *_pt;
4530   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
4531 }
4532
4533 /*!
4534  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
4535  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
4536  * 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
4537  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
4538  */
4539 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
4540 {
4541   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
4542     {
4543       DataArrayDouble *ret=DataArrayDouble::New();
4544       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
4545       return ret;
4546     }
4547   else
4548     {
4549       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
4550       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
4551       throw INTERP_KERNEL::Exception(oss.str().c_str());
4552     }
4553 }
4554
4555 /*!
4556  * Returns a new instance of DataArrayInt. The caller is to delete this array
4557  * using decrRef() as it is no more needed. 
4558  */
4559 DataArrayInt *DataArrayInt::New()
4560 {
4561   return new DataArrayInt;
4562 }
4563
4564 /*!
4565  * Returns the only one value in \a this, if and only if number of elements
4566  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
4567  *  \return double - the sole value stored in \a this array.
4568  *  \throw If at least one of conditions stated above is not fulfilled.
4569  */
4570 int DataArrayInt::intValue() const
4571 {
4572   if(isAllocated())
4573     {
4574       if(getNbOfElems()==1)
4575         {
4576           return *getConstPointer();
4577         }
4578       else
4579         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
4580     }
4581   else
4582     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
4583 }
4584
4585 /*!
4586  * Returns an integer value characterizing \a this array, which is useful for a quick
4587  * comparison of many instances of DataArrayInt.
4588  *  \return int - the hash value.
4589  *  \throw If \a this is not allocated.
4590  */
4591 int DataArrayInt::getHashCode() const
4592 {
4593   checkAllocated();
4594   std::size_t nbOfElems=getNbOfElems();
4595   int ret=nbOfElems*65536;
4596   int delta=3;
4597   if(nbOfElems>48)
4598     delta=nbOfElems/8;
4599   int ret0=0;
4600   const int *pt=begin();
4601   for(std::size_t i=0;i<nbOfElems;i+=delta)
4602     ret0+=pt[i] & 0x1FFF;
4603   return ret+ret0;
4604 }
4605
4606 /*!
4607  * Returns a full copy of \a this. For more info on copying data arrays see
4608  * \ref MEDCouplingArrayBasicsCopyDeep.
4609  *  \return DataArrayInt * - a new instance of DataArrayInt.
4610  */
4611 DataArrayInt *DataArrayInt::deepCopy() const
4612 {
4613   return new DataArrayInt(*this);
4614 }
4615
4616 /*!
4617  * Returns either a \a deep or \a shallow copy of this array. For more info see
4618  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
4619  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
4620  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
4621  *          == \a true) or \a this instance (if \a dCpy == \a false).
4622  */
4623 DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
4624 {
4625   if(dCpy)
4626     return deepCopy();
4627   else
4628     {
4629       incrRef();
4630       return const_cast<DataArrayInt *>(this);
4631     }
4632 }
4633
4634 /*!
4635  * Assign zero to all values in \a this array. To know more on filling arrays see
4636  * \ref MEDCouplingArrayFill.
4637  * \throw If \a this is not allocated.
4638  */
4639 void DataArrayInt::fillWithZero()
4640 {
4641   fillWithValue(0);
4642 }
4643
4644 /*!
4645  * Set all values in \a this array so that the i-th element equals to \a init + i
4646  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
4647  *  \param [in] init - value to assign to the first element of array.
4648  *  \throw If \a this->getNumberOfComponents() != 1
4649  *  \throw If \a this is not allocated.
4650  */
4651 void DataArrayInt::iota(int init)
4652 {
4653   checkAllocated();
4654   if(getNumberOfComponents()!=1)
4655     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
4656   int *ptr=getPointer();
4657   int ntuples=getNumberOfTuples();
4658   for(int i=0;i<ntuples;i++)
4659     ptr[i]=init+i;
4660   declareAsNew();
4661 }
4662
4663 /*!
4664  * Returns a textual and human readable representation of \a this instance of
4665  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
4666  * \return std::string - text describing \a this DataArrayInt.
4667  * 
4668  * \sa reprNotTooLong, reprZip
4669  */
4670 std::string DataArrayInt::repr() const
4671 {
4672   std::ostringstream ret;
4673   reprStream(ret);
4674   return ret.str();
4675 }
4676
4677 std::string DataArrayInt::reprZip() const
4678 {
4679   std::ostringstream ret;
4680   reprZipStream(ret);
4681   return ret.str();
4682 }
4683
4684 /*!
4685  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
4686  * printed out to avoid to consume too much space in interpretor.
4687  * \sa repr
4688  */
4689 std::string DataArrayInt::reprNotTooLong() const
4690 {
4691   std::ostringstream ret;
4692   reprNotTooLongStream(ret);
4693   return ret.str();
4694 }
4695
4696 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
4697 {
4698   static const char SPACE[4]={' ',' ',' ',' '};
4699   checkAllocated();
4700   std::string idt(indent,' ');
4701   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
4702   if(byteArr)
4703     {
4704       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
4705       if(std::string(type)=="Int32")
4706         {
4707           const char *data(reinterpret_cast<const char *>(begin()));
4708           std::size_t sz(getNbOfElems()*sizeof(int));
4709           byteArr->insertAtTheEnd(data,data+sz);
4710           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4711         }
4712       else if(std::string(type)=="Int8")
4713         {
4714           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
4715           std::copy(begin(),end(),(char *)tmp);
4716           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
4717           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4718         }
4719       else if(std::string(type)=="UInt8")
4720         {
4721           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
4722           std::copy(begin(),end(),(unsigned char *)tmp);
4723           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
4724           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4725         }
4726       else
4727         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
4728     }
4729   else
4730     {
4731       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
4732       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
4733     }
4734   ofs << std::endl << idt << "</DataArray>\n";
4735 }
4736
4737 void DataArrayInt::reprStream(std::ostream& stream) const
4738 {
4739   stream << "Name of int array : \"" << _name << "\"\n";
4740   reprWithoutNameStream(stream);
4741 }
4742
4743 void DataArrayInt::reprZipStream(std::ostream& stream) const
4744 {
4745   stream << "Name of int array : \"" << _name << "\"\n";
4746   reprZipWithoutNameStream(stream);
4747 }
4748
4749 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
4750 {
4751   stream << "Name of int array : \"" << _name << "\"\n";
4752   reprNotTooLongWithoutNameStream(stream);
4753 }
4754
4755 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
4756 {
4757   DataArray::reprWithoutNameStream(stream);
4758   _mem.repr(getNumberOfComponents(),stream);
4759 }
4760
4761 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
4762 {
4763   DataArray::reprWithoutNameStream(stream);
4764   _mem.reprZip(getNumberOfComponents(),stream);
4765 }
4766
4767 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
4768 {
4769   DataArray::reprWithoutNameStream(stream);
4770   stream.precision(17);
4771   _mem.reprNotTooLong(getNumberOfComponents(),stream);
4772 }
4773
4774 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
4775 {
4776   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
4777   const int *data=getConstPointer();
4778   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
4779   if(nbTuples*nbComp>=1)
4780     {
4781       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
4782       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
4783       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
4784       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
4785     }
4786   else
4787     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
4788   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
4789 }
4790
4791 /*!
4792  * Method that gives a quick overvien of \a this for python.
4793  */
4794 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
4795 {
4796   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
4797   stream << "DataArrayInt C++ instance at " << this << ". ";
4798   if(isAllocated())
4799     {
4800       int nbOfCompo=(int)_info_on_compo.size();
4801       if(nbOfCompo>=1)
4802         {
4803           int nbOfTuples=getNumberOfTuples();
4804           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
4805           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
4806         }
4807       else
4808         stream << "Number of components : 0.";
4809     }
4810   else
4811     stream << "*** No data allocated ****";
4812 }
4813
4814 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
4815 {
4816   const int *data=begin();
4817   int nbOfTuples=getNumberOfTuples();
4818   int nbOfCompo=(int)_info_on_compo.size();
4819   std::ostringstream oss2; oss2 << "[";
4820   std::string oss2Str(oss2.str());
4821   bool isFinished=true;
4822   for(int i=0;i<nbOfTuples && isFinished;i++)
4823     {
4824       if(nbOfCompo>1)
4825         {
4826           oss2 << "(";
4827           for(int j=0;j<nbOfCompo;j++,data++)
4828             {
4829               oss2 << *data;
4830               if(j!=nbOfCompo-1) oss2 << ", ";
4831             }
4832           oss2 << ")";
4833         }
4834       else
4835         oss2 << *data++;
4836       if(i!=nbOfTuples-1) oss2 << ", ";
4837       std::string oss3Str(oss2.str());
4838       if(oss3Str.length()<maxNbOfByteInRepr)
4839         oss2Str=oss3Str;
4840       else
4841         isFinished=false;
4842     }
4843   stream << oss2Str;
4844   if(!isFinished)
4845     stream << "... ";
4846   stream << "]";
4847 }
4848
4849 /*!
4850  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4851  * i.e. a current value is used as in index to get a new value from \a indArrBg.
4852  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
4853  *         to \a this array.
4854  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4855  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
4856  *  \throw If \a this->getNumberOfComponents() != 1
4857  *  \throw If any value of \a this can't be used as a valid index for 
4858  *         [\a indArrBg, \a indArrEnd).
4859  *
4860  *  \sa changeValue
4861  */
4862 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4863 {
4864   checkAllocated();
4865   if(getNumberOfComponents()!=1)
4866     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4867   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4868   for(int i=0;i<nbOfTuples;i++,pt++)
4869     {
4870       if(*pt>=0 && *pt<nbElemsIn)
4871         *pt=indArrBg[*pt];
4872       else
4873         {
4874           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4875           throw INTERP_KERNEL::Exception(oss.str().c_str());
4876         }
4877     }
4878   declareAsNew();
4879 }
4880
4881 /*!
4882  * Computes distribution of values of \a this one-dimensional array between given value
4883  * ranges (casts). This method is typically useful for entity number spliting by types,
4884  * for example. 
4885  *  \warning The values contained in \a arrBg should be sorted ascendently. No
4886  *           check of this is be done. If not, the result is not warranted. 
4887  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
4888  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
4889  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
4890  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
4891  *         should be more than every value in \a this array.
4892  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
4893  *              the last value of \a arrBg is \a arrEnd[ -1 ].
4894  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
4895  *         (same number of tuples and components), the caller is to delete 
4896  *         using decrRef() as it is no more needed.
4897  *         This array contains indices of ranges for every value of \a this array. I.e.
4898  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
4899  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
4900  *         this in which cast it holds.
4901  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
4902  *         array, the caller is to delete using decrRef() as it is no more needed.
4903  *         This array contains ranks of values of \a this array within ranges
4904  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
4905  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
4906  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
4907  *         for each tuple its rank inside its cast. The rank is computed as difference
4908  *         between the value and the lowest value of range.
4909  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
4910  *         ranges (casts) to which at least one value of \a this array belongs.
4911  *         Or, in other words, this param contains the casts that \a this contains.
4912  *         The caller is to delete this array using decrRef() as it is no more needed.
4913  *
4914  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
4915  *            the output of this method will be : 
4916  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
4917  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
4918  * - \a castsPresent  : [0,1]
4919  *
4920  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
4921  * range #1 and its rank within this range is 2; etc.
4922  *
4923  *  \throw If \a this->getNumberOfComponents() != 1.
4924  *  \throw If \a arrEnd - arrBg < 2.
4925  *  \throw If any value of \a this is not less than \a arrEnd[-1].
4926  */
4927 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
4928                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
4929 {
4930   checkAllocated();
4931   if(getNumberOfComponents()!=1)
4932     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4933   int nbOfTuples=getNumberOfTuples();
4934   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
4935   if(nbOfCast<2)
4936     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
4937   nbOfCast--;
4938   const int *work=getConstPointer();
4939   typedef std::reverse_iterator<const int *> rintstart;
4940   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
4941   rintstart end2(arrBg);
4942   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
4943   MCAuto<DataArrayInt> ret2=DataArrayInt::New();
4944   MCAuto<DataArrayInt> ret3=DataArrayInt::New();
4945   ret1->alloc(nbOfTuples,1);
4946   ret2->alloc(nbOfTuples,1);
4947   int *ret1Ptr=ret1->getPointer();
4948   int *ret2Ptr=ret2->getPointer();
4949   std::set<std::size_t> castsDetected;
4950   for(int i=0;i<nbOfTuples;i++)
4951     {
4952       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
4953       std::size_t pos=std::distance(bg,res);
4954       std::size_t pos2=nbOfCast-pos;
4955       if(pos2<nbOfCast)
4956         {
4957           ret1Ptr[i]=(int)pos2;
4958           ret2Ptr[i]=work[i]-arrBg[pos2];
4959           castsDetected.insert(pos2);
4960         }
4961       else
4962         {
4963           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
4964           throw INTERP_KERNEL::Exception(oss.str().c_str());
4965         }
4966     }
4967   ret3->alloc((int)castsDetected.size(),1);
4968   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
4969   castArr=ret1.retn();
4970   rankInsideCast=ret2.retn();
4971   castsPresent=ret3.retn();
4972 }
4973
4974 /*!
4975  * 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 ).
4976  * 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 ).
4977  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
4978  *
4979  * \param [out] strt - the start of the range (included) if true is returned.
4980  * \param [out] sttoopp - the end of the range (not included) if true is returned.
4981  * \param [out] stteepp - the step of the range if true is returned.
4982  * \return the verdict of the check.
4983  *
4984  * \sa DataArray::GetNumberOfItemGivenBES
4985  */
4986 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
4987 {
4988   checkAllocated();
4989   if(getNumberOfComponents()!=1)
4990     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
4991   int nbTuples(getNumberOfTuples());
4992   if(nbTuples==0)
4993     { strt=0; sttoopp=0; stteepp=1; return true; }
4994   const int *pt(begin());
4995   strt=*pt; 
4996   if(nbTuples==1)
4997     { sttoopp=strt+1; stteepp=1; return true; }
4998   strt=*pt; sttoopp=pt[nbTuples-1];
4999   if(strt==sttoopp)
5000     return false;
5001   if(sttoopp>strt)
5002     {
5003       sttoopp++;
5004       int a(sttoopp-1-strt),tmp(strt);
5005       if(a%(nbTuples-1)!=0)
5006         return false;
5007       stteepp=a/(nbTuples-1);
5008       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5009         if(pt[i]!=tmp)
5010           return false;
5011       return true;
5012     }
5013   else
5014     {
5015       sttoopp--;
5016       int a(strt-sttoopp-1),tmp(strt);
5017       if(a%(nbTuples-1)!=0)
5018         return false;
5019       stteepp=-(a/(nbTuples-1));
5020       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5021         if(pt[i]!=tmp)
5022           return false;
5023       return true;
5024     }
5025 }
5026
5027 /*!
5028  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5029  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5030  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5031  * new value in place \a indArr[ \a v ] is i.
5032  *  \param [in] indArrBg - the array holding indices within the result array to assign
5033  *         indices of values of \a this array pointing to values of \a indArrBg.
5034  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5035  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5036  *  \return DataArrayInt * - the new instance of DataArrayInt.
5037  *          The caller is to delete this result array using decrRef() as it is no more
5038  *          needed.
5039  *  \throw If \a this->getNumberOfComponents() != 1.
5040  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
5041  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
5042  */
5043 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
5044 {
5045   checkAllocated();
5046   if(getNumberOfComponents()!=1)
5047     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5048   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5049   int nbOfTuples=getNumberOfTuples();
5050   const int *pt=getConstPointer();
5051   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5052   ret->alloc(nbOfTuples,1);
5053   ret->fillWithValue(-1);
5054   int *tmp=ret->getPointer();
5055   for(int i=0;i<nbOfTuples;i++,pt++)
5056     {
5057       if(*pt>=0 && *pt<nbElemsIn)
5058         {
5059           int pos=indArrBg[*pt];
5060           if(pos>=0 && pos<nbOfTuples)
5061             tmp[pos]=i;
5062           else
5063             {
5064               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
5065               throw INTERP_KERNEL::Exception(oss.str().c_str());
5066             }
5067         }
5068       else
5069         {
5070           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
5071           throw INTERP_KERNEL::Exception(oss.str().c_str());
5072         }
5073     }
5074   return ret.retn();
5075 }
5076
5077 /*!
5078  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5079  * from values of \a this array, which is supposed to contain a renumbering map in 
5080  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
5081  * To know how to use the renumbering maps see \ref numbering.
5082  *  \param [in] newNbOfElem - the number of tuples in the result array.
5083  *  \return DataArrayInt * - the new instance of DataArrayInt.
5084  *          The caller is to delete this result array using decrRef() as it is no more
5085  *          needed.
5086  * 
5087  *  \if ENABLE_EXAMPLES
5088  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
5089  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
5090  *  \endif
5091  */
5092 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
5093 {
5094   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5095   ret->alloc(newNbOfElem,1);
5096   int nbOfOldNodes=getNumberOfTuples();
5097   const int *old2New=getConstPointer();
5098   int *pt=ret->getPointer();
5099   for(int i=0;i!=nbOfOldNodes;i++)
5100     {
5101       int newp(old2New[i]);
5102       if(newp!=-1)
5103         {
5104           if(newp>=0 && newp<newNbOfElem)
5105             pt[newp]=i;
5106           else
5107             {
5108               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5109               throw INTERP_KERNEL::Exception(oss.str().c_str());
5110             }
5111         }
5112     }
5113   return ret.retn();
5114 }
5115
5116 /*!
5117  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
5118  * 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]
5119  */
5120 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
5121 {
5122   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5123   ret->alloc(newNbOfElem,1);
5124   int nbOfOldNodes=getNumberOfTuples();
5125   const int *old2New=getConstPointer();
5126   int *pt=ret->getPointer();
5127   for(int i=nbOfOldNodes-1;i>=0;i--)
5128     {
5129       int newp(old2New[i]);
5130       if(newp!=-1)
5131         {
5132           if(newp>=0 && newp<newNbOfElem)
5133             pt[newp]=i;
5134           else
5135             {
5136               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5137               throw INTERP_KERNEL::Exception(oss.str().c_str());
5138             }
5139         }
5140     }
5141   return ret.retn();
5142 }
5143
5144 /*!
5145  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5146  * from values of \a this array, which is supposed to contain a renumbering map in 
5147  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
5148  * To know how to use the renumbering maps see \ref numbering.
5149  *  \param [in] newNbOfElem - the number of tuples in the result array.
5150  *  \return DataArrayInt * - the new instance of DataArrayInt.
5151  *          The caller is to delete this result array using decrRef() as it is no more
5152  *          needed.
5153  * 
5154  *  \if ENABLE_EXAMPLES
5155  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
5156  *
5157  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
5158  *  \endif
5159  */
5160 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
5161 {
5162   checkAllocated();
5163   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5164   ret->alloc(oldNbOfElem,1);
5165   const int *new2Old=getConstPointer();
5166   int *pt=ret->getPointer();
5167   std::fill(pt,pt+oldNbOfElem,-1);
5168   int nbOfNewElems=getNumberOfTuples();
5169   for(int i=0;i<nbOfNewElems;i++)
5170     {
5171       int v(new2Old[i]);
5172       if(v>=0 && v<oldNbOfElem)
5173         pt[v]=i;
5174       else
5175         {
5176           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
5177           throw INTERP_KERNEL::Exception(oss.str().c_str());
5178         }
5179     }
5180   return ret.retn();
5181 }
5182
5183 /*!
5184  * Equivalent to DataArrayInt::isEqual except that if false the reason of
5185  * mismatch is given.
5186  * 
5187  * \param [in] other the instance to be compared with \a this
5188  * \param [out] reason In case of inequality returns the reason.
5189  * \sa DataArrayInt::isEqual
5190  */
5191 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
5192 {
5193   if(!areInfoEqualsIfNotWhy(other,reason))
5194     return false;
5195   return _mem.isEqual(other._mem,0,reason);
5196 }
5197
5198 /*!
5199  * Checks if \a this and another DataArrayInt are fully equal. For more info see
5200  * \ref MEDCouplingArrayBasicsCompare.
5201  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5202  *  \return bool - \a true if the two arrays are equal, \a false else.
5203  */
5204 bool DataArrayInt::isEqual(const DataArrayInt& other) const
5205 {
5206   std::string tmp;
5207   return isEqualIfNotWhy(other,tmp);
5208 }
5209
5210 /*!
5211  * Checks if values of \a this and another DataArrayInt are equal. For more info see
5212  * \ref MEDCouplingArrayBasicsCompare.
5213  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5214  *  \return bool - \a true if the values of two arrays are equal, \a false else.
5215  */
5216 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
5217 {
5218   std::string tmp;
5219   return _mem.isEqual(other._mem,0,tmp);
5220 }
5221
5222 /*!
5223  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
5224  * performed on sorted value sequences.
5225  * For more info see\ref MEDCouplingArrayBasicsCompare.
5226  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5227  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
5228  */
5229 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
5230 {
5231   MCAuto<DataArrayInt> a=deepCopy();
5232   MCAuto<DataArrayInt> b=other.deepCopy();
5233   a->sort();
5234   b->sort();
5235   return a->isEqualWithoutConsideringStr(*b);
5236 }
5237
5238 /*!
5239  * This method compares content of input vector \a v and \a this.
5240  * 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.
5241  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
5242  *
5243  * \param [in] v - the vector of 'flags' to be compared with \a this.
5244  *
5245  * \throw If \a this is not sorted ascendingly.
5246  * \throw If \a this has not exactly one component.
5247  * \throw If \a this is not allocated.
5248  */
5249 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
5250 {
5251   checkAllocated();
5252   if(getNumberOfComponents()!=1)
5253     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
5254   const int *w(begin()),*end2(end());
5255   int refVal=-std::numeric_limits<int>::max();
5256   int i=0;
5257   std::vector<bool>::const_iterator it(v.begin());
5258   for(;it!=v.end();it++,i++)
5259     {
5260       if(*it)
5261         {
5262           if(w!=end2)
5263             {
5264               if(*w++==i)
5265                 {
5266                   if(i>refVal)
5267                     refVal=i;
5268                   else
5269                     {
5270                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
5271                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5272                     }
5273                 }
5274               else
5275                 return false;
5276             }
5277           else
5278             return false;
5279         }
5280     }
5281   return w==end2;
5282 }
5283
5284 /*!
5285  * 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
5286  * put True to the corresponding entry in \a vec.
5287  * \a vec is expected to be with the same size than the number of tuples of \a this.
5288  *
5289  *  \sa DataArrayInt::switchOnTupleNotEqualTo.
5290  */
5291 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
5292 {
5293   checkAllocated();
5294   if(getNumberOfComponents()!=1)
5295     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
5296   int nbOfTuples(getNumberOfTuples());
5297   if(nbOfTuples!=(int)vec.size())
5298     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5299   const int *pt(begin());
5300   for(int i=0;i<nbOfTuples;i++)
5301     if(pt[i]==val)
5302       vec[i]=true;
5303 }
5304
5305 /*!
5306  * 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
5307  * put True to the corresponding entry in \a vec.
5308  * \a vec is expected to be with the same size than the number of tuples of \a this.
5309  * 
5310  *  \sa DataArrayInt::switchOnTupleEqualTo.
5311  */
5312 void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const
5313 {
5314   checkAllocated();
5315   if(getNumberOfComponents()!=1)
5316     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !");
5317   int nbOfTuples(getNumberOfTuples());
5318   if(nbOfTuples!=(int)vec.size())
5319     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5320   const int *pt(begin());
5321   for(int i=0;i<nbOfTuples;i++)
5322     if(pt[i]!=val)
5323       vec[i]=true;
5324 }
5325
5326 /*!
5327  * Computes for each tuple the sum of number of components values in the tuple and return it.
5328  * 
5329  * \return DataArrayInt * - the new instance of DataArrayInt containing the
5330  *          same number of tuples as \a this array and one component.
5331  *          The caller is to delete this result array using decrRef() as it is no more
5332  *          needed.
5333  *  \throw If \a this is not allocated.
5334  */
5335 DataArrayInt *DataArrayInt::sumPerTuple() const
5336 {
5337   checkAllocated();
5338   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
5339   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5340   ret->alloc(nbOfTuple,1);
5341   const int *src(getConstPointer());
5342   int *dest(ret->getPointer());
5343   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
5344     *dest=std::accumulate(src,src+nbOfComp,0);
5345   return ret.retn();
5346 }
5347
5348 /*!
5349  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5350  * If not an exception is thrown.
5351  *  \param [in] increasing - if \a true, the array values should be increasing.
5352  *  \throw If sequence of values is not strictly monotonic in agreement with \a
5353  *         increasing arg.
5354  *  \throw If \a this->getNumberOfComponents() != 1.
5355  *  \throw If \a this is not allocated.
5356  */
5357 void DataArrayInt::checkMonotonic(bool increasing) const
5358 {
5359   if(!isMonotonic(increasing))
5360     {
5361       if (increasing)
5362         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
5363       else
5364         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
5365     }
5366 }
5367
5368 /*!
5369  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5370  *  \param [in] increasing - if \a true, array values should be increasing.
5371  *  \return bool - \a true if values change in accordance with \a increasing arg.
5372  *  \throw If \a this->getNumberOfComponents() != 1.
5373  *  \throw If \a this is not allocated.
5374  */
5375 bool DataArrayInt::isMonotonic(bool increasing) const
5376 {
5377   checkAllocated();
5378   if(getNumberOfComponents()!=1)
5379     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
5380   int nbOfElements=getNumberOfTuples();
5381   const int *ptr=getConstPointer();
5382   if(nbOfElements==0)
5383     return true;
5384   int ref=ptr[0];
5385   if(increasing)
5386     {
5387       for(int i=1;i<nbOfElements;i++)
5388         {
5389           if(ptr[i]>=ref)
5390             ref=ptr[i];
5391           else
5392             return false;
5393         }
5394     }
5395   else
5396     {
5397       for(int i=1;i<nbOfElements;i++)
5398         {
5399           if(ptr[i]<=ref)
5400             ref=ptr[i];
5401           else
5402             return false;
5403         }
5404     }
5405   return true;
5406 }
5407
5408 /*!
5409  * This method check that array consistently INCREASING or DECREASING in value.
5410  */
5411 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
5412 {
5413   checkAllocated();
5414   if(getNumberOfComponents()!=1)
5415     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
5416   int nbOfElements=getNumberOfTuples();
5417   const int *ptr=getConstPointer();
5418   if(nbOfElements==0)
5419     return true;
5420   int ref=ptr[0];
5421   if(increasing)
5422     {
5423       for(int i=1;i<nbOfElements;i++)
5424         {
5425           if(ptr[i]>ref)
5426             ref=ptr[i];
5427           else
5428             return false;
5429         }
5430     }
5431   else
5432     {
5433       for(int i=1;i<nbOfElements;i++)
5434         {
5435           if(ptr[i]<ref)
5436             ref=ptr[i];
5437           else
5438             return false;
5439         }
5440     }
5441   return true;
5442 }
5443
5444 /*!
5445  * This method check that array consistently INCREASING or DECREASING in value.
5446  */
5447 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
5448 {
5449   if(!isStrictlyMonotonic(increasing))
5450     {
5451       if (increasing)
5452         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
5453       else
5454         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
5455     }
5456 }
5457
5458 /*!
5459  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
5460  * one-dimensional arrays that must be of the same length. The result array describes
5461  * correspondence between \a this and \a other arrays, so that 
5462  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
5463  * not possible because some element in \a other is not in \a this, an exception is thrown.
5464  *  \param [in] other - an array to compute permutation to.
5465  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
5466  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
5467  * no more needed.
5468  *  \throw If \a this->getNumberOfComponents() != 1.
5469  *  \throw If \a other->getNumberOfComponents() != 1.
5470  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
5471  *  \throw If \a other includes a value which is not in \a this array.
5472  * 
5473  *  \if ENABLE_EXAMPLES
5474  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
5475  *
5476  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
5477  *  \endif
5478  */
5479 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
5480 {
5481   checkAllocated();
5482   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
5483     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
5484   int nbTuple=getNumberOfTuples();
5485   other.checkAllocated();
5486   if(nbTuple!=other.getNumberOfTuples())
5487     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
5488   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5489   ret->alloc(nbTuple,1);
5490   ret->fillWithValue(-1);
5491   const int *pt=getConstPointer();
5492   std::map<int,int> mm;
5493   for(int i=0;i<nbTuple;i++)
5494     mm[pt[i]]=i;
5495   pt=other.getConstPointer();
5496   int *retToFill=ret->getPointer();
5497   for(int i=0;i<nbTuple;i++)
5498     {
5499       std::map<int,int>::const_iterator it=mm.find(pt[i]);
5500       if(it==mm.end())
5501         {
5502           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
5503           throw INTERP_KERNEL::Exception(oss.str().c_str());
5504         }
5505       retToFill[i]=(*it).second;
5506     }
5507   return ret.retn();
5508 }
5509
5510 void DataArrayInt::aggregate(const DataArrayInt *other)
5511 {
5512   if(!other)
5513     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : null pointer !");
5514   if(getNumberOfComponents()!=other->getNumberOfComponents())
5515     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : mismatch number of components !");
5516   _mem.insertAtTheEnd(other->begin(),other->end());
5517 }
5518
5519 /*!
5520  * Returns a new DataArrayInt holding the same values as \a this array but differently
5521  * arranged in memory. If \a this array holds 2 components of 3 values:
5522  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
5523  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
5524  *  \warning Do not confuse this method with transpose()!
5525  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5526  *          is to delete using decrRef() as it is no more needed.
5527  *  \throw If \a this is not allocated.
5528  */
5529 DataArrayInt *DataArrayInt::fromNoInterlace() const
5530 {
5531   checkAllocated();
5532   if(_mem.isNull())
5533     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
5534   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
5535   DataArrayInt *ret=DataArrayInt::New();
5536   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5537   return ret;
5538 }
5539
5540 /*!
5541  * Returns a new DataArrayInt holding the same values as \a this array but differently
5542  * arranged in memory. If \a this array holds 2 components of 3 values:
5543  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
5544  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
5545  *  \warning Do not confuse this method with transpose()!
5546  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5547  *          is to delete using decrRef() as it is no more needed.
5548  *  \throw If \a this is not allocated.
5549  */
5550 DataArrayInt *DataArrayInt::toNoInterlace() const
5551 {
5552   checkAllocated();
5553   if(_mem.isNull())
5554     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
5555   int *tab=_mem.toNoInterlace(getNumberOfComponents());
5556   DataArrayInt *ret=DataArrayInt::New();
5557   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5558   return ret;
5559 }
5560
5561 /*!
5562  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
5563  * This map, if applied to \a this array, would make it sorted. For example, if
5564  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
5565  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
5566  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
5567  * This method is useful for renumbering (in MED file for example). For more info
5568  * on renumbering see \ref numbering.
5569  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5570  *          array using decrRef() as it is no more needed.
5571  *  \throw If \a this is not allocated.
5572  *  \throw If \a this->getNumberOfComponents() != 1.
5573  *  \throw If there are equal values in \a this array.
5574  */
5575 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
5576 {
5577   checkAllocated();
5578   if(getNumberOfComponents()!=1)
5579     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
5580   int nbTuples=getNumberOfTuples();
5581   const int *pt=getConstPointer();
5582   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
5583   DataArrayInt *ret=DataArrayInt::New();
5584   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
5585   return ret;
5586 }
5587
5588 /*!
5589  * 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
5590  * input array \a ids2.
5591  * \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.
5592  * 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
5593  * inversely.
5594  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
5595  *
5596  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5597  *          array using decrRef() as it is no more needed.
5598  * \throw If either ids1 or ids2 is null not allocated or not with one components.
5599  * 
5600  */
5601 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
5602 {
5603   if(!ids1 || !ids2)
5604     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
5605   if(!ids1->isAllocated() || !ids2->isAllocated())
5606     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
5607   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
5608     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
5609   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
5610     {
5611       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 !";
5612       throw INTERP_KERNEL::Exception(oss.str().c_str());
5613     }
5614   MCAuto<DataArrayInt> p1(ids1->deepCopy());
5615   MCAuto<DataArrayInt> p2(ids2->deepCopy());
5616   p1->sort(true); p2->sort(true);
5617   if(!p1->isEqualWithoutConsideringStr(*p2))
5618     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
5619   p1=ids1->checkAndPreparePermutation();
5620   p2=ids2->checkAndPreparePermutation();
5621   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
5622   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
5623   return p2.retn();
5624 }
5625
5626 /*!
5627  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
5628  * onto a set of values of size \a targetNb (\a B). The surjective function is 
5629  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
5630  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
5631  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
5632  * The first of out arrays returns indices of elements of \a this array, grouped by their
5633  * place in the set \a B. The second out array is the index of the first one; it shows how
5634  * many elements of \a A are mapped into each element of \a B. <br>
5635  * For more info on
5636  * mapping and its usage in renumbering see \ref numbering. <br>
5637  * \b Example:
5638  * - \a this: [0,3,2,3,2,2,1,2]
5639  * - \a targetNb: 4
5640  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
5641  * - \a arrI: [0,1,2,6,8]
5642  *
5643  * This result means: <br>
5644  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
5645  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
5646  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
5647  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
5648  * \a arrI[ 2+1 ]]); <br> etc.
5649  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
5650  *         than the maximal value of \a A.
5651  *  \param [out] arr - a new instance of DataArrayInt returning indices of
5652  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
5653  *         this array using decrRef() as it is no more needed.
5654  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
5655  *         elements of \a this. The caller is to delete this array using decrRef() as it
5656  *         is no more needed.
5657  *  \throw If \a this is not allocated.
5658  *  \throw If \a this->getNumberOfComponents() != 1.
5659  *  \throw If any value in \a this is more or equal to \a targetNb.
5660  */
5661 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
5662 {
5663   checkAllocated();
5664   if(getNumberOfComponents()!=1)
5665     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
5666   int nbOfTuples=getNumberOfTuples();
5667   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5668   MCAuto<DataArrayInt> retI(DataArrayInt::New());
5669   retI->alloc(targetNb+1,1);
5670   const int *input=getConstPointer();
5671   std::vector< std::vector<int> > tmp(targetNb);
5672   for(int i=0;i<nbOfTuples;i++)
5673     {
5674       int tmp2=input[i];
5675       if(tmp2>=0 && tmp2<targetNb)
5676         tmp[tmp2].push_back(i);
5677       else
5678         {
5679           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
5680           throw INTERP_KERNEL::Exception(oss.str().c_str());
5681         }
5682     }
5683   int *retIPtr=retI->getPointer();
5684   *retIPtr=0;
5685   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
5686     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
5687   if(nbOfTuples!=retI->getIJ(targetNb,0))
5688     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
5689   ret->alloc(nbOfTuples,1);
5690   int *retPtr=ret->getPointer();
5691   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
5692     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
5693   arr=ret.retn();
5694   arrI=retI.retn();
5695 }
5696
5697
5698 /*!
5699  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
5700  * from a zip representation of a surjective format (returned e.g. by
5701  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
5702  * for example). The result array minimizes the permutation. <br>
5703  * For more info on renumbering see \ref numbering. <br>
5704  * \b Example: <br>
5705  * - \a nbOfOldTuples: 10 
5706  * - \a arr          : [0,3, 5,7,9]
5707  * - \a arrIBg       : [0,2,5]
5708  * - \a newNbOfTuples: 7
5709  * - result array    : [0,1,2,0,3,4,5,4,6,4]
5710  *
5711  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
5712  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
5713  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
5714  *         (indices of) equal values. Its every element (except the last one) points to
5715  *         the first element of a group of equal values.
5716  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
5717  *          arrIBg is \a arrIEnd[ -1 ].
5718  *  \param [out] newNbOfTuples - number of tuples after surjection application.
5719  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5720  *          array using decrRef() as it is no more needed.
5721  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
5722  */
5723 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
5724 {
5725   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5726   ret->alloc(nbOfOldTuples,1);
5727   int *pt=ret->getPointer();
5728   std::fill(pt,pt+nbOfOldTuples,-1);
5729   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
5730   const int *cIPtr=arrIBg;
5731   for(int i=0;i<nbOfGrps;i++)
5732     pt[arr[cIPtr[i]]]=-(i+2);
5733   int newNb=0;
5734   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
5735     {
5736       if(pt[iNode]<0)
5737         {
5738           if(pt[iNode]==-1)
5739             pt[iNode]=newNb++;
5740           else
5741             {
5742               int grpId=-(pt[iNode]+2);
5743               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
5744                 {
5745                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
5746                     pt[arr[j]]=newNb;
5747                   else
5748                     {
5749                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
5750                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5751                     }
5752                 }
5753               newNb++;
5754             }
5755         }
5756     }
5757   newNbOfTuples=newNb;
5758   return ret.retn();
5759 }
5760
5761 /*!
5762  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
5763  * which if applied to \a this array would make it sorted ascendingly.
5764  * For more info on renumbering see \ref numbering. <br>
5765  * \b Example: <br>
5766  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
5767  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
5768  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
5769  *
5770  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5771  *          array using decrRef() as it is no more needed.
5772  *  \throw If \a this is not allocated.
5773  *  \throw If \a this->getNumberOfComponents() != 1.
5774  */
5775 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
5776 {
5777   checkAllocated();
5778   if(getNumberOfComponents()!=1)
5779     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
5780   int nbOfTuples=getNumberOfTuples();
5781   const int *pt=getConstPointer();
5782   std::map<int,int> m;
5783   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5784   ret->alloc(nbOfTuples,1);
5785   int *opt=ret->getPointer();
5786   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5787     {
5788       int val=*pt;
5789       std::map<int,int>::iterator it=m.find(val);
5790       if(it!=m.end())
5791         {
5792           *opt=(*it).second;
5793           (*it).second++;
5794         }
5795       else
5796         {
5797           *opt=0;
5798           m.insert(std::pair<int,int>(val,1));
5799         }
5800     }
5801   int sum=0;
5802   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
5803     {
5804       int vt=(*it).second;
5805       (*it).second=sum;
5806       sum+=vt;
5807     }
5808   pt=getConstPointer();
5809   opt=ret->getPointer();
5810   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5811     *opt+=m[*pt];
5812   //
5813   return ret.retn();
5814 }
5815
5816 /*!
5817  * Checks if \a this array has the given size, and if its contents is equal to an array filled with
5818  * iota(). This method is particularly useful for DataArrayInt instances that represent
5819  * a renumbering array, to check if there is a real need in renumbering.
5820  * This method checks than \a this can be considered as an identity mapping
5821  * of a set having \a sizeExpected elements into itself.
5822  *
5823  *  \param [in] sizeExpected - The number of elements expected.
5824  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
5825  *  \throw If \a this is not allocated.
5826  *  \throw If \a this->getNumberOfComponents() != 1.
5827  */
5828 bool DataArrayInt::isIota(int sizeExpected) const
5829 {
5830   checkAllocated();
5831   if(getNumberOfComponents()!=1)
5832     return false;
5833   int nbOfTuples(getNumberOfTuples());
5834   if(nbOfTuples!=sizeExpected)
5835     return false;
5836   const int *pt=getConstPointer();
5837   for(int i=0;i<nbOfTuples;i++,pt++)
5838     if(*pt!=i)
5839       return false;
5840   return true;
5841 }
5842
5843 /*!
5844  * Checks if all values in \a this array are equal to \a val.
5845  *  \param [in] val - value to check equality of array values to.
5846  *  \return bool - \a true if all values are \a val.
5847  *  \throw If \a this is not allocated.
5848  *  \throw If \a this->getNumberOfComponents() != 1
5849  */
5850 bool DataArrayInt::isUniform(int val) const
5851 {
5852   checkAllocated();
5853   if(getNumberOfComponents()!=1)
5854     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5855   int nbOfTuples=getNumberOfTuples();
5856   const int *w=getConstPointer();
5857   const int *end2=w+nbOfTuples;
5858   for(;w!=end2;w++)
5859     if(*w!=val)
5860       return false;
5861   return true;
5862 }
5863
5864 /*!
5865  * Checks if all values in \a this array are unique.
5866  *  \return bool - \a true if condition above is true
5867  *  \throw If \a this is not allocated.
5868  *  \throw If \a this->getNumberOfComponents() != 1
5869  */
5870 bool DataArrayInt::hasUniqueValues() const
5871 {
5872   checkAllocated();
5873   if(getNumberOfComponents()!=1)
5874     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5875   int nbOfTuples(getNumberOfTuples());
5876   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
5877   if (s.size() != nbOfTuples)
5878     return false;
5879   return true;
5880 }
5881
5882 /*!
5883  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
5884  * array to the new one.
5885  *  \return DataArrayDouble * - the new instance of DataArrayInt.
5886  */
5887 DataArrayDouble *DataArrayInt::convertToDblArr() const
5888 {
5889   checkAllocated();
5890   DataArrayDouble *ret=DataArrayDouble::New();
5891   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
5892   std::size_t nbOfVals=getNbOfElems();
5893   const int *src=getConstPointer();
5894   double *dest=ret->getPointer();
5895   std::copy(src,src+nbOfVals,dest);
5896   ret->copyStringInfoFrom(*this);
5897   return ret;
5898 }
5899
5900 /*!
5901  * Appends components of another array to components of \a this one, tuple by tuple.
5902  * So that the number of tuples of \a this array remains the same and the number of 
5903  * components increases.
5904  *  \param [in] other - the DataArrayInt to append to \a this one.
5905  *  \throw If \a this is not allocated.
5906  *  \throw If \a this and \a other arrays have different number of tuples.
5907  *
5908  *  \if ENABLE_EXAMPLES
5909  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
5910  *
5911  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
5912  *  \endif
5913  */
5914 void DataArrayInt::meldWith(const DataArrayInt *other)
5915 {
5916   if(!other)
5917     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
5918   checkAllocated();
5919   other->checkAllocated();
5920   int nbOfTuples=getNumberOfTuples();
5921   if(nbOfTuples!=other->getNumberOfTuples())
5922     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
5923   int nbOfComp1=getNumberOfComponents();
5924   int nbOfComp2=other->getNumberOfComponents();
5925   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
5926   int *w=newArr;
5927   const int *inp1=getConstPointer();
5928   const int *inp2=other->getConstPointer();
5929   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
5930     {
5931       w=std::copy(inp1,inp1+nbOfComp1,w);
5932       w=std::copy(inp2,inp2+nbOfComp2,w);
5933     }
5934   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
5935   std::vector<int> compIds(nbOfComp2);
5936   for(int i=0;i<nbOfComp2;i++)
5937     compIds[i]=nbOfComp1+i;
5938   copyPartOfStringInfoFrom2(compIds,*other);
5939 }
5940
5941 /*!
5942  * Copy all components in a specified order from another DataArrayInt.
5943  * The specified components become the first ones in \a this array.
5944  * Both numerical and textual data is copied. The number of tuples in \a this and
5945  * the other array can be different.
5946  *  \param [in] a - the array to copy data from.
5947  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
5948  *              to be copied.
5949  *  \throw If \a a is NULL.
5950  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
5951  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
5952  *
5953  *  \if ENABLE_EXAMPLES
5954  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
5955  *  \endif
5956  */
5957 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
5958 {
5959   if(!a)
5960     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
5961   checkAllocated();
5962   a->checkAllocated();
5963   copyPartOfStringInfoFrom2(compoIds,*a);
5964   std::size_t partOfCompoSz=compoIds.size();
5965   int nbOfCompo=getNumberOfComponents();
5966   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
5967   const int *ac=a->getConstPointer();
5968   int *nc=getPointer();
5969   for(int i=0;i<nbOfTuples;i++)
5970     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
5971       nc[nbOfCompo*i+compoIds[j]]=*ac;
5972 }
5973
5974 /*!
5975  * Assign pointer to one array to a pointer to another appay. Reference counter of
5976  * \a arrayToSet is incremented / decremented.
5977  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
5978  *  \param [in,out] arrayToSet - the pointer to array to assign to.
5979  */
5980 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
5981 {
5982   if(newArray!=arrayToSet)
5983     {
5984       if(arrayToSet)
5985         arrayToSet->decrRef();
5986       arrayToSet=newArray;
5987       if(arrayToSet)
5988         arrayToSet->incrRef();
5989     }
5990 }
5991
5992 DataArrayIntIterator *DataArrayInt::iterator()
5993 {
5994   return new DataArrayIntIterator(this);
5995 }
5996
5997 /*!
5998  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
5999  * given one. The ids are sorted in the ascending order.
6000  *  \param [in] val - the value to find within \a this.
6001  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6002  *          array using decrRef() as it is no more needed.
6003  *  \throw If \a this is not allocated.
6004  *  \throw If \a this->getNumberOfComponents() != 1.
6005  *  \sa DataArrayInt::findIdsEqualTuple
6006  */
6007 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
6008 {
6009   checkAllocated();
6010   if(getNumberOfComponents()!=1)
6011     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
6012   const int *cptr(getConstPointer());
6013   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6014   int nbOfTuples=getNumberOfTuples();
6015   for(int i=0;i<nbOfTuples;i++,cptr++)
6016     if(*cptr==val)
6017       ret->pushBackSilent(i);
6018   return ret.retn();
6019 }
6020
6021 /*!
6022  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
6023  * equal to a given one. 
6024  *  \param [in] val - the value to ignore within \a this.
6025  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6026  *          array using decrRef() as it is no more needed.
6027  *  \throw If \a this is not allocated.
6028  *  \throw If \a this->getNumberOfComponents() != 1.
6029  */
6030 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
6031 {
6032   checkAllocated();
6033   if(getNumberOfComponents()!=1)
6034     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
6035   const int *cptr(getConstPointer());
6036   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6037   int nbOfTuples=getNumberOfTuples();
6038   for(int i=0;i<nbOfTuples;i++,cptr++)
6039     if(*cptr!=val)
6040       ret->pushBackSilent(i);
6041   return ret.retn();
6042 }
6043
6044 /*!
6045  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
6046  * This method is an extension of  DataArrayInt::findIdsEqual method.
6047  *
6048  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
6049  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
6050  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6051  *          array using decrRef() as it is no more needed.
6052  *  \throw If \a this is not allocated.
6053  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
6054  * \throw If \a this->getNumberOfComponents() is equal to 0.
6055  * \sa DataArrayInt::findIdsEqual
6056  */
6057 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
6058 {
6059   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
6060   checkAllocated();
6061   if(getNumberOfComponents()!=(int)nbOfCompoExp)
6062     {
6063       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
6064       throw INTERP_KERNEL::Exception(oss.str().c_str());
6065     }
6066   if(nbOfCompoExp==0)
6067     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
6068   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6069   const int *bg(begin()),*end2(end()),*work(begin());
6070   while(work!=end2)
6071     {
6072       work=std::search(work,end2,tupleBg,tupleEnd);
6073       if(work!=end2)
6074         {
6075           std::size_t pos(std::distance(bg,work));
6076           if(pos%nbOfCompoExp==0)
6077             ret->pushBackSilent(pos/nbOfCompoExp);
6078           work++;
6079         }
6080     }
6081   return ret.retn();
6082 }
6083
6084 /*!
6085  * Assigns \a newValue to all elements holding \a oldValue within \a this
6086  * one-dimensional array.
6087  *  \param [in] oldValue - the value to replace.
6088  *  \param [in] newValue - the value to assign.
6089  *  \return int - number of replacements performed.
6090  *  \throw If \a this is not allocated.
6091  *  \throw If \a this->getNumberOfComponents() != 1.
6092  */
6093 int DataArrayInt::changeValue(int oldValue, int newValue)
6094 {
6095   checkAllocated();
6096   if(getNumberOfComponents()!=1)
6097     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
6098   if(oldValue==newValue)
6099     return 0;
6100   int *start(getPointer()),*end2(start+getNbOfElems());
6101   int ret(0);
6102   for(int *val=start;val!=end2;val++)
6103     {
6104       if(*val==oldValue)
6105         {
6106           *val=newValue;
6107           ret++;
6108         }
6109     }
6110   if(ret>0)
6111     declareAsNew();
6112   return ret;
6113 }
6114
6115 /*!
6116  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
6117  * one of given values.
6118  *  \param [in] valsBg - an array of values to find within \a this array.
6119  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6120  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6121  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6122  *          array using decrRef() as it is no more needed.
6123  *  \throw If \a this->getNumberOfComponents() != 1.
6124  */
6125 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
6126 {
6127   if(getNumberOfComponents()!=1)
6128     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
6129   std::set<int> vals2(valsBg,valsEnd);
6130   const int *cptr(getConstPointer());
6131   std::vector<int> res;
6132   int nbOfTuples(getNumberOfTuples());
6133   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6134   for(int i=0;i<nbOfTuples;i++,cptr++)
6135     if(vals2.find(*cptr)!=vals2.end())
6136       ret->pushBackSilent(i);
6137   return ret.retn();
6138 }
6139
6140 /*!
6141  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
6142  * equal to any of given values.
6143  *  \param [in] valsBg - an array of values to ignore within \a this array.
6144  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6145  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6146  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6147  *          array using decrRef() as it is no more needed.
6148  *  \throw If \a this->getNumberOfComponents() != 1.
6149  */
6150 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
6151 {
6152   if(getNumberOfComponents()!=1)
6153     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
6154   std::set<int> vals2(valsBg,valsEnd);
6155   const int *cptr=getConstPointer();
6156   std::vector<int> res;
6157   int nbOfTuples=getNumberOfTuples();
6158   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6159   for(int i=0;i<nbOfTuples;i++,cptr++)
6160     if(vals2.find(*cptr)==vals2.end())
6161       ret->pushBackSilent(i);
6162   return ret.retn();
6163 }
6164
6165 /*!
6166  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
6167  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6168  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6169  * If any the tuple id is returned. If not -1 is returned.
6170  * 
6171  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6172  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6173  *
6174  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
6175  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
6176  */
6177 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
6178 {
6179   checkAllocated();
6180   int nbOfCompo=getNumberOfComponents();
6181   if(nbOfCompo==0)
6182     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
6183   if(nbOfCompo!=(int)tupl.size())
6184     {
6185       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
6186       throw INTERP_KERNEL::Exception(oss.str().c_str());
6187     }
6188   const int *cptr=getConstPointer();
6189   std::size_t nbOfVals=getNbOfElems();
6190   for(const int *work=cptr;work!=cptr+nbOfVals;)
6191     {
6192       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
6193       if(work!=cptr+nbOfVals)
6194         {
6195           if(std::distance(cptr,work)%nbOfCompo!=0)
6196             work++;
6197           else
6198             return std::distance(cptr,work)/nbOfCompo;
6199         }
6200     }
6201   return -1;
6202 }
6203
6204 /*!
6205  * This method searches the sequence specified in input parameter \b vals in \b this.
6206  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
6207  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
6208  * \sa DataArrayInt::findIdFirstEqualTuple
6209  */
6210 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
6211 {
6212   checkAllocated();
6213   int nbOfCompo=getNumberOfComponents();
6214   if(nbOfCompo!=1)
6215     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
6216   const int *cptr=getConstPointer();
6217   std::size_t nbOfVals=getNbOfElems();
6218   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
6219   if(loc!=cptr+nbOfVals)
6220     return std::distance(cptr,loc);
6221   return -1;
6222 }
6223
6224 /*!
6225  * This method expects to be called when number of components of this is equal to one.
6226  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
6227  * If not any tuple contains \b value -1 is returned.
6228  * \sa DataArrayInt::presenceOfValue
6229  */
6230 int DataArrayInt::findIdFirstEqual(int value) const
6231 {
6232   checkAllocated();
6233   if(getNumberOfComponents()!=1)
6234     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6235   const int *cptr=getConstPointer();
6236   int nbOfTuples=getNumberOfTuples();
6237   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
6238   if(ret!=cptr+nbOfTuples)
6239     return std::distance(cptr,ret);
6240   return -1;
6241 }
6242
6243 /*!
6244  * This method expects to be called when number of components of this is equal to one.
6245  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
6246  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
6247  * \sa DataArrayInt::presenceOfValue
6248  */
6249 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
6250 {
6251   checkAllocated();
6252   if(getNumberOfComponents()!=1)
6253     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6254   std::set<int> vals2(vals.begin(),vals.end());
6255   const int *cptr=getConstPointer();
6256   int nbOfTuples=getNumberOfTuples();
6257   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
6258     if(vals2.find(*w)!=vals2.end())
6259       return std::distance(cptr,w);
6260   return -1;
6261 }
6262
6263 /*!
6264  * This method returns the number of values in \a this that are equals to input parameter \a value.
6265  * This method only works for single component array.
6266  *
6267  * \return a value in [ 0, \c this->getNumberOfTuples() )
6268  *
6269  * \throw If \a this is not allocated
6270  *
6271  */
6272 int DataArrayInt::count(int value) const
6273 {
6274   int ret=0;
6275   checkAllocated();
6276   if(getNumberOfComponents()!=1)
6277     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6278   const int *vals=begin();
6279   int nbOfTuples=getNumberOfTuples();
6280   for(int i=0;i<nbOfTuples;i++,vals++)
6281     if(*vals==value)
6282       ret++;
6283   return ret;
6284 }
6285
6286 /*!
6287  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
6288  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6289  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6290  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6291  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6292  * \sa DataArrayInt::findIdFirstEqualTuple
6293  */
6294 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
6295 {
6296   return findIdFirstEqualTuple(tupl)!=-1;
6297 }
6298
6299
6300 /*!
6301  * Returns \a true if a given value is present within \a this one-dimensional array.
6302  *  \param [in] value - the value to find within \a this array.
6303  *  \return bool - \a true in case if \a value is present within \a this array.
6304  *  \throw If \a this is not allocated.
6305  *  \throw If \a this->getNumberOfComponents() != 1.
6306  *  \sa findIdFirstEqual()
6307  */
6308 bool DataArrayInt::presenceOfValue(int value) const
6309 {
6310   return findIdFirstEqual(value)!=-1;
6311 }
6312
6313 /*!
6314  * This method expects to be called when number of components of this is equal to one.
6315  * This method returns true if it exists a tuple so that the value is contained in \b vals.
6316  * If not any tuple contains one of the values contained in 'vals' false is returned.
6317  * \sa DataArrayInt::findIdFirstEqual
6318  */
6319 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
6320 {
6321   return findIdFirstEqual(vals)!=-1;
6322 }
6323
6324 /*!
6325  * Accumulates values of each component of \a this array.
6326  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
6327  *         by the caller, that is filled by this method with sum value for each
6328  *         component.
6329  *  \throw If \a this is not allocated.
6330  */
6331 void DataArrayInt::accumulate(int *res) const
6332 {
6333   checkAllocated();
6334   const int *ptr=getConstPointer();
6335   int nbTuple=getNumberOfTuples();
6336   int nbComps=getNumberOfComponents();
6337   std::fill(res,res+nbComps,0);
6338   for(int i=0;i<nbTuple;i++)
6339     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
6340 }
6341
6342 int DataArrayInt::accumulate(int compId) const
6343 {
6344   checkAllocated();
6345   const int *ptr=getConstPointer();
6346   int nbTuple=getNumberOfTuples();
6347   int nbComps=getNumberOfComponents();
6348   if(compId<0 || compId>=nbComps)
6349     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
6350   int ret=0;
6351   for(int i=0;i<nbTuple;i++)
6352     ret+=ptr[i*nbComps+compId];
6353   return ret;
6354 }
6355
6356 /*!
6357  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
6358  * The returned array will have same number of components than \a this and number of tuples equal to
6359  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
6360  *
6361  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
6362  *
6363  * \param [in] bgOfIndex - begin (included) of the input index array.
6364  * \param [in] endOfIndex - end (excluded) of the input index array.
6365  * \return DataArrayInt * - the new instance having the same number of components than \a this.
6366  * 
6367  * \throw If bgOfIndex or end is NULL.
6368  * \throw If input index array is not ascendingly sorted.
6369  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
6370  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
6371  */
6372 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
6373 {
6374   if(!bgOfIndex || !endOfIndex)
6375     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
6376   checkAllocated();
6377   int nbCompo=getNumberOfComponents();
6378   int nbOfTuples=getNumberOfTuples();
6379   int sz=(int)std::distance(bgOfIndex,endOfIndex);
6380   if(sz<1)
6381     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
6382   sz--;
6383   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
6384   const int *w=bgOfIndex;
6385   if(*w<0 || *w>=nbOfTuples)
6386     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
6387   const int *srcPt=begin()+(*w)*nbCompo;
6388   int *tmp=ret->getPointer();
6389   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
6390     {
6391       std::fill(tmp,tmp+nbCompo,0);
6392       if(w[1]>=w[0])
6393         {
6394           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
6395             {
6396               if(j>=0 && j<nbOfTuples)
6397                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
6398               else
6399                 {
6400                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
6401                   throw INTERP_KERNEL::Exception(oss.str().c_str());
6402                 }
6403             }
6404         }
6405       else
6406         {
6407           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
6408           throw INTERP_KERNEL::Exception(oss.str().c_str());
6409         }
6410     }
6411   ret->copyStringInfoFrom(*this);
6412   return ret.retn();
6413 }
6414
6415 /*!
6416  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
6417  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
6418  * offsetA2</em> and (2)
6419  * the number of component in the result array is same as that of each of given arrays.
6420  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
6421  * Info on components is copied from the first of the given arrays. Number of components
6422  * in the given arrays must be the same.
6423  *  \param [in] a1 - an array to include in the result array.
6424  *  \param [in] a2 - another array to include in the result array.
6425  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
6426  *  \return DataArrayInt * - the new instance of DataArrayInt.
6427  *          The caller is to delete this result array using decrRef() as it is no more
6428  *          needed.
6429  *  \throw If either \a a1 or \a a2 is NULL.
6430  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
6431  */
6432 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
6433 {
6434   if(!a1 || !a2)
6435     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
6436   int nbOfComp=a1->getNumberOfComponents();
6437   if(nbOfComp!=a2->getNumberOfComponents())
6438     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
6439   int nbOfTuple1=a1->getNumberOfTuples();
6440   int nbOfTuple2=a2->getNumberOfTuples();
6441   DataArrayInt *ret=DataArrayInt::New();
6442   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
6443   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
6444   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
6445   ret->copyStringInfoFrom(*a1);
6446   return ret;
6447 }
6448
6449 /*!
6450  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
6451  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
6452  * the number of component in the result array is same as that of each of given arrays.
6453  * Info on components is copied from the first of the given arrays. Number of components
6454  * in the given arrays must be  the same.
6455  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
6456  * not the object itself.
6457  *  \param [in] arr - a sequence of arrays to include in the result array.
6458  *  \return DataArrayInt * - the new instance of DataArrayInt.
6459  *          The caller is to delete this result array using decrRef() as it is no more
6460  *          needed.
6461  *  \throw If all arrays within \a arr are NULL.
6462  *  \throw If getNumberOfComponents() of arrays within \a arr.
6463  */
6464 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
6465 {
6466   std::vector<const DataArrayInt *> a;
6467   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6468     if(*it4)
6469       a.push_back(*it4);
6470   if(a.empty())
6471     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
6472   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
6473   int nbOfComp=(*it)->getNumberOfComponents();
6474   int nbt=(*it++)->getNumberOfTuples();
6475   for(int i=1;it!=a.end();it++,i++)
6476     {
6477       if((*it)->getNumberOfComponents()!=nbOfComp)
6478         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
6479       nbt+=(*it)->getNumberOfTuples();
6480     }
6481   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6482   ret->alloc(nbt,nbOfComp);
6483   int *pt=ret->getPointer();
6484   for(it=a.begin();it!=a.end();it++)
6485     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
6486   ret->copyStringInfoFrom(*(a[0]));
6487   return ret.retn();
6488 }
6489
6490 /*!
6491  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
6492  * A packed index array is an allocated array with one component, and at least one tuple. The first element
6493  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
6494  * 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.
6495  * 
6496  * \return DataArrayInt * - a new object to be managed by the caller.
6497  */
6498 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
6499 {
6500   int retSz=1;
6501   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
6502     {
6503       if(*it4)
6504         {
6505           (*it4)->checkAllocated();
6506           if((*it4)->getNumberOfComponents()!=1)
6507             {
6508               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6509               throw INTERP_KERNEL::Exception(oss.str().c_str());
6510             }
6511           int nbTupl=(*it4)->getNumberOfTuples();
6512           if(nbTupl<1)
6513             {
6514               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6515               throw INTERP_KERNEL::Exception(oss.str().c_str());
6516             }
6517           if((*it4)->front()!=0)
6518             {
6519               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
6520               throw INTERP_KERNEL::Exception(oss.str().c_str());
6521             }
6522           retSz+=nbTupl-1;
6523         }
6524       else
6525         {
6526           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
6527           throw INTERP_KERNEL::Exception(oss.str().c_str());
6528         }
6529     }
6530   if(arrs.empty())
6531     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
6532   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6533   ret->alloc(retSz,1);
6534   int *pt=ret->getPointer(); *pt++=0;
6535   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
6536     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
6537   ret->copyStringInfoFrom(*(arrs[0]));
6538   return ret.retn();
6539 }
6540
6541 /*!
6542  * Returns in a single walk in \a this the min value and the max value in \a this.
6543  * \a this is expected to be single component array.
6544  *
6545  * \param [out] minValue - the min value in \a this.
6546  * \param [out] maxValue - the max value in \a this.
6547  *
6548  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
6549  */
6550 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
6551 {
6552   checkAllocated();
6553   if(getNumberOfComponents()!=1)
6554     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
6555   int nbTuples(getNumberOfTuples());
6556   const int *pt(begin());
6557   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
6558   for(int i=0;i<nbTuples;i++,pt++)
6559     {
6560       if(*pt<minValue)
6561         minValue=*pt;
6562       if(*pt>maxValue)
6563         maxValue=*pt;
6564     }
6565 }
6566
6567 /*!
6568  * Converts every value of \a this array to its absolute value.
6569  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
6570  * should be called instead.
6571  *
6572  * \throw If \a this is not allocated.
6573  * \sa DataArrayInt::computeAbs
6574  */
6575 void DataArrayInt::abs()
6576 {
6577   checkAllocated();
6578   int *ptr(getPointer());
6579   std::size_t nbOfElems(getNbOfElems());
6580   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
6581   declareAsNew();
6582 }
6583
6584 /*!
6585  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
6586  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
6587  *
6588  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6589  *         same number of tuples and component as \a this array.
6590  *         The caller is to delete this result array using decrRef() as it is no more
6591  *         needed.
6592  * \throw If \a this is not allocated.
6593  * \sa DataArrayInt::abs
6594  */
6595 DataArrayInt *DataArrayInt::computeAbs() const
6596 {
6597   checkAllocated();
6598   DataArrayInt *newArr(DataArrayInt::New());
6599   int nbOfTuples(getNumberOfTuples());
6600   int nbOfComp(getNumberOfComponents());
6601   newArr->alloc(nbOfTuples,nbOfComp);
6602   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
6603   newArr->copyStringInfoFrom(*this);
6604   return newArr;
6605 }
6606
6607 /*!
6608  * Apply a liner function to a given component of \a this array, so that
6609  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
6610  *  \param [in] a - the first coefficient of the function.
6611  *  \param [in] b - the second coefficient of the function.
6612  *  \param [in] compoId - the index of component to modify.
6613  *  \throw If \a this is not allocated.
6614  */
6615 void DataArrayInt::applyLin(int a, int b, int compoId)
6616 {
6617   checkAllocated();
6618   int *ptr=getPointer()+compoId;
6619   int nbOfComp=getNumberOfComponents();
6620   int nbOfTuple=getNumberOfTuples();
6621   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
6622     *ptr=a*(*ptr)+b;
6623   declareAsNew();
6624 }
6625
6626 /*!
6627  * Apply a liner function to all elements of \a this array, so that
6628  * an element _x_ becomes \f$ a * x + b \f$.
6629  *  \param [in] a - the first coefficient of the function.
6630  *  \param [in] b - the second coefficient of the function.
6631  *  \throw If \a this is not allocated.
6632  */
6633 void DataArrayInt::applyLin(int a, int b)
6634 {
6635   checkAllocated();
6636   int *ptr=getPointer();
6637   std::size_t nbOfElems=getNbOfElems();
6638   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6639     *ptr=a*(*ptr)+b;
6640   declareAsNew();
6641 }
6642
6643 /*!
6644  * Returns a full copy of \a this array except that sign of all elements is reversed.
6645  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
6646  *          same number of tuples and component as \a this array.
6647  *          The caller is to delete this result array using decrRef() as it is no more
6648  *          needed.
6649  *  \throw If \a this is not allocated.
6650  */
6651 DataArrayInt *DataArrayInt::negate() const
6652 {
6653   checkAllocated();
6654   DataArrayInt *newArr=DataArrayInt::New();
6655   int nbOfTuples=getNumberOfTuples();
6656   int nbOfComp=getNumberOfComponents();
6657   newArr->alloc(nbOfTuples,nbOfComp);
6658   const int *cptr=getConstPointer();
6659   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
6660   newArr->copyStringInfoFrom(*this);
6661   return newArr;
6662 }
6663
6664 /*!
6665  * Modify all elements of \a this array, so that
6666  * an element _x_ becomes \f$ numerator / x \f$.
6667  *  \warning If an exception is thrown because of presence of 0 element in \a this 
6668  *           array, all elements processed before detection of the zero element remain
6669  *           modified.
6670  *  \param [in] numerator - the numerator used to modify array elements.
6671  *  \throw If \a this is not allocated.
6672  *  \throw If there is an element equal to 0 in \a this array.
6673  */
6674 void DataArrayInt::applyInv(int numerator)
6675 {
6676   checkAllocated();
6677   int *ptr=getPointer();
6678   std::size_t nbOfElems=getNbOfElems();
6679   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6680     {
6681       if(*ptr!=0)
6682         {
6683           *ptr=numerator/(*ptr);
6684         }
6685       else
6686         {
6687           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6688           oss << " !";
6689           throw INTERP_KERNEL::Exception(oss.str().c_str());
6690         }
6691     }
6692   declareAsNew();
6693 }
6694
6695 /*!
6696  * Modify all elements of \a this array, so that
6697  * an element _x_ becomes \f$ x / val \f$.
6698  *  \param [in] val - the denominator used to modify array elements.
6699  *  \throw If \a this is not allocated.
6700  *  \throw If \a val == 0.
6701  */
6702 void DataArrayInt::applyDivideBy(int val)
6703 {
6704   if(val==0)
6705     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
6706   checkAllocated();
6707   int *ptr=getPointer();
6708   std::size_t nbOfElems=getNbOfElems();
6709   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
6710   declareAsNew();
6711 }
6712
6713 /*!
6714  * Modify all elements of \a this array, so that
6715  * an element _x_ becomes  <em> x % val </em>.
6716  *  \param [in] val - the divisor used to modify array elements.
6717  *  \throw If \a this is not allocated.
6718  *  \throw If \a val <= 0.
6719  */
6720 void DataArrayInt::applyModulus(int val)
6721 {
6722   if(val<=0)
6723     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
6724   checkAllocated();
6725   int *ptr=getPointer();
6726   std::size_t nbOfElems=getNbOfElems();
6727   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
6728   declareAsNew();
6729 }
6730
6731 /*!
6732  * This method works only on data array with one component.
6733  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6734  * this[*id] in [\b vmin,\b vmax)
6735  * 
6736  * \param [in] vmin begin of range. This value is included in range (included).
6737  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6738  * \return a newly allocated data array that the caller should deal with.
6739  *
6740  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
6741  */
6742 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
6743 {
6744   checkAllocated();
6745   if(getNumberOfComponents()!=1)
6746     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsInRange : this must have exactly one component !");
6747   const int *cptr(begin());
6748   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6749   int nbOfTuples(getNumberOfTuples());
6750   for(int i=0;i<nbOfTuples;i++,cptr++)
6751     if(*cptr>=vmin && *cptr<vmax)
6752       ret->pushBackSilent(i);
6753   return ret.retn();
6754 }
6755
6756 /*!
6757  * This method works only on data array with one component.
6758  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6759  * this[*id] \b not in [\b vmin,\b vmax)
6760  * 
6761  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
6762  * \param [in] vmax end of range. This value is included in range (included).
6763  * \return a newly allocated data array that the caller should deal with.
6764  * 
6765  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
6766  */
6767 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
6768 {
6769   checkAllocated();
6770   if(getNumberOfComponents()!=1)
6771     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotInRange : this must have exactly one component !");
6772   const int *cptr(getConstPointer());
6773   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6774   int nbOfTuples(getNumberOfTuples());
6775   for(int i=0;i<nbOfTuples;i++,cptr++)
6776     if(*cptr<vmin || *cptr>=vmax)
6777       ret->pushBackSilent(i);
6778   return ret.retn();
6779 }
6780
6781 /*!
6782  * This method works only on data array with one component. This method returns a newly allocated array storing stored ascendantly of tuple ids in \a this so that this[id]<0.
6783  *
6784  * \return a newly allocated data array that the caller should deal with.
6785  * \sa DataArrayInt::findIdsInRange
6786  */
6787 DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
6788 {
6789   checkAllocated();
6790   if(getNumberOfComponents()!=1)
6791     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsStricltyNegative : this must have exactly one component !");
6792   const int *cptr(getConstPointer());
6793   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6794   int nbOfTuples(getNumberOfTuples());
6795   for(int i=0;i<nbOfTuples;i++,cptr++)
6796     if(*cptr<0)
6797       ret->pushBackSilent(i);
6798   return ret.retn();
6799 }
6800
6801 /*!
6802  * This method works only on data array with one component.
6803  * 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.
6804  * 
6805  * \param [in] vmin begin of range. This value is included in range (included).
6806  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6807  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
6808 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
6809 {
6810   checkAllocated();
6811   if(getNumberOfComponents()!=1)
6812     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
6813   int nbOfTuples=getNumberOfTuples();
6814   bool ret=true;
6815   const int *cptr=getConstPointer();
6816   for(int i=0;i<nbOfTuples;i++,cptr++)
6817     {
6818       if(*cptr>=vmin && *cptr<vmax)
6819         { ret=ret && *cptr==i; }
6820       else
6821         {
6822           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
6823           throw INTERP_KERNEL::Exception(oss.str().c_str());
6824         }
6825     }
6826   return ret;
6827 }
6828
6829 /*!
6830  * Modify all elements of \a this array, so that
6831  * an element _x_ becomes <em> val % x </em>.
6832  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
6833  *           array, all elements processed before detection of the zero element remain
6834  *           modified.
6835  *  \param [in] val - the divident used to modify array elements.
6836  *  \throw If \a this is not allocated.
6837  *  \throw If there is an element equal to or less than 0 in \a this array.
6838  */
6839 void DataArrayInt::applyRModulus(int val)
6840 {
6841   checkAllocated();
6842   int *ptr=getPointer();
6843   std::size_t nbOfElems=getNbOfElems();
6844   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6845     {
6846       if(*ptr>0)
6847         {
6848           *ptr=val%(*ptr);
6849         }
6850       else
6851         {
6852           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6853           oss << " !";
6854           throw INTERP_KERNEL::Exception(oss.str().c_str());
6855         }
6856     }
6857   declareAsNew();
6858 }
6859
6860 /*!
6861  * Modify all elements of \a this array, so that
6862  * an element _x_ becomes <em> val ^ x </em>.
6863  *  \param [in] val - the value used to apply pow on all array elements.
6864  *  \throw If \a this is not allocated.
6865  *  \throw If \a val < 0.
6866  */
6867 void DataArrayInt::applyPow(int val)
6868 {
6869   checkAllocated();
6870   if(val<0)
6871     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
6872   int *ptr=getPointer();
6873   std::size_t nbOfElems=getNbOfElems();
6874   if(val==0)
6875     {
6876       std::fill(ptr,ptr+nbOfElems,1);
6877       return ;
6878     }
6879   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6880     {
6881       int tmp=1;
6882       for(int j=0;j<val;j++)
6883         tmp*=*ptr;
6884       *ptr=tmp;
6885     }
6886   declareAsNew();
6887 }
6888
6889 /*!
6890  * Modify all elements of \a this array, so that
6891  * an element _x_ becomes \f$ val ^ x \f$.
6892  *  \param [in] val - the value used to apply pow on all array elements.
6893  *  \throw If \a this is not allocated.
6894  *  \throw If there is an element < 0 in \a this array.
6895  *  \warning If an exception is thrown because of presence of 0 element in \a this 
6896  *           array, all elements processed before detection of the zero element remain
6897  *           modified.
6898  */
6899 void DataArrayInt::applyRPow(int val)
6900 {
6901   checkAllocated();
6902   int *ptr=getPointer();
6903   std::size_t nbOfElems=getNbOfElems();
6904   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6905     {
6906       if(*ptr>=0)
6907         {
6908           int tmp=1;
6909           for(int j=0;j<*ptr;j++)
6910             tmp*=val;
6911           *ptr=tmp;
6912         }
6913       else
6914         {
6915           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6916           oss << " !";
6917           throw INTERP_KERNEL::Exception(oss.str().c_str());
6918         }
6919     }
6920   declareAsNew();
6921 }
6922
6923 /*!
6924  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
6925  * of components in the result array is a sum of the number of components of given arrays
6926  * and (2) the number of tuples in the result array is same as that of each of given
6927  * arrays. In other words the i-th tuple of result array includes all components of
6928  * i-th tuples of all given arrays.
6929  * Number of tuples in the given arrays must be the same.
6930  *  \param [in] a1 - an array to include in the result array.
6931  *  \param [in] a2 - another array to include in the result array.
6932  *  \return DataArrayInt * - the new instance of DataArrayInt.
6933  *          The caller is to delete this result array using decrRef() as it is no more
6934  *          needed.
6935  *  \throw If both \a a1 and \a a2 are NULL.
6936  *  \throw If any given array is not allocated.
6937  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6938  */
6939 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
6940 {
6941   std::vector<const DataArrayInt *> arr(2);
6942   arr[0]=a1; arr[1]=a2;
6943   return Meld(arr);
6944 }
6945
6946 /*!
6947  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
6948  * of components in the result array is a sum of the number of components of given arrays
6949  * and (2) the number of tuples in the result array is same as that of each of given
6950  * arrays. In other words the i-th tuple of result array includes all components of
6951  * i-th tuples of all given arrays.
6952  * Number of tuples in the given arrays must be  the same.
6953  *  \param [in] arr - a sequence of arrays to include in the result array.
6954  *  \return DataArrayInt * - the new instance of DataArrayInt.
6955  *          The caller is to delete this result array using decrRef() as it is no more
6956  *          needed.
6957  *  \throw If all arrays within \a arr are NULL.
6958  *  \throw If any given array is not allocated.
6959  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
6960  */
6961 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
6962 {
6963   std::vector<const DataArrayInt *> a;
6964   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6965     if(*it4)
6966       a.push_back(*it4);
6967   if(a.empty())
6968     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
6969   std::vector<const DataArrayInt *>::const_iterator it;
6970   for(it=a.begin();it!=a.end();it++)
6971     (*it)->checkAllocated();
6972   it=a.begin();
6973   int nbOfTuples=(*it)->getNumberOfTuples();
6974   std::vector<int> nbc(a.size());
6975   std::vector<const int *> pts(a.size());
6976   nbc[0]=(*it)->getNumberOfComponents();
6977   pts[0]=(*it++)->getConstPointer();
6978   for(int i=1;it!=a.end();it++,i++)
6979     {
6980       if(nbOfTuples!=(*it)->getNumberOfTuples())
6981         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
6982       nbc[i]=(*it)->getNumberOfComponents();
6983       pts[i]=(*it)->getConstPointer();
6984     }
6985   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
6986   DataArrayInt *ret=DataArrayInt::New();
6987   ret->alloc(nbOfTuples,totalNbOfComp);
6988   int *retPtr=ret->getPointer();
6989   for(int i=0;i<nbOfTuples;i++)
6990     for(int j=0;j<(int)a.size();j++)
6991       {
6992         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
6993         pts[j]+=nbc[j];
6994       }
6995   int k=0;
6996   for(int i=0;i<(int)a.size();i++)
6997     for(int j=0;j<nbc[i];j++,k++)
6998       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
6999   return ret;
7000 }
7001
7002 /*!
7003  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
7004  * The i-th item of the result array is an ID of a set of elements belonging to a
7005  * unique set of groups, which the i-th element is a part of. This set of elements
7006  * belonging to a unique set of groups is called \a family, so the result array contains
7007  * IDs of families each element belongs to.
7008  *
7009  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
7010  * then there are 3 families:
7011  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
7012  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
7013  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
7014  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
7015  * stands for the element #3 which is in none of groups.
7016  *
7017  *  \param [in] groups - sequence of groups of element IDs.
7018  *  \param [in] newNb - total number of elements; it must be more than max ID of element
7019  *         in \a groups.
7020  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
7021  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
7022  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
7023  *         delete this array using decrRef() as it is no more needed.
7024  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
7025  */
7026 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
7027 {
7028   std::vector<const DataArrayInt *> groups2;
7029   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
7030     if(*it4)
7031       groups2.push_back(*it4);
7032   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7033   ret->alloc(newNb,1);
7034   int *retPtr=ret->getPointer();
7035   std::fill(retPtr,retPtr+newNb,0);
7036   int fid=1;
7037   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
7038     {
7039       const int *ptr=(*iter)->getConstPointer();
7040       std::size_t nbOfElem=(*iter)->getNbOfElems();
7041       int sfid=fid;
7042       for(int j=0;j<sfid;j++)
7043         {
7044           bool found=false;
7045           for(std::size_t i=0;i<nbOfElem;i++)
7046             {
7047               if(ptr[i]>=0 && ptr[i]<newNb)
7048                 {
7049                   if(retPtr[ptr[i]]==j)
7050                     {
7051                       retPtr[ptr[i]]=fid;
7052                       found=true;
7053                     }
7054                 }
7055               else
7056                 {
7057                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
7058                   oss << ") !";
7059                   throw INTERP_KERNEL::Exception(oss.str().c_str());
7060                 }
7061             }
7062           if(found)
7063             fid++;
7064         }
7065     }
7066   fidsOfGroups.clear();
7067   fidsOfGroups.resize(groups2.size());
7068   int grId=0;
7069   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
7070     {
7071       std::set<int> tmp;
7072       const int *ptr=(*iter)->getConstPointer();
7073       std::size_t nbOfElem=(*iter)->getNbOfElems();
7074       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
7075         tmp.insert(retPtr[*p]);
7076       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
7077     }
7078   return ret.retn();
7079 }
7080
7081 /*!
7082  * Returns a new DataArrayInt which contains all elements of given one-dimensional
7083  * arrays. The result array does not contain any duplicates and its values
7084  * are sorted in ascending order.
7085  *  \param [in] arr - sequence of DataArrayInt's to unite.
7086  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7087  *         array using decrRef() as it is no more needed.
7088  *  \throw If any \a arr[i] is not allocated.
7089  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7090  */
7091 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
7092 {
7093   std::vector<const DataArrayInt *> a;
7094   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7095     if(*it4)
7096       a.push_back(*it4);
7097   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7098     {
7099       (*it)->checkAllocated();
7100       if((*it)->getNumberOfComponents()!=1)
7101         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
7102     }
7103   //
7104   std::set<int> r;
7105   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7106     {
7107       const int *pt=(*it)->getConstPointer();
7108       int nbOfTuples=(*it)->getNumberOfTuples();
7109       r.insert(pt,pt+nbOfTuples);
7110     }
7111   DataArrayInt *ret=DataArrayInt::New();
7112   ret->alloc((int)r.size(),1);
7113   std::copy(r.begin(),r.end(),ret->getPointer());
7114   return ret;
7115 }
7116
7117 /*!
7118  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
7119  * arrays. The result array does not contain any duplicates and its values
7120  * are sorted in ascending order.
7121  *  \param [in] arr - sequence of DataArrayInt's to intersect.
7122  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7123  *         array using decrRef() as it is no more needed.
7124  *  \throw If any \a arr[i] is not allocated.
7125  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7126  */
7127 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
7128 {
7129   std::vector<const DataArrayInt *> a;
7130   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7131     if(*it4)
7132       a.push_back(*it4);
7133   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7134     {
7135       (*it)->checkAllocated();
7136       if((*it)->getNumberOfComponents()!=1)
7137         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
7138     }
7139   //
7140   std::set<int> r;
7141   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7142     {
7143       const int *pt=(*it)->getConstPointer();
7144       int nbOfTuples=(*it)->getNumberOfTuples();
7145       std::set<int> s1(pt,pt+nbOfTuples);
7146       if(it!=a.begin())
7147         {
7148           std::set<int> r2;
7149           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
7150           r=r2;
7151         }
7152       else
7153         r=s1;
7154     }
7155   DataArrayInt *ret(DataArrayInt::New());
7156   ret->alloc((int)r.size(),1);
7157   std::copy(r.begin(),r.end(),ret->getPointer());
7158   return ret;
7159 }
7160
7161 /// @cond INTERNAL
7162 namespace MEDCouplingImpl
7163 {
7164   class OpSwitchedOn
7165   {
7166   public:
7167     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
7168     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
7169   private:
7170     int *_pt;
7171     int _cnt;
7172   };
7173
7174   class OpSwitchedOff
7175   {
7176   public:
7177     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
7178     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
7179   private:
7180     int *_pt;
7181     int _cnt;
7182   };
7183 }
7184 /// @endcond
7185
7186 /*!
7187  * This method returns the list of ids in ascending mode so that v[id]==true.
7188  */
7189 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
7190 {
7191   int sz((int)std::count(v.begin(),v.end(),true));
7192   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7193   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
7194   return ret.retn();
7195 }
7196
7197 /*!
7198  * This method returns the list of ids in ascending mode so that v[id]==false.
7199  */
7200 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
7201 {
7202   int sz((int)std::count(v.begin(),v.end(),false));
7203   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7204   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
7205   return ret.retn();
7206 }
7207
7208 /*!
7209  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
7210  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
7211  *
7212  * \param [in] v the input data structure to be translate into skyline format.
7213  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
7214  * \param [out] dataIndex the second element of the skyline format.
7215  */
7216 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
7217 {
7218   int sz((int)v.size());
7219   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
7220   ret1->alloc(sz+1,1);
7221   int *pt(ret1->getPointer()); *pt=0;
7222   for(int i=0;i<sz;i++,pt++)
7223     pt[1]=pt[0]+(int)v[i].size();
7224   ret0->alloc(ret1->back(),1);
7225   pt=ret0->getPointer();
7226   for(int i=0;i<sz;i++)
7227     pt=std::copy(v[i].begin(),v[i].end(),pt);
7228   data=ret0.retn(); dataIndex=ret1.retn();
7229 }
7230
7231 /*!
7232  * Returns a new DataArrayInt which contains a complement of elements of \a this
7233  * one-dimensional array. I.e. the result array contains all elements from the range [0,
7234  * \a nbOfElement) not present in \a this array.
7235  *  \param [in] nbOfElement - maximal size of the result array.
7236  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7237  *         array using decrRef() as it is no more needed.
7238  *  \throw If \a this is not allocated.
7239  *  \throw If \a this->getNumberOfComponents() != 1.
7240  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
7241  *         nbOfElement ).
7242  */
7243 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
7244 {
7245   checkAllocated();
7246   if(getNumberOfComponents()!=1)
7247     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
7248   std::vector<bool> tmp(nbOfElement);
7249   const int *pt=getConstPointer();
7250   int nbOfTuples=getNumberOfTuples();
7251   for(const int *w=pt;w!=pt+nbOfTuples;w++)
7252     if(*w>=0 && *w<nbOfElement)
7253       tmp[*w]=true;
7254     else
7255       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
7256   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
7257   DataArrayInt *ret=DataArrayInt::New();
7258   ret->alloc(nbOfRetVal,1);
7259   int j=0;
7260   int *retPtr=ret->getPointer();
7261   for(int i=0;i<nbOfElement;i++)
7262     if(!tmp[i])
7263       retPtr[j++]=i;
7264   return ret;
7265 }
7266
7267 /*!
7268  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
7269  * from an \a other one-dimensional array.
7270  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
7271  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
7272  *         caller is to delete this array using decrRef() as it is no more needed.
7273  *  \throw If \a other is NULL.
7274  *  \throw If \a other is not allocated.
7275  *  \throw If \a other->getNumberOfComponents() != 1.
7276  *  \throw If \a this is not allocated.
7277  *  \throw If \a this->getNumberOfComponents() != 1.
7278  *  \sa DataArrayInt::buildSubstractionOptimized()
7279  */
7280 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
7281 {
7282   if(!other)
7283     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
7284   checkAllocated();
7285   other->checkAllocated();
7286   if(getNumberOfComponents()!=1)
7287     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
7288   if(other->getNumberOfComponents()!=1)
7289     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
7290   const int *pt=getConstPointer();
7291   int nbOfTuples=getNumberOfTuples();
7292   std::set<int> s1(pt,pt+nbOfTuples);
7293   pt=other->getConstPointer();
7294   nbOfTuples=other->getNumberOfTuples();
7295   std::set<int> s2(pt,pt+nbOfTuples);
7296   std::vector<int> r;
7297   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
7298   DataArrayInt *ret=DataArrayInt::New();
7299   ret->alloc((int)r.size(),1);
7300   std::copy(r.begin(),r.end(),ret->getPointer());
7301   return ret;
7302 }
7303
7304 /*!
7305  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
7306  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
7307  * 
7308  * \param [in] other an array with one component and expected to be sorted ascendingly.
7309  * \ret list of ids in \a this but not in \a other.
7310  * \sa DataArrayInt::buildSubstraction
7311  */
7312 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
7313 {
7314   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
7315   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
7316   checkAllocated(); other->checkAllocated();
7317   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7318   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7319   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
7320   const int *work1(pt1Bg),*work2(pt2Bg);
7321   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7322   for(;work1!=pt1End;work1++)
7323     {
7324       if(work2!=pt2End && *work1==*work2)
7325         work2++;
7326       else
7327         ret->pushBackSilent(*work1);
7328     }
7329   return ret.retn();
7330 }
7331
7332
7333 /*!
7334  * Returns a new DataArrayInt which contains all elements of \a this and a given
7335  * one-dimensional arrays. The result array does not contain any duplicates
7336  * and its values are sorted in ascending order.
7337  *  \param [in] other - an array to unite with \a this one.
7338  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7339  *         array using decrRef() as it is no more needed.
7340  *  \throw If \a this or \a other is not allocated.
7341  *  \throw If \a this->getNumberOfComponents() != 1.
7342  *  \throw If \a other->getNumberOfComponents() != 1.
7343  */
7344 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
7345 {
7346   std::vector<const DataArrayInt *>arrs(2);
7347   arrs[0]=this; arrs[1]=other;
7348   return BuildUnion(arrs);
7349 }
7350
7351
7352 /*!
7353  * Returns a new DataArrayInt which contains elements present in both \a this and a given
7354  * one-dimensional arrays. The result array does not contain any duplicates
7355  * and its values are sorted in ascending order.
7356  *  \param [in] other - an array to intersect with \a this one.
7357  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7358  *         array using decrRef() as it is no more needed.
7359  *  \throw If \a this or \a other is not allocated.
7360  *  \throw If \a this->getNumberOfComponents() != 1.
7361  *  \throw If \a other->getNumberOfComponents() != 1.
7362  */
7363 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
7364 {
7365   std::vector<const DataArrayInt *>arrs(2);
7366   arrs[0]=this; arrs[1]=other;
7367   return BuildIntersection(arrs);
7368 }
7369
7370 /*!
7371  * This method can be applied on allocated with one component DataArrayInt instance.
7372  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
7373  * 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]
7374  * 
7375  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7376  * \throw if \a this is not allocated or if \a this has not exactly one component.
7377  * \sa DataArrayInt::buildUniqueNotSorted
7378  */
7379 DataArrayInt *DataArrayInt::buildUnique() const
7380 {
7381   checkAllocated();
7382   if(getNumberOfComponents()!=1)
7383     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
7384   int nbOfTuples=getNumberOfTuples();
7385   MCAuto<DataArrayInt> tmp=deepCopy();
7386   int *data=tmp->getPointer();
7387   int *last=std::unique(data,data+nbOfTuples);
7388   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7389   ret->alloc(std::distance(data,last),1);
7390   std::copy(data,last,ret->getPointer());
7391   return ret.retn();
7392 }
7393
7394 /*!
7395  * This method can be applied on allocated with one component DataArrayInt instance.
7396  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
7397  *
7398  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7399  *
7400  * \throw if \a this is not allocated or if \a this has not exactly one component.
7401  *
7402  * \sa DataArrayInt::buildUnique
7403  */
7404 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
7405 {
7406   checkAllocated();
7407     if(getNumberOfComponents()!=1)
7408       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
7409   int minVal,maxVal;
7410   getMinMaxValues(minVal,maxVal);
7411   std::vector<bool> b(maxVal-minVal+1,false);
7412   const int *ptBg(begin()),*endBg(end());
7413   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7414   for(const int *pt=ptBg;pt!=endBg;pt++)
7415     {
7416       if(!b[*pt-minVal])
7417         {
7418           ret->pushBackSilent(*pt);
7419           b[*pt-minVal]=true;
7420         }
7421     }
7422   ret->copyStringInfoFrom(*this);
7423   return ret.retn();
7424 }
7425
7426 /*!
7427  * Returns a new DataArrayInt which contains size of every of groups described by \a this
7428  * "index" array. Such "index" array is returned for example by 
7429  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
7430  * "MEDCouplingUMesh::buildDescendingConnectivity" and
7431  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
7432  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
7433  * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
7434  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
7435  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
7436  *          The caller is to delete this array using decrRef() as it is no more needed. 
7437  *  \throw If \a this is not allocated.
7438  *  \throw If \a this->getNumberOfComponents() != 1.
7439  *  \throw If \a this->getNumberOfTuples() < 2.
7440  *
7441  *  \b Example: <br> 
7442  *         - this contains [1,3,6,7,7,9,15]
7443  *         - result array contains [2,3,1,0,2,6],
7444  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
7445  *
7446  * \sa DataArrayInt::computeOffsetsFull
7447  */
7448 DataArrayInt *DataArrayInt::deltaShiftIndex() const
7449 {
7450   checkAllocated();
7451   if(getNumberOfComponents()!=1)
7452     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
7453   int nbOfTuples=getNumberOfTuples();
7454   if(nbOfTuples<2)
7455     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
7456   const int *ptr=getConstPointer();
7457   DataArrayInt *ret=DataArrayInt::New();
7458   ret->alloc(nbOfTuples-1,1);
7459   int *out=ret->getPointer();
7460   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
7461   return ret;
7462 }
7463
7464 /*!
7465  * Modifies \a this one-dimensional array so that value of each element \a x
7466  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7467  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
7468  * and components remains the same.<br>
7469  * This method is useful for allToAllV in MPI with contiguous policy. This method
7470  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
7471  * this one.
7472  *  \throw If \a this is not allocated.
7473  *  \throw If \a this->getNumberOfComponents() != 1.
7474  *
7475  *  \b Example: <br>
7476  *          - Before \a this contains [3,5,1,2,0,8]
7477  *          - After \a this contains  [0,3,8,9,11,11]<br>
7478  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
7479  *          array is retained and thus there is no space to store the last element.
7480  */
7481 void DataArrayInt::computeOffsets()
7482 {
7483   checkAllocated();
7484   if(getNumberOfComponents()!=1)
7485     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
7486   int nbOfTuples=getNumberOfTuples();
7487   if(nbOfTuples==0)
7488     return ;
7489   int *work=getPointer();
7490   int tmp=work[0];
7491   work[0]=0;
7492   for(int i=1;i<nbOfTuples;i++)
7493     {
7494       int tmp2=work[i];
7495       work[i]=work[i-1]+tmp;
7496       tmp=tmp2;
7497     }
7498   declareAsNew();
7499 }
7500
7501
7502 /*!
7503  * Modifies \a this one-dimensional array so that value of each element \a x
7504  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7505  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
7506  * components remains the same and number of tuples is inceamented by one.<br>
7507  * This method is useful for allToAllV in MPI with contiguous policy. This method
7508  * differs from computeOffsets() in that the number of tuples is changed by this one.
7509  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
7510  *  \throw If \a this is not allocated.
7511  *  \throw If \a this->getNumberOfComponents() != 1.
7512  *
7513  *  \b Example: <br>
7514  *          - Before \a this contains [3,5,1,2,0,8]
7515  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
7516  * \sa DataArrayInt::deltaShiftIndex
7517  */
7518 void DataArrayInt::computeOffsetsFull()
7519 {
7520   checkAllocated();
7521   if(getNumberOfComponents()!=1)
7522     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
7523   int nbOfTuples=getNumberOfTuples();
7524   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
7525   const int *work=getConstPointer();
7526   ret[0]=0;
7527   for(int i=0;i<nbOfTuples;i++)
7528     ret[i+1]=work[i]+ret[i];
7529   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
7530   declareAsNew();
7531 }
7532
7533 /*!
7534  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
7535  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
7536  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
7537  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
7538  * filling completely one of the ranges in \a this.
7539  *
7540  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
7541  * \param [out] rangeIdsFetched the range ids fetched
7542  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
7543  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
7544  *
7545  * \sa DataArrayInt::computeOffsetsFull
7546  *
7547  *  \b Example: <br>
7548  *          - \a this : [0,3,7,9,15,18]
7549  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
7550  *          - \a rangeIdsFetched result array: [0,2,4]
7551  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
7552  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
7553  * <br>
7554  */
7555 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
7556 {
7557   if(!listOfIds)
7558     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
7559   listOfIds->checkAllocated(); checkAllocated();
7560   if(listOfIds->getNumberOfComponents()!=1)
7561     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
7562   if(getNumberOfComponents()!=1)
7563     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
7564   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
7565   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
7566   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
7567   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
7568   while(tupPtr!=tupEnd && offPtr!=offEnd)
7569     {
7570       if(*tupPtr==*offPtr)
7571         {
7572           int i=offPtr[0];
7573           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
7574           if(i==offPtr[1])
7575             {
7576               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
7577               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
7578               offPtr++;
7579             }
7580         }
7581       else
7582         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
7583     }
7584   rangeIdsFetched=ret0.retn();
7585   idsInInputListThatFetch=ret1.retn();
7586 }
7587
7588 /*!
7589  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
7590  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7591  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7592  * beginning within the "iota" array. And \a this is a one-dimensional array
7593  * considered as a selector of groups described by \a offsets to include into the result array.
7594  *  \throw If \a offsets is NULL.
7595  *  \throw If \a offsets is not allocated.
7596  *  \throw If \a offsets->getNumberOfComponents() != 1.
7597  *  \throw If \a offsets is not monotonically increasing.
7598  *  \throw If \a this is not allocated.
7599  *  \throw If \a this->getNumberOfComponents() != 1.
7600  *  \throw If any element of \a this is not a valid index for \a offsets array.
7601  *
7602  *  \b Example: <br>
7603  *          - \a this: [0,2,3]
7604  *          - \a offsets: [0,3,6,10,14,20]
7605  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
7606  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
7607  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
7608  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
7609  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
7610  */
7611 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
7612 {
7613   if(!offsets)
7614     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
7615   checkAllocated();
7616   if(getNumberOfComponents()!=1)
7617     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
7618   offsets->checkAllocated();
7619   if(offsets->getNumberOfComponents()!=1)
7620     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
7621   int othNbTuples=offsets->getNumberOfTuples()-1;
7622   int nbOfTuples=getNumberOfTuples();
7623   int retNbOftuples=0;
7624   const int *work=getConstPointer();
7625   const int *offPtr=offsets->getConstPointer();
7626   for(int i=0;i<nbOfTuples;i++)
7627     {
7628       int val=work[i];
7629       if(val>=0 && val<othNbTuples)
7630         {
7631           int delta=offPtr[val+1]-offPtr[val];
7632           if(delta>=0)
7633             retNbOftuples+=delta;
7634           else
7635             {
7636               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
7637               throw INTERP_KERNEL::Exception(oss.str().c_str());
7638             }
7639         }
7640       else
7641         {
7642           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
7643           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
7644           throw INTERP_KERNEL::Exception(oss.str().c_str());
7645         }
7646     }
7647   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7648   ret->alloc(retNbOftuples,1);
7649   int *retPtr=ret->getPointer();
7650   for(int i=0;i<nbOfTuples;i++)
7651     {
7652       int val=work[i];
7653       int start=offPtr[val];
7654       int off=offPtr[val+1]-start;
7655       for(int j=0;j<off;j++,retPtr++)
7656         *retPtr=start+j;
7657     }
7658   return ret.retn();
7659 }
7660
7661 /*!
7662  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
7663  * scaled array (monotonically increasing).
7664 from that of \a this and \a
7665  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7666  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7667  * beginning within the "iota" array. And \a this is a one-dimensional array
7668  * considered as a selector of groups described by \a offsets to include into the result array.
7669  *  \throw If \a  is NULL.
7670  *  \throw If \a this is not allocated.
7671  *  \throw If \a this->getNumberOfComponents() != 1.
7672  *  \throw If \a this->getNumberOfTuples() == 0.
7673  *  \throw If \a this is not monotonically increasing.
7674  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
7675  *
7676  *  \b Example: <br>
7677  *          - \a bg , \a stop and \a step : (0,5,2)
7678  *          - \a this: [0,3,6,10,14,20]
7679  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
7680  */
7681 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
7682 {
7683   if(!isAllocated())
7684     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
7685   if(getNumberOfComponents()!=1)
7686     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
7687   int nbOfTuples(getNumberOfTuples());
7688   if(nbOfTuples==0)
7689     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
7690   const int *ids(begin());
7691   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
7692   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7693     {
7694       if(pos>=0 && pos<nbOfTuples-1)
7695         {
7696           int delta(ids[pos+1]-ids[pos]);
7697           sz+=delta;
7698           if(delta<0)
7699             {
7700               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
7701               throw INTERP_KERNEL::Exception(oss.str().c_str());
7702             }          
7703         }
7704       else
7705         {
7706           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
7707           throw INTERP_KERNEL::Exception(oss.str().c_str());
7708         }
7709     }
7710   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7711   int *retPtr(ret->getPointer());
7712   pos=bg;
7713   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7714     {
7715       int delta(ids[pos+1]-ids[pos]);
7716       for(int j=0;j<delta;j++,retPtr++)
7717         *retPtr=pos;
7718     }
7719   return ret.retn();
7720 }
7721
7722 /*!
7723  * 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.
7724  * 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
7725  * in tuple **i** of returned DataArrayInt.
7726  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
7727  *
7728  * 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)]
7729  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
7730  * 
7731  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7732  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7733  * \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
7734  *        is thrown if no ranges in \a ranges contains value in \a this.
7735  * 
7736  * \sa DataArrayInt::findIdInRangeForEachTuple
7737  */
7738 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
7739 {
7740   if(!ranges)
7741     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
7742   if(ranges->getNumberOfComponents()!=2)
7743     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
7744   checkAllocated();
7745   if(getNumberOfComponents()!=1)
7746     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
7747   int nbTuples=getNumberOfTuples();
7748   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7749   int nbOfRanges=ranges->getNumberOfTuples();
7750   const int *rangesPtr=ranges->getConstPointer();
7751   int *retPtr=ret->getPointer();
7752   const int *inPtr=getConstPointer();
7753   for(int i=0;i<nbTuples;i++,retPtr++)
7754     {
7755       int val=inPtr[i];
7756       bool found=false;
7757       for(int j=0;j<nbOfRanges && !found;j++)
7758         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7759           { *retPtr=j; found=true; }
7760       if(found)
7761         continue;
7762       else
7763         {
7764           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
7765           throw INTERP_KERNEL::Exception(oss.str().c_str());
7766         }
7767     }
7768   return ret.retn();
7769 }
7770
7771 /*!
7772  * 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.
7773  * 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
7774  * in tuple **i** of returned DataArrayInt.
7775  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
7776  *
7777  * 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)]
7778  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
7779  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
7780  * 
7781  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7782  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7783  * \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
7784  *        is thrown if no ranges in \a ranges contains value in \a this.
7785  * \sa DataArrayInt::findRangeIdForEachTuple
7786  */
7787 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
7788 {
7789   if(!ranges)
7790     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
7791   if(ranges->getNumberOfComponents()!=2)
7792     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
7793   checkAllocated();
7794   if(getNumberOfComponents()!=1)
7795     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
7796   int nbTuples=getNumberOfTuples();
7797   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7798   int nbOfRanges=ranges->getNumberOfTuples();
7799   const int *rangesPtr=ranges->getConstPointer();
7800   int *retPtr=ret->getPointer();
7801   const int *inPtr=getConstPointer();
7802   for(int i=0;i<nbTuples;i++,retPtr++)
7803     {
7804       int val=inPtr[i];
7805       bool found=false;
7806       for(int j=0;j<nbOfRanges && !found;j++)
7807         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7808           { *retPtr=val-rangesPtr[2*j]; found=true; }
7809       if(found)
7810         continue;
7811       else
7812         {
7813           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
7814           throw INTERP_KERNEL::Exception(oss.str().c_str());
7815         }
7816     }
7817   return ret.retn();
7818 }
7819
7820 /*!
7821  * \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).
7822  * 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).
7823  * 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 !
7824  * If this method has correctly worked, \a this will be able to be considered as a linked list.
7825  * This method does nothing if number of tuples is lower of equal to 1.
7826  *
7827  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
7828  *
7829  * \sa MEDCouplingUMesh::orderConsecutiveCells1D
7830  */
7831 void DataArrayInt::sortEachPairToMakeALinkedList()
7832 {
7833   checkAllocated();
7834   if(getNumberOfComponents()!=2)
7835     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
7836   int nbOfTuples(getNumberOfTuples());
7837   if(nbOfTuples<=1)
7838     return ;
7839   int *conn(getPointer());
7840   for(int i=1;i<nbOfTuples;i++,conn+=2)
7841     {
7842       if(i>1)
7843         {
7844           if(conn[2]==conn[3])
7845             {
7846               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
7847               throw INTERP_KERNEL::Exception(oss.str().c_str());
7848             }
7849           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
7850             std::swap(conn[2],conn[3]);
7851           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
7852           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
7853             {
7854               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
7855               throw INTERP_KERNEL::Exception(oss.str().c_str());
7856             }
7857         }
7858       else
7859         {
7860           if(conn[0]==conn[1] || conn[2]==conn[3])
7861             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
7862           int tmp[4];
7863           std::set<int> s;
7864           s.insert(conn,conn+4);
7865           if(s.size()!=3)
7866             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
7867           if(std::count(conn,conn+4,conn[0])==2)
7868             {
7869               tmp[0]=conn[1];
7870               tmp[1]=conn[0];
7871               tmp[2]=conn[0];
7872               if(conn[2]==conn[0])
7873                 { tmp[3]=conn[3]; }
7874               else
7875                 { tmp[3]=conn[2];}
7876               std::copy(tmp,tmp+4,conn);
7877             }
7878           else
7879             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
7880               if(conn[1]==conn[3])
7881                 std::swap(conn[2],conn[3]);
7882             }
7883         }
7884     }
7885 }
7886
7887 /*!
7888  * 
7889  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
7890  *             \a nbTimes  should be at least equal to 1.
7891  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
7892  * \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.
7893  */
7894 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
7895 {
7896   checkAllocated();
7897   if(getNumberOfComponents()!=1)
7898     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
7899   if(nbTimes<1)
7900     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
7901   int nbTuples=getNumberOfTuples();
7902   const int *inPtr=getConstPointer();
7903   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
7904   int *retPtr=ret->getPointer();
7905   for(int i=0;i<nbTuples;i++,inPtr++)
7906     {
7907       int val=*inPtr;
7908       for(int j=0;j<nbTimes;j++,retPtr++)
7909         *retPtr=val;
7910     }
7911   ret->copyStringInfoFrom(*this);
7912   return ret.retn();
7913 }
7914
7915 /*!
7916  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
7917  * But the number of components can be different from one.
7918  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
7919  */
7920 DataArrayInt *DataArrayInt::getDifferentValues() const
7921 {
7922   checkAllocated();
7923   std::set<int> ret;
7924   ret.insert(begin(),end());
7925   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
7926   std::copy(ret.begin(),ret.end(),ret2->getPointer());
7927   return ret2.retn();
7928 }
7929
7930 /*!
7931  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
7932  * them it tells which tuple id have this id.
7933  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
7934  * This method returns two arrays having same size.
7935  * 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.
7936  * 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]]
7937  */
7938 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
7939 {
7940   checkAllocated();
7941   if(getNumberOfComponents()!=1)
7942     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
7943   int id=0;
7944   std::map<int,int> m,m2,m3;
7945   for(const int *w=begin();w!=end();w++)
7946     m[*w]++;
7947   differentIds.resize(m.size());
7948   std::vector<DataArrayInt *> ret(m.size());
7949   std::vector<int *> retPtr(m.size());
7950   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
7951     {
7952       m2[(*it).first]=id;
7953       ret[id]=DataArrayInt::New();
7954       ret[id]->alloc((*it).second,1);
7955       retPtr[id]=ret[id]->getPointer();
7956       differentIds[id]=(*it).first;
7957     }
7958   id=0;
7959   for(const int *w=begin();w!=end();w++,id++)
7960     {
7961       retPtr[m2[*w]][m3[*w]++]=id;
7962     }
7963   return ret;
7964 }
7965
7966 /*!
7967  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
7968  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
7969  *
7970  * \param [in] nbOfSlices - number of slices expected.
7971  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
7972  * 
7973  * \sa DataArray::GetSlice
7974  * \throw If \a this is not allocated or not with exactly one component.
7975  * \throw If an element in \a this if < 0.
7976  */
7977 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
7978 {
7979   if(!isAllocated() || getNumberOfComponents()!=1)
7980     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
7981   if(nbOfSlices<=0)
7982     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
7983   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
7984   int sumPerSlc(sum/nbOfSlices),pos(0);
7985   const int *w(begin());
7986   std::vector< std::pair<int,int> > ret(nbOfSlices);
7987   for(int i=0;i<nbOfSlices;i++)
7988     {
7989       std::pair<int,int> p(pos,-1);
7990       int locSum(0);
7991       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
7992       if(i!=nbOfSlices-1)
7993         p.second=pos;
7994       else
7995         p.second=nbOfTuples;
7996       ret[i]=p;
7997     }
7998   return ret;
7999 }
8000
8001 /*!
8002  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
8003  * valid cases.
8004  * 1.  The arrays have same number of tuples and components. Then each value of
8005  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
8006  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
8007  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8008  *   component. Then
8009  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
8010  * 3.  The arrays have same number of components and one array, say _a2_, has one
8011  *   tuple. Then
8012  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
8013  *
8014  * Info on components is copied either from the first array (in the first case) or from
8015  * the array with maximal number of elements (getNbOfElems()).
8016  *  \param [in] a1 - an array to sum up.
8017  *  \param [in] a2 - another array to sum up.
8018  *  \return DataArrayInt * - the new instance of DataArrayInt.
8019  *          The caller is to delete this result array using decrRef() as it is no more
8020  *          needed.
8021  *  \throw If either \a a1 or \a a2 is NULL.
8022  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8023  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8024  *         none of them has number of tuples or components equal to 1.
8025  */
8026 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
8027 {
8028   if(!a1 || !a2)
8029     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
8030   int nbOfTuple=a1->getNumberOfTuples();
8031   int nbOfTuple2=a2->getNumberOfTuples();
8032   int nbOfComp=a1->getNumberOfComponents();
8033   int nbOfComp2=a2->getNumberOfComponents();
8034   MCAuto<DataArrayInt> ret=0;
8035   if(nbOfTuple==nbOfTuple2)
8036     {
8037       if(nbOfComp==nbOfComp2)
8038         {
8039           ret=DataArrayInt::New();
8040           ret->alloc(nbOfTuple,nbOfComp);
8041           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
8042           ret->copyStringInfoFrom(*a1);
8043         }
8044       else
8045         {
8046           int nbOfCompMin,nbOfCompMax;
8047           const DataArrayInt *aMin, *aMax;
8048           if(nbOfComp>nbOfComp2)
8049             {
8050               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8051               aMin=a2; aMax=a1;
8052             }
8053           else
8054             {
8055               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8056               aMin=a1; aMax=a2;
8057             }
8058           if(nbOfCompMin==1)
8059             {
8060               ret=DataArrayInt::New();
8061               ret->alloc(nbOfTuple,nbOfCompMax);
8062               const int *aMinPtr=aMin->getConstPointer();
8063               const int *aMaxPtr=aMax->getConstPointer();
8064               int *res=ret->getPointer();
8065               for(int i=0;i<nbOfTuple;i++)
8066                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
8067               ret->copyStringInfoFrom(*aMax);
8068             }
8069           else
8070             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8071         }
8072     }
8073   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8074     {
8075       if(nbOfComp==nbOfComp2)
8076         {
8077           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8078           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8079           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8080           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8081           ret=DataArrayInt::New();
8082           ret->alloc(nbOfTupleMax,nbOfComp);
8083           int *res=ret->getPointer();
8084           for(int i=0;i<nbOfTupleMax;i++)
8085             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
8086           ret->copyStringInfoFrom(*aMax);
8087         }
8088       else
8089         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8090     }
8091   else
8092     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
8093   return ret.retn();
8094 }
8095
8096 /*!
8097  * Adds values of another DataArrayInt to values of \a this one. There are 3
8098  * valid cases.
8099  * 1.  The arrays have same number of tuples and components. Then each value of
8100  *   \a other array is added to the corresponding value of \a this array, i.e.:
8101  *   _a_ [ i, j ] += _other_ [ i, j ].
8102  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8103  *   _a_ [ i, j ] += _other_ [ i, 0 ].
8104  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8105  *   _a_ [ i, j ] += _a2_ [ 0, j ].
8106  *
8107  *  \param [in] other - an array to add to \a this one.
8108  *  \throw If \a other is NULL.
8109  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8110  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8111  *         \a other has number of both tuples and components not equal to 1.
8112  */
8113 void DataArrayInt::addEqual(const DataArrayInt *other)
8114 {
8115   if(!other)
8116     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
8117   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
8118   checkAllocated(); other->checkAllocated();
8119   int nbOfTuple=getNumberOfTuples();
8120   int nbOfTuple2=other->getNumberOfTuples();
8121   int nbOfComp=getNumberOfComponents();
8122   int nbOfComp2=other->getNumberOfComponents();
8123   if(nbOfTuple==nbOfTuple2)
8124     {
8125       if(nbOfComp==nbOfComp2)
8126         {
8127           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
8128         }
8129       else if(nbOfComp2==1)
8130         {
8131           int *ptr=getPointer();
8132           const int *ptrc=other->getConstPointer();
8133           for(int i=0;i<nbOfTuple;i++)
8134             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
8135         }
8136       else
8137         throw INTERP_KERNEL::Exception(msg);
8138     }
8139   else if(nbOfTuple2==1)
8140     {
8141       if(nbOfComp2==nbOfComp)
8142         {
8143           int *ptr=getPointer();
8144           const int *ptrc=other->getConstPointer();
8145           for(int i=0;i<nbOfTuple;i++)
8146             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
8147         }
8148       else
8149         throw INTERP_KERNEL::Exception(msg);
8150     }
8151   else
8152     throw INTERP_KERNEL::Exception(msg);
8153   declareAsNew();
8154 }
8155
8156 /*!
8157  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
8158  * valid cases.
8159  * 1.  The arrays have same number of tuples and components. Then each value of
8160  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
8161  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
8162  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8163  *   component. Then
8164  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
8165  * 3.  The arrays have same number of components and one array, say _a2_, has one
8166  *   tuple. Then
8167  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
8168  *
8169  * Info on components is copied either from the first array (in the first case) or from
8170  * the array with maximal number of elements (getNbOfElems()).
8171  *  \param [in] a1 - an array to subtract from.
8172  *  \param [in] a2 - an array to subtract.
8173  *  \return DataArrayInt * - the new instance of DataArrayInt.
8174  *          The caller is to delete this result array using decrRef() as it is no more
8175  *          needed.
8176  *  \throw If either \a a1 or \a a2 is NULL.
8177  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8178  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8179  *         none of them has number of tuples or components equal to 1.
8180  */
8181 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
8182 {
8183   if(!a1 || !a2)
8184     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
8185   int nbOfTuple1=a1->getNumberOfTuples();
8186   int nbOfTuple2=a2->getNumberOfTuples();
8187   int nbOfComp1=a1->getNumberOfComponents();
8188   int nbOfComp2=a2->getNumberOfComponents();
8189   if(nbOfTuple2==nbOfTuple1)
8190     {
8191       if(nbOfComp1==nbOfComp2)
8192         {
8193           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8194           ret->alloc(nbOfTuple2,nbOfComp1);
8195           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
8196           ret->copyStringInfoFrom(*a1);
8197           return ret.retn();
8198         }
8199       else if(nbOfComp2==1)
8200         {
8201           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8202           ret->alloc(nbOfTuple1,nbOfComp1);
8203           const int *a2Ptr=a2->getConstPointer();
8204           const int *a1Ptr=a1->getConstPointer();
8205           int *res=ret->getPointer();
8206           for(int i=0;i<nbOfTuple1;i++)
8207             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
8208           ret->copyStringInfoFrom(*a1);
8209           return ret.retn();
8210         }
8211       else
8212         {
8213           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8214           return 0;
8215         }
8216     }
8217   else if(nbOfTuple2==1)
8218     {
8219       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8220       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8221       ret->alloc(nbOfTuple1,nbOfComp1);
8222       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8223       int *pt=ret->getPointer();
8224       for(int i=0;i<nbOfTuple1;i++)
8225         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
8226       ret->copyStringInfoFrom(*a1);
8227       return ret.retn();
8228     }
8229   else
8230     {
8231       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
8232       return 0;
8233     }
8234 }
8235
8236 /*!
8237  * Subtract values of another DataArrayInt from values of \a this one. There are 3
8238  * valid cases.
8239  * 1.  The arrays have same number of tuples and components. Then each value of
8240  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
8241  *   _a_ [ i, j ] -= _other_ [ i, j ].
8242  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8243  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
8244  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8245  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
8246  *
8247  *  \param [in] other - an array to subtract from \a this one.
8248  *  \throw If \a other is NULL.
8249  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8250  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8251  *         \a other has number of both tuples and components not equal to 1.
8252  */
8253 void DataArrayInt::substractEqual(const DataArrayInt *other)
8254 {
8255   if(!other)
8256     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
8257   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
8258   checkAllocated(); other->checkAllocated();
8259   int nbOfTuple=getNumberOfTuples();
8260   int nbOfTuple2=other->getNumberOfTuples();
8261   int nbOfComp=getNumberOfComponents();
8262   int nbOfComp2=other->getNumberOfComponents();
8263   if(nbOfTuple==nbOfTuple2)
8264     {
8265       if(nbOfComp==nbOfComp2)
8266         {
8267           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
8268         }
8269       else if(nbOfComp2==1)
8270         {
8271           int *ptr=getPointer();
8272           const int *ptrc=other->getConstPointer();
8273           for(int i=0;i<nbOfTuple;i++)
8274             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
8275         }
8276       else
8277         throw INTERP_KERNEL::Exception(msg);
8278     }
8279   else if(nbOfTuple2==1)
8280     {
8281       int *ptr=getPointer();
8282       const int *ptrc=other->getConstPointer();
8283       for(int i=0;i<nbOfTuple;i++)
8284         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
8285     }
8286   else
8287     throw INTERP_KERNEL::Exception(msg);
8288   declareAsNew();
8289 }
8290
8291 /*!
8292  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
8293  * valid cases.
8294  * 1.  The arrays have same number of tuples and components. Then each value of
8295  *   the result array (_a_) is a product of the corresponding values of \a a1 and
8296  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
8297  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8298  *   component. Then
8299  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
8300  * 3.  The arrays have same number of components and one array, say _a2_, has one
8301  *   tuple. Then
8302  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
8303  *
8304  * Info on components is copied either from the first array (in the first case) or from
8305  * the array with maximal number of elements (getNbOfElems()).
8306  *  \param [in] a1 - a factor array.
8307  *  \param [in] a2 - another factor array.
8308  *  \return DataArrayInt * - the new instance of DataArrayInt.
8309  *          The caller is to delete this result array using decrRef() as it is no more
8310  *          needed.
8311  *  \throw If either \a a1 or \a a2 is NULL.
8312  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8313  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8314  *         none of them has number of tuples or components equal to 1.
8315  */
8316 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
8317 {
8318   if(!a1 || !a2)
8319     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
8320   int nbOfTuple=a1->getNumberOfTuples();
8321   int nbOfTuple2=a2->getNumberOfTuples();
8322   int nbOfComp=a1->getNumberOfComponents();
8323   int nbOfComp2=a2->getNumberOfComponents();
8324   MCAuto<DataArrayInt> ret=0;
8325   if(nbOfTuple==nbOfTuple2)
8326     {
8327       if(nbOfComp==nbOfComp2)
8328         {
8329           ret=DataArrayInt::New();
8330           ret->alloc(nbOfTuple,nbOfComp);
8331           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
8332           ret->copyStringInfoFrom(*a1);
8333         }
8334       else
8335         {
8336           int nbOfCompMin,nbOfCompMax;
8337           const DataArrayInt *aMin, *aMax;
8338           if(nbOfComp>nbOfComp2)
8339             {
8340               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8341               aMin=a2; aMax=a1;
8342             }
8343           else
8344             {
8345               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8346               aMin=a1; aMax=a2;
8347             }
8348           if(nbOfCompMin==1)
8349             {
8350               ret=DataArrayInt::New();
8351               ret->alloc(nbOfTuple,nbOfCompMax);
8352               const int *aMinPtr=aMin->getConstPointer();
8353               const int *aMaxPtr=aMax->getConstPointer();
8354               int *res=ret->getPointer();
8355               for(int i=0;i<nbOfTuple;i++)
8356                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
8357               ret->copyStringInfoFrom(*aMax);
8358             }
8359           else
8360             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8361         }
8362     }
8363   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8364     {
8365       if(nbOfComp==nbOfComp2)
8366         {
8367           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8368           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8369           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8370           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8371           ret=DataArrayInt::New();
8372           ret->alloc(nbOfTupleMax,nbOfComp);
8373           int *res=ret->getPointer();
8374           for(int i=0;i<nbOfTupleMax;i++)
8375             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
8376           ret->copyStringInfoFrom(*aMax);
8377         }
8378       else
8379         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8380     }
8381   else
8382     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
8383   return ret.retn();
8384 }
8385
8386
8387 /*!
8388  * Multiply values of another DataArrayInt to values of \a this one. There are 3
8389  * valid cases.
8390  * 1.  The arrays have same number of tuples and components. Then each value of
8391  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
8392  *   _a_ [ i, j ] *= _other_ [ i, j ].
8393  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8394  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
8395  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8396  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
8397  *
8398  *  \param [in] other - an array to multiply to \a this one.
8399  *  \throw If \a other is NULL.
8400  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8401  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8402  *         \a other has number of both tuples and components not equal to 1.
8403  */
8404 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
8405 {
8406   if(!other)
8407     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
8408   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
8409   checkAllocated(); other->checkAllocated();
8410   int nbOfTuple=getNumberOfTuples();
8411   int nbOfTuple2=other->getNumberOfTuples();
8412   int nbOfComp=getNumberOfComponents();
8413   int nbOfComp2=other->getNumberOfComponents();
8414   if(nbOfTuple==nbOfTuple2)
8415     {
8416       if(nbOfComp==nbOfComp2)
8417         {
8418           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
8419         }
8420       else if(nbOfComp2==1)
8421         {
8422           int *ptr=getPointer();
8423           const int *ptrc=other->getConstPointer();
8424           for(int i=0;i<nbOfTuple;i++)
8425             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
8426         }
8427       else
8428         throw INTERP_KERNEL::Exception(msg);
8429     }
8430   else if(nbOfTuple2==1)
8431     {
8432       if(nbOfComp2==nbOfComp)
8433         {
8434           int *ptr=getPointer();
8435           const int *ptrc=other->getConstPointer();
8436           for(int i=0;i<nbOfTuple;i++)
8437             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
8438         }
8439       else
8440         throw INTERP_KERNEL::Exception(msg);
8441     }
8442   else
8443     throw INTERP_KERNEL::Exception(msg);
8444   declareAsNew();
8445 }
8446
8447
8448 /*!
8449  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
8450  * valid cases.
8451  * 1.  The arrays have same number of tuples and components. Then each value of
8452  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8453  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
8454  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8455  *   component. Then
8456  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
8457  * 3.  The arrays have same number of components and one array, say _a2_, has one
8458  *   tuple. Then
8459  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
8460  *
8461  * Info on components is copied either from the first array (in the first case) or from
8462  * the array with maximal number of elements (getNbOfElems()).
8463  *  \warning No check of division by zero is performed!
8464  *  \param [in] a1 - a numerator array.
8465  *  \param [in] a2 - a denominator array.
8466  *  \return DataArrayInt * - the new instance of DataArrayInt.
8467  *          The caller is to delete this result array using decrRef() as it is no more
8468  *          needed.
8469  *  \throw If either \a a1 or \a a2 is NULL.
8470  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8471  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8472  *         none of them has number of tuples or components equal to 1.
8473  */
8474 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
8475 {
8476   if(!a1 || !a2)
8477     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
8478   int nbOfTuple1=a1->getNumberOfTuples();
8479   int nbOfTuple2=a2->getNumberOfTuples();
8480   int nbOfComp1=a1->getNumberOfComponents();
8481   int nbOfComp2=a2->getNumberOfComponents();
8482   if(nbOfTuple2==nbOfTuple1)
8483     {
8484       if(nbOfComp1==nbOfComp2)
8485         {
8486           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8487           ret->alloc(nbOfTuple2,nbOfComp1);
8488           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
8489           ret->copyStringInfoFrom(*a1);
8490           return ret.retn();
8491         }
8492       else if(nbOfComp2==1)
8493         {
8494           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8495           ret->alloc(nbOfTuple1,nbOfComp1);
8496           const int *a2Ptr=a2->getConstPointer();
8497           const int *a1Ptr=a1->getConstPointer();
8498           int *res=ret->getPointer();
8499           for(int i=0;i<nbOfTuple1;i++)
8500             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
8501           ret->copyStringInfoFrom(*a1);
8502           return ret.retn();
8503         }
8504       else
8505         {
8506           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8507           return 0;
8508         }
8509     }
8510   else if(nbOfTuple2==1)
8511     {
8512       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8513       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8514       ret->alloc(nbOfTuple1,nbOfComp1);
8515       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8516       int *pt=ret->getPointer();
8517       for(int i=0;i<nbOfTuple1;i++)
8518         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
8519       ret->copyStringInfoFrom(*a1);
8520       return ret.retn();
8521     }
8522   else
8523     {
8524       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
8525       return 0;
8526     }
8527 }
8528
8529 /*!
8530  * Divide values of \a this array by values of another DataArrayInt. There are 3
8531  * valid cases.
8532  * 1.  The arrays have same number of tuples and components. Then each value of
8533  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8534  *   _a_ [ i, j ] /= _other_ [ i, j ].
8535  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8536  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
8537  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8538  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
8539  *
8540  *  \warning No check of division by zero is performed!
8541  *  \param [in] other - an array to divide \a this one by.
8542  *  \throw If \a other is NULL.
8543  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8544  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8545  *         \a other has number of both tuples and components not equal to 1.
8546  */
8547 void DataArrayInt::divideEqual(const DataArrayInt *other)
8548 {
8549   if(!other)
8550     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
8551   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
8552   checkAllocated(); other->checkAllocated();
8553   int nbOfTuple=getNumberOfTuples();
8554   int nbOfTuple2=other->getNumberOfTuples();
8555   int nbOfComp=getNumberOfComponents();
8556   int nbOfComp2=other->getNumberOfComponents();
8557   if(nbOfTuple==nbOfTuple2)
8558     {
8559       if(nbOfComp==nbOfComp2)
8560         {
8561           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
8562         }
8563       else if(nbOfComp2==1)
8564         {
8565           int *ptr=getPointer();
8566           const int *ptrc=other->getConstPointer();
8567           for(int i=0;i<nbOfTuple;i++)
8568             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
8569         }
8570       else
8571         throw INTERP_KERNEL::Exception(msg);
8572     }
8573   else if(nbOfTuple2==1)
8574     {
8575       if(nbOfComp2==nbOfComp)
8576         {
8577           int *ptr=getPointer();
8578           const int *ptrc=other->getConstPointer();
8579           for(int i=0;i<nbOfTuple;i++)
8580             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
8581         }
8582       else
8583         throw INTERP_KERNEL::Exception(msg);
8584     }
8585   else
8586     throw INTERP_KERNEL::Exception(msg);
8587   declareAsNew();
8588 }
8589
8590
8591 /*!
8592  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
8593  * valid cases.
8594  * 1.  The arrays have same number of tuples and components. Then each value of
8595  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8596  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
8597  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8598  *   component. Then
8599  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
8600  * 3.  The arrays have same number of components and one array, say _a2_, has one
8601  *   tuple. Then
8602  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
8603  *
8604  * Info on components is copied either from the first array (in the first case) or from
8605  * the array with maximal number of elements (getNbOfElems()).
8606  *  \warning No check of division by zero is performed!
8607  *  \param [in] a1 - a dividend array.
8608  *  \param [in] a2 - a divisor array.
8609  *  \return DataArrayInt * - the new instance of DataArrayInt.
8610  *          The caller is to delete this result array using decrRef() as it is no more
8611  *          needed.
8612  *  \throw If either \a a1 or \a a2 is NULL.
8613  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8614  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8615  *         none of them has number of tuples or components equal to 1.
8616  */
8617 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
8618 {
8619   if(!a1 || !a2)
8620     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
8621   int nbOfTuple1=a1->getNumberOfTuples();
8622   int nbOfTuple2=a2->getNumberOfTuples();
8623   int nbOfComp1=a1->getNumberOfComponents();
8624   int nbOfComp2=a2->getNumberOfComponents();
8625   if(nbOfTuple2==nbOfTuple1)
8626     {
8627       if(nbOfComp1==nbOfComp2)
8628         {
8629           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8630           ret->alloc(nbOfTuple2,nbOfComp1);
8631           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
8632           ret->copyStringInfoFrom(*a1);
8633           return ret.retn();
8634         }
8635       else if(nbOfComp2==1)
8636         {
8637           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8638           ret->alloc(nbOfTuple1,nbOfComp1);
8639           const int *a2Ptr=a2->getConstPointer();
8640           const int *a1Ptr=a1->getConstPointer();
8641           int *res=ret->getPointer();
8642           for(int i=0;i<nbOfTuple1;i++)
8643             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
8644           ret->copyStringInfoFrom(*a1);
8645           return ret.retn();
8646         }
8647       else
8648         {
8649           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8650           return 0;
8651         }
8652     }
8653   else if(nbOfTuple2==1)
8654     {
8655       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8656       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8657       ret->alloc(nbOfTuple1,nbOfComp1);
8658       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8659       int *pt=ret->getPointer();
8660       for(int i=0;i<nbOfTuple1;i++)
8661         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
8662       ret->copyStringInfoFrom(*a1);
8663       return ret.retn();
8664     }
8665   else
8666     {
8667       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
8668       return 0;
8669     }
8670 }
8671
8672 /*!
8673  * Modify \a this array so that each value becomes a modulus of division of this value by
8674  * a value of another DataArrayInt. There are 3 valid cases.
8675  * 1.  The arrays have same number of tuples and components. Then each value of
8676  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8677  *   _a_ [ i, j ] %= _other_ [ i, j ].
8678  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8679  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
8680  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8681  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
8682  *
8683  *  \warning No check of division by zero is performed!
8684  *  \param [in] other - a divisor array.
8685  *  \throw If \a other is NULL.
8686  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8687  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8688  *         \a other has number of both tuples and components not equal to 1.
8689  */
8690 void DataArrayInt::modulusEqual(const DataArrayInt *other)
8691 {
8692   if(!other)
8693     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
8694   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
8695   checkAllocated(); other->checkAllocated();
8696   int nbOfTuple=getNumberOfTuples();
8697   int nbOfTuple2=other->getNumberOfTuples();
8698   int nbOfComp=getNumberOfComponents();
8699   int nbOfComp2=other->getNumberOfComponents();
8700   if(nbOfTuple==nbOfTuple2)
8701     {
8702       if(nbOfComp==nbOfComp2)
8703         {
8704           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
8705         }
8706       else if(nbOfComp2==1)
8707         {
8708           if(nbOfComp2==nbOfComp)
8709             {
8710               int *ptr=getPointer();
8711               const int *ptrc=other->getConstPointer();
8712               for(int i=0;i<nbOfTuple;i++)
8713                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
8714             }
8715           else
8716             throw INTERP_KERNEL::Exception(msg);
8717         }
8718       else
8719         throw INTERP_KERNEL::Exception(msg);
8720     }
8721   else if(nbOfTuple2==1)
8722     {
8723       int *ptr=getPointer();
8724       const int *ptrc=other->getConstPointer();
8725       for(int i=0;i<nbOfTuple;i++)
8726         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
8727     }
8728   else
8729     throw INTERP_KERNEL::Exception(msg);
8730   declareAsNew();
8731 }
8732
8733 /*!
8734  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
8735  * valid cases.
8736  *
8737  *  \param [in] a1 - an array to pow up.
8738  *  \param [in] a2 - another array to sum up.
8739  *  \return DataArrayInt * - the new instance of DataArrayInt.
8740  *          The caller is to delete this result array using decrRef() as it is no more
8741  *          needed.
8742  *  \throw If either \a a1 or \a a2 is NULL.
8743  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8744  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
8745  *  \throw If there is a negative value in \a a2.
8746  */
8747 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
8748 {
8749   if(!a1 || !a2)
8750     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
8751   int nbOfTuple=a1->getNumberOfTuples();
8752   int nbOfTuple2=a2->getNumberOfTuples();
8753   int nbOfComp=a1->getNumberOfComponents();
8754   int nbOfComp2=a2->getNumberOfComponents();
8755   if(nbOfTuple!=nbOfTuple2)
8756     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
8757   if(nbOfComp!=1 || nbOfComp2!=1)
8758     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
8759   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
8760   const int *ptr1(a1->begin()),*ptr2(a2->begin());
8761   int *ptr=ret->getPointer();
8762   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
8763     {
8764       if(*ptr2>=0)
8765         {
8766           int tmp=1;
8767           for(int j=0;j<*ptr2;j++)
8768             tmp*=*ptr1;
8769           *ptr=tmp;
8770         }
8771       else
8772         {
8773           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
8774           throw INTERP_KERNEL::Exception(oss.str().c_str());
8775         }
8776     }
8777   return ret.retn();
8778 }
8779
8780 /*!
8781  * Apply pow on values of another DataArrayInt to values of \a this one.
8782  *
8783  *  \param [in] other - an array to pow to \a this one.
8784  *  \throw If \a other is NULL.
8785  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
8786  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
8787  *  \throw If there is a negative value in \a other.
8788  */
8789 void DataArrayInt::powEqual(const DataArrayInt *other)
8790 {
8791   if(!other)
8792     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
8793   int nbOfTuple=getNumberOfTuples();
8794   int nbOfTuple2=other->getNumberOfTuples();
8795   int nbOfComp=getNumberOfComponents();
8796   int nbOfComp2=other->getNumberOfComponents();
8797   if(nbOfTuple!=nbOfTuple2)
8798     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
8799   if(nbOfComp!=1 || nbOfComp2!=1)
8800     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
8801   int *ptr=getPointer();
8802   const int *ptrc=other->begin();
8803   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
8804     {
8805       if(*ptrc>=0)
8806         {
8807           int tmp=1;
8808           for(int j=0;j<*ptrc;j++)
8809             tmp*=*ptr;
8810           *ptr=tmp;
8811         }
8812       else
8813         {
8814           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
8815           throw INTERP_KERNEL::Exception(oss.str().c_str());
8816         }
8817     }
8818   declareAsNew();
8819 }
8820
8821 /*!
8822  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
8823  * This map, if applied to \a start array, would make it sorted. For example, if
8824  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
8825  * [5,6,0,3,2,7,1,4].
8826  *  \param [in] start - pointer to the first element of the array for which the
8827  *         permutation map is computed.
8828  *  \param [in] end - pointer specifying the end of the array \a start, so that
8829  *         the last value of \a start is \a end[ -1 ].
8830  *  \return int * - the result permutation array that the caller is to delete as it is no
8831  *         more needed.
8832  *  \throw If there are equal values in the input array.
8833  */
8834 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
8835 {
8836   std::size_t sz=std::distance(start,end);
8837   int *ret=(int *)malloc(sz*sizeof(int));
8838   int *work=new int[sz];
8839   std::copy(start,end,work);
8840   std::sort(work,work+sz);
8841   if(std::unique(work,work+sz)!=work+sz)
8842     {
8843       delete [] work;
8844       free(ret);
8845       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
8846     }
8847   std::map<int,int> m;
8848   for(int *workPt=work;workPt!=work+sz;workPt++)
8849     m[*workPt]=(int)std::distance(work,workPt);
8850   int *iter2=ret;
8851   for(const int *iter=start;iter!=end;iter++,iter2++)
8852     *iter2=m[*iter];
8853   delete [] work;
8854   return ret;
8855 }
8856
8857 /*!
8858  * Returns a new DataArrayInt containing an arithmetic progression
8859  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
8860  * function.
8861  *  \param [in] begin - the start value of the result sequence.
8862  *  \param [in] end - limiting value, so that every value of the result array is less than
8863  *              \a end.
8864  *  \param [in] step - specifies the increment or decrement.
8865  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8866  *          array using decrRef() as it is no more needed.
8867  *  \throw If \a step == 0.
8868  *  \throw If \a end < \a begin && \a step > 0.
8869  *  \throw If \a end > \a begin && \a step < 0.
8870  */
8871 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
8872 {
8873   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
8874   MCAuto<DataArrayInt> ret=DataArrayInt::New();
8875   ret->alloc(nbOfTuples,1);
8876   int *ptr=ret->getPointer();
8877   if(step>0)
8878     {
8879       for(int i=begin;i<end;i+=step,ptr++)
8880         *ptr=i;
8881     }
8882   else
8883     {
8884       for(int i=begin;i>end;i+=step,ptr++)
8885         *ptr=i;
8886     }
8887   return ret.retn();
8888 }
8889
8890 /*!
8891  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
8892  * Server side.
8893  */
8894 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
8895 {
8896   tinyInfo.resize(2);
8897   if(isAllocated())
8898     {
8899       tinyInfo[0]=getNumberOfTuples();
8900       tinyInfo[1]=getNumberOfComponents();
8901     }
8902   else
8903     {
8904       tinyInfo[0]=-1;
8905       tinyInfo[1]=-1;
8906     }
8907 }
8908
8909 /*!
8910  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
8911  * Server side.
8912  */
8913 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
8914 {
8915   if(isAllocated())
8916     {
8917       int nbOfCompo=getNumberOfComponents();
8918       tinyInfo.resize(nbOfCompo+1);
8919       tinyInfo[0]=getName();
8920       for(int i=0;i<nbOfCompo;i++)
8921         tinyInfo[i+1]=getInfoOnComponent(i);
8922     }
8923   else
8924     {
8925       tinyInfo.resize(1);
8926       tinyInfo[0]=getName();
8927     }
8928 }
8929
8930 /*!
8931  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
8932  * This method returns if a feeding is needed.
8933  */
8934 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
8935 {
8936   int nbOfTuple=tinyInfoI[0];
8937   int nbOfComp=tinyInfoI[1];
8938   if(nbOfTuple!=-1 || nbOfComp!=-1)
8939     {
8940       alloc(nbOfTuple,nbOfComp);
8941       return true;
8942     }
8943   return false;
8944 }
8945
8946 /*!
8947  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
8948  * This method returns if a feeding is needed.
8949  */
8950 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
8951 {
8952   setName(tinyInfoS[0]);
8953   if(isAllocated())
8954     {
8955       int nbOfCompo=tinyInfoI[1];
8956       for(int i=0;i<nbOfCompo;i++)
8957         setInfoOnComponent(i,tinyInfoS[i+1]);
8958     }
8959 }
8960
8961 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
8962 {
8963   if(_da)
8964     {
8965       _da->incrRef();
8966       if(_da->isAllocated())
8967         {
8968           _nb_comp=da->getNumberOfComponents();
8969           _nb_tuple=da->getNumberOfTuples();
8970           _pt=da->getPointer();
8971         }
8972     }
8973 }
8974
8975 DataArrayIntIterator::~DataArrayIntIterator()
8976 {
8977   if(_da)
8978     _da->decrRef();
8979 }
8980
8981 DataArrayIntTuple *DataArrayIntIterator::nextt()
8982 {
8983   if(_tuple_id<_nb_tuple)
8984     {
8985       _tuple_id++;
8986       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
8987       _pt+=_nb_comp;
8988       return ret;
8989     }
8990   else
8991     return 0;
8992 }
8993
8994 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
8995 {
8996 }
8997
8998 std::string DataArrayIntTuple::repr() const
8999 {
9000   std::ostringstream oss; oss << "(";
9001   for(int i=0;i<_nb_of_compo-1;i++)
9002     oss << _pt[i] << ", ";
9003   oss << _pt[_nb_of_compo-1] << ")";
9004   return oss.str();
9005 }
9006
9007 int DataArrayIntTuple::intValue() const
9008 {
9009   if(_nb_of_compo==1)
9010     return *_pt;
9011   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
9012 }
9013
9014 /*!
9015  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
9016  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
9017  * 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
9018  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
9019  */
9020 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
9021 {
9022   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
9023     {
9024       DataArrayInt *ret=DataArrayInt::New();
9025       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
9026       return ret;
9027     }
9028   else
9029     {
9030       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
9031       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
9032       throw INTERP_KERNEL::Exception(oss.str().c_str());
9033     }
9034 }