Salome HOME
MEDCoupling API renaming - stage #2
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2015  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 #include "MCAuto.hxx"
23
24 #include "BBTree.txx"
25 #include "GenMathFormulae.hxx"
26 #include "InterpKernelAutoPtr.hxx"
27 #include "InterpKernelExprParser.hxx"
28
29 #include <set>
30 #include <cmath>
31 #include <limits>
32 #include <numeric>
33 #include <algorithm>
34 #include <functional>
35
36 typedef double (*MYFUNCPTR)(double);
37
38 using namespace MEDCoupling;
39
40 template<int SPACEDIM>
41 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
42 {
43   const double *coordsPtr=getConstPointer();
44   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
45   std::vector<bool> isDone(nbNodes);
46   for(int i=0;i<nbNodes;i++)
47     {
48       if(!isDone[i])
49         {
50           std::vector<int> intersectingElems;
51           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
52           if(intersectingElems.size()>1)
53             {
54               std::vector<int> commonNodes;
55               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
56                 if(*it!=i)
57                   if(*it>=limitNodeId)
58                     {
59                       commonNodes.push_back(*it);
60                       isDone[*it]=true;
61                     }
62               if(!commonNodes.empty())
63                 {
64                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
65                   c->pushBackSilent(i);
66                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
67                 }
68             }
69         }
70     }
71 }
72
73 template<int SPACEDIM>
74 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
75                                                 DataArrayInt *c, DataArrayInt *cI)
76 {
77   for(int i=0;i<nbOfTuples;i++)
78     {
79       std::vector<int> intersectingElems;
80       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
81       std::vector<int> commonNodes;
82       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
83         commonNodes.push_back(*it);
84       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
85       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
86     }
87 }
88
89 template<int SPACEDIM>
90 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
91 {
92   double distOpt(dist);
93   const double *p(pos);
94   int *r(res);
95   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
96     {
97       while(true)
98         {
99           int elem=-1;
100           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
101           if(ret!=std::numeric_limits<double>::max())
102             {
103               distOpt=std::max(ret,1e-4);
104               *r=elem;
105               break;
106             }
107           else
108             { distOpt=2*distOpt; continue; }
109         }
110     }
111 }
112
113 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
114 {
115   std::size_t sz1=_name.capacity();
116   std::size_t sz2=_info_on_compo.capacity();
117   std::size_t sz3=0;
118   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
119     sz3+=(*it).capacity();
120   return sz1+sz2+sz3;
121 }
122
123 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
124 {
125   return std::vector<const BigMemoryObject *>();
126 }
127
128 /*!
129  * Sets the attribute \a _name of \a this array.
130  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
131  *  \param [in] name - new array name
132  */
133 void DataArray::setName(const std::string& name)
134 {
135   _name=name;
136 }
137
138 /*!
139  * Copies textual data from an \a other DataArray. The copied data are
140  * - the name attribute,
141  * - the information of components.
142  *
143  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
144  *
145  *  \param [in] other - another instance of DataArray to copy the textual data from.
146  *  \throw If number of components of \a this array differs from that of the \a other.
147  */
148 void DataArray::copyStringInfoFrom(const DataArray& other)
149 {
150   if(_info_on_compo.size()!=other._info_on_compo.size())
151     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
152   _name=other._name;
153   _info_on_compo=other._info_on_compo;
154 }
155
156 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
157 {
158   int nbOfCompoOth=other.getNumberOfComponents();
159   std::size_t newNbOfCompo=compoIds.size();
160   for(std::size_t i=0;i<newNbOfCompo;i++)
161     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
162       {
163         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
164         throw INTERP_KERNEL::Exception(oss.str().c_str());
165       }
166   for(std::size_t i=0;i<newNbOfCompo;i++)
167     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
168 }
169
170 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
171 {
172   int nbOfCompo=getNumberOfComponents();
173   std::size_t partOfCompoToSet=compoIds.size();
174   if((int)partOfCompoToSet!=other.getNumberOfComponents())
175     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
176   for(std::size_t i=0;i<partOfCompoToSet;i++)
177     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
178       {
179         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
180         throw INTERP_KERNEL::Exception(oss.str().c_str());
181       }
182   for(std::size_t i=0;i<partOfCompoToSet;i++)
183     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
184 }
185
186 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
187 {
188   std::ostringstream oss;
189   if(_name!=other._name)
190     {
191       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
192       reason=oss.str();
193       return false;
194     }
195   if(_info_on_compo!=other._info_on_compo)
196     {
197       oss << "Components DataArray mismatch : \nThis components=";
198       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
199         oss << "\"" << *it << "\",";
200       oss << "\nOther components=";
201       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
202         oss << "\"" << *it << "\",";
203       reason=oss.str();
204       return false;
205     }
206   return true;
207 }
208
209 /*!
210  * Compares textual information of \a this DataArray with that of an \a other one.
211  * The compared data are
212  * - the name attribute,
213  * - the information of components.
214  *
215  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
216  *  \param [in] other - another instance of DataArray to compare the textual data of.
217  *  \return bool - \a true if the textual information is same, \a false else.
218  */
219 bool DataArray::areInfoEquals(const DataArray& other) const
220 {
221   std::string tmp;
222   return areInfoEqualsIfNotWhy(other,tmp);
223 }
224
225 void DataArray::reprWithoutNameStream(std::ostream& stream) const
226 {
227   stream << "Number of components : "<< getNumberOfComponents() << "\n";
228   stream << "Info of these components : ";
229   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
230     stream << "\"" << *iter << "\"   ";
231   stream << "\n";
232 }
233
234 std::string DataArray::cppRepr(const std::string& varName) const
235 {
236   std::ostringstream ret;
237   reprCppStream(varName,ret);
238   return ret.str();
239 }
240
241 /*!
242  * Sets information on all components. To know more on format of this information
243  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
244  *  \param [in] info - a vector of strings.
245  *  \throw If size of \a info differs from the number of components of \a this.
246  */
247 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
248 {
249   if(getNumberOfComponents()!=(int)info.size())
250     {
251       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
252       throw INTERP_KERNEL::Exception(oss.str().c_str());
253     }
254   _info_on_compo=info;
255 }
256
257 /*!
258  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
259  * type of \a this and \a aBase.
260  *
261  * \throw If \a aBase and \a this do not have the same type.
262  *
263  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
264  */
265 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
266 {
267   if(!aBase)
268     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
269   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
270   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
271   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
272   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
273   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
274   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
275   if(this1 && a1)
276     {
277       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
278       return ;
279     }
280   if(this2 && a2)
281     {
282       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
283       return ;
284     }
285   if(this3 && a3)
286     {
287       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
288       return ;
289     }
290   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
291 }
292
293 std::vector<std::string> DataArray::getVarsOnComponent() const
294 {
295   int nbOfCompo=(int)_info_on_compo.size();
296   std::vector<std::string> ret(nbOfCompo);
297   for(int i=0;i<nbOfCompo;i++)
298     ret[i]=getVarOnComponent(i);
299   return ret;
300 }
301
302 std::vector<std::string> DataArray::getUnitsOnComponent() const
303 {
304   int nbOfCompo=(int)_info_on_compo.size();
305   std::vector<std::string> ret(nbOfCompo);
306   for(int i=0;i<nbOfCompo;i++)
307     ret[i]=getUnitOnComponent(i);
308   return ret;
309 }
310
311 /*!
312  * Returns information on a component specified by an index.
313  * To know more on format of this information
314  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
315  *  \param [in] i - the index (zero based) of the component of interest.
316  *  \return std::string - a string containing the information on \a i-th component.
317  *  \throw If \a i is not a valid component index.
318  */
319 std::string DataArray::getInfoOnComponent(int i) const
320 {
321   if(i<(int)_info_on_compo.size() && i>=0)
322     return _info_on_compo[i];
323   else
324     {
325       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();
326       throw INTERP_KERNEL::Exception(oss.str().c_str());
327     }
328 }
329
330 /*!
331  * Returns the var part of the full information of the \a i-th component.
332  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
333  * \c getVarOnComponent(0) returns "SIGXY".
334  * If a unit part of information is not detected by presence of
335  * two square brackets, then the full information is returned.
336  * To read more about the component information format, see
337  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
338  *  \param [in] i - the index (zero based) of the component of interest.
339  *  \return std::string - a string containing the var information, or the full info.
340  *  \throw If \a i is not a valid component index.
341  */
342 std::string DataArray::getVarOnComponent(int i) const
343 {
344   if(i<(int)_info_on_compo.size() && i>=0)
345     {
346       return GetVarNameFromInfo(_info_on_compo[i]);
347     }
348   else
349     {
350       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();
351       throw INTERP_KERNEL::Exception(oss.str().c_str());
352     }
353 }
354
355 /*!
356  * Returns the unit part of the full information of the \a i-th component.
357  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
358  * \c getUnitOnComponent(0) returns " N/m^2".
359  * If a unit part of information is not detected by presence of
360  * two square brackets, then an empty string is returned.
361  * To read more about the component information format, see
362  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
363  *  \param [in] i - the index (zero based) of the component of interest.
364  *  \return std::string - a string containing the unit information, if any, or "".
365  *  \throw If \a i is not a valid component index.
366  */
367 std::string DataArray::getUnitOnComponent(int i) const
368 {
369   if(i<(int)_info_on_compo.size() && i>=0)
370     {
371       return GetUnitFromInfo(_info_on_compo[i]);
372     }
373   else
374     {
375       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();
376       throw INTERP_KERNEL::Exception(oss.str().c_str());
377     }
378 }
379
380 /*!
381  * Returns the var part of the full component information.
382  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
383  * If a unit part of information is not detected by presence of
384  * two square brackets, then the whole \a info is returned.
385  * To read more about the component information format, see
386  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
387  *  \param [in] info - the full component information.
388  *  \return std::string - a string containing only var information, or the \a info.
389  */
390 std::string DataArray::GetVarNameFromInfo(const std::string& info)
391 {
392   std::size_t p1=info.find_last_of('[');
393   std::size_t p2=info.find_last_of(']');
394   if(p1==std::string::npos || p2==std::string::npos)
395     return info;
396   if(p1>p2)
397     return info;
398   if(p1==0)
399     return std::string();
400   std::size_t p3=info.find_last_not_of(' ',p1-1);
401   return info.substr(0,p3+1);
402 }
403
404 /*!
405  * Returns the unit part of the full component information.
406  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
407  * If a unit part of information is not detected by presence of
408  * two square brackets, then an empty string is returned.
409  * To read more about the component information format, see
410  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
411  *  \param [in] info - the full component information.
412  *  \return std::string - a string containing only unit information, if any, or "".
413  */
414 std::string DataArray::GetUnitFromInfo(const std::string& info)
415 {
416   std::size_t p1=info.find_last_of('[');
417   std::size_t p2=info.find_last_of(']');
418   if(p1==std::string::npos || p2==std::string::npos)
419     return std::string();
420   if(p1>p2)
421     return std::string();
422   return info.substr(p1+1,p2-p1-1);
423 }
424
425 /*!
426  * This method put in info format the result of the merge of \a var and \a unit.
427  * The standard format for that is "var [unit]".
428  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
429  */
430 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
431 {
432   std::ostringstream oss;
433   oss << var << " [" << unit << "]";
434   return oss.str();
435 }
436
437 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
438 {
439   switch(at)
440     {
441     case AX_CART:
442       return std::string("AX_CART");
443     case AX_CYL:
444       return std::string("AX_CYL");
445     case AX_SPHER:
446       return std::string("AX_SPHER");
447     default:
448       throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
449     }
450 }
451
452 /*!
453  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
454  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
455  * the number of component in the result array is same as that of each of given arrays.
456  * Info on components is copied from the first of the given arrays. Number of components
457  * in the given arrays must be  the same.
458  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
459  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
460  *          The caller is to delete this result array using decrRef() as it is no more
461  *          needed.
462  *  \throw If all arrays within \a arrs are NULL.
463  *  \throw If all not null arrays in \a arrs have not the same type.
464  *  \throw If getNumberOfComponents() of arrays within \a arrs.
465  */
466 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
467 {
468   std::vector<const DataArray *> arr2;
469   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
470     if(*it)
471       arr2.push_back(*it);
472   if(arr2.empty())
473     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
474   std::vector<const DataArrayDouble *> arrd;
475   std::vector<const DataArrayInt *> arri;
476   std::vector<const DataArrayChar *> arrc;
477   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
478     {
479       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
480       if(a)
481         { arrd.push_back(a); continue; }
482       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
483       if(b)
484         { arri.push_back(b); continue; }
485       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
486       if(c)
487         { arrc.push_back(c); continue; }
488       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
489     }
490   if(arr2.size()==arrd.size())
491     return DataArrayDouble::Aggregate(arrd);
492   if(arr2.size()==arri.size())
493     return DataArrayInt::Aggregate(arri);
494   if(arr2.size()==arrc.size())
495     return DataArrayChar::Aggregate(arrc);
496   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
497 }
498
499 /*!
500  * Sets information on a component specified by an index.
501  * To know more on format of this information
502  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
503  *  \warning Don't pass NULL as \a info!
504  *  \param [in] i - the index (zero based) of the component of interest.
505  *  \param [in] info - the string containing the information.
506  *  \throw If \a i is not a valid component index.
507  */
508 void DataArray::setInfoOnComponent(int i, const std::string& info)
509 {
510   if(i<(int)_info_on_compo.size() && i>=0)
511     _info_on_compo[i]=info;
512   else
513     {
514       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();
515       throw INTERP_KERNEL::Exception(oss.str().c_str());
516     }
517 }
518
519 /*!
520  * Sets information on all components. This method can change number of components
521  * at certain conditions; if the conditions are not respected, an exception is thrown.
522  * The number of components can be changed in \a this only if \a this is not allocated.
523  * The condition of number of components must not be changed.
524  *
525  * To know more on format of the component information see
526  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
527  *  \param [in] info - a vector of component infos.
528  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
529  */
530 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
531 {
532   if(getNumberOfComponents()!=(int)info.size())
533     {
534       if(!isAllocated())
535         _info_on_compo=info;
536       else
537         {
538           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 !";
539           throw INTERP_KERNEL::Exception(oss.str().c_str());
540         }
541     }
542   else
543     _info_on_compo=info;
544 }
545
546 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
547 {
548   if(getNumberOfTuples()!=nbOfTuples)
549     {
550       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
551       throw INTERP_KERNEL::Exception(oss.str().c_str());
552     }
553 }
554
555 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
556 {
557   if(getNumberOfComponents()!=nbOfCompo)
558     {
559       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
560       throw INTERP_KERNEL::Exception(oss.str().c_str());
561     }
562 }
563
564 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
565 {
566   if(getNbOfElems()!=nbOfElems)
567     {
568       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
569       throw INTERP_KERNEL::Exception(oss.str().c_str());
570     }
571 }
572
573 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
574 {
575   if(getNumberOfTuples()!=other.getNumberOfTuples())
576     {
577       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
578       throw INTERP_KERNEL::Exception(oss.str().c_str());
579     }
580   if(getNumberOfComponents()!=other.getNumberOfComponents())
581     {
582       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
583       throw INTERP_KERNEL::Exception(oss.str().c_str());
584     }
585 }
586
587 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
588 {
589   checkNbOfTuples(nbOfTuples,msg);
590   checkNbOfComps(nbOfCompo,msg);
591 }
592
593 /*!
594  * Simply this method checks that \b value is in [0,\b ref).
595  */
596 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
597 {
598   if(value<0 || value>=ref)
599     {
600       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
601       throw INTERP_KERNEL::Exception(oss.str().c_str());
602     }
603 }
604
605 /*!
606  * This method checks that [\b start, \b end) is compliant with ref length \b value.
607  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
608  */
609 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
610 {
611   if(start<0 || start>=value)
612     {
613       if(value!=start || end!=start)
614         {
615           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
616           throw INTERP_KERNEL::Exception(oss.str().c_str());
617         }
618     }
619   if(end<0 || end>value)
620     {
621       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
622       throw INTERP_KERNEL::Exception(oss.str().c_str());
623     }
624 }
625
626 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
627 {
628   if(value<0 || value>ref)
629     {
630       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
631       throw INTERP_KERNEL::Exception(oss.str().c_str());
632     }
633 }
634
635 /*!
636  * 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, 
637  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
638  *
639  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
640  *
641  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
642  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
643  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
644  * \param [in] sliceId - the slice id considered
645  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
646  * \param [out] startSlice - the start of the slice considered
647  * \param [out] stopSlice - the stop of the slice consided
648  * 
649  * \throw If \a step == 0
650  * \throw If \a nbOfSlices not > 0
651  * \throw If \a sliceId not in [0,nbOfSlices)
652  */
653 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
654 {
655   if(nbOfSlices<=0)
656     {
657       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
658       throw INTERP_KERNEL::Exception(oss.str().c_str());
659     }
660   if(sliceId<0 || sliceId>=nbOfSlices)
661     {
662       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
663       throw INTERP_KERNEL::Exception(oss.str().c_str());
664     }
665   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
666   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
667   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
668   if(sliceId<nbOfSlices-1)
669     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
670   else
671     stopSlice=stop;
672 }
673
674 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
675 {
676   if(end<begin)
677     {
678       std::ostringstream oss; oss << msg << " : end before begin !";
679       throw INTERP_KERNEL::Exception(oss.str().c_str());
680     }
681   if(end==begin)
682     return 0;
683   if(step<=0)
684     {
685       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
686       throw INTERP_KERNEL::Exception(oss.str().c_str());
687     }
688   return (end-1-begin)/step+1;
689 }
690
691 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
692 {
693   if(step==0)
694     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
695   if(end<begin && step>0)
696     {
697       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
698       throw INTERP_KERNEL::Exception(oss.str().c_str());
699     }
700   if(begin<end && step<0)
701     {
702       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
703       throw INTERP_KERNEL::Exception(oss.str().c_str());
704     }
705   if(begin!=end)
706     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
707   else
708     return 0;
709 }
710
711 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
712 {
713   if(step!=0)
714     {
715       if(step>0)
716         {
717           if(begin<=value && value<end)
718             {
719               if((value-begin)%step==0)
720                 return (value-begin)/step;
721               else
722                 return -1;
723             }
724           else
725             return -1;
726         }
727       else
728         {
729           if(begin>=value && value>end)
730             {
731               if((begin-value)%(-step)==0)
732                 return (begin-value)/(-step);
733               else
734                 return -1;
735             }
736           else
737             return -1;
738         }
739     }
740   else
741     return -1;
742 }
743
744 /*!
745  * Returns a new instance of DataArrayDouble. The caller is to delete this array
746  * using decrRef() as it is no more needed. 
747  */
748 DataArrayDouble *DataArrayDouble::New()
749 {
750   return new DataArrayDouble;
751 }
752
753 /*!
754  * Checks if raw data is allocated. Read more on the raw data
755  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
756  *  \return bool - \a true if the raw data is allocated, \a false else.
757  */
758 bool DataArrayDouble::isAllocated() const
759 {
760   return getConstPointer()!=0;
761 }
762
763 /*!
764  * Checks if raw data is allocated and throws an exception if it is not the case.
765  *  \throw If the raw data is not allocated.
766  */
767 void DataArrayDouble::checkAllocated() const
768 {
769   if(!isAllocated())
770     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
771 }
772
773 /*!
774  * This method desallocated \a this without modification of informations relative to the components.
775  * After call of this method, DataArrayDouble::isAllocated will return false.
776  * If \a this is already not allocated, \a this is let unchanged.
777  */
778 void DataArrayDouble::desallocate()
779 {
780   _mem.destroy();
781 }
782
783 std::size_t DataArrayDouble::getHeapMemorySizeWithoutChildren() const
784 {
785   std::size_t sz(_mem.getNbOfElemAllocated());
786   sz*=sizeof(double);
787   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
788 }
789
790 /*!
791  * Returns the only one value in \a this, if and only if number of elements
792  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
793  *  \return double - the sole value stored in \a this array.
794  *  \throw If at least one of conditions stated above is not fulfilled.
795  */
796 double DataArrayDouble::doubleValue() const
797 {
798   if(isAllocated())
799     {
800       if(getNbOfElems()==1)
801         {
802           return *getConstPointer();
803         }
804       else
805         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
806     }
807   else
808     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
809 }
810
811 /*!
812  * Checks the number of tuples.
813  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
814  *  \throw If \a this is not allocated.
815  */
816 bool DataArrayDouble::empty() const
817 {
818   checkAllocated();
819   return getNumberOfTuples()==0;
820 }
821
822 /*!
823  * Returns a full copy of \a this. For more info on copying data arrays see
824  * \ref MEDCouplingArrayBasicsCopyDeep.
825  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
826  *          delete this array using decrRef() as it is no more needed. 
827  */
828 DataArrayDouble *DataArrayDouble::deepCopy() const
829 {
830   return new DataArrayDouble(*this);
831 }
832
833 /*!
834  * Returns either a \a deep or \a shallow copy of this array. For more info see
835  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
836  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
837  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
838  *          == \a true) or \a this instance (if \a dCpy == \a false).
839  */
840 DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const
841 {
842   if(dCpy)
843     return deepCopy();
844   else
845     {
846       incrRef();
847       return const_cast<DataArrayDouble *>(this);
848     }
849 }
850
851 /*!
852  * Copies all the data from another DataArrayDouble. For more info see
853  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
854  *  \param [in] other - another instance of DataArrayDouble to copy data from.
855  *  \throw If the \a other is not allocated.
856  */
857 void DataArrayDouble::deepCopyFrom(const DataArrayDouble& other)
858 {
859   other.checkAllocated();
860   int nbOfTuples=other.getNumberOfTuples();
861   int nbOfComp=other.getNumberOfComponents();
862   allocIfNecessary(nbOfTuples,nbOfComp);
863   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
864   double *pt=getPointer();
865   const double *ptI=other.getConstPointer();
866   for(std::size_t i=0;i<nbOfElems;i++)
867     pt[i]=ptI[i];
868   copyStringInfoFrom(other);
869 }
870
871 /*!
872  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
873  * If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown.
874  * If \a this has not already been allocated, number of components is set to one.
875  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
876  * 
877  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
878  */
879 void DataArrayDouble::reserve(std::size_t nbOfElems)
880 {
881   int nbCompo=getNumberOfComponents();
882   if(nbCompo==1)
883     {
884       _mem.reserve(nbOfElems);
885     }
886   else if(nbCompo==0)
887     {
888       _mem.reserve(nbOfElems);
889       _info_on_compo.resize(1);
890     }
891   else
892     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
893 }
894
895 /*!
896  * This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation
897  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
898  *
899  * \param [in] val the value to be added in \a this
900  * \throw If \a this has already been allocated with number of components different from one.
901  * \sa DataArrayDouble::pushBackValsSilent
902  */
903 void DataArrayDouble::pushBackSilent(double val)
904 {
905   int nbCompo=getNumberOfComponents();
906   if(nbCompo==1)
907     _mem.pushBack(val);
908   else if(nbCompo==0)
909     {
910       _info_on_compo.resize(1);
911       _mem.pushBack(val);
912     }
913   else
914     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
915 }
916
917 /*!
918  * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation
919  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
920  *
921  *  \param [in] valsBg - an array of values to push at the end of \c this.
922  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
923  *              the last value of \a valsBg is \a valsEnd[ -1 ].
924  * \throw If \a this has already been allocated with number of components different from one.
925  * \sa DataArrayDouble::pushBackSilent
926  */
927 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd)
928 {
929   int nbCompo=getNumberOfComponents();
930   if(nbCompo==1)
931     _mem.insertAtTheEnd(valsBg,valsEnd);
932   else if(nbCompo==0)
933     {
934       _info_on_compo.resize(1);
935       _mem.insertAtTheEnd(valsBg,valsEnd);
936     }
937   else
938     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
939 }
940
941 /*!
942  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
943  * \throw If \a this is already empty.
944  * \throw If \a this has number of components different from one.
945  */
946 double DataArrayDouble::popBackSilent()
947 {
948   if(getNumberOfComponents()==1)
949     return _mem.popBack();
950   else
951     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
952 }
953
954 /*!
955  * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store.
956  *
957  * \sa DataArrayDouble::getHeapMemorySizeWithoutChildren, DataArrayDouble::reserve
958  */
959 void DataArrayDouble::pack() const
960 {
961   _mem.pack();
962 }
963
964 /*!
965  * Allocates the raw data in memory. If exactly same memory as needed already
966  * allocated, it is not re-allocated.
967  *  \param [in] nbOfTuple - number of tuples of data to allocate.
968  *  \param [in] nbOfCompo - number of components of data to allocate.
969  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
970  */
971 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo)
972 {
973   if(isAllocated())
974     {
975       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
976         alloc(nbOfTuple,nbOfCompo);
977     }
978   else
979     alloc(nbOfTuple,nbOfCompo);
980 }
981
982 /*!
983  * Allocates the raw data in memory. If the memory was already allocated, then it is
984  * freed and re-allocated. See an example of this method use
985  * \ref MEDCouplingArraySteps1WC "here".
986  *  \param [in] nbOfTuple - number of tuples of data to allocate.
987  *  \param [in] nbOfCompo - number of components of data to allocate.
988  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
989  */
990 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo)
991 {
992   if(nbOfTuple<0 || nbOfCompo<0)
993     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
994   _info_on_compo.resize(nbOfCompo);
995   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
996   declareAsNew();
997 }
998
999 /*!
1000  * Assign zero to all values in \a this array. To know more on filling arrays see
1001  * \ref MEDCouplingArrayFill.
1002  * \throw If \a this is not allocated.
1003  */
1004 void DataArrayDouble::fillWithZero()
1005 {
1006   checkAllocated();
1007   _mem.fillWithValue(0.);
1008   declareAsNew();
1009 }
1010
1011 /*!
1012  * Assign \a val to all values in \a this array. To know more on filling arrays see
1013  * \ref MEDCouplingArrayFill.
1014  *  \param [in] val - the value to fill with.
1015  *  \throw If \a this is not allocated.
1016  */
1017 void DataArrayDouble::fillWithValue(double val)
1018 {
1019   checkAllocated();
1020   _mem.fillWithValue(val);
1021   declareAsNew();
1022 }
1023
1024 /*!
1025  * Set all values in \a this array so that the i-th element equals to \a init + i
1026  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
1027  *  \param [in] init - value to assign to the first element of array.
1028  *  \throw If \a this->getNumberOfComponents() != 1
1029  *  \throw If \a this is not allocated.
1030  */
1031 void DataArrayDouble::iota(double init)
1032 {
1033   checkAllocated();
1034   if(getNumberOfComponents()!=1)
1035     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
1036   double *ptr=getPointer();
1037   int ntuples=getNumberOfTuples();
1038   for(int i=0;i<ntuples;i++)
1039     ptr[i]=init+double(i);
1040   declareAsNew();
1041 }
1042
1043 /*!
1044  * Checks if all values in \a this array are equal to \a val at precision \a eps.
1045  *  \param [in] val - value to check equality of array values to.
1046  *  \param [in] eps - precision to check the equality.
1047  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
1048  *                 \a false else.
1049  *  \throw If \a this->getNumberOfComponents() != 1
1050  *  \throw If \a this is not allocated.
1051  */
1052 bool DataArrayDouble::isUniform(double val, double eps) const
1053 {
1054   checkAllocated();
1055   if(getNumberOfComponents()!=1)
1056     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1057   int nbOfTuples=getNumberOfTuples();
1058   const double *w=getConstPointer();
1059   const double *end2=w+nbOfTuples;
1060   const double vmin=val-eps;
1061   const double vmax=val+eps;
1062   for(;w!=end2;w++)
1063     if(*w<vmin || *w>vmax)
1064       return false;
1065   return true;
1066 }
1067
1068 /*!
1069  * Sorts values of the array.
1070  *  \param [in] asc - \a true means ascending order, \a false, descending.
1071  *  \throw If \a this is not allocated.
1072  *  \throw If \a this->getNumberOfComponents() != 1.
1073  */
1074 void DataArrayDouble::sort(bool asc)
1075 {
1076   checkAllocated();
1077   if(getNumberOfComponents()!=1)
1078     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
1079   _mem.sort(asc);
1080   declareAsNew();
1081 }
1082
1083 /*!
1084  * Reverse the array values.
1085  *  \throw If \a this->getNumberOfComponents() < 1.
1086  *  \throw If \a this is not allocated.
1087  */
1088 void DataArrayDouble::reverse()
1089 {
1090   checkAllocated();
1091   _mem.reverse(getNumberOfComponents());
1092   declareAsNew();
1093 }
1094
1095 /*!
1096  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1097  * with at least absolute difference value of |\a eps| at each step.
1098  * If not an exception is thrown.
1099  *  \param [in] increasing - if \a true, the array values should be increasing.
1100  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1101  *                    the values are considered different.
1102  *  \throw If sequence of values is not strictly monotonic in agreement with \a
1103  *         increasing arg.
1104  *  \throw If \a this->getNumberOfComponents() != 1.
1105  *  \throw If \a this is not allocated.
1106  */
1107 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
1108 {
1109   if(!isMonotonic(increasing,eps))
1110     {
1111       if (increasing)
1112         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
1113       else
1114         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
1115     }
1116 }
1117
1118 /*!
1119  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1120  * with at least absolute difference value of |\a eps| at each step.
1121  *  \param [in] increasing - if \a true, array values should be increasing.
1122  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1123  *                    the values are considered different.
1124  *  \return bool - \a true if values change in accordance with \a increasing arg.
1125  *  \throw If \a this->getNumberOfComponents() != 1.
1126  *  \throw If \a this is not allocated.
1127  */
1128 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
1129 {
1130   checkAllocated();
1131   if(getNumberOfComponents()!=1)
1132     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
1133   int nbOfElements=getNumberOfTuples();
1134   const double *ptr=getConstPointer();
1135   if(nbOfElements==0)
1136     return true;
1137   double ref=ptr[0];
1138   double absEps=fabs(eps);
1139   if(increasing)
1140     {
1141       for(int i=1;i<nbOfElements;i++)
1142         {
1143           if(ptr[i]<(ref+absEps))
1144             return false;
1145           ref=ptr[i];
1146         }
1147       return true;
1148     }
1149   else
1150     {
1151       for(int i=1;i<nbOfElements;i++)
1152         {
1153           if(ptr[i]>(ref-absEps))
1154             return false;
1155           ref=ptr[i];
1156         }
1157       return true;
1158     }
1159 }
1160
1161 /*!
1162  * Returns a textual and human readable representation of \a this instance of
1163  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
1164  * \return std::string - text describing \a this DataArrayDouble.
1165  *
1166  * \sa reprNotTooLong, reprZip
1167  */
1168 std::string DataArrayDouble::repr() const
1169 {
1170   std::ostringstream ret;
1171   reprStream(ret);
1172   return ret.str();
1173 }
1174
1175 std::string DataArrayDouble::reprZip() const
1176 {
1177   std::ostringstream ret;
1178   reprZipStream(ret);
1179   return ret.str();
1180 }
1181
1182 /*!
1183  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
1184  * printed out to avoid to consume too much space in interpretor.
1185  * \sa repr
1186  */
1187 std::string DataArrayDouble::reprNotTooLong() const
1188 {
1189   std::ostringstream ret;
1190   reprNotTooLongStream(ret);
1191   return ret.str();
1192 }
1193
1194 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
1195 {
1196   static const char SPACE[4]={' ',' ',' ',' '};
1197   checkAllocated();
1198   std::string idt(indent,' ');
1199   ofs.precision(17);
1200   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1201   //
1202   bool areAllEmpty(true);
1203   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
1204     if(!(*it).empty())
1205       areAllEmpty=false;
1206   if(!areAllEmpty)
1207     for(std::size_t i=0;i<_info_on_compo.size();i++)
1208       ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
1209   //
1210   if(byteArr)
1211     {
1212       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
1213       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
1214       float *pt(tmp);
1215       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
1216       for(const double *src=begin();src!=end();src++,pt++)
1217         *pt=float(*src);
1218       const char *data(reinterpret_cast<const char *>((float *)tmp));
1219       std::size_t sz(getNbOfElems()*sizeof(float));
1220       byteArr->insertAtTheEnd(data,data+sz);
1221       byteArr->insertAtTheEnd(SPACE,SPACE+4);
1222     }
1223   else
1224     {
1225       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
1226       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1227     }
1228   ofs << std::endl << idt << "</DataArray>\n";
1229 }
1230
1231 void DataArrayDouble::reprStream(std::ostream& stream) const
1232 {
1233   stream << "Name of double array : \"" << _name << "\"\n";
1234   reprWithoutNameStream(stream);
1235 }
1236
1237 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1238 {
1239   stream << "Name of double array : \"" << _name << "\"\n";
1240   reprZipWithoutNameStream(stream);
1241 }
1242
1243 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
1244 {
1245   stream << "Name of double array : \"" << _name << "\"\n";
1246   reprNotTooLongWithoutNameStream(stream);
1247 }
1248
1249 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1250 {
1251   DataArray::reprWithoutNameStream(stream);
1252   stream.precision(17);
1253   _mem.repr(getNumberOfComponents(),stream);
1254 }
1255
1256 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1257 {
1258   DataArray::reprWithoutNameStream(stream);
1259   stream.precision(17);
1260   _mem.reprZip(getNumberOfComponents(),stream);
1261 }
1262
1263 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
1264 {
1265   DataArray::reprWithoutNameStream(stream);
1266   stream.precision(17);
1267   _mem.reprNotTooLong(getNumberOfComponents(),stream);
1268 }
1269
1270 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1271 {
1272   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1273   const double *data=getConstPointer();
1274   stream.precision(17);
1275   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1276   if(nbTuples*nbComp>=1)
1277     {
1278       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1279       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1280       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1281       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1282     }
1283   else
1284     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1285   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1286 }
1287
1288 /*!
1289  * Method that gives a quick overvien of \a this for python.
1290  */
1291 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1292 {
1293   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1294   stream << "DataArrayDouble C++ instance at " << this << ". ";
1295   if(isAllocated())
1296     {
1297       int nbOfCompo=(int)_info_on_compo.size();
1298       if(nbOfCompo>=1)
1299         {
1300           int nbOfTuples=getNumberOfTuples();
1301           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1302           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1303         }
1304       else
1305         stream << "Number of components : 0.";
1306     }
1307   else
1308     stream << "*** No data allocated ****";
1309 }
1310
1311 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1312 {
1313   const double *data=begin();
1314   int nbOfTuples=getNumberOfTuples();
1315   int nbOfCompo=(int)_info_on_compo.size();
1316   std::ostringstream oss2; oss2 << "[";
1317   oss2.precision(17);
1318   std::string oss2Str(oss2.str());
1319   bool isFinished=true;
1320   for(int i=0;i<nbOfTuples && isFinished;i++)
1321     {
1322       if(nbOfCompo>1)
1323         {
1324           oss2 << "(";
1325           for(int j=0;j<nbOfCompo;j++,data++)
1326             {
1327               oss2 << *data;
1328               if(j!=nbOfCompo-1) oss2 << ", ";
1329             }
1330           oss2 << ")";
1331         }
1332       else
1333         oss2 << *data++;
1334       if(i!=nbOfTuples-1) oss2 << ", ";
1335       std::string oss3Str(oss2.str());
1336       if(oss3Str.length()<maxNbOfByteInRepr)
1337         oss2Str=oss3Str;
1338       else
1339         isFinished=false;
1340     }
1341   stream << oss2Str;
1342   if(!isFinished)
1343     stream << "... ";
1344   stream << "]";
1345 }
1346
1347 /*!
1348  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1349  * mismatch is given.
1350  * 
1351  * \param [in] other the instance to be compared with \a this
1352  * \param [in] prec the precision to compare numeric data of the arrays.
1353  * \param [out] reason In case of inequality returns the reason.
1354  * \sa DataArrayDouble::isEqual
1355  */
1356 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1357 {
1358   if(!areInfoEqualsIfNotWhy(other,reason))
1359     return false;
1360   return _mem.isEqual(other._mem,prec,reason);
1361 }
1362
1363 /*!
1364  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1365  * \ref MEDCouplingArrayBasicsCompare.
1366  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1367  *  \param [in] prec - precision value to compare numeric data of the arrays.
1368  *  \return bool - \a true if the two arrays are equal, \a false else.
1369  */
1370 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1371 {
1372   std::string tmp;
1373   return isEqualIfNotWhy(other,prec,tmp);
1374 }
1375
1376 /*!
1377  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1378  * \ref MEDCouplingArrayBasicsCompare.
1379  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1380  *  \param [in] prec - precision value to compare numeric data of the arrays.
1381  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1382  */
1383 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1384 {
1385   std::string tmp;
1386   return _mem.isEqual(other._mem,prec,tmp);
1387 }
1388
1389 /*!
1390  * Changes number of tuples in the array. If the new number of tuples is smaller
1391  * than the current number the array is truncated, otherwise the array is extended.
1392  *  \param [in] nbOfTuples - new number of tuples. 
1393  *  \throw If \a this is not allocated.
1394  *  \throw If \a nbOfTuples is negative.
1395  */
1396 void DataArrayDouble::reAlloc(int nbOfTuples)
1397 {
1398   if(nbOfTuples<0)
1399     throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
1400   checkAllocated();
1401   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1402   declareAsNew();
1403 }
1404
1405 /*!
1406  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1407  * array to the new one.
1408  *  \return DataArrayInt * - the new instance of DataArrayInt.
1409  */
1410 DataArrayInt *DataArrayDouble::convertToIntArr() const
1411 {
1412   DataArrayInt *ret=DataArrayInt::New();
1413   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1414   int *dest=ret->getPointer();
1415   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1416   for(const double *src=begin();src!=end();src++,dest++)
1417     *dest=(int)*src;
1418   ret->copyStringInfoFrom(*this);
1419   return ret;
1420 }
1421
1422 /*!
1423  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1424  * arranged in memory. If \a this array holds 2 components of 3 values:
1425  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1426  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1427  *  \warning Do not confuse this method with transpose()!
1428  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1429  *          is to delete using decrRef() as it is no more needed.
1430  *  \throw If \a this is not allocated.
1431  */
1432 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1433 {
1434   if(_mem.isNull())
1435     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1436   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1437   DataArrayDouble *ret=DataArrayDouble::New();
1438   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1439   return ret;
1440 }
1441
1442 /*!
1443  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1444  * arranged in memory. If \a this array holds 2 components of 3 values:
1445  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1446  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1447  *  \warning Do not confuse this method with transpose()!
1448  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1449  *          is to delete using decrRef() as it is no more needed.
1450  *  \throw If \a this is not allocated.
1451  */
1452 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1453 {
1454   if(_mem.isNull())
1455     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1456   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1457   DataArrayDouble *ret=DataArrayDouble::New();
1458   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1459   return ret;
1460 }
1461
1462 /*!
1463  * Permutes values of \a this array as required by \a old2New array. The values are
1464  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1465  * the same as in \c this one.
1466  * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
1467  * For more info on renumbering see \ref numbering.
1468  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1469  *     giving a new position for i-th old value.
1470  */
1471 void DataArrayDouble::renumberInPlace(const int *old2New)
1472 {
1473   checkAllocated();
1474   int nbTuples=getNumberOfTuples();
1475   int nbOfCompo=getNumberOfComponents();
1476   double *tmp=new double[nbTuples*nbOfCompo];
1477   const double *iptr=getConstPointer();
1478   for(int i=0;i<nbTuples;i++)
1479     {
1480       int v=old2New[i];
1481       if(v>=0 && v<nbTuples)
1482         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1483       else
1484         {
1485           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1486           throw INTERP_KERNEL::Exception(oss.str().c_str());
1487         }
1488     }
1489   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1490   delete [] tmp;
1491   declareAsNew();
1492 }
1493
1494 /*!
1495  * Permutes values of \a this array as required by \a new2Old array. The values are
1496  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1497  * the same as in \c this one.
1498  * For more info on renumbering see \ref numbering.
1499  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1500  *     giving a previous position of i-th new value.
1501  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1502  *          is to delete using decrRef() as it is no more needed.
1503  */
1504 void DataArrayDouble::renumberInPlaceR(const int *new2Old)
1505 {
1506   checkAllocated();
1507   int nbTuples=getNumberOfTuples();
1508   int nbOfCompo=getNumberOfComponents();
1509   double *tmp=new double[nbTuples*nbOfCompo];
1510   const double *iptr=getConstPointer();
1511   for(int i=0;i<nbTuples;i++)
1512     {
1513       int v=new2Old[i];
1514       if(v>=0 && v<nbTuples)
1515         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1516       else
1517         {
1518           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1519           throw INTERP_KERNEL::Exception(oss.str().c_str());
1520         }
1521     }
1522   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1523   delete [] tmp;
1524   declareAsNew();
1525 }
1526
1527 /*!
1528  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1529  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1530  * Number of tuples in the result array remains the same as in \c this one.
1531  * If a permutation reduction is needed, renumberAndReduce() should be used.
1532  * For more info on renumbering see \ref numbering.
1533  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1534  *          giving a new position for i-th old value.
1535  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1536  *          is to delete using decrRef() as it is no more needed.
1537  *  \throw If \a this is not allocated.
1538  */
1539 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
1540 {
1541   checkAllocated();
1542   int nbTuples=getNumberOfTuples();
1543   int nbOfCompo=getNumberOfComponents();
1544   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1545   ret->alloc(nbTuples,nbOfCompo);
1546   ret->copyStringInfoFrom(*this);
1547   const double *iptr=getConstPointer();
1548   double *optr=ret->getPointer();
1549   for(int i=0;i<nbTuples;i++)
1550     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1551   ret->copyStringInfoFrom(*this);
1552   return ret.retn();
1553 }
1554
1555 /*!
1556  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1557  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1558  * tuples in the result array remains the same as in \c this one.
1559  * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
1560  * For more info on renumbering see \ref numbering.
1561  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1562  *     giving a previous position of i-th new value.
1563  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1564  *          is to delete using decrRef() as it is no more needed.
1565  */
1566 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
1567 {
1568   checkAllocated();
1569   int nbTuples=getNumberOfTuples();
1570   int nbOfCompo=getNumberOfComponents();
1571   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1572   ret->alloc(nbTuples,nbOfCompo);
1573   ret->copyStringInfoFrom(*this);
1574   const double *iptr=getConstPointer();
1575   double *optr=ret->getPointer();
1576   for(int i=0;i<nbTuples;i++)
1577     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1578   ret->copyStringInfoFrom(*this);
1579   return ret.retn();
1580 }
1581
1582 /*!
1583  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1584  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1585  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1586  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1587  * \a old2New[ i ] is negative, is missing from the result array.
1588  * For more info on renumbering see \ref numbering.
1589  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1590  *     giving a new position for i-th old tuple and giving negative position for
1591  *     for i-th old tuple that should be omitted.
1592  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1593  *          is to delete using decrRef() as it is no more needed.
1594  */
1595 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
1596 {
1597   checkAllocated();
1598   int nbTuples=getNumberOfTuples();
1599   int nbOfCompo=getNumberOfComponents();
1600   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1601   ret->alloc(newNbOfTuple,nbOfCompo);
1602   const double *iptr=getConstPointer();
1603   double *optr=ret->getPointer();
1604   for(int i=0;i<nbTuples;i++)
1605     {
1606       int w=old2New[i];
1607       if(w>=0)
1608         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1609     }
1610   ret->copyStringInfoFrom(*this);
1611   return ret.retn();
1612 }
1613
1614 /*!
1615  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1616  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1617  * \a new2OldBg array.
1618  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1619  * This method is equivalent to renumberAndReduce() except that convention in input is
1620  * \c new2old and \b not \c old2new.
1621  * For more info on renumbering see \ref numbering.
1622  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1623  *              tuple index in \a this array to fill the i-th tuple in the new array.
1624  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1625  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1626  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1627  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1628  *          is to delete using decrRef() as it is no more needed.
1629  */
1630 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1631 {
1632   checkAllocated();
1633   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1634   int nbComp=getNumberOfComponents();
1635   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1636   ret->copyStringInfoFrom(*this);
1637   double *pt=ret->getPointer();
1638   const double *srcPt=getConstPointer();
1639   int i=0;
1640   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1641     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1642   ret->copyStringInfoFrom(*this);
1643   return ret.retn();
1644 }
1645
1646 DataArrayDouble *DataArrayDouble::selectByTupleId(const DataArrayInt & di) const
1647 {
1648   return selectByTupleId(di.getConstPointer(), di.getConstPointer()+di.getNumberOfTuples());
1649 }
1650
1651 /*!
1652  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1653  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1654  * \a new2OldBg array.
1655  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1656  * This method is equivalent to renumberAndReduce() except that convention in input is
1657  * \c new2old and \b not \c old2new.
1658  * This method is equivalent to selectByTupleId() except that it prevents coping data
1659  * from behind the end of \a this array.
1660  * For more info on renumbering see \ref numbering.
1661  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1662  *              tuple index in \a this array to fill the i-th tuple in the new array.
1663  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1664  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1665  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1666  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1667  *          is to delete using decrRef() as it is no more needed.
1668  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1669  */
1670 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
1671 {
1672   checkAllocated();
1673   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1674   int nbComp=getNumberOfComponents();
1675   int oldNbOfTuples=getNumberOfTuples();
1676   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1677   ret->copyStringInfoFrom(*this);
1678   double *pt=ret->getPointer();
1679   const double *srcPt=getConstPointer();
1680   int i=0;
1681   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1682     if(*w>=0 && *w<oldNbOfTuples)
1683       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1684     else
1685       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1686   ret->copyStringInfoFrom(*this);
1687   return ret.retn();
1688 }
1689
1690 /*!
1691  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1692  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1693  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1694  * command \c range( \a bg, \a end2, \a step ).
1695  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1696  * not constructed explicitly.
1697  * For more info on renumbering see \ref numbering.
1698  *  \param [in] bg - index of the first tuple to copy from \a this array.
1699  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1700  *  \param [in] step - index increment to get index of the next tuple to copy.
1701  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1702  *          is to delete using decrRef() as it is no more needed.
1703  *  \sa DataArrayDouble::subArray.
1704  */
1705 DataArrayDouble *DataArrayDouble::selectByTupleIdSafeSlice(int bg, int end2, int step) const
1706 {
1707   checkAllocated();
1708   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1709   int nbComp=getNumberOfComponents();
1710   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleIdSafeSlice : ");
1711   ret->alloc(newNbOfTuples,nbComp);
1712   double *pt=ret->getPointer();
1713   const double *srcPt=getConstPointer()+bg*nbComp;
1714   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1715     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1716   ret->copyStringInfoFrom(*this);
1717   return ret.retn();
1718 }
1719
1720 /*!
1721  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1722  * of tuples specified by \a ranges parameter.
1723  * For more info on renumbering see \ref numbering.
1724  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1725  *              of tuples in [\c begin,\c end) format.
1726  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1727  *          is to delete using decrRef() as it is no more needed.
1728  *  \throw If \a end < \a begin.
1729  *  \throw If \a end > \a this->getNumberOfTuples().
1730  *  \throw If \a this is not allocated.
1731  */
1732 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
1733 {
1734   checkAllocated();
1735   int nbOfComp=getNumberOfComponents();
1736   int nbOfTuplesThis=getNumberOfTuples();
1737   if(ranges.empty())
1738     {
1739       DataArrayDouble *ret=DataArrayDouble::New();
1740       ret->alloc(0,nbOfComp);
1741       ret->copyStringInfoFrom(*this);
1742       return ret;
1743     }
1744   int ref=ranges.front().first;
1745   int nbOfTuples=0;
1746   bool isIncreasing=true;
1747   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1748     {
1749       if((*it).first<=(*it).second)
1750         {
1751           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1752             {
1753               nbOfTuples+=(*it).second-(*it).first;
1754               if(isIncreasing)
1755                 isIncreasing=ref<=(*it).first;
1756               ref=(*it).second;
1757             }
1758           else
1759             {
1760               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1761               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1762               throw INTERP_KERNEL::Exception(oss.str().c_str());
1763             }
1764         }
1765       else
1766         {
1767           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1768           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1769           throw INTERP_KERNEL::Exception(oss.str().c_str());
1770         }
1771     }
1772   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1773     return deepCopy();
1774   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1775   ret->alloc(nbOfTuples,nbOfComp);
1776   ret->copyStringInfoFrom(*this);
1777   const double *src=getConstPointer();
1778   double *work=ret->getPointer();
1779   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1780     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1781   return ret.retn();
1782 }
1783
1784 /*!
1785  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1786  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1787  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1788  * This method is a specialization of selectByTupleIdSafeSlice().
1789  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1790  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1791  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1792  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1793  *          is to delete using decrRef() as it is no more needed.
1794  *  \throw If \a tupleIdBg < 0.
1795  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1796     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1797  *  \sa DataArrayDouble::selectByTupleIdSafeSlice
1798  */
1799 DataArrayDouble *DataArrayDouble::subArray(int tupleIdBg, int tupleIdEnd) const
1800 {
1801   checkAllocated();
1802   int nbt=getNumberOfTuples();
1803   if(tupleIdBg<0)
1804     throw INTERP_KERNEL::Exception("DataArrayDouble::subArray : The tupleIdBg parameter must be greater than 0 !");
1805   if(tupleIdBg>nbt)
1806     throw INTERP_KERNEL::Exception("DataArrayDouble::subArray : The tupleIdBg parameter is greater than number of tuples !");
1807   int trueEnd=tupleIdEnd;
1808   if(tupleIdEnd!=-1)
1809     {
1810       if(tupleIdEnd>nbt)
1811         throw INTERP_KERNEL::Exception("DataArrayDouble::subArray : The tupleIdBg parameter is greater or equal than number of tuples !");
1812     }
1813   else
1814     trueEnd=nbt;
1815   int nbComp=getNumberOfComponents();
1816   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1817   ret->alloc(trueEnd-tupleIdBg,nbComp);
1818   ret->copyStringInfoFrom(*this);
1819   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1820   return ret.retn();
1821 }
1822
1823 /*!
1824  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1825  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1826  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1827  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1828  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1829  * components.  
1830  *  \param [in] newNbOfComp - number of components for the new array to have.
1831  *  \param [in] dftValue - value assigned to new values added to the new array.
1832  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1833  *          is to delete using decrRef() as it is no more needed.
1834  *  \throw If \a this is not allocated.
1835  */
1836 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const
1837 {
1838   checkAllocated();
1839   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
1840   ret->alloc(getNumberOfTuples(),newNbOfComp);
1841   const double *oldc=getConstPointer();
1842   double *nc=ret->getPointer();
1843   int nbOfTuples=getNumberOfTuples();
1844   int oldNbOfComp=getNumberOfComponents();
1845   int dim=std::min(oldNbOfComp,newNbOfComp);
1846   for(int i=0;i<nbOfTuples;i++)
1847     {
1848       int j=0;
1849       for(;j<dim;j++)
1850         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1851       for(;j<newNbOfComp;j++)
1852         nc[newNbOfComp*i+j]=dftValue;
1853     }
1854   ret->setName(getName());
1855   for(int i=0;i<dim;i++)
1856     ret->setInfoOnComponent(i,getInfoOnComponent(i));
1857   ret->setName(getName());
1858   return ret.retn();
1859 }
1860
1861 /*!
1862  * Changes the number of components within \a this array so that its raw data **does
1863  * not** change, instead splitting this data into tuples changes.
1864  *  \warning This method erases all (name and unit) component info set before!
1865  *  \param [in] newNbOfComp - number of components for \a this array to have.
1866  *  \throw If \a this is not allocated
1867  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1868  *  \throw If \a newNbOfCompo is lower than 1.
1869  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1870  *  \warning This method erases all (name and unit) component info set before!
1871  */
1872 void DataArrayDouble::rearrange(int newNbOfCompo)
1873 {
1874   checkAllocated();
1875   if(newNbOfCompo<1)
1876     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1877   std::size_t nbOfElems=getNbOfElems();
1878   if(nbOfElems%newNbOfCompo!=0)
1879     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1880   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1881     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1882   _info_on_compo.clear();
1883   _info_on_compo.resize(newNbOfCompo);
1884   declareAsNew();
1885 }
1886
1887 /*!
1888  * Changes the number of components within \a this array to be equal to its number
1889  * of tuples, and inversely its number of tuples to become equal to its number of 
1890  * components. So that its raw data **does not** change, instead splitting this
1891  * data into tuples changes.
1892  *  \warning This method erases all (name and unit) component info set before!
1893  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1894  *  \throw If \a this is not allocated.
1895  *  \sa rearrange()
1896  */
1897 void DataArrayDouble::transpose()
1898 {
1899   checkAllocated();
1900   int nbOfTuples=getNumberOfTuples();
1901   rearrange(nbOfTuples);
1902 }
1903
1904 /*!
1905  * Returns a copy of \a this array composed of selected components.
1906  * The new DataArrayDouble has the same number of tuples but includes components
1907  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1908  * can be either less, same or more than \a this->getNbOfElems().
1909  *  \param [in] compoIds - sequence of zero based indices of components to include
1910  *              into the new array.
1911  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1912  *          is to delete using decrRef() as it is no more needed.
1913  *  \throw If \a this is not allocated.
1914  *  \throw If a component index (\a i) is not valid: 
1915  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1916  *
1917  *  \if ENABLE_EXAMPLES
1918  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1919  *  \endif
1920  */
1921 DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
1922 {
1923   checkAllocated();
1924   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
1925   std::size_t newNbOfCompo=compoIds.size();
1926   int oldNbOfCompo=getNumberOfComponents();
1927   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1928     if((*it)<0 || (*it)>=oldNbOfCompo)
1929       {
1930         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1931         throw INTERP_KERNEL::Exception(oss.str().c_str());
1932       }
1933   int nbOfTuples=getNumberOfTuples();
1934   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1935   ret->copyPartOfStringInfoFrom(*this,compoIds);
1936   const double *oldc=getConstPointer();
1937   double *nc=ret->getPointer();
1938   for(int i=0;i<nbOfTuples;i++)
1939     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1940       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1941   return ret.retn();
1942 }
1943
1944 /*!
1945  * Appends components of another array to components of \a this one, tuple by tuple.
1946  * So that the number of tuples of \a this array remains the same and the number of 
1947  * components increases.
1948  *  \param [in] other - the DataArrayDouble to append to \a this one.
1949  *  \throw If \a this is not allocated.
1950  *  \throw If \a this and \a other arrays have different number of tuples.
1951  *
1952  *  \if ENABLE_EXAMPLES
1953  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1954  *
1955  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1956  *  \endif
1957  */
1958 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1959 {
1960   checkAllocated();
1961   other->checkAllocated();
1962   int nbOfTuples=getNumberOfTuples();
1963   if(nbOfTuples!=other->getNumberOfTuples())
1964     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1965   int nbOfComp1=getNumberOfComponents();
1966   int nbOfComp2=other->getNumberOfComponents();
1967   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1968   double *w=newArr;
1969   const double *inp1=getConstPointer();
1970   const double *inp2=other->getConstPointer();
1971   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1972     {
1973       w=std::copy(inp1,inp1+nbOfComp1,w);
1974       w=std::copy(inp2,inp2+nbOfComp2,w);
1975     }
1976   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1977   std::vector<int> compIds(nbOfComp2);
1978   for(int i=0;i<nbOfComp2;i++)
1979     compIds[i]=nbOfComp1+i;
1980   copyPartOfStringInfoFrom2(compIds,*other);
1981 }
1982
1983 /*!
1984  * This method checks that all tuples in \a other are in \a this.
1985  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1986  * 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.
1987  *
1988  * \param [in] other - the array having the same number of components than \a this.
1989  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1990  * \sa DataArrayDouble::findCommonTuples
1991  */
1992 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1993 {
1994   if(!other)
1995     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1996   checkAllocated(); other->checkAllocated();
1997   if(getNumberOfComponents()!=other->getNumberOfComponents())
1998     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1999   MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
2000   DataArrayInt *c=0,*ci=0;
2001   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
2002   MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
2003   int newNbOfTuples=-1;
2004   MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
2005   MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
2006   tupleIds=ret1.retn();
2007   return newNbOfTuples==getNumberOfTuples();
2008 }
2009
2010 /*!
2011  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
2012  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
2013  * distance separating two points is computed with the infinite norm.
2014  *
2015  * Indices of coincident tuples are stored in output arrays.
2016  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
2017  *
2018  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
2019  * MEDCouplingUMesh::mergeNodes().
2020  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
2021  *              considered not coincident.
2022  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2023  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
2024  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
2025  *               \a comm->getNumberOfComponents() == 1. 
2026  *               \a comm->getNumberOfTuples() == \a commIndex->back().
2027  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
2028  *               groups of (indices of) coincident tuples. Its every value is a tuple
2029  *               index where a next group of tuples begins. For example the second
2030  *               group of tuples in \a comm is described by following range of indices:
2031  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
2032  *               gives the number of groups of coincident tuples.
2033  *  \throw If \a this is not allocated.
2034  *  \throw If the number of components is not in [1,2,3,4].
2035  *
2036  *  \if ENABLE_EXAMPLES
2037  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
2038  *
2039  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
2040  *  \endif
2041  *  \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
2042  */
2043 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
2044 {
2045   checkAllocated();
2046   int nbOfCompo=getNumberOfComponents();
2047   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
2048     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
2049
2050   int nbOfTuples=getNumberOfTuples();
2051   //
2052   MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
2053   switch(nbOfCompo)
2054   {
2055     case 4:
2056       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2057       break;
2058     case 3:
2059       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2060       break;
2061     case 2:
2062       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2063       break;
2064     case 1:
2065       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2066       break;
2067     default:
2068       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
2069   }
2070   comm=c.retn();
2071   commIndex=cI.retn();
2072 }
2073
2074 /*!
2075  * 
2076  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
2077  *             \a nbTimes  should be at least equal to 1.
2078  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
2079  * \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.
2080  */
2081 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
2082 {
2083   checkAllocated();
2084   if(getNumberOfComponents()!=1)
2085     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
2086   if(nbTimes<1)
2087     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
2088   int nbTuples=getNumberOfTuples();
2089   const double *inPtr=getConstPointer();
2090   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
2091   double *retPtr=ret->getPointer();
2092   for(int i=0;i<nbTuples;i++,inPtr++)
2093     {
2094       double val=*inPtr;
2095       for(int j=0;j<nbTimes;j++,retPtr++)
2096         *retPtr=val;
2097     }
2098   ret->copyStringInfoFrom(*this);
2099   return ret.retn();
2100 }
2101
2102 /*!
2103  * This methods returns the minimal distance between the two set of points \a this and \a other.
2104  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2105  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2106  *
2107  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2108  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2109  * \return the minimal distance between the two set of points \a this and \a other.
2110  * \sa DataArrayDouble::findClosestTupleId
2111  */
2112 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
2113 {
2114   MCAuto<DataArrayInt> part1=findClosestTupleId(other);
2115   int nbOfCompo(getNumberOfComponents());
2116   int otherNbTuples(other->getNumberOfTuples());
2117   const double *thisPt(begin()),*otherPt(other->begin());
2118   const int *part1Pt(part1->begin());
2119   double ret=std::numeric_limits<double>::max();
2120   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2121     {
2122       double tmp(0.);
2123       for(int j=0;j<nbOfCompo;j++)
2124         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2125       if(tmp<ret)
2126         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2127     }
2128   return sqrt(ret);
2129 }
2130
2131 /*!
2132  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2133  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2134  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2135  *
2136  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2137  * \sa DataArrayDouble::minimalDistanceTo
2138  */
2139 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
2140 {
2141   if(!other)
2142     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2143   checkAllocated(); other->checkAllocated();
2144   int nbOfCompo=getNumberOfComponents();
2145   if(nbOfCompo!=other->getNumberOfComponents())
2146     {
2147       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2148       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2149       throw INTERP_KERNEL::Exception(oss.str().c_str());
2150     }
2151   int nbOfTuples=other->getNumberOfTuples();
2152   int thisNbOfTuples=getNumberOfTuples();
2153   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2154   double bounds[6];
2155   getMinMaxPerComponent(bounds);
2156   switch(nbOfCompo)
2157   {
2158     case 3:
2159       {
2160         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2161         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2162         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2163         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2164         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2165         break;
2166       }
2167     case 2:
2168       {
2169         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2170         double delta=std::max(xDelta,yDelta);
2171         double characSize=sqrt(delta/(double)thisNbOfTuples);
2172         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2173         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2174         break;
2175       }
2176     case 1:
2177       {
2178         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2179         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2180         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2181         break;
2182       }
2183     default:
2184       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2185   }
2186   return ret.retn();
2187 }
2188
2189 /*!
2190  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
2191  * 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
2192  * how many bounding boxes in \a otherBBoxFrmt.
2193  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
2194  *
2195  * \param [in] otherBBoxFrmt - It is an array .
2196  * \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.
2197  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
2198  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
2199  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
2200  */
2201 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
2202 {
2203   if(!otherBBoxFrmt)
2204     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
2205   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
2206     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
2207   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
2208   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
2209     {
2210       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
2211       throw INTERP_KERNEL::Exception(oss.str().c_str());
2212     }
2213   if(nbOfComp%2!=0)
2214     {
2215       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
2216       throw INTERP_KERNEL::Exception(oss.str().c_str());
2217     }
2218   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
2219   const double *thisBBPtr(begin());
2220   int *retPtr(ret->getPointer());
2221   switch(nbOfComp/2)
2222   {
2223     case 3:
2224       {
2225         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2226         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2227           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2228         break;
2229       }
2230     case 2:
2231       {
2232         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2233         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2234           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2235         break;
2236       }
2237     case 1:
2238       {
2239         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2240         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2241           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2242         break;
2243       }
2244     default:
2245       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
2246   }
2247
2248   return ret.retn();
2249 }
2250
2251 /*!
2252  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2253  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2254  * space. The distance between tuples is computed using norm2. If several tuples are
2255  * not far each from other than \a prec, only one of them remains in the result
2256  * array. The order of tuples in the result array is same as in \a this one except
2257  * that coincident tuples are excluded.
2258  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2259  *              considered not coincident.
2260  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2261  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2262  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2263  *          is to delete using decrRef() as it is no more needed.
2264  *  \throw If \a this is not allocated.
2265  *  \throw If the number of components is not in [1,2,3,4].
2266  *
2267  *  \if ENABLE_EXAMPLES
2268  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2269  *  \endif
2270  */
2271 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
2272 {
2273   checkAllocated();
2274   DataArrayInt *c0=0,*cI0=0;
2275   findCommonTuples(prec,limitTupleId,c0,cI0);
2276   MCAuto<DataArrayInt> c(c0),cI(cI0);
2277   int newNbOfTuples=-1;
2278   MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2279   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2280 }
2281
2282 /*!
2283  * Copy all components in a specified order from another DataArrayDouble.
2284  * Both numerical and textual data is copied. The number of tuples in \a this and
2285  * the other array can be different.
2286  *  \param [in] a - the array to copy data from.
2287  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2288  *              to be copied.
2289  *  \throw If \a a is NULL.
2290  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2291  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2292  *
2293  *  \if ENABLE_EXAMPLES
2294  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2295  *  \endif
2296  */
2297 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
2298 {
2299   if(!a)
2300     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2301   checkAllocated();
2302   copyPartOfStringInfoFrom2(compoIds,*a);
2303   std::size_t partOfCompoSz=compoIds.size();
2304   int nbOfCompo=getNumberOfComponents();
2305   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2306   const double *ac=a->getConstPointer();
2307   double *nc=getPointer();
2308   for(int i=0;i<nbOfTuples;i++)
2309     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2310       nc[nbOfCompo*i+compoIds[j]]=*ac;
2311 }
2312
2313 /*!
2314  * Copy all values from another DataArrayDouble into specified tuples and components
2315  * of \a this array. Textual data is not copied.
2316  * The tree parameters defining set of indices of tuples and components are similar to
2317  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2318  *  \param [in] a - the array to copy values from.
2319  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2320  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2321  *              are located.
2322  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2323  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2324  *  \param [in] endComp - index of the component before which the components to assign
2325  *              to are located.
2326  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2327  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2328  *              must be equal to the number of columns to assign to, else an
2329  *              exception is thrown; if \a false, then it is only required that \a
2330  *              a->getNbOfElems() equals to number of values to assign to (this condition
2331  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2332  *              values to assign to is given by following Python expression:
2333  *              \a nbTargetValues = 
2334  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2335  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2336  *  \throw If \a a is NULL.
2337  *  \throw If \a a is not allocated.
2338  *  \throw If \a this is not allocated.
2339  *  \throw If parameters specifying tuples and components to assign to do not give a
2340  *            non-empty range of increasing indices.
2341  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2342  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2343  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2344  *
2345  *  \if ENABLE_EXAMPLES
2346  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2347  *  \endif
2348  */
2349 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2350 {
2351   if(!a)
2352     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2353   const char msg[]="DataArrayDouble::setPartOfValues1";
2354   checkAllocated();
2355   a->checkAllocated();
2356   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2357   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2358   int nbComp=getNumberOfComponents();
2359   int nbOfTuples=getNumberOfTuples();
2360   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2361   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2362   bool assignTech=true;
2363   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2364     {
2365       if(strictCompoCompare)
2366         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2367     }
2368   else
2369     {
2370       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2371       assignTech=false;
2372     }
2373   const double *srcPt=a->getConstPointer();
2374   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2375   if(assignTech)
2376     {
2377       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2378         for(int j=0;j<newNbOfComp;j++,srcPt++)
2379           pt[j*stepComp]=*srcPt;
2380     }
2381   else
2382     {
2383       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2384         {
2385           const double *srcPt2=srcPt;
2386           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2387             pt[j*stepComp]=*srcPt2;
2388         }
2389     }
2390 }
2391
2392 /*!
2393  * Assign a given value to values at specified tuples and components of \a this array.
2394  * The tree parameters defining set of indices of tuples and components are similar to
2395  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2396  *  \param [in] a - the value to assign.
2397  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2398  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2399  *              are located.
2400  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2401  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2402  *  \param [in] endComp - index of the component before which the components to assign
2403  *              to are located.
2404  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2405  *  \throw If \a this is not allocated.
2406  *  \throw If parameters specifying tuples and components to assign to, do not give a
2407  *            non-empty range of increasing indices or indices are out of a valid range
2408  *            for \c this array.
2409  *
2410  *  \if ENABLE_EXAMPLES
2411  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2412  *  \endif
2413  */
2414 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
2415 {
2416   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2417   checkAllocated();
2418   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2419   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2420   int nbComp=getNumberOfComponents();
2421   int nbOfTuples=getNumberOfTuples();
2422   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2423   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2424   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2425   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2426     for(int j=0;j<newNbOfComp;j++)
2427       pt[j*stepComp]=a;
2428 }
2429
2430 /*!
2431  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2432  * components of \a this array. Textual data is not copied.
2433  * The tuples and components to assign to are defined by C arrays of indices.
2434  * There are two *modes of usage*:
2435  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2436  *   of \a a is assigned to its own location within \a this array. 
2437  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2438  *   components of every specified tuple of \a this array. In this mode it is required
2439  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2440  *
2441  *  \param [in] a - the array to copy values from.
2442  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2443  *              assign values of \a a to.
2444  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2445  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2446  *              \a bgTuples <= \a pi < \a endTuples.
2447  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2448  *              assign values of \a a to.
2449  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2450  *              pointer to a component index <em>(pi)</em> varies as this: 
2451  *              \a bgComp <= \a pi < \a endComp.
2452  *  \param [in] strictCompoCompare - this parameter is checked only if the
2453  *               *mode of usage* is the first; if it is \a true (default), 
2454  *               then \a a->getNumberOfComponents() must be equal 
2455  *               to the number of specified columns, else this is not required.
2456  *  \throw If \a a is NULL.
2457  *  \throw If \a a is not allocated.
2458  *  \throw If \a this is not allocated.
2459  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2460  *         out of a valid range for \a this array.
2461  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2462  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2463  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2464  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2465  *
2466  *  \if ENABLE_EXAMPLES
2467  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2468  *  \endif
2469  */
2470 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2471 {
2472   if(!a)
2473     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2474   const char msg[]="DataArrayDouble::setPartOfValues2";
2475   checkAllocated();
2476   a->checkAllocated();
2477   int nbComp=getNumberOfComponents();
2478   int nbOfTuples=getNumberOfTuples();
2479   for(const int *z=bgComp;z!=endComp;z++)
2480     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2481   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2482   int newNbOfComp=(int)std::distance(bgComp,endComp);
2483   bool assignTech=true;
2484   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2485     {
2486       if(strictCompoCompare)
2487         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2488     }
2489   else
2490     {
2491       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2492       assignTech=false;
2493     }
2494   double *pt=getPointer();
2495   const double *srcPt=a->getConstPointer();
2496   if(assignTech)
2497     {    
2498       for(const int *w=bgTuples;w!=endTuples;w++)
2499         {
2500           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2501           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2502             {    
2503               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2504             }
2505         }
2506     }
2507   else
2508     {
2509       for(const int *w=bgTuples;w!=endTuples;w++)
2510         {
2511           const double *srcPt2=srcPt;
2512           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2513           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2514             {    
2515               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2516             }
2517         }
2518     }
2519 }
2520
2521 /*!
2522  * Assign a given value to values at specified tuples and components of \a this array.
2523  * The tuples and components to assign to are defined by C arrays of indices.
2524  *  \param [in] a - the value to assign.
2525  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2526  *              assign \a a to.
2527  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2528  *              pointer to a tuple index (\a pi) varies as this: 
2529  *              \a bgTuples <= \a pi < \a endTuples.
2530  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2531  *              assign \a a to.
2532  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2533  *              pointer to a component index (\a pi) varies as this: 
2534  *              \a bgComp <= \a pi < \a endComp.
2535  *  \throw If \a this is not allocated.
2536  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2537  *         out of a valid range for \a this array.
2538  *
2539  *  \if ENABLE_EXAMPLES
2540  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2541  *  \endif
2542  */
2543 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
2544 {
2545   checkAllocated();
2546   int nbComp=getNumberOfComponents();
2547   int nbOfTuples=getNumberOfTuples();
2548   for(const int *z=bgComp;z!=endComp;z++)
2549     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2550   double *pt=getPointer();
2551   for(const int *w=bgTuples;w!=endTuples;w++)
2552     for(const int *z=bgComp;z!=endComp;z++)
2553       {
2554         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2555         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2556       }
2557 }
2558
2559 /*!
2560  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2561  * components of \a this array. Textual data is not copied.
2562  * The tuples to assign to are defined by a C array of indices.
2563  * The components to assign to are defined by three values similar to parameters of
2564  * the Python function \c range(\c start,\c stop,\c step).
2565  * There are two *modes of usage*:
2566  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2567  *   of \a a is assigned to its own location within \a this array. 
2568  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2569  *   components of every specified tuple of \a this array. In this mode it is required
2570  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2571  *
2572  *  \param [in] a - the array to copy values from.
2573  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2574  *              assign values of \a a to.
2575  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2576  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2577  *              \a bgTuples <= \a pi < \a endTuples.
2578  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2579  *  \param [in] endComp - index of the component before which the components to assign
2580  *              to are located.
2581  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2582  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2583  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2584  *               then \a a->getNumberOfComponents() must be equal 
2585  *               to the number of specified columns, else this is not required.
2586  *  \throw If \a a is NULL.
2587  *  \throw If \a a is not allocated.
2588  *  \throw If \a this is not allocated.
2589  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2590  *         \a this array.
2591  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2592  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2593  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2594  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2595  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2596  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2597  *  \throw If parameters specifying components to assign to, do not give a
2598  *            non-empty range of increasing indices or indices are out of a valid range
2599  *            for \c this array.
2600  *
2601  *  \if ENABLE_EXAMPLES
2602  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2603  *  \endif
2604  */
2605 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2606 {
2607   if(!a)
2608     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2609   const char msg[]="DataArrayDouble::setPartOfValues3";
2610   checkAllocated();
2611   a->checkAllocated();
2612   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2613   int nbComp=getNumberOfComponents();
2614   int nbOfTuples=getNumberOfTuples();
2615   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2616   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2617   bool assignTech=true;
2618   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2619     {
2620       if(strictCompoCompare)
2621         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2622     }
2623   else
2624     {
2625       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2626       assignTech=false;
2627     }
2628   double *pt=getPointer()+bgComp;
2629   const double *srcPt=a->getConstPointer();
2630   if(assignTech)
2631     {
2632       for(const int *w=bgTuples;w!=endTuples;w++)
2633         for(int j=0;j<newNbOfComp;j++,srcPt++)
2634           {
2635             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2636             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2637           }
2638     }
2639   else
2640     {
2641       for(const int *w=bgTuples;w!=endTuples;w++)
2642         {
2643           const double *srcPt2=srcPt;
2644           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2645             {
2646               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2647               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2648             }
2649         }
2650     }
2651 }
2652
2653 /*!
2654  * Assign a given value to values at specified tuples and components of \a this array.
2655  * The tuples to assign to are defined by a C array of indices.
2656  * The components to assign to are defined by three values similar to parameters of
2657  * the Python function \c range(\c start,\c stop,\c step).
2658  *  \param [in] a - the value to assign.
2659  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2660  *              assign \a a to.
2661  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2662  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2663  *              \a bgTuples <= \a pi < \a endTuples.
2664  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2665  *  \param [in] endComp - index of the component before which the components to assign
2666  *              to are located.
2667  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2668  *  \throw If \a this is not allocated.
2669  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2670  *         \a this array.
2671  *  \throw If parameters specifying components to assign to, do not give a
2672  *            non-empty range of increasing indices or indices are out of a valid range
2673  *            for \c this array.
2674  *
2675  *  \if ENABLE_EXAMPLES
2676  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2677  *  \endif
2678  */
2679 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
2680 {
2681   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2682   checkAllocated();
2683   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2684   int nbComp=getNumberOfComponents();
2685   int nbOfTuples=getNumberOfTuples();
2686   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2687   double *pt=getPointer()+bgComp;
2688   for(const int *w=bgTuples;w!=endTuples;w++)
2689     for(int j=0;j<newNbOfComp;j++)
2690       {
2691         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2692         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2693       }
2694 }
2695
2696 /*!
2697  * Copy all values from another DataArrayDouble into specified tuples and components
2698  * of \a this array. Textual data is not copied.
2699  * The tree parameters defining set of indices of tuples and components are similar to
2700  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2701  *  \param [in] a - the array to copy values from.
2702  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2703  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2704  *              are located.
2705  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2706  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2707  *              assign \a a to.
2708  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2709  *              pointer to a component index (\a pi) varies as this: 
2710  *              \a bgComp <= \a pi < \a endComp.
2711  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2712  *              must be equal to the number of columns to assign to, else an
2713  *              exception is thrown; if \a false, then it is only required that \a
2714  *              a->getNbOfElems() equals to number of values to assign to (this condition
2715  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2716  *              values to assign to is given by following Python expression:
2717  *              \a nbTargetValues = 
2718  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2719  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2720  *  \throw If \a a is NULL.
2721  *  \throw If \a a is not allocated.
2722  *  \throw If \a this is not allocated.
2723  *  \throw If parameters specifying tuples and components to assign to do not give a
2724  *            non-empty range of increasing indices.
2725  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2726  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2727  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2728  *
2729  */
2730 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2731 {
2732   if(!a)
2733     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2734   const char msg[]="DataArrayDouble::setPartOfValues4";
2735   checkAllocated();
2736   a->checkAllocated();
2737   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2738   int newNbOfComp=(int)std::distance(bgComp,endComp);
2739   int nbComp=getNumberOfComponents();
2740   for(const int *z=bgComp;z!=endComp;z++)
2741     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2742   int nbOfTuples=getNumberOfTuples();
2743   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2744   bool assignTech=true;
2745   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2746     {
2747       if(strictCompoCompare)
2748         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2749     }
2750   else
2751     {
2752       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2753       assignTech=false;
2754     }
2755   const double *srcPt=a->getConstPointer();
2756   double *pt=getPointer()+bgTuples*nbComp;
2757   if(assignTech)
2758     {
2759       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2760         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2761           pt[*z]=*srcPt;
2762     }
2763   else
2764     {
2765       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2766         {
2767           const double *srcPt2=srcPt;
2768           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2769             pt[*z]=*srcPt2;
2770         }
2771     }
2772 }
2773
2774 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
2775 {
2776   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2777   checkAllocated();
2778   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2779   int nbComp=getNumberOfComponents();
2780   for(const int *z=bgComp;z!=endComp;z++)
2781     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2782   int nbOfTuples=getNumberOfTuples();
2783   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2784   double *pt=getPointer()+bgTuples*nbComp;
2785   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2786     for(const int *z=bgComp;z!=endComp;z++)
2787       pt[*z]=a;
2788 }
2789
2790 /*!
2791  * Copy some tuples from another DataArrayDouble into specified tuples
2792  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2793  * components.
2794  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2795  * All components of selected tuples are copied.
2796  *  \param [in] a - the array to copy values from.
2797  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2798  *              target tuples of \a this. \a tuplesSelec has two components, and the
2799  *              first component specifies index of the source tuple and the second
2800  *              one specifies index of the target tuple.
2801  *  \throw If \a this is not allocated.
2802  *  \throw If \a a is NULL.
2803  *  \throw If \a a is not allocated.
2804  *  \throw If \a tuplesSelec is NULL.
2805  *  \throw If \a tuplesSelec is not allocated.
2806  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2807  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2808  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2809  *         the corresponding (\a this or \a a) array.
2810  */
2811 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec)
2812 {
2813   if(!a || !tuplesSelec)
2814     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2815   checkAllocated();
2816   a->checkAllocated();
2817   tuplesSelec->checkAllocated();
2818   int nbOfComp=getNumberOfComponents();
2819   if(nbOfComp!=a->getNumberOfComponents())
2820     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2821   if(tuplesSelec->getNumberOfComponents()!=2)
2822     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2823   int thisNt=getNumberOfTuples();
2824   int aNt=a->getNumberOfTuples();
2825   double *valsToSet=getPointer();
2826   const double *valsSrc=a->getConstPointer();
2827   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2828     {
2829       if(tuple[1]>=0 && tuple[1]<aNt)
2830         {
2831           if(tuple[0]>=0 && tuple[0]<thisNt)
2832             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2833           else
2834             {
2835               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2836               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2837               throw INTERP_KERNEL::Exception(oss.str().c_str());
2838             }
2839         }
2840       else
2841         {
2842           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2843           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2844           throw INTERP_KERNEL::Exception(oss.str().c_str());
2845         }
2846     }
2847 }
2848
2849 /*!
2850  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2851  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2852  * components.
2853  * The tuples to assign to are defined by index of the first tuple, and
2854  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2855  * The tuples to copy are defined by values of a DataArrayInt.
2856  * All components of selected tuples are copied.
2857  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2858  *              values to.
2859  *  \param [in] aBase - the array to copy values from.
2860  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2861  *  \throw If \a this is not allocated.
2862  *  \throw If \a aBase is NULL.
2863  *  \throw If \a aBase is not allocated.
2864  *  \throw If \a tuplesSelec is NULL.
2865  *  \throw If \a tuplesSelec is not allocated.
2866  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2867  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2868  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2869  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2870  *         \a aBase array.
2871  */
2872 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
2873 {
2874   if(!aBase || !tuplesSelec)
2875     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2876   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2877   if(!a)
2878     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2879   checkAllocated();
2880   a->checkAllocated();
2881   tuplesSelec->checkAllocated();
2882   int nbOfComp=getNumberOfComponents();
2883   if(nbOfComp!=a->getNumberOfComponents())
2884     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2885   if(tuplesSelec->getNumberOfComponents()!=1)
2886     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2887   int thisNt=getNumberOfTuples();
2888   int aNt=a->getNumberOfTuples();
2889   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2890   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2891   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2892     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2893   const double *valsSrc=a->getConstPointer();
2894   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2895     {
2896       if(*tuple>=0 && *tuple<aNt)
2897         {
2898           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2899         }
2900       else
2901         {
2902           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2903           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2904           throw INTERP_KERNEL::Exception(oss.str().c_str());
2905         }
2906     }
2907 }
2908
2909 /*!
2910  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2911  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2912  * components.
2913  * The tuples to copy are defined by three values similar to parameters of
2914  * the Python function \c range(\c start,\c stop,\c step).
2915  * The tuples to assign to are defined by index of the first tuple, and
2916  * their number is defined by number of tuples to copy.
2917  * All components of selected tuples are copied.
2918  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2919  *              values to.
2920  *  \param [in] aBase - the array to copy values from.
2921  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2922  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2923  *              are located.
2924  *  \param [in] step - index increment to get index of the next tuple to copy.
2925  *  \throw If \a this is not allocated.
2926  *  \throw If \a aBase is NULL.
2927  *  \throw If \a aBase is not allocated.
2928  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2929  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2930  *  \throw If parameters specifying tuples to copy, do not give a
2931  *            non-empty range of increasing indices or indices are out of a valid range
2932  *            for the array \a aBase.
2933  */
2934 void DataArrayDouble::setContigPartOfSelectedValuesSlice(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
2935 {
2936   if(!aBase)
2937     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValuesSlice : input DataArray is NULL !");
2938   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2939   if(!a)
2940     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValuesSlice : input DataArray aBase is not a DataArrayDouble !");
2941   checkAllocated();
2942   a->checkAllocated();
2943   int nbOfComp=getNumberOfComponents();
2944   const char msg[]="DataArrayDouble::setContigPartOfSelectedValuesSlice";
2945   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2946   if(nbOfComp!=a->getNumberOfComponents())
2947     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValuesSlice : This and a do not have the same number of components !");
2948   int thisNt=getNumberOfTuples();
2949   int aNt=a->getNumberOfTuples();
2950   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2951   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2952     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValuesSlice : invalid number range of values to write !");
2953   if(end2>aNt)
2954     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValuesSlice : invalid range of values to read !");
2955   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2956   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2957     {
2958       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2959     }
2960 }
2961
2962 /*!
2963  * Returns a value located at specified tuple and component.
2964  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2965  * parameters is checked. So this method is safe but expensive if used to go through
2966  * all values of \a this.
2967  *  \param [in] tupleId - index of tuple of interest.
2968  *  \param [in] compoId - index of component of interest.
2969  *  \return double - value located by \a tupleId and \a compoId.
2970  *  \throw If \a this is not allocated.
2971  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2972  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2973  */
2974 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const
2975 {
2976   checkAllocated();
2977   if(tupleId<0 || tupleId>=getNumberOfTuples())
2978     {
2979       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2980       throw INTERP_KERNEL::Exception(oss.str().c_str());
2981     }
2982   if(compoId<0 || compoId>=getNumberOfComponents())
2983     {
2984       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2985       throw INTERP_KERNEL::Exception(oss.str().c_str());
2986     }
2987   return _mem[tupleId*_info_on_compo.size()+compoId];
2988 }
2989
2990 /*!
2991  * Returns the first value of \a this. 
2992  *  \return double - the last value of \a this array.
2993  *  \throw If \a this is not allocated.
2994  *  \throw If \a this->getNumberOfComponents() != 1.
2995  *  \throw If \a this->getNumberOfTuples() < 1.
2996  */
2997 double DataArrayDouble::front() const
2998 {
2999   checkAllocated();
3000   if(getNumberOfComponents()!=1)
3001     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
3002   int nbOfTuples=getNumberOfTuples();
3003   if(nbOfTuples<1)
3004     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
3005   return *(getConstPointer());
3006 }
3007
3008 /*!
3009  * Returns the last value of \a this. 
3010  *  \return double - the last value of \a this array.
3011  *  \throw If \a this is not allocated.
3012  *  \throw If \a this->getNumberOfComponents() != 1.
3013  *  \throw If \a this->getNumberOfTuples() < 1.
3014  */
3015 double DataArrayDouble::back() const
3016 {
3017   checkAllocated();
3018   if(getNumberOfComponents()!=1)
3019     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
3020   int nbOfTuples=getNumberOfTuples();
3021   if(nbOfTuples<1)
3022     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
3023   return *(getConstPointer()+nbOfTuples-1);
3024 }
3025
3026 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
3027 {
3028   if(newArray!=arrayToSet)
3029     {
3030       if(arrayToSet)
3031         arrayToSet->decrRef();
3032       arrayToSet=newArray;
3033       if(arrayToSet)
3034         arrayToSet->incrRef();
3035     }
3036 }
3037
3038 /*!
3039  * Sets a C array to be used as raw data of \a this. The previously set info
3040  *  of components is retained and re-sized. 
3041  * For more info see \ref MEDCouplingArraySteps1.
3042  *  \param [in] array - the C array to be used as raw data of \a this.
3043  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
3044  *  \param [in] type - specifies how to deallocate \a array. If \a type == MEDCoupling::CPP_DEALLOC,
3045  *                     \c delete [] \c array; will be called. If \a type == MEDCoupling::C_DEALLOC,
3046  *                     \c free(\c array ) will be called.
3047  *  \param [in] nbOfTuple - new number of tuples in \a this.
3048  *  \param [in] nbOfCompo - new number of components in \a this.
3049  */
3050 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
3051 {
3052   _info_on_compo.resize(nbOfCompo);
3053   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
3054   declareAsNew();
3055 }
3056
3057 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo)
3058 {
3059   _info_on_compo.resize(nbOfCompo);
3060   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
3061   declareAsNew();
3062 }
3063
3064 /*!
3065  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
3066  * is thrown.
3067  * \throw If zero is found in \a this array.
3068  */
3069 void DataArrayDouble::checkNoNullValues() const
3070 {
3071   const double *tmp=getConstPointer();
3072   std::size_t nbOfElems=getNbOfElems();
3073   const double *where=std::find(tmp,tmp+nbOfElems,0.);
3074   if(where!=tmp+nbOfElems)
3075     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
3076 }
3077
3078 /*!
3079  * Computes minimal and maximal value in each component. An output array is filled
3080  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
3081  * enough memory before calling this method.
3082  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
3083  *               It is filled as follows:<br>
3084  *               \a bounds[0] = \c min_of_component_0 <br>
3085  *               \a bounds[1] = \c max_of_component_0 <br>
3086  *               \a bounds[2] = \c min_of_component_1 <br>
3087  *               \a bounds[3] = \c max_of_component_1 <br>
3088  *               ...
3089  */
3090 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
3091 {
3092   checkAllocated();
3093   int dim=getNumberOfComponents();
3094   for (int idim=0; idim<dim; idim++)
3095     {
3096       bounds[idim*2]=std::numeric_limits<double>::max();
3097       bounds[idim*2+1]=-std::numeric_limits<double>::max();
3098     } 
3099   const double *ptr=getConstPointer();
3100   int nbOfTuples=getNumberOfTuples();
3101   for(int i=0;i<nbOfTuples;i++)
3102     {
3103       for(int idim=0;idim<dim;idim++)
3104         {
3105           if(bounds[idim*2]>ptr[i*dim+idim])
3106             {
3107               bounds[idim*2]=ptr[i*dim+idim];
3108             }
3109           if(bounds[idim*2+1]<ptr[i*dim+idim])
3110             {
3111               bounds[idim*2+1]=ptr[i*dim+idim];
3112             }
3113         }
3114     }
3115 }
3116
3117 /*!
3118  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3119  * to store both the min and max per component of each tuples. 
3120  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3121  *
3122  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3123  *
3124  * \throw If \a this is not allocated yet.
3125  */
3126 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
3127 {
3128   checkAllocated();
3129   const double *dataPtr=getConstPointer();
3130   int nbOfCompo=getNumberOfComponents();
3131   int nbTuples=getNumberOfTuples();
3132   MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
3133   bbox->alloc(nbTuples,2*nbOfCompo);
3134   double *bboxPtr=bbox->getPointer();
3135   for(int i=0;i<nbTuples;i++)
3136     {
3137       for(int j=0;j<nbOfCompo;j++)
3138         {
3139           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3140           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3141         }
3142     }
3143   return bbox.retn();
3144 }
3145
3146 /*!
3147  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3148  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3149  * 
3150  * \param [in] other a DataArrayDouble having same number of components than \a this.
3151  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3152  * \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.
3153  *             \a cI allows to extract information in \a c.
3154  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3155  *
3156  * \throw In case of:
3157  *  - \a this is not allocated
3158  *  - \a other is not allocated or null
3159  *  - \a this and \a other do not have the same number of components
3160  *  - if number of components of \a this is not in [1,2,3]
3161  *
3162  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3163  */
3164 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
3165 {
3166   if(!other)
3167     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3168   checkAllocated();
3169   other->checkAllocated();
3170   int nbOfCompo=getNumberOfComponents();
3171   int otherNbOfCompo=other->getNumberOfComponents();
3172   if(nbOfCompo!=otherNbOfCompo)
3173     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3174   int nbOfTuplesOther=other->getNumberOfTuples();
3175   MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3176   switch(nbOfCompo)
3177   {
3178     case 3:
3179       {
3180         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3181         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3182         break;
3183       }
3184     case 2:
3185       {
3186         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3187         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3188         break;
3189       }
3190     case 1:
3191       {
3192         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3193         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3194         break;
3195       }
3196     default:
3197       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3198   }
3199   c=cArr.retn(); cI=cIArr.retn();
3200 }
3201
3202 /*!
3203  * 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
3204  * around origin of 'radius' 1.
3205  * 
3206  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3207  */
3208 void DataArrayDouble::recenterForMaxPrecision(double eps)
3209 {
3210   checkAllocated();
3211   int dim=getNumberOfComponents();
3212   std::vector<double> bounds(2*dim);
3213   getMinMaxPerComponent(&bounds[0]);
3214   for(int i=0;i<dim;i++)
3215     {
3216       double delta=bounds[2*i+1]-bounds[2*i];
3217       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3218       if(delta>eps)
3219         applyLin(1./delta,-offset/delta,i);
3220       else
3221         applyLin(1.,-offset,i);
3222     }
3223 }
3224
3225 /*!
3226  * Returns the maximal value and its location within \a this one-dimensional array.
3227  *  \param [out] tupleId - index of the tuple holding the maximal value.
3228  *  \return double - the maximal value among all values of \a this array.
3229  *  \throw If \a this->getNumberOfComponents() != 1
3230  *  \throw If \a this->getNumberOfTuples() < 1
3231  */
3232 double DataArrayDouble::getMaxValue(int& tupleId) const
3233 {
3234   checkAllocated();
3235   if(getNumberOfComponents()!=1)
3236     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before or call 'getMaxValueInArray' method !");
3237   int nbOfTuples=getNumberOfTuples();
3238   if(nbOfTuples<=0)
3239     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3240   const double *vals=getConstPointer();
3241   const double *loc=std::max_element(vals,vals+nbOfTuples);
3242   tupleId=(int)std::distance(vals,loc);
3243   return *loc;
3244 }
3245
3246 /*!
3247  * Returns the maximal value within \a this array that is allowed to have more than
3248  *  one component.
3249  *  \return double - the maximal value among all values of \a this array.
3250  *  \throw If \a this is not allocated.
3251  */
3252 double DataArrayDouble::getMaxValueInArray() const
3253 {
3254   checkAllocated();
3255   const double *loc=std::max_element(begin(),end());
3256   return *loc;
3257 }
3258
3259 /*!
3260  * Returns the maximal value and all its locations within \a this one-dimensional array.
3261  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3262  *               tuples holding the maximal value. The caller is to delete it using
3263  *               decrRef() as it is no more needed.
3264  *  \return double - the maximal value among all values of \a this array.
3265  *  \throw If \a this->getNumberOfComponents() != 1
3266  *  \throw If \a this->getNumberOfTuples() < 1
3267  */
3268 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
3269 {
3270   int tmp;
3271   tupleIds=0;
3272   double ret=getMaxValue(tmp);
3273   tupleIds=findIdsInRange(ret,ret);
3274   return ret;
3275 }
3276
3277 /*!
3278  * Returns the minimal value and its location within \a this one-dimensional array.
3279  *  \param [out] tupleId - index of the tuple holding the minimal value.
3280  *  \return double - the minimal value among all values of \a this array.
3281  *  \throw If \a this->getNumberOfComponents() != 1
3282  *  \throw If \a this->getNumberOfTuples() < 1
3283  */
3284 double DataArrayDouble::getMinValue(int& tupleId) const
3285 {
3286   checkAllocated();
3287   if(getNumberOfComponents()!=1)
3288     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3289   int nbOfTuples=getNumberOfTuples();
3290   if(nbOfTuples<=0)
3291     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3292   const double *vals=getConstPointer();
3293   const double *loc=std::min_element(vals,vals+nbOfTuples);
3294   tupleId=(int)std::distance(vals,loc);
3295   return *loc;
3296 }
3297
3298 /*!
3299  * Returns the minimal value within \a this array that is allowed to have more than
3300  *  one component.
3301  *  \return double - the minimal value among all values of \a this array.
3302  *  \throw If \a this is not allocated.
3303  */
3304 double DataArrayDouble::getMinValueInArray() const
3305 {
3306   checkAllocated();
3307   const double *loc=std::min_element(begin(),end());
3308   return *loc;
3309 }
3310
3311 /*!
3312  * Returns the minimal value and all its locations within \a this one-dimensional array.
3313  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3314  *               tuples holding the minimal value. The caller is to delete it using
3315  *               decrRef() as it is no more needed.
3316  *  \return double - the minimal value among all values of \a this array.
3317  *  \throw If \a this->getNumberOfComponents() != 1
3318  *  \throw If \a this->getNumberOfTuples() < 1
3319  */
3320 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
3321 {
3322   int tmp;
3323   tupleIds=0;
3324   double ret=getMinValue(tmp);
3325   tupleIds=findIdsInRange(ret,ret);
3326   return ret;
3327 }
3328
3329 /*!
3330  * 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.
3331  * This method only works for single component array.
3332  *
3333  * \return a value in [ 0, \c this->getNumberOfTuples() )
3334  *
3335  * \throw If \a this is not allocated
3336  *
3337  */
3338 int DataArrayDouble::count(double value, double eps) const
3339 {
3340   int ret=0;
3341   checkAllocated();
3342   if(getNumberOfComponents()!=1)
3343     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3344   const double *vals=begin();
3345   int nbOfTuples=getNumberOfTuples();
3346   for(int i=0;i<nbOfTuples;i++,vals++)
3347     if(fabs(*vals-value)<=eps)
3348       ret++;
3349   return ret;
3350 }
3351
3352 /*!
3353  * Returns the average value of \a this one-dimensional array.
3354  *  \return double - the average value over all values of \a this array.
3355  *  \throw If \a this->getNumberOfComponents() != 1
3356  *  \throw If \a this->getNumberOfTuples() < 1
3357  */
3358 double DataArrayDouble::getAverageValue() const
3359 {
3360   if(getNumberOfComponents()!=1)
3361     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3362   int nbOfTuples=getNumberOfTuples();
3363   if(nbOfTuples<=0)
3364     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3365   const double *vals=getConstPointer();
3366   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3367   return ret/nbOfTuples;
3368 }
3369
3370 /*!
3371  * Returns the Euclidean norm of the vector defined by \a this array.
3372  *  \return double - the value of the Euclidean norm, i.e.
3373  *          the square root of the inner product of vector.
3374  *  \throw If \a this is not allocated.
3375  */
3376 double DataArrayDouble::norm2() const
3377 {
3378   checkAllocated();
3379   double ret=0.;
3380   std::size_t nbOfElems=getNbOfElems();
3381   const double *pt=getConstPointer();
3382   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3383     ret+=(*pt)*(*pt);
3384   return sqrt(ret);
3385 }
3386
3387 /*!
3388  * Returns the maximum norm of the vector defined by \a this array.
3389  * This method works even if the number of components is diferent from one.
3390  * If the number of elements in \a this is 0, -1. is returned.
3391  *  \return double - the value of the maximum norm, i.e.
3392  *          the maximal absolute value among values of \a this array (whatever its number of components).
3393  *  \throw If \a this is not allocated.
3394  */
3395 double DataArrayDouble::normMax() const
3396 {
3397   checkAllocated();
3398   double ret(-1.);
3399   std::size_t nbOfElems(getNbOfElems());
3400   const double *pt(getConstPointer());
3401   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3402     {
3403       double val(std::abs(*pt));
3404       if(val>ret)
3405         ret=val;
3406     }
3407   return ret;
3408 }
3409
3410 /*!
3411  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
3412  * This method works even if the number of components is diferent from one.
3413  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
3414  *  \return double - the value of the minimum norm, i.e.
3415  *          the minimal absolute value among values of \a this array (whatever its number of components).
3416  *  \throw If \a this is not allocated.
3417  */
3418 double DataArrayDouble::normMin() const
3419 {
3420   checkAllocated();
3421   double ret(std::numeric_limits<double>::max());
3422   std::size_t nbOfElems(getNbOfElems());
3423   const double *pt(getConstPointer());
3424   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3425     {
3426       double val(std::abs(*pt));
3427       if(val<ret)
3428         ret=val;
3429     }
3430   return ret;
3431 }
3432
3433 /*!
3434  * Accumulates values of each component of \a this array.
3435  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3436  *         by the caller, that is filled by this method with sum value for each
3437  *         component.
3438  *  \throw If \a this is not allocated.
3439  */
3440 void DataArrayDouble::accumulate(double *res) const
3441 {
3442   checkAllocated();
3443   const double *ptr=getConstPointer();
3444   int nbTuple=getNumberOfTuples();
3445   int nbComps=getNumberOfComponents();
3446   std::fill(res,res+nbComps,0.);
3447   for(int i=0;i<nbTuple;i++)
3448     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3449 }
3450
3451 /*!
3452  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3453  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3454  *
3455  *
3456  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3457  * \a tupleEnd. If not an exception will be thrown.
3458  *
3459  * \param [in] tupleBg start pointer (included) of input external tuple
3460  * \param [in] tupleEnd end pointer (not included) of input external tuple
3461  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3462  * \return the min distance.
3463  * \sa MEDCouplingUMesh::distanceToPoint
3464  */
3465 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
3466 {
3467   checkAllocated();
3468   int nbTuple=getNumberOfTuples();
3469   int nbComps=getNumberOfComponents();
3470   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3471     { 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()); }
3472   if(nbTuple==0)
3473     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3474   double ret0=std::numeric_limits<double>::max();
3475   tupleId=-1;
3476   const double *work=getConstPointer();
3477   for(int i=0;i<nbTuple;i++)
3478     {
3479       double val=0.;
3480       for(int j=0;j<nbComps;j++,work++) 
3481         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3482       if(val>=ret0)
3483         continue;
3484       else
3485         { ret0=val; tupleId=i; }
3486     }
3487   return sqrt(ret0);
3488 }
3489
3490 /*!
3491  * Accumulate values of the given component of \a this array.
3492  *  \param [in] compId - the index of the component of interest.
3493  *  \return double - a sum value of \a compId-th component.
3494  *  \throw If \a this is not allocated.
3495  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3496  *         not respected.
3497  */
3498 double DataArrayDouble::accumulate(int compId) const
3499 {
3500   checkAllocated();
3501   const double *ptr=getConstPointer();
3502   int nbTuple=getNumberOfTuples();
3503   int nbComps=getNumberOfComponents();
3504   if(compId<0 || compId>=nbComps)
3505     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3506   double ret=0.;
3507   for(int i=0;i<nbTuple;i++)
3508     ret+=ptr[i*nbComps+compId];
3509   return ret;
3510 }
3511
3512 /*!
3513  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3514  * The returned array will have same number of components than \a this and number of tuples equal to
3515  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3516  *
3517  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3518  * 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.
3519  *
3520  * \param [in] bgOfIndex - begin (included) of the input index array.
3521  * \param [in] endOfIndex - end (excluded) of the input index array.
3522  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3523  * 
3524  * \throw If bgOfIndex or end is NULL.
3525  * \throw If input index array is not ascendingly sorted.
3526  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3527  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3528  */
3529 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
3530 {
3531   if(!bgOfIndex || !endOfIndex)
3532     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3533   checkAllocated();
3534   int nbCompo=getNumberOfComponents();
3535   int nbOfTuples=getNumberOfTuples();
3536   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3537   if(sz<1)
3538     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3539   sz--;
3540   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3541   const int *w=bgOfIndex;
3542   if(*w<0 || *w>=nbOfTuples)
3543     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3544   const double *srcPt=begin()+(*w)*nbCompo;
3545   double *tmp=ret->getPointer();
3546   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3547     {
3548       std::fill(tmp,tmp+nbCompo,0.);
3549       if(w[1]>=w[0])
3550         {
3551           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3552             {
3553               if(j>=0 && j<nbOfTuples)
3554                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3555               else
3556                 {
3557                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3558                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3559                 }
3560             }
3561         }
3562       else
3563         {
3564           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3565           throw INTERP_KERNEL::Exception(oss.str().c_str());
3566         }
3567     }
3568   ret->copyStringInfoFrom(*this);
3569   return ret.retn();
3570 }
3571
3572 /*!
3573  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3574  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3575  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3576  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3577  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3578  *          is to delete this array using decrRef() as it is no more needed. The array
3579  *          does not contain any textual info on components.
3580  *  \throw If \a this->getNumberOfComponents() != 2.
3581  */
3582 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
3583 {
3584   checkAllocated();
3585   int nbOfComp(getNumberOfComponents());
3586   if(nbOfComp!=2)
3587     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3588   int nbOfTuple(getNumberOfTuples());
3589   DataArrayDouble *ret(DataArrayDouble::New());
3590   ret->alloc(nbOfTuple,2);
3591   double *w(ret->getPointer());
3592   const double *wIn(getConstPointer());
3593   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3594     {
3595       w[0]=wIn[0]*cos(wIn[1]);
3596       w[1]=wIn[0]*sin(wIn[1]);
3597     }
3598   return ret;
3599 }
3600
3601 /*!
3602  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3603  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3604  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3605  * the Cylindrical CS.
3606  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3607  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3608  *          on the third component is copied from \a this array. The caller
3609  *          is to delete this array using decrRef() as it is no more needed. 
3610  *  \throw If \a this->getNumberOfComponents() != 3.
3611  */
3612 DataArrayDouble *DataArrayDouble::fromCylToCart() const
3613 {
3614   checkAllocated();
3615   int nbOfComp(getNumberOfComponents());
3616   if(nbOfComp!=3)
3617     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3618   int nbOfTuple(getNumberOfTuples());
3619   DataArrayDouble *ret(DataArrayDouble::New());
3620   ret->alloc(getNumberOfTuples(),3);
3621   double *w(ret->getPointer());
3622   const double *wIn(getConstPointer());
3623   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3624     {
3625       w[0]=wIn[0]*cos(wIn[1]);
3626       w[1]=wIn[0]*sin(wIn[1]);
3627       w[2]=wIn[2];
3628     }
3629   ret->setInfoOnComponent(2,getInfoOnComponent(2));
3630   return ret;
3631 }
3632
3633 /*!
3634  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3635  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3636  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3637  * point in the Cylindrical CS.
3638  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3639  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3640  *          on the third component is copied from \a this array. The caller
3641  *          is to delete this array using decrRef() as it is no more needed.
3642  *  \throw If \a this->getNumberOfComponents() != 3.
3643  */
3644 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
3645 {
3646   checkAllocated();
3647   int nbOfComp(getNumberOfComponents());
3648   if(nbOfComp!=3)
3649     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3650   int nbOfTuple(getNumberOfTuples());
3651   DataArrayDouble *ret(DataArrayDouble::New());
3652   ret->alloc(getNumberOfTuples(),3);
3653   double *w(ret->getPointer());
3654   const double *wIn(getConstPointer());
3655   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3656     {
3657       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3658       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3659       w[2]=wIn[0]*cos(wIn[1]);
3660     }
3661   return ret;
3662 }
3663
3664 /*!
3665  * 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.
3666  * 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.
3667  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
3668  *
3669  * \param [in] atOfThis - The axis type of \a this.
3670  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
3671  */
3672 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
3673 {
3674   checkAllocated();
3675   int nbOfComp(getNumberOfComponents());
3676   MCAuto<DataArrayDouble> ret;
3677   switch(atOfThis)
3678     {
3679     case AX_CART:
3680       ret=deepCopy();
3681     case AX_CYL:
3682       if(nbOfComp==3)
3683         {
3684           ret=fromCylToCart();
3685           break;
3686         }
3687       if(nbOfComp==2)
3688         {
3689           ret=fromPolarToCart();
3690           break;
3691         }
3692       else
3693         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
3694     case AX_SPHER:
3695       if(nbOfComp==3)
3696         {
3697           ret=fromSpherToCart();
3698           break;
3699         }
3700       if(nbOfComp==2)
3701         {
3702           ret=fromPolarToCart();
3703           break;
3704         }
3705       else
3706         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
3707     default:
3708       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
3709     }
3710   ret->copyStringInfoFrom(*this);
3711   return ret.retn();
3712 }
3713
3714 /*!
3715  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3716  * array contating 6 components.
3717  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3718  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3719  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3720  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3721  *  \throw If \a this->getNumberOfComponents() != 6.
3722  */
3723 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
3724 {
3725   checkAllocated();
3726   int nbOfComp(getNumberOfComponents());
3727   if(nbOfComp!=6)
3728     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3729   DataArrayDouble *ret=DataArrayDouble::New();
3730   int nbOfTuple=getNumberOfTuples();
3731   ret->alloc(nbOfTuple,1);
3732   const double *src=getConstPointer();
3733   double *dest=ret->getPointer();
3734   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3735     *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];
3736   return ret;
3737 }
3738
3739 /*!
3740  * Computes the determinant of every square matrix defined by the tuple of \a this
3741  * array, which contains either 4, 6 or 9 components. The case of 6 components
3742  * corresponds to that of the upper triangular matrix.
3743  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3744  *          is the determinant of matrix of the corresponding tuple of \a this array.
3745  *          The caller is to delete this result array using decrRef() as it is no more
3746  *          needed. 
3747  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3748  */
3749 DataArrayDouble *DataArrayDouble::determinant() const
3750 {
3751   checkAllocated();
3752   DataArrayDouble *ret=DataArrayDouble::New();
3753   int nbOfTuple=getNumberOfTuples();
3754   ret->alloc(nbOfTuple,1);
3755   const double *src=getConstPointer();
3756   double *dest=ret->getPointer();
3757   switch(getNumberOfComponents())
3758   {
3759     case 6:
3760       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3761         *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];
3762       return ret;
3763     case 4:
3764       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3765         *dest=src[0]*src[3]-src[1]*src[2];
3766       return ret;
3767     case 9:
3768       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3769         *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];
3770       return ret;
3771     default:
3772       ret->decrRef();
3773       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3774   }
3775 }
3776
3777 /*!
3778  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3779  * \a this array, which contains 6 components.
3780  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3781  *          components, whose each tuple contains the eigenvalues of the matrix of
3782  *          corresponding tuple of \a this array. 
3783  *          The caller is to delete this result array using decrRef() as it is no more
3784  *          needed. 
3785  *  \throw If \a this->getNumberOfComponents() != 6.
3786  */
3787 DataArrayDouble *DataArrayDouble::eigenValues() const
3788 {
3789   checkAllocated();
3790   int nbOfComp=getNumberOfComponents();
3791   if(nbOfComp!=6)
3792     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3793   DataArrayDouble *ret=DataArrayDouble::New();
3794   int nbOfTuple=getNumberOfTuples();
3795   ret->alloc(nbOfTuple,3);
3796   const double *src=getConstPointer();
3797   double *dest=ret->getPointer();
3798   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3799     INTERP_KERNEL::computeEigenValues6(src,dest);
3800   return ret;
3801 }
3802
3803 /*!
3804  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3805  * \a this array, which contains 6 components.
3806  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3807  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3808  *          corresponding tuple of \a this array.
3809  *          The caller is to delete this result array using decrRef() as it is no more
3810  *          needed.
3811  *  \throw If \a this->getNumberOfComponents() != 6.
3812  */
3813 DataArrayDouble *DataArrayDouble::eigenVectors() const
3814 {
3815   checkAllocated();
3816   int nbOfComp=getNumberOfComponents();
3817   if(nbOfComp!=6)
3818     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3819   DataArrayDouble *ret=DataArrayDouble::New();
3820   int nbOfTuple=getNumberOfTuples();
3821   ret->alloc(nbOfTuple,9);
3822   const double *src=getConstPointer();
3823   double *dest=ret->getPointer();
3824   for(int i=0;i<nbOfTuple;i++,src+=6)
3825     {
3826       double tmp[3];
3827       INTERP_KERNEL::computeEigenValues6(src,tmp);
3828       for(int j=0;j<3;j++,dest+=3)
3829         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3830     }
3831   return ret;
3832 }
3833
3834 /*!
3835  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3836  * array, which contains either 4, 6 or 9 components. The case of 6 components
3837  * corresponds to that of the upper triangular matrix.
3838  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3839  *          same number of components as \a this one, whose each tuple is the inverse
3840  *          matrix of the matrix of corresponding tuple of \a this array. 
3841  *          The caller is to delete this result array using decrRef() as it is no more
3842  *          needed. 
3843  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3844  */
3845 DataArrayDouble *DataArrayDouble::inverse() const
3846 {
3847   checkAllocated();
3848   int nbOfComp=getNumberOfComponents();
3849   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3850     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3851   DataArrayDouble *ret=DataArrayDouble::New();
3852   int nbOfTuple=getNumberOfTuples();
3853   ret->alloc(nbOfTuple,nbOfComp);
3854   const double *src=getConstPointer();
3855   double *dest=ret->getPointer();
3856   if(nbOfComp==6)
3857     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3858       {
3859         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];
3860         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3861         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3862         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3863         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3864         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3865         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3866       }
3867   else if(nbOfComp==4)
3868     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3869       {
3870         double det=src[0]*src[3]-src[1]*src[2];
3871         dest[0]=src[3]/det;
3872         dest[1]=-src[1]/det;
3873         dest[2]=-src[2]/det;
3874         dest[3]=src[0]/det;
3875       }
3876   else
3877     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3878       {
3879         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];
3880         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3881         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3882         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3883         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3884         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3885         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3886         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3887         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3888         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3889       }
3890   return ret;
3891 }
3892
3893 /*!
3894  * Computes the trace of every matrix defined by the tuple of \a this
3895  * array, which contains either 4, 6 or 9 components. The case of 6 components
3896  * corresponds to that of the upper triangular matrix.
3897  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3898  *          1 component, whose each tuple is the trace of
3899  *          the matrix of corresponding tuple of \a this array. 
3900  *          The caller is to delete this result array using decrRef() as it is no more
3901  *          needed. 
3902  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3903  */
3904 DataArrayDouble *DataArrayDouble::trace() const
3905 {
3906   checkAllocated();
3907   int nbOfComp=getNumberOfComponents();
3908   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3909     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3910   DataArrayDouble *ret=DataArrayDouble::New();
3911   int nbOfTuple=getNumberOfTuples();
3912   ret->alloc(nbOfTuple,1);
3913   const double *src=getConstPointer();
3914   double *dest=ret->getPointer();
3915   if(nbOfComp==6)
3916     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3917       *dest=src[0]+src[1]+src[2];
3918   else if(nbOfComp==4)
3919     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3920       *dest=src[0]+src[3];
3921   else
3922     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3923       *dest=src[0]+src[4]+src[8];
3924   return ret;
3925 }
3926
3927 /*!
3928  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3929  * \a this array, which contains 6 components.
3930  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3931  *          same number of components and tuples as \a this array.
3932  *          The caller is to delete this result array using decrRef() as it is no more
3933  *          needed.
3934  *  \throw If \a this->getNumberOfComponents() != 6.
3935  */
3936 DataArrayDouble *DataArrayDouble::deviator() const
3937 {
3938   checkAllocated();
3939   int nbOfComp=getNumberOfComponents();
3940   if(nbOfComp!=6)
3941     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3942   DataArrayDouble *ret=DataArrayDouble::New();
3943   int nbOfTuple=getNumberOfTuples();
3944   ret->alloc(nbOfTuple,6);
3945   const double *src=getConstPointer();
3946   double *dest=ret->getPointer();
3947   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3948     {
3949       double tr=(src[0]+src[1]+src[2])/3.;
3950       dest[0]=src[0]-tr;
3951       dest[1]=src[1]-tr;
3952       dest[2]=src[2]-tr;
3953       dest[3]=src[3];
3954       dest[4]=src[4];
3955       dest[5]=src[5];
3956     }
3957   return ret;
3958 }
3959
3960 /*!
3961  * Computes the magnitude of every vector defined by the tuple of
3962  * \a this array.
3963  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3964  *          same number of tuples as \a this array and one component.
3965  *          The caller is to delete this result array using decrRef() as it is no more
3966  *          needed.
3967  *  \throw If \a this is not allocated.
3968  */
3969 DataArrayDouble *DataArrayDouble::magnitude() const
3970 {
3971   checkAllocated();
3972   int nbOfComp=getNumberOfComponents();
3973   DataArrayDouble *ret=DataArrayDouble::New();
3974   int nbOfTuple=getNumberOfTuples();
3975   ret->alloc(nbOfTuple,1);
3976   const double *src=getConstPointer();
3977   double *dest=ret->getPointer();
3978   for(int i=0;i<nbOfTuple;i++,dest++)
3979     {
3980       double sum=0.;
3981       for(int j=0;j<nbOfComp;j++,src++)
3982         sum+=(*src)*(*src);
3983       *dest=sqrt(sum);
3984     }
3985   return ret;
3986 }
3987
3988 /*!
3989  * Computes for each tuple the sum of number of components values in the tuple and return it.
3990  * 
3991  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3992  *          same number of tuples as \a this array and one component.
3993  *          The caller is to delete this result array using decrRef() as it is no more
3994  *          needed.
3995  *  \throw If \a this is not allocated.
3996  */
3997 DataArrayDouble *DataArrayDouble::sumPerTuple() const
3998 {
3999   checkAllocated();
4000   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
4001   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
4002   ret->alloc(nbOfTuple,1);
4003   const double *src(getConstPointer());
4004   double *dest(ret->getPointer());
4005   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
4006     *dest=std::accumulate(src,src+nbOfComp,0.);
4007   return ret.retn();
4008 }
4009
4010 /*!
4011  * Computes the maximal value within every tuple of \a this array.
4012  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4013  *          same number of tuples as \a this array and one component.
4014  *          The caller is to delete this result array using decrRef() as it is no more
4015  *          needed.
4016  *  \throw If \a this is not allocated.
4017  *  \sa DataArrayDouble::maxPerTupleWithCompoId
4018  */
4019 DataArrayDouble *DataArrayDouble::maxPerTuple() const
4020 {
4021   checkAllocated();
4022   int nbOfComp=getNumberOfComponents();
4023   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4024   int nbOfTuple=getNumberOfTuples();
4025   ret->alloc(nbOfTuple,1);
4026   const double *src=getConstPointer();
4027   double *dest=ret->getPointer();
4028   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
4029     *dest=*std::max_element(src,src+nbOfComp);
4030   return ret.retn();
4031 }
4032
4033 /*!
4034  * Computes the maximal value within every tuple of \a this array and it returns the first component
4035  * id for each tuple that corresponds to the maximal value within the tuple.
4036  * 
4037  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
4038  *          same number of tuples and only one component.
4039  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4040  *          same number of tuples as \a this array and one component.
4041  *          The caller is to delete this result array using decrRef() as it is no more
4042  *          needed.
4043  *  \throw If \a this is not allocated.
4044  *  \sa DataArrayDouble::maxPerTuple
4045  */
4046 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
4047 {
4048   checkAllocated();
4049   int nbOfComp=getNumberOfComponents();
4050   MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
4051   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
4052   int nbOfTuple=getNumberOfTuples();
4053   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
4054   const double *src=getConstPointer();
4055   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
4056   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
4057     {
4058       const double *loc=std::max_element(src,src+nbOfComp);
4059       *dest=*loc;
4060       *dest1=(int)std::distance(src,loc);
4061     }
4062   compoIdOfMaxPerTuple=ret1.retn();
4063   return ret0.retn();
4064 }
4065
4066 /*!
4067  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
4068  * \n This returned array contains the euclidian distance for each tuple in \a this. 
4069  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
4070  * \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)
4071  *
4072  * \warning use this method with care because it can leads to big amount of consumed memory !
4073  * 
4074  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
4075  *
4076  * \throw If \a this is not allocated.
4077  *
4078  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
4079  */
4080 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
4081 {
4082   checkAllocated();
4083   int nbOfComp=getNumberOfComponents();
4084   int nbOfTuples=getNumberOfTuples();
4085   const double *inData=getConstPointer();
4086   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4087   ret->alloc(nbOfTuples*nbOfTuples,1);
4088   double *outData=ret->getPointer();
4089   for(int i=0;i<nbOfTuples;i++)
4090     {
4091       outData[i*nbOfTuples+i]=0.;
4092       for(int j=i+1;j<nbOfTuples;j++)
4093         {
4094           double dist=0.;
4095           for(int k=0;k<nbOfComp;k++)
4096             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4097           dist=sqrt(dist);
4098           outData[i*nbOfTuples+j]=dist;
4099           outData[j*nbOfTuples+i]=dist;
4100         }
4101     }
4102   return ret.retn();
4103 }
4104
4105 /*!
4106  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
4107  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
4108  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
4109  * \n Output rectangular matrix is sorted along rows.
4110  * \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)
4111  *
4112  * \warning use this method with care because it can leads to big amount of consumed memory !
4113  * 
4114  * \param [in] other DataArrayDouble instance having same number of components than \a this.
4115  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
4116  *
4117  * \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.
4118  *
4119  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
4120  */
4121 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
4122 {
4123   if(!other)
4124     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
4125   checkAllocated();
4126   other->checkAllocated();
4127   int nbOfComp=getNumberOfComponents();
4128   int otherNbOfComp=other->getNumberOfComponents();
4129   if(nbOfComp!=otherNbOfComp)
4130     {
4131       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
4132       throw INTERP_KERNEL::Exception(oss.str().c_str());
4133     }
4134   int nbOfTuples=getNumberOfTuples();
4135   int otherNbOfTuples=other->getNumberOfTuples();
4136   const double *inData=getConstPointer();
4137   const double *inDataOther=other->getConstPointer();
4138   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4139   ret->alloc(otherNbOfTuples*nbOfTuples,1);
4140   double *outData=ret->getPointer();
4141   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
4142     {
4143       for(int j=0;j<nbOfTuples;j++)
4144         {
4145           double dist=0.;
4146           for(int k=0;k<nbOfComp;k++)
4147             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4148           dist=sqrt(dist);
4149           outData[i*nbOfTuples+j]=dist;
4150         }
4151     }
4152   return ret.retn();
4153 }
4154
4155 /*!
4156  * Sorts value within every tuple of \a this array.
4157  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
4158  *              in descending order.
4159  *  \throw If \a this is not allocated.
4160  */
4161 void DataArrayDouble::sortPerTuple(bool asc)
4162 {
4163   checkAllocated();
4164   double *pt=getPointer();
4165   int nbOfTuple=getNumberOfTuples();
4166   int nbOfComp=getNumberOfComponents();
4167   if(asc)
4168     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4169       std::sort(pt,pt+nbOfComp);
4170   else
4171     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4172       std::sort(pt,pt+nbOfComp,std::greater<double>());
4173   declareAsNew();
4174 }
4175
4176 /*!
4177  * Converts every value of \a this array to its absolute value.
4178  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
4179  * should be called instead.
4180  *
4181  * \throw If \a this is not allocated.
4182  * \sa DataArrayDouble::computeAbs
4183  */
4184 void DataArrayDouble::abs()
4185 {
4186   checkAllocated();
4187   double *ptr(getPointer());
4188   std::size_t nbOfElems(getNbOfElems());
4189   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
4190   declareAsNew();
4191 }
4192
4193 /*!
4194  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
4195  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
4196  *
4197  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4198  *         same number of tuples and component as \a this array.
4199  *         The caller is to delete this result array using decrRef() as it is no more
4200  *         needed.
4201  * \throw If \a this is not allocated.
4202  * \sa DataArrayDouble::abs
4203  */
4204 DataArrayDouble *DataArrayDouble::computeAbs() const
4205 {
4206   checkAllocated();
4207   DataArrayDouble *newArr(DataArrayDouble::New());
4208   int nbOfTuples(getNumberOfTuples());
4209   int nbOfComp(getNumberOfComponents());
4210   newArr->alloc(nbOfTuples,nbOfComp);
4211   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
4212   newArr->copyStringInfoFrom(*this);
4213   return newArr;
4214 }
4215
4216 /*!
4217  * Apply a linear function to a given component of \a this array, so that
4218  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
4219  *  \param [in] a - the first coefficient of the function.
4220  *  \param [in] b - the second coefficient of the function.
4221  *  \param [in] compoId - the index of component to modify.
4222  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
4223  */
4224 void DataArrayDouble::applyLin(double a, double b, int compoId)
4225 {
4226   checkAllocated();
4227   double *ptr(getPointer()+compoId);
4228   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
4229   if(compoId<0 || compoId>=nbOfComp)
4230     {
4231       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
4232       throw INTERP_KERNEL::Exception(oss.str().c_str());
4233     }
4234   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
4235     *ptr=a*(*ptr)+b;
4236   declareAsNew();
4237 }
4238
4239 /*!
4240  * Apply a linear function to all elements of \a this array, so that
4241  * an element _x_ becomes \f$ a * x + b \f$.
4242  *  \param [in] a - the first coefficient of the function.
4243  *  \param [in] b - the second coefficient of the function.
4244  *  \throw If \a this is not allocated.
4245  */
4246 void DataArrayDouble::applyLin(double a, double b)
4247 {
4248   checkAllocated();
4249   double *ptr=getPointer();
4250   std::size_t nbOfElems=getNbOfElems();
4251   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4252     *ptr=a*(*ptr)+b;
4253   declareAsNew();
4254 }
4255
4256 /*!
4257  * Modify all elements of \a this array, so that
4258  * an element _x_ becomes \f$ numerator / x \f$.
4259  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4260  *           array, all elements processed before detection of the zero element remain
4261  *           modified.
4262  *  \param [in] numerator - the numerator used to modify array elements.
4263  *  \throw If \a this is not allocated.
4264  *  \throw If there is an element equal to 0.0 in \a this array.
4265  */
4266 void DataArrayDouble::applyInv(double numerator)
4267 {
4268   checkAllocated();
4269   double *ptr=getPointer();
4270   std::size_t nbOfElems=getNbOfElems();
4271   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4272     {
4273       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4274         {
4275           *ptr=numerator/(*ptr);
4276         }
4277       else
4278         {
4279           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4280           oss << " !";
4281           throw INTERP_KERNEL::Exception(oss.str().c_str());
4282         }
4283     }
4284   declareAsNew();
4285 }
4286
4287 /*!
4288  * Returns a full copy of \a this array except that sign of all elements is reversed.
4289  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4290  *          same number of tuples and component as \a this array.
4291  *          The caller is to delete this result array using decrRef() as it is no more
4292  *          needed.
4293  *  \throw If \a this is not allocated.
4294  */
4295 DataArrayDouble *DataArrayDouble::negate() const
4296 {
4297   checkAllocated();
4298   DataArrayDouble *newArr=DataArrayDouble::New();
4299   int nbOfTuples=getNumberOfTuples();
4300   int nbOfComp=getNumberOfComponents();
4301   newArr->alloc(nbOfTuples,nbOfComp);
4302   const double *cptr=getConstPointer();
4303   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4304   newArr->copyStringInfoFrom(*this);
4305   return newArr;
4306 }
4307
4308 /*!
4309  * Modify all elements of \a this array, so that
4310  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4311  * all values in \a this have to be >= 0 if val is \b not integer.
4312  *  \param [in] val - the value used to apply pow on all array elements.
4313  *  \throw If \a this is not allocated.
4314  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4315  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4316  *           modified.
4317  */
4318 void DataArrayDouble::applyPow(double val)
4319 {
4320   checkAllocated();
4321   double *ptr=getPointer();
4322   std::size_t nbOfElems=getNbOfElems();
4323   int val2=(int)val;
4324   bool isInt=((double)val2)==val;
4325   if(!isInt)
4326     {
4327       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4328         {
4329           if(*ptr>=0)
4330             *ptr=pow(*ptr,val);
4331           else
4332             {
4333               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4334               throw INTERP_KERNEL::Exception(oss.str().c_str());
4335             }
4336         }
4337     }
4338   else
4339     {
4340       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4341         *ptr=pow(*ptr,val2);
4342     }
4343   declareAsNew();
4344 }
4345
4346 /*!
4347  * Modify all elements of \a this array, so that
4348  * an element _x_ becomes \f$ val ^ x \f$.
4349  *  \param [in] val - the value used to apply pow on all array elements.
4350  *  \throw If \a this is not allocated.
4351  *  \throw If \a val < 0.
4352  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4353  *           array, all elements processed before detection of the zero element remain
4354  *           modified.
4355  */
4356 void DataArrayDouble::applyRPow(double val)
4357 {
4358   checkAllocated();
4359   if(val<0.)
4360     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4361   double *ptr=getPointer();
4362   std::size_t nbOfElems=getNbOfElems();
4363   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4364     *ptr=pow(val,*ptr);
4365   declareAsNew();
4366 }
4367
4368 /*!
4369  * Returns a new DataArrayDouble created from \a this one by applying \a
4370  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4371  * For more info see \ref MEDCouplingArrayApplyFunc
4372  *  \param [in] nbOfComp - number of components in the result array.
4373  *  \param [in] func - the \a FunctionToEvaluate declared as 
4374  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4375  *              where \a pos points to the first component of a tuple of \a this array
4376  *              and \a res points to the first component of a tuple of the result array.
4377  *              Note that length (number of components) of \a pos can differ from
4378  *              that of \a res.
4379  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4380  *          same number of tuples as \a this array.
4381  *          The caller is to delete this result array using decrRef() as it is no more
4382  *          needed.
4383  *  \throw If \a this is not allocated.
4384  *  \throw If \a func returns \a false.
4385  */
4386 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
4387 {
4388   checkAllocated();
4389   DataArrayDouble *newArr=DataArrayDouble::New();
4390   int nbOfTuples=getNumberOfTuples();
4391   int oldNbOfComp=getNumberOfComponents();
4392   newArr->alloc(nbOfTuples,nbOfComp);
4393   const double *ptr=getConstPointer();
4394   double *ptrToFill=newArr->getPointer();
4395   for(int i=0;i<nbOfTuples;i++)
4396     {
4397       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4398         {
4399           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4400           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4401           oss << ") : Evaluation of function failed !";
4402           newArr->decrRef();
4403           throw INTERP_KERNEL::Exception(oss.str().c_str());
4404         }
4405     }
4406   return newArr;
4407 }
4408
4409 /*!
4410  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4411  * tuple of \a this array. Textual data is not copied.
4412  * For more info see \ref MEDCouplingArrayApplyFunc1.
4413  *  \param [in] nbOfComp - number of components in the result array.
4414  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4415  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4416  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4417  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4418  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4419  *          same number of tuples as \a this array and \a nbOfComp components.
4420  *          The caller is to delete this result array using decrRef() as it is no more
4421  *          needed.
4422  *  \throw If \a this is not allocated.
4423  *  \throw If computing \a func fails.
4424  */
4425 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
4426 {
4427   INTERP_KERNEL::ExprParser expr(func);
4428   expr.parse();
4429   std::set<std::string> vars;
4430   expr.getTrueSetOfVars(vars);
4431   std::vector<std::string> varsV(vars.begin(),vars.end());
4432   return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
4433 }
4434
4435 /*!
4436  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4437  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
4438  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
4439  *
4440  * For more info see \ref MEDCouplingArrayApplyFunc0.
4441  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4442  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4443  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4444  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
4445  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4446  *          same number of tuples and components as \a this array.
4447  *          The caller is to delete this result array using decrRef() as it is no more
4448  *          needed.
4449  *  \sa applyFuncOnThis
4450  *  \throw If \a this is not allocated.
4451  *  \throw If computing \a func fails.
4452  */
4453 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
4454 {
4455   int nbOfComp(getNumberOfComponents());
4456   if(nbOfComp<=0)
4457     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
4458   checkAllocated();
4459   int nbOfTuples(getNumberOfTuples());
4460   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
4461   newArr->alloc(nbOfTuples,nbOfComp);
4462   INTERP_KERNEL::ExprParser expr(func);
4463   expr.parse();
4464   std::set<std::string> vars;
4465   expr.getTrueSetOfVars(vars);
4466   if((int)vars.size()>1)
4467     {
4468       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 : ";
4469       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4470       throw INTERP_KERNEL::Exception(oss.str().c_str());
4471     }
4472   if(vars.empty())
4473     {
4474       expr.prepareFastEvaluator();
4475       newArr->rearrange(1);
4476       newArr->fillWithValue(expr.evaluateDouble());
4477       newArr->rearrange(nbOfComp);
4478       return newArr.retn();
4479     }
4480   std::vector<std::string> vars2(vars.begin(),vars.end());
4481   double buff,*ptrToFill(newArr->getPointer());
4482   const double *ptr(begin());
4483   std::vector<double> stck;
4484   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4485   expr.prepareFastEvaluator();
4486   if(!isSafe)
4487     {
4488       for(int i=0;i<nbOfTuples;i++)
4489         {
4490           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4491             {
4492               buff=*ptr;
4493               expr.evaluateDoubleInternal(stck);
4494               *ptrToFill=stck.back();
4495               stck.pop_back();
4496             }
4497         }
4498     }
4499   else
4500     {
4501       for(int i=0;i<nbOfTuples;i++)
4502         {
4503           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4504             {
4505               buff=*ptr;
4506               try
4507               {
4508                   expr.evaluateDoubleInternalSafe(stck);
4509               }
4510               catch(INTERP_KERNEL::Exception& e)
4511               {
4512                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4513                   oss << buff;
4514                   oss << ") : Evaluation of function failed !" << e.what();
4515                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4516               }
4517               *ptrToFill=stck.back();
4518               stck.pop_back();
4519             }
4520         }
4521     }
4522   return newArr.retn();
4523 }
4524
4525 /*!
4526  * This method is a non const method that modify the array in \a this.
4527  * This method only works on one component array. It means that function \a func must
4528  * contain at most one variable.
4529  * This method is a specialization of applyFunc method with one parameter on one component array.
4530  *
4531  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4532  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4533  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4534  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4535  *
4536  * \sa applyFunc
4537  */
4538 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
4539 {
4540   int nbOfComp(getNumberOfComponents());
4541   if(nbOfComp<=0)
4542     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
4543   checkAllocated();
4544   int nbOfTuples(getNumberOfTuples());
4545   INTERP_KERNEL::ExprParser expr(func);
4546   expr.parse();
4547   std::set<std::string> vars;
4548   expr.getTrueSetOfVars(vars);
4549   if((int)vars.size()>1)
4550     {
4551       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 : ";
4552       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4553       throw INTERP_KERNEL::Exception(oss.str().c_str());
4554     }
4555   if(vars.empty())
4556     {
4557       expr.prepareFastEvaluator();
4558       std::vector<std::string> compInfo(getInfoOnComponents());
4559       rearrange(1);
4560       fillWithValue(expr.evaluateDouble());
4561       rearrange(nbOfComp);
4562       setInfoOnComponents(compInfo);
4563       return ;
4564     }
4565   std::vector<std::string> vars2(vars.begin(),vars.end());
4566   double buff,*ptrToFill(getPointer());
4567   const double *ptr(begin());
4568   std::vector<double> stck;
4569   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4570   expr.prepareFastEvaluator();
4571   if(!isSafe)
4572     {
4573       for(int i=0;i<nbOfTuples;i++)
4574         {
4575           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4576             {
4577               buff=*ptr;
4578               expr.evaluateDoubleInternal(stck);
4579               *ptrToFill=stck.back();
4580               stck.pop_back();
4581             }
4582         }
4583     }
4584   else
4585     {
4586       for(int i=0;i<nbOfTuples;i++)
4587         {
4588           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4589             {
4590               buff=*ptr;
4591               try
4592               {
4593                   expr.evaluateDoubleInternalSafe(stck);
4594               }
4595               catch(INTERP_KERNEL::Exception& e)
4596               {
4597                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4598                   oss << buff;
4599                   oss << ") : Evaluation of function failed !" << e.what();
4600                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4601               }
4602               *ptrToFill=stck.back();
4603               stck.pop_back();
4604             }
4605         }
4606     }
4607 }
4608
4609 /*!
4610  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4611  * tuple of \a this array. Textual data is not copied.
4612  * For more info see \ref MEDCouplingArrayApplyFunc2.
4613  *  \param [in] nbOfComp - number of components in the result array.
4614  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4615  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4616  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4617  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4618  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4619  *          same number of tuples as \a this array.
4620  *          The caller is to delete this result array using decrRef() as it is no more
4621  *          needed.
4622  *  \throw If \a this is not allocated.
4623  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4624  *  \throw If computing \a func fails.
4625  */
4626 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
4627 {
4628   return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
4629 }
4630
4631 /*!
4632  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4633  * tuple of \a this array. Textual data is not copied.
4634  * For more info see \ref MEDCouplingArrayApplyFunc3.
4635  *  \param [in] nbOfComp - number of components in the result array.
4636  *  \param [in] varsOrder - sequence of vars defining their order.
4637  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4638  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4639  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4640  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4641  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4642  *          same number of tuples as \a this array.
4643  *          The caller is to delete this result array using decrRef() as it is no more
4644  *          needed.
4645  *  \throw If \a this is not allocated.
4646  *  \throw If \a func contains vars not in \a varsOrder.
4647  *  \throw If computing \a func fails.
4648  */
4649 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
4650 {
4651   if(nbOfComp<=0)
4652     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
4653   std::vector<std::string> varsOrder2(varsOrder);
4654   int oldNbOfComp(getNumberOfComponents());
4655   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
4656     varsOrder2.push_back(std::string());
4657   checkAllocated();
4658   int nbOfTuples(getNumberOfTuples());
4659   INTERP_KERNEL::ExprParser expr(func);
4660   expr.parse();
4661   std::set<std::string> vars;
4662   expr.getTrueSetOfVars(vars);
4663   if((int)vars.size()>oldNbOfComp)
4664     {
4665       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4666       oss << vars.size() << " variables : ";
4667       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4668       throw INTERP_KERNEL::Exception(oss.str().c_str());
4669     }
4670   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
4671   newArr->alloc(nbOfTuples,nbOfComp);
4672   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
4673   double *buffPtr(buff),*ptrToFill;
4674   std::vector<double> stck;
4675   for(int iComp=0;iComp<nbOfComp;iComp++)
4676     {
4677       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
4678       expr.prepareFastEvaluator();
4679       const double *ptr(getConstPointer());
4680       ptrToFill=newArr->getPointer()+iComp;
4681       if(!isSafe)
4682         {
4683           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4684             {
4685               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4686               expr.evaluateDoubleInternal(stck);
4687               *ptrToFill=stck.back();
4688               stck.pop_back();
4689             }
4690         }
4691       else
4692         {
4693           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4694             {
4695               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4696               try
4697               {
4698                   expr.evaluateDoubleInternalSafe(stck);
4699                   *ptrToFill=stck.back();
4700                   stck.pop_back();
4701               }
4702               catch(INTERP_KERNEL::Exception& e)
4703               {
4704                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4705                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4706                   oss << ") : Evaluation of function failed !" << e.what();
4707                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4708               }
4709             }
4710         }
4711     }
4712   return newArr.retn();
4713 }
4714
4715 void DataArrayDouble::applyFuncFast32(const std::string& func)
4716 {
4717   checkAllocated();
4718   INTERP_KERNEL::ExprParser expr(func);
4719   expr.parse();
4720   char *funcStr=expr.compileX86();
4721   MYFUNCPTR funcPtr;
4722   *((void **)&funcPtr)=funcStr;//he he...
4723   //
4724   double *ptr=getPointer();
4725   int nbOfComp=getNumberOfComponents();
4726   int nbOfTuples=getNumberOfTuples();
4727   int nbOfElems=nbOfTuples*nbOfComp;
4728   for(int i=0;i<nbOfElems;i++,ptr++)
4729     *ptr=funcPtr(*ptr);
4730   declareAsNew();
4731 }
4732
4733 void DataArrayDouble::applyFuncFast64(const std::string& func)
4734 {
4735   checkAllocated();
4736   INTERP_KERNEL::ExprParser expr(func);
4737   expr.parse();
4738   char *funcStr=expr.compileX86_64();
4739   MYFUNCPTR funcPtr;
4740   *((void **)&funcPtr)=funcStr;//he he...
4741   //
4742   double *ptr=getPointer();
4743   int nbOfComp=getNumberOfComponents();
4744   int nbOfTuples=getNumberOfTuples();
4745   int nbOfElems=nbOfTuples*nbOfComp;
4746   for(int i=0;i<nbOfElems;i++,ptr++)
4747     *ptr=funcPtr(*ptr);
4748   declareAsNew();
4749 }
4750
4751 DataArrayDoubleIterator *DataArrayDouble::iterator()
4752 {
4753   return new DataArrayDoubleIterator(this);
4754 }
4755
4756 /*!
4757  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4758  * array whose values are within a given range. Textual data is not copied.
4759  *  \param [in] vmin - a lowest acceptable value (included).
4760  *  \param [in] vmax - a greatest acceptable value (included).
4761  *  \return DataArrayInt * - the new instance of DataArrayInt.
4762  *          The caller is to delete this result array using decrRef() as it is no more
4763  *          needed.
4764  *  \throw If \a this->getNumberOfComponents() != 1.
4765  *
4766  *  \sa DataArrayDouble::findIdsNotInRange
4767  *
4768  *  \if ENABLE_EXAMPLES
4769  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4770  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4771  *  \endif
4772  */
4773 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
4774 {
4775   checkAllocated();
4776   if(getNumberOfComponents()!=1)
4777     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
4778   const double *cptr(begin());
4779   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4780   int nbOfTuples(getNumberOfTuples());
4781   for(int i=0;i<nbOfTuples;i++,cptr++)
4782     if(*cptr>=vmin && *cptr<=vmax)
4783       ret->pushBackSilent(i);
4784   return ret.retn();
4785 }
4786
4787 /*!
4788  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4789  * array whose values are not within a given range. Textual data is not copied.
4790  *  \param [in] vmin - a lowest not acceptable value (excluded).
4791  *  \param [in] vmax - a greatest not acceptable value (excluded).
4792  *  \return DataArrayInt * - the new instance of DataArrayInt.
4793  *          The caller is to delete this result array using decrRef() as it is no more
4794  *          needed.
4795  *  \throw If \a this->getNumberOfComponents() != 1.
4796  *
4797  *  \sa DataArrayDouble::findIdsInRange
4798  */
4799 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
4800 {
4801   checkAllocated();
4802   if(getNumberOfComponents()!=1)
4803     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
4804   const double *cptr(begin());
4805   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4806   int nbOfTuples(getNumberOfTuples());
4807   for(int i=0;i<nbOfTuples;i++,cptr++)
4808     if(*cptr<vmin || *cptr>vmax)
4809       ret->pushBackSilent(i);
4810   return ret.retn();
4811 }
4812
4813 /*!
4814  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4815  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4816  * the number of component in the result array is same as that of each of given arrays.
4817  * Info on components is copied from the first of the given arrays. Number of components
4818  * in the given arrays must be  the same.
4819  *  \param [in] a1 - an array to include in the result array.
4820  *  \param [in] a2 - another array to include in the result array.
4821  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4822  *          The caller is to delete this result array using decrRef() as it is no more
4823  *          needed.
4824  *  \throw If both \a a1 and \a a2 are NULL.
4825  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4826  */
4827 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
4828 {
4829   std::vector<const DataArrayDouble *> tmp(2);
4830   tmp[0]=a1; tmp[1]=a2;
4831   return Aggregate(tmp);
4832 }
4833
4834 /*!
4835  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4836  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4837  * the number of component in the result array is same as that of each of given arrays.
4838  * Info on components is copied from the first of the given arrays. Number of components
4839  * in the given arrays must be  the same.
4840  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
4841  * not the object itself.
4842  *  \param [in] arr - a sequence of arrays to include in the result array.
4843  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4844  *          The caller is to delete this result array using decrRef() as it is no more
4845  *          needed.
4846  *  \throw If all arrays within \a arr are NULL.
4847  *  \throw If getNumberOfComponents() of arrays within \a arr.
4848  */
4849 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
4850 {
4851   std::vector<const DataArrayDouble *> a;
4852   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4853     if(*it4)
4854       a.push_back(*it4);
4855   if(a.empty())
4856     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4857   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4858   int nbOfComp=(*it)->getNumberOfComponents();
4859   int nbt=(*it++)->getNumberOfTuples();
4860   for(int i=1;it!=a.end();it++,i++)
4861     {
4862       if((*it)->getNumberOfComponents()!=nbOfComp)
4863         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4864       nbt+=(*it)->getNumberOfTuples();
4865     }
4866   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4867   ret->alloc(nbt,nbOfComp);
4868   double *pt=ret->getPointer();
4869   for(it=a.begin();it!=a.end();it++)
4870     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4871   ret->copyStringInfoFrom(*(a[0]));
4872   return ret.retn();
4873 }
4874
4875 /*!
4876  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4877  * of components in the result array is a sum of the number of components of given arrays
4878  * and (2) the number of tuples in the result array is same as that of each of given
4879  * arrays. In other words the i-th tuple of result array includes all components of
4880  * i-th tuples of all given arrays.
4881  * Number of tuples in the given arrays must be  the same.
4882  *  \param [in] a1 - an array to include in the result array.
4883  *  \param [in] a2 - another array to include in the result array.
4884  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4885  *          The caller is to delete this result array using decrRef() as it is no more
4886  *          needed.
4887  *  \throw If both \a a1 and \a a2 are NULL.
4888  *  \throw If any given array is not allocated.
4889  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4890  */
4891 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
4892 {
4893   std::vector<const DataArrayDouble *> arr(2);
4894   arr[0]=a1; arr[1]=a2;
4895   return Meld(arr);
4896 }
4897
4898 /*!
4899  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4900  * of components in the result array is a sum of the number of components of given arrays
4901  * and (2) the number of tuples in the result array is same as that of each of given
4902  * arrays. In other words the i-th tuple of result array includes all components of
4903  * i-th tuples of all given arrays.
4904  * Number of tuples in the given arrays must be  the same.
4905  *  \param [in] arr - a sequence of arrays to include in the result array.
4906  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4907  *          The caller is to delete this result array using decrRef() as it is no more
4908  *          needed.
4909  *  \throw If all arrays within \a arr are NULL.
4910  *  \throw If any given array is not allocated.
4911  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4912  */
4913 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
4914 {
4915   std::vector<const DataArrayDouble *> a;
4916   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4917     if(*it4)
4918       a.push_back(*it4);
4919   if(a.empty())
4920     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4921   std::vector<const DataArrayDouble *>::const_iterator it;
4922   for(it=a.begin();it!=a.end();it++)
4923     (*it)->checkAllocated();
4924   it=a.begin();
4925   int nbOfTuples=(*it)->getNumberOfTuples();
4926   std::vector<int> nbc(a.size());
4927   std::vector<const double *> pts(a.size());
4928   nbc[0]=(*it)->getNumberOfComponents();
4929   pts[0]=(*it++)->getConstPointer();
4930   for(int i=1;it!=a.end();it++,i++)
4931     {
4932       if(nbOfTuples!=(*it)->getNumberOfTuples())
4933         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4934       nbc[i]=(*it)->getNumberOfComponents();
4935       pts[i]=(*it)->getConstPointer();
4936     }
4937   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4938   DataArrayDouble *ret=DataArrayDouble::New();
4939   ret->alloc(nbOfTuples,totalNbOfComp);
4940   double *retPtr=ret->getPointer();
4941   for(int i=0;i<nbOfTuples;i++)
4942     for(int j=0;j<(int)a.size();j++)
4943       {
4944         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4945         pts[j]+=nbc[j];
4946       }
4947   int k=0;
4948   for(int i=0;i<(int)a.size();i++)
4949     for(int j=0;j<nbc[i];j++,k++)
4950       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
4951   return ret;
4952 }
4953
4954 /*!
4955  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4956  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4957  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4958  * Info on components and name is copied from the first of the given arrays.
4959  * Number of tuples and components in the given arrays must be the same.
4960  *  \param [in] a1 - a given array.
4961  *  \param [in] a2 - another given array.
4962  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4963  *          The caller is to delete this result array using decrRef() as it is no more
4964  *          needed.
4965  *  \throw If either \a a1 or \a a2 is NULL.
4966  *  \throw If any given array is not allocated.
4967  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4968  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4969  */
4970 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
4971 {
4972   if(!a1 || !a2)
4973     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4974   a1->checkAllocated();
4975   a2->checkAllocated();
4976   int nbOfComp=a1->getNumberOfComponents();
4977   if(nbOfComp!=a2->getNumberOfComponents())
4978     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4979   int nbOfTuple=a1->getNumberOfTuples();
4980   if(nbOfTuple!=a2->getNumberOfTuples())
4981     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4982   DataArrayDouble *ret=DataArrayDouble::New();
4983   ret->alloc(nbOfTuple,1);
4984   double *retPtr=ret->getPointer();
4985   const double *a1Ptr=a1->getConstPointer();
4986   const double *a2Ptr=a2->getConstPointer();
4987   for(int i=0;i<nbOfTuple;i++)
4988     {
4989       double sum=0.;
4990       for(int j=0;j<nbOfComp;j++)
4991         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4992       retPtr[i]=sum;
4993     }
4994   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
4995   ret->setName(a1->getName());
4996   return ret;
4997 }
4998
4999 /*!
5000  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
5001  * the i-th tuple of the result array contains 3 components of a vector which is a cross
5002  * product of two vectors defined by the i-th tuples of given arrays.
5003  * Info on components is copied from the first of the given arrays.
5004  * Number of tuples in the given arrays must be the same.
5005  * Number of components in the given arrays must be 3.
5006  *  \param [in] a1 - a given array.
5007  *  \param [in] a2 - another given array.
5008  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5009  *          The caller is to delete this result array using decrRef() as it is no more
5010  *          needed.
5011  *  \throw If either \a a1 or \a a2 is NULL.
5012  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5013  *  \throw If \a a1->getNumberOfComponents() != 3
5014  *  \throw If \a a2->getNumberOfComponents() != 3
5015  */
5016 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
5017 {
5018   if(!a1 || !a2)
5019     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
5020   int nbOfComp=a1->getNumberOfComponents();
5021   if(nbOfComp!=a2->getNumberOfComponents())
5022     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
5023   if(nbOfComp!=3)
5024     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
5025   int nbOfTuple=a1->getNumberOfTuples();
5026   if(nbOfTuple!=a2->getNumberOfTuples())
5027     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
5028   DataArrayDouble *ret=DataArrayDouble::New();
5029   ret->alloc(nbOfTuple,3);
5030   double *retPtr=ret->getPointer();
5031   const double *a1Ptr=a1->getConstPointer();
5032   const double *a2Ptr=a2->getConstPointer();
5033   for(int i=0;i<nbOfTuple;i++)
5034     {
5035       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
5036       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
5037       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
5038     }
5039   ret->copyStringInfoFrom(*a1);
5040   return ret;
5041 }
5042
5043 /*!
5044  * Returns a new DataArrayDouble containing maximal values of two given arrays.
5045  * Info on components is copied from the first of the given arrays.
5046  * Number of tuples and components in the given arrays must be the same.
5047  *  \param [in] a1 - an array to compare values with another one.
5048  *  \param [in] a2 - another array to compare values with the first one.
5049  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5050  *          The caller is to delete this result array using decrRef() as it is no more
5051  *          needed.
5052  *  \throw If either \a a1 or \a a2 is NULL.
5053  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5054  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
5055  */
5056 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
5057 {
5058   if(!a1 || !a2)
5059     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
5060   int nbOfComp=a1->getNumberOfComponents();
5061   if(nbOfComp!=a2->getNumberOfComponents())
5062     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
5063   int nbOfTuple=a1->getNumberOfTuples();
5064   if(nbOfTuple!=a2->getNumberOfTuples())
5065     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
5066   DataArrayDouble *ret=DataArrayDouble::New();
5067   ret->alloc(nbOfTuple,nbOfComp);
5068   double *retPtr=ret->getPointer();
5069   const double *a1Ptr=a1->getConstPointer();
5070   const double *a2Ptr=a2->getConstPointer();
5071   int nbElem=nbOfTuple*nbOfComp;
5072   for(int i=0;i<nbElem;i++)
5073     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
5074   ret->copyStringInfoFrom(*a1);
5075   return ret;
5076 }
5077
5078 /*!
5079  * Returns a new DataArrayDouble containing minimal values of two given arrays.
5080  * Info on components is copied from the first of the given arrays.
5081  * Number of tuples and components in the given arrays must be the same.
5082  *  \param [in] a1 - an array to compare values with another one.
5083  *  \param [in] a2 - another array to compare values with the first one.
5084  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5085  *          The caller is to delete this result array using decrRef() as it is no more
5086  *          needed.
5087  *  \throw If either \a a1 or \a a2 is NULL.
5088  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5089  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
5090  */
5091 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
5092 {
5093   if(!a1 || !a2)
5094     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
5095   int nbOfComp=a1->getNumberOfComponents();
5096   if(nbOfComp!=a2->getNumberOfComponents())
5097     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
5098   int nbOfTuple=a1->getNumberOfTuples();
5099   if(nbOfTuple!=a2->getNumberOfTuples())
5100     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
5101   DataArrayDouble *ret=DataArrayDouble::New();
5102   ret->alloc(nbOfTuple,nbOfComp);
5103   double *retPtr=ret->getPointer();
5104   const double *a1Ptr=a1->getConstPointer();
5105   const double *a2Ptr=a2->getConstPointer();
5106   int nbElem=nbOfTuple*nbOfComp;
5107   for(int i=0;i<nbElem;i++)
5108     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
5109   ret->copyStringInfoFrom(*a1);
5110   return ret;
5111 }
5112
5113 /*!
5114  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
5115  * valid cases.
5116  * 1.  The arrays have same number of tuples and components. Then each value of
5117  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
5118  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
5119  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5120  *   component. Then
5121  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
5122  * 3.  The arrays have same number of components and one array, say _a2_, has one
5123  *   tuple. Then
5124  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
5125  *
5126  * Info on components is copied either from the first array (in the first case) or from
5127  * the array with maximal number of elements (getNbOfElems()).
5128  *  \param [in] a1 - an array to sum up.
5129  *  \param [in] a2 - another array to sum up.
5130  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5131  *          The caller is to delete this result array using decrRef() as it is no more
5132  *          needed.
5133  *  \throw If either \a a1 or \a a2 is NULL.
5134  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5135  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5136  *         none of them has number of tuples or components equal to 1.
5137  */
5138 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
5139 {
5140   if(!a1 || !a2)
5141     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
5142   int nbOfTuple=a1->getNumberOfTuples();
5143   int nbOfTuple2=a2->getNumberOfTuples();
5144   int nbOfComp=a1->getNumberOfComponents();
5145   int nbOfComp2=a2->getNumberOfComponents();
5146   MCAuto<DataArrayDouble> ret=0;
5147   if(nbOfTuple==nbOfTuple2)
5148     {
5149       if(nbOfComp==nbOfComp2)
5150         {
5151           ret=DataArrayDouble::New();
5152           ret->alloc(nbOfTuple,nbOfComp);
5153           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
5154           ret->copyStringInfoFrom(*a1);
5155         }
5156       else
5157         {
5158           int nbOfCompMin,nbOfCompMax;
5159           const DataArrayDouble *aMin, *aMax;
5160           if(nbOfComp>nbOfComp2)
5161             {
5162               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5163               aMin=a2; aMax=a1;
5164             }
5165           else
5166             {
5167               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5168               aMin=a1; aMax=a2;
5169             }
5170           if(nbOfCompMin==1)
5171             {
5172               ret=DataArrayDouble::New();
5173               ret->alloc(nbOfTuple,nbOfCompMax);
5174               const double *aMinPtr=aMin->getConstPointer();
5175               const double *aMaxPtr=aMax->getConstPointer();
5176               double *res=ret->getPointer();
5177               for(int i=0;i<nbOfTuple;i++)
5178                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
5179               ret->copyStringInfoFrom(*aMax);
5180             }
5181           else
5182             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5183         }
5184     }
5185   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5186     {
5187       if(nbOfComp==nbOfComp2)
5188         {
5189           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5190           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5191           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5192           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5193           ret=DataArrayDouble::New();
5194           ret->alloc(nbOfTupleMax,nbOfComp);
5195           double *res=ret->getPointer();
5196           for(int i=0;i<nbOfTupleMax;i++)
5197             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
5198           ret->copyStringInfoFrom(*aMax);
5199         }
5200       else
5201         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5202     }
5203   else
5204     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
5205   return ret.retn();
5206 }
5207
5208 /*!
5209  * Adds values of another DataArrayDouble to values of \a this one. There are 3
5210  * valid cases.
5211  * 1.  The arrays have same number of tuples and components. Then each value of
5212  *   \a other array is added to the corresponding value of \a this array, i.e.:
5213  *   _a_ [ i, j ] += _other_ [ i, j ].
5214  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5215  *   _a_ [ i, j ] += _other_ [ i, 0 ].
5216  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5217  *   _a_ [ i, j ] += _a2_ [ 0, j ].
5218  *
5219  *  \param [in] other - an array to add to \a this one.
5220  *  \throw If \a other is NULL.
5221  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5222  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5223  *         \a other has number of both tuples and components not equal to 1.
5224  */
5225 void DataArrayDouble::addEqual(const DataArrayDouble *other)
5226 {
5227   if(!other)
5228     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
5229   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
5230   checkAllocated();
5231   other->checkAllocated();
5232   int nbOfTuple=getNumberOfTuples();
5233   int nbOfTuple2=other->getNumberOfTuples();
5234   int nbOfComp=getNumberOfComponents();
5235   int nbOfComp2=other->getNumberOfComponents();
5236   if(nbOfTuple==nbOfTuple2)
5237     {
5238       if(nbOfComp==nbOfComp2)
5239         {
5240           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
5241         }
5242       else if(nbOfComp2==1)
5243         {
5244           double *ptr=getPointer();
5245           const double *ptrc=other->getConstPointer();
5246           for(int i=0;i<nbOfTuple;i++)
5247             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
5248         }
5249       else
5250         throw INTERP_KERNEL::Exception(msg);
5251     }
5252   else if(nbOfTuple2==1)
5253     {
5254       if(nbOfComp2==nbOfComp)
5255         {
5256           double *ptr=getPointer();
5257           const double *ptrc=other->getConstPointer();
5258           for(int i=0;i<nbOfTuple;i++)
5259             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
5260         }
5261       else
5262         throw INTERP_KERNEL::Exception(msg);
5263     }
5264   else
5265     throw INTERP_KERNEL::Exception(msg);
5266   declareAsNew();
5267 }
5268
5269 /*!
5270  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
5271  * valid cases.
5272  * 1.  The arrays have same number of tuples and components. Then each value of
5273  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
5274  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
5275  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5276  *   component. Then
5277  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
5278  * 3.  The arrays have same number of components and one array, say _a2_, has one
5279  *   tuple. Then
5280  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
5281  *
5282  * Info on components is copied either from the first array (in the first case) or from
5283  * the array with maximal number of elements (getNbOfElems()).
5284  *  \param [in] a1 - an array to subtract from.
5285  *  \param [in] a2 - an array to subtract.
5286  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5287  *          The caller is to delete this result array using decrRef() as it is no more
5288  *          needed.
5289  *  \throw If either \a a1 or \a a2 is NULL.
5290  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5291  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5292  *         none of them has number of tuples or components equal to 1.
5293  */
5294 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
5295 {
5296   if(!a1 || !a2)
5297     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
5298   int nbOfTuple1=a1->getNumberOfTuples();
5299   int nbOfTuple2=a2->getNumberOfTuples();
5300   int nbOfComp1=a1->getNumberOfComponents();
5301   int nbOfComp2=a2->getNumberOfComponents();
5302   if(nbOfTuple2==nbOfTuple1)
5303     {
5304       if(nbOfComp1==nbOfComp2)
5305         {
5306           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5307           ret->alloc(nbOfTuple2,nbOfComp1);
5308           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
5309           ret->copyStringInfoFrom(*a1);
5310           return ret.retn();
5311         }
5312       else if(nbOfComp2==1)
5313         {
5314           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5315           ret->alloc(nbOfTuple1,nbOfComp1);
5316           const double *a2Ptr=a2->getConstPointer();
5317           const double *a1Ptr=a1->getConstPointer();
5318           double *res=ret->getPointer();
5319           for(int i=0;i<nbOfTuple1;i++)
5320             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
5321           ret->copyStringInfoFrom(*a1);
5322           return ret.retn();
5323         }
5324       else
5325         {
5326           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5327           return 0;
5328         }
5329     }
5330   else if(nbOfTuple2==1)
5331     {
5332       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5333       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5334       ret->alloc(nbOfTuple1,nbOfComp1);
5335       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5336       double *pt=ret->getPointer();
5337       for(int i=0;i<nbOfTuple1;i++)
5338         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
5339       ret->copyStringInfoFrom(*a1);
5340       return ret.retn();
5341     }
5342   else
5343     {
5344       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
5345       return 0;
5346     }
5347 }
5348
5349 /*!
5350  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
5351  * valid cases.
5352  * 1.  The arrays have same number of tuples and components. Then each value of
5353  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
5354  *   _a_ [ i, j ] -= _other_ [ i, j ].
5355  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5356  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
5357  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5358  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
5359  *
5360  *  \param [in] other - an array to subtract from \a this one.
5361  *  \throw If \a other is NULL.
5362  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5363  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5364  *         \a other has number of both tuples and components not equal to 1.
5365  */
5366 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
5367 {
5368   if(!other)
5369     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
5370   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
5371   checkAllocated();
5372   other->checkAllocated();
5373   int nbOfTuple=getNumberOfTuples();
5374   int nbOfTuple2=other->getNumberOfTuples();
5375   int nbOfComp=getNumberOfComponents();
5376   int nbOfComp2=other->getNumberOfComponents();
5377   if(nbOfTuple==nbOfTuple2)
5378     {
5379       if(nbOfComp==nbOfComp2)
5380         {
5381           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5382         }
5383       else if(nbOfComp2==1)
5384         {
5385           double *ptr=getPointer();
5386           const double *ptrc=other->getConstPointer();
5387           for(int i=0;i<nbOfTuple;i++)
5388             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5389         }
5390       else
5391         throw INTERP_KERNEL::Exception(msg);
5392     }
5393   else if(nbOfTuple2==1)
5394     {
5395       if(nbOfComp2==nbOfComp)
5396         {
5397           double *ptr=getPointer();
5398           const double *ptrc=other->getConstPointer();
5399           for(int i=0;i<nbOfTuple;i++)
5400             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5401         }
5402       else
5403         throw INTERP_KERNEL::Exception(msg);
5404     }
5405   else
5406     throw INTERP_KERNEL::Exception(msg);
5407   declareAsNew();
5408 }
5409
5410 /*!
5411  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5412  * valid cases.
5413  * 1.  The arrays have same number of tuples and components. Then each value of
5414  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5415  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5416  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5417  *   component. Then
5418  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5419  * 3.  The arrays have same number of components and one array, say _a2_, has one
5420  *   tuple. Then
5421  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5422  *
5423  * Info on components is copied either from the first array (in the first case) or from
5424  * the array with maximal number of elements (getNbOfElems()).
5425  *  \param [in] a1 - a factor array.
5426  *  \param [in] a2 - another factor array.
5427  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5428  *          The caller is to delete this result array using decrRef() as it is no more
5429  *          needed.
5430  *  \throw If either \a a1 or \a a2 is NULL.
5431  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5432  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5433  *         none of them has number of tuples or components equal to 1.
5434  */
5435 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
5436 {
5437   if(!a1 || !a2)
5438     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5439   int nbOfTuple=a1->getNumberOfTuples();
5440   int nbOfTuple2=a2->getNumberOfTuples();
5441   int nbOfComp=a1->getNumberOfComponents();
5442   int nbOfComp2=a2->getNumberOfComponents();
5443   MCAuto<DataArrayDouble> ret=0;
5444   if(nbOfTuple==nbOfTuple2)
5445     {
5446       if(nbOfComp==nbOfComp2)
5447         {
5448           ret=DataArrayDouble::New();
5449           ret->alloc(nbOfTuple,nbOfComp);
5450           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5451           ret->copyStringInfoFrom(*a1);
5452         }
5453       else
5454         {
5455           int nbOfCompMin,nbOfCompMax;
5456           const DataArrayDouble *aMin, *aMax;
5457           if(nbOfComp>nbOfComp2)
5458             {
5459               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5460               aMin=a2; aMax=a1;
5461             }
5462           else
5463             {
5464               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5465               aMin=a1; aMax=a2;
5466             }
5467           if(nbOfCompMin==1)
5468             {
5469               ret=DataArrayDouble::New();
5470               ret->alloc(nbOfTuple,nbOfCompMax);
5471               const double *aMinPtr=aMin->getConstPointer();
5472               const double *aMaxPtr=aMax->getConstPointer();
5473               double *res=ret->getPointer();
5474               for(int i=0;i<nbOfTuple;i++)
5475                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5476               ret->copyStringInfoFrom(*aMax);
5477             }
5478           else
5479             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5480         }
5481     }
5482   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5483     {
5484       if(nbOfComp==nbOfComp2)
5485         {
5486           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5487           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5488           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5489           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5490           ret=DataArrayDouble::New();
5491           ret->alloc(nbOfTupleMax,nbOfComp);
5492           double *res=ret->getPointer();
5493           for(int i=0;i<nbOfTupleMax;i++)
5494             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5495           ret->copyStringInfoFrom(*aMax);
5496         }
5497       else
5498         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5499     }
5500   else
5501     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5502   return ret.retn();
5503 }
5504
5505 /*!
5506  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5507  * valid cases.
5508  * 1.  The arrays have same number of tuples and components. Then each value of
5509  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5510  *   _this_ [ i, j ] *= _other_ [ i, j ].
5511  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5512  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5513  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5514  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5515  *
5516  *  \param [in] other - an array to multiply to \a this one.
5517  *  \throw If \a other is NULL.
5518  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5519  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5520  *         \a other has number of both tuples and components not equal to 1.
5521  */
5522 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
5523 {
5524   if(!other)
5525     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5526   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5527   checkAllocated();
5528   other->checkAllocated();
5529   int nbOfTuple=getNumberOfTuples();
5530   int nbOfTuple2=other->getNumberOfTuples();
5531   int nbOfComp=getNumberOfComponents();
5532   int nbOfComp2=other->getNumberOfComponents();
5533   if(nbOfTuple==nbOfTuple2)
5534     {
5535       if(nbOfComp==nbOfComp2)
5536         {
5537           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5538         }
5539       else if(nbOfComp2==1)
5540         {
5541           double *ptr=getPointer();
5542           const double *ptrc=other->getConstPointer();
5543           for(int i=0;i<nbOfTuple;i++)
5544             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5545         }
5546       else
5547         throw INTERP_KERNEL::Exception(msg);
5548     }
5549   else if(nbOfTuple2==1)
5550     {
5551       if(nbOfComp2==nbOfComp)
5552         {
5553           double *ptr=getPointer();
5554           const double *ptrc=other->getConstPointer();
5555           for(int i=0;i<nbOfTuple;i++)
5556             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5557         }
5558       else
5559         throw INTERP_KERNEL::Exception(msg);
5560     }
5561   else
5562     throw INTERP_KERNEL::Exception(msg);
5563   declareAsNew();
5564 }
5565
5566 /*!
5567  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5568  * valid cases.
5569  * 1.  The arrays have same number of tuples and components. Then each value of
5570  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5571  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5572  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5573  *   component. Then
5574  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5575  * 3.  The arrays have same number of components and one array, say _a2_, has one
5576  *   tuple. Then
5577  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5578  *
5579  * Info on components is copied either from the first array (in the first case) or from
5580  * the array with maximal number of elements (getNbOfElems()).
5581  *  \warning No check of division by zero is performed!
5582  *  \param [in] a1 - a numerator array.
5583  *  \param [in] a2 - a denominator array.
5584  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5585  *          The caller is to delete this result array using decrRef() as it is no more
5586  *          needed.
5587  *  \throw If either \a a1 or \a a2 is NULL.
5588  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5589  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5590  *         none of them has number of tuples or components equal to 1.
5591  */
5592 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
5593 {
5594   if(!a1 || !a2)
5595     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5596   int nbOfTuple1=a1->getNumberOfTuples();
5597   int nbOfTuple2=a2->getNumberOfTuples();
5598   int nbOfComp1=a1->getNumberOfComponents();
5599   int nbOfComp2=a2->getNumberOfComponents();
5600   if(nbOfTuple2==nbOfTuple1)
5601     {
5602       if(nbOfComp1==nbOfComp2)
5603         {
5604           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5605           ret->alloc(nbOfTuple2,nbOfComp1);
5606           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5607           ret->copyStringInfoFrom(*a1);
5608           return ret.retn();
5609         }
5610       else if(nbOfComp2==1)
5611         {
5612           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5613           ret->alloc(nbOfTuple1,nbOfComp1);
5614           const double *a2Ptr=a2->getConstPointer();
5615           const double *a1Ptr=a1->getConstPointer();
5616           double *res=ret->getPointer();
5617           for(int i=0;i<nbOfTuple1;i++)
5618             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5619           ret->copyStringInfoFrom(*a1);
5620           return ret.retn();
5621         }
5622       else
5623         {
5624           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5625           return 0;
5626         }
5627     }
5628   else if(nbOfTuple2==1)
5629     {
5630       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5631       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5632       ret->alloc(nbOfTuple1,nbOfComp1);
5633       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5634       double *pt=ret->getPointer();
5635       for(int i=0;i<nbOfTuple1;i++)
5636         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5637       ret->copyStringInfoFrom(*a1);
5638       return ret.retn();
5639     }
5640   else
5641     {
5642       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5643       return 0;
5644     }
5645 }
5646
5647 /*!
5648  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5649  * valid cases.
5650  * 1.  The arrays have same number of tuples and components. Then each value of
5651  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5652  *   _a_ [ i, j ] /= _other_ [ i, j ].
5653  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5654  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5655  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5656  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5657  *
5658  *  \warning No check of division by zero is performed!
5659  *  \param [in] other - an array to divide \a this one by.
5660  *  \throw If \a other is NULL.
5661  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5662  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5663  *         \a other has number of both tuples and components not equal to 1.
5664  */
5665 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
5666 {
5667   if(!other)
5668     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5669   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5670   checkAllocated();
5671   other->checkAllocated();
5672   int nbOfTuple=getNumberOfTuples();
5673   int nbOfTuple2=other->getNumberOfTuples();
5674   int nbOfComp=getNumberOfComponents();
5675   int nbOfComp2=other->getNumberOfComponents();
5676   if(nbOfTuple==nbOfTuple2)
5677     {
5678       if(nbOfComp==nbOfComp2)
5679         {
5680           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5681         }
5682       else if(nbOfComp2==1)
5683         {
5684           double *ptr=getPointer();
5685           const double *ptrc=other->getConstPointer();
5686           for(int i=0;i<nbOfTuple;i++)
5687             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5688         }
5689       else
5690         throw INTERP_KERNEL::Exception(msg);
5691     }
5692   else if(nbOfTuple2==1)
5693     {
5694       if(nbOfComp2==nbOfComp)
5695         {
5696           double *ptr=getPointer();
5697           const double *ptrc=other->getConstPointer();
5698           for(int i=0;i<nbOfTuple;i++)
5699             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5700         }
5701       else
5702         throw INTERP_KERNEL::Exception(msg);
5703     }
5704   else
5705     throw INTERP_KERNEL::Exception(msg);
5706   declareAsNew();
5707 }
5708
5709 /*!
5710  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5711  * valid cases.
5712  *
5713  *  \param [in] a1 - an array to pow up.
5714  *  \param [in] a2 - another array to sum up.
5715  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5716  *          The caller is to delete this result array using decrRef() as it is no more
5717  *          needed.
5718  *  \throw If either \a a1 or \a a2 is NULL.
5719  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5720  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5721  *  \throw If there is a negative value in \a a1.
5722  */
5723 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
5724 {
5725   if(!a1 || !a2)
5726     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5727   int nbOfTuple=a1->getNumberOfTuples();
5728   int nbOfTuple2=a2->getNumberOfTuples();
5729   int nbOfComp=a1->getNumberOfComponents();
5730   int nbOfComp2=a2->getNumberOfComponents();
5731   if(nbOfTuple!=nbOfTuple2)
5732     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5733   if(nbOfComp!=1 || nbOfComp2!=1)
5734     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5735   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5736   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5737   double *ptr=ret->getPointer();
5738   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5739     {
5740       if(*ptr1>=0)
5741         {
5742           *ptr=pow(*ptr1,*ptr2);
5743         }
5744       else
5745         {
5746           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5747           throw INTERP_KERNEL::Exception(oss.str().c_str());
5748         }
5749     }
5750   return ret.retn();
5751 }
5752
5753 /*!
5754  * Apply pow on values of another DataArrayDouble to values of \a this one.
5755  *
5756  *  \param [in] other - an array to pow to \a this one.
5757  *  \throw If \a other is NULL.
5758  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5759  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5760  *  \throw If there is a negative value in \a this.
5761  */
5762 void DataArrayDouble::powEqual(const DataArrayDouble *other)
5763 {
5764   if(!other)
5765     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5766   int nbOfTuple=getNumberOfTuples();
5767   int nbOfTuple2=other->getNumberOfTuples();
5768   int nbOfComp=getNumberOfComponents();
5769   int nbOfComp2=other->getNumberOfComponents();
5770   if(nbOfTuple!=nbOfTuple2)
5771     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5772   if(nbOfComp!=1 || nbOfComp2!=1)
5773     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5774   double *ptr=getPointer();
5775   const double *ptrc=other->begin();
5776   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5777     {
5778       if(*ptr>=0)
5779         *ptr=pow(*ptr,*ptrc);
5780       else
5781         {
5782           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5783           throw INTERP_KERNEL::Exception(oss.str().c_str());
5784         }
5785     }
5786   declareAsNew();
5787 }
5788
5789 /*!
5790  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
5791  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
5792  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
5793  *
5794  * \throw if \a this is not allocated.
5795  * \throw if \a this has not exactly one component.
5796  */
5797 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
5798 {
5799   checkAllocated();
5800   if(getNumberOfComponents()!=1)
5801     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
5802   int nbt(getNumberOfTuples());
5803   std::vector<bool> ret(nbt);
5804   const double *pt(begin());
5805   for(int i=0;i<nbt;i++)
5806     {
5807       if(fabs(pt[i])<eps)
5808         ret[i]=false;
5809       else if(fabs(pt[i]-1.)<eps)
5810         ret[i]=true;
5811       else
5812         {
5813           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
5814           throw INTERP_KERNEL::Exception(oss.str().c_str());
5815         }
5816     }
5817   return ret;
5818 }
5819
5820 /*!
5821  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5822  * Server side.
5823  */
5824 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5825 {
5826   tinyInfo.resize(2);
5827   if(isAllocated())
5828     {
5829       tinyInfo[0]=getNumberOfTuples();
5830       tinyInfo[1]=getNumberOfComponents();
5831     }
5832   else
5833     {
5834       tinyInfo[0]=-1;
5835       tinyInfo[1]=-1;
5836     }
5837 }
5838
5839 /*!
5840  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5841  * Server side.
5842  */
5843 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5844 {
5845   if(isAllocated())
5846     {
5847       int nbOfCompo=getNumberOfComponents();
5848       tinyInfo.resize(nbOfCompo+1);
5849       tinyInfo[0]=getName();
5850       for(int i=0;i<nbOfCompo;i++)
5851         tinyInfo[i+1]=getInfoOnComponent(i);
5852     }
5853   else
5854     {
5855       tinyInfo.resize(1);
5856       tinyInfo[0]=getName();
5857     }
5858 }
5859
5860 /*!
5861  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5862  * This method returns if a feeding is needed.
5863  */
5864 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5865 {
5866   int nbOfTuple=tinyInfoI[0];
5867   int nbOfComp=tinyInfoI[1];
5868   if(nbOfTuple!=-1 || nbOfComp!=-1)
5869     {
5870       alloc(nbOfTuple,nbOfComp);
5871       return true;
5872     }
5873   return false;
5874 }
5875
5876 /*!
5877  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5878  */
5879 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5880 {
5881   setName(tinyInfoS[0]);
5882   if(isAllocated())
5883     {
5884       int nbOfCompo=getNumberOfComponents();
5885       for(int i=0;i<nbOfCompo;i++)
5886         setInfoOnComponent(i,tinyInfoS[i+1]);
5887     }
5888 }
5889
5890 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5891 {
5892   if(_da)
5893     {
5894       _da->incrRef();
5895       if(_da->isAllocated())
5896         {
5897           _nb_comp=da->getNumberOfComponents();
5898           _nb_tuple=da->getNumberOfTuples();
5899           _pt=da->getPointer();
5900         }
5901     }
5902 }
5903
5904 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5905 {
5906   if(_da)
5907     _da->decrRef();
5908 }
5909
5910 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
5911 {
5912   if(_tuple_id<_nb_tuple)
5913     {
5914       _tuple_id++;
5915       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5916       _pt+=_nb_comp;
5917       return ret;
5918     }
5919   else
5920     return 0;
5921 }
5922
5923 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5924 {
5925 }
5926
5927
5928 std::string DataArrayDoubleTuple::repr() const
5929 {
5930   std::ostringstream oss; oss.precision(17); oss << "(";
5931   for(int i=0;i<_nb_of_compo-1;i++)
5932     oss << _pt[i] << ", ";
5933   oss << _pt[_nb_of_compo-1] << ")";
5934   return oss.str();
5935 }
5936
5937 double DataArrayDoubleTuple::doubleValue() const
5938 {
5939   if(_nb_of_compo==1)
5940     return *_pt;
5941   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5942 }
5943
5944 /*!
5945  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
5946  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
5947  * 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
5948  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5949  */
5950 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
5951 {
5952   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5953     {
5954       DataArrayDouble *ret=DataArrayDouble::New();
5955       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5956       return ret;
5957     }
5958   else
5959     {
5960       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5961       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5962       throw INTERP_KERNEL::Exception(oss.str().c_str());
5963     }
5964 }
5965
5966 /*!
5967  * Returns a new instance of DataArrayInt. The caller is to delete this array
5968  * using decrRef() as it is no more needed. 
5969  */
5970 DataArrayInt *DataArrayInt::New()
5971 {
5972   return new DataArrayInt;
5973 }
5974
5975 /*!
5976  * Checks if raw data is allocated. Read more on the raw data
5977  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5978  *  \return bool - \a true if the raw data is allocated, \a false else.
5979  */
5980 bool DataArrayInt::isAllocated() const
5981 {
5982   return getConstPointer()!=0;
5983 }
5984
5985 /*!
5986  * Checks if raw data is allocated and throws an exception if it is not the case.
5987  *  \throw If the raw data is not allocated.
5988  */
5989 void DataArrayInt::checkAllocated() const
5990 {
5991   if(!isAllocated())
5992     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5993 }
5994
5995 /*!
5996  * This method desallocated \a this without modification of informations relative to the components.
5997  * After call of this method, DataArrayInt::isAllocated will return false.
5998  * If \a this is already not allocated, \a this is let unchanged.
5999  */
6000 void DataArrayInt::desallocate()
6001 {
6002   _mem.destroy();
6003 }
6004
6005 std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
6006 {
6007   std::size_t sz(_mem.getNbOfElemAllocated());
6008   sz*=sizeof(int);
6009   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
6010 }
6011
6012 /*!
6013  * Returns the only one value in \a this, if and only if number of elements
6014  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
6015  *  \return double - the sole value stored in \a this array.
6016  *  \throw If at least one of conditions stated above is not fulfilled.
6017  */
6018 int DataArrayInt::intValue() const
6019 {
6020   if(isAllocated())
6021     {
6022       if(getNbOfElems()==1)
6023         {
6024           return *getConstPointer();
6025         }
6026       else
6027         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
6028     }
6029   else
6030     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
6031 }
6032
6033 /*!
6034  * Returns an integer value characterizing \a this array, which is useful for a quick
6035  * comparison of many instances of DataArrayInt.
6036  *  \return int - the hash value.
6037  *  \throw If \a this is not allocated.
6038  */
6039 int DataArrayInt::getHashCode() const
6040 {
6041   checkAllocated();
6042   std::size_t nbOfElems=getNbOfElems();
6043   int ret=nbOfElems*65536;
6044   int delta=3;
6045   if(nbOfElems>48)
6046     delta=nbOfElems/8;
6047   int ret0=0;
6048   const int *pt=begin();
6049   for(std::size_t i=0;i<nbOfElems;i+=delta)
6050     ret0+=pt[i] & 0x1FFF;
6051   return ret+ret0;
6052 }
6053
6054 /*!
6055  * Checks the number of tuples.
6056  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
6057  *  \throw If \a this is not allocated.
6058  */
6059 bool DataArrayInt::empty() const
6060 {
6061   checkAllocated();
6062   return getNumberOfTuples()==0;
6063 }
6064
6065 /*!
6066  * Returns a full copy of \a this. For more info on copying data arrays see
6067  * \ref MEDCouplingArrayBasicsCopyDeep.
6068  *  \return DataArrayInt * - a new instance of DataArrayInt.
6069  */
6070 DataArrayInt *DataArrayInt::deepCopy() const
6071 {
6072   return new DataArrayInt(*this);
6073 }
6074
6075 /*!
6076  * Returns either a \a deep or \a shallow copy of this array. For more info see
6077  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
6078  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
6079  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
6080  *          == \a true) or \a this instance (if \a dCpy == \a false).
6081  */
6082 DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
6083 {
6084   if(dCpy)
6085     return deepCopy();
6086   else
6087     {
6088       incrRef();
6089       return const_cast<DataArrayInt *>(this);
6090     }
6091 }
6092
6093 /*!
6094  * Copies all the data from another DataArrayInt. For more info see
6095  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
6096  *  \param [in] other - another instance of DataArrayInt to copy data from.
6097  *  \throw If the \a other is not allocated.
6098  */
6099 void DataArrayInt::deepCopyFrom(const DataArrayInt& other)
6100 {
6101   other.checkAllocated();
6102   int nbOfTuples=other.getNumberOfTuples();
6103   int nbOfComp=other.getNumberOfComponents();
6104   allocIfNecessary(nbOfTuples,nbOfComp);
6105   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
6106   int *pt=getPointer();
6107   const int *ptI=other.getConstPointer();
6108   for(std::size_t i=0;i<nbOfElems;i++)
6109     pt[i]=ptI[i];
6110   copyStringInfoFrom(other);
6111 }
6112
6113 /*!
6114  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
6115  * If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown.
6116  * If \a this has not already been allocated, number of components is set to one.
6117  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
6118  * 
6119  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
6120  */
6121 void DataArrayInt::reserve(std::size_t nbOfElems)
6122 {
6123   int nbCompo=getNumberOfComponents();
6124   if(nbCompo==1)
6125     {
6126       _mem.reserve(nbOfElems);
6127     }
6128   else if(nbCompo==0)
6129     {
6130       _mem.reserve(nbOfElems);
6131       _info_on_compo.resize(1);
6132     }
6133   else
6134     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
6135 }
6136
6137 /*!
6138  * This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation
6139  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
6140  *
6141  * \param [in] val the value to be added in \a this
6142  * \throw If \a this has already been allocated with number of components different from one.
6143  * \sa DataArrayInt::pushBackValsSilent
6144  */
6145 void DataArrayInt::pushBackSilent(int val)
6146 {
6147   int nbCompo=getNumberOfComponents();
6148   if(nbCompo==1)
6149     _mem.pushBack(val);
6150   else if(nbCompo==0)
6151     {
6152       _info_on_compo.resize(1);
6153       _mem.pushBack(val);
6154     }
6155   else
6156     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
6157 }
6158
6159 /*!
6160  * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation
6161  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
6162  *
6163  *  \param [in] valsBg - an array of values to push at the end of \c this.
6164  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6165  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6166  * \throw If \a this has already been allocated with number of components different from one.
6167  * \sa DataArrayInt::pushBackSilent
6168  */
6169 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd)
6170 {
6171   int nbCompo=getNumberOfComponents();
6172   if(nbCompo==1)
6173     _mem.insertAtTheEnd(valsBg,valsEnd);
6174   else if(nbCompo==0)
6175     {
6176       _info_on_compo.resize(1);
6177       _mem.insertAtTheEnd(valsBg,valsEnd);
6178     }
6179   else
6180     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
6181 }
6182
6183 /*!
6184  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
6185  * \throw If \a this is already empty.
6186  * \throw If \a this has number of components different from one.
6187  */
6188 int DataArrayInt::popBackSilent()
6189 {
6190   if(getNumberOfComponents()==1)
6191     return _mem.popBack();
6192   else
6193     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
6194 }
6195
6196 /*!
6197  * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store.
6198  *
6199  * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
6200  */
6201 void DataArrayInt::pack() const
6202 {
6203   _mem.pack();
6204 }
6205
6206 /*!
6207  * Allocates the raw data in memory. If exactly as same memory as needed already
6208  * allocated, it is not re-allocated.
6209  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6210  *  \param [in] nbOfCompo - number of components of data to allocate.
6211  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6212  */
6213 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
6214 {
6215   if(isAllocated())
6216     {
6217       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
6218         alloc(nbOfTuple,nbOfCompo);
6219     }
6220   else
6221     alloc(nbOfTuple,nbOfCompo);
6222 }
6223
6224 /*!
6225  * Allocates the raw data in memory. If the memory was already allocated, then it is
6226  * freed and re-allocated. See an example of this method use
6227  * \ref MEDCouplingArraySteps1WC "here".
6228  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6229  *  \param [in] nbOfCompo - number of components of data to allocate.
6230  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6231  */
6232 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
6233 {
6234   if(nbOfTuple<0 || nbOfCompo<0)
6235     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
6236   _info_on_compo.resize(nbOfCompo);
6237   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
6238   declareAsNew();
6239 }
6240
6241 /*!
6242  * Assign zero to all values in \a this array. To know more on filling arrays see
6243  * \ref MEDCouplingArrayFill.
6244  * \throw If \a this is not allocated.
6245  */
6246 void DataArrayInt::fillWithZero()
6247 {
6248   checkAllocated();
6249   _mem.fillWithValue(0);
6250   declareAsNew();
6251 }
6252
6253 /*!
6254  * Assign \a val to all values in \a this array. To know more on filling arrays see
6255  * \ref MEDCouplingArrayFill.
6256  *  \param [in] val - the value to fill with.
6257  *  \throw If \a this is not allocated.
6258  */
6259 void DataArrayInt::fillWithValue(int val)
6260 {
6261   checkAllocated();
6262   _mem.fillWithValue(val);
6263   declareAsNew();
6264 }
6265
6266 /*!
6267  * Set all values in \a this array so that the i-th element equals to \a init + i
6268  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
6269  *  \param [in] init - value to assign to the first element of array.
6270  *  \throw If \a this->getNumberOfComponents() != 1
6271  *  \throw If \a this is not allocated.
6272  */
6273 void DataArrayInt::iota(int init)
6274 {
6275   checkAllocated();
6276   if(getNumberOfComponents()!=1)
6277     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
6278   int *ptr=getPointer();
6279   int ntuples=getNumberOfTuples();
6280   for(int i=0;i<ntuples;i++)
6281     ptr[i]=init+i;
6282   declareAsNew();
6283 }
6284
6285 /*!
6286  * Returns a textual and human readable representation of \a this instance of
6287  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
6288  * \return std::string - text describing \a this DataArrayInt.
6289  * 
6290  * \sa reprNotTooLong, reprZip
6291  */
6292 std::string DataArrayInt::repr() const
6293 {
6294   std::ostringstream ret;
6295   reprStream(ret);
6296   return ret.str();
6297 }
6298
6299 std::string DataArrayInt::reprZip() const
6300 {
6301   std::ostringstream ret;
6302   reprZipStream(ret);
6303   return ret.str();
6304 }
6305
6306 /*!
6307  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
6308  * printed out to avoid to consume too much space in interpretor.
6309  * \sa repr
6310  */
6311 std::string DataArrayInt::reprNotTooLong() const
6312 {
6313   std::ostringstream ret;
6314   reprNotTooLongStream(ret);
6315   return ret.str();
6316 }
6317
6318 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
6319 {
6320   static const char SPACE[4]={' ',' ',' ',' '};
6321   checkAllocated();
6322   std::string idt(indent,' ');
6323   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
6324   if(byteArr)
6325     {
6326       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
6327       if(std::string(type)=="Int32")
6328         {
6329           const char *data(reinterpret_cast<const char *>(begin()));
6330           std::size_t sz(getNbOfElems()*sizeof(int));
6331           byteArr->insertAtTheEnd(data,data+sz);
6332           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6333         }
6334       else if(std::string(type)=="Int8")
6335         {
6336           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
6337           std::copy(begin(),end(),(char *)tmp);
6338           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
6339           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6340         }
6341       else if(std::string(type)=="UInt8")
6342         {
6343           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
6344           std::copy(begin(),end(),(unsigned char *)tmp);
6345           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
6346           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6347         }
6348       else
6349         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
6350     }
6351   else
6352     {
6353       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
6354       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
6355     }
6356   ofs << std::endl << idt << "</DataArray>\n";
6357 }
6358
6359 void DataArrayInt::reprStream(std::ostream& stream) const
6360 {
6361   stream << "Name of int array : \"" << _name << "\"\n";
6362   reprWithoutNameStream(stream);
6363 }
6364
6365 void DataArrayInt::reprZipStream(std::ostream& stream) const
6366 {
6367   stream << "Name of int array : \"" << _name << "\"\n";
6368   reprZipWithoutNameStream(stream);
6369 }
6370
6371 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
6372 {
6373   stream << "Name of int array : \"" << _name << "\"\n";
6374   reprNotTooLongWithoutNameStream(stream);
6375 }
6376
6377 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
6378 {
6379   DataArray::reprWithoutNameStream(stream);
6380   _mem.repr(getNumberOfComponents(),stream);
6381 }
6382
6383 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
6384 {
6385   DataArray::reprWithoutNameStream(stream);
6386   _mem.reprZip(getNumberOfComponents(),stream);
6387 }
6388
6389 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
6390 {
6391   DataArray::reprWithoutNameStream(stream);
6392   stream.precision(17);
6393   _mem.reprNotTooLong(getNumberOfComponents(),stream);
6394 }
6395
6396 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
6397 {
6398   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
6399   const int *data=getConstPointer();
6400   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
6401   if(nbTuples*nbComp>=1)
6402     {
6403       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
6404       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
6405       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
6406       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
6407     }
6408   else
6409     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
6410   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
6411 }
6412
6413 /*!
6414  * Method that gives a quick overvien of \a this for python.
6415  */
6416 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
6417 {
6418   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6419   stream << "DataArrayInt C++ instance at " << this << ". ";
6420   if(isAllocated())
6421     {
6422       int nbOfCompo=(int)_info_on_compo.size();
6423       if(nbOfCompo>=1)
6424         {
6425           int nbOfTuples=getNumberOfTuples();
6426           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6427           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6428         }
6429       else
6430         stream << "Number of components : 0.";
6431     }
6432   else
6433     stream << "*** No data allocated ****";
6434 }
6435
6436 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
6437 {
6438   const int *data=begin();
6439   int nbOfTuples=getNumberOfTuples();
6440   int nbOfCompo=(int)_info_on_compo.size();
6441   std::ostringstream oss2; oss2 << "[";
6442   std::string oss2Str(oss2.str());
6443   bool isFinished=true;
6444   for(int i=0;i<nbOfTuples && isFinished;i++)
6445     {
6446       if(nbOfCompo>1)
6447         {
6448           oss2 << "(";
6449           for(int j=0;j<nbOfCompo;j++,data++)
6450             {
6451               oss2 << *data;
6452               if(j!=nbOfCompo-1) oss2 << ", ";
6453             }
6454           oss2 << ")";
6455         }
6456       else
6457         oss2 << *data++;
6458       if(i!=nbOfTuples-1) oss2 << ", ";
6459       std::string oss3Str(oss2.str());
6460       if(oss3Str.length()<maxNbOfByteInRepr)
6461         oss2Str=oss3Str;
6462       else
6463         isFinished=false;
6464     }
6465   stream << oss2Str;
6466   if(!isFinished)
6467     stream << "... ";
6468   stream << "]";
6469 }
6470
6471 /*!
6472  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6473  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6474  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6475  *         to \a this array.
6476  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6477  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6478  *  \throw If \a this->getNumberOfComponents() != 1
6479  *  \throw If any value of \a this can't be used as a valid index for 
6480  *         [\a indArrBg, \a indArrEnd).
6481  *
6482  *  \sa changeValue
6483  */
6484 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
6485 {
6486   checkAllocated();
6487   if(getNumberOfComponents()!=1)
6488     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6489   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
6490   for(int i=0;i<nbOfTuples;i++,pt++)
6491     {
6492       if(*pt>=0 && *pt<nbElemsIn)
6493         *pt=indArrBg[*pt];
6494       else
6495         {
6496           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6497           throw INTERP_KERNEL::Exception(oss.str().c_str());
6498         }
6499     }
6500   declareAsNew();
6501 }
6502
6503 /*!
6504  * Computes distribution of values of \a this one-dimensional array between given value
6505  * ranges (casts). This method is typically useful for entity number spliting by types,
6506  * for example. 
6507  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6508  *           check of this is be done. If not, the result is not warranted. 
6509  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6510  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6511  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6512  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6513  *         should be more than every value in \a this array.
6514  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6515  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6516  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6517  *         (same number of tuples and components), the caller is to delete 
6518  *         using decrRef() as it is no more needed.
6519  *         This array contains indices of ranges for every value of \a this array. I.e.
6520  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6521  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6522  *         this in which cast it holds.
6523  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6524  *         array, the caller is to delete using decrRef() as it is no more needed.
6525  *         This array contains ranks of values of \a this array within ranges
6526  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6527  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6528  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6529  *         for each tuple its rank inside its cast. The rank is computed as difference
6530  *         between the value and the lowest value of range.
6531  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6532  *         ranges (casts) to which at least one value of \a this array belongs.
6533  *         Or, in other words, this param contains the casts that \a this contains.
6534  *         The caller is to delete this array using decrRef() as it is no more needed.
6535  *
6536  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6537  *            the output of this method will be : 
6538  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6539  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6540  * - \a castsPresent  : [0,1]
6541  *
6542  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6543  * range #1 and its rank within this range is 2; etc.
6544  *
6545  *  \throw If \a this->getNumberOfComponents() != 1.
6546  *  \throw If \a arrEnd - arrBg < 2.
6547  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6548  */
6549 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6550                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
6551 {
6552   checkAllocated();
6553   if(getNumberOfComponents()!=1)
6554     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6555   int nbOfTuples=getNumberOfTuples();
6556   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6557   if(nbOfCast<2)
6558     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6559   nbOfCast--;
6560   const int *work=getConstPointer();
6561   typedef std::reverse_iterator<const int *> rintstart;
6562   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6563   rintstart end2(arrBg);
6564   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
6565   MCAuto<DataArrayInt> ret2=DataArrayInt::New();
6566   MCAuto<DataArrayInt> ret3=DataArrayInt::New();
6567   ret1->alloc(nbOfTuples,1);
6568   ret2->alloc(nbOfTuples,1);
6569   int *ret1Ptr=ret1->getPointer();
6570   int *ret2Ptr=ret2->getPointer();
6571   std::set<std::size_t> castsDetected;
6572   for(int i=0;i<nbOfTuples;i++)
6573     {
6574       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6575       std::size_t pos=std::distance(bg,res);
6576       std::size_t pos2=nbOfCast-pos;
6577       if(pos2<nbOfCast)
6578         {
6579           ret1Ptr[i]=(int)pos2;
6580           ret2Ptr[i]=work[i]-arrBg[pos2];
6581           castsDetected.insert(pos2);
6582         }
6583       else
6584         {
6585           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6586           throw INTERP_KERNEL::Exception(oss.str().c_str());
6587         }
6588     }
6589   ret3->alloc((int)castsDetected.size(),1);
6590   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6591   castArr=ret1.retn();
6592   rankInsideCast=ret2.retn();
6593   castsPresent=ret3.retn();
6594 }
6595
6596 /*!
6597  * 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 ).
6598  * 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 ).
6599  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
6600  *
6601  * \param [out] strt - the start of the range (included) if true is returned.
6602  * \param [out] sttoopp - the end of the range (not included) if true is returned.
6603  * \param [out] stteepp - the step of the range if true is returned.
6604  * \return the verdict of the check.
6605  *
6606  * \sa DataArray::GetNumberOfItemGivenBES
6607  */
6608 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
6609 {
6610   checkAllocated();
6611   if(getNumberOfComponents()!=1)
6612     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
6613   int nbTuples(getNumberOfTuples());
6614   if(nbTuples==0)
6615     { strt=0; sttoopp=0; stteepp=1; return true; }
6616   const int *pt(begin());
6617   strt=*pt; 
6618   if(nbTuples==1)
6619     { sttoopp=strt+1; stteepp=1; return true; }
6620   strt=*pt; sttoopp=pt[nbTuples-1];
6621   if(strt==sttoopp)
6622     return false;
6623   if(sttoopp>strt)
6624     {
6625       sttoopp++;
6626       int a(sttoopp-1-strt),tmp(strt);
6627       if(a%(nbTuples-1)!=0)
6628         return false;
6629       stteepp=a/(nbTuples-1);
6630       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
6631         if(pt[i]!=tmp)
6632           return false;
6633       return true;
6634     }
6635   else
6636     {
6637       sttoopp--;
6638       int a(strt-sttoopp-1),tmp(strt);
6639       if(a%(nbTuples-1)!=0)
6640         return false;
6641       stteepp=-(a/(nbTuples-1));
6642       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
6643         if(pt[i]!=tmp)
6644           return false;
6645       return true;
6646     }
6647 }
6648
6649 /*!
6650  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6651  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6652  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6653  * new value in place \a indArr[ \a v ] is i.
6654  *  \param [in] indArrBg - the array holding indices within the result array to assign
6655  *         indices of values of \a this array pointing to values of \a indArrBg.
6656  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6657  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6658  *  \return DataArrayInt * - the new instance of DataArrayInt.
6659  *          The caller is to delete this result array using decrRef() as it is no more
6660  *          needed.
6661  *  \throw If \a this->getNumberOfComponents() != 1.
6662  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6663  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6664  */
6665 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6666 {
6667   checkAllocated();
6668   if(getNumberOfComponents()!=1)
6669     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6670   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6671   int nbOfTuples=getNumberOfTuples();
6672   const int *pt=getConstPointer();
6673   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6674   ret->alloc(nbOfTuples,1);
6675   ret->fillWithValue(-1);
6676   int *tmp=ret->getPointer();
6677   for(int i=0;i<nbOfTuples;i++,pt++)
6678     {
6679       if(*pt>=0 && *pt<nbElemsIn)
6680         {
6681           int pos=indArrBg[*pt];
6682           if(pos>=0 && pos<nbOfTuples)
6683             tmp[pos]=i;
6684           else
6685             {
6686               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6687               throw INTERP_KERNEL::Exception(oss.str().c_str());
6688             }
6689         }
6690       else
6691         {
6692           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6693           throw INTERP_KERNEL::Exception(oss.str().c_str());
6694         }
6695     }
6696   return ret.retn();
6697 }
6698
6699 /*!
6700  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6701  * from values of \a this array, which is supposed to contain a renumbering map in 
6702  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6703  * To know how to use the renumbering maps see \ref numbering.
6704  *  \param [in] newNbOfElem - the number of tuples in the result array.
6705  *  \return DataArrayInt * - the new instance of DataArrayInt.
6706  *          The caller is to delete this result array using decrRef() as it is no more
6707  *          needed.
6708  * 
6709  *  \if ENABLE_EXAMPLES
6710  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6711  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6712  *  \endif
6713  */
6714 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6715 {
6716   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6717   ret->alloc(newNbOfElem,1);
6718   int nbOfOldNodes=getNumberOfTuples();
6719   const int *old2New=getConstPointer();
6720   int *pt=ret->getPointer();
6721   for(int i=0;i!=nbOfOldNodes;i++)
6722     {
6723       int newp(old2New[i]);
6724       if(newp!=-1)
6725         {
6726           if(newp>=0 && newp<newNbOfElem)
6727             pt[newp]=i;
6728           else
6729             {
6730               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6731               throw INTERP_KERNEL::Exception(oss.str().c_str());
6732             }
6733         }
6734     }
6735   return ret.retn();
6736 }
6737
6738 /*!
6739  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6740  * 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]
6741  */
6742 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6743 {
6744   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6745   ret->alloc(newNbOfElem,1);
6746   int nbOfOldNodes=getNumberOfTuples();
6747   const int *old2New=getConstPointer();
6748   int *pt=ret->getPointer();
6749   for(int i=nbOfOldNodes-1;i>=0;i--)
6750     {
6751       int newp(old2New[i]);
6752       if(newp!=-1)
6753         {
6754           if(newp>=0 && newp<newNbOfElem)
6755             pt[newp]=i;
6756           else
6757             {
6758               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6759               throw INTERP_KERNEL::Exception(oss.str().c_str());
6760             }
6761         }
6762     }
6763   return ret.retn();
6764 }
6765
6766 /*!
6767  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6768  * from values of \a this array, which is supposed to contain a renumbering map in 
6769  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6770  * To know how to use the renumbering maps see \ref numbering.
6771  *  \param [in] newNbOfElem - the number of tuples in the result array.
6772  *  \return DataArrayInt * - the new instance of DataArrayInt.
6773  *          The caller is to delete this result array using decrRef() as it is no more
6774  *          needed.
6775  * 
6776  *  \if ENABLE_EXAMPLES
6777  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6778  *
6779  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6780  *  \endif
6781  */
6782 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6783 {
6784   checkAllocated();
6785   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6786   ret->alloc(oldNbOfElem,1);
6787   const int *new2Old=getConstPointer();
6788   int *pt=ret->getPointer();
6789   std::fill(pt,pt+oldNbOfElem,-1);
6790   int nbOfNewElems=getNumberOfTuples();
6791   for(int i=0;i<nbOfNewElems;i++)
6792     {
6793       int v(new2Old[i]);
6794       if(v>=0 && v<oldNbOfElem)
6795         pt[v]=i;
6796       else
6797         {
6798           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6799           throw INTERP_KERNEL::Exception(oss.str().c_str());
6800         }
6801     }
6802   return ret.retn();
6803 }
6804
6805 /*!
6806  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6807  * mismatch is given.
6808  * 
6809  * \param [in] other the instance to be compared with \a this
6810  * \param [out] reason In case of inequality returns the reason.
6811  * \sa DataArrayInt::isEqual
6812  */
6813 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6814 {
6815   if(!areInfoEqualsIfNotWhy(other,reason))
6816     return false;
6817   return _mem.isEqual(other._mem,0,reason);
6818 }
6819
6820 /*!
6821  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6822  * \ref MEDCouplingArrayBasicsCompare.
6823  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6824  *  \return bool - \a true if the two arrays are equal, \a false else.
6825  */
6826 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6827 {
6828   std::string tmp;
6829   return isEqualIfNotWhy(other,tmp);
6830 }
6831
6832 /*!
6833  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6834  * \ref MEDCouplingArrayBasicsCompare.
6835  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6836  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6837  */
6838 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6839 {
6840   std::string tmp;
6841   return _mem.isEqual(other._mem,0,tmp);
6842 }
6843
6844 /*!
6845  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6846  * performed on sorted value sequences.
6847  * For more info see\ref MEDCouplingArrayBasicsCompare.
6848  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6849  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6850  */
6851 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6852 {
6853   MCAuto<DataArrayInt> a=deepCopy();
6854   MCAuto<DataArrayInt> b=other.deepCopy();
6855   a->sort();
6856   b->sort();
6857   return a->isEqualWithoutConsideringStr(*b);
6858 }
6859
6860 /*!
6861  * This method compares content of input vector \a v and \a this.
6862  * 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.
6863  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6864  *
6865  * \param [in] v - the vector of 'flags' to be compared with \a this.
6866  *
6867  * \throw If \a this is not sorted ascendingly.
6868  * \throw If \a this has not exactly one component.
6869  * \throw If \a this is not allocated.
6870  */
6871 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6872 {
6873   checkAllocated();
6874   if(getNumberOfComponents()!=1)
6875     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6876   const int *w(begin()),*end2(end());
6877   int refVal=-std::numeric_limits<int>::max();
6878   int i=0;
6879   std::vector<bool>::const_iterator it(v.begin());
6880   for(;it!=v.end();it++,i++)
6881     {
6882       if(*it)
6883         {
6884           if(w!=end2)
6885             {
6886               if(*w++==i)
6887                 {
6888                   if(i>refVal)
6889                     refVal=i;
6890                   else
6891                     {
6892                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6893                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6894                     }
6895                 }
6896               else
6897                 return false;
6898             }
6899           else
6900             return false;
6901         }
6902     }
6903   return w==end2;
6904 }
6905
6906 /*!
6907  * 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
6908  * put True to the corresponding entry in \a vec.
6909  * \a vec is expected to be with the same size than the number of tuples of \a this.
6910  */
6911 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
6912 {
6913   checkAllocated();
6914   if(getNumberOfComponents()!=1)
6915     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
6916   int nbOfTuples(getNumberOfTuples());
6917   if(nbOfTuples!=(int)vec.size())
6918     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
6919   const int *pt(begin());
6920   for(int i=0;i<nbOfTuples;i++)
6921     if(pt[i]==val)
6922       vec[i]=true;
6923 }
6924
6925 /*!
6926  * Sorts values of the array.
6927  *  \param [in] asc - \a true means ascending order, \a false, descending.
6928  *  \throw If \a this is not allocated.
6929  *  \throw If \a this->getNumberOfComponents() != 1.
6930  */
6931 void DataArrayInt::sort(bool asc)
6932 {
6933   checkAllocated();
6934   if(getNumberOfComponents()!=1)
6935     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6936   _mem.sort(asc);
6937   declareAsNew();
6938 }
6939
6940 /*!
6941  * Computes for each tuple the sum of number of components values in the tuple and return it.
6942  * 
6943  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6944  *          same number of tuples as \a this array and one component.
6945  *          The caller is to delete this result array using decrRef() as it is no more
6946  *          needed.
6947  *  \throw If \a this is not allocated.
6948  */
6949 DataArrayInt *DataArrayInt::sumPerTuple() const
6950 {
6951   checkAllocated();
6952   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6953   MCAuto<DataArrayInt> ret(DataArrayInt::New());
6954   ret->alloc(nbOfTuple,1);
6955   const int *src(getConstPointer());
6956   int *dest(ret->getPointer());
6957   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6958     *dest=std::accumulate(src,src+nbOfComp,0);
6959   return ret.retn();
6960 }
6961
6962 /*!
6963  * Reverse the array values.
6964  *  \throw If \a this->getNumberOfComponents() < 1.
6965  *  \throw If \a this is not allocated.
6966  */
6967 void DataArrayInt::reverse()
6968 {
6969   checkAllocated();
6970   _mem.reverse(getNumberOfComponents());
6971   declareAsNew();
6972 }
6973
6974 /*!
6975  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6976  * If not an exception is thrown.
6977  *  \param [in] increasing - if \a true, the array values should be increasing.
6978  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6979  *         increasing arg.
6980  *  \throw If \a this->getNumberOfComponents() != 1.
6981  *  \throw If \a this is not allocated.
6982  */
6983 void DataArrayInt::checkMonotonic(bool increasing) const
6984 {
6985   if(!isMonotonic(increasing))
6986     {
6987       if (increasing)
6988         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6989       else
6990         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6991     }
6992 }
6993
6994 /*!
6995  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6996  *  \param [in] increasing - if \a true, array values should be increasing.
6997  *  \return bool - \a true if values change in accordance with \a increasing arg.
6998  *  \throw If \a this->getNumberOfComponents() != 1.
6999  *  \throw If \a this is not allocated.
7000  */
7001 bool DataArrayInt::isMonotonic(bool increasing) const
7002 {
7003   checkAllocated();
7004   if(getNumberOfComponents()!=1)
7005     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
7006   int nbOfElements=getNumberOfTuples();
7007   const int *ptr=getConstPointer();
7008   if(nbOfElements==0)
7009     return true;
7010   int ref=ptr[0];
7011   if(increasing)
7012     {
7013       for(int i=1;i<nbOfElements;i++)
7014         {
7015           if(ptr[i]>=ref)
7016             ref=ptr[i];
7017           else
7018             return false;
7019         }
7020     }
7021   else
7022     {
7023       for(int i=1;i<nbOfElements;i++)
7024         {
7025           if(ptr[i]<=ref)
7026             ref=ptr[i];
7027           else
7028             return false;
7029         }
7030     }
7031   return true;
7032 }
7033
7034 /*!
7035  * This method check that array consistently INCREASING or DECREASING in value.
7036  */
7037 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
7038 {
7039   checkAllocated();
7040   if(getNumberOfComponents()!=1)
7041     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
7042   int nbOfElements=getNumberOfTuples();
7043   const int *ptr=getConstPointer();
7044   if(nbOfElements==0)
7045     return true;
7046   int ref=ptr[0];
7047   if(increasing)
7048     {
7049       for(int i=1;i<nbOfElements;i++)
7050         {
7051           if(ptr[i]>ref)
7052             ref=ptr[i];
7053           else
7054             return false;
7055         }
7056     }
7057   else
7058     {
7059       for(int i=1;i<nbOfElements;i++)
7060         {
7061           if(ptr[i]<ref)
7062             ref=ptr[i];
7063           else
7064             return false;
7065         }
7066     }
7067   return true;
7068 }
7069
7070 /*!
7071  * This method check that array consistently INCREASING or DECREASING in value.
7072  */
7073 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
7074 {
7075   if(!isStrictlyMonotonic(increasing))
7076     {
7077       if (increasing)
7078         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
7079       else
7080         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
7081     }
7082 }
7083
7084 /*!
7085  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
7086  * one-dimensional arrays that must be of the same length. The result array describes
7087  * correspondence between \a this and \a other arrays, so that 
7088  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
7089  * not possible because some element in \a other is not in \a this, an exception is thrown.
7090  *  \param [in] other - an array to compute permutation to.
7091  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
7092  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
7093  * no more needed.
7094  *  \throw If \a this->getNumberOfComponents() != 1.
7095  *  \throw If \a other->getNumberOfComponents() != 1.
7096  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
7097  *  \throw If \a other includes a value which is not in \a this array.
7098  * 
7099  *  \if ENABLE_EXAMPLES
7100  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
7101  *
7102  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
7103  *  \endif
7104  */
7105 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
7106 {
7107   checkAllocated();
7108   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
7109     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
7110   int nbTuple=getNumberOfTuples();
7111   other.checkAllocated();
7112   if(nbTuple!=other.getNumberOfTuples())
7113     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
7114   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7115   ret->alloc(nbTuple,1);
7116   ret->fillWithValue(-1);
7117   const int *pt=getConstPointer();
7118   std::map<int,int> mm;
7119   for(int i=0;i<nbTuple;i++)
7120     mm[pt[i]]=i;
7121   pt=other.getConstPointer();
7122   int *retToFill=ret->getPointer();
7123   for(int i=0;i<nbTuple;i++)
7124     {
7125       std::map<int,int>::const_iterator it=mm.find(pt[i]);
7126       if(it==mm.end())
7127         {
7128           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
7129           throw INTERP_KERNEL::Exception(oss.str().c_str());
7130         }
7131       retToFill[i]=(*it).second;
7132     }
7133   return ret.retn();
7134 }
7135
7136 /*!
7137  * Sets a C array to be used as raw data of \a this. The previously set info
7138  *  of components is retained and re-sized. 
7139  * For more info see \ref MEDCouplingArraySteps1.
7140  *  \param [in] array - the C array to be used as raw data of \a this.
7141  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
7142  *  \param [in] type - specifies how to deallocate \a array. If \a type == MEDCoupling::CPP_DEALLOC,
7143  *                     \c delete [] \c array; will be called. If \a type == MEDCoupling::C_DEALLOC,
7144  *                     \c free(\c array ) will be called.
7145  *  \param [in] nbOfTuple - new number of tuples in \a this.
7146  *  \param [in] nbOfCompo - new number of components in \a this.
7147  */
7148 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
7149 {
7150   _info_on_compo.resize(nbOfCompo);
7151   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
7152   declareAsNew();
7153 }
7154
7155 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
7156 {
7157   _info_on_compo.resize(nbOfCompo);
7158   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
7159   declareAsNew();
7160 }
7161
7162 /*!
7163  * Returns a new DataArrayInt holding the same values as \a this array but differently
7164  * arranged in memory. If \a this array holds 2 components of 3 values:
7165  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
7166  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
7167  *  \warning Do not confuse this method with transpose()!
7168  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7169  *          is to delete using decrRef() as it is no more needed.
7170  *  \throw If \a this is not allocated.
7171  */
7172 DataArrayInt *DataArrayInt::fromNoInterlace() const
7173 {
7174   checkAllocated();
7175   if(_mem.isNull())
7176     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
7177   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
7178   DataArrayInt *ret=DataArrayInt::New();
7179   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
7180   return ret;
7181 }
7182
7183 /*!
7184  * Returns a new DataArrayInt holding the same values as \a this array but differently
7185  * arranged in memory. If \a this array holds 2 components of 3 values:
7186  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
7187  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
7188  *  \warning Do not confuse this method with transpose()!
7189  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7190  *          is to delete using decrRef() as it is no more needed.
7191  *  \throw If \a this is not allocated.
7192  */
7193 DataArrayInt *DataArrayInt::toNoInterlace() const
7194 {
7195   checkAllocated();
7196   if(_mem.isNull())
7197     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
7198   int *tab=_mem.toNoInterlace(getNumberOfComponents());
7199   DataArrayInt *ret=DataArrayInt::New();
7200   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
7201   return ret;
7202 }
7203
7204 /*!
7205  * Permutes values of \a this array as required by \a old2New array. The values are
7206  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
7207  * the same as in \c this one.
7208  * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
7209  * For more info on renumbering see \ref numbering.
7210  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7211  *     giving a new position for i-th old value.
7212  */
7213 void DataArrayInt::renumberInPlace(const int *old2New)
7214 {
7215   checkAllocated();
7216   int nbTuples=getNumberOfTuples();
7217   int nbOfCompo=getNumberOfComponents();
7218   int *tmp=new int[nbTuples*nbOfCompo];
7219   const int *iptr=getConstPointer();
7220   for(int i=0;i<nbTuples;i++)
7221     {
7222       int v=old2New[i];
7223       if(v>=0 && v<nbTuples)
7224         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
7225       else
7226         {
7227           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7228           throw INTERP_KERNEL::Exception(oss.str().c_str());
7229         }
7230     }
7231   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7232   delete [] tmp;
7233   declareAsNew();
7234 }
7235
7236 /*!
7237  * Permutes values of \a this array as required by \a new2Old array. The values are
7238  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
7239  * the same as in \c this one.
7240  * For more info on renumbering see \ref numbering.
7241  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7242  *     giving a previous position of i-th new value.
7243  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7244  *          is to delete using decrRef() as it is no more needed.
7245  */
7246 void DataArrayInt::renumberInPlaceR(const int *new2Old)
7247 {
7248   checkAllocated();
7249   int nbTuples=getNumberOfTuples();
7250   int nbOfCompo=getNumberOfComponents();
7251   int *tmp=new int[nbTuples*nbOfCompo];
7252   const int *iptr=getConstPointer();
7253   for(int i=0;i<nbTuples;i++)
7254     {
7255       int v=new2Old[i];
7256       if(v>=0 && v<nbTuples)
7257         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
7258       else
7259         {
7260           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7261           throw INTERP_KERNEL::Exception(oss.str().c_str());
7262         }
7263     }
7264   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7265   delete [] tmp;
7266   declareAsNew();
7267 }
7268
7269 /*!
7270  * Returns a copy of \a this array with values permuted as required by \a old2New array.
7271  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
7272  * Number of tuples in the result array remains the same as in \c this one.
7273  * If a permutation reduction is needed, renumberAndReduce() should be used.
7274  * For more info on renumbering see \ref numbering.
7275  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7276  *          giving a new position for i-th old value.
7277  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7278  *          is to delete using decrRef() as it is no more needed.
7279  *  \throw If \a this is not allocated.
7280  */
7281 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
7282 {
7283   checkAllocated();
7284   int nbTuples=getNumberOfTuples();
7285   int nbOfCompo=getNumberOfComponents();
7286   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7287   ret->alloc(nbTuples,nbOfCompo);
7288   ret->copyStringInfoFrom(*this);
7289   const int *iptr=getConstPointer();
7290   int *optr=ret->getPointer();
7291   for(int i=0;i<nbTuples;i++)
7292     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
7293   ret->copyStringInfoFrom(*this);
7294   return ret.retn();
7295 }
7296
7297 /*!
7298  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
7299  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
7300  * tuples in the result array remains the same as in \c this one.
7301  * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
7302  * For more info on renumbering see \ref numbering.
7303  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7304  *     giving a previous position of i-th new value.
7305  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7306  *          is to delete using decrRef() as it is no more needed.
7307  */
7308 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
7309 {
7310   checkAllocated();
7311   int nbTuples=getNumberOfTuples();
7312   int nbOfCompo=getNumberOfComponents();
7313   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7314   ret->alloc(nbTuples,nbOfCompo);
7315   ret->copyStringInfoFrom(*this);
7316   const int *iptr=getConstPointer();
7317   int *optr=ret->getPointer();
7318   for(int i=0;i<nbTuples;i++)
7319     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
7320   ret->copyStringInfoFrom(*this);
7321   return ret.retn();
7322 }
7323
7324 /*!
7325  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7326  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
7327  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
7328  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
7329  * \a old2New[ i ] is negative, is missing from the result array.
7330  * For more info on renumbering see \ref numbering.
7331  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7332  *     giving a new position for i-th old tuple and giving negative position for
7333  *     for i-th old tuple that should be omitted.
7334  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7335  *          is to delete using decrRef() as it is no more needed.
7336  */
7337 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
7338 {
7339   checkAllocated();
7340   int nbTuples=getNumberOfTuples();
7341   int nbOfCompo=getNumberOfComponents();
7342   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7343   ret->alloc(newNbOfTuple,nbOfCompo);
7344   const int *iptr=getConstPointer();
7345   int *optr=ret->getPointer();
7346   for(int i=0;i<nbTuples;i++)
7347     {
7348       int w=old2New[i];
7349       if(w>=0)
7350         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
7351     }
7352   ret->copyStringInfoFrom(*this);
7353   return ret.retn();
7354 }
7355
7356 /*!
7357  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7358  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7359  * \a new2OldBg array.
7360  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7361  * This method is equivalent to renumberAndReduce() except that convention in input is
7362  * \c new2old and \b not \c old2new.
7363  * For more info on renumbering see \ref numbering.
7364  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7365  *              tuple index in \a this array to fill the i-th tuple in the new array.
7366  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7367  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7368  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7369  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7370  *          is to delete using decrRef() as it is no more needed.
7371  */
7372 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
7373 {
7374   checkAllocated();
7375   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7376   int nbComp=getNumberOfComponents();
7377   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7378   ret->copyStringInfoFrom(*this);
7379   int *pt=ret->getPointer();
7380   const int *srcPt=getConstPointer();
7381   int i=0;
7382   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7383     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7384   ret->copyStringInfoFrom(*this);
7385   return ret.retn();
7386 }
7387
7388 /*!
7389  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7390  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7391  * \a new2OldBg array.
7392  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7393  * This method is equivalent to renumberAndReduce() except that convention in input is
7394  * \c new2old and \b not \c old2new.
7395  * This method is equivalent to selectByTupleId() except that it prevents coping data
7396  * from behind the end of \a this array.
7397  * For more info on renumbering see \ref numbering.
7398  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7399  *              tuple index in \a this array to fill the i-th tuple in the new array.
7400  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7401  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7402  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7403  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7404  *          is to delete using decrRef() as it is no more needed.
7405  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
7406  */
7407 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
7408 {
7409   checkAllocated();
7410   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7411   int nbComp=getNumberOfComponents();
7412   int oldNbOfTuples=getNumberOfTuples();
7413   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7414   ret->copyStringInfoFrom(*this);
7415   int *pt=ret->getPointer();
7416   const int *srcPt=getConstPointer();
7417   int i=0;
7418   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7419     if(*w>=0 && *w<oldNbOfTuples)
7420       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7421     else
7422       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
7423   ret->copyStringInfoFrom(*this);
7424   return ret.retn();
7425 }
7426
7427 /*!
7428  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
7429  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
7430  * tuple. Indices of the selected tuples are the same as ones returned by the Python
7431  * command \c range( \a bg, \a end2, \a step ).
7432  * This method is equivalent to selectByTupleIdSafe() except that the input array is
7433  * not constructed explicitly.
7434  * For more info on renumbering see \ref numbering.
7435  *  \param [in] bg - index of the first tuple to copy from \a this array.
7436  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
7437  *  \param [in] step - index increment to get index of the next tuple to copy.
7438  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7439  *          is to delete using decrRef() as it is no more needed.
7440  *  \sa DataArrayInt::subArray.
7441  */
7442 DataArrayInt *DataArrayInt::selectByTupleIdSafeSlice(int bg, int end2, int step) const
7443 {
7444   checkAllocated();
7445   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7446   int nbComp=getNumberOfComponents();
7447   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleIdSafeSlice : ");
7448   ret->alloc(newNbOfTuples,nbComp);
7449   int *pt=ret->getPointer();
7450   const int *srcPt=getConstPointer()+bg*nbComp;
7451   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
7452     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
7453   ret->copyStringInfoFrom(*this);
7454   return ret.retn();
7455 }
7456
7457 /*!
7458  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
7459  * of tuples specified by \a ranges parameter.
7460  * For more info on renumbering see \ref numbering.
7461  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
7462  *              of tuples in [\c begin,\c end) format.
7463  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7464  *          is to delete using decrRef() as it is no more needed.
7465  *  \throw If \a end < \a begin.
7466  *  \throw If \a end > \a this->getNumberOfTuples().
7467  *  \throw If \a this is not allocated.
7468  */
7469 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
7470 {
7471   checkAllocated();
7472   int nbOfComp=getNumberOfComponents();
7473   int nbOfTuplesThis=getNumberOfTuples();
7474   if(ranges.empty())
7475     {
7476       MCAuto<DataArrayInt> ret=DataArrayInt::New();
7477       ret->alloc(0,nbOfComp);
7478       ret->copyStringInfoFrom(*this);
7479       return ret.retn();
7480     }
7481   int ref=ranges.front().first;
7482   int nbOfTuples=0;
7483   bool isIncreasing=true;
7484   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7485     {
7486       if((*it).first<=(*it).second)
7487         {
7488           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
7489             {
7490               nbOfTuples+=(*it).second-(*it).first;
7491               if(isIncreasing)
7492                 isIncreasing=ref<=(*it).first;
7493               ref=(*it).second;
7494             }
7495           else
7496             {
7497               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7498               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
7499               throw INTERP_KERNEL::Exception(oss.str().c_str());
7500             }
7501         }
7502       else
7503         {
7504           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7505           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7506           throw INTERP_KERNEL::Exception(oss.str().c_str());
7507         }
7508     }
7509   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7510     return deepCopy();
7511   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7512   ret->alloc(nbOfTuples,nbOfComp);
7513   ret->copyStringInfoFrom(*this);
7514   const int *src=getConstPointer();
7515   int *work=ret->getPointer();
7516   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7517     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7518   return ret.retn();
7519 }
7520
7521 /*!
7522  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7523  * This map, if applied to \a this array, would make it sorted. For example, if
7524  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7525  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7526  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7527  * This method is useful for renumbering (in MED file for example). For more info
7528  * on renumbering see \ref numbering.
7529  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7530  *          array using decrRef() as it is no more needed.
7531  *  \throw If \a this is not allocated.
7532  *  \throw If \a this->getNumberOfComponents() != 1.
7533  *  \throw If there are equal values in \a this array.
7534  */
7535 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7536 {
7537   checkAllocated();
7538   if(getNumberOfComponents()!=1)
7539     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7540   int nbTuples=getNumberOfTuples();
7541   const int *pt=getConstPointer();
7542   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7543   DataArrayInt *ret=DataArrayInt::New();
7544   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7545   return ret;
7546 }
7547
7548 /*!
7549  * 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
7550  * input array \a ids2.
7551  * \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.
7552  * 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
7553  * inversely.
7554  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7555  *
7556  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7557  *          array using decrRef() as it is no more needed.
7558  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7559  * 
7560  */
7561 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7562 {
7563   if(!ids1 || !ids2)
7564     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7565   if(!ids1->isAllocated() || !ids2->isAllocated())
7566     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7567   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7568     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7569   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7570     {
7571       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 !";
7572       throw INTERP_KERNEL::Exception(oss.str().c_str());
7573     }
7574   MCAuto<DataArrayInt> p1(ids1->deepCopy());
7575   MCAuto<DataArrayInt> p2(ids2->deepCopy());
7576   p1->sort(true); p2->sort(true);
7577   if(!p1->isEqualWithoutConsideringStr(*p2))
7578     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7579   p1=ids1->checkAndPreparePermutation();
7580   p2=ids2->checkAndPreparePermutation();
7581   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7582   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7583   return p2.retn();
7584 }
7585
7586 /*!
7587  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7588  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7589  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7590  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7591  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7592  * The first of out arrays returns indices of elements of \a this array, grouped by their
7593  * place in the set \a B. The second out array is the index of the first one; it shows how
7594  * many elements of \a A are mapped into each element of \a B. <br>
7595  * For more info on
7596  * mapping and its usage in renumbering see \ref numbering. <br>
7597  * \b Example:
7598  * - \a this: [0,3,2,3,2,2,1,2]
7599  * - \a targetNb: 4
7600  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7601  * - \a arrI: [0,1,2,6,8]
7602  *
7603  * This result means: <br>
7604  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7605  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7606  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7607  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7608  * \a arrI[ 2+1 ]]); <br> etc.
7609  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7610  *         than the maximal value of \a A.
7611  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7612  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7613  *         this array using decrRef() as it is no more needed.
7614  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7615  *         elements of \a this. The caller is to delete this array using decrRef() as it
7616  *         is no more needed.
7617  *  \throw If \a this is not allocated.
7618  *  \throw If \a this->getNumberOfComponents() != 1.
7619  *  \throw If any value in \a this is more or equal to \a targetNb.
7620  */
7621 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7622 {
7623   checkAllocated();
7624   if(getNumberOfComponents()!=1)
7625     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7626   int nbOfTuples=getNumberOfTuples();
7627   MCAuto<DataArrayInt> ret(DataArrayInt::New());
7628   MCAuto<DataArrayInt> retI(DataArrayInt::New());
7629   retI->alloc(targetNb+1,1);
7630   const int *input=getConstPointer();
7631   std::vector< std::vector<int> > tmp(targetNb);
7632   for(int i=0;i<nbOfTuples;i++)
7633     {
7634       int tmp2=input[i];
7635       if(tmp2>=0 && tmp2<targetNb)
7636         tmp[tmp2].push_back(i);
7637       else
7638         {
7639           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7640           throw INTERP_KERNEL::Exception(oss.str().c_str());
7641         }
7642     }
7643   int *retIPtr=retI->getPointer();
7644   *retIPtr=0;
7645   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7646     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7647   if(nbOfTuples!=retI->getIJ(targetNb,0))
7648     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7649   ret->alloc(nbOfTuples,1);
7650   int *retPtr=ret->getPointer();
7651   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7652     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7653   arr=ret.retn();
7654   arrI=retI.retn();
7655 }
7656
7657
7658 /*!
7659  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7660  * from a zip representation of a surjective format (returned e.g. by
7661  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7662  * for example). The result array minimizes the permutation. <br>
7663  * For more info on renumbering see \ref numbering. <br>
7664  * \b Example: <br>
7665  * - \a nbOfOldTuples: 10 
7666  * - \a arr          : [0,3, 5,7,9]
7667  * - \a arrIBg       : [0,2,5]
7668  * - \a newNbOfTuples: 7
7669  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7670  *
7671  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7672  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7673  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7674  *         (indices of) equal values. Its every element (except the last one) points to
7675  *         the first element of a group of equal values.
7676  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7677  *          arrIBg is \a arrIEnd[ -1 ].
7678  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7679  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7680  *          array using decrRef() as it is no more needed.
7681  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7682  */
7683 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7684 {
7685   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7686   ret->alloc(nbOfOldTuples,1);
7687   int *pt=ret->getPointer();
7688   std::fill(pt,pt+nbOfOldTuples,-1);
7689   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7690   const int *cIPtr=arrIBg;
7691   for(int i=0;i<nbOfGrps;i++)
7692     pt[arr[cIPtr[i]]]=-(i+2);
7693   int newNb=0;
7694   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7695     {
7696       if(pt[iNode]<0)
7697         {
7698           if(pt[iNode]==-1)
7699             pt[iNode]=newNb++;
7700           else
7701             {
7702               int grpId=-(pt[iNode]+2);
7703               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7704                 {
7705                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7706                     pt[arr[j]]=newNb;
7707                   else
7708                     {
7709                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7710                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7711                     }
7712                 }
7713               newNb++;
7714             }
7715         }
7716     }
7717   newNbOfTuples=newNb;
7718   return ret.retn();
7719 }
7720
7721 /*!
7722  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7723  * which if applied to \a this array would make it sorted ascendingly.
7724  * For more info on renumbering see \ref numbering. <br>
7725  * \b Example: <br>
7726  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7727  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7728  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7729  *
7730  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7731  *          array using decrRef() as it is no more needed.
7732  *  \throw If \a this is not allocated.
7733  *  \throw If \a this->getNumberOfComponents() != 1.
7734  */
7735 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7736 {
7737   checkAllocated();
7738   if(getNumberOfComponents()!=1)
7739     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7740   int nbOfTuples=getNumberOfTuples();
7741   const int *pt=getConstPointer();
7742   std::map<int,int> m;
7743   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7744   ret->alloc(nbOfTuples,1);
7745   int *opt=ret->getPointer();
7746   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7747     {
7748       int val=*pt;
7749       std::map<int,int>::iterator it=m.find(val);
7750       if(it!=m.end())
7751         {
7752           *opt=(*it).second;
7753           (*it).second++;
7754         }
7755       else
7756         {
7757           *opt=0;
7758           m.insert(std::pair<int,int>(val,1));
7759         }
7760     }
7761   int sum=0;
7762   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7763     {
7764       int vt=(*it).second;
7765       (*it).second=sum;
7766       sum+=vt;
7767     }
7768   pt=getConstPointer();
7769   opt=ret->getPointer();
7770   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7771     *opt+=m[*pt];
7772   //
7773   return ret.retn();
7774 }
7775
7776 /*!
7777  * Checks if contents of \a this array are equal to that of an array filled with
7778  * iota(). This method is particularly useful for DataArrayInt instances that represent
7779  * a renumbering array to check the real need in renumbering. This method checks than \a this can be considered as an identity function
7780  * of a set having \a sizeExpected elements into itself.
7781  *
7782  *  \param [in] sizeExpected - The number of elements expected.
7783  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7784  *  \throw If \a this is not allocated.
7785  *  \throw If \a this->getNumberOfComponents() != 1.
7786  */
7787 bool DataArrayInt::isIota(int sizeExpected) const
7788 {
7789   checkAllocated();
7790   if(getNumberOfComponents()!=1)
7791     return false;
7792   int nbOfTuples(getNumberOfTuples());
7793   if(nbOfTuples!=sizeExpected)
7794     return false;
7795   const int *pt=getConstPointer();
7796   for(int i=0;i<nbOfTuples;i++,pt++)
7797     if(*pt!=i)
7798       return false;
7799   return true;
7800 }
7801
7802 /*!
7803  * Checks if all values in \a this array are equal to \a val.
7804  *  \param [in] val - value to check equality of array values to.
7805  *  \return bool - \a true if all values are \a val.
7806  *  \throw If \a this is not allocated.
7807  *  \throw If \a this->getNumberOfComponents() != 1
7808  */
7809 bool DataArrayInt::isUniform(int val) const
7810 {
7811   checkAllocated();
7812   if(getNumberOfComponents()!=1)
7813     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7814   int nbOfTuples=getNumberOfTuples();
7815   const int *w=getConstPointer();
7816   const int *end2=w+nbOfTuples;
7817   for(;w!=end2;w++)
7818     if(*w!=val)
7819       return false;
7820   return true;
7821 }
7822
7823 /*!
7824  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7825  * array to the new one.
7826  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7827  */
7828 DataArrayDouble *DataArrayInt::convertToDblArr() const
7829 {
7830   checkAllocated();
7831   DataArrayDouble *ret=DataArrayDouble::New();
7832   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7833   std::size_t nbOfVals=getNbOfElems();
7834   const int *src=getConstPointer();
7835   double *dest=ret->getPointer();
7836   std::copy(src,src+nbOfVals,dest);
7837   ret->copyStringInfoFrom(*this);
7838   return ret;
7839 }
7840
7841 /*!
7842  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7843  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7844  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7845  * This method is a specialization of selectByTupleIdSafeSlice().
7846  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7847  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7848  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7849  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7850  *          is to delete using decrRef() as it is no more needed.
7851  *  \throw If \a tupleIdBg < 0.
7852  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7853     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7854  *  \sa DataArrayInt::selectByTupleIdSafeSlice
7855  */
7856 DataArrayInt *DataArrayInt::subArray(int tupleIdBg, int tupleIdEnd) const
7857 {
7858   checkAllocated();
7859   int nbt=getNumberOfTuples();
7860   if(tupleIdBg<0)
7861     throw INTERP_KERNEL::Exception("DataArrayInt::subArray : The tupleIdBg parameter must be greater than 0 !");
7862   if(tupleIdBg>nbt)
7863     throw INTERP_KERNEL::Exception("DataArrayInt::subArray : The tupleIdBg parameter is greater than number of tuples !");
7864   int trueEnd=tupleIdEnd;
7865   if(tupleIdEnd!=-1)
7866     {
7867       if(tupleIdEnd>nbt)
7868         throw INTERP_KERNEL::Exception("DataArrayInt::subArray : The tupleIdBg parameter is greater or equal than number of tuples !");
7869     }
7870   else
7871     trueEnd=nbt;
7872   int nbComp=getNumberOfComponents();
7873   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7874   ret->alloc(trueEnd-tupleIdBg,nbComp);
7875   ret->copyStringInfoFrom(*this);
7876   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7877   return ret.retn();
7878 }
7879
7880 /*!
7881  * Changes the number of components within \a this array so that its raw data **does
7882  * not** change, instead splitting this data into tuples changes.
7883  *  \warning This method erases all (name and unit) component info set before!
7884  *  \param [in] newNbOfComp - number of components for \a this array to have.
7885  *  \throw If \a this is not allocated
7886  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7887  *  \throw If \a newNbOfCompo is lower than 1.
7888  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7889  *  \warning This method erases all (name and unit) component info set before!
7890  */
7891 void DataArrayInt::rearrange(int newNbOfCompo)
7892 {
7893   checkAllocated();
7894   if(newNbOfCompo<1)
7895     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7896   std::size_t nbOfElems=getNbOfElems();
7897   if(nbOfElems%newNbOfCompo!=0)
7898     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7899   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7900     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7901   _info_on_compo.clear();
7902   _info_on_compo.resize(newNbOfCompo);
7903   declareAsNew();
7904 }
7905
7906 /*!
7907  * Changes the number of components within \a this array to be equal to its number
7908  * of tuples, and inversely its number of tuples to become equal to its number of 
7909  * components. So that its raw data **does not** change, instead splitting this
7910  * data into tuples changes.
7911  *  \warning This method erases all (name and unit) component info set before!
7912  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7913  *  \throw If \a this is not allocated.
7914  *  \sa rearrange()
7915  */
7916 void DataArrayInt::transpose()
7917 {
7918   checkAllocated();
7919   int nbOfTuples=getNumberOfTuples();
7920   rearrange(nbOfTuples);
7921 }
7922
7923 /*!
7924  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7925  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7926  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7927  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7928  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7929  * components.  
7930  *  \param [in] newNbOfComp - number of components for the new array to have.
7931  *  \param [in] dftValue - value assigned to new values added to the new array.
7932  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7933  *          is to delete using decrRef() as it is no more needed.
7934  *  \throw If \a this is not allocated.
7935  */
7936 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7937 {
7938   checkAllocated();
7939   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7940   ret->alloc(getNumberOfTuples(),newNbOfComp);
7941   const int *oldc=getConstPointer();
7942   int *nc=ret->getPointer();
7943   int nbOfTuples=getNumberOfTuples();
7944   int oldNbOfComp=getNumberOfComponents();
7945   int dim=std::min(oldNbOfComp,newNbOfComp);
7946   for(int i=0;i<nbOfTuples;i++)
7947     {
7948       int j=0;
7949       for(;j<dim;j++)
7950         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7951       for(;j<newNbOfComp;j++)
7952         nc[newNbOfComp*i+j]=dftValue;
7953     }
7954   ret->setName(getName());
7955   for(int i=0;i<dim;i++)
7956     ret->setInfoOnComponent(i,getInfoOnComponent(i));
7957   ret->setName(getName());
7958   return ret.retn();
7959 }
7960
7961 /*!
7962  * Changes number of tuples in the array. If the new number of tuples is smaller
7963  * than the current number the array is truncated, otherwise the array is extended.
7964  *  \param [in] nbOfTuples - new number of tuples. 
7965  *  \throw If \a this is not allocated.
7966  *  \throw If \a nbOfTuples is negative.
7967  */
7968 void DataArrayInt::reAlloc(int nbOfTuples)
7969 {
7970   if(nbOfTuples<0)
7971     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7972   checkAllocated();
7973   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7974   declareAsNew();
7975 }
7976
7977
7978 /*!
7979  * Returns a copy of \a this array composed of selected components.
7980  * The new DataArrayInt has the same number of tuples but includes components
7981  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7982  * can be either less, same or more than \a this->getNbOfElems().
7983  *  \param [in] compoIds - sequence of zero based indices of components to include
7984  *              into the new array.
7985  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7986  *          is to delete using decrRef() as it is no more needed.
7987  *  \throw If \a this is not allocated.
7988  *  \throw If a component index (\a i) is not valid: 
7989  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7990  *
7991  *  \if ENABLE_EXAMPLES
7992  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7993  *  \endif
7994  */
7995 DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
7996 {
7997   checkAllocated();
7998   MCAuto<DataArrayInt> ret(DataArrayInt::New());
7999   int newNbOfCompo=(int)compoIds.size();
8000   int oldNbOfCompo=getNumberOfComponents();
8001   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
8002     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
8003   int nbOfTuples=getNumberOfTuples();
8004   ret->alloc(nbOfTuples,newNbOfCompo);
8005   ret->copyPartOfStringInfoFrom(*this,compoIds);
8006   const int *oldc=getConstPointer();
8007   int *nc=ret->getPointer();
8008   for(int i=0;i<nbOfTuples;i++)
8009     for(int j=0;j<newNbOfCompo;j++,nc++)
8010       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
8011   return ret.retn();
8012 }
8013
8014 /*!
8015  * Appends components of another array to components of \a this one, tuple by tuple.
8016  * So that the number of tuples of \a this array remains the same and the number of 
8017  * components increases.
8018  *  \param [in] other - the DataArrayInt to append to \a this one.
8019  *  \throw If \a this is not allocated.
8020  *  \throw If \a this and \a other arrays have different number of tuples.
8021  *
8022  *  \if ENABLE_EXAMPLES
8023  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
8024  *
8025  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
8026  *  \endif
8027  */
8028 void DataArrayInt::meldWith(const DataArrayInt *other)
8029 {
8030   if(!other)
8031     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
8032   checkAllocated();
8033   other->checkAllocated();
8034   int nbOfTuples=getNumberOfTuples();
8035   if(nbOfTuples!=other->getNumberOfTuples())
8036     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
8037   int nbOfComp1=getNumberOfComponents();
8038   int nbOfComp2=other->getNumberOfComponents();
8039   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
8040   int *w=newArr;
8041   const int *inp1=getConstPointer();
8042   const int *inp2=other->getConstPointer();
8043   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
8044     {
8045       w=std::copy(inp1,inp1+nbOfComp1,w);
8046       w=std::copy(inp2,inp2+nbOfComp2,w);
8047     }
8048   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
8049   std::vector<int> compIds(nbOfComp2);
8050   for(int i=0;i<nbOfComp2;i++)
8051     compIds[i]=nbOfComp1+i;
8052   copyPartOfStringInfoFrom2(compIds,*other);
8053 }
8054
8055 /*!
8056  * Copy all components in a specified order from another DataArrayInt.
8057  * The specified components become the first ones in \a this array.
8058  * Both numerical and textual data is copied. The number of tuples in \a this and
8059  * the other array can be different.
8060  *  \param [in] a - the array to copy data from.
8061  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
8062  *              to be copied.
8063  *  \throw If \a a is NULL.
8064  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
8065  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
8066  *
8067  *  \if ENABLE_EXAMPLES
8068  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
8069  *  \endif
8070  */
8071 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
8072 {
8073   if(!a)
8074     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
8075   checkAllocated();
8076   a->checkAllocated();
8077   copyPartOfStringInfoFrom2(compoIds,*a);
8078   std::size_t partOfCompoSz=compoIds.size();
8079   int nbOfCompo=getNumberOfComponents();
8080   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
8081   const int *ac=a->getConstPointer();
8082   int *nc=getPointer();
8083   for(int i=0;i<nbOfTuples;i++)
8084     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
8085       nc[nbOfCompo*i+compoIds[j]]=*ac;
8086 }
8087
8088 /*!
8089  * Copy all values from another DataArrayInt into specified tuples and components
8090  * of \a this array. Textual data is not copied.
8091  * The tree parameters defining set of indices of tuples and components are similar to
8092  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
8093  *  \param [in] a - the array to copy values from.
8094  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
8095  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
8096  *              are located.
8097  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
8098  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
8099  *  \param [in] endComp - index of the component before which the components to assign
8100  *              to are located.
8101  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8102  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
8103  *              must be equal to the number of columns to assign to, else an
8104  *              exception is thrown; if \a false, then it is only required that \a
8105  *              a->getNbOfElems() equals to number of values to assign to (this condition
8106  *              must be respected even if \a strictCompoCompare is \a true). The number of 
8107  *              values to assign to is given by following Python expression:
8108  *              \a nbTargetValues = 
8109  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
8110  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
8111  *  \throw If \a a is NULL.
8112  *  \throw If \a a is not allocated.
8113  *  \throw If \a this is not allocated.
8114  *  \throw If parameters specifying tuples and components to assign to do not give a
8115  *            non-empty range of increasing indices.
8116  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
8117  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
8118  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
8119  *
8120  *  \if ENABLE_EXAMPLES
8121  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
8122  *  \endif
8123  */
8124 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8125 {
8126   if(!a)
8127     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
8128   const char msg[]="DataArrayInt::setPartOfValues1";
8129   checkAllocated();
8130   a->checkAllocated();
8131   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8132   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8133   int nbComp=getNumberOfComponents();
8134   int nbOfTuples=getNumberOfTuples();
8135   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8136   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8137   bool assignTech=true;
8138   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8139     {
8140       if(strictCompoCompare)
8141         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8142     }
8143   else
8144     {
8145       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8146       assignTech=false;
8147     }
8148   int *pt=getPointer()+bgTuples*nbComp+bgComp;
8149   const int *srcPt=a->getConstPointer();
8150   if(assignTech)
8151     {
8152       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8153         for(int j=0;j<newNbOfComp;j++,srcPt++)
8154           pt[j*stepComp]=*srcPt;
8155     }
8156   else
8157     {
8158       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8159         {
8160           const int *srcPt2=srcPt;
8161           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8162             pt[j*stepComp]=*srcPt2;
8163         }
8164     }
8165 }
8166
8167 /*!
8168  * Assign a given value to values at specified tuples and components of \a this array.
8169  * The tree parameters defining set of indices of tuples and components are similar to
8170  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
8171  *  \param [in] a - the value to assign.
8172  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
8173  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
8174  *              are located.
8175  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
8176  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8177  *  \param [in] endComp - index of the component before which the components to assign
8178  *              to are located.
8179  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8180  *  \throw If \a this is not allocated.
8181  *  \throw If parameters specifying tuples and components to assign to, do not give a
8182  *            non-empty range of increasing indices or indices are out of a valid range
8183  *            for \c this array.
8184  *
8185  *  \if ENABLE_EXAMPLES
8186  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
8187  *  \endif
8188  */
8189 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
8190 {
8191   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
8192   checkAllocated();
8193   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8194   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8195   int nbComp=getNumberOfComponents();
8196   int nbOfTuples=getNumberOfTuples();
8197   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8198   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8199   int *pt=getPointer()+bgTuples*nbComp+bgComp;
8200   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8201     for(int j=0;j<newNbOfComp;j++)
8202       pt[j*stepComp]=a;
8203 }
8204
8205
8206 /*!
8207  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8208  * components of \a this array. Textual data is not copied.
8209  * The tuples and components to assign to are defined by C arrays of indices.
8210  * There are two *modes of usage*:
8211  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8212  *   of \a a is assigned to its own location within \a this array. 
8213  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8214  *   components of every specified tuple of \a this array. In this mode it is required
8215  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8216  * 
8217  *  \param [in] a - the array to copy values from.
8218  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8219  *              assign values of \a a to.
8220  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8221  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8222  *              \a bgTuples <= \a pi < \a endTuples.
8223  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8224  *              assign values of \a a to.
8225  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8226  *              pointer to a component index <em>(pi)</em> varies as this: 
8227  *              \a bgComp <= \a pi < \a endComp.
8228  *  \param [in] strictCompoCompare - this parameter is checked only if the
8229  *               *mode of usage* is the first; if it is \a true (default), 
8230  *               then \a a->getNumberOfComponents() must be equal 
8231  *               to the number of specified columns, else this is not required.
8232  *  \throw If \a a is NULL.
8233  *  \throw If \a a is not allocated.
8234  *  \throw If \a this is not allocated.
8235  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8236  *         out of a valid range for \a this array.
8237  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8238  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
8239  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8240  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
8241  *
8242  *  \if ENABLE_EXAMPLES
8243  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
8244  *  \endif
8245  */
8246 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8247 {
8248   if(!a)
8249     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
8250   const char msg[]="DataArrayInt::setPartOfValues2";
8251   checkAllocated();
8252   a->checkAllocated();
8253   int nbComp=getNumberOfComponents();
8254   int nbOfTuples=getNumberOfTuples();
8255   for(const int *z=bgComp;z!=endComp;z++)
8256     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8257   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8258   int newNbOfComp=(int)std::distance(bgComp,endComp);
8259   bool assignTech=true;
8260   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8261     {
8262       if(strictCompoCompare)
8263         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8264     }
8265   else
8266     {
8267       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8268       assignTech=false;
8269     }
8270   int *pt=getPointer();
8271   const int *srcPt=a->getConstPointer();
8272   if(assignTech)
8273     {    
8274       for(const int *w=bgTuples;w!=endTuples;w++)
8275         {
8276           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8277           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8278             {    
8279               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
8280             }
8281         }
8282     }
8283   else
8284     {
8285       for(const int *w=bgTuples;w!=endTuples;w++)
8286         {
8287           const int *srcPt2=srcPt;
8288           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8289           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8290             {    
8291               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
8292             }
8293         }
8294     }
8295 }
8296
8297 /*!
8298  * Assign a given value to values at specified tuples and components of \a this array.
8299  * The tuples and components to assign to are defined by C arrays of indices.
8300  *  \param [in] a - the value to assign.
8301  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8302  *              assign \a a to.
8303  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8304  *              pointer to a tuple index (\a pi) varies as this: 
8305  *              \a bgTuples <= \a pi < \a endTuples.
8306  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8307  *              assign \a a to.
8308  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8309  *              pointer to a component index (\a pi) varies as this: 
8310  *              \a bgComp <= \a pi < \a endComp.
8311  *  \throw If \a this is not allocated.
8312  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8313  *         out of a valid range for \a this array.
8314  *
8315  *  \if ENABLE_EXAMPLES
8316  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
8317  *  \endif
8318  */
8319 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
8320 {
8321   checkAllocated();
8322   int nbComp=getNumberOfComponents();
8323   int nbOfTuples=getNumberOfTuples();
8324   for(const int *z=bgComp;z!=endComp;z++)
8325     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8326   int *pt=getPointer();
8327   for(const int *w=bgTuples;w!=endTuples;w++)
8328     for(const int *z=bgComp;z!=endComp;z++)
8329       {
8330         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8331         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
8332       }
8333 }
8334
8335 /*!
8336  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8337  * components of \a this array. Textual data is not copied.
8338  * The tuples to assign to are defined by a C array of indices.
8339  * The components to assign to are defined by three values similar to parameters of
8340  * the Python function \c range(\c start,\c stop,\c step).
8341  * There are two *modes of usage*:
8342  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8343  *   of \a a is assigned to its own location within \a this array. 
8344  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8345  *   components of every specified tuple of \a this array. In this mode it is required
8346  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8347  *
8348  *  \param [in] a - the array to copy values from.
8349  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8350  *              assign values of \a a to.
8351  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8352  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8353  *              \a bgTuples <= \a pi < \a endTuples.
8354  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8355  *  \param [in] endComp - index of the component before which the components to assign
8356  *              to are located.
8357  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8358  *  \param [in] strictCompoCompare - this parameter is checked only in the first
8359  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
8360  *               then \a a->getNumberOfComponents() must be equal 
8361  *               to the number of specified columns, else this is not required.
8362  *  \throw If \a a is NULL.
8363  *  \throw If \a a is not allocated.
8364  *  \throw If \a this is not allocated.
8365  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8366  *         \a this array.
8367  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8368  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
8369  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8370  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8371  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
8372  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8373  *  \throw If parameters specifying components to assign to, do not give a
8374  *            non-empty range of increasing indices or indices are out of a valid range
8375  *            for \c this array.
8376  *
8377  *  \if ENABLE_EXAMPLES
8378  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
8379  *  \endif
8380  */
8381 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8382 {
8383   if(!a)
8384     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
8385   const char msg[]="DataArrayInt::setPartOfValues3";
8386   checkAllocated();
8387   a->checkAllocated();
8388   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8389   int nbComp=getNumberOfComponents();
8390   int nbOfTuples=getNumberOfTuples();
8391   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8392   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8393   bool assignTech=true;
8394   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8395     {
8396       if(strictCompoCompare)
8397         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8398     }
8399   else
8400     {
8401       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8402       assignTech=false;
8403     }
8404   int *pt=getPointer()+bgComp;
8405   const int *srcPt=a->getConstPointer();
8406   if(assignTech)
8407     {
8408       for(const int *w=bgTuples;w!=endTuples;w++)
8409         for(int j=0;j<newNbOfComp;j++,srcPt++)
8410           {
8411             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8412             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
8413           }
8414     }
8415   else
8416     {
8417       for(const int *w=bgTuples;w!=endTuples;w++)
8418         {
8419           const int *srcPt2=srcPt;
8420           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8421             {
8422               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8423               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
8424             }
8425         }
8426     }
8427 }
8428
8429 /*!
8430  * Assign a given value to values at specified tuples and components of \a this array.
8431  * The tuples to assign to are defined by a C array of indices.
8432  * The components to assign to are defined by three values similar to parameters of
8433  * the Python function \c range(\c start,\c stop,\c step).
8434  *  \param [in] a - the value to assign.
8435  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8436  *              assign \a a to.
8437  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8438  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8439  *              \a bgTuples <= \a pi < \a endTuples.
8440  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8441  *  \param [in] endComp - index of the component before which the components to assign
8442  *              to are located.
8443  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8444  *  \throw If \a this is not allocated.
8445  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8446  *         \a this array.
8447  *  \throw If parameters specifying components to assign to, do not give a
8448  *            non-empty range of increasing indices or indices are out of a valid range
8449  *            for \c this array.
8450  *
8451  *  \if ENABLE_EXAMPLES
8452  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
8453  *  \endif
8454  */
8455 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
8456 {
8457   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
8458   checkAllocated();
8459   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8460   int nbComp=getNumberOfComponents();
8461   int nbOfTuples=getNumberOfTuples();
8462   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8463   int *pt=getPointer()+bgComp;
8464   for(const int *w=bgTuples;w!=endTuples;w++)
8465     for(int j=0;j<newNbOfComp;j++)
8466       {
8467         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8468         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
8469       }
8470 }
8471
8472 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8473 {
8474   if(!a)
8475     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
8476   const char msg[]="DataArrayInt::setPartOfValues4";
8477   checkAllocated();
8478   a->checkAllocated();
8479   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8480   int newNbOfComp=(int)std::distance(bgComp,endComp);
8481   int nbComp=getNumberOfComponents();
8482   for(const int *z=bgComp;z!=endComp;z++)
8483     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8484   int nbOfTuples=getNumberOfTuples();
8485   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8486   bool assignTech=true;
8487   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8488     {
8489       if(strictCompoCompare)
8490         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8491     }
8492   else
8493     {
8494       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8495       assignTech=false;
8496     }
8497   const int *srcPt=a->getConstPointer();
8498   int *pt=getPointer()+bgTuples*nbComp;
8499   if(assignTech)
8500     {
8501       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8502         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8503           pt[*z]=*srcPt;
8504     }
8505   else
8506     {
8507       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8508         {
8509           const int *srcPt2=srcPt;
8510           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8511             pt[*z]=*srcPt2;
8512         }
8513     }
8514 }
8515
8516 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
8517 {
8518   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
8519   checkAllocated();
8520   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8521   int nbComp=getNumberOfComponents();
8522   for(const int *z=bgComp;z!=endComp;z++)
8523     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8524   int nbOfTuples=getNumberOfTuples();
8525   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8526   int *pt=getPointer()+bgTuples*nbComp;
8527   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8528     for(const int *z=bgComp;z!=endComp;z++)
8529       pt[*z]=a;
8530 }
8531
8532 /*!
8533  * Copy some tuples from another DataArrayInt into specified tuples
8534  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8535  * components.
8536  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8537  * All components of selected tuples are copied.
8538  *  \param [in] a - the array to copy values from.
8539  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8540  *              target tuples of \a this. \a tuplesSelec has two components, and the
8541  *              first component specifies index of the source tuple and the second
8542  *              one specifies index of the target tuple.
8543  *  \throw If \a this is not allocated.
8544  *  \throw If \a a is NULL.
8545  *  \throw If \a a is not allocated.
8546  *  \throw If \a tuplesSelec is NULL.
8547  *  \throw If \a tuplesSelec is not allocated.
8548  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8549  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8550  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8551  *         the corresponding (\a this or \a a) array.
8552  */
8553 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8554 {
8555   if(!a || !tuplesSelec)
8556     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8557   checkAllocated();
8558   a->checkAllocated();
8559   tuplesSelec->checkAllocated();
8560   int nbOfComp=getNumberOfComponents();
8561   if(nbOfComp!=a->getNumberOfComponents())
8562     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8563   if(tuplesSelec->getNumberOfComponents()!=2)
8564     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8565   int thisNt=getNumberOfTuples();
8566   int aNt=a->getNumberOfTuples();
8567   int *valsToSet=getPointer();
8568   const int *valsSrc=a->getConstPointer();
8569   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8570     {
8571       if(tuple[1]>=0 && tuple[1]<aNt)
8572         {
8573           if(tuple[0]>=0 && tuple[0]<thisNt)
8574             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8575           else
8576             {
8577               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8578               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8579               throw INTERP_KERNEL::Exception(oss.str().c_str());
8580             }
8581         }
8582       else
8583         {
8584           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8585           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8586           throw INTERP_KERNEL::Exception(oss.str().c_str());
8587         }
8588     }
8589 }
8590
8591 /*!
8592  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8593  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8594  * components.
8595  * The tuples to assign to are defined by index of the first tuple, and
8596  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8597  * The tuples to copy are defined by values of a DataArrayInt.
8598  * All components of selected tuples are copied.
8599  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8600  *              values to.
8601  *  \param [in] aBase - the array to copy values from.
8602  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8603  *  \throw If \a this is not allocated.
8604  *  \throw If \a aBase is NULL.
8605  *  \throw If \a aBase is not allocated.
8606  *  \throw If \a tuplesSelec is NULL.
8607  *  \throw If \a tuplesSelec is not allocated.
8608  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8609  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8610  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8611  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8612  *         \a aBase array.
8613  */
8614 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8615 {
8616   if(!aBase || !tuplesSelec)
8617     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8618   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8619   if(!a)
8620     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8621   checkAllocated();
8622   a->checkAllocated();
8623   tuplesSelec->checkAllocated();
8624   int nbOfComp=getNumberOfComponents();
8625   if(nbOfComp!=a->getNumberOfComponents())
8626     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8627   if(tuplesSelec->getNumberOfComponents()!=1)
8628     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8629   int thisNt=getNumberOfTuples();
8630   int aNt=a->getNumberOfTuples();
8631   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8632   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8633   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8634     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8635   const int *valsSrc=a->getConstPointer();
8636   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8637     {
8638       if(*tuple>=0 && *tuple<aNt)
8639         {
8640           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8641         }
8642       else
8643         {
8644           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8645           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8646           throw INTERP_KERNEL::Exception(oss.str().c_str());
8647         }
8648     }
8649 }
8650
8651 /*!
8652  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8653  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8654  * components.
8655  * The tuples to copy are defined by three values similar to parameters of
8656  * the Python function \c range(\c start,\c stop,\c step).
8657  * The tuples to assign to are defined by index of the first tuple, and
8658  * their number is defined by number of tuples to copy.
8659  * All components of selected tuples are copied.
8660  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8661  *              values to.
8662  *  \param [in] aBase - the array to copy values from.
8663  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8664  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8665  *              are located.
8666  *  \param [in] step - index increment to get index of the next tuple to copy.
8667  *  \throw If \a this is not allocated.
8668  *  \throw If \a aBase is NULL.
8669  *  \throw If \a aBase is not allocated.
8670  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8671  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8672  *  \throw If parameters specifying tuples to copy, do not give a
8673  *            non-empty range of increasing indices or indices are out of a valid range
8674  *            for the array \a aBase.
8675  */
8676 void DataArrayInt::setContigPartOfSelectedValuesSlice(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8677 {
8678   if(!aBase)
8679     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : input DataArray is NULL !");
8680   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8681   if(!a)
8682     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : input DataArray aBase is not a DataArrayInt !");
8683   checkAllocated();
8684   a->checkAllocated();
8685   int nbOfComp=getNumberOfComponents();
8686   const char msg[]="DataArrayInt::setContigPartOfSelectedValuesSlice";
8687   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8688   if(nbOfComp!=a->getNumberOfComponents())
8689     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : This and a do not have the same number of components !");
8690   int thisNt=getNumberOfTuples();
8691   int aNt=a->getNumberOfTuples();
8692   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8693   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8694     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : invalid number range of values to write !");
8695   if(end2>aNt)
8696     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : invalid range of values to read !");
8697   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8698   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8699     {
8700       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8701     }
8702 }
8703
8704 /*!
8705  * Returns a value located at specified tuple and component.
8706  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8707  * parameters is checked. So this method is safe but expensive if used to go through
8708  * all values of \a this.
8709  *  \param [in] tupleId - index of tuple of interest.
8710  *  \param [in] compoId - index of component of interest.
8711  *  \return double - value located by \a tupleId and \a compoId.
8712  *  \throw If \a this is not allocated.
8713  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8714  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8715  */
8716 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8717 {
8718   checkAllocated();
8719   if(tupleId<0 || tupleId>=getNumberOfTuples())
8720     {
8721       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8722       throw INTERP_KERNEL::Exception(oss.str().c_str());
8723     }
8724   if(compoId<0 || compoId>=getNumberOfComponents())
8725     {
8726       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8727       throw INTERP_KERNEL::Exception(oss.str().c_str());
8728     }
8729   return _mem[tupleId*_info_on_compo.size()+compoId];
8730 }
8731
8732 /*!
8733  * Returns the first value of \a this. 
8734  *  \return int - the last value of \a this array.
8735  *  \throw If \a this is not allocated.
8736  *  \throw If \a this->getNumberOfComponents() != 1.
8737  *  \throw If \a this->getNumberOfTuples() < 1.
8738  */
8739 int DataArrayInt::front() const
8740 {
8741   checkAllocated();
8742   if(getNumberOfComponents()!=1)
8743     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8744   int nbOfTuples=getNumberOfTuples();
8745   if(nbOfTuples<1)
8746     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8747   return *(getConstPointer());
8748 }
8749
8750 /*!
8751  * Returns the last value of \a this. 
8752  *  \return int - the last value of \a this array.
8753  *  \throw If \a this is not allocated.
8754  *  \throw If \a this->getNumberOfComponents() != 1.
8755  *  \throw If \a this->getNumberOfTuples() < 1.
8756  */
8757 int DataArrayInt::back() const
8758 {
8759   checkAllocated();
8760   if(getNumberOfComponents()!=1)
8761     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8762   int nbOfTuples=getNumberOfTuples();
8763   if(nbOfTuples<1)
8764     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8765   return *(getConstPointer()+nbOfTuples-1);
8766 }
8767
8768 /*!
8769  * Assign pointer to one array to a pointer to another appay. Reference counter of
8770  * \a arrayToSet is incremented / decremented.
8771  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8772  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8773  */
8774 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8775 {
8776   if(newArray!=arrayToSet)
8777     {
8778       if(arrayToSet)
8779         arrayToSet->decrRef();
8780       arrayToSet=newArray;
8781       if(arrayToSet)
8782         arrayToSet->incrRef();
8783     }
8784 }
8785
8786 DataArrayIntIterator *DataArrayInt::iterator()
8787 {
8788   return new DataArrayIntIterator(this);
8789 }
8790
8791 /*!
8792  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8793  * given one. The ids are sorted in the ascending order.
8794  *  \param [in] val - the value to find within \a this.
8795  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8796  *          array using decrRef() as it is no more needed.
8797  *  \throw If \a this is not allocated.
8798  *  \throw If \a this->getNumberOfComponents() != 1.
8799  *  \sa DataArrayInt::findIdsEqualTuple
8800  */
8801 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
8802 {
8803   checkAllocated();
8804   if(getNumberOfComponents()!=1)
8805     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8806   const int *cptr(getConstPointer());
8807   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8808   int nbOfTuples=getNumberOfTuples();
8809   for(int i=0;i<nbOfTuples;i++,cptr++)
8810     if(*cptr==val)
8811       ret->pushBackSilent(i);
8812   return ret.retn();
8813 }
8814
8815 /*!
8816  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8817  * equal to a given one. 
8818  *  \param [in] val - the value to ignore within \a this.
8819  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8820  *          array using decrRef() as it is no more needed.
8821  *  \throw If \a this is not allocated.
8822  *  \throw If \a this->getNumberOfComponents() != 1.
8823  */
8824 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
8825 {
8826   checkAllocated();
8827   if(getNumberOfComponents()!=1)
8828     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8829   const int *cptr(getConstPointer());
8830   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8831   int nbOfTuples=getNumberOfTuples();
8832   for(int i=0;i<nbOfTuples;i++,cptr++)
8833     if(*cptr!=val)
8834       ret->pushBackSilent(i);
8835   return ret.retn();
8836 }
8837
8838 /*!
8839  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
8840  * This method is an extension of  DataArrayInt::findIdsEqual method.
8841  *
8842  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
8843  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
8844  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8845  *          array using decrRef() as it is no more needed.
8846  *  \throw If \a this is not allocated.
8847  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
8848  * \throw If \a this->getNumberOfComponents() is equal to 0.
8849  * \sa DataArrayInt::findIdsEqual
8850  */
8851 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
8852 {
8853   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
8854   checkAllocated();
8855   if(getNumberOfComponents()!=(int)nbOfCompoExp)
8856     {
8857       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
8858       throw INTERP_KERNEL::Exception(oss.str().c_str());
8859     }
8860   if(nbOfCompoExp==0)
8861     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
8862   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8863   const int *bg(begin()),*end2(end()),*work(begin());
8864   while(work!=end2)
8865     {
8866       work=std::search(work,end2,tupleBg,tupleEnd);
8867       if(work!=end2)
8868         {
8869           std::size_t pos(std::distance(bg,work));
8870           if(pos%nbOfCompoExp==0)
8871             ret->pushBackSilent(pos/nbOfCompoExp);
8872           work++;
8873         }
8874     }
8875   return ret.retn();
8876 }
8877
8878 /*!
8879  * Assigns \a newValue to all elements holding \a oldValue within \a this
8880  * one-dimensional array.
8881  *  \param [in] oldValue - the value to replace.
8882  *  \param [in] newValue - the value to assign.
8883  *  \return int - number of replacements performed.
8884  *  \throw If \a this is not allocated.
8885  *  \throw If \a this->getNumberOfComponents() != 1.
8886  */
8887 int DataArrayInt::changeValue(int oldValue, int newValue)
8888 {
8889   checkAllocated();
8890   if(getNumberOfComponents()!=1)
8891     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8892   if(oldValue==newValue)
8893     return 0;
8894   int *start(getPointer()),*end2(start+getNbOfElems());
8895   int ret(0);
8896   for(int *val=start;val!=end2;val++)
8897     {
8898       if(*val==oldValue)
8899         {
8900           *val=newValue;
8901           ret++;
8902         }
8903     }
8904   if(ret>0)
8905     declareAsNew();
8906   return ret;
8907 }
8908
8909 /*!
8910  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8911  * one of given values.
8912  *  \param [in] valsBg - an array of values to find within \a this array.
8913  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8914  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8915  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8916  *          array using decrRef() as it is no more needed.
8917  *  \throw If \a this->getNumberOfComponents() != 1.
8918  */
8919 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
8920 {
8921   if(getNumberOfComponents()!=1)
8922     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8923   std::set<int> vals2(valsBg,valsEnd);
8924   const int *cptr(getConstPointer());
8925   std::vector<int> res;
8926   int nbOfTuples(getNumberOfTuples());
8927   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8928   for(int i=0;i<nbOfTuples;i++,cptr++)
8929     if(vals2.find(*cptr)!=vals2.end())
8930       ret->pushBackSilent(i);
8931   return ret.retn();
8932 }
8933
8934 /*!
8935  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8936  * equal to any of given values.
8937  *  \param [in] valsBg - an array of values to ignore within \a this array.
8938  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8939  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8940  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8941  *          array using decrRef() as it is no more needed.
8942  *  \throw If \a this->getNumberOfComponents() != 1.
8943  */
8944 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8945 {
8946   if(getNumberOfComponents()!=1)
8947     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8948   std::set<int> vals2(valsBg,valsEnd);
8949   const int *cptr=getConstPointer();
8950   std::vector<int> res;
8951   int nbOfTuples=getNumberOfTuples();
8952   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8953   for(int i=0;i<nbOfTuples;i++,cptr++)
8954     if(vals2.find(*cptr)==vals2.end())
8955       ret->pushBackSilent(i);
8956   return ret.retn();
8957 }
8958
8959 /*!
8960  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
8961  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8962  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8963  * If any the tuple id is returned. If not -1 is returned.
8964  * 
8965  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8966  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8967  *
8968  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8969  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
8970  */
8971 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
8972 {
8973   checkAllocated();
8974   int nbOfCompo=getNumberOfComponents();
8975   if(nbOfCompo==0)
8976     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
8977   if(nbOfCompo!=(int)tupl.size())
8978     {
8979       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8980       throw INTERP_KERNEL::Exception(oss.str().c_str());
8981     }
8982   const int *cptr=getConstPointer();
8983   std::size_t nbOfVals=getNbOfElems();
8984   for(const int *work=cptr;work!=cptr+nbOfVals;)
8985     {
8986       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8987       if(work!=cptr+nbOfVals)
8988         {
8989           if(std::distance(cptr,work)%nbOfCompo!=0)
8990             work++;
8991           else
8992             return std::distance(cptr,work)/nbOfCompo;
8993         }
8994     }
8995   return -1;
8996 }
8997
8998 /*!
8999  * This method searches the sequence specified in input parameter \b vals in \b this.
9000  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
9001  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
9002  * \sa DataArrayInt::findIdFirstEqualTuple
9003  */
9004 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
9005 {
9006   checkAllocated();
9007   int nbOfCompo=getNumberOfComponents();
9008   if(nbOfCompo!=1)
9009     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
9010   const int *cptr=getConstPointer();
9011   std::size_t nbOfVals=getNbOfElems();
9012   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
9013   if(loc!=cptr+nbOfVals)
9014     return std::distance(cptr,loc);
9015   return -1;
9016 }
9017
9018 /*!
9019  * This method expects to be called when number of components of this is equal to one.
9020  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
9021  * If not any tuple contains \b value -1 is returned.
9022  * \sa DataArrayInt::presenceOfValue
9023  */
9024 int DataArrayInt::findIdFirstEqual(int value) const
9025 {
9026   checkAllocated();
9027   if(getNumberOfComponents()!=1)
9028     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
9029   const int *cptr=getConstPointer();
9030   int nbOfTuples=getNumberOfTuples();
9031   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
9032   if(ret!=cptr+nbOfTuples)
9033     return std::distance(cptr,ret);
9034   return -1;
9035 }
9036
9037 /*!
9038  * This method expects to be called when number of components of this is equal to one.
9039  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
9040  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
9041  * \sa DataArrayInt::presenceOfValue
9042  */
9043 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
9044 {
9045   checkAllocated();
9046   if(getNumberOfComponents()!=1)
9047     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
9048   std::set<int> vals2(vals.begin(),vals.end());
9049   const int *cptr=getConstPointer();
9050   int nbOfTuples=getNumberOfTuples();
9051   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
9052     if(vals2.find(*w)!=vals2.end())
9053       return std::distance(cptr,w);
9054   return -1;
9055 }
9056
9057 /*!
9058  * This method returns the number of values in \a this that are equals to input parameter \a value.
9059  * This method only works for single component array.
9060  *
9061  * \return a value in [ 0, \c this->getNumberOfTuples() )
9062  *
9063  * \throw If \a this is not allocated
9064  *
9065  */
9066 int DataArrayInt::count(int value) const
9067 {
9068   int ret=0;
9069   checkAllocated();
9070   if(getNumberOfComponents()!=1)
9071     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
9072   const int *vals=begin();
9073   int nbOfTuples=getNumberOfTuples();
9074   for(int i=0;i<nbOfTuples;i++,vals++)
9075     if(*vals==value)
9076       ret++;
9077   return ret;
9078 }
9079
9080 /*!
9081  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
9082  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
9083  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
9084  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
9085  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
9086  * \sa DataArrayInt::findIdFirstEqualTuple
9087  */
9088 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
9089 {
9090   return findIdFirstEqualTuple(tupl)!=-1;
9091 }
9092
9093
9094 /*!
9095  * Returns \a true if a given value is present within \a this one-dimensional array.
9096  *  \param [in] value - the value to find within \a this array.
9097  *  \return bool - \a true in case if \a value is present within \a this array.
9098  *  \throw If \a this is not allocated.
9099  *  \throw If \a this->getNumberOfComponents() != 1.
9100  *  \sa findIdFirstEqual()
9101  */
9102 bool DataArrayInt::presenceOfValue(int value) const
9103 {
9104   return findIdFirstEqual(value)!=-1;
9105 }
9106
9107 /*!
9108  * This method expects to be called when number of components of this is equal to one.
9109  * This method returns true if it exists a tuple so that the value is contained in \b vals.
9110  * If not any tuple contains one of the values contained in 'vals' false is returned.
9111  * \sa DataArrayInt::findIdFirstEqual
9112  */
9113 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
9114 {
9115   return findIdFirstEqual(vals)!=-1;
9116 }
9117
9118 /*!
9119  * Accumulates values of each component of \a this array.
9120  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
9121  *         by the caller, that is filled by this method with sum value for each
9122  *         component.
9123  *  \throw If \a this is not allocated.
9124  */
9125 void DataArrayInt::accumulate(int *res) const
9126 {
9127   checkAllocated();
9128   const int *ptr=getConstPointer();
9129   int nbTuple=getNumberOfTuples();
9130   int nbComps=getNumberOfComponents();
9131   std::fill(res,res+nbComps,0);
9132   for(int i=0;i<nbTuple;i++)
9133     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
9134 }
9135
9136 int DataArrayInt::accumulate(int compId) const
9137 {
9138   checkAllocated();
9139   const int *ptr=getConstPointer();
9140   int nbTuple=getNumberOfTuples();
9141   int nbComps=getNumberOfComponents();
9142   if(compId<0 || compId>=nbComps)
9143     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
9144   int ret=0;
9145   for(int i=0;i<nbTuple;i++)
9146     ret+=ptr[i*nbComps+compId];
9147   return ret;
9148 }
9149
9150 /*!
9151  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
9152  * The returned array will have same number of components than \a this and number of tuples equal to
9153  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
9154  *
9155  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
9156  *
9157  * \param [in] bgOfIndex - begin (included) of the input index array.
9158  * \param [in] endOfIndex - end (excluded) of the input index array.
9159  * \return DataArrayInt * - the new instance having the same number of components than \a this.
9160  * 
9161  * \throw If bgOfIndex or end is NULL.
9162  * \throw If input index array is not ascendingly sorted.
9163  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
9164  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
9165  */
9166 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
9167 {
9168   if(!bgOfIndex || !endOfIndex)
9169     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
9170   checkAllocated();
9171   int nbCompo=getNumberOfComponents();
9172   int nbOfTuples=getNumberOfTuples();
9173   int sz=(int)std::distance(bgOfIndex,endOfIndex);
9174   if(sz<1)
9175     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
9176   sz--;
9177   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
9178   const int *w=bgOfIndex;
9179   if(*w<0 || *w>=nbOfTuples)
9180     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
9181   const int *srcPt=begin()+(*w)*nbCompo;
9182   int *tmp=ret->getPointer();
9183   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
9184     {
9185       std::fill(tmp,tmp+nbCompo,0);
9186       if(w[1]>=w[0])
9187         {
9188           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
9189             {
9190               if(j>=0 && j<nbOfTuples)
9191                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
9192               else
9193                 {
9194                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
9195                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9196                 }
9197             }
9198         }
9199       else
9200         {
9201           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
9202           throw INTERP_KERNEL::Exception(oss.str().c_str());
9203         }
9204     }
9205   ret->copyStringInfoFrom(*this);
9206   return ret.retn();
9207 }
9208
9209 /*!
9210  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
9211  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
9212  * offsetA2</em> and (2)
9213  * the number of component in the result array is same as that of each of given arrays.
9214  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
9215  * Info on components is copied from the first of the given arrays. Number of components
9216  * in the given arrays must be the same.
9217  *  \param [in] a1 - an array to include in the result array.
9218  *  \param [in] a2 - another array to include in the result array.
9219  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
9220  *  \return DataArrayInt * - the new instance of DataArrayInt.
9221  *          The caller is to delete this result array using decrRef() as it is no more
9222  *          needed.
9223  *  \throw If either \a a1 or \a a2 is NULL.
9224  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
9225  */
9226 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
9227 {
9228   if(!a1 || !a2)
9229     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
9230   int nbOfComp=a1->getNumberOfComponents();
9231   if(nbOfComp!=a2->getNumberOfComponents())
9232     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
9233   int nbOfTuple1=a1->getNumberOfTuples();
9234   int nbOfTuple2=a2->getNumberOfTuples();
9235   DataArrayInt *ret=DataArrayInt::New();
9236   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
9237   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
9238   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
9239   ret->copyStringInfoFrom(*a1);
9240   return ret;
9241 }
9242
9243 /*!
9244  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
9245  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
9246  * the number of component in the result array is same as that of each of given arrays.
9247  * Info on components is copied from the first of the given arrays. Number of components
9248  * in the given arrays must be  the same.
9249  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
9250  * not the object itself.
9251  *  \param [in] arr - a sequence of arrays to include in the result array.
9252  *  \return DataArrayInt * - the new instance of DataArrayInt.
9253  *          The caller is to delete this result array using decrRef() as it is no more
9254  *          needed.
9255  *  \throw If all arrays within \a arr are NULL.
9256  *  \throw If getNumberOfComponents() of arrays within \a arr.
9257  */
9258 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
9259 {
9260   std::vector<const DataArrayInt *> a;
9261   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9262     if(*it4)
9263       a.push_back(*it4);
9264   if(a.empty())
9265     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
9266   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
9267   int nbOfComp=(*it)->getNumberOfComponents();
9268   int nbt=(*it++)->getNumberOfTuples();
9269   for(int i=1;it!=a.end();it++,i++)
9270     {
9271       if((*it)->getNumberOfComponents()!=nbOfComp)
9272         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
9273       nbt+=(*it)->getNumberOfTuples();
9274     }
9275   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9276   ret->alloc(nbt,nbOfComp);
9277   int *pt=ret->getPointer();
9278   for(it=a.begin();it!=a.end();it++)
9279     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
9280   ret->copyStringInfoFrom(*(a[0]));
9281   return ret.retn();
9282 }
9283
9284 /*!
9285  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
9286  * A packed index array is an allocated array with one component, and at least one tuple. The first element
9287  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
9288  * 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.
9289  * 
9290  * \return DataArrayInt * - a new object to be managed by the caller.
9291  */
9292 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
9293 {
9294   int retSz=1;
9295   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
9296     {
9297       if(*it4)
9298         {
9299           (*it4)->checkAllocated();
9300           if((*it4)->getNumberOfComponents()!=1)
9301             {
9302               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9303               throw INTERP_KERNEL::Exception(oss.str().c_str());
9304             }
9305           int nbTupl=(*it4)->getNumberOfTuples();
9306           if(nbTupl<1)
9307             {
9308               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9309               throw INTERP_KERNEL::Exception(oss.str().c_str());
9310             }
9311           if((*it4)->front()!=0)
9312             {
9313               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
9314               throw INTERP_KERNEL::Exception(oss.str().c_str());
9315             }
9316           retSz+=nbTupl-1;
9317         }
9318       else
9319         {
9320           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
9321           throw INTERP_KERNEL::Exception(oss.str().c_str());
9322         }
9323     }
9324   if(arrs.empty())
9325     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
9326   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9327   ret->alloc(retSz,1);
9328   int *pt=ret->getPointer(); *pt++=0;
9329   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
9330     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
9331   ret->copyStringInfoFrom(*(arrs[0]));
9332   return ret.retn();
9333 }
9334
9335 /*!
9336  * Returns the maximal value and its location within \a this one-dimensional array.
9337  *  \param [out] tupleId - index of the tuple holding the maximal value.
9338  *  \return int - the maximal value among all values of \a this array.
9339  *  \throw If \a this->getNumberOfComponents() != 1
9340  *  \throw If \a this->getNumberOfTuples() < 1
9341  */
9342 int DataArrayInt::getMaxValue(int& tupleId) const
9343 {
9344   checkAllocated();
9345   if(getNumberOfComponents()!=1)
9346     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9347   int nbOfTuples=getNumberOfTuples();
9348   if(nbOfTuples<=0)
9349     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9350   const int *vals=getConstPointer();
9351   const int *loc=std::max_element(vals,vals+nbOfTuples);
9352   tupleId=(int)std::distance(vals,loc);
9353   return *loc;
9354 }
9355
9356 /*!
9357  * Returns the maximal value within \a this array that is allowed to have more than
9358  *  one component.
9359  *  \return int - the maximal value among all values of \a this array.
9360  *  \throw If \a this is not allocated.
9361  */
9362 int DataArrayInt::getMaxValueInArray() const
9363 {
9364   checkAllocated();
9365   const int *loc=std::max_element(begin(),end());
9366   return *loc;
9367 }
9368
9369 /*!
9370  * Returns the minimal value and its location within \a this one-dimensional array.
9371  *  \param [out] tupleId - index of the tuple holding the minimal value.
9372  *  \return int - the minimal value among all values of \a this array.
9373  *  \throw If \a this->getNumberOfComponents() != 1
9374  *  \throw If \a this->getNumberOfTuples() < 1
9375  */
9376 int DataArrayInt::getMinValue(int& tupleId) const
9377 {
9378   checkAllocated();
9379   if(getNumberOfComponents()!=1)
9380     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9381   int nbOfTuples=getNumberOfTuples();
9382   if(nbOfTuples<=0)
9383     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9384   const int *vals=getConstPointer();
9385   const int *loc=std::min_element(vals,vals+nbOfTuples);
9386   tupleId=(int)std::distance(vals,loc);
9387   return *loc;
9388 }
9389
9390 /*!
9391  * Returns the minimal value within \a this array that is allowed to have more than
9392  *  one component.
9393  *  \return int - the minimal value among all values of \a this array.
9394  *  \throw If \a this is not allocated.
9395  */
9396 int DataArrayInt::getMinValueInArray() const
9397 {
9398   checkAllocated();
9399   const int *loc=std::min_element(begin(),end());
9400   return *loc;
9401 }
9402
9403 /*!
9404  * Returns in a single walk in \a this the min value and the max value in \a this.
9405  * \a this is expected to be single component array.
9406  *
9407  * \param [out] minValue - the min value in \a this.
9408  * \param [out] maxValue - the max value in \a this.
9409  *
9410  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
9411  */
9412 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
9413 {
9414   checkAllocated();
9415   if(getNumberOfComponents()!=1)
9416     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
9417   int nbTuples(getNumberOfTuples());
9418   const int *pt(begin());
9419   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
9420   for(int i=0;i<nbTuples;i++,pt++)
9421     {
9422       if(*pt<minValue)
9423         minValue=*pt;
9424       if(*pt>maxValue)
9425         maxValue=*pt;
9426     }
9427 }
9428
9429 /*!
9430  * Converts every value of \a this array to its absolute value.
9431  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
9432  * should be called instead.
9433  *
9434  * \throw If \a this is not allocated.
9435  * \sa DataArrayInt::computeAbs
9436  */
9437 void DataArrayInt::abs()
9438 {
9439   checkAllocated();
9440   int *ptr(getPointer());
9441   std::size_t nbOfElems(getNbOfElems());
9442   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
9443   declareAsNew();
9444 }
9445
9446 /*!
9447  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
9448  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
9449  *
9450  * \return DataArrayInt * - the new instance of DataArrayInt containing the
9451  *         same number of tuples and component as \a this array.
9452  *         The caller is to delete this result array using decrRef() as it is no more
9453  *         needed.
9454  * \throw If \a this is not allocated.
9455  * \sa DataArrayInt::abs
9456  */
9457 DataArrayInt *DataArrayInt::computeAbs() const
9458 {
9459   checkAllocated();
9460   DataArrayInt *newArr(DataArrayInt::New());
9461   int nbOfTuples(getNumberOfTuples());
9462   int nbOfComp(getNumberOfComponents());
9463   newArr->alloc(nbOfTuples,nbOfComp);
9464   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
9465   newArr->copyStringInfoFrom(*this);
9466   return newArr;
9467 }
9468
9469 /*!
9470  * Apply a liner function to a given component of \a this array, so that
9471  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
9472  *  \param [in] a - the first coefficient of the function.
9473  *  \param [in] b - the second coefficient of the function.
9474  *  \param [in] compoId - the index of component to modify.
9475  *  \throw If \a this is not allocated.
9476  */
9477 void DataArrayInt::applyLin(int a, int b, int compoId)
9478 {
9479   checkAllocated();
9480   int *ptr=getPointer()+compoId;
9481   int nbOfComp=getNumberOfComponents();
9482   int nbOfTuple=getNumberOfTuples();
9483   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
9484     *ptr=a*(*ptr)+b;
9485   declareAsNew();
9486 }
9487
9488 /*!
9489  * Apply a liner function to all elements of \a this array, so that
9490  * an element _x_ becomes \f$ a * x + b \f$.
9491  *  \param [in] a - the first coefficient of the function.
9492  *  \param [in] b - the second coefficient of the function.
9493  *  \throw If \a this is not allocated.
9494  */
9495 void DataArrayInt::applyLin(int a, int b)
9496 {
9497   checkAllocated();
9498   int *ptr=getPointer();
9499   std::size_t nbOfElems=getNbOfElems();
9500   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9501     *ptr=a*(*ptr)+b;
9502   declareAsNew();
9503 }
9504
9505 /*!
9506  * Returns a full copy of \a this array except that sign of all elements is reversed.
9507  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
9508  *          same number of tuples and component as \a this array.
9509  *          The caller is to delete this result array using decrRef() as it is no more
9510  *          needed.
9511  *  \throw If \a this is not allocated.
9512  */
9513 DataArrayInt *DataArrayInt::negate() const
9514 {
9515   checkAllocated();
9516   DataArrayInt *newArr=DataArrayInt::New();
9517   int nbOfTuples=getNumberOfTuples();
9518   int nbOfComp=getNumberOfComponents();
9519   newArr->alloc(nbOfTuples,nbOfComp);
9520   const int *cptr=getConstPointer();
9521   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
9522   newArr->copyStringInfoFrom(*this);
9523   return newArr;
9524 }
9525
9526 /*!
9527  * Modify all elements of \a this array, so that
9528  * an element _x_ becomes \f$ numerator / x \f$.
9529  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9530  *           array, all elements processed before detection of the zero element remain
9531  *           modified.
9532  *  \param [in] numerator - the numerator used to modify array elements.
9533  *  \throw If \a this is not allocated.
9534  *  \throw If there is an element equal to 0 in \a this array.
9535  */
9536 void DataArrayInt::applyInv(int numerator)
9537 {
9538   checkAllocated();
9539   int *ptr=getPointer();
9540   std::size_t nbOfElems=getNbOfElems();
9541   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9542     {
9543       if(*ptr!=0)
9544         {
9545           *ptr=numerator/(*ptr);
9546         }
9547       else
9548         {
9549           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9550           oss << " !";
9551           throw INTERP_KERNEL::Exception(oss.str().c_str());
9552         }
9553     }
9554   declareAsNew();
9555 }
9556
9557 /*!
9558  * Modify all elements of \a this array, so that
9559  * an element _x_ becomes \f$ x / val \f$.
9560  *  \param [in] val - the denominator used to modify array elements.
9561  *  \throw If \a this is not allocated.
9562  *  \throw If \a val == 0.
9563  */
9564 void DataArrayInt::applyDivideBy(int val)
9565 {
9566   if(val==0)
9567     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
9568   checkAllocated();
9569   int *ptr=getPointer();
9570   std::size_t nbOfElems=getNbOfElems();
9571   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
9572   declareAsNew();
9573 }
9574
9575 /*!
9576  * Modify all elements of \a this array, so that
9577  * an element _x_ becomes  <em> x % val </em>.
9578  *  \param [in] val - the divisor used to modify array elements.
9579  *  \throw If \a this is not allocated.
9580  *  \throw If \a val <= 0.
9581  */
9582 void DataArrayInt::applyModulus(int val)
9583 {
9584   if(val<=0)
9585     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
9586   checkAllocated();
9587   int *ptr=getPointer();
9588   std::size_t nbOfElems=getNbOfElems();
9589   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
9590   declareAsNew();
9591 }
9592
9593 /*!
9594  * This method works only on data array with one component.
9595  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9596  * this[*id] in [\b vmin,\b vmax)
9597  * 
9598  * \param [in] vmin begin of range. This value is included in range (included).
9599  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9600  * \return a newly allocated data array that the caller should deal with.
9601  *
9602  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
9603  */
9604 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
9605 {
9606   checkAllocated();
9607   if(getNumberOfComponents()!=1)
9608     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsInRange : this must have exactly one component !");
9609   const int *cptr(begin());
9610   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9611   int nbOfTuples(getNumberOfTuples());
9612   for(int i=0;i<nbOfTuples;i++,cptr++)
9613     if(*cptr>=vmin && *cptr<vmax)
9614       ret->pushBackSilent(i);
9615   return ret.retn();
9616 }
9617
9618 /*!
9619  * This method works only on data array with one component.
9620  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9621  * this[*id] \b not in [\b vmin,\b vmax)
9622  * 
9623  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
9624  * \param [in] vmax end of range. This value is included in range (included).
9625  * \return a newly allocated data array that the caller should deal with.
9626  * 
9627  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
9628  */
9629 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
9630 {
9631   checkAllocated();
9632   if(getNumberOfComponents()!=1)
9633     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotInRange : this must have exactly one component !");
9634   const int *cptr(getConstPointer());
9635   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9636   int nbOfTuples(getNumberOfTuples());
9637   for(int i=0;i<nbOfTuples;i++,cptr++)
9638     if(*cptr<vmin || *cptr>=vmax)
9639       ret->pushBackSilent(i);
9640   return ret.retn();
9641 }
9642
9643 /*!
9644  * 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.
9645  *
9646  * \return a newly allocated data array that the caller should deal with.
9647  * \sa DataArrayInt::findIdsInRange
9648  */
9649 DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
9650 {
9651   checkAllocated();
9652   if(getNumberOfComponents()!=1)
9653     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsStricltyNegative : this must have exactly one component !");
9654   const int *cptr(getConstPointer());
9655   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9656   int nbOfTuples(getNumberOfTuples());
9657   for(int i=0;i<nbOfTuples;i++,cptr++)
9658     if(*cptr<0)
9659       ret->pushBackSilent(i);
9660   return ret.retn();
9661 }
9662
9663 /*!
9664  * This method works only on data array with one component.
9665  * 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.
9666  * 
9667  * \param [in] vmin begin of range. This value is included in range (included).
9668  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9669  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
9670 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
9671 {
9672   checkAllocated();
9673   if(getNumberOfComponents()!=1)
9674     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9675   int nbOfTuples=getNumberOfTuples();
9676   bool ret=true;
9677   const int *cptr=getConstPointer();
9678   for(int i=0;i<nbOfTuples;i++,cptr++)
9679     {
9680       if(*cptr>=vmin && *cptr<vmax)
9681         { ret=ret && *cptr==i; }
9682       else
9683         {
9684           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9685           throw INTERP_KERNEL::Exception(oss.str().c_str());
9686         }
9687     }
9688   return ret;
9689 }
9690
9691 /*!
9692  * Modify all elements of \a this array, so that
9693  * an element _x_ becomes <em> val % x </em>.
9694  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9695  *           array, all elements processed before detection of the zero element remain
9696  *           modified.
9697  *  \param [in] val - the divident used to modify array elements.
9698  *  \throw If \a this is not allocated.
9699  *  \throw If there is an element equal to or less than 0 in \a this array.
9700  */
9701 void DataArrayInt::applyRModulus(int val)
9702 {
9703   checkAllocated();
9704   int *ptr=getPointer();
9705   std::size_t nbOfElems=getNbOfElems();
9706   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9707     {
9708       if(*ptr>0)
9709         {
9710           *ptr=val%(*ptr);
9711         }
9712       else
9713         {
9714           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9715           oss << " !";
9716           throw INTERP_KERNEL::Exception(oss.str().c_str());
9717         }
9718     }
9719   declareAsNew();
9720 }
9721
9722 /*!
9723  * Modify all elements of \a this array, so that
9724  * an element _x_ becomes <em> val ^ x </em>.
9725  *  \param [in] val - the value used to apply pow on all array elements.
9726  *  \throw If \a this is not allocated.
9727  *  \throw If \a val < 0.
9728  */
9729 void DataArrayInt::applyPow(int val)
9730 {
9731   checkAllocated();
9732   if(val<0)
9733     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9734   int *ptr=getPointer();
9735   std::size_t nbOfElems=getNbOfElems();
9736   if(val==0)
9737     {
9738       std::fill(ptr,ptr+nbOfElems,1);
9739       return ;
9740     }
9741   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9742     {
9743       int tmp=1;
9744       for(int j=0;j<val;j++)
9745         tmp*=*ptr;
9746       *ptr=tmp;
9747     }
9748   declareAsNew();
9749 }
9750
9751 /*!
9752  * Modify all elements of \a this array, so that
9753  * an element _x_ becomes \f$ val ^ x \f$.
9754  *  \param [in] val - the value used to apply pow on all array elements.
9755  *  \throw If \a this is not allocated.
9756  *  \throw If there is an element < 0 in \a this array.
9757  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9758  *           array, all elements processed before detection of the zero element remain
9759  *           modified.
9760  */
9761 void DataArrayInt::applyRPow(int val)
9762 {
9763   checkAllocated();
9764   int *ptr=getPointer();
9765   std::size_t nbOfElems=getNbOfElems();
9766   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9767     {
9768       if(*ptr>=0)
9769         {
9770           int tmp=1;
9771           for(int j=0;j<*ptr;j++)
9772             tmp*=val;
9773           *ptr=tmp;
9774         }
9775       else
9776         {
9777           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9778           oss << " !";
9779           throw INTERP_KERNEL::Exception(oss.str().c_str());
9780         }
9781     }
9782   declareAsNew();
9783 }
9784
9785 /*!
9786  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9787  * of components in the result array is a sum of the number of components of given arrays
9788  * and (2) the number of tuples in the result array is same as that of each of given
9789  * arrays. In other words the i-th tuple of result array includes all components of
9790  * i-th tuples of all given arrays.
9791  * Number of tuples in the given arrays must be the same.
9792  *  \param [in] a1 - an array to include in the result array.
9793  *  \param [in] a2 - another array to include in the result array.
9794  *  \return DataArrayInt * - the new instance of DataArrayInt.
9795  *          The caller is to delete this result array using decrRef() as it is no more
9796  *          needed.
9797  *  \throw If both \a a1 and \a a2 are NULL.
9798  *  \throw If any given array is not allocated.
9799  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9800  */
9801 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9802 {
9803   std::vector<const DataArrayInt *> arr(2);
9804   arr[0]=a1; arr[1]=a2;
9805   return Meld(arr);
9806 }
9807
9808 /*!
9809  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9810  * of components in the result array is a sum of the number of components of given arrays
9811  * and (2) the number of tuples in the result array is same as that of each of given
9812  * arrays. In other words the i-th tuple of result array includes all components of
9813  * i-th tuples of all given arrays.
9814  * Number of tuples in the given arrays must be  the same.
9815  *  \param [in] arr - a sequence of arrays to include in the result array.
9816  *  \return DataArrayInt * - the new instance of DataArrayInt.
9817  *          The caller is to delete this result array using decrRef() as it is no more
9818  *          needed.
9819  *  \throw If all arrays within \a arr are NULL.
9820  *  \throw If any given array is not allocated.
9821  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9822  */
9823 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9824 {
9825   std::vector<const DataArrayInt *> a;
9826   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9827     if(*it4)
9828       a.push_back(*it4);
9829   if(a.empty())
9830     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9831   std::vector<const DataArrayInt *>::const_iterator it;
9832   for(it=a.begin();it!=a.end();it++)
9833     (*it)->checkAllocated();
9834   it=a.begin();
9835   int nbOfTuples=(*it)->getNumberOfTuples();
9836   std::vector<int> nbc(a.size());
9837   std::vector<const int *> pts(a.size());
9838   nbc[0]=(*it)->getNumberOfComponents();
9839   pts[0]=(*it++)->getConstPointer();
9840   for(int i=1;it!=a.end();it++,i++)
9841     {
9842       if(nbOfTuples!=(*it)->getNumberOfTuples())
9843         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9844       nbc[i]=(*it)->getNumberOfComponents();
9845       pts[i]=(*it)->getConstPointer();
9846     }
9847   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9848   DataArrayInt *ret=DataArrayInt::New();
9849   ret->alloc(nbOfTuples,totalNbOfComp);
9850   int *retPtr=ret->getPointer();
9851   for(int i=0;i<nbOfTuples;i++)
9852     for(int j=0;j<(int)a.size();j++)
9853       {
9854         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9855         pts[j]+=nbc[j];
9856       }
9857   int k=0;
9858   for(int i=0;i<(int)a.size();i++)
9859     for(int j=0;j<nbc[i];j++,k++)
9860       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
9861   return ret;
9862 }
9863
9864 /*!
9865  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9866  * The i-th item of the result array is an ID of a set of elements belonging to a
9867  * unique set of groups, which the i-th element is a part of. This set of elements
9868  * belonging to a unique set of groups is called \a family, so the result array contains
9869  * IDs of families each element belongs to.
9870  *
9871  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9872  * then there are 3 families:
9873  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9874  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9875  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9876  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9877  * stands for the element #3 which is in none of groups.
9878  *
9879  *  \param [in] groups - sequence of groups of element IDs.
9880  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9881  *         in \a groups.
9882  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9883  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9884  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9885  *         delete this array using decrRef() as it is no more needed.
9886  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9887  */
9888 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9889 {
9890   std::vector<const DataArrayInt *> groups2;
9891   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9892     if(*it4)
9893       groups2.push_back(*it4);
9894   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9895   ret->alloc(newNb,1);
9896   int *retPtr=ret->getPointer();
9897   std::fill(retPtr,retPtr+newNb,0);
9898   int fid=1;
9899   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9900     {
9901       const int *ptr=(*iter)->getConstPointer();
9902       std::size_t nbOfElem=(*iter)->getNbOfElems();
9903       int sfid=fid;
9904       for(int j=0;j<sfid;j++)
9905         {
9906           bool found=false;
9907           for(std::size_t i=0;i<nbOfElem;i++)
9908             {
9909               if(ptr[i]>=0 && ptr[i]<newNb)
9910                 {
9911                   if(retPtr[ptr[i]]==j)
9912                     {
9913                       retPtr[ptr[i]]=fid;
9914                       found=true;
9915                     }
9916                 }
9917               else
9918                 {
9919                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9920                   oss << ") !";
9921                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9922                 }
9923             }
9924           if(found)
9925             fid++;
9926         }
9927     }
9928   fidsOfGroups.clear();
9929   fidsOfGroups.resize(groups2.size());
9930   int grId=0;
9931   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9932     {
9933       std::set<int> tmp;
9934       const int *ptr=(*iter)->getConstPointer();
9935       std::size_t nbOfElem=(*iter)->getNbOfElems();
9936       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9937         tmp.insert(retPtr[*p]);
9938       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9939     }
9940   return ret.retn();
9941 }
9942
9943 /*!
9944  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9945  * arrays. The result array does not contain any duplicates and its values
9946  * are sorted in ascending order.
9947  *  \param [in] arr - sequence of DataArrayInt's to unite.
9948  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9949  *         array using decrRef() as it is no more needed.
9950  *  \throw If any \a arr[i] is not allocated.
9951  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9952  */
9953 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
9954 {
9955   std::vector<const DataArrayInt *> a;
9956   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9957     if(*it4)
9958       a.push_back(*it4);
9959   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9960     {
9961       (*it)->checkAllocated();
9962       if((*it)->getNumberOfComponents()!=1)
9963         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9964     }
9965   //
9966   std::set<int> r;
9967   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9968     {
9969       const int *pt=(*it)->getConstPointer();
9970       int nbOfTuples=(*it)->getNumberOfTuples();
9971       r.insert(pt,pt+nbOfTuples);
9972     }
9973   DataArrayInt *ret=DataArrayInt::New();
9974   ret->alloc((int)r.size(),1);
9975   std::copy(r.begin(),r.end(),ret->getPointer());
9976   return ret;
9977 }
9978
9979 /*!
9980  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9981  * arrays. The result array does not contain any duplicates and its values
9982  * are sorted in ascending order.
9983  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9984  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9985  *         array using decrRef() as it is no more needed.
9986  *  \throw If any \a arr[i] is not allocated.
9987  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9988  */
9989 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
9990 {
9991   std::vector<const DataArrayInt *> a;
9992   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9993     if(*it4)
9994       a.push_back(*it4);
9995   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9996     {
9997       (*it)->checkAllocated();
9998       if((*it)->getNumberOfComponents()!=1)
9999         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
10000     }
10001   //
10002   std::set<int> r;
10003   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
10004     {
10005       const int *pt=(*it)->getConstPointer();
10006       int nbOfTuples=(*it)->getNumberOfTuples();
10007       std::set<int> s1(pt,pt+nbOfTuples);
10008       if(it!=a.begin())
10009         {
10010           std::set<int> r2;
10011           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
10012           r=r2;
10013         }
10014       else
10015         r=s1;
10016     }
10017   DataArrayInt *ret(DataArrayInt::New());
10018   ret->alloc((int)r.size(),1);
10019   std::copy(r.begin(),r.end(),ret->getPointer());
10020   return ret;
10021 }
10022
10023 /// @cond INTERNAL
10024 namespace MEDCouplingImpl
10025 {
10026   class OpSwitchedOn
10027   {
10028   public:
10029     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
10030     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
10031   private:
10032     int *_pt;
10033     int _cnt;
10034   };
10035
10036   class OpSwitchedOff
10037   {
10038   public:
10039     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
10040     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
10041   private:
10042     int *_pt;
10043     int _cnt;
10044   };
10045 }
10046 /// @endcond
10047
10048 /*!
10049  * This method returns the list of ids in ascending mode so that v[id]==true.
10050  */
10051 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
10052 {
10053   int sz((int)std::count(v.begin(),v.end(),true));
10054   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10055   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
10056   return ret.retn();
10057 }
10058
10059 /*!
10060  * This method returns the list of ids in ascending mode so that v[id]==false.
10061  */
10062 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
10063 {
10064   int sz((int)std::count(v.begin(),v.end(),false));
10065   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10066   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
10067   return ret.retn();
10068 }
10069
10070 /*!
10071  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
10072  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
10073  *
10074  * \param [in] v the input data structure to be translate into skyline format.
10075  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
10076  * \param [out] dataIndex the second element of the skyline format.
10077  */
10078 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
10079 {
10080   int sz((int)v.size());
10081   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
10082   ret1->alloc(sz+1,1);
10083   int *pt(ret1->getPointer()); *pt=0;
10084   for(int i=0;i<sz;i++,pt++)
10085     pt[1]=pt[0]+(int)v[i].size();
10086   ret0->alloc(ret1->back(),1);
10087   pt=ret0->getPointer();
10088   for(int i=0;i<sz;i++)
10089     pt=std::copy(v[i].begin(),v[i].end(),pt);
10090   data=ret0.retn(); dataIndex=ret1.retn();
10091 }
10092
10093 /*!
10094  * Returns a new DataArrayInt which contains a complement of elements of \a this
10095  * one-dimensional array. I.e. the result array contains all elements from the range [0,
10096  * \a nbOfElement) not present in \a this array.
10097  *  \param [in] nbOfElement - maximal size of the result array.
10098  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10099  *         array using decrRef() as it is no more needed.
10100  *  \throw If \a this is not allocated.
10101  *  \throw If \a this->getNumberOfComponents() != 1.
10102  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
10103  *         nbOfElement ).
10104  */
10105 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
10106 {
10107   checkAllocated();
10108   if(getNumberOfComponents()!=1)
10109     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
10110   std::vector<bool> tmp(nbOfElement);
10111   const int *pt=getConstPointer();
10112   int nbOfTuples=getNumberOfTuples();
10113   for(const int *w=pt;w!=pt+nbOfTuples;w++)
10114     if(*w>=0 && *w<nbOfElement)
10115       tmp[*w]=true;
10116     else
10117       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
10118   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
10119   DataArrayInt *ret=DataArrayInt::New();
10120   ret->alloc(nbOfRetVal,1);
10121   int j=0;
10122   int *retPtr=ret->getPointer();
10123   for(int i=0;i<nbOfElement;i++)
10124     if(!tmp[i])
10125       retPtr[j++]=i;
10126   return ret;
10127 }
10128
10129 /*!
10130  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
10131  * from an \a other one-dimensional array.
10132  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
10133  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
10134  *         caller is to delete this array using decrRef() as it is no more needed.
10135  *  \throw If \a other is NULL.
10136  *  \throw If \a other is not allocated.
10137  *  \throw If \a other->getNumberOfComponents() != 1.
10138  *  \throw If \a this is not allocated.
10139  *  \throw If \a this->getNumberOfComponents() != 1.
10140  *  \sa DataArrayInt::buildSubstractionOptimized()
10141  */
10142 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
10143 {
10144   if(!other)
10145     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
10146   checkAllocated();
10147   other->checkAllocated();
10148   if(getNumberOfComponents()!=1)
10149     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
10150   if(other->getNumberOfComponents()!=1)
10151     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
10152   const int *pt=getConstPointer();
10153   int nbOfTuples=getNumberOfTuples();
10154   std::set<int> s1(pt,pt+nbOfTuples);
10155   pt=other->getConstPointer();
10156   nbOfTuples=other->getNumberOfTuples();
10157   std::set<int> s2(pt,pt+nbOfTuples);
10158   std::vector<int> r;
10159   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
10160   DataArrayInt *ret=DataArrayInt::New();
10161   ret->alloc((int)r.size(),1);
10162   std::copy(r.begin(),r.end(),ret->getPointer());
10163   return ret;
10164 }
10165
10166 /*!
10167  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
10168  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
10169  * 
10170  * \param [in] other an array with one component and expected to be sorted ascendingly.
10171  * \ret list of ids in \a this but not in \a other.
10172  * \sa DataArrayInt::buildSubstraction
10173  */
10174 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
10175 {
10176   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
10177   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
10178   checkAllocated(); other->checkAllocated();
10179   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
10180   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
10181   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
10182   const int *work1(pt1Bg),*work2(pt2Bg);
10183   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
10184   for(;work1!=pt1End;work1++)
10185     {
10186       if(work2!=pt2End && *work1==*work2)
10187         work2++;
10188       else
10189         ret->pushBackSilent(*work1);
10190     }
10191   return ret.retn();
10192 }
10193
10194
10195 /*!
10196  * Returns a new DataArrayInt which contains all elements of \a this and a given
10197  * one-dimensional arrays. The result array does not contain any duplicates
10198  * and its values are sorted in ascending order.
10199  *  \param [in] other - an array to unite with \a this one.
10200  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10201  *         array using decrRef() as it is no more needed.
10202  *  \throw If \a this or \a other is not allocated.
10203  *  \throw If \a this->getNumberOfComponents() != 1.
10204  *  \throw If \a other->getNumberOfComponents() != 1.
10205  */
10206 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
10207 {
10208   std::vector<const DataArrayInt *>arrs(2);
10209   arrs[0]=this; arrs[1]=other;
10210   return BuildUnion(arrs);
10211 }
10212
10213
10214 /*!
10215  * Returns a new DataArrayInt which contains elements present in both \a this and a given
10216  * one-dimensional arrays. The result array does not contain any duplicates
10217  * and its values are sorted in ascending order.
10218  *  \param [in] other - an array to intersect with \a this one.
10219  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10220  *         array using decrRef() as it is no more needed.
10221  *  \throw If \a this or \a other is not allocated.
10222  *  \throw If \a this->getNumberOfComponents() != 1.
10223  *  \throw If \a other->getNumberOfComponents() != 1.
10224  */
10225 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
10226 {
10227   std::vector<const DataArrayInt *>arrs(2);
10228   arrs[0]=this; arrs[1]=other;
10229   return BuildIntersection(arrs);
10230 }
10231
10232 /*!
10233  * This method can be applied on allocated with one component DataArrayInt instance.
10234  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
10235  * 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]
10236  * 
10237  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
10238  * \throw if \a this is not allocated or if \a this has not exactly one component.
10239  * \sa DataArrayInt::buildUniqueNotSorted
10240  */
10241 DataArrayInt *DataArrayInt::buildUnique() const
10242 {
10243   checkAllocated();
10244   if(getNumberOfComponents()!=1)
10245     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
10246   int nbOfTuples=getNumberOfTuples();
10247   MCAuto<DataArrayInt> tmp=deepCopy();
10248   int *data=tmp->getPointer();
10249   int *last=std::unique(data,data+nbOfTuples);
10250   MCAuto<DataArrayInt> ret=DataArrayInt::New();
10251   ret->alloc(std::distance(data,last),1);
10252   std::copy(data,last,ret->getPointer());
10253   return ret.retn();
10254 }
10255
10256 /*!
10257  * This method can be applied on allocated with one component DataArrayInt instance.
10258  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
10259  *
10260  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
10261  *
10262  * \throw if \a this is not allocated or if \a this has not exactly one component.
10263  *
10264  * \sa DataArrayInt::buildUnique
10265  */
10266 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
10267 {
10268   checkAllocated();
10269     if(getNumberOfComponents()!=1)
10270       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
10271   int minVal,maxVal;
10272   getMinMaxValues(minVal,maxVal);
10273   std::vector<bool> b(maxVal-minVal+1,false);
10274   const int *ptBg(begin()),*endBg(end());
10275   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
10276   for(const int *pt=ptBg;pt!=endBg;pt++)
10277     {
10278       if(!b[*pt-minVal])
10279         {
10280           ret->pushBackSilent(*pt);
10281           b[*pt-minVal]=true;
10282         }
10283     }
10284   ret->copyStringInfoFrom(*this);
10285   return ret.retn();
10286 }
10287
10288 /*!
10289  * Returns a new DataArrayInt which contains size of every of groups described by \a this
10290  * "index" array. Such "index" array is returned for example by 
10291  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
10292  * "MEDCouplingUMesh::buildDescendingConnectivity" and
10293  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
10294  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
10295  * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
10296  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
10297  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
10298  *          The caller is to delete this array using decrRef() as it is no more needed. 
10299  *  \throw If \a this is not allocated.
10300  *  \throw If \a this->getNumberOfComponents() != 1.
10301  *  \throw If \a this->getNumberOfTuples() < 2.
10302  *
10303  *  \b Example: <br> 
10304  *         - this contains [1,3,6,7,7,9,15]
10305  *         - result array contains [2,3,1,0,2,6],
10306  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
10307  *
10308  * \sa DataArrayInt::computeOffsetsFull
10309  */
10310 DataArrayInt *DataArrayInt::deltaShiftIndex() const
10311 {
10312   checkAllocated();
10313   if(getNumberOfComponents()!=1)
10314     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
10315   int nbOfTuples=getNumberOfTuples();
10316   if(nbOfTuples<2)
10317     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
10318   const int *ptr=getConstPointer();
10319   DataArrayInt *ret=DataArrayInt::New();
10320   ret->alloc(nbOfTuples-1,1);
10321   int *out=ret->getPointer();
10322   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
10323   return ret;
10324 }
10325
10326 /*!
10327  * Modifies \a this one-dimensional array so that value of each element \a x
10328  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10329  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
10330  * and components remains the same.<br>
10331  * This method is useful for allToAllV in MPI with contiguous policy. This method
10332  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
10333  * this one.
10334  *  \throw If \a this is not allocated.
10335  *  \throw If \a this->getNumberOfComponents() != 1.
10336  *
10337  *  \b Example: <br>
10338  *          - Before \a this contains [3,5,1,2,0,8]
10339  *          - After \a this contains  [0,3,8,9,11,11]<br>
10340  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
10341  *          array is retained and thus there is no space to store the last element.
10342  */
10343 void DataArrayInt::computeOffsets()
10344 {
10345   checkAllocated();
10346   if(getNumberOfComponents()!=1)
10347     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
10348   int nbOfTuples=getNumberOfTuples();
10349   if(nbOfTuples==0)
10350     return ;
10351   int *work=getPointer();
10352   int tmp=work[0];
10353   work[0]=0;
10354   for(int i=1;i<nbOfTuples;i++)
10355     {
10356       int tmp2=work[i];
10357       work[i]=work[i-1]+tmp;
10358       tmp=tmp2;
10359     }
10360   declareAsNew();
10361 }
10362
10363
10364 /*!
10365  * Modifies \a this one-dimensional array so that value of each element \a x
10366  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10367  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
10368  * components remains the same and number of tuples is inceamented by one.<br>
10369  * This method is useful for allToAllV in MPI with contiguous policy. This method
10370  * differs from computeOffsets() in that the number of tuples is changed by this one.
10371  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
10372  *  \throw If \a this is not allocated.
10373  *  \throw If \a this->getNumberOfComponents() != 1.
10374  *
10375  *  \b Example: <br>
10376  *          - Before \a this contains [3,5,1,2,0,8]
10377  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
10378  * \sa DataArrayInt::deltaShiftIndex
10379  */
10380 void DataArrayInt::computeOffsetsFull()
10381 {
10382   checkAllocated();
10383   if(getNumberOfComponents()!=1)
10384     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
10385   int nbOfTuples=getNumberOfTuples();
10386   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
10387   const int *work=getConstPointer();
10388   ret[0]=0;
10389   for(int i=0;i<nbOfTuples;i++)
10390     ret[i+1]=work[i]+ret[i];
10391   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
10392   declareAsNew();
10393 }
10394
10395 /*!
10396  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
10397  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
10398  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
10399  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
10400  * filling completely one of the ranges in \a this.
10401  *
10402  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
10403  * \param [out] rangeIdsFetched the range ids fetched
10404  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
10405  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
10406  *
10407  * \sa DataArrayInt::computeOffsetsFull
10408  *
10409  *  \b Example: <br>
10410  *          - \a this : [0,3,7,9,15,18]
10411  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
10412  *          - \a rangeIdsFetched result array: [0,2,4]
10413  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
10414  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
10415  * <br>
10416  */
10417 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
10418 {
10419   if(!listOfIds)
10420     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
10421   listOfIds->checkAllocated(); checkAllocated();
10422   if(listOfIds->getNumberOfComponents()!=1)
10423     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
10424   if(getNumberOfComponents()!=1)
10425     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
10426   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
10427   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
10428   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
10429   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
10430   while(tupPtr!=tupEnd && offPtr!=offEnd)
10431     {
10432       if(*tupPtr==*offPtr)
10433         {
10434           int i=offPtr[0];
10435           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
10436           if(i==offPtr[1])
10437             {
10438               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
10439               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
10440               offPtr++;
10441             }
10442         }
10443       else
10444         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
10445     }
10446   rangeIdsFetched=ret0.retn();
10447   idsInInputListThatFetch=ret1.retn();
10448 }
10449
10450 /*!
10451  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
10452  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10453  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10454  * beginning within the "iota" array. And \a this is a one-dimensional array
10455  * considered as a selector of groups described by \a offsets to include into the result array.
10456  *  \throw If \a offsets is NULL.
10457  *  \throw If \a offsets is not allocated.
10458  *  \throw If \a offsets->getNumberOfComponents() != 1.
10459  *  \throw If \a offsets is not monotonically increasing.
10460  *  \throw If \a this is not allocated.
10461  *  \throw If \a this->getNumberOfComponents() != 1.
10462  *  \throw If any element of \a this is not a valid index for \a offsets array.
10463  *
10464  *  \b Example: <br>
10465  *          - \a this: [0,2,3]
10466  *          - \a offsets: [0,3,6,10,14,20]
10467  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
10468  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
10469  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
10470  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
10471  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
10472  */
10473 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
10474 {
10475   if(!offsets)
10476     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
10477   checkAllocated();
10478   if(getNumberOfComponents()!=1)
10479     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
10480   offsets->checkAllocated();
10481   if(offsets->getNumberOfComponents()!=1)
10482     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
10483   int othNbTuples=offsets->getNumberOfTuples()-1;
10484   int nbOfTuples=getNumberOfTuples();
10485   int retNbOftuples=0;
10486   const int *work=getConstPointer();
10487   const int *offPtr=offsets->getConstPointer();
10488   for(int i=0;i<nbOfTuples;i++)
10489     {
10490       int val=work[i];
10491       if(val>=0 && val<othNbTuples)
10492         {
10493           int delta=offPtr[val+1]-offPtr[val];
10494           if(delta>=0)
10495             retNbOftuples+=delta;
10496           else
10497             {
10498               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
10499               throw INTERP_KERNEL::Exception(oss.str().c_str());
10500             }
10501         }
10502       else
10503         {
10504           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
10505           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
10506           throw INTERP_KERNEL::Exception(oss.str().c_str());
10507         }
10508     }
10509   MCAuto<DataArrayInt> ret=DataArrayInt::New();
10510   ret->alloc(retNbOftuples,1);
10511   int *retPtr=ret->getPointer();
10512   for(int i=0;i<nbOfTuples;i++)
10513     {
10514       int val=work[i];
10515       int start=offPtr[val];
10516       int off=offPtr[val+1]-start;
10517       for(int j=0;j<off;j++,retPtr++)
10518         *retPtr=start+j;
10519     }
10520   return ret.retn();
10521 }
10522
10523 /*!
10524  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
10525  * scaled array (monotonically increasing).
10526 from that of \a this and \a
10527  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10528  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10529  * beginning within the "iota" array. And \a this is a one-dimensional array
10530  * considered as a selector of groups described by \a offsets to include into the result array.
10531  *  \throw If \a  is NULL.
10532  *  \throw If \a this is not allocated.
10533  *  \throw If \a this->getNumberOfComponents() != 1.
10534  *  \throw If \a this->getNumberOfTuples() == 0.
10535  *  \throw If \a this is not monotonically increasing.
10536  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
10537  *
10538  *  \b Example: <br>
10539  *          - \a bg , \a stop and \a step : (0,5,2)
10540  *          - \a this: [0,3,6,10,14,20]
10541  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
10542  */
10543 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
10544 {
10545   if(!isAllocated())
10546     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
10547   if(getNumberOfComponents()!=1)
10548     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
10549   int nbOfTuples(getNumberOfTuples());
10550   if(nbOfTuples==0)
10551     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
10552   const int *ids(begin());
10553   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
10554   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10555     {
10556       if(pos>=0 && pos<nbOfTuples-1)
10557         {
10558           int delta(ids[pos+1]-ids[pos]);
10559           sz+=delta;
10560           if(delta<0)
10561             {
10562               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
10563               throw INTERP_KERNEL::Exception(oss.str().c_str());
10564             }          
10565         }
10566       else
10567         {
10568           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
10569           throw INTERP_KERNEL::Exception(oss.str().c_str());
10570         }
10571     }
10572   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10573   int *retPtr(ret->getPointer());
10574   pos=bg;
10575   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10576     {
10577       int delta(ids[pos+1]-ids[pos]);
10578       for(int j=0;j<delta;j++,retPtr++)
10579         *retPtr=pos;
10580     }
10581   return ret.retn();
10582 }
10583
10584 /*!
10585  * 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.
10586  * 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
10587  * in tuple **i** of returned DataArrayInt.
10588  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
10589  *
10590  * 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)]
10591  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
10592  * 
10593  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10594  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10595  * \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
10596  *        is thrown if no ranges in \a ranges contains value in \a this.
10597  * 
10598  * \sa DataArrayInt::findIdInRangeForEachTuple
10599  */
10600 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
10601 {
10602   if(!ranges)
10603     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
10604   if(ranges->getNumberOfComponents()!=2)
10605     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
10606   checkAllocated();
10607   if(getNumberOfComponents()!=1)
10608     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
10609   int nbTuples=getNumberOfTuples();
10610   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10611   int nbOfRanges=ranges->getNumberOfTuples();
10612   const int *rangesPtr=ranges->getConstPointer();
10613   int *retPtr=ret->getPointer();
10614   const int *inPtr=getConstPointer();
10615   for(int i=0;i<nbTuples;i++,retPtr++)
10616     {
10617       int val=inPtr[i];
10618       bool found=false;
10619       for(int j=0;j<nbOfRanges && !found;j++)
10620         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10621           { *retPtr=j; found=true; }
10622       if(found)
10623         continue;
10624       else
10625         {
10626           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
10627           throw INTERP_KERNEL::Exception(oss.str().c_str());
10628         }
10629     }
10630   return ret.retn();
10631 }
10632
10633 /*!
10634  * 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.
10635  * 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
10636  * in tuple **i** of returned DataArrayInt.
10637  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
10638  *
10639  * 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)]
10640  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
10641  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
10642  * 
10643  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10644  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10645  * \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
10646  *        is thrown if no ranges in \a ranges contains value in \a this.
10647  * \sa DataArrayInt::findRangeIdForEachTuple
10648  */
10649 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
10650 {
10651   if(!ranges)
10652     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
10653   if(ranges->getNumberOfComponents()!=2)
10654     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
10655   checkAllocated();
10656   if(getNumberOfComponents()!=1)
10657     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
10658   int nbTuples=getNumberOfTuples();
10659   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10660   int nbOfRanges=ranges->getNumberOfTuples();
10661   const int *rangesPtr=ranges->getConstPointer();
10662   int *retPtr=ret->getPointer();
10663   const int *inPtr=getConstPointer();
10664   for(int i=0;i<nbTuples;i++,retPtr++)
10665     {
10666       int val=inPtr[i];
10667       bool found=false;
10668       for(int j=0;j<nbOfRanges && !found;j++)
10669         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10670           { *retPtr=val-rangesPtr[2*j]; found=true; }
10671       if(found)
10672         continue;
10673       else
10674         {
10675           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
10676           throw INTERP_KERNEL::Exception(oss.str().c_str());
10677         }
10678     }
10679   return ret.retn();
10680 }
10681
10682 /*!
10683  * \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).
10684  * 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).
10685  * 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 !
10686  * If this method has correctly worked, \a this will be able to be considered as a linked list.
10687  * This method does nothing if number of tuples is lower of equal to 1.
10688  *
10689  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
10690  *
10691  * \sa MEDCouplingUMesh::orderConsecutiveCells1D
10692  */
10693 void DataArrayInt::sortEachPairToMakeALinkedList()
10694 {
10695   checkAllocated();
10696   if(getNumberOfComponents()!=2)
10697     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
10698   int nbOfTuples(getNumberOfTuples());
10699   if(nbOfTuples<=1)
10700     return ;
10701   int *conn(getPointer());
10702   for(int i=1;i<nbOfTuples;i++,conn+=2)
10703     {
10704       if(i>1)
10705         {
10706           if(conn[2]==conn[3])
10707             {
10708               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
10709               throw INTERP_KERNEL::Exception(oss.str().c_str());
10710             }
10711           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
10712             std::swap(conn[2],conn[3]);
10713           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
10714           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
10715             {
10716               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
10717               throw INTERP_KERNEL::Exception(oss.str().c_str());
10718             }
10719         }
10720       else
10721         {
10722           if(conn[0]==conn[1] || conn[2]==conn[3])
10723             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
10724           int tmp[4];
10725           std::set<int> s;
10726           s.insert(conn,conn+4);
10727           if(s.size()!=3)
10728             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
10729           if(std::count(conn,conn+4,conn[0])==2)
10730             {
10731               tmp[0]=conn[1];
10732               tmp[1]=conn[0];
10733               tmp[2]=conn[0];
10734               if(conn[2]==conn[0])
10735                 { tmp[3]=conn[3]; }
10736               else
10737                 { tmp[3]=conn[2];}
10738               std::copy(tmp,tmp+4,conn);
10739             }
10740         }
10741     }
10742 }
10743
10744 /*!
10745  * 
10746  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
10747  *             \a nbTimes  should be at least equal to 1.
10748  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
10749  * \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.
10750  */
10751 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
10752 {
10753   checkAllocated();
10754   if(getNumberOfComponents()!=1)
10755     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
10756   if(nbTimes<1)
10757     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
10758   int nbTuples=getNumberOfTuples();
10759   const int *inPtr=getConstPointer();
10760   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
10761   int *retPtr=ret->getPointer();
10762   for(int i=0;i<nbTuples;i++,inPtr++)
10763     {
10764       int val=*inPtr;
10765       for(int j=0;j<nbTimes;j++,retPtr++)
10766         *retPtr=val;
10767     }
10768   ret->copyStringInfoFrom(*this);
10769   return ret.retn();
10770 }
10771
10772 /*!
10773  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
10774  * But the number of components can be different from one.
10775  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
10776  */
10777 DataArrayInt *DataArrayInt::getDifferentValues() const
10778 {
10779   checkAllocated();
10780   std::set<int> ret;
10781   ret.insert(begin(),end());
10782   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
10783   std::copy(ret.begin(),ret.end(),ret2->getPointer());
10784   return ret2.retn();
10785 }
10786
10787 /*!
10788  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
10789  * them it tells which tuple id have this id.
10790  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
10791  * This method returns two arrays having same size.
10792  * 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.
10793  * 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]]
10794  */
10795 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10796 {
10797   checkAllocated();
10798   if(getNumberOfComponents()!=1)
10799     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10800   int id=0;
10801   std::map<int,int> m,m2,m3;
10802   for(const int *w=begin();w!=end();w++)
10803     m[*w]++;
10804   differentIds.resize(m.size());
10805   std::vector<DataArrayInt *> ret(m.size());
10806   std::vector<int *> retPtr(m.size());
10807   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10808     {
10809       m2[(*it).first]=id;
10810       ret[id]=DataArrayInt::New();
10811       ret[id]->alloc((*it).second,1);
10812       retPtr[id]=ret[id]->getPointer();
10813       differentIds[id]=(*it).first;
10814     }
10815   id=0;
10816   for(const int *w=begin();w!=end();w++,id++)
10817     {
10818       retPtr[m2[*w]][m3[*w]++]=id;
10819     }
10820   return ret;
10821 }
10822
10823 /*!
10824  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10825  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10826  *
10827  * \param [in] nbOfSlices - number of slices expected.
10828  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10829  * 
10830  * \sa DataArray::GetSlice
10831  * \throw If \a this is not allocated or not with exactly one component.
10832  * \throw If an element in \a this if < 0.
10833  */
10834 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10835 {
10836   if(!isAllocated() || getNumberOfComponents()!=1)
10837     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10838   if(nbOfSlices<=0)
10839     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10840   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10841   int sumPerSlc(sum/nbOfSlices),pos(0);
10842   const int *w(begin());
10843   std::vector< std::pair<int,int> > ret(nbOfSlices);
10844   for(int i=0;i<nbOfSlices;i++)
10845     {
10846       std::pair<int,int> p(pos,-1);
10847       int locSum(0);
10848       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10849       if(i!=nbOfSlices-1)
10850         p.second=pos;
10851       else
10852         p.second=nbOfTuples;
10853       ret[i]=p;
10854     }
10855   return ret;
10856 }
10857
10858 /*!
10859  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10860  * valid cases.
10861  * 1.  The arrays have same number of tuples and components. Then each value of
10862  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10863  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10864  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10865  *   component. Then
10866  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10867  * 3.  The arrays have same number of components and one array, say _a2_, has one
10868  *   tuple. Then
10869  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10870  *
10871  * Info on components is copied either from the first array (in the first case) or from
10872  * the array with maximal number of elements (getNbOfElems()).
10873  *  \param [in] a1 - an array to sum up.
10874  *  \param [in] a2 - another array to sum up.
10875  *  \return DataArrayInt * - the new instance of DataArrayInt.
10876  *          The caller is to delete this result array using decrRef() as it is no more
10877  *          needed.
10878  *  \throw If either \a a1 or \a a2 is NULL.
10879  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10880  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10881  *         none of them has number of tuples or components equal to 1.
10882  */
10883 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10884 {
10885   if(!a1 || !a2)
10886     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10887   int nbOfTuple=a1->getNumberOfTuples();
10888   int nbOfTuple2=a2->getNumberOfTuples();
10889   int nbOfComp=a1->getNumberOfComponents();
10890   int nbOfComp2=a2->getNumberOfComponents();
10891   MCAuto<DataArrayInt> ret=0;
10892   if(nbOfTuple==nbOfTuple2)
10893     {
10894       if(nbOfComp==nbOfComp2)
10895         {
10896           ret=DataArrayInt::New();
10897           ret->alloc(nbOfTuple,nbOfComp);
10898           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10899           ret->copyStringInfoFrom(*a1);
10900         }
10901       else
10902         {
10903           int nbOfCompMin,nbOfCompMax;
10904           const DataArrayInt *aMin, *aMax;
10905           if(nbOfComp>nbOfComp2)
10906             {
10907               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10908               aMin=a2; aMax=a1;
10909             }
10910           else
10911             {
10912               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10913               aMin=a1; aMax=a2;
10914             }
10915           if(nbOfCompMin==1)
10916             {
10917               ret=DataArrayInt::New();
10918               ret->alloc(nbOfTuple,nbOfCompMax);
10919               const int *aMinPtr=aMin->getConstPointer();
10920               const int *aMaxPtr=aMax->getConstPointer();
10921               int *res=ret->getPointer();
10922               for(int i=0;i<nbOfTuple;i++)
10923                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10924               ret->copyStringInfoFrom(*aMax);
10925             }
10926           else
10927             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10928         }
10929     }
10930   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10931     {
10932       if(nbOfComp==nbOfComp2)
10933         {
10934           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10935           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10936           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10937           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10938           ret=DataArrayInt::New();
10939           ret->alloc(nbOfTupleMax,nbOfComp);
10940           int *res=ret->getPointer();
10941           for(int i=0;i<nbOfTupleMax;i++)
10942             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10943           ret->copyStringInfoFrom(*aMax);
10944         }
10945       else
10946         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10947     }
10948   else
10949     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10950   return ret.retn();
10951 }
10952
10953 /*!
10954  * Adds values of another DataArrayInt to values of \a this one. There are 3
10955  * valid cases.
10956  * 1.  The arrays have same number of tuples and components. Then each value of
10957  *   \a other array is added to the corresponding value of \a this array, i.e.:
10958  *   _a_ [ i, j ] += _other_ [ i, j ].
10959  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10960  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10961  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10962  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10963  *
10964  *  \param [in] other - an array to add to \a this one.
10965  *  \throw If \a other is NULL.
10966  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10967  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10968  *         \a other has number of both tuples and components not equal to 1.
10969  */
10970 void DataArrayInt::addEqual(const DataArrayInt *other)
10971 {
10972   if(!other)
10973     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10974   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10975   checkAllocated(); other->checkAllocated();
10976   int nbOfTuple=getNumberOfTuples();
10977   int nbOfTuple2=other->getNumberOfTuples();
10978   int nbOfComp=getNumberOfComponents();
10979   int nbOfComp2=other->getNumberOfComponents();
10980   if(nbOfTuple==nbOfTuple2)
10981     {
10982       if(nbOfComp==nbOfComp2)
10983         {
10984           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10985         }
10986       else if(nbOfComp2==1)
10987         {
10988           int *ptr=getPointer();
10989           const int *ptrc=other->getConstPointer();
10990           for(int i=0;i<nbOfTuple;i++)
10991             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10992         }
10993       else
10994         throw INTERP_KERNEL::Exception(msg);
10995     }
10996   else if(nbOfTuple2==1)
10997     {
10998       if(nbOfComp2==nbOfComp)
10999         {
11000           int *ptr=getPointer();
11001           const int *ptrc=other->getConstPointer();
11002           for(int i=0;i<nbOfTuple;i++)
11003             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
11004         }
11005       else
11006         throw INTERP_KERNEL::Exception(msg);
11007     }
11008   else
11009     throw INTERP_KERNEL::Exception(msg);
11010   declareAsNew();
11011 }
11012
11013 /*!
11014  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
11015  * valid cases.
11016  * 1.  The arrays have same number of tuples and components. Then each value of
11017  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
11018  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
11019  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11020  *   component. Then
11021  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
11022  * 3.  The arrays have same number of components and one array, say _a2_, has one
11023  *   tuple. Then
11024  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
11025  *
11026  * Info on components is copied either from the first array (in the first case) or from
11027  * the array with maximal number of elements (getNbOfElems()).
11028  *  \param [in] a1 - an array to subtract from.
11029  *  \param [in] a2 - an array to subtract.
11030  *  \return DataArrayInt * - the new instance of DataArrayInt.
11031  *          The caller is to delete this result array using decrRef() as it is no more
11032  *          needed.
11033  *  \throw If either \a a1 or \a a2 is NULL.
11034  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11035  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11036  *         none of them has number of tuples or components equal to 1.
11037  */
11038 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
11039 {
11040   if(!a1 || !a2)
11041     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
11042   int nbOfTuple1=a1->getNumberOfTuples();
11043   int nbOfTuple2=a2->getNumberOfTuples();
11044   int nbOfComp1=a1->getNumberOfComponents();
11045   int nbOfComp2=a2->getNumberOfComponents();
11046   if(nbOfTuple2==nbOfTuple1)
11047     {
11048       if(nbOfComp1==nbOfComp2)
11049         {
11050           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11051           ret->alloc(nbOfTuple2,nbOfComp1);
11052           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
11053           ret->copyStringInfoFrom(*a1);
11054           return ret.retn();
11055         }
11056       else if(nbOfComp2==1)
11057         {
11058           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11059           ret->alloc(nbOfTuple1,nbOfComp1);
11060           const int *a2Ptr=a2->getConstPointer();
11061           const int *a1Ptr=a1->getConstPointer();
11062           int *res=ret->getPointer();
11063           for(int i=0;i<nbOfTuple1;i++)
11064             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
11065           ret->copyStringInfoFrom(*a1);
11066           return ret.retn();
11067         }
11068       else
11069         {
11070           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
11071           return 0;
11072         }
11073     }
11074   else if(nbOfTuple2==1)
11075     {
11076       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
11077       MCAuto<DataArrayInt> ret=DataArrayInt::New();
11078       ret->alloc(nbOfTuple1,nbOfComp1);
11079       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11080       int *pt=ret->getPointer();
11081       for(int i=0;i<nbOfTuple1;i++)
11082         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
11083       ret->copyStringInfoFrom(*a1);
11084       return ret.retn();
11085     }
11086   else
11087     {
11088       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
11089       return 0;
11090     }
11091 }
11092
11093 /*!
11094  * Subtract values of another DataArrayInt from values of \a this one. There are 3
11095  * valid cases.
11096  * 1.  The arrays have same number of tuples and components. Then each value of
11097  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
11098  *   _a_ [ i, j ] -= _other_ [ i, j ].
11099  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11100  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
11101  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11102  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
11103  *
11104  *  \param [in] other - an array to subtract from \a this one.
11105  *  \throw If \a other is NULL.
11106  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11107  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11108  *         \a other has number of both tuples and components not equal to 1.
11109  */
11110 void DataArrayInt::substractEqual(const DataArrayInt *other)
11111 {
11112   if(!other)
11113     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
11114   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
11115   checkAllocated(); other->checkAllocated();
11116   int nbOfTuple=getNumberOfTuples();
11117   int nbOfTuple2=other->getNumberOfTuples();
11118   int nbOfComp=getNumberOfComponents();
11119   int nbOfComp2=other->getNumberOfComponents();
11120   if(nbOfTuple==nbOfTuple2)
11121     {
11122       if(nbOfComp==nbOfComp2)
11123         {
11124           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
11125         }
11126       else if(nbOfComp2==1)
11127         {
11128           int *ptr=getPointer();
11129           const int *ptrc=other->getConstPointer();
11130           for(int i=0;i<nbOfTuple;i++)
11131             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
11132         }
11133       else
11134         throw INTERP_KERNEL::Exception(msg);
11135     }
11136   else if(nbOfTuple2==1)
11137     {
11138       int *ptr=getPointer();
11139       const int *ptrc=other->getConstPointer();
11140       for(int i=0;i<nbOfTuple;i++)
11141         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
11142     }
11143   else
11144     throw INTERP_KERNEL::Exception(msg);
11145   declareAsNew();
11146 }
11147
11148 /*!
11149  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
11150  * valid cases.
11151  * 1.  The arrays have same number of tuples and components. Then each value of
11152  *   the result array (_a_) is a product of the corresponding values of \a a1 and
11153  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
11154  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11155  *   component. Then
11156  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
11157  * 3.  The arrays have same number of components and one array, say _a2_, has one
11158  *   tuple. Then
11159  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
11160  *
11161  * Info on components is copied either from the first array (in the first case) or from
11162  * the array with maximal number of elements (getNbOfElems()).
11163  *  \param [in] a1 - a factor array.
11164  *  \param [in] a2 - another factor array.
11165  *  \return DataArrayInt * - the new instance of DataArrayInt.
11166  *          The caller is to delete this result array using decrRef() as it is no more
11167  *          needed.
11168  *  \throw If either \a a1 or \a a2 is NULL.
11169  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11170  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11171  *         none of them has number of tuples or components equal to 1.
11172  */
11173 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
11174 {
11175   if(!a1 || !a2)
11176     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
11177   int nbOfTuple=a1->getNumberOfTuples();
11178   int nbOfTuple2=a2->getNumberOfTuples();
11179   int nbOfComp=a1->getNumberOfComponents();
11180   int nbOfComp2=a2->getNumberOfComponents();
11181   MCAuto<DataArrayInt> ret=0;
11182   if(nbOfTuple==nbOfTuple2)
11183     {
11184       if(nbOfComp==nbOfComp2)
11185         {
11186           ret=DataArrayInt::New();
11187           ret->alloc(nbOfTuple,nbOfComp);
11188           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
11189           ret->copyStringInfoFrom(*a1);
11190         }
11191       else
11192         {
11193           int nbOfCompMin,nbOfCompMax;
11194           const DataArrayInt *aMin, *aMax;
11195           if(nbOfComp>nbOfComp2)
11196             {
11197               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
11198               aMin=a2; aMax=a1;
11199             }
11200           else
11201             {
11202               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
11203               aMin=a1; aMax=a2;
11204             }
11205           if(nbOfCompMin==1)
11206             {
11207               ret=DataArrayInt::New();
11208               ret->alloc(nbOfTuple,nbOfCompMax);
11209               const int *aMinPtr=aMin->getConstPointer();
11210               const int *aMaxPtr=aMax->getConstPointer();
11211               int *res=ret->getPointer();
11212               for(int i=0;i<nbOfTuple;i++)
11213                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
11214               ret->copyStringInfoFrom(*aMax);
11215             }
11216           else
11217             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
11218         }
11219     }
11220   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
11221     {
11222       if(nbOfComp==nbOfComp2)
11223         {
11224           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
11225           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
11226           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
11227           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
11228           ret=DataArrayInt::New();
11229           ret->alloc(nbOfTupleMax,nbOfComp);
11230           int *res=ret->getPointer();
11231           for(int i=0;i<nbOfTupleMax;i++)
11232             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
11233           ret->copyStringInfoFrom(*aMax);
11234         }
11235       else
11236         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
11237     }
11238   else
11239     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
11240   return ret.retn();
11241 }
11242
11243
11244 /*!
11245  * Multiply values of another DataArrayInt to values of \a this one. There are 3
11246  * valid cases.
11247  * 1.  The arrays have same number of tuples and components. Then each value of
11248  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
11249  *   _a_ [ i, j ] *= _other_ [ i, j ].
11250  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11251  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
11252  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11253  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
11254  *
11255  *  \param [in] other - an array to multiply to \a this one.
11256  *  \throw If \a other is NULL.
11257  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11258  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11259  *         \a other has number of both tuples and components not equal to 1.
11260  */
11261 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
11262 {
11263   if(!other)
11264     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
11265   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
11266   checkAllocated(); other->checkAllocated();
11267   int nbOfTuple=getNumberOfTuples();
11268   int nbOfTuple2=other->getNumberOfTuples();
11269   int nbOfComp=getNumberOfComponents();
11270   int nbOfComp2=other->getNumberOfComponents();
11271   if(nbOfTuple==nbOfTuple2)
11272     {
11273       if(nbOfComp==nbOfComp2)
11274         {
11275           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
11276         }
11277       else if(nbOfComp2==1)
11278         {
11279           int *ptr=getPointer();
11280           const int *ptrc=other->getConstPointer();
11281           for(int i=0;i<nbOfTuple;i++)
11282             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
11283         }
11284       else
11285         throw INTERP_KERNEL::Exception(msg);
11286     }
11287   else if(nbOfTuple2==1)
11288     {
11289       if(nbOfComp2==nbOfComp)
11290         {
11291           int *ptr=getPointer();
11292           const int *ptrc=other->getConstPointer();
11293           for(int i=0;i<nbOfTuple;i++)
11294             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
11295         }
11296       else
11297         throw INTERP_KERNEL::Exception(msg);
11298     }
11299   else
11300     throw INTERP_KERNEL::Exception(msg);
11301   declareAsNew();
11302 }
11303
11304
11305 /*!
11306  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
11307  * valid cases.
11308  * 1.  The arrays have same number of tuples and components. Then each value of
11309  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11310  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
11311  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11312  *   component. Then
11313  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
11314  * 3.  The arrays have same number of components and one array, say _a2_, has one
11315  *   tuple. Then
11316  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
11317  *
11318  * Info on components is copied either from the first array (in the first case) or from
11319  * the array with maximal number of elements (getNbOfElems()).
11320  *  \warning No check of division by zero is performed!
11321  *  \param [in] a1 - a numerator array.
11322  *  \param [in] a2 - a denominator array.
11323  *  \return DataArrayInt * - the new instance of DataArrayInt.
11324  *          The caller is to delete this result array using decrRef() as it is no more
11325  *          needed.
11326  *  \throw If either \a a1 or \a a2 is NULL.
11327  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11328  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11329  *         none of them has number of tuples or components equal to 1.
11330  */
11331 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
11332 {
11333   if(!a1 || !a2)
11334     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
11335   int nbOfTuple1=a1->getNumberOfTuples();
11336   int nbOfTuple2=a2->getNumberOfTuples();
11337   int nbOfComp1=a1->getNumberOfComponents();
11338   int nbOfComp2=a2->getNumberOfComponents();
11339   if(nbOfTuple2==nbOfTuple1)
11340     {
11341       if(nbOfComp1==nbOfComp2)
11342         {
11343           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11344           ret->alloc(nbOfTuple2,nbOfComp1);
11345           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
11346           ret->copyStringInfoFrom(*a1);
11347           return ret.retn();
11348         }
11349       else if(nbOfComp2==1)
11350         {
11351           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11352           ret->alloc(nbOfTuple1,nbOfComp1);
11353           const int *a2Ptr=a2->getConstPointer();
11354           const int *a1Ptr=a1->getConstPointer();
11355           int *res=ret->getPointer();
11356           for(int i=0;i<nbOfTuple1;i++)
11357             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
11358           ret->copyStringInfoFrom(*a1);
11359           return ret.retn();
11360         }
11361       else
11362         {
11363           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11364           return 0;
11365         }
11366     }
11367   else if(nbOfTuple2==1)
11368     {
11369       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11370       MCAuto<DataArrayInt> ret=DataArrayInt::New();
11371       ret->alloc(nbOfTuple1,nbOfComp1);
11372       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11373       int *pt=ret->getPointer();
11374       for(int i=0;i<nbOfTuple1;i++)
11375         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
11376       ret->copyStringInfoFrom(*a1);
11377       return ret.retn();
11378     }
11379   else
11380     {
11381       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
11382       return 0;
11383     }
11384 }
11385
11386 /*!
11387  * Divide values of \a this array by values of another DataArrayInt. There are 3
11388  * valid cases.
11389  * 1.  The arrays have same number of tuples and components. Then each value of
11390  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11391  *   _a_ [ i, j ] /= _other_ [ i, j ].
11392  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11393  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
11394  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11395  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
11396  *
11397  *  \warning No check of division by zero is performed!
11398  *  \param [in] other - an array to divide \a this one by.
11399  *  \throw If \a other is NULL.
11400  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11401  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11402  *         \a other has number of both tuples and components not equal to 1.
11403  */
11404 void DataArrayInt::divideEqual(const DataArrayInt *other)
11405 {
11406   if(!other)
11407     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
11408   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
11409   checkAllocated(); other->checkAllocated();
11410   int nbOfTuple=getNumberOfTuples();
11411   int nbOfTuple2=other->getNumberOfTuples();
11412   int nbOfComp=getNumberOfComponents();
11413   int nbOfComp2=other->getNumberOfComponents();
11414   if(nbOfTuple==nbOfTuple2)
11415     {
11416       if(nbOfComp==nbOfComp2)
11417         {
11418           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
11419         }
11420       else if(nbOfComp2==1)
11421         {
11422           int *ptr=getPointer();
11423           const int *ptrc=other->getConstPointer();
11424           for(int i=0;i<nbOfTuple;i++)
11425             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
11426         }
11427       else
11428         throw INTERP_KERNEL::Exception(msg);
11429     }
11430   else if(nbOfTuple2==1)
11431     {
11432       if(nbOfComp2==nbOfComp)
11433         {
11434           int *ptr=getPointer();
11435           const int *ptrc=other->getConstPointer();
11436           for(int i=0;i<nbOfTuple;i++)
11437             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
11438         }
11439       else
11440         throw INTERP_KERNEL::Exception(msg);
11441     }
11442   else
11443     throw INTERP_KERNEL::Exception(msg);
11444   declareAsNew();
11445 }
11446
11447
11448 /*!
11449  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
11450  * valid cases.
11451  * 1.  The arrays have same number of tuples and components. Then each value of
11452  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11453  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
11454  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11455  *   component. Then
11456  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
11457  * 3.  The arrays have same number of components and one array, say _a2_, has one
11458  *   tuple. Then
11459  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
11460  *
11461  * Info on components is copied either from the first array (in the first case) or from
11462  * the array with maximal number of elements (getNbOfElems()).
11463  *  \warning No check of division by zero is performed!
11464  *  \param [in] a1 - a dividend array.
11465  *  \param [in] a2 - a divisor array.
11466  *  \return DataArrayInt * - the new instance of DataArrayInt.
11467  *          The caller is to delete this result array using decrRef() as it is no more
11468  *          needed.
11469  *  \throw If either \a a1 or \a a2 is NULL.
11470  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11471  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11472  *         none of them has number of tuples or components equal to 1.
11473  */
11474 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
11475 {
11476   if(!a1 || !a2)
11477     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
11478   int nbOfTuple1=a1->getNumberOfTuples();
11479   int nbOfTuple2=a2->getNumberOfTuples();
11480   int nbOfComp1=a1->getNumberOfComponents();
11481   int nbOfComp2=a2->getNumberOfComponents();
11482   if(nbOfTuple2==nbOfTuple1)
11483     {
11484       if(nbOfComp1==nbOfComp2)
11485         {
11486           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11487           ret->alloc(nbOfTuple2,nbOfComp1);
11488           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
11489           ret->copyStringInfoFrom(*a1);
11490           return ret.retn();
11491         }
11492       else if(nbOfComp2==1)
11493         {
11494           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11495           ret->alloc(nbOfTuple1,nbOfComp1);
11496           const int *a2Ptr=a2->getConstPointer();
11497           const int *a1Ptr=a1->getConstPointer();
11498           int *res=ret->getPointer();
11499           for(int i=0;i<nbOfTuple1;i++)
11500             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
11501           ret->copyStringInfoFrom(*a1);
11502           return ret.retn();
11503         }
11504       else
11505         {
11506           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11507           return 0;
11508         }
11509     }
11510   else if(nbOfTuple2==1)
11511     {
11512       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11513       MCAuto<DataArrayInt> ret=DataArrayInt::New();
11514       ret->alloc(nbOfTuple1,nbOfComp1);
11515       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11516       int *pt=ret->getPointer();
11517       for(int i=0;i<nbOfTuple1;i++)
11518         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
11519       ret->copyStringInfoFrom(*a1);
11520       return ret.retn();
11521     }
11522   else
11523     {
11524       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
11525       return 0;
11526     }
11527 }
11528
11529 /*!
11530  * Modify \a this array so that each value becomes a modulus of division of this value by
11531  * a value of another DataArrayInt. There are 3 valid cases.
11532  * 1.  The arrays have same number of tuples and components. Then each value of
11533  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11534  *   _a_ [ i, j ] %= _other_ [ i, j ].
11535  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11536  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
11537  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11538  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
11539  *
11540  *  \warning No check of division by zero is performed!
11541  *  \param [in] other - a divisor array.
11542  *  \throw If \a other is NULL.
11543  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11544  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11545  *         \a other has number of both tuples and components not equal to 1.
11546  */
11547 void DataArrayInt::modulusEqual(const DataArrayInt *other)
11548 {
11549   if(!other)
11550     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
11551   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
11552   checkAllocated(); other->checkAllocated();
11553   int nbOfTuple=getNumberOfTuples();
11554   int nbOfTuple2=other->getNumberOfTuples();
11555   int nbOfComp=getNumberOfComponents();
11556   int nbOfComp2=other->getNumberOfComponents();
11557   if(nbOfTuple==nbOfTuple2)
11558     {
11559       if(nbOfComp==nbOfComp2)
11560         {
11561           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
11562         }
11563       else if(nbOfComp2==1)
11564         {
11565           if(nbOfComp2==nbOfComp)
11566             {
11567               int *ptr=getPointer();
11568               const int *ptrc=other->getConstPointer();
11569               for(int i=0;i<nbOfTuple;i++)
11570                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
11571             }
11572           else
11573             throw INTERP_KERNEL::Exception(msg);
11574         }
11575       else
11576         throw INTERP_KERNEL::Exception(msg);
11577     }
11578   else if(nbOfTuple2==1)
11579     {
11580       int *ptr=getPointer();
11581       const int *ptrc=other->getConstPointer();
11582       for(int i=0;i<nbOfTuple;i++)
11583         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
11584     }
11585   else
11586     throw INTERP_KERNEL::Exception(msg);
11587   declareAsNew();
11588 }
11589
11590 /*!
11591  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
11592  * valid cases.
11593  *
11594  *  \param [in] a1 - an array to pow up.
11595  *  \param [in] a2 - another array to sum up.
11596  *  \return DataArrayInt * - the new instance of DataArrayInt.
11597  *          The caller is to delete this result array using decrRef() as it is no more
11598  *          needed.
11599  *  \throw If either \a a1 or \a a2 is NULL.
11600  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
11601  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
11602  *  \throw If there is a negative value in \a a2.
11603  */
11604 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
11605 {
11606   if(!a1 || !a2)
11607     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
11608   int nbOfTuple=a1->getNumberOfTuples();
11609   int nbOfTuple2=a2->getNumberOfTuples();
11610   int nbOfComp=a1->getNumberOfComponents();
11611   int nbOfComp2=a2->getNumberOfComponents();
11612   if(nbOfTuple!=nbOfTuple2)
11613     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
11614   if(nbOfComp!=1 || nbOfComp2!=1)
11615     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
11616   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
11617   const int *ptr1(a1->begin()),*ptr2(a2->begin());
11618   int *ptr=ret->getPointer();
11619   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
11620     {
11621       if(*ptr2>=0)
11622         {
11623           int tmp=1;
11624           for(int j=0;j<*ptr2;j++)
11625             tmp*=*ptr1;
11626           *ptr=tmp;
11627         }
11628       else
11629         {
11630           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
11631           throw INTERP_KERNEL::Exception(oss.str().c_str());
11632         }
11633     }
11634   return ret.retn();
11635 }
11636
11637 /*!
11638  * Apply pow on values of another DataArrayInt to values of \a this one.
11639  *
11640  *  \param [in] other - an array to pow to \a this one.
11641  *  \throw If \a other is NULL.
11642  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
11643  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
11644  *  \throw If there is a negative value in \a other.
11645  */
11646 void DataArrayInt::powEqual(const DataArrayInt *other)
11647 {
11648   if(!other)
11649     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
11650   int nbOfTuple=getNumberOfTuples();
11651   int nbOfTuple2=other->getNumberOfTuples();
11652   int nbOfComp=getNumberOfComponents();
11653   int nbOfComp2=other->getNumberOfComponents();
11654   if(nbOfTuple!=nbOfTuple2)
11655     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
11656   if(nbOfComp!=1 || nbOfComp2!=1)
11657     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
11658   int *ptr=getPointer();
11659   const int *ptrc=other->begin();
11660   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
11661     {
11662       if(*ptrc>=0)
11663         {
11664           int tmp=1;
11665           for(int j=0;j<*ptrc;j++)
11666             tmp*=*ptr;
11667           *ptr=tmp;
11668         }
11669       else
11670         {
11671           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
11672           throw INTERP_KERNEL::Exception(oss.str().c_str());
11673         }
11674     }
11675   declareAsNew();
11676 }
11677
11678 /*!
11679  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
11680  * This map, if applied to \a start array, would make it sorted. For example, if
11681  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
11682  * [5,6,0,3,2,7,1,4].
11683  *  \param [in] start - pointer to the first element of the array for which the
11684  *         permutation map is computed.
11685  *  \param [in] end - pointer specifying the end of the array \a start, so that
11686  *         the last value of \a start is \a end[ -1 ].
11687  *  \return int * - the result permutation array that the caller is to delete as it is no
11688  *         more needed.
11689  *  \throw If there are equal values in the input array.
11690  */
11691 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
11692 {
11693   std::size_t sz=std::distance(start,end);
11694   int *ret=(int *)malloc(sz*sizeof(int));
11695   int *work=new int[sz];
11696   std::copy(start,end,work);
11697   std::sort(work,work+sz);
11698   if(std::unique(work,work+sz)!=work+sz)
11699     {
11700       delete [] work;
11701       free(ret);
11702       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
11703     }
11704   std::map<int,int> m;
11705   for(int *workPt=work;workPt!=work+sz;workPt++)
11706     m[*workPt]=(int)std::distance(work,workPt);
11707   int *iter2=ret;
11708   for(const int *iter=start;iter!=end;iter++,iter2++)
11709     *iter2=m[*iter];
11710   delete [] work;
11711   return ret;
11712 }
11713
11714 /*!
11715  * Returns a new DataArrayInt containing an arithmetic progression
11716  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
11717  * function.
11718  *  \param [in] begin - the start value of the result sequence.
11719  *  \param [in] end - limiting value, so that every value of the result array is less than
11720  *              \a end.
11721  *  \param [in] step - specifies the increment or decrement.
11722  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
11723  *          array using decrRef() as it is no more needed.
11724  *  \throw If \a step == 0.
11725  *  \throw If \a end < \a begin && \a step > 0.
11726  *  \throw If \a end > \a begin && \a step < 0.
11727  */
11728 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
11729 {
11730   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
11731   MCAuto<DataArrayInt> ret=DataArrayInt::New();
11732   ret->alloc(nbOfTuples,1);
11733   int *ptr=ret->getPointer();
11734   if(step>0)
11735     {
11736       for(int i=begin;i<end;i+=step,ptr++)
11737         *ptr=i;
11738     }
11739   else
11740     {
11741       for(int i=begin;i>end;i+=step,ptr++)
11742         *ptr=i;
11743     }
11744   return ret.retn();
11745 }
11746
11747 /*!
11748  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11749  * Server side.
11750  */
11751 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
11752 {
11753   tinyInfo.resize(2);
11754   if(isAllocated())
11755     {
11756       tinyInfo[0]=getNumberOfTuples();
11757       tinyInfo[1]=getNumberOfComponents();
11758     }
11759   else
11760     {
11761       tinyInfo[0]=-1;
11762       tinyInfo[1]=-1;
11763     }
11764 }
11765
11766 /*!
11767  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11768  * Server side.
11769  */
11770 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
11771 {
11772   if(isAllocated())
11773     {
11774       int nbOfCompo=getNumberOfComponents();
11775       tinyInfo.resize(nbOfCompo+1);
11776       tinyInfo[0]=getName();
11777       for(int i=0;i<nbOfCompo;i++)
11778         tinyInfo[i+1]=getInfoOnComponent(i);
11779     }
11780   else
11781     {
11782       tinyInfo.resize(1);
11783       tinyInfo[0]=getName();
11784     }
11785 }
11786
11787 /*!
11788  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11789  * This method returns if a feeding is needed.
11790  */
11791 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11792 {
11793   int nbOfTuple=tinyInfoI[0];
11794   int nbOfComp=tinyInfoI[1];
11795   if(nbOfTuple!=-1 || nbOfComp!=-1)
11796     {
11797       alloc(nbOfTuple,nbOfComp);
11798       return true;
11799     }
11800   return false;
11801 }
11802
11803 /*!
11804  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11805  * This method returns if a feeding is needed.
11806  */
11807 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11808 {
11809   setName(tinyInfoS[0]);
11810   if(isAllocated())
11811     {
11812       int nbOfCompo=tinyInfoI[1];
11813       for(int i=0;i<nbOfCompo;i++)
11814         setInfoOnComponent(i,tinyInfoS[i+1]);
11815     }
11816 }
11817
11818 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11819 {
11820   if(_da)
11821     {
11822       _da->incrRef();
11823       if(_da->isAllocated())
11824         {
11825           _nb_comp=da->getNumberOfComponents();
11826           _nb_tuple=da->getNumberOfTuples();
11827           _pt=da->getPointer();
11828         }
11829     }
11830 }
11831
11832 DataArrayIntIterator::~DataArrayIntIterator()
11833 {
11834   if(_da)
11835     _da->decrRef();
11836 }
11837
11838 DataArrayIntTuple *DataArrayIntIterator::nextt()
11839 {
11840   if(_tuple_id<_nb_tuple)
11841     {
11842       _tuple_id++;
11843       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11844       _pt+=_nb_comp;
11845       return ret;
11846     }
11847   else
11848     return 0;
11849 }
11850
11851 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11852 {
11853 }
11854
11855 std::string DataArrayIntTuple::repr() const
11856 {
11857   std::ostringstream oss; oss << "(";
11858   for(int i=0;i<_nb_of_compo-1;i++)
11859     oss << _pt[i] << ", ";
11860   oss << _pt[_nb_of_compo-1] << ")";
11861   return oss.str();
11862 }
11863
11864 int DataArrayIntTuple::intValue() const
11865 {
11866   if(_nb_of_compo==1)
11867     return *_pt;
11868   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11869 }
11870
11871 /*!
11872  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
11873  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
11874  * 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
11875  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11876  */
11877 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11878 {
11879   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11880     {
11881       DataArrayInt *ret=DataArrayInt::New();
11882       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11883       return ret;
11884     }
11885   else
11886     {
11887       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11888       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11889       throw INTERP_KERNEL::Exception(oss.str().c_str());
11890     }
11891 }