Salome HOME
9a41ce72992c9fd71392027553664b00a958fb75
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingMemArray.txx"
22 #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 void DataArrayDouble::aggregate(const DataArrayDouble *other)
3065 {
3066   if(!other)
3067     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !");
3068   if(getNumberOfComponents()!=other->getNumberOfComponents())
3069     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !");
3070   _mem.insertAtTheEnd(other->begin(),other->end());
3071 }
3072
3073 /*!
3074  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
3075  * is thrown.
3076  * \throw If zero is found in \a this array.
3077  */
3078 void DataArrayDouble::checkNoNullValues() const
3079 {
3080   const double *tmp=getConstPointer();
3081   std::size_t nbOfElems=getNbOfElems();
3082   const double *where=std::find(tmp,tmp+nbOfElems,0.);
3083   if(where!=tmp+nbOfElems)
3084     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
3085 }
3086
3087 /*!
3088  * Computes minimal and maximal value in each component. An output array is filled
3089  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
3090  * enough memory before calling this method.
3091  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
3092  *               It is filled as follows:<br>
3093  *               \a bounds[0] = \c min_of_component_0 <br>
3094  *               \a bounds[1] = \c max_of_component_0 <br>
3095  *               \a bounds[2] = \c min_of_component_1 <br>
3096  *               \a bounds[3] = \c max_of_component_1 <br>
3097  *               ...
3098  */
3099 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
3100 {
3101   checkAllocated();
3102   int dim=getNumberOfComponents();
3103   for (int idim=0; idim<dim; idim++)
3104     {
3105       bounds[idim*2]=std::numeric_limits<double>::max();
3106       bounds[idim*2+1]=-std::numeric_limits<double>::max();
3107     } 
3108   const double *ptr=getConstPointer();
3109   int nbOfTuples=getNumberOfTuples();
3110   for(int i=0;i<nbOfTuples;i++)
3111     {
3112       for(int idim=0;idim<dim;idim++)
3113         {
3114           if(bounds[idim*2]>ptr[i*dim+idim])
3115             {
3116               bounds[idim*2]=ptr[i*dim+idim];
3117             }
3118           if(bounds[idim*2+1]<ptr[i*dim+idim])
3119             {
3120               bounds[idim*2+1]=ptr[i*dim+idim];
3121             }
3122         }
3123     }
3124 }
3125
3126 /*!
3127  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3128  * to store both the min and max per component of each tuples. 
3129  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3130  *
3131  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3132  *
3133  * \throw If \a this is not allocated yet.
3134  */
3135 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
3136 {
3137   checkAllocated();
3138   const double *dataPtr=getConstPointer();
3139   int nbOfCompo=getNumberOfComponents();
3140   int nbTuples=getNumberOfTuples();
3141   MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
3142   bbox->alloc(nbTuples,2*nbOfCompo);
3143   double *bboxPtr=bbox->getPointer();
3144   for(int i=0;i<nbTuples;i++)
3145     {
3146       for(int j=0;j<nbOfCompo;j++)
3147         {
3148           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3149           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3150         }
3151     }
3152   return bbox.retn();
3153 }
3154
3155 /*!
3156  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3157  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3158  * 
3159  * \param [in] other a DataArrayDouble having same number of components than \a this.
3160  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3161  * \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.
3162  *             \a cI allows to extract information in \a c.
3163  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3164  *
3165  * \throw In case of:
3166  *  - \a this is not allocated
3167  *  - \a other is not allocated or null
3168  *  - \a this and \a other do not have the same number of components
3169  *  - if number of components of \a this is not in [1,2,3]
3170  *
3171  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3172  */
3173 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
3174 {
3175   if(!other)
3176     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3177   checkAllocated();
3178   other->checkAllocated();
3179   int nbOfCompo=getNumberOfComponents();
3180   int otherNbOfCompo=other->getNumberOfComponents();
3181   if(nbOfCompo!=otherNbOfCompo)
3182     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3183   int nbOfTuplesOther=other->getNumberOfTuples();
3184   MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3185   switch(nbOfCompo)
3186   {
3187     case 3:
3188       {
3189         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3190         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3191         break;
3192       }
3193     case 2:
3194       {
3195         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3196         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3197         break;
3198       }
3199     case 1:
3200       {
3201         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3202         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3203         break;
3204       }
3205     default:
3206       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3207   }
3208   c=cArr.retn(); cI=cIArr.retn();
3209 }
3210
3211 /*!
3212  * 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
3213  * around origin of 'radius' 1.
3214  * 
3215  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3216  */
3217 void DataArrayDouble::recenterForMaxPrecision(double eps)
3218 {
3219   checkAllocated();
3220   int dim=getNumberOfComponents();
3221   std::vector<double> bounds(2*dim);
3222   getMinMaxPerComponent(&bounds[0]);
3223   for(int i=0;i<dim;i++)
3224     {
3225       double delta=bounds[2*i+1]-bounds[2*i];
3226       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3227       if(delta>eps)
3228         applyLin(1./delta,-offset/delta,i);
3229       else
3230         applyLin(1.,-offset,i);
3231     }
3232 }
3233
3234 /*!
3235  * Returns the maximal value and its location within \a this one-dimensional array.
3236  *  \param [out] tupleId - index of the tuple holding the maximal value.
3237  *  \return double - the maximal value among all values of \a this array.
3238  *  \throw If \a this->getNumberOfComponents() != 1
3239  *  \throw If \a this->getNumberOfTuples() < 1
3240  */
3241 double DataArrayDouble::getMaxValue(int& tupleId) const
3242 {
3243   checkAllocated();
3244   if(getNumberOfComponents()!=1)
3245     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 !");
3246   int nbOfTuples=getNumberOfTuples();
3247   if(nbOfTuples<=0)
3248     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3249   const double *vals=getConstPointer();
3250   const double *loc=std::max_element(vals,vals+nbOfTuples);
3251   tupleId=(int)std::distance(vals,loc);
3252   return *loc;
3253 }
3254
3255 /*!
3256  * Returns the maximal value within \a this array that is allowed to have more than
3257  *  one component.
3258  *  \return double - the maximal value among all values of \a this array.
3259  *  \throw If \a this is not allocated.
3260  */
3261 double DataArrayDouble::getMaxValueInArray() const
3262 {
3263   checkAllocated();
3264   const double *loc=std::max_element(begin(),end());
3265   return *loc;
3266 }
3267
3268 /*!
3269  * Returns the maximal value and all its locations within \a this one-dimensional array.
3270  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3271  *               tuples holding the maximal value. The caller is to delete it using
3272  *               decrRef() as it is no more needed.
3273  *  \return double - the maximal value among all values of \a this array.
3274  *  \throw If \a this->getNumberOfComponents() != 1
3275  *  \throw If \a this->getNumberOfTuples() < 1
3276  */
3277 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
3278 {
3279   int tmp;
3280   tupleIds=0;
3281   double ret=getMaxValue(tmp);
3282   tupleIds=findIdsInRange(ret,ret);
3283   return ret;
3284 }
3285
3286 /*!
3287  * Returns the minimal value and its location within \a this one-dimensional array.
3288  *  \param [out] tupleId - index of the tuple holding the minimal value.
3289  *  \return double - the minimal value among all values of \a this array.
3290  *  \throw If \a this->getNumberOfComponents() != 1
3291  *  \throw If \a this->getNumberOfTuples() < 1
3292  */
3293 double DataArrayDouble::getMinValue(int& tupleId) const
3294 {
3295   checkAllocated();
3296   if(getNumberOfComponents()!=1)
3297     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3298   int nbOfTuples=getNumberOfTuples();
3299   if(nbOfTuples<=0)
3300     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3301   const double *vals=getConstPointer();
3302   const double *loc=std::min_element(vals,vals+nbOfTuples);
3303   tupleId=(int)std::distance(vals,loc);
3304   return *loc;
3305 }
3306
3307 /*!
3308  * Returns the minimal value within \a this array that is allowed to have more than
3309  *  one component.
3310  *  \return double - the minimal value among all values of \a this array.
3311  *  \throw If \a this is not allocated.
3312  */
3313 double DataArrayDouble::getMinValueInArray() const
3314 {
3315   checkAllocated();
3316   const double *loc=std::min_element(begin(),end());
3317   return *loc;
3318 }
3319
3320 /*!
3321  * Returns the minimal value and all its locations within \a this one-dimensional array.
3322  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3323  *               tuples holding the minimal value. The caller is to delete it using
3324  *               decrRef() as it is no more needed.
3325  *  \return double - the minimal value among all values of \a this array.
3326  *  \throw If \a this->getNumberOfComponents() != 1
3327  *  \throw If \a this->getNumberOfTuples() < 1
3328  */
3329 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
3330 {
3331   int tmp;
3332   tupleIds=0;
3333   double ret=getMinValue(tmp);
3334   tupleIds=findIdsInRange(ret,ret);
3335   return ret;
3336 }
3337
3338 /*!
3339  * 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.
3340  * This method only works for single component array.
3341  *
3342  * \return a value in [ 0, \c this->getNumberOfTuples() )
3343  *
3344  * \throw If \a this is not allocated
3345  *
3346  */
3347 int DataArrayDouble::count(double value, double eps) const
3348 {
3349   int ret=0;
3350   checkAllocated();
3351   if(getNumberOfComponents()!=1)
3352     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3353   const double *vals=begin();
3354   int nbOfTuples=getNumberOfTuples();
3355   for(int i=0;i<nbOfTuples;i++,vals++)
3356     if(fabs(*vals-value)<=eps)
3357       ret++;
3358   return ret;
3359 }
3360
3361 /*!
3362  * Returns the average value of \a this one-dimensional array.
3363  *  \return double - the average value over all values of \a this array.
3364  *  \throw If \a this->getNumberOfComponents() != 1
3365  *  \throw If \a this->getNumberOfTuples() < 1
3366  */
3367 double DataArrayDouble::getAverageValue() const
3368 {
3369   if(getNumberOfComponents()!=1)
3370     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3371   int nbOfTuples=getNumberOfTuples();
3372   if(nbOfTuples<=0)
3373     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3374   const double *vals=getConstPointer();
3375   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3376   return ret/nbOfTuples;
3377 }
3378
3379 /*!
3380  * Returns the Euclidean norm of the vector defined by \a this array.
3381  *  \return double - the value of the Euclidean norm, i.e.
3382  *          the square root of the inner product of vector.
3383  *  \throw If \a this is not allocated.
3384  */
3385 double DataArrayDouble::norm2() const
3386 {
3387   checkAllocated();
3388   double ret=0.;
3389   std::size_t nbOfElems=getNbOfElems();
3390   const double *pt=getConstPointer();
3391   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3392     ret+=(*pt)*(*pt);
3393   return sqrt(ret);
3394 }
3395
3396 /*!
3397  * Returns the maximum norm of the vector defined by \a this array.
3398  * This method works even if the number of components is diferent from one.
3399  * If the number of elements in \a this is 0, -1. is returned.
3400  *  \return double - the value of the maximum norm, i.e.
3401  *          the maximal absolute value among values of \a this array (whatever its number of components).
3402  *  \throw If \a this is not allocated.
3403  */
3404 double DataArrayDouble::normMax() const
3405 {
3406   checkAllocated();
3407   double ret(-1.);
3408   std::size_t nbOfElems(getNbOfElems());
3409   const double *pt(getConstPointer());
3410   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3411     {
3412       double val(std::abs(*pt));
3413       if(val>ret)
3414         ret=val;
3415     }
3416   return ret;
3417 }
3418
3419 /*!
3420  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
3421  * This method works even if the number of components is diferent from one.
3422  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
3423  *  \return double - the value of the minimum norm, i.e.
3424  *          the minimal absolute value among values of \a this array (whatever its number of components).
3425  *  \throw If \a this is not allocated.
3426  */
3427 double DataArrayDouble::normMin() const
3428 {
3429   checkAllocated();
3430   double ret(std::numeric_limits<double>::max());
3431   std::size_t nbOfElems(getNbOfElems());
3432   const double *pt(getConstPointer());
3433   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3434     {
3435       double val(std::abs(*pt));
3436       if(val<ret)
3437         ret=val;
3438     }
3439   return ret;
3440 }
3441
3442 /*!
3443  * Accumulates values of each component of \a this array.
3444  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3445  *         by the caller, that is filled by this method with sum value for each
3446  *         component.
3447  *  \throw If \a this is not allocated.
3448  */
3449 void DataArrayDouble::accumulate(double *res) const
3450 {
3451   checkAllocated();
3452   const double *ptr=getConstPointer();
3453   int nbTuple=getNumberOfTuples();
3454   int nbComps=getNumberOfComponents();
3455   std::fill(res,res+nbComps,0.);
3456   for(int i=0;i<nbTuple;i++)
3457     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3458 }
3459
3460 /*!
3461  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3462  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3463  *
3464  *
3465  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3466  * \a tupleEnd. If not an exception will be thrown.
3467  *
3468  * \param [in] tupleBg start pointer (included) of input external tuple
3469  * \param [in] tupleEnd end pointer (not included) of input external tuple
3470  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3471  * \return the min distance.
3472  * \sa MEDCouplingUMesh::distanceToPoint
3473  */
3474 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
3475 {
3476   checkAllocated();
3477   int nbTuple=getNumberOfTuples();
3478   int nbComps=getNumberOfComponents();
3479   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3480     { 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()); }
3481   if(nbTuple==0)
3482     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3483   double ret0=std::numeric_limits<double>::max();
3484   tupleId=-1;
3485   const double *work=getConstPointer();
3486   for(int i=0;i<nbTuple;i++)
3487     {
3488       double val=0.;
3489       for(int j=0;j<nbComps;j++,work++) 
3490         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3491       if(val>=ret0)
3492         continue;
3493       else
3494         { ret0=val; tupleId=i; }
3495     }
3496   return sqrt(ret0);
3497 }
3498
3499 /*!
3500  * Accumulate values of the given component of \a this array.
3501  *  \param [in] compId - the index of the component of interest.
3502  *  \return double - a sum value of \a compId-th component.
3503  *  \throw If \a this is not allocated.
3504  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3505  *         not respected.
3506  */
3507 double DataArrayDouble::accumulate(int compId) const
3508 {
3509   checkAllocated();
3510   const double *ptr=getConstPointer();
3511   int nbTuple=getNumberOfTuples();
3512   int nbComps=getNumberOfComponents();
3513   if(compId<0 || compId>=nbComps)
3514     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3515   double ret=0.;
3516   for(int i=0;i<nbTuple;i++)
3517     ret+=ptr[i*nbComps+compId];
3518   return ret;
3519 }
3520
3521 /*!
3522  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3523  * The returned array will have same number of components than \a this and number of tuples equal to
3524  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3525  *
3526  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3527  * 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.
3528  *
3529  * \param [in] bgOfIndex - begin (included) of the input index array.
3530  * \param [in] endOfIndex - end (excluded) of the input index array.
3531  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3532  * 
3533  * \throw If bgOfIndex or end is NULL.
3534  * \throw If input index array is not ascendingly sorted.
3535  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3536  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3537  */
3538 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
3539 {
3540   if(!bgOfIndex || !endOfIndex)
3541     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3542   checkAllocated();
3543   int nbCompo=getNumberOfComponents();
3544   int nbOfTuples=getNumberOfTuples();
3545   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3546   if(sz<1)
3547     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3548   sz--;
3549   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3550   const int *w=bgOfIndex;
3551   if(*w<0 || *w>=nbOfTuples)
3552     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3553   const double *srcPt=begin()+(*w)*nbCompo;
3554   double *tmp=ret->getPointer();
3555   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3556     {
3557       std::fill(tmp,tmp+nbCompo,0.);
3558       if(w[1]>=w[0])
3559         {
3560           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3561             {
3562               if(j>=0 && j<nbOfTuples)
3563                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3564               else
3565                 {
3566                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3567                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3568                 }
3569             }
3570         }
3571       else
3572         {
3573           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3574           throw INTERP_KERNEL::Exception(oss.str().c_str());
3575         }
3576     }
3577   ret->copyStringInfoFrom(*this);
3578   return ret.retn();
3579 }
3580
3581 /*!
3582  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3583  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3584  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3585  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3586  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3587  *          is to delete this array using decrRef() as it is no more needed. The array
3588  *          does not contain any textual info on components.
3589  *  \throw If \a this->getNumberOfComponents() != 2.
3590  */
3591 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
3592 {
3593   checkAllocated();
3594   int nbOfComp(getNumberOfComponents());
3595   if(nbOfComp!=2)
3596     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3597   int nbOfTuple(getNumberOfTuples());
3598   DataArrayDouble *ret(DataArrayDouble::New());
3599   ret->alloc(nbOfTuple,2);
3600   double *w(ret->getPointer());
3601   const double *wIn(getConstPointer());
3602   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3603     {
3604       w[0]=wIn[0]*cos(wIn[1]);
3605       w[1]=wIn[0]*sin(wIn[1]);
3606     }
3607   return ret;
3608 }
3609
3610 /*!
3611  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3612  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3613  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3614  * the Cylindrical CS.
3615  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3616  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3617  *          on the third component is copied from \a this array. The caller
3618  *          is to delete this array using decrRef() as it is no more needed. 
3619  *  \throw If \a this->getNumberOfComponents() != 3.
3620  */
3621 DataArrayDouble *DataArrayDouble::fromCylToCart() const
3622 {
3623   checkAllocated();
3624   int nbOfComp(getNumberOfComponents());
3625   if(nbOfComp!=3)
3626     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3627   int nbOfTuple(getNumberOfTuples());
3628   DataArrayDouble *ret(DataArrayDouble::New());
3629   ret->alloc(getNumberOfTuples(),3);
3630   double *w(ret->getPointer());
3631   const double *wIn(getConstPointer());
3632   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3633     {
3634       w[0]=wIn[0]*cos(wIn[1]);
3635       w[1]=wIn[0]*sin(wIn[1]);
3636       w[2]=wIn[2];
3637     }
3638   ret->setInfoOnComponent(2,getInfoOnComponent(2));
3639   return ret;
3640 }
3641
3642 /*!
3643  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3644  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3645  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3646  * point in the Cylindrical CS.
3647  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3648  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3649  *          on the third component is copied from \a this array. The caller
3650  *          is to delete this array using decrRef() as it is no more needed.
3651  *  \throw If \a this->getNumberOfComponents() != 3.
3652  */
3653 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
3654 {
3655   checkAllocated();
3656   int nbOfComp(getNumberOfComponents());
3657   if(nbOfComp!=3)
3658     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3659   int nbOfTuple(getNumberOfTuples());
3660   DataArrayDouble *ret(DataArrayDouble::New());
3661   ret->alloc(getNumberOfTuples(),3);
3662   double *w(ret->getPointer());
3663   const double *wIn(getConstPointer());
3664   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3665     {
3666       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3667       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3668       w[2]=wIn[0]*cos(wIn[1]);
3669     }
3670   return ret;
3671 }
3672
3673 /*!
3674  * 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.
3675  * 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.
3676  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
3677  *
3678  * \param [in] atOfThis - The axis type of \a this.
3679  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
3680  */
3681 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
3682 {
3683   checkAllocated();
3684   int nbOfComp(getNumberOfComponents());
3685   MCAuto<DataArrayDouble> ret;
3686   switch(atOfThis)
3687     {
3688     case AX_CART:
3689       ret=deepCopy();
3690     case AX_CYL:
3691       if(nbOfComp==3)
3692         {
3693           ret=fromCylToCart();
3694           break;
3695         }
3696       if(nbOfComp==2)
3697         {
3698           ret=fromPolarToCart();
3699           break;
3700         }
3701       else
3702         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
3703     case AX_SPHER:
3704       if(nbOfComp==3)
3705         {
3706           ret=fromSpherToCart();
3707           break;
3708         }
3709       if(nbOfComp==2)
3710         {
3711           ret=fromPolarToCart();
3712           break;
3713         }
3714       else
3715         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
3716     default:
3717       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
3718     }
3719   ret->copyStringInfoFrom(*this);
3720   return ret.retn();
3721 }
3722
3723 /*!
3724  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3725  * array contating 6 components.
3726  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3727  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3728  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3729  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3730  *  \throw If \a this->getNumberOfComponents() != 6.
3731  */
3732 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
3733 {
3734   checkAllocated();
3735   int nbOfComp(getNumberOfComponents());
3736   if(nbOfComp!=6)
3737     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3738   DataArrayDouble *ret=DataArrayDouble::New();
3739   int nbOfTuple=getNumberOfTuples();
3740   ret->alloc(nbOfTuple,1);
3741   const double *src=getConstPointer();
3742   double *dest=ret->getPointer();
3743   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3744     *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];
3745   return ret;
3746 }
3747
3748 /*!
3749  * Computes the determinant of every square matrix defined by the tuple of \a this
3750  * array, which contains either 4, 6 or 9 components. The case of 6 components
3751  * corresponds to that of the upper triangular matrix.
3752  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3753  *          is the determinant of matrix of the corresponding tuple of \a this array.
3754  *          The caller is to delete this result array using decrRef() as it is no more
3755  *          needed. 
3756  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3757  */
3758 DataArrayDouble *DataArrayDouble::determinant() const
3759 {
3760   checkAllocated();
3761   DataArrayDouble *ret=DataArrayDouble::New();
3762   int nbOfTuple=getNumberOfTuples();
3763   ret->alloc(nbOfTuple,1);
3764   const double *src=getConstPointer();
3765   double *dest=ret->getPointer();
3766   switch(getNumberOfComponents())
3767   {
3768     case 6:
3769       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3770         *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];
3771       return ret;
3772     case 4:
3773       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3774         *dest=src[0]*src[3]-src[1]*src[2];
3775       return ret;
3776     case 9:
3777       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3778         *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];
3779       return ret;
3780     default:
3781       ret->decrRef();
3782       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3783   }
3784 }
3785
3786 /*!
3787  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3788  * \a this array, which contains 6 components.
3789  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3790  *          components, whose each tuple contains the eigenvalues of the matrix of
3791  *          corresponding tuple of \a this array. 
3792  *          The caller is to delete this result array using decrRef() as it is no more
3793  *          needed. 
3794  *  \throw If \a this->getNumberOfComponents() != 6.
3795  */
3796 DataArrayDouble *DataArrayDouble::eigenValues() const
3797 {
3798   checkAllocated();
3799   int nbOfComp=getNumberOfComponents();
3800   if(nbOfComp!=6)
3801     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3802   DataArrayDouble *ret=DataArrayDouble::New();
3803   int nbOfTuple=getNumberOfTuples();
3804   ret->alloc(nbOfTuple,3);
3805   const double *src=getConstPointer();
3806   double *dest=ret->getPointer();
3807   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3808     INTERP_KERNEL::computeEigenValues6(src,dest);
3809   return ret;
3810 }
3811
3812 /*!
3813  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3814  * \a this array, which contains 6 components.
3815  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3816  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3817  *          corresponding tuple of \a this array.
3818  *          The caller is to delete this result array using decrRef() as it is no more
3819  *          needed.
3820  *  \throw If \a this->getNumberOfComponents() != 6.
3821  */
3822 DataArrayDouble *DataArrayDouble::eigenVectors() const
3823 {
3824   checkAllocated();
3825   int nbOfComp=getNumberOfComponents();
3826   if(nbOfComp!=6)
3827     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3828   DataArrayDouble *ret=DataArrayDouble::New();
3829   int nbOfTuple=getNumberOfTuples();
3830   ret->alloc(nbOfTuple,9);
3831   const double *src=getConstPointer();
3832   double *dest=ret->getPointer();
3833   for(int i=0;i<nbOfTuple;i++,src+=6)
3834     {
3835       double tmp[3];
3836       INTERP_KERNEL::computeEigenValues6(src,tmp);
3837       for(int j=0;j<3;j++,dest+=3)
3838         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3839     }
3840   return ret;
3841 }
3842
3843 /*!
3844  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3845  * array, which contains either 4, 6 or 9 components. The case of 6 components
3846  * corresponds to that of the upper triangular matrix.
3847  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3848  *          same number of components as \a this one, whose each tuple is the inverse
3849  *          matrix of the matrix of corresponding tuple of \a this array. 
3850  *          The caller is to delete this result array using decrRef() as it is no more
3851  *          needed. 
3852  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3853  */
3854 DataArrayDouble *DataArrayDouble::inverse() const
3855 {
3856   checkAllocated();
3857   int nbOfComp=getNumberOfComponents();
3858   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3859     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3860   DataArrayDouble *ret=DataArrayDouble::New();
3861   int nbOfTuple=getNumberOfTuples();
3862   ret->alloc(nbOfTuple,nbOfComp);
3863   const double *src=getConstPointer();
3864   double *dest=ret->getPointer();
3865   if(nbOfComp==6)
3866     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3867       {
3868         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];
3869         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3870         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3871         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3872         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3873         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3874         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3875       }
3876   else if(nbOfComp==4)
3877     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3878       {
3879         double det=src[0]*src[3]-src[1]*src[2];
3880         dest[0]=src[3]/det;
3881         dest[1]=-src[1]/det;
3882         dest[2]=-src[2]/det;
3883         dest[3]=src[0]/det;
3884       }
3885   else
3886     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3887       {
3888         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];
3889         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3890         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3891         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3892         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3893         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3894         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3895         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3896         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3897         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3898       }
3899   return ret;
3900 }
3901
3902 /*!
3903  * Computes the trace of every matrix defined by the tuple of \a this
3904  * array, which contains either 4, 6 or 9 components. The case of 6 components
3905  * corresponds to that of the upper triangular matrix.
3906  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3907  *          1 component, whose each tuple is the trace of
3908  *          the matrix of corresponding tuple of \a this array. 
3909  *          The caller is to delete this result array using decrRef() as it is no more
3910  *          needed. 
3911  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3912  */
3913 DataArrayDouble *DataArrayDouble::trace() const
3914 {
3915   checkAllocated();
3916   int nbOfComp=getNumberOfComponents();
3917   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3918     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3919   DataArrayDouble *ret=DataArrayDouble::New();
3920   int nbOfTuple=getNumberOfTuples();
3921   ret->alloc(nbOfTuple,1);
3922   const double *src=getConstPointer();
3923   double *dest=ret->getPointer();
3924   if(nbOfComp==6)
3925     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3926       *dest=src[0]+src[1]+src[2];
3927   else if(nbOfComp==4)
3928     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3929       *dest=src[0]+src[3];
3930   else
3931     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3932       *dest=src[0]+src[4]+src[8];
3933   return ret;
3934 }
3935
3936 /*!
3937  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3938  * \a this array, which contains 6 components.
3939  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3940  *          same number of components and tuples as \a this array.
3941  *          The caller is to delete this result array using decrRef() as it is no more
3942  *          needed.
3943  *  \throw If \a this->getNumberOfComponents() != 6.
3944  */
3945 DataArrayDouble *DataArrayDouble::deviator() const
3946 {
3947   checkAllocated();
3948   int nbOfComp=getNumberOfComponents();
3949   if(nbOfComp!=6)
3950     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3951   DataArrayDouble *ret=DataArrayDouble::New();
3952   int nbOfTuple=getNumberOfTuples();
3953   ret->alloc(nbOfTuple,6);
3954   const double *src=getConstPointer();
3955   double *dest=ret->getPointer();
3956   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3957     {
3958       double tr=(src[0]+src[1]+src[2])/3.;
3959       dest[0]=src[0]-tr;
3960       dest[1]=src[1]-tr;
3961       dest[2]=src[2]-tr;
3962       dest[3]=src[3];
3963       dest[4]=src[4];
3964       dest[5]=src[5];
3965     }
3966   return ret;
3967 }
3968
3969 /*!
3970  * Computes the magnitude of every vector defined by the tuple of
3971  * \a this array.
3972  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3973  *          same number of tuples as \a this array and one component.
3974  *          The caller is to delete this result array using decrRef() as it is no more
3975  *          needed.
3976  *  \throw If \a this is not allocated.
3977  */
3978 DataArrayDouble *DataArrayDouble::magnitude() const
3979 {
3980   checkAllocated();
3981   int nbOfComp=getNumberOfComponents();
3982   DataArrayDouble *ret=DataArrayDouble::New();
3983   int nbOfTuple=getNumberOfTuples();
3984   ret->alloc(nbOfTuple,1);
3985   const double *src=getConstPointer();
3986   double *dest=ret->getPointer();
3987   for(int i=0;i<nbOfTuple;i++,dest++)
3988     {
3989       double sum=0.;
3990       for(int j=0;j<nbOfComp;j++,src++)
3991         sum+=(*src)*(*src);
3992       *dest=sqrt(sum);
3993     }
3994   return ret;
3995 }
3996
3997 /*!
3998  * Computes for each tuple the sum of number of components values in the tuple and return it.
3999  * 
4000  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4001  *          same number of tuples as \a this array and one component.
4002  *          The caller is to delete this result array using decrRef() as it is no more
4003  *          needed.
4004  *  \throw If \a this is not allocated.
4005  */
4006 DataArrayDouble *DataArrayDouble::sumPerTuple() const
4007 {
4008   checkAllocated();
4009   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
4010   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
4011   ret->alloc(nbOfTuple,1);
4012   const double *src(getConstPointer());
4013   double *dest(ret->getPointer());
4014   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
4015     *dest=std::accumulate(src,src+nbOfComp,0.);
4016   return ret.retn();
4017 }
4018
4019 /*!
4020  * Computes the maximal value within every tuple of \a this array.
4021  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4022  *          same number of tuples as \a this array and one component.
4023  *          The caller is to delete this result array using decrRef() as it is no more
4024  *          needed.
4025  *  \throw If \a this is not allocated.
4026  *  \sa DataArrayDouble::maxPerTupleWithCompoId
4027  */
4028 DataArrayDouble *DataArrayDouble::maxPerTuple() const
4029 {
4030   checkAllocated();
4031   int nbOfComp=getNumberOfComponents();
4032   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4033   int nbOfTuple=getNumberOfTuples();
4034   ret->alloc(nbOfTuple,1);
4035   const double *src=getConstPointer();
4036   double *dest=ret->getPointer();
4037   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
4038     *dest=*std::max_element(src,src+nbOfComp);
4039   return ret.retn();
4040 }
4041
4042 /*!
4043  * Computes the maximal value within every tuple of \a this array and it returns the first component
4044  * id for each tuple that corresponds to the maximal value within the tuple.
4045  * 
4046  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
4047  *          same number of tuples and only one component.
4048  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4049  *          same number of tuples as \a this array and one component.
4050  *          The caller is to delete this result array using decrRef() as it is no more
4051  *          needed.
4052  *  \throw If \a this is not allocated.
4053  *  \sa DataArrayDouble::maxPerTuple
4054  */
4055 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
4056 {
4057   checkAllocated();
4058   int nbOfComp=getNumberOfComponents();
4059   MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
4060   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
4061   int nbOfTuple=getNumberOfTuples();
4062   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
4063   const double *src=getConstPointer();
4064   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
4065   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
4066     {
4067       const double *loc=std::max_element(src,src+nbOfComp);
4068       *dest=*loc;
4069       *dest1=(int)std::distance(src,loc);
4070     }
4071   compoIdOfMaxPerTuple=ret1.retn();
4072   return ret0.retn();
4073 }
4074
4075 /*!
4076  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
4077  * \n This returned array contains the euclidian distance for each tuple in \a this. 
4078  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
4079  * \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)
4080  *
4081  * \warning use this method with care because it can leads to big amount of consumed memory !
4082  * 
4083  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
4084  *
4085  * \throw If \a this is not allocated.
4086  *
4087  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
4088  */
4089 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
4090 {
4091   checkAllocated();
4092   int nbOfComp=getNumberOfComponents();
4093   int nbOfTuples=getNumberOfTuples();
4094   const double *inData=getConstPointer();
4095   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4096   ret->alloc(nbOfTuples*nbOfTuples,1);
4097   double *outData=ret->getPointer();
4098   for(int i=0;i<nbOfTuples;i++)
4099     {
4100       outData[i*nbOfTuples+i]=0.;
4101       for(int j=i+1;j<nbOfTuples;j++)
4102         {
4103           double dist=0.;
4104           for(int k=0;k<nbOfComp;k++)
4105             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4106           dist=sqrt(dist);
4107           outData[i*nbOfTuples+j]=dist;
4108           outData[j*nbOfTuples+i]=dist;
4109         }
4110     }
4111   return ret.retn();
4112 }
4113
4114 /*!
4115  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
4116  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
4117  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
4118  * \n Output rectangular matrix is sorted along rows.
4119  * \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)
4120  *
4121  * \warning use this method with care because it can leads to big amount of consumed memory !
4122  * 
4123  * \param [in] other DataArrayDouble instance having same number of components than \a this.
4124  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
4125  *
4126  * \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.
4127  *
4128  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
4129  */
4130 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
4131 {
4132   if(!other)
4133     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
4134   checkAllocated();
4135   other->checkAllocated();
4136   int nbOfComp=getNumberOfComponents();
4137   int otherNbOfComp=other->getNumberOfComponents();
4138   if(nbOfComp!=otherNbOfComp)
4139     {
4140       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
4141       throw INTERP_KERNEL::Exception(oss.str().c_str());
4142     }
4143   int nbOfTuples=getNumberOfTuples();
4144   int otherNbOfTuples=other->getNumberOfTuples();
4145   const double *inData=getConstPointer();
4146   const double *inDataOther=other->getConstPointer();
4147   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4148   ret->alloc(otherNbOfTuples*nbOfTuples,1);
4149   double *outData=ret->getPointer();
4150   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
4151     {
4152       for(int j=0;j<nbOfTuples;j++)
4153         {
4154           double dist=0.;
4155           for(int k=0;k<nbOfComp;k++)
4156             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4157           dist=sqrt(dist);
4158           outData[i*nbOfTuples+j]=dist;
4159         }
4160     }
4161   return ret.retn();
4162 }
4163
4164 /*!
4165  * Sorts value within every tuple of \a this array.
4166  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
4167  *              in descending order.
4168  *  \throw If \a this is not allocated.
4169  */
4170 void DataArrayDouble::sortPerTuple(bool asc)
4171 {
4172   checkAllocated();
4173   double *pt=getPointer();
4174   int nbOfTuple=getNumberOfTuples();
4175   int nbOfComp=getNumberOfComponents();
4176   if(asc)
4177     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4178       std::sort(pt,pt+nbOfComp);
4179   else
4180     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4181       std::sort(pt,pt+nbOfComp,std::greater<double>());
4182   declareAsNew();
4183 }
4184
4185 /*!
4186  * Converts every value of \a this array to its absolute value.
4187  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
4188  * should be called instead.
4189  *
4190  * \throw If \a this is not allocated.
4191  * \sa DataArrayDouble::computeAbs
4192  */
4193 void DataArrayDouble::abs()
4194 {
4195   checkAllocated();
4196   double *ptr(getPointer());
4197   std::size_t nbOfElems(getNbOfElems());
4198   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
4199   declareAsNew();
4200 }
4201
4202 /*!
4203  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
4204  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
4205  *
4206  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4207  *         same number of tuples and component as \a this array.
4208  *         The caller is to delete this result array using decrRef() as it is no more
4209  *         needed.
4210  * \throw If \a this is not allocated.
4211  * \sa DataArrayDouble::abs
4212  */
4213 DataArrayDouble *DataArrayDouble::computeAbs() const
4214 {
4215   checkAllocated();
4216   DataArrayDouble *newArr(DataArrayDouble::New());
4217   int nbOfTuples(getNumberOfTuples());
4218   int nbOfComp(getNumberOfComponents());
4219   newArr->alloc(nbOfTuples,nbOfComp);
4220   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
4221   newArr->copyStringInfoFrom(*this);
4222   return newArr;
4223 }
4224
4225 /*!
4226  * Apply a linear function to a given component of \a this array, so that
4227  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
4228  *  \param [in] a - the first coefficient of the function.
4229  *  \param [in] b - the second coefficient of the function.
4230  *  \param [in] compoId - the index of component to modify.
4231  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
4232  */
4233 void DataArrayDouble::applyLin(double a, double b, int compoId)
4234 {
4235   checkAllocated();
4236   double *ptr(getPointer()+compoId);
4237   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
4238   if(compoId<0 || compoId>=nbOfComp)
4239     {
4240       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
4241       throw INTERP_KERNEL::Exception(oss.str().c_str());
4242     }
4243   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
4244     *ptr=a*(*ptr)+b;
4245   declareAsNew();
4246 }
4247
4248 /*!
4249  * Apply a linear function to all elements of \a this array, so that
4250  * an element _x_ becomes \f$ a * x + b \f$.
4251  *  \param [in] a - the first coefficient of the function.
4252  *  \param [in] b - the second coefficient of the function.
4253  *  \throw If \a this is not allocated.
4254  */
4255 void DataArrayDouble::applyLin(double a, double b)
4256 {
4257   checkAllocated();
4258   double *ptr=getPointer();
4259   std::size_t nbOfElems=getNbOfElems();
4260   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4261     *ptr=a*(*ptr)+b;
4262   declareAsNew();
4263 }
4264
4265 /*!
4266  * Modify all elements of \a this array, so that
4267  * an element _x_ becomes \f$ numerator / x \f$.
4268  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4269  *           array, all elements processed before detection of the zero element remain
4270  *           modified.
4271  *  \param [in] numerator - the numerator used to modify array elements.
4272  *  \throw If \a this is not allocated.
4273  *  \throw If there is an element equal to 0.0 in \a this array.
4274  */
4275 void DataArrayDouble::applyInv(double numerator)
4276 {
4277   checkAllocated();
4278   double *ptr=getPointer();
4279   std::size_t nbOfElems=getNbOfElems();
4280   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4281     {
4282       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4283         {
4284           *ptr=numerator/(*ptr);
4285         }
4286       else
4287         {
4288           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4289           oss << " !";
4290           throw INTERP_KERNEL::Exception(oss.str().c_str());
4291         }
4292     }
4293   declareAsNew();
4294 }
4295
4296 /*!
4297  * Returns a full copy of \a this array except that sign of all elements is reversed.
4298  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4299  *          same number of tuples and component as \a this array.
4300  *          The caller is to delete this result array using decrRef() as it is no more
4301  *          needed.
4302  *  \throw If \a this is not allocated.
4303  */
4304 DataArrayDouble *DataArrayDouble::negate() const
4305 {
4306   checkAllocated();
4307   DataArrayDouble *newArr=DataArrayDouble::New();
4308   int nbOfTuples=getNumberOfTuples();
4309   int nbOfComp=getNumberOfComponents();
4310   newArr->alloc(nbOfTuples,nbOfComp);
4311   const double *cptr=getConstPointer();
4312   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4313   newArr->copyStringInfoFrom(*this);
4314   return newArr;
4315 }
4316
4317 /*!
4318  * Modify all elements of \a this array, so that
4319  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4320  * all values in \a this have to be >= 0 if val is \b not integer.
4321  *  \param [in] val - the value used to apply pow on all array elements.
4322  *  \throw If \a this is not allocated.
4323  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4324  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4325  *           modified.
4326  */
4327 void DataArrayDouble::applyPow(double val)
4328 {
4329   checkAllocated();
4330   double *ptr=getPointer();
4331   std::size_t nbOfElems=getNbOfElems();
4332   int val2=(int)val;
4333   bool isInt=((double)val2)==val;
4334   if(!isInt)
4335     {
4336       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4337         {
4338           if(*ptr>=0)
4339             *ptr=pow(*ptr,val);
4340           else
4341             {
4342               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4343               throw INTERP_KERNEL::Exception(oss.str().c_str());
4344             }
4345         }
4346     }
4347   else
4348     {
4349       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4350         *ptr=pow(*ptr,val2);
4351     }
4352   declareAsNew();
4353 }
4354
4355 /*!
4356  * Modify all elements of \a this array, so that
4357  * an element _x_ becomes \f$ val ^ x \f$.
4358  *  \param [in] val - the value used to apply pow on all array elements.
4359  *  \throw If \a this is not allocated.
4360  *  \throw If \a val < 0.
4361  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4362  *           array, all elements processed before detection of the zero element remain
4363  *           modified.
4364  */
4365 void DataArrayDouble::applyRPow(double val)
4366 {
4367   checkAllocated();
4368   if(val<0.)
4369     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4370   double *ptr=getPointer();
4371   std::size_t nbOfElems=getNbOfElems();
4372   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4373     *ptr=pow(val,*ptr);
4374   declareAsNew();
4375 }
4376
4377 /*!
4378  * Returns a new DataArrayDouble created from \a this one by applying \a
4379  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4380  * For more info see \ref MEDCouplingArrayApplyFunc
4381  *  \param [in] nbOfComp - number of components in the result array.
4382  *  \param [in] func - the \a FunctionToEvaluate declared as 
4383  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4384  *              where \a pos points to the first component of a tuple of \a this array
4385  *              and \a res points to the first component of a tuple of the result array.
4386  *              Note that length (number of components) of \a pos can differ from
4387  *              that of \a res.
4388  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4389  *          same number of tuples as \a this array.
4390  *          The caller is to delete this result array using decrRef() as it is no more
4391  *          needed.
4392  *  \throw If \a this is not allocated.
4393  *  \throw If \a func returns \a false.
4394  */
4395 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
4396 {
4397   checkAllocated();
4398   DataArrayDouble *newArr=DataArrayDouble::New();
4399   int nbOfTuples=getNumberOfTuples();
4400   int oldNbOfComp=getNumberOfComponents();
4401   newArr->alloc(nbOfTuples,nbOfComp);
4402   const double *ptr=getConstPointer();
4403   double *ptrToFill=newArr->getPointer();
4404   for(int i=0;i<nbOfTuples;i++)
4405     {
4406       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4407         {
4408           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4409           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4410           oss << ") : Evaluation of function failed !";
4411           newArr->decrRef();
4412           throw INTERP_KERNEL::Exception(oss.str().c_str());
4413         }
4414     }
4415   return newArr;
4416 }
4417
4418 /*!
4419  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4420  * tuple of \a this array. Textual data is not copied.
4421  * For more info see \ref MEDCouplingArrayApplyFunc1.
4422  *  \param [in] nbOfComp - number of components in the result array.
4423  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4424  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4425  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4426  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4427  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4428  *          same number of tuples as \a this array and \a nbOfComp components.
4429  *          The caller is to delete this result array using decrRef() as it is no more
4430  *          needed.
4431  *  \throw If \a this is not allocated.
4432  *  \throw If computing \a func fails.
4433  */
4434 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
4435 {
4436   INTERP_KERNEL::ExprParser expr(func);
4437   expr.parse();
4438   std::set<std::string> vars;
4439   expr.getTrueSetOfVars(vars);
4440   std::vector<std::string> varsV(vars.begin(),vars.end());
4441   return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
4442 }
4443
4444 /*!
4445  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4446  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
4447  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
4448  *
4449  * For more info see \ref MEDCouplingArrayApplyFunc0.
4450  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4451  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4452  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4453  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
4454  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4455  *          same number of tuples and components as \a this array.
4456  *          The caller is to delete this result array using decrRef() as it is no more
4457  *          needed.
4458  *  \sa applyFuncOnThis
4459  *  \throw If \a this is not allocated.
4460  *  \throw If computing \a func fails.
4461  */
4462 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
4463 {
4464   int nbOfComp(getNumberOfComponents());
4465   if(nbOfComp<=0)
4466     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
4467   checkAllocated();
4468   int nbOfTuples(getNumberOfTuples());
4469   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
4470   newArr->alloc(nbOfTuples,nbOfComp);
4471   INTERP_KERNEL::ExprParser expr(func);
4472   expr.parse();
4473   std::set<std::string> vars;
4474   expr.getTrueSetOfVars(vars);
4475   if((int)vars.size()>1)
4476     {
4477       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 : ";
4478       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4479       throw INTERP_KERNEL::Exception(oss.str().c_str());
4480     }
4481   if(vars.empty())
4482     {
4483       expr.prepareFastEvaluator();
4484       newArr->rearrange(1);
4485       newArr->fillWithValue(expr.evaluateDouble());
4486       newArr->rearrange(nbOfComp);
4487       return newArr.retn();
4488     }
4489   std::vector<std::string> vars2(vars.begin(),vars.end());
4490   double buff,*ptrToFill(newArr->getPointer());
4491   const double *ptr(begin());
4492   std::vector<double> stck;
4493   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4494   expr.prepareFastEvaluator();
4495   if(!isSafe)
4496     {
4497       for(int i=0;i<nbOfTuples;i++)
4498         {
4499           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4500             {
4501               buff=*ptr;
4502               expr.evaluateDoubleInternal(stck);
4503               *ptrToFill=stck.back();
4504               stck.pop_back();
4505             }
4506         }
4507     }
4508   else
4509     {
4510       for(int i=0;i<nbOfTuples;i++)
4511         {
4512           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4513             {
4514               buff=*ptr;
4515               try
4516               {
4517                   expr.evaluateDoubleInternalSafe(stck);
4518               }
4519               catch(INTERP_KERNEL::Exception& e)
4520               {
4521                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4522                   oss << buff;
4523                   oss << ") : Evaluation of function failed !" << e.what();
4524                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4525               }
4526               *ptrToFill=stck.back();
4527               stck.pop_back();
4528             }
4529         }
4530     }
4531   return newArr.retn();
4532 }
4533
4534 /*!
4535  * This method is a non const method that modify the array in \a this.
4536  * This method only works on one component array. It means that function \a func must
4537  * contain at most one variable.
4538  * This method is a specialization of applyFunc method with one parameter on one component array.
4539  *
4540  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4541  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4542  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4543  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4544  *
4545  * \sa applyFunc
4546  */
4547 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
4548 {
4549   int nbOfComp(getNumberOfComponents());
4550   if(nbOfComp<=0)
4551     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
4552   checkAllocated();
4553   int nbOfTuples(getNumberOfTuples());
4554   INTERP_KERNEL::ExprParser expr(func);
4555   expr.parse();
4556   std::set<std::string> vars;
4557   expr.getTrueSetOfVars(vars);
4558   if((int)vars.size()>1)
4559     {
4560       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 : ";
4561       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4562       throw INTERP_KERNEL::Exception(oss.str().c_str());
4563     }
4564   if(vars.empty())
4565     {
4566       expr.prepareFastEvaluator();
4567       std::vector<std::string> compInfo(getInfoOnComponents());
4568       rearrange(1);
4569       fillWithValue(expr.evaluateDouble());
4570       rearrange(nbOfComp);
4571       setInfoOnComponents(compInfo);
4572       return ;
4573     }
4574   std::vector<std::string> vars2(vars.begin(),vars.end());
4575   double buff,*ptrToFill(getPointer());
4576   const double *ptr(begin());
4577   std::vector<double> stck;
4578   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
4579   expr.prepareFastEvaluator();
4580   if(!isSafe)
4581     {
4582       for(int i=0;i<nbOfTuples;i++)
4583         {
4584           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4585             {
4586               buff=*ptr;
4587               expr.evaluateDoubleInternal(stck);
4588               *ptrToFill=stck.back();
4589               stck.pop_back();
4590             }
4591         }
4592     }
4593   else
4594     {
4595       for(int i=0;i<nbOfTuples;i++)
4596         {
4597           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
4598             {
4599               buff=*ptr;
4600               try
4601               {
4602                   expr.evaluateDoubleInternalSafe(stck);
4603               }
4604               catch(INTERP_KERNEL::Exception& e)
4605               {
4606                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
4607                   oss << buff;
4608                   oss << ") : Evaluation of function failed !" << e.what();
4609                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4610               }
4611               *ptrToFill=stck.back();
4612               stck.pop_back();
4613             }
4614         }
4615     }
4616 }
4617
4618 /*!
4619  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4620  * tuple of \a this array. Textual data is not copied.
4621  * For more info see \ref MEDCouplingArrayApplyFunc2.
4622  *  \param [in] nbOfComp - number of components in the result array.
4623  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4624  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4625  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4626  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4627  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4628  *          same number of tuples as \a this array.
4629  *          The caller is to delete this result array using decrRef() as it is no more
4630  *          needed.
4631  *  \throw If \a this is not allocated.
4632  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4633  *  \throw If computing \a func fails.
4634  */
4635 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
4636 {
4637   return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
4638 }
4639
4640 /*!
4641  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4642  * tuple of \a this array. Textual data is not copied.
4643  * For more info see \ref MEDCouplingArrayApplyFunc3.
4644  *  \param [in] nbOfComp - number of components in the result array.
4645  *  \param [in] varsOrder - sequence of vars defining their order.
4646  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4647  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4648  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
4649  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
4650  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4651  *          same number of tuples as \a this array.
4652  *          The caller is to delete this result array using decrRef() as it is no more
4653  *          needed.
4654  *  \throw If \a this is not allocated.
4655  *  \throw If \a func contains vars not in \a varsOrder.
4656  *  \throw If computing \a func fails.
4657  */
4658 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
4659 {
4660   if(nbOfComp<=0)
4661     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
4662   std::vector<std::string> varsOrder2(varsOrder);
4663   int oldNbOfComp(getNumberOfComponents());
4664   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
4665     varsOrder2.push_back(std::string());
4666   checkAllocated();
4667   int nbOfTuples(getNumberOfTuples());
4668   INTERP_KERNEL::ExprParser expr(func);
4669   expr.parse();
4670   std::set<std::string> vars;
4671   expr.getTrueSetOfVars(vars);
4672   if((int)vars.size()>oldNbOfComp)
4673     {
4674       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4675       oss << vars.size() << " variables : ";
4676       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4677       throw INTERP_KERNEL::Exception(oss.str().c_str());
4678     }
4679   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
4680   newArr->alloc(nbOfTuples,nbOfComp);
4681   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
4682   double *buffPtr(buff),*ptrToFill;
4683   std::vector<double> stck;
4684   for(int iComp=0;iComp<nbOfComp;iComp++)
4685     {
4686       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
4687       expr.prepareFastEvaluator();
4688       const double *ptr(getConstPointer());
4689       ptrToFill=newArr->getPointer()+iComp;
4690       if(!isSafe)
4691         {
4692           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4693             {
4694               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4695               expr.evaluateDoubleInternal(stck);
4696               *ptrToFill=stck.back();
4697               stck.pop_back();
4698             }
4699         }
4700       else
4701         {
4702           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
4703             {
4704               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
4705               try
4706               {
4707                   expr.evaluateDoubleInternalSafe(stck);
4708                   *ptrToFill=stck.back();
4709                   stck.pop_back();
4710               }
4711               catch(INTERP_KERNEL::Exception& e)
4712               {
4713                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4714                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4715                   oss << ") : Evaluation of function failed !" << e.what();
4716                   throw INTERP_KERNEL::Exception(oss.str().c_str());
4717               }
4718             }
4719         }
4720     }
4721   return newArr.retn();
4722 }
4723
4724 void DataArrayDouble::applyFuncFast32(const std::string& func)
4725 {
4726   checkAllocated();
4727   INTERP_KERNEL::ExprParser expr(func);
4728   expr.parse();
4729   char *funcStr=expr.compileX86();
4730   MYFUNCPTR funcPtr;
4731   *((void **)&funcPtr)=funcStr;//he he...
4732   //
4733   double *ptr=getPointer();
4734   int nbOfComp=getNumberOfComponents();
4735   int nbOfTuples=getNumberOfTuples();
4736   int nbOfElems=nbOfTuples*nbOfComp;
4737   for(int i=0;i<nbOfElems;i++,ptr++)
4738     *ptr=funcPtr(*ptr);
4739   declareAsNew();
4740 }
4741
4742 void DataArrayDouble::applyFuncFast64(const std::string& func)
4743 {
4744   checkAllocated();
4745   INTERP_KERNEL::ExprParser expr(func);
4746   expr.parse();
4747   char *funcStr=expr.compileX86_64();
4748   MYFUNCPTR funcPtr;
4749   *((void **)&funcPtr)=funcStr;//he he...
4750   //
4751   double *ptr=getPointer();
4752   int nbOfComp=getNumberOfComponents();
4753   int nbOfTuples=getNumberOfTuples();
4754   int nbOfElems=nbOfTuples*nbOfComp;
4755   for(int i=0;i<nbOfElems;i++,ptr++)
4756     *ptr=funcPtr(*ptr);
4757   declareAsNew();
4758 }
4759
4760 DataArrayDoubleIterator *DataArrayDouble::iterator()
4761 {
4762   return new DataArrayDoubleIterator(this);
4763 }
4764
4765 /*!
4766  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4767  * array whose values are within a given range. Textual data is not copied.
4768  *  \param [in] vmin - a lowest acceptable value (included).
4769  *  \param [in] vmax - a greatest acceptable value (included).
4770  *  \return DataArrayInt * - the new instance of DataArrayInt.
4771  *          The caller is to delete this result array using decrRef() as it is no more
4772  *          needed.
4773  *  \throw If \a this->getNumberOfComponents() != 1.
4774  *
4775  *  \sa DataArrayDouble::findIdsNotInRange
4776  *
4777  *  \if ENABLE_EXAMPLES
4778  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4779  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4780  *  \endif
4781  */
4782 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
4783 {
4784   checkAllocated();
4785   if(getNumberOfComponents()!=1)
4786     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
4787   const double *cptr(begin());
4788   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4789   int nbOfTuples(getNumberOfTuples());
4790   for(int i=0;i<nbOfTuples;i++,cptr++)
4791     if(*cptr>=vmin && *cptr<=vmax)
4792       ret->pushBackSilent(i);
4793   return ret.retn();
4794 }
4795
4796 /*!
4797  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4798  * array whose values are not within a given range. Textual data is not copied.
4799  *  \param [in] vmin - a lowest not acceptable value (excluded).
4800  *  \param [in] vmax - a greatest not acceptable value (excluded).
4801  *  \return DataArrayInt * - the new instance of DataArrayInt.
4802  *          The caller is to delete this result array using decrRef() as it is no more
4803  *          needed.
4804  *  \throw If \a this->getNumberOfComponents() != 1.
4805  *
4806  *  \sa DataArrayDouble::findIdsInRange
4807  */
4808 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
4809 {
4810   checkAllocated();
4811   if(getNumberOfComponents()!=1)
4812     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
4813   const double *cptr(begin());
4814   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4815   int nbOfTuples(getNumberOfTuples());
4816   for(int i=0;i<nbOfTuples;i++,cptr++)
4817     if(*cptr<vmin || *cptr>vmax)
4818       ret->pushBackSilent(i);
4819   return ret.retn();
4820 }
4821
4822 /*!
4823  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4824  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4825  * the number of component in the result array is same as that of each of given arrays.
4826  * Info on components is copied from the first of the given arrays. Number of components
4827  * in the given arrays must be  the same.
4828  *  \param [in] a1 - an array to include in the result array.
4829  *  \param [in] a2 - another array to include in the result array.
4830  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4831  *          The caller is to delete this result array using decrRef() as it is no more
4832  *          needed.
4833  *  \throw If both \a a1 and \a a2 are NULL.
4834  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4835  */
4836 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
4837 {
4838   std::vector<const DataArrayDouble *> tmp(2);
4839   tmp[0]=a1; tmp[1]=a2;
4840   return Aggregate(tmp);
4841 }
4842
4843 /*!
4844  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4845  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4846  * the number of component in the result array is same as that of each of given arrays.
4847  * Info on components is copied from the first of the given arrays. Number of components
4848  * in the given arrays must be  the same.
4849  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
4850  * not the object itself.
4851  *  \param [in] arr - a sequence of arrays to include in the result array.
4852  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4853  *          The caller is to delete this result array using decrRef() as it is no more
4854  *          needed.
4855  *  \throw If all arrays within \a arr are NULL.
4856  *  \throw If getNumberOfComponents() of arrays within \a arr.
4857  */
4858 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
4859 {
4860   std::vector<const DataArrayDouble *> a;
4861   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4862     if(*it4)
4863       a.push_back(*it4);
4864   if(a.empty())
4865     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4866   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4867   int nbOfComp=(*it)->getNumberOfComponents();
4868   int nbt=(*it++)->getNumberOfTuples();
4869   for(int i=1;it!=a.end();it++,i++)
4870     {
4871       if((*it)->getNumberOfComponents()!=nbOfComp)
4872         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4873       nbt+=(*it)->getNumberOfTuples();
4874     }
4875   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4876   ret->alloc(nbt,nbOfComp);
4877   double *pt=ret->getPointer();
4878   for(it=a.begin();it!=a.end();it++)
4879     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4880   ret->copyStringInfoFrom(*(a[0]));
4881   return ret.retn();
4882 }
4883
4884 /*!
4885  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4886  * of components in the result array is a sum of the number of components of given arrays
4887  * and (2) the number of tuples in the result array is same as that of each of given
4888  * arrays. In other words the i-th tuple of result array includes all components of
4889  * i-th tuples of all given arrays.
4890  * Number of tuples in the given arrays must be  the same.
4891  *  \param [in] a1 - an array to include in the result array.
4892  *  \param [in] a2 - another array to include in the result array.
4893  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4894  *          The caller is to delete this result array using decrRef() as it is no more
4895  *          needed.
4896  *  \throw If both \a a1 and \a a2 are NULL.
4897  *  \throw If any given array is not allocated.
4898  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4899  */
4900 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
4901 {
4902   std::vector<const DataArrayDouble *> arr(2);
4903   arr[0]=a1; arr[1]=a2;
4904   return Meld(arr);
4905 }
4906
4907 /*!
4908  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4909  * of components in the result array is a sum of the number of components of given arrays
4910  * and (2) the number of tuples in the result array is same as that of each of given
4911  * arrays. In other words the i-th tuple of result array includes all components of
4912  * i-th tuples of all given arrays.
4913  * Number of tuples in the given arrays must be  the same.
4914  *  \param [in] arr - a sequence of arrays to include in the result array.
4915  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4916  *          The caller is to delete this result array using decrRef() as it is no more
4917  *          needed.
4918  *  \throw If all arrays within \a arr are NULL.
4919  *  \throw If any given array is not allocated.
4920  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4921  */
4922 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
4923 {
4924   std::vector<const DataArrayDouble *> a;
4925   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4926     if(*it4)
4927       a.push_back(*it4);
4928   if(a.empty())
4929     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4930   std::vector<const DataArrayDouble *>::const_iterator it;
4931   for(it=a.begin();it!=a.end();it++)
4932     (*it)->checkAllocated();
4933   it=a.begin();
4934   int nbOfTuples=(*it)->getNumberOfTuples();
4935   std::vector<int> nbc(a.size());
4936   std::vector<const double *> pts(a.size());
4937   nbc[0]=(*it)->getNumberOfComponents();
4938   pts[0]=(*it++)->getConstPointer();
4939   for(int i=1;it!=a.end();it++,i++)
4940     {
4941       if(nbOfTuples!=(*it)->getNumberOfTuples())
4942         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4943       nbc[i]=(*it)->getNumberOfComponents();
4944       pts[i]=(*it)->getConstPointer();
4945     }
4946   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4947   DataArrayDouble *ret=DataArrayDouble::New();
4948   ret->alloc(nbOfTuples,totalNbOfComp);
4949   double *retPtr=ret->getPointer();
4950   for(int i=0;i<nbOfTuples;i++)
4951     for(int j=0;j<(int)a.size();j++)
4952       {
4953         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4954         pts[j]+=nbc[j];
4955       }
4956   int k=0;
4957   for(int i=0;i<(int)a.size();i++)
4958     for(int j=0;j<nbc[i];j++,k++)
4959       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
4960   return ret;
4961 }
4962
4963 /*!
4964  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4965  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4966  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4967  * Info on components and name is copied from the first of the given arrays.
4968  * Number of tuples and components in the given arrays must be the same.
4969  *  \param [in] a1 - a given array.
4970  *  \param [in] a2 - another given array.
4971  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4972  *          The caller is to delete this result array using decrRef() as it is no more
4973  *          needed.
4974  *  \throw If either \a a1 or \a a2 is NULL.
4975  *  \throw If any given array is not allocated.
4976  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4977  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4978  */
4979 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
4980 {
4981   if(!a1 || !a2)
4982     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4983   a1->checkAllocated();
4984   a2->checkAllocated();
4985   int nbOfComp=a1->getNumberOfComponents();
4986   if(nbOfComp!=a2->getNumberOfComponents())
4987     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4988   int nbOfTuple=a1->getNumberOfTuples();
4989   if(nbOfTuple!=a2->getNumberOfTuples())
4990     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4991   DataArrayDouble *ret=DataArrayDouble::New();
4992   ret->alloc(nbOfTuple,1);
4993   double *retPtr=ret->getPointer();
4994   const double *a1Ptr=a1->getConstPointer();
4995   const double *a2Ptr=a2->getConstPointer();
4996   for(int i=0;i<nbOfTuple;i++)
4997     {
4998       double sum=0.;
4999       for(int j=0;j<nbOfComp;j++)
5000         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
5001       retPtr[i]=sum;
5002     }
5003   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
5004   ret->setName(a1->getName());
5005   return ret;
5006 }
5007
5008 /*!
5009  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
5010  * the i-th tuple of the result array contains 3 components of a vector which is a cross
5011  * product of two vectors defined by the i-th tuples of given arrays.
5012  * Info on components is copied from the first of the given arrays.
5013  * Number of tuples in the given arrays must be the same.
5014  * Number of components in the given arrays must be 3.
5015  *  \param [in] a1 - a given array.
5016  *  \param [in] a2 - another given array.
5017  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5018  *          The caller is to delete this result array using decrRef() as it is no more
5019  *          needed.
5020  *  \throw If either \a a1 or \a a2 is NULL.
5021  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5022  *  \throw If \a a1->getNumberOfComponents() != 3
5023  *  \throw If \a a2->getNumberOfComponents() != 3
5024  */
5025 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
5026 {
5027   if(!a1 || !a2)
5028     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
5029   int nbOfComp=a1->getNumberOfComponents();
5030   if(nbOfComp!=a2->getNumberOfComponents())
5031     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
5032   if(nbOfComp!=3)
5033     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
5034   int nbOfTuple=a1->getNumberOfTuples();
5035   if(nbOfTuple!=a2->getNumberOfTuples())
5036     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
5037   DataArrayDouble *ret=DataArrayDouble::New();
5038   ret->alloc(nbOfTuple,3);
5039   double *retPtr=ret->getPointer();
5040   const double *a1Ptr=a1->getConstPointer();
5041   const double *a2Ptr=a2->getConstPointer();
5042   for(int i=0;i<nbOfTuple;i++)
5043     {
5044       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
5045       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
5046       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
5047     }
5048   ret->copyStringInfoFrom(*a1);
5049   return ret;
5050 }
5051
5052 /*!
5053  * Returns a new DataArrayDouble containing maximal values of two given arrays.
5054  * Info on components is copied from the first of the given arrays.
5055  * Number of tuples and components in the given arrays must be the same.
5056  *  \param [in] a1 - an array to compare values with another one.
5057  *  \param [in] a2 - another array to compare values with the first one.
5058  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5059  *          The caller is to delete this result array using decrRef() as it is no more
5060  *          needed.
5061  *  \throw If either \a a1 or \a a2 is NULL.
5062  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5063  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
5064  */
5065 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
5066 {
5067   if(!a1 || !a2)
5068     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
5069   int nbOfComp=a1->getNumberOfComponents();
5070   if(nbOfComp!=a2->getNumberOfComponents())
5071     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
5072   int nbOfTuple=a1->getNumberOfTuples();
5073   if(nbOfTuple!=a2->getNumberOfTuples())
5074     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
5075   DataArrayDouble *ret=DataArrayDouble::New();
5076   ret->alloc(nbOfTuple,nbOfComp);
5077   double *retPtr=ret->getPointer();
5078   const double *a1Ptr=a1->getConstPointer();
5079   const double *a2Ptr=a2->getConstPointer();
5080   int nbElem=nbOfTuple*nbOfComp;
5081   for(int i=0;i<nbElem;i++)
5082     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
5083   ret->copyStringInfoFrom(*a1);
5084   return ret;
5085 }
5086
5087 /*!
5088  * Returns a new DataArrayDouble containing minimal values of two given arrays.
5089  * Info on components is copied from the first of the given arrays.
5090  * Number of tuples and components in the given arrays must be the same.
5091  *  \param [in] a1 - an array to compare values with another one.
5092  *  \param [in] a2 - another array to compare values with the first one.
5093  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5094  *          The caller is to delete this result array using decrRef() as it is no more
5095  *          needed.
5096  *  \throw If either \a a1 or \a a2 is NULL.
5097  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5098  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
5099  */
5100 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
5101 {
5102   if(!a1 || !a2)
5103     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
5104   int nbOfComp=a1->getNumberOfComponents();
5105   if(nbOfComp!=a2->getNumberOfComponents())
5106     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
5107   int nbOfTuple=a1->getNumberOfTuples();
5108   if(nbOfTuple!=a2->getNumberOfTuples())
5109     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
5110   DataArrayDouble *ret=DataArrayDouble::New();
5111   ret->alloc(nbOfTuple,nbOfComp);
5112   double *retPtr=ret->getPointer();
5113   const double *a1Ptr=a1->getConstPointer();
5114   const double *a2Ptr=a2->getConstPointer();
5115   int nbElem=nbOfTuple*nbOfComp;
5116   for(int i=0;i<nbElem;i++)
5117     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
5118   ret->copyStringInfoFrom(*a1);
5119   return ret;
5120 }
5121
5122 /*!
5123  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
5124  * valid cases.
5125  * 1.  The arrays have same number of tuples and components. Then each value of
5126  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
5127  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
5128  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5129  *   component. Then
5130  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
5131  * 3.  The arrays have same number of components and one array, say _a2_, has one
5132  *   tuple. Then
5133  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
5134  *
5135  * Info on components is copied either from the first array (in the first case) or from
5136  * the array with maximal number of elements (getNbOfElems()).
5137  *  \param [in] a1 - an array to sum up.
5138  *  \param [in] a2 - another array to sum up.
5139  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5140  *          The caller is to delete this result array using decrRef() as it is no more
5141  *          needed.
5142  *  \throw If either \a a1 or \a a2 is NULL.
5143  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5144  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5145  *         none of them has number of tuples or components equal to 1.
5146  */
5147 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
5148 {
5149   if(!a1 || !a2)
5150     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
5151   int nbOfTuple=a1->getNumberOfTuples();
5152   int nbOfTuple2=a2->getNumberOfTuples();
5153   int nbOfComp=a1->getNumberOfComponents();
5154   int nbOfComp2=a2->getNumberOfComponents();
5155   MCAuto<DataArrayDouble> ret=0;
5156   if(nbOfTuple==nbOfTuple2)
5157     {
5158       if(nbOfComp==nbOfComp2)
5159         {
5160           ret=DataArrayDouble::New();
5161           ret->alloc(nbOfTuple,nbOfComp);
5162           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
5163           ret->copyStringInfoFrom(*a1);
5164         }
5165       else
5166         {
5167           int nbOfCompMin,nbOfCompMax;
5168           const DataArrayDouble *aMin, *aMax;
5169           if(nbOfComp>nbOfComp2)
5170             {
5171               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5172               aMin=a2; aMax=a1;
5173             }
5174           else
5175             {
5176               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5177               aMin=a1; aMax=a2;
5178             }
5179           if(nbOfCompMin==1)
5180             {
5181               ret=DataArrayDouble::New();
5182               ret->alloc(nbOfTuple,nbOfCompMax);
5183               const double *aMinPtr=aMin->getConstPointer();
5184               const double *aMaxPtr=aMax->getConstPointer();
5185               double *res=ret->getPointer();
5186               for(int i=0;i<nbOfTuple;i++)
5187                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
5188               ret->copyStringInfoFrom(*aMax);
5189             }
5190           else
5191             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5192         }
5193     }
5194   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5195     {
5196       if(nbOfComp==nbOfComp2)
5197         {
5198           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5199           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5200           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5201           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5202           ret=DataArrayDouble::New();
5203           ret->alloc(nbOfTupleMax,nbOfComp);
5204           double *res=ret->getPointer();
5205           for(int i=0;i<nbOfTupleMax;i++)
5206             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
5207           ret->copyStringInfoFrom(*aMax);
5208         }
5209       else
5210         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
5211     }
5212   else
5213     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
5214   return ret.retn();
5215 }
5216
5217 /*!
5218  * Adds values of another DataArrayDouble to values of \a this one. There are 3
5219  * valid cases.
5220  * 1.  The arrays have same number of tuples and components. Then each value of
5221  *   \a other array is added to the corresponding value of \a this array, i.e.:
5222  *   _a_ [ i, j ] += _other_ [ i, j ].
5223  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5224  *   _a_ [ i, j ] += _other_ [ i, 0 ].
5225  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5226  *   _a_ [ i, j ] += _a2_ [ 0, j ].
5227  *
5228  *  \param [in] other - an array to add to \a this one.
5229  *  \throw If \a other is NULL.
5230  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5231  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5232  *         \a other has number of both tuples and components not equal to 1.
5233  */
5234 void DataArrayDouble::addEqual(const DataArrayDouble *other)
5235 {
5236   if(!other)
5237     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
5238   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
5239   checkAllocated();
5240   other->checkAllocated();
5241   int nbOfTuple=getNumberOfTuples();
5242   int nbOfTuple2=other->getNumberOfTuples();
5243   int nbOfComp=getNumberOfComponents();
5244   int nbOfComp2=other->getNumberOfComponents();
5245   if(nbOfTuple==nbOfTuple2)
5246     {
5247       if(nbOfComp==nbOfComp2)
5248         {
5249           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
5250         }
5251       else if(nbOfComp2==1)
5252         {
5253           double *ptr=getPointer();
5254           const double *ptrc=other->getConstPointer();
5255           for(int i=0;i<nbOfTuple;i++)
5256             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
5257         }
5258       else
5259         throw INTERP_KERNEL::Exception(msg);
5260     }
5261   else if(nbOfTuple2==1)
5262     {
5263       if(nbOfComp2==nbOfComp)
5264         {
5265           double *ptr=getPointer();
5266           const double *ptrc=other->getConstPointer();
5267           for(int i=0;i<nbOfTuple;i++)
5268             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
5269         }
5270       else
5271         throw INTERP_KERNEL::Exception(msg);
5272     }
5273   else
5274     throw INTERP_KERNEL::Exception(msg);
5275   declareAsNew();
5276 }
5277
5278 /*!
5279  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
5280  * valid cases.
5281  * 1.  The arrays have same number of tuples and components. Then each value of
5282  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
5283  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
5284  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5285  *   component. Then
5286  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
5287  * 3.  The arrays have same number of components and one array, say _a2_, has one
5288  *   tuple. Then
5289  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
5290  *
5291  * Info on components is copied either from the first array (in the first case) or from
5292  * the array with maximal number of elements (getNbOfElems()).
5293  *  \param [in] a1 - an array to subtract from.
5294  *  \param [in] a2 - an array to subtract.
5295  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5296  *          The caller is to delete this result array using decrRef() as it is no more
5297  *          needed.
5298  *  \throw If either \a a1 or \a a2 is NULL.
5299  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5300  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5301  *         none of them has number of tuples or components equal to 1.
5302  */
5303 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
5304 {
5305   if(!a1 || !a2)
5306     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
5307   int nbOfTuple1=a1->getNumberOfTuples();
5308   int nbOfTuple2=a2->getNumberOfTuples();
5309   int nbOfComp1=a1->getNumberOfComponents();
5310   int nbOfComp2=a2->getNumberOfComponents();
5311   if(nbOfTuple2==nbOfTuple1)
5312     {
5313       if(nbOfComp1==nbOfComp2)
5314         {
5315           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5316           ret->alloc(nbOfTuple2,nbOfComp1);
5317           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
5318           ret->copyStringInfoFrom(*a1);
5319           return ret.retn();
5320         }
5321       else if(nbOfComp2==1)
5322         {
5323           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5324           ret->alloc(nbOfTuple1,nbOfComp1);
5325           const double *a2Ptr=a2->getConstPointer();
5326           const double *a1Ptr=a1->getConstPointer();
5327           double *res=ret->getPointer();
5328           for(int i=0;i<nbOfTuple1;i++)
5329             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
5330           ret->copyStringInfoFrom(*a1);
5331           return ret.retn();
5332         }
5333       else
5334         {
5335           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5336           return 0;
5337         }
5338     }
5339   else if(nbOfTuple2==1)
5340     {
5341       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5342       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5343       ret->alloc(nbOfTuple1,nbOfComp1);
5344       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5345       double *pt=ret->getPointer();
5346       for(int i=0;i<nbOfTuple1;i++)
5347         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
5348       ret->copyStringInfoFrom(*a1);
5349       return ret.retn();
5350     }
5351   else
5352     {
5353       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
5354       return 0;
5355     }
5356 }
5357
5358 /*!
5359  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
5360  * valid cases.
5361  * 1.  The arrays have same number of tuples and components. Then each value of
5362  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
5363  *   _a_ [ i, j ] -= _other_ [ i, j ].
5364  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5365  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
5366  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5367  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
5368  *
5369  *  \param [in] other - an array to subtract from \a this one.
5370  *  \throw If \a other is NULL.
5371  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5372  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5373  *         \a other has number of both tuples and components not equal to 1.
5374  */
5375 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
5376 {
5377   if(!other)
5378     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
5379   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
5380   checkAllocated();
5381   other->checkAllocated();
5382   int nbOfTuple=getNumberOfTuples();
5383   int nbOfTuple2=other->getNumberOfTuples();
5384   int nbOfComp=getNumberOfComponents();
5385   int nbOfComp2=other->getNumberOfComponents();
5386   if(nbOfTuple==nbOfTuple2)
5387     {
5388       if(nbOfComp==nbOfComp2)
5389         {
5390           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5391         }
5392       else if(nbOfComp2==1)
5393         {
5394           double *ptr=getPointer();
5395           const double *ptrc=other->getConstPointer();
5396           for(int i=0;i<nbOfTuple;i++)
5397             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5398         }
5399       else
5400         throw INTERP_KERNEL::Exception(msg);
5401     }
5402   else if(nbOfTuple2==1)
5403     {
5404       if(nbOfComp2==nbOfComp)
5405         {
5406           double *ptr=getPointer();
5407           const double *ptrc=other->getConstPointer();
5408           for(int i=0;i<nbOfTuple;i++)
5409             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5410         }
5411       else
5412         throw INTERP_KERNEL::Exception(msg);
5413     }
5414   else
5415     throw INTERP_KERNEL::Exception(msg);
5416   declareAsNew();
5417 }
5418
5419 /*!
5420  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5421  * valid cases.
5422  * 1.  The arrays have same number of tuples and components. Then each value of
5423  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5424  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5425  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5426  *   component. Then
5427  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5428  * 3.  The arrays have same number of components and one array, say _a2_, has one
5429  *   tuple. Then
5430  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5431  *
5432  * Info on components is copied either from the first array (in the first case) or from
5433  * the array with maximal number of elements (getNbOfElems()).
5434  *  \param [in] a1 - a factor array.
5435  *  \param [in] a2 - another factor array.
5436  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5437  *          The caller is to delete this result array using decrRef() as it is no more
5438  *          needed.
5439  *  \throw If either \a a1 or \a a2 is NULL.
5440  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5441  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5442  *         none of them has number of tuples or components equal to 1.
5443  */
5444 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
5445 {
5446   if(!a1 || !a2)
5447     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5448   int nbOfTuple=a1->getNumberOfTuples();
5449   int nbOfTuple2=a2->getNumberOfTuples();
5450   int nbOfComp=a1->getNumberOfComponents();
5451   int nbOfComp2=a2->getNumberOfComponents();
5452   MCAuto<DataArrayDouble> ret=0;
5453   if(nbOfTuple==nbOfTuple2)
5454     {
5455       if(nbOfComp==nbOfComp2)
5456         {
5457           ret=DataArrayDouble::New();
5458           ret->alloc(nbOfTuple,nbOfComp);
5459           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5460           ret->copyStringInfoFrom(*a1);
5461         }
5462       else
5463         {
5464           int nbOfCompMin,nbOfCompMax;
5465           const DataArrayDouble *aMin, *aMax;
5466           if(nbOfComp>nbOfComp2)
5467             {
5468               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5469               aMin=a2; aMax=a1;
5470             }
5471           else
5472             {
5473               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5474               aMin=a1; aMax=a2;
5475             }
5476           if(nbOfCompMin==1)
5477             {
5478               ret=DataArrayDouble::New();
5479               ret->alloc(nbOfTuple,nbOfCompMax);
5480               const double *aMinPtr=aMin->getConstPointer();
5481               const double *aMaxPtr=aMax->getConstPointer();
5482               double *res=ret->getPointer();
5483               for(int i=0;i<nbOfTuple;i++)
5484                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5485               ret->copyStringInfoFrom(*aMax);
5486             }
5487           else
5488             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5489         }
5490     }
5491   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5492     {
5493       if(nbOfComp==nbOfComp2)
5494         {
5495           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5496           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5497           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5498           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5499           ret=DataArrayDouble::New();
5500           ret->alloc(nbOfTupleMax,nbOfComp);
5501           double *res=ret->getPointer();
5502           for(int i=0;i<nbOfTupleMax;i++)
5503             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5504           ret->copyStringInfoFrom(*aMax);
5505         }
5506       else
5507         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5508     }
5509   else
5510     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5511   return ret.retn();
5512 }
5513
5514 /*!
5515  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5516  * valid cases.
5517  * 1.  The arrays have same number of tuples and components. Then each value of
5518  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5519  *   _this_ [ i, j ] *= _other_ [ i, j ].
5520  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5521  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5522  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5523  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5524  *
5525  *  \param [in] other - an array to multiply to \a this one.
5526  *  \throw If \a other is NULL.
5527  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5528  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5529  *         \a other has number of both tuples and components not equal to 1.
5530  */
5531 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
5532 {
5533   if(!other)
5534     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5535   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5536   checkAllocated();
5537   other->checkAllocated();
5538   int nbOfTuple=getNumberOfTuples();
5539   int nbOfTuple2=other->getNumberOfTuples();
5540   int nbOfComp=getNumberOfComponents();
5541   int nbOfComp2=other->getNumberOfComponents();
5542   if(nbOfTuple==nbOfTuple2)
5543     {
5544       if(nbOfComp==nbOfComp2)
5545         {
5546           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5547         }
5548       else if(nbOfComp2==1)
5549         {
5550           double *ptr=getPointer();
5551           const double *ptrc=other->getConstPointer();
5552           for(int i=0;i<nbOfTuple;i++)
5553             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5554         }
5555       else
5556         throw INTERP_KERNEL::Exception(msg);
5557     }
5558   else if(nbOfTuple2==1)
5559     {
5560       if(nbOfComp2==nbOfComp)
5561         {
5562           double *ptr=getPointer();
5563           const double *ptrc=other->getConstPointer();
5564           for(int i=0;i<nbOfTuple;i++)
5565             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5566         }
5567       else
5568         throw INTERP_KERNEL::Exception(msg);
5569     }
5570   else
5571     throw INTERP_KERNEL::Exception(msg);
5572   declareAsNew();
5573 }
5574
5575 /*!
5576  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5577  * valid cases.
5578  * 1.  The arrays have same number of tuples and components. Then each value of
5579  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5580  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5581  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5582  *   component. Then
5583  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5584  * 3.  The arrays have same number of components and one array, say _a2_, has one
5585  *   tuple. Then
5586  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5587  *
5588  * Info on components is copied either from the first array (in the first case) or from
5589  * the array with maximal number of elements (getNbOfElems()).
5590  *  \warning No check of division by zero is performed!
5591  *  \param [in] a1 - a numerator array.
5592  *  \param [in] a2 - a denominator array.
5593  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5594  *          The caller is to delete this result array using decrRef() as it is no more
5595  *          needed.
5596  *  \throw If either \a a1 or \a a2 is NULL.
5597  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5598  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5599  *         none of them has number of tuples or components equal to 1.
5600  */
5601 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
5602 {
5603   if(!a1 || !a2)
5604     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5605   int nbOfTuple1=a1->getNumberOfTuples();
5606   int nbOfTuple2=a2->getNumberOfTuples();
5607   int nbOfComp1=a1->getNumberOfComponents();
5608   int nbOfComp2=a2->getNumberOfComponents();
5609   if(nbOfTuple2==nbOfTuple1)
5610     {
5611       if(nbOfComp1==nbOfComp2)
5612         {
5613           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5614           ret->alloc(nbOfTuple2,nbOfComp1);
5615           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5616           ret->copyStringInfoFrom(*a1);
5617           return ret.retn();
5618         }
5619       else if(nbOfComp2==1)
5620         {
5621           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5622           ret->alloc(nbOfTuple1,nbOfComp1);
5623           const double *a2Ptr=a2->getConstPointer();
5624           const double *a1Ptr=a1->getConstPointer();
5625           double *res=ret->getPointer();
5626           for(int i=0;i<nbOfTuple1;i++)
5627             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5628           ret->copyStringInfoFrom(*a1);
5629           return ret.retn();
5630         }
5631       else
5632         {
5633           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5634           return 0;
5635         }
5636     }
5637   else if(nbOfTuple2==1)
5638     {
5639       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5640       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
5641       ret->alloc(nbOfTuple1,nbOfComp1);
5642       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5643       double *pt=ret->getPointer();
5644       for(int i=0;i<nbOfTuple1;i++)
5645         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5646       ret->copyStringInfoFrom(*a1);
5647       return ret.retn();
5648     }
5649   else
5650     {
5651       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5652       return 0;
5653     }
5654 }
5655
5656 /*!
5657  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5658  * valid cases.
5659  * 1.  The arrays have same number of tuples and components. Then each value of
5660  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5661  *   _a_ [ i, j ] /= _other_ [ i, j ].
5662  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5663  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5664  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5665  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5666  *
5667  *  \warning No check of division by zero is performed!
5668  *  \param [in] other - an array to divide \a this one by.
5669  *  \throw If \a other is NULL.
5670  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5671  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5672  *         \a other has number of both tuples and components not equal to 1.
5673  */
5674 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
5675 {
5676   if(!other)
5677     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5678   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5679   checkAllocated();
5680   other->checkAllocated();
5681   int nbOfTuple=getNumberOfTuples();
5682   int nbOfTuple2=other->getNumberOfTuples();
5683   int nbOfComp=getNumberOfComponents();
5684   int nbOfComp2=other->getNumberOfComponents();
5685   if(nbOfTuple==nbOfTuple2)
5686     {
5687       if(nbOfComp==nbOfComp2)
5688         {
5689           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5690         }
5691       else if(nbOfComp2==1)
5692         {
5693           double *ptr=getPointer();
5694           const double *ptrc=other->getConstPointer();
5695           for(int i=0;i<nbOfTuple;i++)
5696             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5697         }
5698       else
5699         throw INTERP_KERNEL::Exception(msg);
5700     }
5701   else if(nbOfTuple2==1)
5702     {
5703       if(nbOfComp2==nbOfComp)
5704         {
5705           double *ptr=getPointer();
5706           const double *ptrc=other->getConstPointer();
5707           for(int i=0;i<nbOfTuple;i++)
5708             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5709         }
5710       else
5711         throw INTERP_KERNEL::Exception(msg);
5712     }
5713   else
5714     throw INTERP_KERNEL::Exception(msg);
5715   declareAsNew();
5716 }
5717
5718 /*!
5719  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5720  * valid cases.
5721  *
5722  *  \param [in] a1 - an array to pow up.
5723  *  \param [in] a2 - another array to sum up.
5724  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5725  *          The caller is to delete this result array using decrRef() as it is no more
5726  *          needed.
5727  *  \throw If either \a a1 or \a a2 is NULL.
5728  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5729  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5730  *  \throw If there is a negative value in \a a1.
5731  */
5732 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
5733 {
5734   if(!a1 || !a2)
5735     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5736   int nbOfTuple=a1->getNumberOfTuples();
5737   int nbOfTuple2=a2->getNumberOfTuples();
5738   int nbOfComp=a1->getNumberOfComponents();
5739   int nbOfComp2=a2->getNumberOfComponents();
5740   if(nbOfTuple!=nbOfTuple2)
5741     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5742   if(nbOfComp!=1 || nbOfComp2!=1)
5743     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5744   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5745   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5746   double *ptr=ret->getPointer();
5747   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5748     {
5749       if(*ptr1>=0)
5750         {
5751           *ptr=pow(*ptr1,*ptr2);
5752         }
5753       else
5754         {
5755           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5756           throw INTERP_KERNEL::Exception(oss.str().c_str());
5757         }
5758     }
5759   return ret.retn();
5760 }
5761
5762 /*!
5763  * Apply pow on values of another DataArrayDouble to values of \a this one.
5764  *
5765  *  \param [in] other - an array to pow to \a this one.
5766  *  \throw If \a other is NULL.
5767  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5768  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5769  *  \throw If there is a negative value in \a this.
5770  */
5771 void DataArrayDouble::powEqual(const DataArrayDouble *other)
5772 {
5773   if(!other)
5774     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5775   int nbOfTuple=getNumberOfTuples();
5776   int nbOfTuple2=other->getNumberOfTuples();
5777   int nbOfComp=getNumberOfComponents();
5778   int nbOfComp2=other->getNumberOfComponents();
5779   if(nbOfTuple!=nbOfTuple2)
5780     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5781   if(nbOfComp!=1 || nbOfComp2!=1)
5782     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5783   double *ptr=getPointer();
5784   const double *ptrc=other->begin();
5785   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5786     {
5787       if(*ptr>=0)
5788         *ptr=pow(*ptr,*ptrc);
5789       else
5790         {
5791           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5792           throw INTERP_KERNEL::Exception(oss.str().c_str());
5793         }
5794     }
5795   declareAsNew();
5796 }
5797
5798 /*!
5799  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
5800  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
5801  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
5802  *
5803  * \throw if \a this is not allocated.
5804  * \throw if \a this has not exactly one component.
5805  */
5806 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
5807 {
5808   checkAllocated();
5809   if(getNumberOfComponents()!=1)
5810     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
5811   int nbt(getNumberOfTuples());
5812   std::vector<bool> ret(nbt);
5813   const double *pt(begin());
5814   for(int i=0;i<nbt;i++)
5815     {
5816       if(fabs(pt[i])<eps)
5817         ret[i]=false;
5818       else if(fabs(pt[i]-1.)<eps)
5819         ret[i]=true;
5820       else
5821         {
5822           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
5823           throw INTERP_KERNEL::Exception(oss.str().c_str());
5824         }
5825     }
5826   return ret;
5827 }
5828
5829 /*!
5830  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5831  * Server side.
5832  */
5833 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5834 {
5835   tinyInfo.resize(2);
5836   if(isAllocated())
5837     {
5838       tinyInfo[0]=getNumberOfTuples();
5839       tinyInfo[1]=getNumberOfComponents();
5840     }
5841   else
5842     {
5843       tinyInfo[0]=-1;
5844       tinyInfo[1]=-1;
5845     }
5846 }
5847
5848 /*!
5849  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5850  * Server side.
5851  */
5852 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5853 {
5854   if(isAllocated())
5855     {
5856       int nbOfCompo=getNumberOfComponents();
5857       tinyInfo.resize(nbOfCompo+1);
5858       tinyInfo[0]=getName();
5859       for(int i=0;i<nbOfCompo;i++)
5860         tinyInfo[i+1]=getInfoOnComponent(i);
5861     }
5862   else
5863     {
5864       tinyInfo.resize(1);
5865       tinyInfo[0]=getName();
5866     }
5867 }
5868
5869 /*!
5870  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5871  * This method returns if a feeding is needed.
5872  */
5873 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5874 {
5875   int nbOfTuple=tinyInfoI[0];
5876   int nbOfComp=tinyInfoI[1];
5877   if(nbOfTuple!=-1 || nbOfComp!=-1)
5878     {
5879       alloc(nbOfTuple,nbOfComp);
5880       return true;
5881     }
5882   return false;
5883 }
5884
5885 /*!
5886  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5887  */
5888 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5889 {
5890   setName(tinyInfoS[0]);
5891   if(isAllocated())
5892     {
5893       int nbOfCompo=getNumberOfComponents();
5894       for(int i=0;i<nbOfCompo;i++)
5895         setInfoOnComponent(i,tinyInfoS[i+1]);
5896     }
5897 }
5898
5899 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5900 {
5901   if(_da)
5902     {
5903       _da->incrRef();
5904       if(_da->isAllocated())
5905         {
5906           _nb_comp=da->getNumberOfComponents();
5907           _nb_tuple=da->getNumberOfTuples();
5908           _pt=da->getPointer();
5909         }
5910     }
5911 }
5912
5913 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5914 {
5915   if(_da)
5916     _da->decrRef();
5917 }
5918
5919 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
5920 {
5921   if(_tuple_id<_nb_tuple)
5922     {
5923       _tuple_id++;
5924       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5925       _pt+=_nb_comp;
5926       return ret;
5927     }
5928   else
5929     return 0;
5930 }
5931
5932 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5933 {
5934 }
5935
5936
5937 std::string DataArrayDoubleTuple::repr() const
5938 {
5939   std::ostringstream oss; oss.precision(17); oss << "(";
5940   for(int i=0;i<_nb_of_compo-1;i++)
5941     oss << _pt[i] << ", ";
5942   oss << _pt[_nb_of_compo-1] << ")";
5943   return oss.str();
5944 }
5945
5946 double DataArrayDoubleTuple::doubleValue() const
5947 {
5948   if(_nb_of_compo==1)
5949     return *_pt;
5950   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5951 }
5952
5953 /*!
5954  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
5955  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
5956  * 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
5957  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5958  */
5959 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
5960 {
5961   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5962     {
5963       DataArrayDouble *ret=DataArrayDouble::New();
5964       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5965       return ret;
5966     }
5967   else
5968     {
5969       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5970       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5971       throw INTERP_KERNEL::Exception(oss.str().c_str());
5972     }
5973 }
5974
5975 /*!
5976  * Returns a new instance of DataArrayInt. The caller is to delete this array
5977  * using decrRef() as it is no more needed. 
5978  */
5979 DataArrayInt *DataArrayInt::New()
5980 {
5981   return new DataArrayInt;
5982 }
5983
5984 /*!
5985  * Checks if raw data is allocated. Read more on the raw data
5986  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5987  *  \return bool - \a true if the raw data is allocated, \a false else.
5988  */
5989 bool DataArrayInt::isAllocated() const
5990 {
5991   return getConstPointer()!=0;
5992 }
5993
5994 /*!
5995  * Checks if raw data is allocated and throws an exception if it is not the case.
5996  *  \throw If the raw data is not allocated.
5997  */
5998 void DataArrayInt::checkAllocated() const
5999 {
6000   if(!isAllocated())
6001     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
6002 }
6003
6004 /*!
6005  * This method desallocated \a this without modification of informations relative to the components.
6006  * After call of this method, DataArrayInt::isAllocated will return false.
6007  * If \a this is already not allocated, \a this is let unchanged.
6008  */
6009 void DataArrayInt::desallocate()
6010 {
6011   _mem.destroy();
6012 }
6013
6014 std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
6015 {
6016   std::size_t sz(_mem.getNbOfElemAllocated());
6017   sz*=sizeof(int);
6018   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
6019 }
6020
6021 /*!
6022  * Returns the only one value in \a this, if and only if number of elements
6023  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
6024  *  \return double - the sole value stored in \a this array.
6025  *  \throw If at least one of conditions stated above is not fulfilled.
6026  */
6027 int DataArrayInt::intValue() const
6028 {
6029   if(isAllocated())
6030     {
6031       if(getNbOfElems()==1)
6032         {
6033           return *getConstPointer();
6034         }
6035       else
6036         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
6037     }
6038   else
6039     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
6040 }
6041
6042 /*!
6043  * Returns an integer value characterizing \a this array, which is useful for a quick
6044  * comparison of many instances of DataArrayInt.
6045  *  \return int - the hash value.
6046  *  \throw If \a this is not allocated.
6047  */
6048 int DataArrayInt::getHashCode() const
6049 {
6050   checkAllocated();
6051   std::size_t nbOfElems=getNbOfElems();
6052   int ret=nbOfElems*65536;
6053   int delta=3;
6054   if(nbOfElems>48)
6055     delta=nbOfElems/8;
6056   int ret0=0;
6057   const int *pt=begin();
6058   for(std::size_t i=0;i<nbOfElems;i+=delta)
6059     ret0+=pt[i] & 0x1FFF;
6060   return ret+ret0;
6061 }
6062
6063 /*!
6064  * Checks the number of tuples.
6065  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
6066  *  \throw If \a this is not allocated.
6067  */
6068 bool DataArrayInt::empty() const
6069 {
6070   checkAllocated();
6071   return getNumberOfTuples()==0;
6072 }
6073
6074 /*!
6075  * Returns a full copy of \a this. For more info on copying data arrays see
6076  * \ref MEDCouplingArrayBasicsCopyDeep.
6077  *  \return DataArrayInt * - a new instance of DataArrayInt.
6078  */
6079 DataArrayInt *DataArrayInt::deepCopy() const
6080 {
6081   return new DataArrayInt(*this);
6082 }
6083
6084 /*!
6085  * Returns either a \a deep or \a shallow copy of this array. For more info see
6086  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
6087  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
6088  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
6089  *          == \a true) or \a this instance (if \a dCpy == \a false).
6090  */
6091 DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
6092 {
6093   if(dCpy)
6094     return deepCopy();
6095   else
6096     {
6097       incrRef();
6098       return const_cast<DataArrayInt *>(this);
6099     }
6100 }
6101
6102 /*!
6103  * Copies all the data from another DataArrayInt. For more info see
6104  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
6105  *  \param [in] other - another instance of DataArrayInt to copy data from.
6106  *  \throw If the \a other is not allocated.
6107  */
6108 void DataArrayInt::deepCopyFrom(const DataArrayInt& other)
6109 {
6110   other.checkAllocated();
6111   int nbOfTuples=other.getNumberOfTuples();
6112   int nbOfComp=other.getNumberOfComponents();
6113   allocIfNecessary(nbOfTuples,nbOfComp);
6114   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
6115   int *pt=getPointer();
6116   const int *ptI=other.getConstPointer();
6117   for(std::size_t i=0;i<nbOfElems;i++)
6118     pt[i]=ptI[i];
6119   copyStringInfoFrom(other);
6120 }
6121
6122 /*!
6123  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
6124  * 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.
6125  * If \a this has not already been allocated, number of components is set to one.
6126  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
6127  * 
6128  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
6129  */
6130 void DataArrayInt::reserve(std::size_t nbOfElems)
6131 {
6132   int nbCompo=getNumberOfComponents();
6133   if(nbCompo==1)
6134     {
6135       _mem.reserve(nbOfElems);
6136     }
6137   else if(nbCompo==0)
6138     {
6139       _mem.reserve(nbOfElems);
6140       _info_on_compo.resize(1);
6141     }
6142   else
6143     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
6144 }
6145
6146 /*!
6147  * 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
6148  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
6149  *
6150  * \param [in] val the value to be added in \a this
6151  * \throw If \a this has already been allocated with number of components different from one.
6152  * \sa DataArrayInt::pushBackValsSilent
6153  */
6154 void DataArrayInt::pushBackSilent(int val)
6155 {
6156   int nbCompo=getNumberOfComponents();
6157   if(nbCompo==1)
6158     _mem.pushBack(val);
6159   else if(nbCompo==0)
6160     {
6161       _info_on_compo.resize(1);
6162       _mem.pushBack(val);
6163     }
6164   else
6165     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
6166 }
6167
6168 /*!
6169  * 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
6170  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
6171  *
6172  *  \param [in] valsBg - an array of values to push at the end of \c this.
6173  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6174  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6175  * \throw If \a this has already been allocated with number of components different from one.
6176  * \sa DataArrayInt::pushBackSilent
6177  */
6178 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd)
6179 {
6180   int nbCompo=getNumberOfComponents();
6181   if(nbCompo==1)
6182     _mem.insertAtTheEnd(valsBg,valsEnd);
6183   else if(nbCompo==0)
6184     {
6185       _info_on_compo.resize(1);
6186       _mem.insertAtTheEnd(valsBg,valsEnd);
6187     }
6188   else
6189     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
6190 }
6191
6192 /*!
6193  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
6194  * \throw If \a this is already empty.
6195  * \throw If \a this has number of components different from one.
6196  */
6197 int DataArrayInt::popBackSilent()
6198 {
6199   if(getNumberOfComponents()==1)
6200     return _mem.popBack();
6201   else
6202     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
6203 }
6204
6205 /*!
6206  * 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.
6207  *
6208  * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
6209  */
6210 void DataArrayInt::pack() const
6211 {
6212   _mem.pack();
6213 }
6214
6215 /*!
6216  * Allocates the raw data in memory. If exactly as same memory as needed already
6217  * allocated, it is not re-allocated.
6218  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6219  *  \param [in] nbOfCompo - number of components of data to allocate.
6220  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6221  */
6222 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
6223 {
6224   if(isAllocated())
6225     {
6226       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
6227         alloc(nbOfTuple,nbOfCompo);
6228     }
6229   else
6230     alloc(nbOfTuple,nbOfCompo);
6231 }
6232
6233 /*!
6234  * Allocates the raw data in memory. If the memory was already allocated, then it is
6235  * freed and re-allocated. See an example of this method use
6236  * \ref MEDCouplingArraySteps1WC "here".
6237  *  \param [in] nbOfTuple - number of tuples of data to allocate.
6238  *  \param [in] nbOfCompo - number of components of data to allocate.
6239  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
6240  */
6241 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
6242 {
6243   if(nbOfTuple<0 || nbOfCompo<0)
6244     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
6245   _info_on_compo.resize(nbOfCompo);
6246   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
6247   declareAsNew();
6248 }
6249
6250 /*!
6251  * Assign zero to all values in \a this array. To know more on filling arrays see
6252  * \ref MEDCouplingArrayFill.
6253  * \throw If \a this is not allocated.
6254  */
6255 void DataArrayInt::fillWithZero()
6256 {
6257   checkAllocated();
6258   _mem.fillWithValue(0);
6259   declareAsNew();
6260 }
6261
6262 /*!
6263  * Assign \a val to all values in \a this array. To know more on filling arrays see
6264  * \ref MEDCouplingArrayFill.
6265  *  \param [in] val - the value to fill with.
6266  *  \throw If \a this is not allocated.
6267  */
6268 void DataArrayInt::fillWithValue(int val)
6269 {
6270   checkAllocated();
6271   _mem.fillWithValue(val);
6272   declareAsNew();
6273 }
6274
6275 /*!
6276  * Set all values in \a this array so that the i-th element equals to \a init + i
6277  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
6278  *  \param [in] init - value to assign to the first element of array.
6279  *  \throw If \a this->getNumberOfComponents() != 1
6280  *  \throw If \a this is not allocated.
6281  */
6282 void DataArrayInt::iota(int init)
6283 {
6284   checkAllocated();
6285   if(getNumberOfComponents()!=1)
6286     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
6287   int *ptr=getPointer();
6288   int ntuples=getNumberOfTuples();
6289   for(int i=0;i<ntuples;i++)
6290     ptr[i]=init+i;
6291   declareAsNew();
6292 }
6293
6294 /*!
6295  * Returns a textual and human readable representation of \a this instance of
6296  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
6297  * \return std::string - text describing \a this DataArrayInt.
6298  * 
6299  * \sa reprNotTooLong, reprZip
6300  */
6301 std::string DataArrayInt::repr() const
6302 {
6303   std::ostringstream ret;
6304   reprStream(ret);
6305   return ret.str();
6306 }
6307
6308 std::string DataArrayInt::reprZip() const
6309 {
6310   std::ostringstream ret;
6311   reprZipStream(ret);
6312   return ret.str();
6313 }
6314
6315 /*!
6316  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
6317  * printed out to avoid to consume too much space in interpretor.
6318  * \sa repr
6319  */
6320 std::string DataArrayInt::reprNotTooLong() const
6321 {
6322   std::ostringstream ret;
6323   reprNotTooLongStream(ret);
6324   return ret.str();
6325 }
6326
6327 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
6328 {
6329   static const char SPACE[4]={' ',' ',' ',' '};
6330   checkAllocated();
6331   std::string idt(indent,' ');
6332   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
6333   if(byteArr)
6334     {
6335       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
6336       if(std::string(type)=="Int32")
6337         {
6338           const char *data(reinterpret_cast<const char *>(begin()));
6339           std::size_t sz(getNbOfElems()*sizeof(int));
6340           byteArr->insertAtTheEnd(data,data+sz);
6341           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6342         }
6343       else if(std::string(type)=="Int8")
6344         {
6345           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
6346           std::copy(begin(),end(),(char *)tmp);
6347           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
6348           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6349         }
6350       else if(std::string(type)=="UInt8")
6351         {
6352           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
6353           std::copy(begin(),end(),(unsigned char *)tmp);
6354           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
6355           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6356         }
6357       else
6358         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
6359     }
6360   else
6361     {
6362       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
6363       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
6364     }
6365   ofs << std::endl << idt << "</DataArray>\n";
6366 }
6367
6368 void DataArrayInt::reprStream(std::ostream& stream) const
6369 {
6370   stream << "Name of int array : \"" << _name << "\"\n";
6371   reprWithoutNameStream(stream);
6372 }
6373
6374 void DataArrayInt::reprZipStream(std::ostream& stream) const
6375 {
6376   stream << "Name of int array : \"" << _name << "\"\n";
6377   reprZipWithoutNameStream(stream);
6378 }
6379
6380 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
6381 {
6382   stream << "Name of int array : \"" << _name << "\"\n";
6383   reprNotTooLongWithoutNameStream(stream);
6384 }
6385
6386 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
6387 {
6388   DataArray::reprWithoutNameStream(stream);
6389   _mem.repr(getNumberOfComponents(),stream);
6390 }
6391
6392 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
6393 {
6394   DataArray::reprWithoutNameStream(stream);
6395   _mem.reprZip(getNumberOfComponents(),stream);
6396 }
6397
6398 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
6399 {
6400   DataArray::reprWithoutNameStream(stream);
6401   stream.precision(17);
6402   _mem.reprNotTooLong(getNumberOfComponents(),stream);
6403 }
6404
6405 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
6406 {
6407   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
6408   const int *data=getConstPointer();
6409   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
6410   if(nbTuples*nbComp>=1)
6411     {
6412       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
6413       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
6414       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
6415       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
6416     }
6417   else
6418     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
6419   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
6420 }
6421
6422 /*!
6423  * Method that gives a quick overvien of \a this for python.
6424  */
6425 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
6426 {
6427   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6428   stream << "DataArrayInt C++ instance at " << this << ". ";
6429   if(isAllocated())
6430     {
6431       int nbOfCompo=(int)_info_on_compo.size();
6432       if(nbOfCompo>=1)
6433         {
6434           int nbOfTuples=getNumberOfTuples();
6435           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6436           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6437         }
6438       else
6439         stream << "Number of components : 0.";
6440     }
6441   else
6442     stream << "*** No data allocated ****";
6443 }
6444
6445 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
6446 {
6447   const int *data=begin();
6448   int nbOfTuples=getNumberOfTuples();
6449   int nbOfCompo=(int)_info_on_compo.size();
6450   std::ostringstream oss2; oss2 << "[";
6451   std::string oss2Str(oss2.str());
6452   bool isFinished=true;
6453   for(int i=0;i<nbOfTuples && isFinished;i++)
6454     {
6455       if(nbOfCompo>1)
6456         {
6457           oss2 << "(";
6458           for(int j=0;j<nbOfCompo;j++,data++)
6459             {
6460               oss2 << *data;
6461               if(j!=nbOfCompo-1) oss2 << ", ";
6462             }
6463           oss2 << ")";
6464         }
6465       else
6466         oss2 << *data++;
6467       if(i!=nbOfTuples-1) oss2 << ", ";
6468       std::string oss3Str(oss2.str());
6469       if(oss3Str.length()<maxNbOfByteInRepr)
6470         oss2Str=oss3Str;
6471       else
6472         isFinished=false;
6473     }
6474   stream << oss2Str;
6475   if(!isFinished)
6476     stream << "... ";
6477   stream << "]";
6478 }
6479
6480 /*!
6481  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6482  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6483  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6484  *         to \a this array.
6485  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6486  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6487  *  \throw If \a this->getNumberOfComponents() != 1
6488  *  \throw If any value of \a this can't be used as a valid index for 
6489  *         [\a indArrBg, \a indArrEnd).
6490  *
6491  *  \sa changeValue
6492  */
6493 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
6494 {
6495   checkAllocated();
6496   if(getNumberOfComponents()!=1)
6497     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6498   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
6499   for(int i=0;i<nbOfTuples;i++,pt++)
6500     {
6501       if(*pt>=0 && *pt<nbElemsIn)
6502         *pt=indArrBg[*pt];
6503       else
6504         {
6505           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6506           throw INTERP_KERNEL::Exception(oss.str().c_str());
6507         }
6508     }
6509   declareAsNew();
6510 }
6511
6512 /*!
6513  * Computes distribution of values of \a this one-dimensional array between given value
6514  * ranges (casts). This method is typically useful for entity number spliting by types,
6515  * for example. 
6516  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6517  *           check of this is be done. If not, the result is not warranted. 
6518  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6519  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6520  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6521  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6522  *         should be more than every value in \a this array.
6523  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6524  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6525  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6526  *         (same number of tuples and components), the caller is to delete 
6527  *         using decrRef() as it is no more needed.
6528  *         This array contains indices of ranges for every value of \a this array. I.e.
6529  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6530  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6531  *         this in which cast it holds.
6532  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6533  *         array, the caller is to delete using decrRef() as it is no more needed.
6534  *         This array contains ranks of values of \a this array within ranges
6535  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6536  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6537  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6538  *         for each tuple its rank inside its cast. The rank is computed as difference
6539  *         between the value and the lowest value of range.
6540  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6541  *         ranges (casts) to which at least one value of \a this array belongs.
6542  *         Or, in other words, this param contains the casts that \a this contains.
6543  *         The caller is to delete this array using decrRef() as it is no more needed.
6544  *
6545  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6546  *            the output of this method will be : 
6547  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6548  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6549  * - \a castsPresent  : [0,1]
6550  *
6551  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6552  * range #1 and its rank within this range is 2; etc.
6553  *
6554  *  \throw If \a this->getNumberOfComponents() != 1.
6555  *  \throw If \a arrEnd - arrBg < 2.
6556  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6557  */
6558 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6559                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
6560 {
6561   checkAllocated();
6562   if(getNumberOfComponents()!=1)
6563     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6564   int nbOfTuples=getNumberOfTuples();
6565   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6566   if(nbOfCast<2)
6567     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6568   nbOfCast--;
6569   const int *work=getConstPointer();
6570   typedef std::reverse_iterator<const int *> rintstart;
6571   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6572   rintstart end2(arrBg);
6573   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
6574   MCAuto<DataArrayInt> ret2=DataArrayInt::New();
6575   MCAuto<DataArrayInt> ret3=DataArrayInt::New();
6576   ret1->alloc(nbOfTuples,1);
6577   ret2->alloc(nbOfTuples,1);
6578   int *ret1Ptr=ret1->getPointer();
6579   int *ret2Ptr=ret2->getPointer();
6580   std::set<std::size_t> castsDetected;
6581   for(int i=0;i<nbOfTuples;i++)
6582     {
6583       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6584       std::size_t pos=std::distance(bg,res);
6585       std::size_t pos2=nbOfCast-pos;
6586       if(pos2<nbOfCast)
6587         {
6588           ret1Ptr[i]=(int)pos2;
6589           ret2Ptr[i]=work[i]-arrBg[pos2];
6590           castsDetected.insert(pos2);
6591         }
6592       else
6593         {
6594           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6595           throw INTERP_KERNEL::Exception(oss.str().c_str());
6596         }
6597     }
6598   ret3->alloc((int)castsDetected.size(),1);
6599   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6600   castArr=ret1.retn();
6601   rankInsideCast=ret2.retn();
6602   castsPresent=ret3.retn();
6603 }
6604
6605 /*!
6606  * 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 ).
6607  * 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 ).
6608  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
6609  *
6610  * \param [out] strt - the start of the range (included) if true is returned.
6611  * \param [out] sttoopp - the end of the range (not included) if true is returned.
6612  * \param [out] stteepp - the step of the range if true is returned.
6613  * \return the verdict of the check.
6614  *
6615  * \sa DataArray::GetNumberOfItemGivenBES
6616  */
6617 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
6618 {
6619   checkAllocated();
6620   if(getNumberOfComponents()!=1)
6621     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
6622   int nbTuples(getNumberOfTuples());
6623   if(nbTuples==0)
6624     { strt=0; sttoopp=0; stteepp=1; return true; }
6625   const int *pt(begin());
6626   strt=*pt; 
6627   if(nbTuples==1)
6628     { sttoopp=strt+1; stteepp=1; return true; }
6629   strt=*pt; sttoopp=pt[nbTuples-1];
6630   if(strt==sttoopp)
6631     return false;
6632   if(sttoopp>strt)
6633     {
6634       sttoopp++;
6635       int a(sttoopp-1-strt),tmp(strt);
6636       if(a%(nbTuples-1)!=0)
6637         return false;
6638       stteepp=a/(nbTuples-1);
6639       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
6640         if(pt[i]!=tmp)
6641           return false;
6642       return true;
6643     }
6644   else
6645     {
6646       sttoopp--;
6647       int a(strt-sttoopp-1),tmp(strt);
6648       if(a%(nbTuples-1)!=0)
6649         return false;
6650       stteepp=-(a/(nbTuples-1));
6651       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
6652         if(pt[i]!=tmp)
6653           return false;
6654       return true;
6655     }
6656 }
6657
6658 /*!
6659  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6660  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6661  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6662  * new value in place \a indArr[ \a v ] is i.
6663  *  \param [in] indArrBg - the array holding indices within the result array to assign
6664  *         indices of values of \a this array pointing to values of \a indArrBg.
6665  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6666  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6667  *  \return DataArrayInt * - the new instance of DataArrayInt.
6668  *          The caller is to delete this result array using decrRef() as it is no more
6669  *          needed.
6670  *  \throw If \a this->getNumberOfComponents() != 1.
6671  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6672  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6673  */
6674 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6675 {
6676   checkAllocated();
6677   if(getNumberOfComponents()!=1)
6678     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6679   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6680   int nbOfTuples=getNumberOfTuples();
6681   const int *pt=getConstPointer();
6682   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6683   ret->alloc(nbOfTuples,1);
6684   ret->fillWithValue(-1);
6685   int *tmp=ret->getPointer();
6686   for(int i=0;i<nbOfTuples;i++,pt++)
6687     {
6688       if(*pt>=0 && *pt<nbElemsIn)
6689         {
6690           int pos=indArrBg[*pt];
6691           if(pos>=0 && pos<nbOfTuples)
6692             tmp[pos]=i;
6693           else
6694             {
6695               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6696               throw INTERP_KERNEL::Exception(oss.str().c_str());
6697             }
6698         }
6699       else
6700         {
6701           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6702           throw INTERP_KERNEL::Exception(oss.str().c_str());
6703         }
6704     }
6705   return ret.retn();
6706 }
6707
6708 /*!
6709  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6710  * from values of \a this array, which is supposed to contain a renumbering map in 
6711  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6712  * To know how to use the renumbering maps see \ref numbering.
6713  *  \param [in] newNbOfElem - the number of tuples in the result array.
6714  *  \return DataArrayInt * - the new instance of DataArrayInt.
6715  *          The caller is to delete this result array using decrRef() as it is no more
6716  *          needed.
6717  * 
6718  *  \if ENABLE_EXAMPLES
6719  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6720  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6721  *  \endif
6722  */
6723 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6724 {
6725   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6726   ret->alloc(newNbOfElem,1);
6727   int nbOfOldNodes=getNumberOfTuples();
6728   const int *old2New=getConstPointer();
6729   int *pt=ret->getPointer();
6730   for(int i=0;i!=nbOfOldNodes;i++)
6731     {
6732       int newp(old2New[i]);
6733       if(newp!=-1)
6734         {
6735           if(newp>=0 && newp<newNbOfElem)
6736             pt[newp]=i;
6737           else
6738             {
6739               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6740               throw INTERP_KERNEL::Exception(oss.str().c_str());
6741             }
6742         }
6743     }
6744   return ret.retn();
6745 }
6746
6747 /*!
6748  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6749  * 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]
6750  */
6751 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6752 {
6753   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6754   ret->alloc(newNbOfElem,1);
6755   int nbOfOldNodes=getNumberOfTuples();
6756   const int *old2New=getConstPointer();
6757   int *pt=ret->getPointer();
6758   for(int i=nbOfOldNodes-1;i>=0;i--)
6759     {
6760       int newp(old2New[i]);
6761       if(newp!=-1)
6762         {
6763           if(newp>=0 && newp<newNbOfElem)
6764             pt[newp]=i;
6765           else
6766             {
6767               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6768               throw INTERP_KERNEL::Exception(oss.str().c_str());
6769             }
6770         }
6771     }
6772   return ret.retn();
6773 }
6774
6775 /*!
6776  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6777  * from values of \a this array, which is supposed to contain a renumbering map in 
6778  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6779  * To know how to use the renumbering maps see \ref numbering.
6780  *  \param [in] newNbOfElem - the number of tuples in the result array.
6781  *  \return DataArrayInt * - the new instance of DataArrayInt.
6782  *          The caller is to delete this result array using decrRef() as it is no more
6783  *          needed.
6784  * 
6785  *  \if ENABLE_EXAMPLES
6786  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6787  *
6788  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6789  *  \endif
6790  */
6791 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6792 {
6793   checkAllocated();
6794   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6795   ret->alloc(oldNbOfElem,1);
6796   const int *new2Old=getConstPointer();
6797   int *pt=ret->getPointer();
6798   std::fill(pt,pt+oldNbOfElem,-1);
6799   int nbOfNewElems=getNumberOfTuples();
6800   for(int i=0;i<nbOfNewElems;i++)
6801     {
6802       int v(new2Old[i]);
6803       if(v>=0 && v<oldNbOfElem)
6804         pt[v]=i;
6805       else
6806         {
6807           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6808           throw INTERP_KERNEL::Exception(oss.str().c_str());
6809         }
6810     }
6811   return ret.retn();
6812 }
6813
6814 /*!
6815  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6816  * mismatch is given.
6817  * 
6818  * \param [in] other the instance to be compared with \a this
6819  * \param [out] reason In case of inequality returns the reason.
6820  * \sa DataArrayInt::isEqual
6821  */
6822 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6823 {
6824   if(!areInfoEqualsIfNotWhy(other,reason))
6825     return false;
6826   return _mem.isEqual(other._mem,0,reason);
6827 }
6828
6829 /*!
6830  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6831  * \ref MEDCouplingArrayBasicsCompare.
6832  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6833  *  \return bool - \a true if the two arrays are equal, \a false else.
6834  */
6835 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6836 {
6837   std::string tmp;
6838   return isEqualIfNotWhy(other,tmp);
6839 }
6840
6841 /*!
6842  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6843  * \ref MEDCouplingArrayBasicsCompare.
6844  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6845  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6846  */
6847 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6848 {
6849   std::string tmp;
6850   return _mem.isEqual(other._mem,0,tmp);
6851 }
6852
6853 /*!
6854  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6855  * performed on sorted value sequences.
6856  * For more info see\ref MEDCouplingArrayBasicsCompare.
6857  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6858  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6859  */
6860 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6861 {
6862   MCAuto<DataArrayInt> a=deepCopy();
6863   MCAuto<DataArrayInt> b=other.deepCopy();
6864   a->sort();
6865   b->sort();
6866   return a->isEqualWithoutConsideringStr(*b);
6867 }
6868
6869 /*!
6870  * This method compares content of input vector \a v and \a this.
6871  * 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.
6872  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6873  *
6874  * \param [in] v - the vector of 'flags' to be compared with \a this.
6875  *
6876  * \throw If \a this is not sorted ascendingly.
6877  * \throw If \a this has not exactly one component.
6878  * \throw If \a this is not allocated.
6879  */
6880 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6881 {
6882   checkAllocated();
6883   if(getNumberOfComponents()!=1)
6884     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6885   const int *w(begin()),*end2(end());
6886   int refVal=-std::numeric_limits<int>::max();
6887   int i=0;
6888   std::vector<bool>::const_iterator it(v.begin());
6889   for(;it!=v.end();it++,i++)
6890     {
6891       if(*it)
6892         {
6893           if(w!=end2)
6894             {
6895               if(*w++==i)
6896                 {
6897                   if(i>refVal)
6898                     refVal=i;
6899                   else
6900                     {
6901                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6902                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6903                     }
6904                 }
6905               else
6906                 return false;
6907             }
6908           else
6909             return false;
6910         }
6911     }
6912   return w==end2;
6913 }
6914
6915 /*!
6916  * 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
6917  * put True to the corresponding entry in \a vec.
6918  * \a vec is expected to be with the same size than the number of tuples of \a this.
6919  */
6920 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
6921 {
6922   checkAllocated();
6923   if(getNumberOfComponents()!=1)
6924     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
6925   int nbOfTuples(getNumberOfTuples());
6926   if(nbOfTuples!=(int)vec.size())
6927     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
6928   const int *pt(begin());
6929   for(int i=0;i<nbOfTuples;i++)
6930     if(pt[i]==val)
6931       vec[i]=true;
6932 }
6933
6934 /*!
6935  * Sorts values of the array.
6936  *  \param [in] asc - \a true means ascending order, \a false, descending.
6937  *  \throw If \a this is not allocated.
6938  *  \throw If \a this->getNumberOfComponents() != 1.
6939  */
6940 void DataArrayInt::sort(bool asc)
6941 {
6942   checkAllocated();
6943   if(getNumberOfComponents()!=1)
6944     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6945   _mem.sort(asc);
6946   declareAsNew();
6947 }
6948
6949 /*!
6950  * Computes for each tuple the sum of number of components values in the tuple and return it.
6951  * 
6952  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6953  *          same number of tuples as \a this array and one component.
6954  *          The caller is to delete this result array using decrRef() as it is no more
6955  *          needed.
6956  *  \throw If \a this is not allocated.
6957  */
6958 DataArrayInt *DataArrayInt::sumPerTuple() const
6959 {
6960   checkAllocated();
6961   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6962   MCAuto<DataArrayInt> ret(DataArrayInt::New());
6963   ret->alloc(nbOfTuple,1);
6964   const int *src(getConstPointer());
6965   int *dest(ret->getPointer());
6966   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6967     *dest=std::accumulate(src,src+nbOfComp,0);
6968   return ret.retn();
6969 }
6970
6971 /*!
6972  * Reverse the array values.
6973  *  \throw If \a this->getNumberOfComponents() < 1.
6974  *  \throw If \a this is not allocated.
6975  */
6976 void DataArrayInt::reverse()
6977 {
6978   checkAllocated();
6979   _mem.reverse(getNumberOfComponents());
6980   declareAsNew();
6981 }
6982
6983 /*!
6984  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6985  * If not an exception is thrown.
6986  *  \param [in] increasing - if \a true, the array values should be increasing.
6987  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6988  *         increasing arg.
6989  *  \throw If \a this->getNumberOfComponents() != 1.
6990  *  \throw If \a this is not allocated.
6991  */
6992 void DataArrayInt::checkMonotonic(bool increasing) const
6993 {
6994   if(!isMonotonic(increasing))
6995     {
6996       if (increasing)
6997         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6998       else
6999         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
7000     }
7001 }
7002
7003 /*!
7004  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
7005  *  \param [in] increasing - if \a true, array values should be increasing.
7006  *  \return bool - \a true if values change in accordance with \a increasing arg.
7007  *  \throw If \a this->getNumberOfComponents() != 1.
7008  *  \throw If \a this is not allocated.
7009  */
7010 bool DataArrayInt::isMonotonic(bool increasing) const
7011 {
7012   checkAllocated();
7013   if(getNumberOfComponents()!=1)
7014     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
7015   int nbOfElements=getNumberOfTuples();
7016   const int *ptr=getConstPointer();
7017   if(nbOfElements==0)
7018     return true;
7019   int ref=ptr[0];
7020   if(increasing)
7021     {
7022       for(int i=1;i<nbOfElements;i++)
7023         {
7024           if(ptr[i]>=ref)
7025             ref=ptr[i];
7026           else
7027             return false;
7028         }
7029     }
7030   else
7031     {
7032       for(int i=1;i<nbOfElements;i++)
7033         {
7034           if(ptr[i]<=ref)
7035             ref=ptr[i];
7036           else
7037             return false;
7038         }
7039     }
7040   return true;
7041 }
7042
7043 /*!
7044  * This method check that array consistently INCREASING or DECREASING in value.
7045  */
7046 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
7047 {
7048   checkAllocated();
7049   if(getNumberOfComponents()!=1)
7050     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
7051   int nbOfElements=getNumberOfTuples();
7052   const int *ptr=getConstPointer();
7053   if(nbOfElements==0)
7054     return true;
7055   int ref=ptr[0];
7056   if(increasing)
7057     {
7058       for(int i=1;i<nbOfElements;i++)
7059         {
7060           if(ptr[i]>ref)
7061             ref=ptr[i];
7062           else
7063             return false;
7064         }
7065     }
7066   else
7067     {
7068       for(int i=1;i<nbOfElements;i++)
7069         {
7070           if(ptr[i]<ref)
7071             ref=ptr[i];
7072           else
7073             return false;
7074         }
7075     }
7076   return true;
7077 }
7078
7079 /*!
7080  * This method check that array consistently INCREASING or DECREASING in value.
7081  */
7082 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
7083 {
7084   if(!isStrictlyMonotonic(increasing))
7085     {
7086       if (increasing)
7087         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
7088       else
7089         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
7090     }
7091 }
7092
7093 /*!
7094  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
7095  * one-dimensional arrays that must be of the same length. The result array describes
7096  * correspondence between \a this and \a other arrays, so that 
7097  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
7098  * not possible because some element in \a other is not in \a this, an exception is thrown.
7099  *  \param [in] other - an array to compute permutation to.
7100  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
7101  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
7102  * no more needed.
7103  *  \throw If \a this->getNumberOfComponents() != 1.
7104  *  \throw If \a other->getNumberOfComponents() != 1.
7105  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
7106  *  \throw If \a other includes a value which is not in \a this array.
7107  * 
7108  *  \if ENABLE_EXAMPLES
7109  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
7110  *
7111  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
7112  *  \endif
7113  */
7114 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
7115 {
7116   checkAllocated();
7117   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
7118     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
7119   int nbTuple=getNumberOfTuples();
7120   other.checkAllocated();
7121   if(nbTuple!=other.getNumberOfTuples())
7122     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
7123   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7124   ret->alloc(nbTuple,1);
7125   ret->fillWithValue(-1);
7126   const int *pt=getConstPointer();
7127   std::map<int,int> mm;
7128   for(int i=0;i<nbTuple;i++)
7129     mm[pt[i]]=i;
7130   pt=other.getConstPointer();
7131   int *retToFill=ret->getPointer();
7132   for(int i=0;i<nbTuple;i++)
7133     {
7134       std::map<int,int>::const_iterator it=mm.find(pt[i]);
7135       if(it==mm.end())
7136         {
7137           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
7138           throw INTERP_KERNEL::Exception(oss.str().c_str());
7139         }
7140       retToFill[i]=(*it).second;
7141     }
7142   return ret.retn();
7143 }
7144
7145 /*!
7146  * Sets a C array to be used as raw data of \a this. The previously set info
7147  *  of components is retained and re-sized. 
7148  * For more info see \ref MEDCouplingArraySteps1.
7149  *  \param [in] array - the C array to be used as raw data of \a this.
7150  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
7151  *  \param [in] type - specifies how to deallocate \a array. If \a type == MEDCoupling::CPP_DEALLOC,
7152  *                     \c delete [] \c array; will be called. If \a type == MEDCoupling::C_DEALLOC,
7153  *                     \c free(\c array ) will be called.
7154  *  \param [in] nbOfTuple - new number of tuples in \a this.
7155  *  \param [in] nbOfCompo - new number of components in \a this.
7156  */
7157 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
7158 {
7159   _info_on_compo.resize(nbOfCompo);
7160   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
7161   declareAsNew();
7162 }
7163
7164 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
7165 {
7166   _info_on_compo.resize(nbOfCompo);
7167   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
7168   declareAsNew();
7169 }
7170
7171 void DataArrayInt::aggregate(const DataArrayInt *other)
7172 {
7173   if(!other)
7174     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : null pointer !");
7175   if(getNumberOfComponents()!=other->getNumberOfComponents())
7176     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : mismatch number of components !");
7177   _mem.insertAtTheEnd(other->begin(),other->end());
7178 }
7179
7180 /*!
7181  * Returns a new DataArrayInt holding the same values as \a this array but differently
7182  * arranged in memory. If \a this array holds 2 components of 3 values:
7183  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
7184  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
7185  *  \warning Do not confuse this method with transpose()!
7186  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7187  *          is to delete using decrRef() as it is no more needed.
7188  *  \throw If \a this is not allocated.
7189  */
7190 DataArrayInt *DataArrayInt::fromNoInterlace() const
7191 {
7192   checkAllocated();
7193   if(_mem.isNull())
7194     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
7195   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
7196   DataArrayInt *ret=DataArrayInt::New();
7197   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
7198   return ret;
7199 }
7200
7201 /*!
7202  * Returns a new DataArrayInt holding the same values as \a this array but differently
7203  * arranged in memory. If \a this array holds 2 components of 3 values:
7204  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
7205  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
7206  *  \warning Do not confuse this method with transpose()!
7207  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7208  *          is to delete using decrRef() as it is no more needed.
7209  *  \throw If \a this is not allocated.
7210  */
7211 DataArrayInt *DataArrayInt::toNoInterlace() const
7212 {
7213   checkAllocated();
7214   if(_mem.isNull())
7215     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
7216   int *tab=_mem.toNoInterlace(getNumberOfComponents());
7217   DataArrayInt *ret=DataArrayInt::New();
7218   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
7219   return ret;
7220 }
7221
7222 /*!
7223  * Permutes values of \a this array as required by \a old2New array. The values are
7224  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
7225  * the same as in \c this one.
7226  * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
7227  * For more info on renumbering see \ref numbering.
7228  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7229  *     giving a new position for i-th old value.
7230  */
7231 void DataArrayInt::renumberInPlace(const int *old2New)
7232 {
7233   checkAllocated();
7234   int nbTuples=getNumberOfTuples();
7235   int nbOfCompo=getNumberOfComponents();
7236   int *tmp=new int[nbTuples*nbOfCompo];
7237   const int *iptr=getConstPointer();
7238   for(int i=0;i<nbTuples;i++)
7239     {
7240       int v=old2New[i];
7241       if(v>=0 && v<nbTuples)
7242         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
7243       else
7244         {
7245           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7246           throw INTERP_KERNEL::Exception(oss.str().c_str());
7247         }
7248     }
7249   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7250   delete [] tmp;
7251   declareAsNew();
7252 }
7253
7254 /*!
7255  * Permutes values of \a this array as required by \a new2Old array. The values are
7256  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
7257  * the same as in \c this one.
7258  * For more info on renumbering see \ref numbering.
7259  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7260  *     giving a previous position of i-th new value.
7261  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7262  *          is to delete using decrRef() as it is no more needed.
7263  */
7264 void DataArrayInt::renumberInPlaceR(const int *new2Old)
7265 {
7266   checkAllocated();
7267   int nbTuples=getNumberOfTuples();
7268   int nbOfCompo=getNumberOfComponents();
7269   int *tmp=new int[nbTuples*nbOfCompo];
7270   const int *iptr=getConstPointer();
7271   for(int i=0;i<nbTuples;i++)
7272     {
7273       int v=new2Old[i];
7274       if(v>=0 && v<nbTuples)
7275         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
7276       else
7277         {
7278           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7279           throw INTERP_KERNEL::Exception(oss.str().c_str());
7280         }
7281     }
7282   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7283   delete [] tmp;
7284   declareAsNew();
7285 }
7286
7287 /*!
7288  * Returns a copy of \a this array with values permuted as required by \a old2New array.
7289  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
7290  * Number of tuples in the result array remains the same as in \c this one.
7291  * If a permutation reduction is needed, renumberAndReduce() should be used.
7292  * For more info on renumbering see \ref numbering.
7293  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7294  *          giving a new position for i-th old value.
7295  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7296  *          is to delete using decrRef() as it is no more needed.
7297  *  \throw If \a this is not allocated.
7298  */
7299 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
7300 {
7301   checkAllocated();
7302   int nbTuples=getNumberOfTuples();
7303   int nbOfCompo=getNumberOfComponents();
7304   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7305   ret->alloc(nbTuples,nbOfCompo);
7306   ret->copyStringInfoFrom(*this);
7307   const int *iptr=getConstPointer();
7308   int *optr=ret->getPointer();
7309   for(int i=0;i<nbTuples;i++)
7310     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
7311   ret->copyStringInfoFrom(*this);
7312   return ret.retn();
7313 }
7314
7315 /*!
7316  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
7317  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
7318  * tuples in the result array remains the same as in \c this one.
7319  * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
7320  * For more info on renumbering see \ref numbering.
7321  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7322  *     giving a previous position of i-th new value.
7323  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7324  *          is to delete using decrRef() as it is no more needed.
7325  */
7326 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
7327 {
7328   checkAllocated();
7329   int nbTuples=getNumberOfTuples();
7330   int nbOfCompo=getNumberOfComponents();
7331   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7332   ret->alloc(nbTuples,nbOfCompo);
7333   ret->copyStringInfoFrom(*this);
7334   const int *iptr=getConstPointer();
7335   int *optr=ret->getPointer();
7336   for(int i=0;i<nbTuples;i++)
7337     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
7338   ret->copyStringInfoFrom(*this);
7339   return ret.retn();
7340 }
7341
7342 /*!
7343  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7344  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
7345  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
7346  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
7347  * \a old2New[ i ] is negative, is missing from the result array.
7348  * For more info on renumbering see \ref numbering.
7349  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7350  *     giving a new position for i-th old tuple and giving negative position for
7351  *     for i-th old tuple that should be omitted.
7352  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7353  *          is to delete using decrRef() as it is no more needed.
7354  */
7355 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
7356 {
7357   checkAllocated();
7358   int nbTuples=getNumberOfTuples();
7359   int nbOfCompo=getNumberOfComponents();
7360   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7361   ret->alloc(newNbOfTuple,nbOfCompo);
7362   const int *iptr=getConstPointer();
7363   int *optr=ret->getPointer();
7364   for(int i=0;i<nbTuples;i++)
7365     {
7366       int w=old2New[i];
7367       if(w>=0)
7368         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
7369     }
7370   ret->copyStringInfoFrom(*this);
7371   return ret.retn();
7372 }
7373
7374 /*!
7375  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7376  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7377  * \a new2OldBg array.
7378  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7379  * This method is equivalent to renumberAndReduce() except that convention in input is
7380  * \c new2old and \b not \c old2new.
7381  * For more info on renumbering see \ref numbering.
7382  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7383  *              tuple index in \a this array to fill the i-th tuple in the new array.
7384  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7385  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7386  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7387  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7388  *          is to delete using decrRef() as it is no more needed.
7389  */
7390 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
7391 {
7392   checkAllocated();
7393   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7394   int nbComp=getNumberOfComponents();
7395   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7396   ret->copyStringInfoFrom(*this);
7397   int *pt=ret->getPointer();
7398   const int *srcPt=getConstPointer();
7399   int i=0;
7400   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7401     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7402   ret->copyStringInfoFrom(*this);
7403   return ret.retn();
7404 }
7405
7406 /*!
7407  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7408  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7409  * \a new2OldBg array.
7410  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7411  * This method is equivalent to renumberAndReduce() except that convention in input is
7412  * \c new2old and \b not \c old2new.
7413  * This method is equivalent to selectByTupleId() except that it prevents coping data
7414  * from behind the end of \a this array.
7415  * For more info on renumbering see \ref numbering.
7416  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7417  *              tuple index in \a this array to fill the i-th tuple in the new array.
7418  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7419  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7420  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7421  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7422  *          is to delete using decrRef() as it is no more needed.
7423  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
7424  */
7425 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
7426 {
7427   checkAllocated();
7428   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7429   int nbComp=getNumberOfComponents();
7430   int oldNbOfTuples=getNumberOfTuples();
7431   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7432   ret->copyStringInfoFrom(*this);
7433   int *pt=ret->getPointer();
7434   const int *srcPt=getConstPointer();
7435   int i=0;
7436   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7437     if(*w>=0 && *w<oldNbOfTuples)
7438       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7439     else
7440       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
7441   ret->copyStringInfoFrom(*this);
7442   return ret.retn();
7443 }
7444
7445 /*!
7446  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
7447  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
7448  * tuple. Indices of the selected tuples are the same as ones returned by the Python
7449  * command \c range( \a bg, \a end2, \a step ).
7450  * This method is equivalent to selectByTupleIdSafe() except that the input array is
7451  * not constructed explicitly.
7452  * For more info on renumbering see \ref numbering.
7453  *  \param [in] bg - index of the first tuple to copy from \a this array.
7454  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
7455  *  \param [in] step - index increment to get index of the next tuple to copy.
7456  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7457  *          is to delete using decrRef() as it is no more needed.
7458  *  \sa DataArrayInt::subArray.
7459  */
7460 DataArrayInt *DataArrayInt::selectByTupleIdSafeSlice(int bg, int end2, int step) const
7461 {
7462   checkAllocated();
7463   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7464   int nbComp=getNumberOfComponents();
7465   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleIdSafeSlice : ");
7466   ret->alloc(newNbOfTuples,nbComp);
7467   int *pt=ret->getPointer();
7468   const int *srcPt=getConstPointer()+bg*nbComp;
7469   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
7470     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
7471   ret->copyStringInfoFrom(*this);
7472   return ret.retn();
7473 }
7474
7475 /*!
7476  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
7477  * of tuples specified by \a ranges parameter.
7478  * For more info on renumbering see \ref numbering.
7479  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
7480  *              of tuples in [\c begin,\c end) format.
7481  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7482  *          is to delete using decrRef() as it is no more needed.
7483  *  \throw If \a end < \a begin.
7484  *  \throw If \a end > \a this->getNumberOfTuples().
7485  *  \throw If \a this is not allocated.
7486  */
7487 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
7488 {
7489   checkAllocated();
7490   int nbOfComp=getNumberOfComponents();
7491   int nbOfTuplesThis=getNumberOfTuples();
7492   if(ranges.empty())
7493     {
7494       MCAuto<DataArrayInt> ret=DataArrayInt::New();
7495       ret->alloc(0,nbOfComp);
7496       ret->copyStringInfoFrom(*this);
7497       return ret.retn();
7498     }
7499   int ref=ranges.front().first;
7500   int nbOfTuples=0;
7501   bool isIncreasing=true;
7502   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7503     {
7504       if((*it).first<=(*it).second)
7505         {
7506           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
7507             {
7508               nbOfTuples+=(*it).second-(*it).first;
7509               if(isIncreasing)
7510                 isIncreasing=ref<=(*it).first;
7511               ref=(*it).second;
7512             }
7513           else
7514             {
7515               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7516               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
7517               throw INTERP_KERNEL::Exception(oss.str().c_str());
7518             }
7519         }
7520       else
7521         {
7522           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7523           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7524           throw INTERP_KERNEL::Exception(oss.str().c_str());
7525         }
7526     }
7527   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7528     return deepCopy();
7529   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7530   ret->alloc(nbOfTuples,nbOfComp);
7531   ret->copyStringInfoFrom(*this);
7532   const int *src=getConstPointer();
7533   int *work=ret->getPointer();
7534   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7535     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7536   return ret.retn();
7537 }
7538
7539 /*!
7540  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7541  * This map, if applied to \a this array, would make it sorted. For example, if
7542  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7543  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7544  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7545  * This method is useful for renumbering (in MED file for example). For more info
7546  * on renumbering see \ref numbering.
7547  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7548  *          array using decrRef() as it is no more needed.
7549  *  \throw If \a this is not allocated.
7550  *  \throw If \a this->getNumberOfComponents() != 1.
7551  *  \throw If there are equal values in \a this array.
7552  */
7553 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7554 {
7555   checkAllocated();
7556   if(getNumberOfComponents()!=1)
7557     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7558   int nbTuples=getNumberOfTuples();
7559   const int *pt=getConstPointer();
7560   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7561   DataArrayInt *ret=DataArrayInt::New();
7562   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7563   return ret;
7564 }
7565
7566 /*!
7567  * 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
7568  * input array \a ids2.
7569  * \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.
7570  * 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
7571  * inversely.
7572  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7573  *
7574  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7575  *          array using decrRef() as it is no more needed.
7576  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7577  * 
7578  */
7579 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7580 {
7581   if(!ids1 || !ids2)
7582     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7583   if(!ids1->isAllocated() || !ids2->isAllocated())
7584     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7585   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7586     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7587   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7588     {
7589       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 !";
7590       throw INTERP_KERNEL::Exception(oss.str().c_str());
7591     }
7592   MCAuto<DataArrayInt> p1(ids1->deepCopy());
7593   MCAuto<DataArrayInt> p2(ids2->deepCopy());
7594   p1->sort(true); p2->sort(true);
7595   if(!p1->isEqualWithoutConsideringStr(*p2))
7596     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7597   p1=ids1->checkAndPreparePermutation();
7598   p2=ids2->checkAndPreparePermutation();
7599   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7600   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7601   return p2.retn();
7602 }
7603
7604 /*!
7605  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7606  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7607  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7608  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7609  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7610  * The first of out arrays returns indices of elements of \a this array, grouped by their
7611  * place in the set \a B. The second out array is the index of the first one; it shows how
7612  * many elements of \a A are mapped into each element of \a B. <br>
7613  * For more info on
7614  * mapping and its usage in renumbering see \ref numbering. <br>
7615  * \b Example:
7616  * - \a this: [0,3,2,3,2,2,1,2]
7617  * - \a targetNb: 4
7618  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7619  * - \a arrI: [0,1,2,6,8]
7620  *
7621  * This result means: <br>
7622  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7623  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7624  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7625  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7626  * \a arrI[ 2+1 ]]); <br> etc.
7627  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7628  *         than the maximal value of \a A.
7629  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7630  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7631  *         this array using decrRef() as it is no more needed.
7632  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7633  *         elements of \a this. The caller is to delete this array using decrRef() as it
7634  *         is no more needed.
7635  *  \throw If \a this is not allocated.
7636  *  \throw If \a this->getNumberOfComponents() != 1.
7637  *  \throw If any value in \a this is more or equal to \a targetNb.
7638  */
7639 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7640 {
7641   checkAllocated();
7642   if(getNumberOfComponents()!=1)
7643     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7644   int nbOfTuples=getNumberOfTuples();
7645   MCAuto<DataArrayInt> ret(DataArrayInt::New());
7646   MCAuto<DataArrayInt> retI(DataArrayInt::New());
7647   retI->alloc(targetNb+1,1);
7648   const int *input=getConstPointer();
7649   std::vector< std::vector<int> > tmp(targetNb);
7650   for(int i=0;i<nbOfTuples;i++)
7651     {
7652       int tmp2=input[i];
7653       if(tmp2>=0 && tmp2<targetNb)
7654         tmp[tmp2].push_back(i);
7655       else
7656         {
7657           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7658           throw INTERP_KERNEL::Exception(oss.str().c_str());
7659         }
7660     }
7661   int *retIPtr=retI->getPointer();
7662   *retIPtr=0;
7663   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7664     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7665   if(nbOfTuples!=retI->getIJ(targetNb,0))
7666     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7667   ret->alloc(nbOfTuples,1);
7668   int *retPtr=ret->getPointer();
7669   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7670     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7671   arr=ret.retn();
7672   arrI=retI.retn();
7673 }
7674
7675
7676 /*!
7677  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7678  * from a zip representation of a surjective format (returned e.g. by
7679  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7680  * for example). The result array minimizes the permutation. <br>
7681  * For more info on renumbering see \ref numbering. <br>
7682  * \b Example: <br>
7683  * - \a nbOfOldTuples: 10 
7684  * - \a arr          : [0,3, 5,7,9]
7685  * - \a arrIBg       : [0,2,5]
7686  * - \a newNbOfTuples: 7
7687  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7688  *
7689  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7690  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7691  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7692  *         (indices of) equal values. Its every element (except the last one) points to
7693  *         the first element of a group of equal values.
7694  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7695  *          arrIBg is \a arrIEnd[ -1 ].
7696  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7697  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7698  *          array using decrRef() as it is no more needed.
7699  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7700  */
7701 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7702 {
7703   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7704   ret->alloc(nbOfOldTuples,1);
7705   int *pt=ret->getPointer();
7706   std::fill(pt,pt+nbOfOldTuples,-1);
7707   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7708   const int *cIPtr=arrIBg;
7709   for(int i=0;i<nbOfGrps;i++)
7710     pt[arr[cIPtr[i]]]=-(i+2);
7711   int newNb=0;
7712   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7713     {
7714       if(pt[iNode]<0)
7715         {
7716           if(pt[iNode]==-1)
7717             pt[iNode]=newNb++;
7718           else
7719             {
7720               int grpId=-(pt[iNode]+2);
7721               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7722                 {
7723                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7724                     pt[arr[j]]=newNb;
7725                   else
7726                     {
7727                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7728                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7729                     }
7730                 }
7731               newNb++;
7732             }
7733         }
7734     }
7735   newNbOfTuples=newNb;
7736   return ret.retn();
7737 }
7738
7739 /*!
7740  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7741  * which if applied to \a this array would make it sorted ascendingly.
7742  * For more info on renumbering see \ref numbering. <br>
7743  * \b Example: <br>
7744  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7745  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7746  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7747  *
7748  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7749  *          array using decrRef() as it is no more needed.
7750  *  \throw If \a this is not allocated.
7751  *  \throw If \a this->getNumberOfComponents() != 1.
7752  */
7753 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7754 {
7755   checkAllocated();
7756   if(getNumberOfComponents()!=1)
7757     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7758   int nbOfTuples=getNumberOfTuples();
7759   const int *pt=getConstPointer();
7760   std::map<int,int> m;
7761   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7762   ret->alloc(nbOfTuples,1);
7763   int *opt=ret->getPointer();
7764   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7765     {
7766       int val=*pt;
7767       std::map<int,int>::iterator it=m.find(val);
7768       if(it!=m.end())
7769         {
7770           *opt=(*it).second;
7771           (*it).second++;
7772         }
7773       else
7774         {
7775           *opt=0;
7776           m.insert(std::pair<int,int>(val,1));
7777         }
7778     }
7779   int sum=0;
7780   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7781     {
7782       int vt=(*it).second;
7783       (*it).second=sum;
7784       sum+=vt;
7785     }
7786   pt=getConstPointer();
7787   opt=ret->getPointer();
7788   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7789     *opt+=m[*pt];
7790   //
7791   return ret.retn();
7792 }
7793
7794 /*!
7795  * Checks if contents of \a this array are equal to that of an array filled with
7796  * iota(). This method is particularly useful for DataArrayInt instances that represent
7797  * a renumbering array to check the real need in renumbering. This method checks than \a this can be considered as an identity function
7798  * of a set having \a sizeExpected elements into itself.
7799  *
7800  *  \param [in] sizeExpected - The number of elements expected.
7801  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7802  *  \throw If \a this is not allocated.
7803  *  \throw If \a this->getNumberOfComponents() != 1.
7804  */
7805 bool DataArrayInt::isIota(int sizeExpected) const
7806 {
7807   checkAllocated();
7808   if(getNumberOfComponents()!=1)
7809     return false;
7810   int nbOfTuples(getNumberOfTuples());
7811   if(nbOfTuples!=sizeExpected)
7812     return false;
7813   const int *pt=getConstPointer();
7814   for(int i=0;i<nbOfTuples;i++,pt++)
7815     if(*pt!=i)
7816       return false;
7817   return true;
7818 }
7819
7820 /*!
7821  * Checks if all values in \a this array are equal to \a val.
7822  *  \param [in] val - value to check equality of array values to.
7823  *  \return bool - \a true if all values are \a val.
7824  *  \throw If \a this is not allocated.
7825  *  \throw If \a this->getNumberOfComponents() != 1
7826  */
7827 bool DataArrayInt::isUniform(int val) const
7828 {
7829   checkAllocated();
7830   if(getNumberOfComponents()!=1)
7831     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7832   int nbOfTuples=getNumberOfTuples();
7833   const int *w=getConstPointer();
7834   const int *end2=w+nbOfTuples;
7835   for(;w!=end2;w++)
7836     if(*w!=val)
7837       return false;
7838   return true;
7839 }
7840
7841 /*!
7842  * Checks if all values in \a this array are unique.
7843  *  \return bool - \a true if condition above is true
7844  *  \throw If \a this is not allocated.
7845  *  \throw If \a this->getNumberOfComponents() != 1
7846  */
7847 bool DataArrayInt::hasUniqueValues() const
7848 {
7849   checkAllocated();
7850   if(getNumberOfComponents()!=1)
7851     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7852   int nbOfTuples(getNumberOfTuples());
7853   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
7854   if (s.size() != nbOfTuples)
7855     return false;
7856   return true;
7857 }
7858
7859 /*!
7860  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7861  * array to the new one.
7862  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7863  */
7864 DataArrayDouble *DataArrayInt::convertToDblArr() const
7865 {
7866   checkAllocated();
7867   DataArrayDouble *ret=DataArrayDouble::New();
7868   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7869   std::size_t nbOfVals=getNbOfElems();
7870   const int *src=getConstPointer();
7871   double *dest=ret->getPointer();
7872   std::copy(src,src+nbOfVals,dest);
7873   ret->copyStringInfoFrom(*this);
7874   return ret;
7875 }
7876
7877 /*!
7878  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7879  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7880  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7881  * This method is a specialization of selectByTupleIdSafeSlice().
7882  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7883  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7884  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7885  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7886  *          is to delete using decrRef() as it is no more needed.
7887  *  \throw If \a tupleIdBg < 0.
7888  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7889     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7890  *  \sa DataArrayInt::selectByTupleIdSafeSlice
7891  */
7892 DataArrayInt *DataArrayInt::subArray(int tupleIdBg, int tupleIdEnd) const
7893 {
7894   checkAllocated();
7895   int nbt=getNumberOfTuples();
7896   if(tupleIdBg<0)
7897     throw INTERP_KERNEL::Exception("DataArrayInt::subArray : The tupleIdBg parameter must be greater than 0 !");
7898   if(tupleIdBg>nbt)
7899     throw INTERP_KERNEL::Exception("DataArrayInt::subArray : The tupleIdBg parameter is greater than number of tuples !");
7900   int trueEnd=tupleIdEnd;
7901   if(tupleIdEnd!=-1)
7902     {
7903       if(tupleIdEnd>nbt)
7904         throw INTERP_KERNEL::Exception("DataArrayInt::subArray : The tupleIdBg parameter is greater or equal than number of tuples !");
7905     }
7906   else
7907     trueEnd=nbt;
7908   int nbComp=getNumberOfComponents();
7909   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7910   ret->alloc(trueEnd-tupleIdBg,nbComp);
7911   ret->copyStringInfoFrom(*this);
7912   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7913   return ret.retn();
7914 }
7915
7916 /*!
7917  * Changes the number of components within \a this array so that its raw data **does
7918  * not** change, instead splitting this data into tuples changes.
7919  *  \warning This method erases all (name and unit) component info set before!
7920  *  \param [in] newNbOfComp - number of components for \a this array to have.
7921  *  \throw If \a this is not allocated
7922  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7923  *  \throw If \a newNbOfCompo is lower than 1.
7924  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7925  *  \warning This method erases all (name and unit) component info set before!
7926  */
7927 void DataArrayInt::rearrange(int newNbOfCompo)
7928 {
7929   checkAllocated();
7930   if(newNbOfCompo<1)
7931     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7932   std::size_t nbOfElems=getNbOfElems();
7933   if(nbOfElems%newNbOfCompo!=0)
7934     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7935   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7936     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7937   _info_on_compo.clear();
7938   _info_on_compo.resize(newNbOfCompo);
7939   declareAsNew();
7940 }
7941
7942 /*!
7943  * Changes the number of components within \a this array to be equal to its number
7944  * of tuples, and inversely its number of tuples to become equal to its number of 
7945  * components. So that its raw data **does not** change, instead splitting this
7946  * data into tuples changes.
7947  *  \warning This method erases all (name and unit) component info set before!
7948  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7949  *  \throw If \a this is not allocated.
7950  *  \sa rearrange()
7951  */
7952 void DataArrayInt::transpose()
7953 {
7954   checkAllocated();
7955   int nbOfTuples=getNumberOfTuples();
7956   rearrange(nbOfTuples);
7957 }
7958
7959 /*!
7960  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7961  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7962  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7963  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7964  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7965  * components.  
7966  *  \param [in] newNbOfComp - number of components for the new array to have.
7967  *  \param [in] dftValue - value assigned to new values added to the new array.
7968  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7969  *          is to delete using decrRef() as it is no more needed.
7970  *  \throw If \a this is not allocated.
7971  */
7972 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7973 {
7974   checkAllocated();
7975   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7976   ret->alloc(getNumberOfTuples(),newNbOfComp);
7977   const int *oldc=getConstPointer();
7978   int *nc=ret->getPointer();
7979   int nbOfTuples=getNumberOfTuples();
7980   int oldNbOfComp=getNumberOfComponents();
7981   int dim=std::min(oldNbOfComp,newNbOfComp);
7982   for(int i=0;i<nbOfTuples;i++)
7983     {
7984       int j=0;
7985       for(;j<dim;j++)
7986         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7987       for(;j<newNbOfComp;j++)
7988         nc[newNbOfComp*i+j]=dftValue;
7989     }
7990   ret->setName(getName());
7991   for(int i=0;i<dim;i++)
7992     ret->setInfoOnComponent(i,getInfoOnComponent(i));
7993   ret->setName(getName());
7994   return ret.retn();
7995 }
7996
7997 /*!
7998  * Changes number of tuples in the array. If the new number of tuples is smaller
7999  * than the current number the array is truncated, otherwise the array is extended.
8000  *  \param [in] nbOfTuples - new number of tuples. 
8001  *  \throw If \a this is not allocated.
8002  *  \throw If \a nbOfTuples is negative.
8003  */
8004 void DataArrayInt::reAlloc(int nbOfTuples)
8005 {
8006   if(nbOfTuples<0)
8007     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
8008   checkAllocated();
8009   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
8010   declareAsNew();
8011 }
8012
8013
8014 /*!
8015  * Returns a copy of \a this array composed of selected components.
8016  * The new DataArrayInt has the same number of tuples but includes components
8017  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
8018  * can be either less, same or more than \a this->getNbOfElems().
8019  *  \param [in] compoIds - sequence of zero based indices of components to include
8020  *              into the new array.
8021  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
8022  *          is to delete using decrRef() as it is no more needed.
8023  *  \throw If \a this is not allocated.
8024  *  \throw If a component index (\a i) is not valid: 
8025  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
8026  *
8027  *  \if ENABLE_EXAMPLES
8028  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
8029  *  \endif
8030  */
8031 DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
8032 {
8033   checkAllocated();
8034   MCAuto<DataArrayInt> ret(DataArrayInt::New());
8035   int newNbOfCompo=(int)compoIds.size();
8036   int oldNbOfCompo=getNumberOfComponents();
8037   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
8038     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
8039   int nbOfTuples=getNumberOfTuples();
8040   ret->alloc(nbOfTuples,newNbOfCompo);
8041   ret->copyPartOfStringInfoFrom(*this,compoIds);
8042   const int *oldc=getConstPointer();
8043   int *nc=ret->getPointer();
8044   for(int i=0;i<nbOfTuples;i++)
8045     for(int j=0;j<newNbOfCompo;j++,nc++)
8046       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
8047   return ret.retn();
8048 }
8049
8050 /*!
8051  * Appends components of another array to components of \a this one, tuple by tuple.
8052  * So that the number of tuples of \a this array remains the same and the number of 
8053  * components increases.
8054  *  \param [in] other - the DataArrayInt to append to \a this one.
8055  *  \throw If \a this is not allocated.
8056  *  \throw If \a this and \a other arrays have different number of tuples.
8057  *
8058  *  \if ENABLE_EXAMPLES
8059  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
8060  *
8061  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
8062  *  \endif
8063  */
8064 void DataArrayInt::meldWith(const DataArrayInt *other)
8065 {
8066   if(!other)
8067     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
8068   checkAllocated();
8069   other->checkAllocated();
8070   int nbOfTuples=getNumberOfTuples();
8071   if(nbOfTuples!=other->getNumberOfTuples())
8072     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
8073   int nbOfComp1=getNumberOfComponents();
8074   int nbOfComp2=other->getNumberOfComponents();
8075   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
8076   int *w=newArr;
8077   const int *inp1=getConstPointer();
8078   const int *inp2=other->getConstPointer();
8079   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
8080     {
8081       w=std::copy(inp1,inp1+nbOfComp1,w);
8082       w=std::copy(inp2,inp2+nbOfComp2,w);
8083     }
8084   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
8085   std::vector<int> compIds(nbOfComp2);
8086   for(int i=0;i<nbOfComp2;i++)
8087     compIds[i]=nbOfComp1+i;
8088   copyPartOfStringInfoFrom2(compIds,*other);
8089 }
8090
8091 /*!
8092  * Copy all components in a specified order from another DataArrayInt.
8093  * The specified components become the first ones in \a this array.
8094  * Both numerical and textual data is copied. The number of tuples in \a this and
8095  * the other array can be different.
8096  *  \param [in] a - the array to copy data from.
8097  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
8098  *              to be copied.
8099  *  \throw If \a a is NULL.
8100  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
8101  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
8102  *
8103  *  \if ENABLE_EXAMPLES
8104  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
8105  *  \endif
8106  */
8107 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
8108 {
8109   if(!a)
8110     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
8111   checkAllocated();
8112   a->checkAllocated();
8113   copyPartOfStringInfoFrom2(compoIds,*a);
8114   std::size_t partOfCompoSz=compoIds.size();
8115   int nbOfCompo=getNumberOfComponents();
8116   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
8117   const int *ac=a->getConstPointer();
8118   int *nc=getPointer();
8119   for(int i=0;i<nbOfTuples;i++)
8120     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
8121       nc[nbOfCompo*i+compoIds[j]]=*ac;
8122 }
8123
8124 /*!
8125  * Copy all values from another DataArrayInt into specified tuples and components
8126  * of \a this array. Textual data is not copied.
8127  * The tree parameters defining set of indices of tuples and components are similar to
8128  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
8129  *  \param [in] a - the array to copy values from.
8130  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
8131  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
8132  *              are located.
8133  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
8134  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
8135  *  \param [in] endComp - index of the component before which the components to assign
8136  *              to are located.
8137  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8138  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
8139  *              must be equal to the number of columns to assign to, else an
8140  *              exception is thrown; if \a false, then it is only required that \a
8141  *              a->getNbOfElems() equals to number of values to assign to (this condition
8142  *              must be respected even if \a strictCompoCompare is \a true). The number of 
8143  *              values to assign to is given by following Python expression:
8144  *              \a nbTargetValues = 
8145  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
8146  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
8147  *  \throw If \a a is NULL.
8148  *  \throw If \a a is not allocated.
8149  *  \throw If \a this is not allocated.
8150  *  \throw If parameters specifying tuples and components to assign to do not give a
8151  *            non-empty range of increasing indices.
8152  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
8153  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
8154  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
8155  *
8156  *  \if ENABLE_EXAMPLES
8157  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
8158  *  \endif
8159  */
8160 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8161 {
8162   if(!a)
8163     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
8164   const char msg[]="DataArrayInt::setPartOfValues1";
8165   checkAllocated();
8166   a->checkAllocated();
8167   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8168   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8169   int nbComp=getNumberOfComponents();
8170   int nbOfTuples=getNumberOfTuples();
8171   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8172   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8173   bool assignTech=true;
8174   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8175     {
8176       if(strictCompoCompare)
8177         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8178     }
8179   else
8180     {
8181       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8182       assignTech=false;
8183     }
8184   int *pt=getPointer()+bgTuples*nbComp+bgComp;
8185   const int *srcPt=a->getConstPointer();
8186   if(assignTech)
8187     {
8188       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8189         for(int j=0;j<newNbOfComp;j++,srcPt++)
8190           pt[j*stepComp]=*srcPt;
8191     }
8192   else
8193     {
8194       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8195         {
8196           const int *srcPt2=srcPt;
8197           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8198             pt[j*stepComp]=*srcPt2;
8199         }
8200     }
8201 }
8202
8203 /*!
8204  * Assign a given value to values at specified tuples and components of \a this array.
8205  * The tree parameters defining set of indices of tuples and components are similar to
8206  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
8207  *  \param [in] a - the value to assign.
8208  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
8209  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
8210  *              are located.
8211  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
8212  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8213  *  \param [in] endComp - index of the component before which the components to assign
8214  *              to are located.
8215  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8216  *  \throw If \a this is not allocated.
8217  *  \throw If parameters specifying tuples and components to assign to, do not give a
8218  *            non-empty range of increasing indices or indices are out of a valid range
8219  *            for \c this array.
8220  *
8221  *  \if ENABLE_EXAMPLES
8222  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
8223  *  \endif
8224  */
8225 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
8226 {
8227   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
8228   checkAllocated();
8229   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8230   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8231   int nbComp=getNumberOfComponents();
8232   int nbOfTuples=getNumberOfTuples();
8233   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8234   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8235   int *pt=getPointer()+bgTuples*nbComp+bgComp;
8236   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8237     for(int j=0;j<newNbOfComp;j++)
8238       pt[j*stepComp]=a;
8239 }
8240
8241
8242 /*!
8243  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8244  * components of \a this array. Textual data is not copied.
8245  * The tuples and components to assign to are defined by C arrays of indices.
8246  * There are two *modes of usage*:
8247  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8248  *   of \a a is assigned to its own location within \a this array. 
8249  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8250  *   components of every specified tuple of \a this array. In this mode it is required
8251  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8252  * 
8253  *  \param [in] a - the array to copy values from.
8254  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8255  *              assign values of \a a to.
8256  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8257  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8258  *              \a bgTuples <= \a pi < \a endTuples.
8259  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8260  *              assign values of \a a to.
8261  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8262  *              pointer to a component index <em>(pi)</em> varies as this: 
8263  *              \a bgComp <= \a pi < \a endComp.
8264  *  \param [in] strictCompoCompare - this parameter is checked only if the
8265  *               *mode of usage* is the first; if it is \a true (default), 
8266  *               then \a a->getNumberOfComponents() must be equal 
8267  *               to the number of specified columns, else this is not required.
8268  *  \throw If \a a is NULL.
8269  *  \throw If \a a is not allocated.
8270  *  \throw If \a this is not allocated.
8271  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8272  *         out of a valid range for \a this array.
8273  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8274  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
8275  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8276  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
8277  *
8278  *  \if ENABLE_EXAMPLES
8279  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
8280  *  \endif
8281  */
8282 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8283 {
8284   if(!a)
8285     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
8286   const char msg[]="DataArrayInt::setPartOfValues2";
8287   checkAllocated();
8288   a->checkAllocated();
8289   int nbComp=getNumberOfComponents();
8290   int nbOfTuples=getNumberOfTuples();
8291   for(const int *z=bgComp;z!=endComp;z++)
8292     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8293   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8294   int newNbOfComp=(int)std::distance(bgComp,endComp);
8295   bool assignTech=true;
8296   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8297     {
8298       if(strictCompoCompare)
8299         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8300     }
8301   else
8302     {
8303       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8304       assignTech=false;
8305     }
8306   int *pt=getPointer();
8307   const int *srcPt=a->getConstPointer();
8308   if(assignTech)
8309     {    
8310       for(const int *w=bgTuples;w!=endTuples;w++)
8311         {
8312           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8313           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8314             {    
8315               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
8316             }
8317         }
8318     }
8319   else
8320     {
8321       for(const int *w=bgTuples;w!=endTuples;w++)
8322         {
8323           const int *srcPt2=srcPt;
8324           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8325           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8326             {    
8327               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
8328             }
8329         }
8330     }
8331 }
8332
8333 /*!
8334  * Assign a given value to values at specified tuples and components of \a this array.
8335  * The tuples and components to assign to are defined by C arrays of indices.
8336  *  \param [in] a - the value to assign.
8337  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8338  *              assign \a a to.
8339  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8340  *              pointer to a tuple index (\a pi) varies as this: 
8341  *              \a bgTuples <= \a pi < \a endTuples.
8342  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8343  *              assign \a a to.
8344  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8345  *              pointer to a component index (\a pi) varies as this: 
8346  *              \a bgComp <= \a pi < \a endComp.
8347  *  \throw If \a this is not allocated.
8348  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8349  *         out of a valid range for \a this array.
8350  *
8351  *  \if ENABLE_EXAMPLES
8352  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
8353  *  \endif
8354  */
8355 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
8356 {
8357   checkAllocated();
8358   int nbComp=getNumberOfComponents();
8359   int nbOfTuples=getNumberOfTuples();
8360   for(const int *z=bgComp;z!=endComp;z++)
8361     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8362   int *pt=getPointer();
8363   for(const int *w=bgTuples;w!=endTuples;w++)
8364     for(const int *z=bgComp;z!=endComp;z++)
8365       {
8366         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8367         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
8368       }
8369 }
8370
8371 /*!
8372  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8373  * components of \a this array. Textual data is not copied.
8374  * The tuples to assign to are defined by a C array of indices.
8375  * The components to assign to are defined by three values similar to parameters of
8376  * the Python function \c range(\c start,\c stop,\c step).
8377  * There are two *modes of usage*:
8378  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8379  *   of \a a is assigned to its own location within \a this array. 
8380  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8381  *   components of every specified tuple of \a this array. In this mode it is required
8382  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8383  *
8384  *  \param [in] a - the array to copy values from.
8385  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8386  *              assign values of \a a to.
8387  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8388  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8389  *              \a bgTuples <= \a pi < \a endTuples.
8390  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8391  *  \param [in] endComp - index of the component before which the components to assign
8392  *              to are located.
8393  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8394  *  \param [in] strictCompoCompare - this parameter is checked only in the first
8395  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
8396  *               then \a a->getNumberOfComponents() must be equal 
8397  *               to the number of specified columns, else this is not required.
8398  *  \throw If \a a is NULL.
8399  *  \throw If \a a is not allocated.
8400  *  \throw If \a this is not allocated.
8401  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8402  *         \a this array.
8403  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8404  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
8405  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8406  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8407  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
8408  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8409  *  \throw If parameters specifying components to assign to, do not give a
8410  *            non-empty range of increasing indices or indices are out of a valid range
8411  *            for \c this array.
8412  *
8413  *  \if ENABLE_EXAMPLES
8414  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
8415  *  \endif
8416  */
8417 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8418 {
8419   if(!a)
8420     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
8421   const char msg[]="DataArrayInt::setPartOfValues3";
8422   checkAllocated();
8423   a->checkAllocated();
8424   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8425   int nbComp=getNumberOfComponents();
8426   int nbOfTuples=getNumberOfTuples();
8427   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8428   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8429   bool assignTech=true;
8430   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8431     {
8432       if(strictCompoCompare)
8433         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8434     }
8435   else
8436     {
8437       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8438       assignTech=false;
8439     }
8440   int *pt=getPointer()+bgComp;
8441   const int *srcPt=a->getConstPointer();
8442   if(assignTech)
8443     {
8444       for(const int *w=bgTuples;w!=endTuples;w++)
8445         for(int j=0;j<newNbOfComp;j++,srcPt++)
8446           {
8447             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8448             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
8449           }
8450     }
8451   else
8452     {
8453       for(const int *w=bgTuples;w!=endTuples;w++)
8454         {
8455           const int *srcPt2=srcPt;
8456           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8457             {
8458               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8459               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
8460             }
8461         }
8462     }
8463 }
8464
8465 /*!
8466  * Assign a given value to values at specified tuples and components of \a this array.
8467  * The tuples to assign to are defined by a C array of indices.
8468  * The components to assign to are defined by three values similar to parameters of
8469  * the Python function \c range(\c start,\c stop,\c step).
8470  *  \param [in] a - the value to assign.
8471  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8472  *              assign \a a to.
8473  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8474  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8475  *              \a bgTuples <= \a pi < \a endTuples.
8476  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8477  *  \param [in] endComp - index of the component before which the components to assign
8478  *              to are located.
8479  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8480  *  \throw If \a this is not allocated.
8481  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8482  *         \a this array.
8483  *  \throw If parameters specifying components to assign to, do not give a
8484  *            non-empty range of increasing indices or indices are out of a valid range
8485  *            for \c this array.
8486  *
8487  *  \if ENABLE_EXAMPLES
8488  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
8489  *  \endif
8490  */
8491 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
8492 {
8493   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
8494   checkAllocated();
8495   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8496   int nbComp=getNumberOfComponents();
8497   int nbOfTuples=getNumberOfTuples();
8498   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8499   int *pt=getPointer()+bgComp;
8500   for(const int *w=bgTuples;w!=endTuples;w++)
8501     for(int j=0;j<newNbOfComp;j++)
8502       {
8503         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8504         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
8505       }
8506 }
8507
8508 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8509 {
8510   if(!a)
8511     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
8512   const char msg[]="DataArrayInt::setPartOfValues4";
8513   checkAllocated();
8514   a->checkAllocated();
8515   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8516   int newNbOfComp=(int)std::distance(bgComp,endComp);
8517   int nbComp=getNumberOfComponents();
8518   for(const int *z=bgComp;z!=endComp;z++)
8519     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8520   int nbOfTuples=getNumberOfTuples();
8521   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8522   bool assignTech=true;
8523   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8524     {
8525       if(strictCompoCompare)
8526         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8527     }
8528   else
8529     {
8530       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8531       assignTech=false;
8532     }
8533   const int *srcPt=a->getConstPointer();
8534   int *pt=getPointer()+bgTuples*nbComp;
8535   if(assignTech)
8536     {
8537       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8538         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8539           pt[*z]=*srcPt;
8540     }
8541   else
8542     {
8543       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8544         {
8545           const int *srcPt2=srcPt;
8546           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8547             pt[*z]=*srcPt2;
8548         }
8549     }
8550 }
8551
8552 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
8553 {
8554   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
8555   checkAllocated();
8556   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8557   int nbComp=getNumberOfComponents();
8558   for(const int *z=bgComp;z!=endComp;z++)
8559     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8560   int nbOfTuples=getNumberOfTuples();
8561   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8562   int *pt=getPointer()+bgTuples*nbComp;
8563   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8564     for(const int *z=bgComp;z!=endComp;z++)
8565       pt[*z]=a;
8566 }
8567
8568 /*!
8569  * Copy some tuples from another DataArrayInt into specified tuples
8570  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8571  * components.
8572  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8573  * All components of selected tuples are copied.
8574  *  \param [in] a - the array to copy values from.
8575  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8576  *              target tuples of \a this. \a tuplesSelec has two components, and the
8577  *              first component specifies index of the source tuple and the second
8578  *              one specifies index of the target tuple.
8579  *  \throw If \a this is not allocated.
8580  *  \throw If \a a is NULL.
8581  *  \throw If \a a is not allocated.
8582  *  \throw If \a tuplesSelec is NULL.
8583  *  \throw If \a tuplesSelec is not allocated.
8584  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8585  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8586  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8587  *         the corresponding (\a this or \a a) array.
8588  */
8589 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8590 {
8591   if(!a || !tuplesSelec)
8592     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8593   checkAllocated();
8594   a->checkAllocated();
8595   tuplesSelec->checkAllocated();
8596   int nbOfComp=getNumberOfComponents();
8597   if(nbOfComp!=a->getNumberOfComponents())
8598     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8599   if(tuplesSelec->getNumberOfComponents()!=2)
8600     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8601   int thisNt=getNumberOfTuples();
8602   int aNt=a->getNumberOfTuples();
8603   int *valsToSet=getPointer();
8604   const int *valsSrc=a->getConstPointer();
8605   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8606     {
8607       if(tuple[1]>=0 && tuple[1]<aNt)
8608         {
8609           if(tuple[0]>=0 && tuple[0]<thisNt)
8610             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8611           else
8612             {
8613               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8614               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8615               throw INTERP_KERNEL::Exception(oss.str().c_str());
8616             }
8617         }
8618       else
8619         {
8620           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8621           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8622           throw INTERP_KERNEL::Exception(oss.str().c_str());
8623         }
8624     }
8625 }
8626
8627 /*!
8628  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8629  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8630  * components.
8631  * The tuples to assign to are defined by index of the first tuple, and
8632  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8633  * The tuples to copy are defined by values of a DataArrayInt.
8634  * All components of selected tuples are copied.
8635  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8636  *              values to.
8637  *  \param [in] aBase - the array to copy values from.
8638  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8639  *  \throw If \a this is not allocated.
8640  *  \throw If \a aBase is NULL.
8641  *  \throw If \a aBase is not allocated.
8642  *  \throw If \a tuplesSelec is NULL.
8643  *  \throw If \a tuplesSelec is not allocated.
8644  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8645  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8646  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8647  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8648  *         \a aBase array.
8649  */
8650 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8651 {
8652   if(!aBase || !tuplesSelec)
8653     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8654   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8655   if(!a)
8656     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8657   checkAllocated();
8658   a->checkAllocated();
8659   tuplesSelec->checkAllocated();
8660   int nbOfComp=getNumberOfComponents();
8661   if(nbOfComp!=a->getNumberOfComponents())
8662     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8663   if(tuplesSelec->getNumberOfComponents()!=1)
8664     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8665   int thisNt=getNumberOfTuples();
8666   int aNt=a->getNumberOfTuples();
8667   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8668   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8669   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8670     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8671   const int *valsSrc=a->getConstPointer();
8672   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8673     {
8674       if(*tuple>=0 && *tuple<aNt)
8675         {
8676           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8677         }
8678       else
8679         {
8680           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8681           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8682           throw INTERP_KERNEL::Exception(oss.str().c_str());
8683         }
8684     }
8685 }
8686
8687 /*!
8688  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8689  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8690  * components.
8691  * The tuples to copy are defined by three values similar to parameters of
8692  * the Python function \c range(\c start,\c stop,\c step).
8693  * The tuples to assign to are defined by index of the first tuple, and
8694  * their number is defined by number of tuples to copy.
8695  * All components of selected tuples are copied.
8696  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8697  *              values to.
8698  *  \param [in] aBase - the array to copy values from.
8699  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8700  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8701  *              are located.
8702  *  \param [in] step - index increment to get index of the next tuple to copy.
8703  *  \throw If \a this is not allocated.
8704  *  \throw If \a aBase is NULL.
8705  *  \throw If \a aBase is not allocated.
8706  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8707  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8708  *  \throw If parameters specifying tuples to copy, do not give a
8709  *            non-empty range of increasing indices or indices are out of a valid range
8710  *            for the array \a aBase.
8711  */
8712 void DataArrayInt::setContigPartOfSelectedValuesSlice(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8713 {
8714   if(!aBase)
8715     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : input DataArray is NULL !");
8716   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8717   if(!a)
8718     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : input DataArray aBase is not a DataArrayInt !");
8719   checkAllocated();
8720   a->checkAllocated();
8721   int nbOfComp=getNumberOfComponents();
8722   const char msg[]="DataArrayInt::setContigPartOfSelectedValuesSlice";
8723   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8724   if(nbOfComp!=a->getNumberOfComponents())
8725     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : This and a do not have the same number of components !");
8726   int thisNt=getNumberOfTuples();
8727   int aNt=a->getNumberOfTuples();
8728   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8729   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8730     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : invalid number range of values to write !");
8731   if(end2>aNt)
8732     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : invalid range of values to read !");
8733   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8734   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8735     {
8736       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8737     }
8738 }
8739
8740 /*!
8741  * Returns a value located at specified tuple and component.
8742  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8743  * parameters is checked. So this method is safe but expensive if used to go through
8744  * all values of \a this.
8745  *  \param [in] tupleId - index of tuple of interest.
8746  *  \param [in] compoId - index of component of interest.
8747  *  \return double - value located by \a tupleId and \a compoId.
8748  *  \throw If \a this is not allocated.
8749  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8750  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8751  */
8752 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8753 {
8754   checkAllocated();
8755   if(tupleId<0 || tupleId>=getNumberOfTuples())
8756     {
8757       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8758       throw INTERP_KERNEL::Exception(oss.str().c_str());
8759     }
8760   if(compoId<0 || compoId>=getNumberOfComponents())
8761     {
8762       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8763       throw INTERP_KERNEL::Exception(oss.str().c_str());
8764     }
8765   return _mem[tupleId*_info_on_compo.size()+compoId];
8766 }
8767
8768 /*!
8769  * Returns the first value of \a this. 
8770  *  \return int - the last value of \a this array.
8771  *  \throw If \a this is not allocated.
8772  *  \throw If \a this->getNumberOfComponents() != 1.
8773  *  \throw If \a this->getNumberOfTuples() < 1.
8774  */
8775 int DataArrayInt::front() const
8776 {
8777   checkAllocated();
8778   if(getNumberOfComponents()!=1)
8779     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8780   int nbOfTuples=getNumberOfTuples();
8781   if(nbOfTuples<1)
8782     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8783   return *(getConstPointer());
8784 }
8785
8786 /*!
8787  * Returns the last value of \a this. 
8788  *  \return int - the last value of \a this array.
8789  *  \throw If \a this is not allocated.
8790  *  \throw If \a this->getNumberOfComponents() != 1.
8791  *  \throw If \a this->getNumberOfTuples() < 1.
8792  */
8793 int DataArrayInt::back() const
8794 {
8795   checkAllocated();
8796   if(getNumberOfComponents()!=1)
8797     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8798   int nbOfTuples=getNumberOfTuples();
8799   if(nbOfTuples<1)
8800     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8801   return *(getConstPointer()+nbOfTuples-1);
8802 }
8803
8804 /*!
8805  * Assign pointer to one array to a pointer to another appay. Reference counter of
8806  * \a arrayToSet is incremented / decremented.
8807  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8808  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8809  */
8810 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8811 {
8812   if(newArray!=arrayToSet)
8813     {
8814       if(arrayToSet)
8815         arrayToSet->decrRef();
8816       arrayToSet=newArray;
8817       if(arrayToSet)
8818         arrayToSet->incrRef();
8819     }
8820 }
8821
8822 DataArrayIntIterator *DataArrayInt::iterator()
8823 {
8824   return new DataArrayIntIterator(this);
8825 }
8826
8827 /*!
8828  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8829  * given one. The ids are sorted in the ascending order.
8830  *  \param [in] val - the value to find within \a this.
8831  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8832  *          array using decrRef() as it is no more needed.
8833  *  \throw If \a this is not allocated.
8834  *  \throw If \a this->getNumberOfComponents() != 1.
8835  *  \sa DataArrayInt::findIdsEqualTuple
8836  */
8837 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
8838 {
8839   checkAllocated();
8840   if(getNumberOfComponents()!=1)
8841     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8842   const int *cptr(getConstPointer());
8843   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8844   int nbOfTuples=getNumberOfTuples();
8845   for(int i=0;i<nbOfTuples;i++,cptr++)
8846     if(*cptr==val)
8847       ret->pushBackSilent(i);
8848   return ret.retn();
8849 }
8850
8851 /*!
8852  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8853  * equal to a given one. 
8854  *  \param [in] val - the value to ignore within \a this.
8855  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8856  *          array using decrRef() as it is no more needed.
8857  *  \throw If \a this is not allocated.
8858  *  \throw If \a this->getNumberOfComponents() != 1.
8859  */
8860 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
8861 {
8862   checkAllocated();
8863   if(getNumberOfComponents()!=1)
8864     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8865   const int *cptr(getConstPointer());
8866   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8867   int nbOfTuples=getNumberOfTuples();
8868   for(int i=0;i<nbOfTuples;i++,cptr++)
8869     if(*cptr!=val)
8870       ret->pushBackSilent(i);
8871   return ret.retn();
8872 }
8873
8874 /*!
8875  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
8876  * This method is an extension of  DataArrayInt::findIdsEqual method.
8877  *
8878  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
8879  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
8880  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8881  *          array using decrRef() as it is no more needed.
8882  *  \throw If \a this is not allocated.
8883  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
8884  * \throw If \a this->getNumberOfComponents() is equal to 0.
8885  * \sa DataArrayInt::findIdsEqual
8886  */
8887 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
8888 {
8889   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
8890   checkAllocated();
8891   if(getNumberOfComponents()!=(int)nbOfCompoExp)
8892     {
8893       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
8894       throw INTERP_KERNEL::Exception(oss.str().c_str());
8895     }
8896   if(nbOfCompoExp==0)
8897     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
8898   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8899   const int *bg(begin()),*end2(end()),*work(begin());
8900   while(work!=end2)
8901     {
8902       work=std::search(work,end2,tupleBg,tupleEnd);
8903       if(work!=end2)
8904         {
8905           std::size_t pos(std::distance(bg,work));
8906           if(pos%nbOfCompoExp==0)
8907             ret->pushBackSilent(pos/nbOfCompoExp);
8908           work++;
8909         }
8910     }
8911   return ret.retn();
8912 }
8913
8914 /*!
8915  * Assigns \a newValue to all elements holding \a oldValue within \a this
8916  * one-dimensional array.
8917  *  \param [in] oldValue - the value to replace.
8918  *  \param [in] newValue - the value to assign.
8919  *  \return int - number of replacements performed.
8920  *  \throw If \a this is not allocated.
8921  *  \throw If \a this->getNumberOfComponents() != 1.
8922  */
8923 int DataArrayInt::changeValue(int oldValue, int newValue)
8924 {
8925   checkAllocated();
8926   if(getNumberOfComponents()!=1)
8927     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8928   if(oldValue==newValue)
8929     return 0;
8930   int *start(getPointer()),*end2(start+getNbOfElems());
8931   int ret(0);
8932   for(int *val=start;val!=end2;val++)
8933     {
8934       if(*val==oldValue)
8935         {
8936           *val=newValue;
8937           ret++;
8938         }
8939     }
8940   if(ret>0)
8941     declareAsNew();
8942   return ret;
8943 }
8944
8945 /*!
8946  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8947  * one of given values.
8948  *  \param [in] valsBg - an array of values to find within \a this array.
8949  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8950  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8951  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8952  *          array using decrRef() as it is no more needed.
8953  *  \throw If \a this->getNumberOfComponents() != 1.
8954  */
8955 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
8956 {
8957   if(getNumberOfComponents()!=1)
8958     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8959   std::set<int> vals2(valsBg,valsEnd);
8960   const int *cptr(getConstPointer());
8961   std::vector<int> res;
8962   int nbOfTuples(getNumberOfTuples());
8963   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8964   for(int i=0;i<nbOfTuples;i++,cptr++)
8965     if(vals2.find(*cptr)!=vals2.end())
8966       ret->pushBackSilent(i);
8967   return ret.retn();
8968 }
8969
8970 /*!
8971  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8972  * equal to any of given values.
8973  *  \param [in] valsBg - an array of values to ignore within \a this array.
8974  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8975  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8976  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8977  *          array using decrRef() as it is no more needed.
8978  *  \throw If \a this->getNumberOfComponents() != 1.
8979  */
8980 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8981 {
8982   if(getNumberOfComponents()!=1)
8983     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8984   std::set<int> vals2(valsBg,valsEnd);
8985   const int *cptr=getConstPointer();
8986   std::vector<int> res;
8987   int nbOfTuples=getNumberOfTuples();
8988   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8989   for(int i=0;i<nbOfTuples;i++,cptr++)
8990     if(vals2.find(*cptr)==vals2.end())
8991       ret->pushBackSilent(i);
8992   return ret.retn();
8993 }
8994
8995 /*!
8996  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
8997  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8998  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8999  * If any the tuple id is returned. If not -1 is returned.
9000  * 
9001  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
9002  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
9003  *
9004  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
9005  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
9006  */
9007 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
9008 {
9009   checkAllocated();
9010   int nbOfCompo=getNumberOfComponents();
9011   if(nbOfCompo==0)
9012     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
9013   if(nbOfCompo!=(int)tupl.size())
9014     {
9015       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
9016       throw INTERP_KERNEL::Exception(oss.str().c_str());
9017     }
9018   const int *cptr=getConstPointer();
9019   std::size_t nbOfVals=getNbOfElems();
9020   for(const int *work=cptr;work!=cptr+nbOfVals;)
9021     {
9022       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
9023       if(work!=cptr+nbOfVals)
9024         {
9025           if(std::distance(cptr,work)%nbOfCompo!=0)
9026             work++;
9027           else
9028             return std::distance(cptr,work)/nbOfCompo;
9029         }
9030     }
9031   return -1;
9032 }
9033
9034 /*!
9035  * This method searches the sequence specified in input parameter \b vals in \b this.
9036  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
9037  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
9038  * \sa DataArrayInt::findIdFirstEqualTuple
9039  */
9040 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
9041 {
9042   checkAllocated();
9043   int nbOfCompo=getNumberOfComponents();
9044   if(nbOfCompo!=1)
9045     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
9046   const int *cptr=getConstPointer();
9047   std::size_t nbOfVals=getNbOfElems();
9048   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
9049   if(loc!=cptr+nbOfVals)
9050     return std::distance(cptr,loc);
9051   return -1;
9052 }
9053
9054 /*!
9055  * This method expects to be called when number of components of this is equal to one.
9056  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
9057  * If not any tuple contains \b value -1 is returned.
9058  * \sa DataArrayInt::presenceOfValue
9059  */
9060 int DataArrayInt::findIdFirstEqual(int value) const
9061 {
9062   checkAllocated();
9063   if(getNumberOfComponents()!=1)
9064     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
9065   const int *cptr=getConstPointer();
9066   int nbOfTuples=getNumberOfTuples();
9067   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
9068   if(ret!=cptr+nbOfTuples)
9069     return std::distance(cptr,ret);
9070   return -1;
9071 }
9072
9073 /*!
9074  * This method expects to be called when number of components of this is equal to one.
9075  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
9076  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
9077  * \sa DataArrayInt::presenceOfValue
9078  */
9079 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
9080 {
9081   checkAllocated();
9082   if(getNumberOfComponents()!=1)
9083     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
9084   std::set<int> vals2(vals.begin(),vals.end());
9085   const int *cptr=getConstPointer();
9086   int nbOfTuples=getNumberOfTuples();
9087   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
9088     if(vals2.find(*w)!=vals2.end())
9089       return std::distance(cptr,w);
9090   return -1;
9091 }
9092
9093 /*!
9094  * This method returns the number of values in \a this that are equals to input parameter \a value.
9095  * This method only works for single component array.
9096  *
9097  * \return a value in [ 0, \c this->getNumberOfTuples() )
9098  *
9099  * \throw If \a this is not allocated
9100  *
9101  */
9102 int DataArrayInt::count(int value) const
9103 {
9104   int ret=0;
9105   checkAllocated();
9106   if(getNumberOfComponents()!=1)
9107     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
9108   const int *vals=begin();
9109   int nbOfTuples=getNumberOfTuples();
9110   for(int i=0;i<nbOfTuples;i++,vals++)
9111     if(*vals==value)
9112       ret++;
9113   return ret;
9114 }
9115
9116 /*!
9117  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
9118  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
9119  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
9120  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
9121  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
9122  * \sa DataArrayInt::findIdFirstEqualTuple
9123  */
9124 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
9125 {
9126   return findIdFirstEqualTuple(tupl)!=-1;
9127 }
9128
9129
9130 /*!
9131  * Returns \a true if a given value is present within \a this one-dimensional array.
9132  *  \param [in] value - the value to find within \a this array.
9133  *  \return bool - \a true in case if \a value is present within \a this array.
9134  *  \throw If \a this is not allocated.
9135  *  \throw If \a this->getNumberOfComponents() != 1.
9136  *  \sa findIdFirstEqual()
9137  */
9138 bool DataArrayInt::presenceOfValue(int value) const
9139 {
9140   return findIdFirstEqual(value)!=-1;
9141 }
9142
9143 /*!
9144  * This method expects to be called when number of components of this is equal to one.
9145  * This method returns true if it exists a tuple so that the value is contained in \b vals.
9146  * If not any tuple contains one of the values contained in 'vals' false is returned.
9147  * \sa DataArrayInt::findIdFirstEqual
9148  */
9149 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
9150 {
9151   return findIdFirstEqual(vals)!=-1;
9152 }
9153
9154 /*!
9155  * Accumulates values of each component of \a this array.
9156  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
9157  *         by the caller, that is filled by this method with sum value for each
9158  *         component.
9159  *  \throw If \a this is not allocated.
9160  */
9161 void DataArrayInt::accumulate(int *res) const
9162 {
9163   checkAllocated();
9164   const int *ptr=getConstPointer();
9165   int nbTuple=getNumberOfTuples();
9166   int nbComps=getNumberOfComponents();
9167   std::fill(res,res+nbComps,0);
9168   for(int i=0;i<nbTuple;i++)
9169     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
9170 }
9171
9172 int DataArrayInt::accumulate(int compId) const
9173 {
9174   checkAllocated();
9175   const int *ptr=getConstPointer();
9176   int nbTuple=getNumberOfTuples();
9177   int nbComps=getNumberOfComponents();
9178   if(compId<0 || compId>=nbComps)
9179     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
9180   int ret=0;
9181   for(int i=0;i<nbTuple;i++)
9182     ret+=ptr[i*nbComps+compId];
9183   return ret;
9184 }
9185
9186 /*!
9187  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
9188  * The returned array will have same number of components than \a this and number of tuples equal to
9189  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
9190  *
9191  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
9192  *
9193  * \param [in] bgOfIndex - begin (included) of the input index array.
9194  * \param [in] endOfIndex - end (excluded) of the input index array.
9195  * \return DataArrayInt * - the new instance having the same number of components than \a this.
9196  * 
9197  * \throw If bgOfIndex or end is NULL.
9198  * \throw If input index array is not ascendingly sorted.
9199  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
9200  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
9201  */
9202 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
9203 {
9204   if(!bgOfIndex || !endOfIndex)
9205     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
9206   checkAllocated();
9207   int nbCompo=getNumberOfComponents();
9208   int nbOfTuples=getNumberOfTuples();
9209   int sz=(int)std::distance(bgOfIndex,endOfIndex);
9210   if(sz<1)
9211     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
9212   sz--;
9213   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
9214   const int *w=bgOfIndex;
9215   if(*w<0 || *w>=nbOfTuples)
9216     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
9217   const int *srcPt=begin()+(*w)*nbCompo;
9218   int *tmp=ret->getPointer();
9219   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
9220     {
9221       std::fill(tmp,tmp+nbCompo,0);
9222       if(w[1]>=w[0])
9223         {
9224           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
9225             {
9226               if(j>=0 && j<nbOfTuples)
9227                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
9228               else
9229                 {
9230                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
9231                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9232                 }
9233             }
9234         }
9235       else
9236         {
9237           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
9238           throw INTERP_KERNEL::Exception(oss.str().c_str());
9239         }
9240     }
9241   ret->copyStringInfoFrom(*this);
9242   return ret.retn();
9243 }
9244
9245 /*!
9246  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
9247  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
9248  * offsetA2</em> and (2)
9249  * the number of component in the result array is same as that of each of given arrays.
9250  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
9251  * Info on components is copied from the first of the given arrays. Number of components
9252  * in the given arrays must be the same.
9253  *  \param [in] a1 - an array to include in the result array.
9254  *  \param [in] a2 - another array to include in the result array.
9255  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
9256  *  \return DataArrayInt * - the new instance of DataArrayInt.
9257  *          The caller is to delete this result array using decrRef() as it is no more
9258  *          needed.
9259  *  \throw If either \a a1 or \a a2 is NULL.
9260  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
9261  */
9262 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
9263 {
9264   if(!a1 || !a2)
9265     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
9266   int nbOfComp=a1->getNumberOfComponents();
9267   if(nbOfComp!=a2->getNumberOfComponents())
9268     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
9269   int nbOfTuple1=a1->getNumberOfTuples();
9270   int nbOfTuple2=a2->getNumberOfTuples();
9271   DataArrayInt *ret=DataArrayInt::New();
9272   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
9273   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
9274   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
9275   ret->copyStringInfoFrom(*a1);
9276   return ret;
9277 }
9278
9279 /*!
9280  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
9281  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
9282  * the number of component in the result array is same as that of each of given arrays.
9283  * Info on components is copied from the first of the given arrays. Number of components
9284  * in the given arrays must be  the same.
9285  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
9286  * not the object itself.
9287  *  \param [in] arr - a sequence of arrays to include in the result array.
9288  *  \return DataArrayInt * - the new instance of DataArrayInt.
9289  *          The caller is to delete this result array using decrRef() as it is no more
9290  *          needed.
9291  *  \throw If all arrays within \a arr are NULL.
9292  *  \throw If getNumberOfComponents() of arrays within \a arr.
9293  */
9294 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
9295 {
9296   std::vector<const DataArrayInt *> a;
9297   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9298     if(*it4)
9299       a.push_back(*it4);
9300   if(a.empty())
9301     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
9302   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
9303   int nbOfComp=(*it)->getNumberOfComponents();
9304   int nbt=(*it++)->getNumberOfTuples();
9305   for(int i=1;it!=a.end();it++,i++)
9306     {
9307       if((*it)->getNumberOfComponents()!=nbOfComp)
9308         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
9309       nbt+=(*it)->getNumberOfTuples();
9310     }
9311   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9312   ret->alloc(nbt,nbOfComp);
9313   int *pt=ret->getPointer();
9314   for(it=a.begin();it!=a.end();it++)
9315     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
9316   ret->copyStringInfoFrom(*(a[0]));
9317   return ret.retn();
9318 }
9319
9320 /*!
9321  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
9322  * A packed index array is an allocated array with one component, and at least one tuple. The first element
9323  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
9324  * 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.
9325  * 
9326  * \return DataArrayInt * - a new object to be managed by the caller.
9327  */
9328 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
9329 {
9330   int retSz=1;
9331   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
9332     {
9333       if(*it4)
9334         {
9335           (*it4)->checkAllocated();
9336           if((*it4)->getNumberOfComponents()!=1)
9337             {
9338               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9339               throw INTERP_KERNEL::Exception(oss.str().c_str());
9340             }
9341           int nbTupl=(*it4)->getNumberOfTuples();
9342           if(nbTupl<1)
9343             {
9344               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9345               throw INTERP_KERNEL::Exception(oss.str().c_str());
9346             }
9347           if((*it4)->front()!=0)
9348             {
9349               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
9350               throw INTERP_KERNEL::Exception(oss.str().c_str());
9351             }
9352           retSz+=nbTupl-1;
9353         }
9354       else
9355         {
9356           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
9357           throw INTERP_KERNEL::Exception(oss.str().c_str());
9358         }
9359     }
9360   if(arrs.empty())
9361     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
9362   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9363   ret->alloc(retSz,1);
9364   int *pt=ret->getPointer(); *pt++=0;
9365   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
9366     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
9367   ret->copyStringInfoFrom(*(arrs[0]));
9368   return ret.retn();
9369 }
9370
9371 /*!
9372  * Returns the maximal value and its location within \a this one-dimensional array.
9373  *  \param [out] tupleId - index of the tuple holding the maximal value.
9374  *  \return int - the maximal value among all values of \a this array.
9375  *  \throw If \a this->getNumberOfComponents() != 1
9376  *  \throw If \a this->getNumberOfTuples() < 1
9377  */
9378 int DataArrayInt::getMaxValue(int& tupleId) const
9379 {
9380   checkAllocated();
9381   if(getNumberOfComponents()!=1)
9382     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9383   int nbOfTuples=getNumberOfTuples();
9384   if(nbOfTuples<=0)
9385     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9386   const int *vals=getConstPointer();
9387   const int *loc=std::max_element(vals,vals+nbOfTuples);
9388   tupleId=(int)std::distance(vals,loc);
9389   return *loc;
9390 }
9391
9392 /*!
9393  * Returns the maximal value within \a this array that is allowed to have more than
9394  *  one component.
9395  *  \return int - the maximal value among all values of \a this array.
9396  *  \throw If \a this is not allocated.
9397  */
9398 int DataArrayInt::getMaxValueInArray() const
9399 {
9400   checkAllocated();
9401   const int *loc=std::max_element(begin(),end());
9402   return *loc;
9403 }
9404
9405 /*!
9406  * Returns the minimal value and its location within \a this one-dimensional array.
9407  *  \param [out] tupleId - index of the tuple holding the minimal value.
9408  *  \return int - the minimal value among all values of \a this array.
9409  *  \throw If \a this->getNumberOfComponents() != 1
9410  *  \throw If \a this->getNumberOfTuples() < 1
9411  */
9412 int DataArrayInt::getMinValue(int& tupleId) const
9413 {
9414   checkAllocated();
9415   if(getNumberOfComponents()!=1)
9416     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9417   int nbOfTuples=getNumberOfTuples();
9418   if(nbOfTuples<=0)
9419     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9420   const int *vals=getConstPointer();
9421   const int *loc=std::min_element(vals,vals+nbOfTuples);
9422   tupleId=(int)std::distance(vals,loc);
9423   return *loc;
9424 }
9425
9426 /*!
9427  * Returns the minimal value within \a this array that is allowed to have more than
9428  *  one component.
9429  *  \return int - the minimal value among all values of \a this array.
9430  *  \throw If \a this is not allocated.
9431  */
9432 int DataArrayInt::getMinValueInArray() const
9433 {
9434   checkAllocated();
9435   const int *loc=std::min_element(begin(),end());
9436   return *loc;
9437 }
9438
9439 /*!
9440  * Returns in a single walk in \a this the min value and the max value in \a this.
9441  * \a this is expected to be single component array.
9442  *
9443  * \param [out] minValue - the min value in \a this.
9444  * \param [out] maxValue - the max value in \a this.
9445  *
9446  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
9447  */
9448 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
9449 {
9450   checkAllocated();
9451   if(getNumberOfComponents()!=1)
9452     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
9453   int nbTuples(getNumberOfTuples());
9454   const int *pt(begin());
9455   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
9456   for(int i=0;i<nbTuples;i++,pt++)
9457     {
9458       if(*pt<minValue)
9459         minValue=*pt;
9460       if(*pt>maxValue)
9461         maxValue=*pt;
9462     }
9463 }
9464
9465 /*!
9466  * Converts every value of \a this array to its absolute value.
9467  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
9468  * should be called instead.
9469  *
9470  * \throw If \a this is not allocated.
9471  * \sa DataArrayInt::computeAbs
9472  */
9473 void DataArrayInt::abs()
9474 {
9475   checkAllocated();
9476   int *ptr(getPointer());
9477   std::size_t nbOfElems(getNbOfElems());
9478   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
9479   declareAsNew();
9480 }
9481
9482 /*!
9483  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
9484  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
9485  *
9486  * \return DataArrayInt * - the new instance of DataArrayInt containing the
9487  *         same number of tuples and component as \a this array.
9488  *         The caller is to delete this result array using decrRef() as it is no more
9489  *         needed.
9490  * \throw If \a this is not allocated.
9491  * \sa DataArrayInt::abs
9492  */
9493 DataArrayInt *DataArrayInt::computeAbs() const
9494 {
9495   checkAllocated();
9496   DataArrayInt *newArr(DataArrayInt::New());
9497   int nbOfTuples(getNumberOfTuples());
9498   int nbOfComp(getNumberOfComponents());
9499   newArr->alloc(nbOfTuples,nbOfComp);
9500   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
9501   newArr->copyStringInfoFrom(*this);
9502   return newArr;
9503 }
9504
9505 /*!
9506  * Apply a liner function to a given component of \a this array, so that
9507  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
9508  *  \param [in] a - the first coefficient of the function.
9509  *  \param [in] b - the second coefficient of the function.
9510  *  \param [in] compoId - the index of component to modify.
9511  *  \throw If \a this is not allocated.
9512  */
9513 void DataArrayInt::applyLin(int a, int b, int compoId)
9514 {
9515   checkAllocated();
9516   int *ptr=getPointer()+compoId;
9517   int nbOfComp=getNumberOfComponents();
9518   int nbOfTuple=getNumberOfTuples();
9519   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
9520     *ptr=a*(*ptr)+b;
9521   declareAsNew();
9522 }
9523
9524 /*!
9525  * Apply a liner function to all elements of \a this array, so that
9526  * an element _x_ becomes \f$ a * x + b \f$.
9527  *  \param [in] a - the first coefficient of the function.
9528  *  \param [in] b - the second coefficient of the function.
9529  *  \throw If \a this is not allocated.
9530  */
9531 void DataArrayInt::applyLin(int a, int b)
9532 {
9533   checkAllocated();
9534   int *ptr=getPointer();
9535   std::size_t nbOfElems=getNbOfElems();
9536   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9537     *ptr=a*(*ptr)+b;
9538   declareAsNew();
9539 }
9540
9541 /*!
9542  * Returns a full copy of \a this array except that sign of all elements is reversed.
9543  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
9544  *          same number of tuples and component as \a this array.
9545  *          The caller is to delete this result array using decrRef() as it is no more
9546  *          needed.
9547  *  \throw If \a this is not allocated.
9548  */
9549 DataArrayInt *DataArrayInt::negate() const
9550 {
9551   checkAllocated();
9552   DataArrayInt *newArr=DataArrayInt::New();
9553   int nbOfTuples=getNumberOfTuples();
9554   int nbOfComp=getNumberOfComponents();
9555   newArr->alloc(nbOfTuples,nbOfComp);
9556   const int *cptr=getConstPointer();
9557   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
9558   newArr->copyStringInfoFrom(*this);
9559   return newArr;
9560 }
9561
9562 /*!
9563  * Modify all elements of \a this array, so that
9564  * an element _x_ becomes \f$ numerator / x \f$.
9565  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9566  *           array, all elements processed before detection of the zero element remain
9567  *           modified.
9568  *  \param [in] numerator - the numerator used to modify array elements.
9569  *  \throw If \a this is not allocated.
9570  *  \throw If there is an element equal to 0 in \a this array.
9571  */
9572 void DataArrayInt::applyInv(int numerator)
9573 {
9574   checkAllocated();
9575   int *ptr=getPointer();
9576   std::size_t nbOfElems=getNbOfElems();
9577   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9578     {
9579       if(*ptr!=0)
9580         {
9581           *ptr=numerator/(*ptr);
9582         }
9583       else
9584         {
9585           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9586           oss << " !";
9587           throw INTERP_KERNEL::Exception(oss.str().c_str());
9588         }
9589     }
9590   declareAsNew();
9591 }
9592
9593 /*!
9594  * Modify all elements of \a this array, so that
9595  * an element _x_ becomes \f$ x / val \f$.
9596  *  \param [in] val - the denominator used to modify array elements.
9597  *  \throw If \a this is not allocated.
9598  *  \throw If \a val == 0.
9599  */
9600 void DataArrayInt::applyDivideBy(int val)
9601 {
9602   if(val==0)
9603     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
9604   checkAllocated();
9605   int *ptr=getPointer();
9606   std::size_t nbOfElems=getNbOfElems();
9607   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
9608   declareAsNew();
9609 }
9610
9611 /*!
9612  * Modify all elements of \a this array, so that
9613  * an element _x_ becomes  <em> x % val </em>.
9614  *  \param [in] val - the divisor used to modify array elements.
9615  *  \throw If \a this is not allocated.
9616  *  \throw If \a val <= 0.
9617  */
9618 void DataArrayInt::applyModulus(int val)
9619 {
9620   if(val<=0)
9621     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
9622   checkAllocated();
9623   int *ptr=getPointer();
9624   std::size_t nbOfElems=getNbOfElems();
9625   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
9626   declareAsNew();
9627 }
9628
9629 /*!
9630  * This method works only on data array with one component.
9631  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9632  * this[*id] in [\b vmin,\b vmax)
9633  * 
9634  * \param [in] vmin begin of range. This value is included in range (included).
9635  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9636  * \return a newly allocated data array that the caller should deal with.
9637  *
9638  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
9639  */
9640 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
9641 {
9642   checkAllocated();
9643   if(getNumberOfComponents()!=1)
9644     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsInRange : this must have exactly one component !");
9645   const int *cptr(begin());
9646   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9647   int nbOfTuples(getNumberOfTuples());
9648   for(int i=0;i<nbOfTuples;i++,cptr++)
9649     if(*cptr>=vmin && *cptr<vmax)
9650       ret->pushBackSilent(i);
9651   return ret.retn();
9652 }
9653
9654 /*!
9655  * This method works only on data array with one component.
9656  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9657  * this[*id] \b not in [\b vmin,\b vmax)
9658  * 
9659  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
9660  * \param [in] vmax end of range. This value is included in range (included).
9661  * \return a newly allocated data array that the caller should deal with.
9662  * 
9663  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
9664  */
9665 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
9666 {
9667   checkAllocated();
9668   if(getNumberOfComponents()!=1)
9669     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotInRange : this must have exactly one component !");
9670   const int *cptr(getConstPointer());
9671   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9672   int nbOfTuples(getNumberOfTuples());
9673   for(int i=0;i<nbOfTuples;i++,cptr++)
9674     if(*cptr<vmin || *cptr>=vmax)
9675       ret->pushBackSilent(i);
9676   return ret.retn();
9677 }
9678
9679 /*!
9680  * 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.
9681  *
9682  * \return a newly allocated data array that the caller should deal with.
9683  * \sa DataArrayInt::findIdsInRange
9684  */
9685 DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
9686 {
9687   checkAllocated();
9688   if(getNumberOfComponents()!=1)
9689     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsStricltyNegative : this must have exactly one component !");
9690   const int *cptr(getConstPointer());
9691   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9692   int nbOfTuples(getNumberOfTuples());
9693   for(int i=0;i<nbOfTuples;i++,cptr++)
9694     if(*cptr<0)
9695       ret->pushBackSilent(i);
9696   return ret.retn();
9697 }
9698
9699 /*!
9700  * This method works only on data array with one component.
9701  * 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.
9702  * 
9703  * \param [in] vmin begin of range. This value is included in range (included).
9704  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9705  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
9706 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
9707 {
9708   checkAllocated();
9709   if(getNumberOfComponents()!=1)
9710     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9711   int nbOfTuples=getNumberOfTuples();
9712   bool ret=true;
9713   const int *cptr=getConstPointer();
9714   for(int i=0;i<nbOfTuples;i++,cptr++)
9715     {
9716       if(*cptr>=vmin && *cptr<vmax)
9717         { ret=ret && *cptr==i; }
9718       else
9719         {
9720           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9721           throw INTERP_KERNEL::Exception(oss.str().c_str());
9722         }
9723     }
9724   return ret;
9725 }
9726
9727 /*!
9728  * Modify all elements of \a this array, so that
9729  * an element _x_ becomes <em> val % x </em>.
9730  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9731  *           array, all elements processed before detection of the zero element remain
9732  *           modified.
9733  *  \param [in] val - the divident used to modify array elements.
9734  *  \throw If \a this is not allocated.
9735  *  \throw If there is an element equal to or less than 0 in \a this array.
9736  */
9737 void DataArrayInt::applyRModulus(int val)
9738 {
9739   checkAllocated();
9740   int *ptr=getPointer();
9741   std::size_t nbOfElems=getNbOfElems();
9742   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9743     {
9744       if(*ptr>0)
9745         {
9746           *ptr=val%(*ptr);
9747         }
9748       else
9749         {
9750           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9751           oss << " !";
9752           throw INTERP_KERNEL::Exception(oss.str().c_str());
9753         }
9754     }
9755   declareAsNew();
9756 }
9757
9758 /*!
9759  * Modify all elements of \a this array, so that
9760  * an element _x_ becomes <em> val ^ x </em>.
9761  *  \param [in] val - the value used to apply pow on all array elements.
9762  *  \throw If \a this is not allocated.
9763  *  \throw If \a val < 0.
9764  */
9765 void DataArrayInt::applyPow(int val)
9766 {
9767   checkAllocated();
9768   if(val<0)
9769     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9770   int *ptr=getPointer();
9771   std::size_t nbOfElems=getNbOfElems();
9772   if(val==0)
9773     {
9774       std::fill(ptr,ptr+nbOfElems,1);
9775       return ;
9776     }
9777   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9778     {
9779       int tmp=1;
9780       for(int j=0;j<val;j++)
9781         tmp*=*ptr;
9782       *ptr=tmp;
9783     }
9784   declareAsNew();
9785 }
9786
9787 /*!
9788  * Modify all elements of \a this array, so that
9789  * an element _x_ becomes \f$ val ^ x \f$.
9790  *  \param [in] val - the value used to apply pow on all array elements.
9791  *  \throw If \a this is not allocated.
9792  *  \throw If there is an element < 0 in \a this array.
9793  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9794  *           array, all elements processed before detection of the zero element remain
9795  *           modified.
9796  */
9797 void DataArrayInt::applyRPow(int val)
9798 {
9799   checkAllocated();
9800   int *ptr=getPointer();
9801   std::size_t nbOfElems=getNbOfElems();
9802   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9803     {
9804       if(*ptr>=0)
9805         {
9806           int tmp=1;
9807           for(int j=0;j<*ptr;j++)
9808             tmp*=val;
9809           *ptr=tmp;
9810         }
9811       else
9812         {
9813           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9814           oss << " !";
9815           throw INTERP_KERNEL::Exception(oss.str().c_str());
9816         }
9817     }
9818   declareAsNew();
9819 }
9820
9821 /*!
9822  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9823  * of components in the result array is a sum of the number of components of given arrays
9824  * and (2) the number of tuples in the result array is same as that of each of given
9825  * arrays. In other words the i-th tuple of result array includes all components of
9826  * i-th tuples of all given arrays.
9827  * Number of tuples in the given arrays must be the same.
9828  *  \param [in] a1 - an array to include in the result array.
9829  *  \param [in] a2 - another array to include in the result array.
9830  *  \return DataArrayInt * - the new instance of DataArrayInt.
9831  *          The caller is to delete this result array using decrRef() as it is no more
9832  *          needed.
9833  *  \throw If both \a a1 and \a a2 are NULL.
9834  *  \throw If any given array is not allocated.
9835  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9836  */
9837 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9838 {
9839   std::vector<const DataArrayInt *> arr(2);
9840   arr[0]=a1; arr[1]=a2;
9841   return Meld(arr);
9842 }
9843
9844 /*!
9845  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9846  * of components in the result array is a sum of the number of components of given arrays
9847  * and (2) the number of tuples in the result array is same as that of each of given
9848  * arrays. In other words the i-th tuple of result array includes all components of
9849  * i-th tuples of all given arrays.
9850  * Number of tuples in the given arrays must be  the same.
9851  *  \param [in] arr - a sequence of arrays to include in the result array.
9852  *  \return DataArrayInt * - the new instance of DataArrayInt.
9853  *          The caller is to delete this result array using decrRef() as it is no more
9854  *          needed.
9855  *  \throw If all arrays within \a arr are NULL.
9856  *  \throw If any given array is not allocated.
9857  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9858  */
9859 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9860 {
9861   std::vector<const DataArrayInt *> a;
9862   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9863     if(*it4)
9864       a.push_back(*it4);
9865   if(a.empty())
9866     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9867   std::vector<const DataArrayInt *>::const_iterator it;
9868   for(it=a.begin();it!=a.end();it++)
9869     (*it)->checkAllocated();
9870   it=a.begin();
9871   int nbOfTuples=(*it)->getNumberOfTuples();
9872   std::vector<int> nbc(a.size());
9873   std::vector<const int *> pts(a.size());
9874   nbc[0]=(*it)->getNumberOfComponents();
9875   pts[0]=(*it++)->getConstPointer();
9876   for(int i=1;it!=a.end();it++,i++)
9877     {
9878       if(nbOfTuples!=(*it)->getNumberOfTuples())
9879         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9880       nbc[i]=(*it)->getNumberOfComponents();
9881       pts[i]=(*it)->getConstPointer();
9882     }
9883   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9884   DataArrayInt *ret=DataArrayInt::New();
9885   ret->alloc(nbOfTuples,totalNbOfComp);
9886   int *retPtr=ret->getPointer();
9887   for(int i=0;i<nbOfTuples;i++)
9888     for(int j=0;j<(int)a.size();j++)
9889       {
9890         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9891         pts[j]+=nbc[j];
9892       }
9893   int k=0;
9894   for(int i=0;i<(int)a.size();i++)
9895     for(int j=0;j<nbc[i];j++,k++)
9896       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
9897   return ret;
9898 }
9899
9900 /*!
9901  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9902  * The i-th item of the result array is an ID of a set of elements belonging to a
9903  * unique set of groups, which the i-th element is a part of. This set of elements
9904  * belonging to a unique set of groups is called \a family, so the result array contains
9905  * IDs of families each element belongs to.
9906  *
9907  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9908  * then there are 3 families:
9909  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9910  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9911  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9912  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9913  * stands for the element #3 which is in none of groups.
9914  *
9915  *  \param [in] groups - sequence of groups of element IDs.
9916  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9917  *         in \a groups.
9918  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9919  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9920  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9921  *         delete this array using decrRef() as it is no more needed.
9922  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9923  */
9924 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9925 {
9926   std::vector<const DataArrayInt *> groups2;
9927   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9928     if(*it4)
9929       groups2.push_back(*it4);
9930   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9931   ret->alloc(newNb,1);
9932   int *retPtr=ret->getPointer();
9933   std::fill(retPtr,retPtr+newNb,0);
9934   int fid=1;
9935   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9936     {
9937       const int *ptr=(*iter)->getConstPointer();
9938       std::size_t nbOfElem=(*iter)->getNbOfElems();
9939       int sfid=fid;
9940       for(int j=0;j<sfid;j++)
9941         {
9942           bool found=false;
9943           for(std::size_t i=0;i<nbOfElem;i++)
9944             {
9945               if(ptr[i]>=0 && ptr[i]<newNb)
9946                 {
9947                   if(retPtr[ptr[i]]==j)
9948                     {
9949                       retPtr[ptr[i]]=fid;
9950                       found=true;
9951                     }
9952                 }
9953               else
9954                 {
9955                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9956                   oss << ") !";
9957                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9958                 }
9959             }
9960           if(found)
9961             fid++;
9962         }
9963     }
9964   fidsOfGroups.clear();
9965   fidsOfGroups.resize(groups2.size());
9966   int grId=0;
9967   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9968     {
9969       std::set<int> tmp;
9970       const int *ptr=(*iter)->getConstPointer();
9971       std::size_t nbOfElem=(*iter)->getNbOfElems();
9972       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9973         tmp.insert(retPtr[*p]);
9974       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9975     }
9976   return ret.retn();
9977 }
9978
9979 /*!
9980  * Returns a new DataArrayInt which contains all elements 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 unite.
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::BuildUnion(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::BuildUnion : 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       r.insert(pt,pt+nbOfTuples);
10008     }
10009   DataArrayInt *ret=DataArrayInt::New();
10010   ret->alloc((int)r.size(),1);
10011   std::copy(r.begin(),r.end(),ret->getPointer());
10012   return ret;
10013 }
10014
10015 /*!
10016  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
10017  * arrays. The result array does not contain any duplicates and its values
10018  * are sorted in ascending order.
10019  *  \param [in] arr - sequence of DataArrayInt's to intersect.
10020  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10021  *         array using decrRef() as it is no more needed.
10022  *  \throw If any \a arr[i] is not allocated.
10023  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
10024  */
10025 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
10026 {
10027   std::vector<const DataArrayInt *> a;
10028   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
10029     if(*it4)
10030       a.push_back(*it4);
10031   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
10032     {
10033       (*it)->checkAllocated();
10034       if((*it)->getNumberOfComponents()!=1)
10035         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
10036     }
10037   //
10038   std::set<int> r;
10039   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
10040     {
10041       const int *pt=(*it)->getConstPointer();
10042       int nbOfTuples=(*it)->getNumberOfTuples();
10043       std::set<int> s1(pt,pt+nbOfTuples);
10044       if(it!=a.begin())
10045         {
10046           std::set<int> r2;
10047           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
10048           r=r2;
10049         }
10050       else
10051         r=s1;
10052     }
10053   DataArrayInt *ret(DataArrayInt::New());
10054   ret->alloc((int)r.size(),1);
10055   std::copy(r.begin(),r.end(),ret->getPointer());
10056   return ret;
10057 }
10058
10059 /// @cond INTERNAL
10060 namespace MEDCouplingImpl
10061 {
10062   class OpSwitchedOn
10063   {
10064   public:
10065     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
10066     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
10067   private:
10068     int *_pt;
10069     int _cnt;
10070   };
10071
10072   class OpSwitchedOff
10073   {
10074   public:
10075     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
10076     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
10077   private:
10078     int *_pt;
10079     int _cnt;
10080   };
10081 }
10082 /// @endcond
10083
10084 /*!
10085  * This method returns the list of ids in ascending mode so that v[id]==true.
10086  */
10087 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
10088 {
10089   int sz((int)std::count(v.begin(),v.end(),true));
10090   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10091   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
10092   return ret.retn();
10093 }
10094
10095 /*!
10096  * This method returns the list of ids in ascending mode so that v[id]==false.
10097  */
10098 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
10099 {
10100   int sz((int)std::count(v.begin(),v.end(),false));
10101   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10102   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
10103   return ret.retn();
10104 }
10105
10106 /*!
10107  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
10108  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
10109  *
10110  * \param [in] v the input data structure to be translate into skyline format.
10111  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
10112  * \param [out] dataIndex the second element of the skyline format.
10113  */
10114 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
10115 {
10116   int sz((int)v.size());
10117   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
10118   ret1->alloc(sz+1,1);
10119   int *pt(ret1->getPointer()); *pt=0;
10120   for(int i=0;i<sz;i++,pt++)
10121     pt[1]=pt[0]+(int)v[i].size();
10122   ret0->alloc(ret1->back(),1);
10123   pt=ret0->getPointer();
10124   for(int i=0;i<sz;i++)
10125     pt=std::copy(v[i].begin(),v[i].end(),pt);
10126   data=ret0.retn(); dataIndex=ret1.retn();
10127 }
10128
10129 /*!
10130  * Returns a new DataArrayInt which contains a complement of elements of \a this
10131  * one-dimensional array. I.e. the result array contains all elements from the range [0,
10132  * \a nbOfElement) not present in \a this array.
10133  *  \param [in] nbOfElement - maximal size of the result array.
10134  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10135  *         array using decrRef() as it is no more needed.
10136  *  \throw If \a this is not allocated.
10137  *  \throw If \a this->getNumberOfComponents() != 1.
10138  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
10139  *         nbOfElement ).
10140  */
10141 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
10142 {
10143   checkAllocated();
10144   if(getNumberOfComponents()!=1)
10145     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
10146   std::vector<bool> tmp(nbOfElement);
10147   const int *pt=getConstPointer();
10148   int nbOfTuples=getNumberOfTuples();
10149   for(const int *w=pt;w!=pt+nbOfTuples;w++)
10150     if(*w>=0 && *w<nbOfElement)
10151       tmp[*w]=true;
10152     else
10153       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
10154   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
10155   DataArrayInt *ret=DataArrayInt::New();
10156   ret->alloc(nbOfRetVal,1);
10157   int j=0;
10158   int *retPtr=ret->getPointer();
10159   for(int i=0;i<nbOfElement;i++)
10160     if(!tmp[i])
10161       retPtr[j++]=i;
10162   return ret;
10163 }
10164
10165 /*!
10166  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
10167  * from an \a other one-dimensional array.
10168  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
10169  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
10170  *         caller is to delete this array using decrRef() as it is no more needed.
10171  *  \throw If \a other is NULL.
10172  *  \throw If \a other is not allocated.
10173  *  \throw If \a other->getNumberOfComponents() != 1.
10174  *  \throw If \a this is not allocated.
10175  *  \throw If \a this->getNumberOfComponents() != 1.
10176  *  \sa DataArrayInt::buildSubstractionOptimized()
10177  */
10178 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
10179 {
10180   if(!other)
10181     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
10182   checkAllocated();
10183   other->checkAllocated();
10184   if(getNumberOfComponents()!=1)
10185     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
10186   if(other->getNumberOfComponents()!=1)
10187     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
10188   const int *pt=getConstPointer();
10189   int nbOfTuples=getNumberOfTuples();
10190   std::set<int> s1(pt,pt+nbOfTuples);
10191   pt=other->getConstPointer();
10192   nbOfTuples=other->getNumberOfTuples();
10193   std::set<int> s2(pt,pt+nbOfTuples);
10194   std::vector<int> r;
10195   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
10196   DataArrayInt *ret=DataArrayInt::New();
10197   ret->alloc((int)r.size(),1);
10198   std::copy(r.begin(),r.end(),ret->getPointer());
10199   return ret;
10200 }
10201
10202 /*!
10203  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
10204  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
10205  * 
10206  * \param [in] other an array with one component and expected to be sorted ascendingly.
10207  * \ret list of ids in \a this but not in \a other.
10208  * \sa DataArrayInt::buildSubstraction
10209  */
10210 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
10211 {
10212   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
10213   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
10214   checkAllocated(); other->checkAllocated();
10215   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
10216   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
10217   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
10218   const int *work1(pt1Bg),*work2(pt2Bg);
10219   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
10220   for(;work1!=pt1End;work1++)
10221     {
10222       if(work2!=pt2End && *work1==*work2)
10223         work2++;
10224       else
10225         ret->pushBackSilent(*work1);
10226     }
10227   return ret.retn();
10228 }
10229
10230
10231 /*!
10232  * Returns a new DataArrayInt which contains all elements of \a this and a given
10233  * one-dimensional arrays. The result array does not contain any duplicates
10234  * and its values are sorted in ascending order.
10235  *  \param [in] other - an array to unite with \a this one.
10236  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10237  *         array using decrRef() as it is no more needed.
10238  *  \throw If \a this or \a other is not allocated.
10239  *  \throw If \a this->getNumberOfComponents() != 1.
10240  *  \throw If \a other->getNumberOfComponents() != 1.
10241  */
10242 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
10243 {
10244   std::vector<const DataArrayInt *>arrs(2);
10245   arrs[0]=this; arrs[1]=other;
10246   return BuildUnion(arrs);
10247 }
10248
10249
10250 /*!
10251  * Returns a new DataArrayInt which contains elements present in both \a this and a given
10252  * one-dimensional arrays. The result array does not contain any duplicates
10253  * and its values are sorted in ascending order.
10254  *  \param [in] other - an array to intersect with \a this one.
10255  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10256  *         array using decrRef() as it is no more needed.
10257  *  \throw If \a this or \a other is not allocated.
10258  *  \throw If \a this->getNumberOfComponents() != 1.
10259  *  \throw If \a other->getNumberOfComponents() != 1.
10260  */
10261 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
10262 {
10263   std::vector<const DataArrayInt *>arrs(2);
10264   arrs[0]=this; arrs[1]=other;
10265   return BuildIntersection(arrs);
10266 }
10267
10268 /*!
10269  * This method can be applied on allocated with one component DataArrayInt instance.
10270  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
10271  * 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]
10272  * 
10273  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
10274  * \throw if \a this is not allocated or if \a this has not exactly one component.
10275  * \sa DataArrayInt::buildUniqueNotSorted
10276  */
10277 DataArrayInt *DataArrayInt::buildUnique() const
10278 {
10279   checkAllocated();
10280   if(getNumberOfComponents()!=1)
10281     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
10282   int nbOfTuples=getNumberOfTuples();
10283   MCAuto<DataArrayInt> tmp=deepCopy();
10284   int *data=tmp->getPointer();
10285   int *last=std::unique(data,data+nbOfTuples);
10286   MCAuto<DataArrayInt> ret=DataArrayInt::New();
10287   ret->alloc(std::distance(data,last),1);
10288   std::copy(data,last,ret->getPointer());
10289   return ret.retn();
10290 }
10291
10292 /*!
10293  * This method can be applied on allocated with one component DataArrayInt instance.
10294  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
10295  *
10296  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
10297  *
10298  * \throw if \a this is not allocated or if \a this has not exactly one component.
10299  *
10300  * \sa DataArrayInt::buildUnique
10301  */
10302 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
10303 {
10304   checkAllocated();
10305     if(getNumberOfComponents()!=1)
10306       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
10307   int minVal,maxVal;
10308   getMinMaxValues(minVal,maxVal);
10309   std::vector<bool> b(maxVal-minVal+1,false);
10310   const int *ptBg(begin()),*endBg(end());
10311   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
10312   for(const int *pt=ptBg;pt!=endBg;pt++)
10313     {
10314       if(!b[*pt-minVal])
10315         {
10316           ret->pushBackSilent(*pt);
10317           b[*pt-minVal]=true;
10318         }
10319     }
10320   ret->copyStringInfoFrom(*this);
10321   return ret.retn();
10322 }
10323
10324 /*!
10325  * Returns a new DataArrayInt which contains size of every of groups described by \a this
10326  * "index" array. Such "index" array is returned for example by 
10327  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
10328  * "MEDCouplingUMesh::buildDescendingConnectivity" and
10329  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
10330  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
10331  * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
10332  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
10333  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
10334  *          The caller is to delete this array using decrRef() as it is no more needed. 
10335  *  \throw If \a this is not allocated.
10336  *  \throw If \a this->getNumberOfComponents() != 1.
10337  *  \throw If \a this->getNumberOfTuples() < 2.
10338  *
10339  *  \b Example: <br> 
10340  *         - this contains [1,3,6,7,7,9,15]
10341  *         - result array contains [2,3,1,0,2,6],
10342  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
10343  *
10344  * \sa DataArrayInt::computeOffsetsFull
10345  */
10346 DataArrayInt *DataArrayInt::deltaShiftIndex() const
10347 {
10348   checkAllocated();
10349   if(getNumberOfComponents()!=1)
10350     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
10351   int nbOfTuples=getNumberOfTuples();
10352   if(nbOfTuples<2)
10353     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
10354   const int *ptr=getConstPointer();
10355   DataArrayInt *ret=DataArrayInt::New();
10356   ret->alloc(nbOfTuples-1,1);
10357   int *out=ret->getPointer();
10358   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
10359   return ret;
10360 }
10361
10362 /*!
10363  * Modifies \a this one-dimensional array so that value of each element \a x
10364  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10365  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
10366  * and components remains the same.<br>
10367  * This method is useful for allToAllV in MPI with contiguous policy. This method
10368  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
10369  * this one.
10370  *  \throw If \a this is not allocated.
10371  *  \throw If \a this->getNumberOfComponents() != 1.
10372  *
10373  *  \b Example: <br>
10374  *          - Before \a this contains [3,5,1,2,0,8]
10375  *          - After \a this contains  [0,3,8,9,11,11]<br>
10376  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
10377  *          array is retained and thus there is no space to store the last element.
10378  */
10379 void DataArrayInt::computeOffsets()
10380 {
10381   checkAllocated();
10382   if(getNumberOfComponents()!=1)
10383     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
10384   int nbOfTuples=getNumberOfTuples();
10385   if(nbOfTuples==0)
10386     return ;
10387   int *work=getPointer();
10388   int tmp=work[0];
10389   work[0]=0;
10390   for(int i=1;i<nbOfTuples;i++)
10391     {
10392       int tmp2=work[i];
10393       work[i]=work[i-1]+tmp;
10394       tmp=tmp2;
10395     }
10396   declareAsNew();
10397 }
10398
10399
10400 /*!
10401  * Modifies \a this one-dimensional array so that value of each element \a x
10402  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10403  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
10404  * components remains the same and number of tuples is inceamented by one.<br>
10405  * This method is useful for allToAllV in MPI with contiguous policy. This method
10406  * differs from computeOffsets() in that the number of tuples is changed by this one.
10407  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
10408  *  \throw If \a this is not allocated.
10409  *  \throw If \a this->getNumberOfComponents() != 1.
10410  *
10411  *  \b Example: <br>
10412  *          - Before \a this contains [3,5,1,2,0,8]
10413  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
10414  * \sa DataArrayInt::deltaShiftIndex
10415  */
10416 void DataArrayInt::computeOffsetsFull()
10417 {
10418   checkAllocated();
10419   if(getNumberOfComponents()!=1)
10420     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
10421   int nbOfTuples=getNumberOfTuples();
10422   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
10423   const int *work=getConstPointer();
10424   ret[0]=0;
10425   for(int i=0;i<nbOfTuples;i++)
10426     ret[i+1]=work[i]+ret[i];
10427   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
10428   declareAsNew();
10429 }
10430
10431 /*!
10432  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
10433  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
10434  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
10435  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
10436  * filling completely one of the ranges in \a this.
10437  *
10438  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
10439  * \param [out] rangeIdsFetched the range ids fetched
10440  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
10441  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
10442  *
10443  * \sa DataArrayInt::computeOffsetsFull
10444  *
10445  *  \b Example: <br>
10446  *          - \a this : [0,3,7,9,15,18]
10447  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
10448  *          - \a rangeIdsFetched result array: [0,2,4]
10449  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
10450  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
10451  * <br>
10452  */
10453 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
10454 {
10455   if(!listOfIds)
10456     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
10457   listOfIds->checkAllocated(); checkAllocated();
10458   if(listOfIds->getNumberOfComponents()!=1)
10459     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
10460   if(getNumberOfComponents()!=1)
10461     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
10462   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
10463   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
10464   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
10465   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
10466   while(tupPtr!=tupEnd && offPtr!=offEnd)
10467     {
10468       if(*tupPtr==*offPtr)
10469         {
10470           int i=offPtr[0];
10471           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
10472           if(i==offPtr[1])
10473             {
10474               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
10475               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
10476               offPtr++;
10477             }
10478         }
10479       else
10480         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
10481     }
10482   rangeIdsFetched=ret0.retn();
10483   idsInInputListThatFetch=ret1.retn();
10484 }
10485
10486 /*!
10487  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
10488  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10489  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10490  * beginning within the "iota" array. And \a this is a one-dimensional array
10491  * considered as a selector of groups described by \a offsets to include into the result array.
10492  *  \throw If \a offsets is NULL.
10493  *  \throw If \a offsets is not allocated.
10494  *  \throw If \a offsets->getNumberOfComponents() != 1.
10495  *  \throw If \a offsets is not monotonically increasing.
10496  *  \throw If \a this is not allocated.
10497  *  \throw If \a this->getNumberOfComponents() != 1.
10498  *  \throw If any element of \a this is not a valid index for \a offsets array.
10499  *
10500  *  \b Example: <br>
10501  *          - \a this: [0,2,3]
10502  *          - \a offsets: [0,3,6,10,14,20]
10503  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
10504  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
10505  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
10506  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
10507  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
10508  */
10509 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
10510 {
10511   if(!offsets)
10512     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
10513   checkAllocated();
10514   if(getNumberOfComponents()!=1)
10515     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
10516   offsets->checkAllocated();
10517   if(offsets->getNumberOfComponents()!=1)
10518     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
10519   int othNbTuples=offsets->getNumberOfTuples()-1;
10520   int nbOfTuples=getNumberOfTuples();
10521   int retNbOftuples=0;
10522   const int *work=getConstPointer();
10523   const int *offPtr=offsets->getConstPointer();
10524   for(int i=0;i<nbOfTuples;i++)
10525     {
10526       int val=work[i];
10527       if(val>=0 && val<othNbTuples)
10528         {
10529           int delta=offPtr[val+1]-offPtr[val];
10530           if(delta>=0)
10531             retNbOftuples+=delta;
10532           else
10533             {
10534               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
10535               throw INTERP_KERNEL::Exception(oss.str().c_str());
10536             }
10537         }
10538       else
10539         {
10540           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
10541           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
10542           throw INTERP_KERNEL::Exception(oss.str().c_str());
10543         }
10544     }
10545   MCAuto<DataArrayInt> ret=DataArrayInt::New();
10546   ret->alloc(retNbOftuples,1);
10547   int *retPtr=ret->getPointer();
10548   for(int i=0;i<nbOfTuples;i++)
10549     {
10550       int val=work[i];
10551       int start=offPtr[val];
10552       int off=offPtr[val+1]-start;
10553       for(int j=0;j<off;j++,retPtr++)
10554         *retPtr=start+j;
10555     }
10556   return ret.retn();
10557 }
10558
10559 /*!
10560  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
10561  * scaled array (monotonically increasing).
10562 from that of \a this and \a
10563  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10564  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10565  * beginning within the "iota" array. And \a this is a one-dimensional array
10566  * considered as a selector of groups described by \a offsets to include into the result array.
10567  *  \throw If \a  is NULL.
10568  *  \throw If \a this is not allocated.
10569  *  \throw If \a this->getNumberOfComponents() != 1.
10570  *  \throw If \a this->getNumberOfTuples() == 0.
10571  *  \throw If \a this is not monotonically increasing.
10572  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
10573  *
10574  *  \b Example: <br>
10575  *          - \a bg , \a stop and \a step : (0,5,2)
10576  *          - \a this: [0,3,6,10,14,20]
10577  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
10578  */
10579 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
10580 {
10581   if(!isAllocated())
10582     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
10583   if(getNumberOfComponents()!=1)
10584     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
10585   int nbOfTuples(getNumberOfTuples());
10586   if(nbOfTuples==0)
10587     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
10588   const int *ids(begin());
10589   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
10590   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10591     {
10592       if(pos>=0 && pos<nbOfTuples-1)
10593         {
10594           int delta(ids[pos+1]-ids[pos]);
10595           sz+=delta;
10596           if(delta<0)
10597             {
10598               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
10599               throw INTERP_KERNEL::Exception(oss.str().c_str());
10600             }          
10601         }
10602       else
10603         {
10604           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
10605           throw INTERP_KERNEL::Exception(oss.str().c_str());
10606         }
10607     }
10608   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10609   int *retPtr(ret->getPointer());
10610   pos=bg;
10611   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10612     {
10613       int delta(ids[pos+1]-ids[pos]);
10614       for(int j=0;j<delta;j++,retPtr++)
10615         *retPtr=pos;
10616     }
10617   return ret.retn();
10618 }
10619
10620 /*!
10621  * 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.
10622  * 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
10623  * in tuple **i** of returned DataArrayInt.
10624  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
10625  *
10626  * 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)]
10627  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
10628  * 
10629  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10630  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10631  * \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
10632  *        is thrown if no ranges in \a ranges contains value in \a this.
10633  * 
10634  * \sa DataArrayInt::findIdInRangeForEachTuple
10635  */
10636 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
10637 {
10638   if(!ranges)
10639     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
10640   if(ranges->getNumberOfComponents()!=2)
10641     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
10642   checkAllocated();
10643   if(getNumberOfComponents()!=1)
10644     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
10645   int nbTuples=getNumberOfTuples();
10646   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10647   int nbOfRanges=ranges->getNumberOfTuples();
10648   const int *rangesPtr=ranges->getConstPointer();
10649   int *retPtr=ret->getPointer();
10650   const int *inPtr=getConstPointer();
10651   for(int i=0;i<nbTuples;i++,retPtr++)
10652     {
10653       int val=inPtr[i];
10654       bool found=false;
10655       for(int j=0;j<nbOfRanges && !found;j++)
10656         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10657           { *retPtr=j; found=true; }
10658       if(found)
10659         continue;
10660       else
10661         {
10662           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
10663           throw INTERP_KERNEL::Exception(oss.str().c_str());
10664         }
10665     }
10666   return ret.retn();
10667 }
10668
10669 /*!
10670  * 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.
10671  * 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
10672  * in tuple **i** of returned DataArrayInt.
10673  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
10674  *
10675  * 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)]
10676  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
10677  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
10678  * 
10679  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10680  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10681  * \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
10682  *        is thrown if no ranges in \a ranges contains value in \a this.
10683  * \sa DataArrayInt::findRangeIdForEachTuple
10684  */
10685 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
10686 {
10687   if(!ranges)
10688     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
10689   if(ranges->getNumberOfComponents()!=2)
10690     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
10691   checkAllocated();
10692   if(getNumberOfComponents()!=1)
10693     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
10694   int nbTuples=getNumberOfTuples();
10695   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10696   int nbOfRanges=ranges->getNumberOfTuples();
10697   const int *rangesPtr=ranges->getConstPointer();
10698   int *retPtr=ret->getPointer();
10699   const int *inPtr=getConstPointer();
10700   for(int i=0;i<nbTuples;i++,retPtr++)
10701     {
10702       int val=inPtr[i];
10703       bool found=false;
10704       for(int j=0;j<nbOfRanges && !found;j++)
10705         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10706           { *retPtr=val-rangesPtr[2*j]; found=true; }
10707       if(found)
10708         continue;
10709       else
10710         {
10711           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
10712           throw INTERP_KERNEL::Exception(oss.str().c_str());
10713         }
10714     }
10715   return ret.retn();
10716 }
10717
10718 /*!
10719  * \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).
10720  * 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).
10721  * 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 !
10722  * If this method has correctly worked, \a this will be able to be considered as a linked list.
10723  * This method does nothing if number of tuples is lower of equal to 1.
10724  *
10725  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
10726  *
10727  * \sa MEDCouplingUMesh::orderConsecutiveCells1D
10728  */
10729 void DataArrayInt::sortEachPairToMakeALinkedList()
10730 {
10731   checkAllocated();
10732   if(getNumberOfComponents()!=2)
10733     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
10734   int nbOfTuples(getNumberOfTuples());
10735   if(nbOfTuples<=1)
10736     return ;
10737   int *conn(getPointer());
10738   for(int i=1;i<nbOfTuples;i++,conn+=2)
10739     {
10740       if(i>1)
10741         {
10742           if(conn[2]==conn[3])
10743             {
10744               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
10745               throw INTERP_KERNEL::Exception(oss.str().c_str());
10746             }
10747           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
10748             std::swap(conn[2],conn[3]);
10749           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
10750           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
10751             {
10752               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
10753               throw INTERP_KERNEL::Exception(oss.str().c_str());
10754             }
10755         }
10756       else
10757         {
10758           if(conn[0]==conn[1] || conn[2]==conn[3])
10759             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
10760           int tmp[4];
10761           std::set<int> s;
10762           s.insert(conn,conn+4);
10763           if(s.size()!=3)
10764             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
10765           if(std::count(conn,conn+4,conn[0])==2)
10766             {
10767               tmp[0]=conn[1];
10768               tmp[1]=conn[0];
10769               tmp[2]=conn[0];
10770               if(conn[2]==conn[0])
10771                 { tmp[3]=conn[3]; }
10772               else
10773                 { tmp[3]=conn[2];}
10774               std::copy(tmp,tmp+4,conn);
10775             }
10776           else
10777             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
10778               if(conn[1]==conn[3])
10779                 std::swap(conn[2],conn[3]);
10780             }
10781         }
10782     }
10783 }
10784
10785 /*!
10786  * 
10787  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
10788  *             \a nbTimes  should be at least equal to 1.
10789  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
10790  * \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.
10791  */
10792 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
10793 {
10794   checkAllocated();
10795   if(getNumberOfComponents()!=1)
10796     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
10797   if(nbTimes<1)
10798     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
10799   int nbTuples=getNumberOfTuples();
10800   const int *inPtr=getConstPointer();
10801   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
10802   int *retPtr=ret->getPointer();
10803   for(int i=0;i<nbTuples;i++,inPtr++)
10804     {
10805       int val=*inPtr;
10806       for(int j=0;j<nbTimes;j++,retPtr++)
10807         *retPtr=val;
10808     }
10809   ret->copyStringInfoFrom(*this);
10810   return ret.retn();
10811 }
10812
10813 /*!
10814  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
10815  * But the number of components can be different from one.
10816  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
10817  */
10818 DataArrayInt *DataArrayInt::getDifferentValues() const
10819 {
10820   checkAllocated();
10821   std::set<int> ret;
10822   ret.insert(begin(),end());
10823   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
10824   std::copy(ret.begin(),ret.end(),ret2->getPointer());
10825   return ret2.retn();
10826 }
10827
10828 /*!
10829  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
10830  * them it tells which tuple id have this id.
10831  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
10832  * This method returns two arrays having same size.
10833  * 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.
10834  * 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]]
10835  */
10836 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10837 {
10838   checkAllocated();
10839   if(getNumberOfComponents()!=1)
10840     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10841   int id=0;
10842   std::map<int,int> m,m2,m3;
10843   for(const int *w=begin();w!=end();w++)
10844     m[*w]++;
10845   differentIds.resize(m.size());
10846   std::vector<DataArrayInt *> ret(m.size());
10847   std::vector<int *> retPtr(m.size());
10848   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10849     {
10850       m2[(*it).first]=id;
10851       ret[id]=DataArrayInt::New();
10852       ret[id]->alloc((*it).second,1);
10853       retPtr[id]=ret[id]->getPointer();
10854       differentIds[id]=(*it).first;
10855     }
10856   id=0;
10857   for(const int *w=begin();w!=end();w++,id++)
10858     {
10859       retPtr[m2[*w]][m3[*w]++]=id;
10860     }
10861   return ret;
10862 }
10863
10864 /*!
10865  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10866  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10867  *
10868  * \param [in] nbOfSlices - number of slices expected.
10869  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10870  * 
10871  * \sa DataArray::GetSlice
10872  * \throw If \a this is not allocated or not with exactly one component.
10873  * \throw If an element in \a this if < 0.
10874  */
10875 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10876 {
10877   if(!isAllocated() || getNumberOfComponents()!=1)
10878     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10879   if(nbOfSlices<=0)
10880     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10881   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10882   int sumPerSlc(sum/nbOfSlices),pos(0);
10883   const int *w(begin());
10884   std::vector< std::pair<int,int> > ret(nbOfSlices);
10885   for(int i=0;i<nbOfSlices;i++)
10886     {
10887       std::pair<int,int> p(pos,-1);
10888       int locSum(0);
10889       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10890       if(i!=nbOfSlices-1)
10891         p.second=pos;
10892       else
10893         p.second=nbOfTuples;
10894       ret[i]=p;
10895     }
10896   return ret;
10897 }
10898
10899 /*!
10900  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10901  * valid cases.
10902  * 1.  The arrays have same number of tuples and components. Then each value of
10903  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10904  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10905  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10906  *   component. Then
10907  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10908  * 3.  The arrays have same number of components and one array, say _a2_, has one
10909  *   tuple. Then
10910  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10911  *
10912  * Info on components is copied either from the first array (in the first case) or from
10913  * the array with maximal number of elements (getNbOfElems()).
10914  *  \param [in] a1 - an array to sum up.
10915  *  \param [in] a2 - another array to sum up.
10916  *  \return DataArrayInt * - the new instance of DataArrayInt.
10917  *          The caller is to delete this result array using decrRef() as it is no more
10918  *          needed.
10919  *  \throw If either \a a1 or \a a2 is NULL.
10920  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10921  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10922  *         none of them has number of tuples or components equal to 1.
10923  */
10924 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10925 {
10926   if(!a1 || !a2)
10927     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10928   int nbOfTuple=a1->getNumberOfTuples();
10929   int nbOfTuple2=a2->getNumberOfTuples();
10930   int nbOfComp=a1->getNumberOfComponents();
10931   int nbOfComp2=a2->getNumberOfComponents();
10932   MCAuto<DataArrayInt> ret=0;
10933   if(nbOfTuple==nbOfTuple2)
10934     {
10935       if(nbOfComp==nbOfComp2)
10936         {
10937           ret=DataArrayInt::New();
10938           ret->alloc(nbOfTuple,nbOfComp);
10939           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10940           ret->copyStringInfoFrom(*a1);
10941         }
10942       else
10943         {
10944           int nbOfCompMin,nbOfCompMax;
10945           const DataArrayInt *aMin, *aMax;
10946           if(nbOfComp>nbOfComp2)
10947             {
10948               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10949               aMin=a2; aMax=a1;
10950             }
10951           else
10952             {
10953               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10954               aMin=a1; aMax=a2;
10955             }
10956           if(nbOfCompMin==1)
10957             {
10958               ret=DataArrayInt::New();
10959               ret->alloc(nbOfTuple,nbOfCompMax);
10960               const int *aMinPtr=aMin->getConstPointer();
10961               const int *aMaxPtr=aMax->getConstPointer();
10962               int *res=ret->getPointer();
10963               for(int i=0;i<nbOfTuple;i++)
10964                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10965               ret->copyStringInfoFrom(*aMax);
10966             }
10967           else
10968             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10969         }
10970     }
10971   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10972     {
10973       if(nbOfComp==nbOfComp2)
10974         {
10975           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10976           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10977           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10978           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10979           ret=DataArrayInt::New();
10980           ret->alloc(nbOfTupleMax,nbOfComp);
10981           int *res=ret->getPointer();
10982           for(int i=0;i<nbOfTupleMax;i++)
10983             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10984           ret->copyStringInfoFrom(*aMax);
10985         }
10986       else
10987         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10988     }
10989   else
10990     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10991   return ret.retn();
10992 }
10993
10994 /*!
10995  * Adds values of another DataArrayInt to values of \a this one. There are 3
10996  * valid cases.
10997  * 1.  The arrays have same number of tuples and components. Then each value of
10998  *   \a other array is added to the corresponding value of \a this array, i.e.:
10999  *   _a_ [ i, j ] += _other_ [ i, j ].
11000  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11001  *   _a_ [ i, j ] += _other_ [ i, 0 ].
11002  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11003  *   _a_ [ i, j ] += _a2_ [ 0, j ].
11004  *
11005  *  \param [in] other - an array to add to \a this one.
11006  *  \throw If \a other is NULL.
11007  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11008  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11009  *         \a other has number of both tuples and components not equal to 1.
11010  */
11011 void DataArrayInt::addEqual(const DataArrayInt *other)
11012 {
11013   if(!other)
11014     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
11015   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
11016   checkAllocated(); other->checkAllocated();
11017   int nbOfTuple=getNumberOfTuples();
11018   int nbOfTuple2=other->getNumberOfTuples();
11019   int nbOfComp=getNumberOfComponents();
11020   int nbOfComp2=other->getNumberOfComponents();
11021   if(nbOfTuple==nbOfTuple2)
11022     {
11023       if(nbOfComp==nbOfComp2)
11024         {
11025           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
11026         }
11027       else if(nbOfComp2==1)
11028         {
11029           int *ptr=getPointer();
11030           const int *ptrc=other->getConstPointer();
11031           for(int i=0;i<nbOfTuple;i++)
11032             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
11033         }
11034       else
11035         throw INTERP_KERNEL::Exception(msg);
11036     }
11037   else if(nbOfTuple2==1)
11038     {
11039       if(nbOfComp2==nbOfComp)
11040         {
11041           int *ptr=getPointer();
11042           const int *ptrc=other->getConstPointer();
11043           for(int i=0;i<nbOfTuple;i++)
11044             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
11045         }
11046       else
11047         throw INTERP_KERNEL::Exception(msg);
11048     }
11049   else
11050     throw INTERP_KERNEL::Exception(msg);
11051   declareAsNew();
11052 }
11053
11054 /*!
11055  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
11056  * valid cases.
11057  * 1.  The arrays have same number of tuples and components. Then each value of
11058  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
11059  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
11060  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11061  *   component. Then
11062  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
11063  * 3.  The arrays have same number of components and one array, say _a2_, has one
11064  *   tuple. Then
11065  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
11066  *
11067  * Info on components is copied either from the first array (in the first case) or from
11068  * the array with maximal number of elements (getNbOfElems()).
11069  *  \param [in] a1 - an array to subtract from.
11070  *  \param [in] a2 - an array to subtract.
11071  *  \return DataArrayInt * - the new instance of DataArrayInt.
11072  *          The caller is to delete this result array using decrRef() as it is no more
11073  *          needed.
11074  *  \throw If either \a a1 or \a a2 is NULL.
11075  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11076  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11077  *         none of them has number of tuples or components equal to 1.
11078  */
11079 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
11080 {
11081   if(!a1 || !a2)
11082     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
11083   int nbOfTuple1=a1->getNumberOfTuples();
11084   int nbOfTuple2=a2->getNumberOfTuples();
11085   int nbOfComp1=a1->getNumberOfComponents();
11086   int nbOfComp2=a2->getNumberOfComponents();
11087   if(nbOfTuple2==nbOfTuple1)
11088     {
11089       if(nbOfComp1==nbOfComp2)
11090         {
11091           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11092           ret->alloc(nbOfTuple2,nbOfComp1);
11093           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
11094           ret->copyStringInfoFrom(*a1);
11095           return ret.retn();
11096         }
11097       else if(nbOfComp2==1)
11098         {
11099           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11100           ret->alloc(nbOfTuple1,nbOfComp1);
11101           const int *a2Ptr=a2->getConstPointer();
11102           const int *a1Ptr=a1->getConstPointer();
11103           int *res=ret->getPointer();
11104           for(int i=0;i<nbOfTuple1;i++)
11105             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
11106           ret->copyStringInfoFrom(*a1);
11107           return ret.retn();
11108         }
11109       else
11110         {
11111           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
11112           return 0;
11113         }
11114     }
11115   else if(nbOfTuple2==1)
11116     {
11117       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
11118       MCAuto<DataArrayInt> ret=DataArrayInt::New();
11119       ret->alloc(nbOfTuple1,nbOfComp1);
11120       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11121       int *pt=ret->getPointer();
11122       for(int i=0;i<nbOfTuple1;i++)
11123         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
11124       ret->copyStringInfoFrom(*a1);
11125       return ret.retn();
11126     }
11127   else
11128     {
11129       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
11130       return 0;
11131     }
11132 }
11133
11134 /*!
11135  * Subtract values of another DataArrayInt from values of \a this one. There are 3
11136  * valid cases.
11137  * 1.  The arrays have same number of tuples and components. Then each value of
11138  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
11139  *   _a_ [ i, j ] -= _other_ [ i, j ].
11140  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11141  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
11142  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11143  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
11144  *
11145  *  \param [in] other - an array to subtract from \a this one.
11146  *  \throw If \a other is NULL.
11147  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11148  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11149  *         \a other has number of both tuples and components not equal to 1.
11150  */
11151 void DataArrayInt::substractEqual(const DataArrayInt *other)
11152 {
11153   if(!other)
11154     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
11155   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
11156   checkAllocated(); other->checkAllocated();
11157   int nbOfTuple=getNumberOfTuples();
11158   int nbOfTuple2=other->getNumberOfTuples();
11159   int nbOfComp=getNumberOfComponents();
11160   int nbOfComp2=other->getNumberOfComponents();
11161   if(nbOfTuple==nbOfTuple2)
11162     {
11163       if(nbOfComp==nbOfComp2)
11164         {
11165           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
11166         }
11167       else if(nbOfComp2==1)
11168         {
11169           int *ptr=getPointer();
11170           const int *ptrc=other->getConstPointer();
11171           for(int i=0;i<nbOfTuple;i++)
11172             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
11173         }
11174       else
11175         throw INTERP_KERNEL::Exception(msg);
11176     }
11177   else if(nbOfTuple2==1)
11178     {
11179       int *ptr=getPointer();
11180       const int *ptrc=other->getConstPointer();
11181       for(int i=0;i<nbOfTuple;i++)
11182         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
11183     }
11184   else
11185     throw INTERP_KERNEL::Exception(msg);
11186   declareAsNew();
11187 }
11188
11189 /*!
11190  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
11191  * valid cases.
11192  * 1.  The arrays have same number of tuples and components. Then each value of
11193  *   the result array (_a_) is a product of the corresponding values of \a a1 and
11194  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
11195  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11196  *   component. Then
11197  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
11198  * 3.  The arrays have same number of components and one array, say _a2_, has one
11199  *   tuple. Then
11200  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
11201  *
11202  * Info on components is copied either from the first array (in the first case) or from
11203  * the array with maximal number of elements (getNbOfElems()).
11204  *  \param [in] a1 - a factor array.
11205  *  \param [in] a2 - another factor array.
11206  *  \return DataArrayInt * - the new instance of DataArrayInt.
11207  *          The caller is to delete this result array using decrRef() as it is no more
11208  *          needed.
11209  *  \throw If either \a a1 or \a a2 is NULL.
11210  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11211  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11212  *         none of them has number of tuples or components equal to 1.
11213  */
11214 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
11215 {
11216   if(!a1 || !a2)
11217     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
11218   int nbOfTuple=a1->getNumberOfTuples();
11219   int nbOfTuple2=a2->getNumberOfTuples();
11220   int nbOfComp=a1->getNumberOfComponents();
11221   int nbOfComp2=a2->getNumberOfComponents();
11222   MCAuto<DataArrayInt> ret=0;
11223   if(nbOfTuple==nbOfTuple2)
11224     {
11225       if(nbOfComp==nbOfComp2)
11226         {
11227           ret=DataArrayInt::New();
11228           ret->alloc(nbOfTuple,nbOfComp);
11229           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
11230           ret->copyStringInfoFrom(*a1);
11231         }
11232       else
11233         {
11234           int nbOfCompMin,nbOfCompMax;
11235           const DataArrayInt *aMin, *aMax;
11236           if(nbOfComp>nbOfComp2)
11237             {
11238               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
11239               aMin=a2; aMax=a1;
11240             }
11241           else
11242             {
11243               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
11244               aMin=a1; aMax=a2;
11245             }
11246           if(nbOfCompMin==1)
11247             {
11248               ret=DataArrayInt::New();
11249               ret->alloc(nbOfTuple,nbOfCompMax);
11250               const int *aMinPtr=aMin->getConstPointer();
11251               const int *aMaxPtr=aMax->getConstPointer();
11252               int *res=ret->getPointer();
11253               for(int i=0;i<nbOfTuple;i++)
11254                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
11255               ret->copyStringInfoFrom(*aMax);
11256             }
11257           else
11258             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
11259         }
11260     }
11261   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
11262     {
11263       if(nbOfComp==nbOfComp2)
11264         {
11265           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
11266           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
11267           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
11268           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
11269           ret=DataArrayInt::New();
11270           ret->alloc(nbOfTupleMax,nbOfComp);
11271           int *res=ret->getPointer();
11272           for(int i=0;i<nbOfTupleMax;i++)
11273             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
11274           ret->copyStringInfoFrom(*aMax);
11275         }
11276       else
11277         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
11278     }
11279   else
11280     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
11281   return ret.retn();
11282 }
11283
11284
11285 /*!
11286  * Multiply values of another DataArrayInt to values of \a this one. There are 3
11287  * valid cases.
11288  * 1.  The arrays have same number of tuples and components. Then each value of
11289  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
11290  *   _a_ [ i, j ] *= _other_ [ i, j ].
11291  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11292  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
11293  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11294  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
11295  *
11296  *  \param [in] other - an array to multiply to \a this one.
11297  *  \throw If \a other is NULL.
11298  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11299  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11300  *         \a other has number of both tuples and components not equal to 1.
11301  */
11302 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
11303 {
11304   if(!other)
11305     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
11306   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
11307   checkAllocated(); other->checkAllocated();
11308   int nbOfTuple=getNumberOfTuples();
11309   int nbOfTuple2=other->getNumberOfTuples();
11310   int nbOfComp=getNumberOfComponents();
11311   int nbOfComp2=other->getNumberOfComponents();
11312   if(nbOfTuple==nbOfTuple2)
11313     {
11314       if(nbOfComp==nbOfComp2)
11315         {
11316           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
11317         }
11318       else if(nbOfComp2==1)
11319         {
11320           int *ptr=getPointer();
11321           const int *ptrc=other->getConstPointer();
11322           for(int i=0;i<nbOfTuple;i++)
11323             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
11324         }
11325       else
11326         throw INTERP_KERNEL::Exception(msg);
11327     }
11328   else if(nbOfTuple2==1)
11329     {
11330       if(nbOfComp2==nbOfComp)
11331         {
11332           int *ptr=getPointer();
11333           const int *ptrc=other->getConstPointer();
11334           for(int i=0;i<nbOfTuple;i++)
11335             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
11336         }
11337       else
11338         throw INTERP_KERNEL::Exception(msg);
11339     }
11340   else
11341     throw INTERP_KERNEL::Exception(msg);
11342   declareAsNew();
11343 }
11344
11345
11346 /*!
11347  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
11348  * valid cases.
11349  * 1.  The arrays have same number of tuples and components. Then each value of
11350  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11351  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
11352  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11353  *   component. Then
11354  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
11355  * 3.  The arrays have same number of components and one array, say _a2_, has one
11356  *   tuple. Then
11357  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
11358  *
11359  * Info on components is copied either from the first array (in the first case) or from
11360  * the array with maximal number of elements (getNbOfElems()).
11361  *  \warning No check of division by zero is performed!
11362  *  \param [in] a1 - a numerator array.
11363  *  \param [in] a2 - a denominator array.
11364  *  \return DataArrayInt * - the new instance of DataArrayInt.
11365  *          The caller is to delete this result array using decrRef() as it is no more
11366  *          needed.
11367  *  \throw If either \a a1 or \a a2 is NULL.
11368  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11369  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11370  *         none of them has number of tuples or components equal to 1.
11371  */
11372 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
11373 {
11374   if(!a1 || !a2)
11375     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
11376   int nbOfTuple1=a1->getNumberOfTuples();
11377   int nbOfTuple2=a2->getNumberOfTuples();
11378   int nbOfComp1=a1->getNumberOfComponents();
11379   int nbOfComp2=a2->getNumberOfComponents();
11380   if(nbOfTuple2==nbOfTuple1)
11381     {
11382       if(nbOfComp1==nbOfComp2)
11383         {
11384           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11385           ret->alloc(nbOfTuple2,nbOfComp1);
11386           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
11387           ret->copyStringInfoFrom(*a1);
11388           return ret.retn();
11389         }
11390       else if(nbOfComp2==1)
11391         {
11392           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11393           ret->alloc(nbOfTuple1,nbOfComp1);
11394           const int *a2Ptr=a2->getConstPointer();
11395           const int *a1Ptr=a1->getConstPointer();
11396           int *res=ret->getPointer();
11397           for(int i=0;i<nbOfTuple1;i++)
11398             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
11399           ret->copyStringInfoFrom(*a1);
11400           return ret.retn();
11401         }
11402       else
11403         {
11404           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11405           return 0;
11406         }
11407     }
11408   else if(nbOfTuple2==1)
11409     {
11410       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11411       MCAuto<DataArrayInt> ret=DataArrayInt::New();
11412       ret->alloc(nbOfTuple1,nbOfComp1);
11413       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11414       int *pt=ret->getPointer();
11415       for(int i=0;i<nbOfTuple1;i++)
11416         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
11417       ret->copyStringInfoFrom(*a1);
11418       return ret.retn();
11419     }
11420   else
11421     {
11422       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
11423       return 0;
11424     }
11425 }
11426
11427 /*!
11428  * Divide values of \a this array by values of another DataArrayInt. There are 3
11429  * valid cases.
11430  * 1.  The arrays have same number of tuples and components. Then each value of
11431  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11432  *   _a_ [ i, j ] /= _other_ [ i, j ].
11433  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11434  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
11435  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11436  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
11437  *
11438  *  \warning No check of division by zero is performed!
11439  *  \param [in] other - an array to divide \a this one by.
11440  *  \throw If \a other is NULL.
11441  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11442  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11443  *         \a other has number of both tuples and components not equal to 1.
11444  */
11445 void DataArrayInt::divideEqual(const DataArrayInt *other)
11446 {
11447   if(!other)
11448     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
11449   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
11450   checkAllocated(); other->checkAllocated();
11451   int nbOfTuple=getNumberOfTuples();
11452   int nbOfTuple2=other->getNumberOfTuples();
11453   int nbOfComp=getNumberOfComponents();
11454   int nbOfComp2=other->getNumberOfComponents();
11455   if(nbOfTuple==nbOfTuple2)
11456     {
11457       if(nbOfComp==nbOfComp2)
11458         {
11459           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
11460         }
11461       else if(nbOfComp2==1)
11462         {
11463           int *ptr=getPointer();
11464           const int *ptrc=other->getConstPointer();
11465           for(int i=0;i<nbOfTuple;i++)
11466             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
11467         }
11468       else
11469         throw INTERP_KERNEL::Exception(msg);
11470     }
11471   else if(nbOfTuple2==1)
11472     {
11473       if(nbOfComp2==nbOfComp)
11474         {
11475           int *ptr=getPointer();
11476           const int *ptrc=other->getConstPointer();
11477           for(int i=0;i<nbOfTuple;i++)
11478             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
11479         }
11480       else
11481         throw INTERP_KERNEL::Exception(msg);
11482     }
11483   else
11484     throw INTERP_KERNEL::Exception(msg);
11485   declareAsNew();
11486 }
11487
11488
11489 /*!
11490  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
11491  * valid cases.
11492  * 1.  The arrays have same number of tuples and components. Then each value of
11493  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11494  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
11495  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11496  *   component. Then
11497  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
11498  * 3.  The arrays have same number of components and one array, say _a2_, has one
11499  *   tuple. Then
11500  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
11501  *
11502  * Info on components is copied either from the first array (in the first case) or from
11503  * the array with maximal number of elements (getNbOfElems()).
11504  *  \warning No check of division by zero is performed!
11505  *  \param [in] a1 - a dividend array.
11506  *  \param [in] a2 - a divisor array.
11507  *  \return DataArrayInt * - the new instance of DataArrayInt.
11508  *          The caller is to delete this result array using decrRef() as it is no more
11509  *          needed.
11510  *  \throw If either \a a1 or \a a2 is NULL.
11511  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11512  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11513  *         none of them has number of tuples or components equal to 1.
11514  */
11515 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
11516 {
11517   if(!a1 || !a2)
11518     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
11519   int nbOfTuple1=a1->getNumberOfTuples();
11520   int nbOfTuple2=a2->getNumberOfTuples();
11521   int nbOfComp1=a1->getNumberOfComponents();
11522   int nbOfComp2=a2->getNumberOfComponents();
11523   if(nbOfTuple2==nbOfTuple1)
11524     {
11525       if(nbOfComp1==nbOfComp2)
11526         {
11527           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11528           ret->alloc(nbOfTuple2,nbOfComp1);
11529           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
11530           ret->copyStringInfoFrom(*a1);
11531           return ret.retn();
11532         }
11533       else if(nbOfComp2==1)
11534         {
11535           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11536           ret->alloc(nbOfTuple1,nbOfComp1);
11537           const int *a2Ptr=a2->getConstPointer();
11538           const int *a1Ptr=a1->getConstPointer();
11539           int *res=ret->getPointer();
11540           for(int i=0;i<nbOfTuple1;i++)
11541             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
11542           ret->copyStringInfoFrom(*a1);
11543           return ret.retn();
11544         }
11545       else
11546         {
11547           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11548           return 0;
11549         }
11550     }
11551   else if(nbOfTuple2==1)
11552     {
11553       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11554       MCAuto<DataArrayInt> ret=DataArrayInt::New();
11555       ret->alloc(nbOfTuple1,nbOfComp1);
11556       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11557       int *pt=ret->getPointer();
11558       for(int i=0;i<nbOfTuple1;i++)
11559         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
11560       ret->copyStringInfoFrom(*a1);
11561       return ret.retn();
11562     }
11563   else
11564     {
11565       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
11566       return 0;
11567     }
11568 }
11569
11570 /*!
11571  * Modify \a this array so that each value becomes a modulus of division of this value by
11572  * a value of another DataArrayInt. There are 3 valid cases.
11573  * 1.  The arrays have same number of tuples and components. Then each value of
11574  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11575  *   _a_ [ i, j ] %= _other_ [ i, j ].
11576  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11577  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
11578  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11579  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
11580  *
11581  *  \warning No check of division by zero is performed!
11582  *  \param [in] other - a divisor array.
11583  *  \throw If \a other is NULL.
11584  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11585  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11586  *         \a other has number of both tuples and components not equal to 1.
11587  */
11588 void DataArrayInt::modulusEqual(const DataArrayInt *other)
11589 {
11590   if(!other)
11591     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
11592   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
11593   checkAllocated(); other->checkAllocated();
11594   int nbOfTuple=getNumberOfTuples();
11595   int nbOfTuple2=other->getNumberOfTuples();
11596   int nbOfComp=getNumberOfComponents();
11597   int nbOfComp2=other->getNumberOfComponents();
11598   if(nbOfTuple==nbOfTuple2)
11599     {
11600       if(nbOfComp==nbOfComp2)
11601         {
11602           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
11603         }
11604       else if(nbOfComp2==1)
11605         {
11606           if(nbOfComp2==nbOfComp)
11607             {
11608               int *ptr=getPointer();
11609               const int *ptrc=other->getConstPointer();
11610               for(int i=0;i<nbOfTuple;i++)
11611                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
11612             }
11613           else
11614             throw INTERP_KERNEL::Exception(msg);
11615         }
11616       else
11617         throw INTERP_KERNEL::Exception(msg);
11618     }
11619   else if(nbOfTuple2==1)
11620     {
11621       int *ptr=getPointer();
11622       const int *ptrc=other->getConstPointer();
11623       for(int i=0;i<nbOfTuple;i++)
11624         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
11625     }
11626   else
11627     throw INTERP_KERNEL::Exception(msg);
11628   declareAsNew();
11629 }
11630
11631 /*!
11632  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
11633  * valid cases.
11634  *
11635  *  \param [in] a1 - an array to pow up.
11636  *  \param [in] a2 - another array to sum up.
11637  *  \return DataArrayInt * - the new instance of DataArrayInt.
11638  *          The caller is to delete this result array using decrRef() as it is no more
11639  *          needed.
11640  *  \throw If either \a a1 or \a a2 is NULL.
11641  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
11642  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
11643  *  \throw If there is a negative value in \a a2.
11644  */
11645 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
11646 {
11647   if(!a1 || !a2)
11648     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
11649   int nbOfTuple=a1->getNumberOfTuples();
11650   int nbOfTuple2=a2->getNumberOfTuples();
11651   int nbOfComp=a1->getNumberOfComponents();
11652   int nbOfComp2=a2->getNumberOfComponents();
11653   if(nbOfTuple!=nbOfTuple2)
11654     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
11655   if(nbOfComp!=1 || nbOfComp2!=1)
11656     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
11657   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
11658   const int *ptr1(a1->begin()),*ptr2(a2->begin());
11659   int *ptr=ret->getPointer();
11660   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
11661     {
11662       if(*ptr2>=0)
11663         {
11664           int tmp=1;
11665           for(int j=0;j<*ptr2;j++)
11666             tmp*=*ptr1;
11667           *ptr=tmp;
11668         }
11669       else
11670         {
11671           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
11672           throw INTERP_KERNEL::Exception(oss.str().c_str());
11673         }
11674     }
11675   return ret.retn();
11676 }
11677
11678 /*!
11679  * Apply pow on values of another DataArrayInt to values of \a this one.
11680  *
11681  *  \param [in] other - an array to pow to \a this one.
11682  *  \throw If \a other is NULL.
11683  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
11684  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
11685  *  \throw If there is a negative value in \a other.
11686  */
11687 void DataArrayInt::powEqual(const DataArrayInt *other)
11688 {
11689   if(!other)
11690     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
11691   int nbOfTuple=getNumberOfTuples();
11692   int nbOfTuple2=other->getNumberOfTuples();
11693   int nbOfComp=getNumberOfComponents();
11694   int nbOfComp2=other->getNumberOfComponents();
11695   if(nbOfTuple!=nbOfTuple2)
11696     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
11697   if(nbOfComp!=1 || nbOfComp2!=1)
11698     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
11699   int *ptr=getPointer();
11700   const int *ptrc=other->begin();
11701   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
11702     {
11703       if(*ptrc>=0)
11704         {
11705           int tmp=1;
11706           for(int j=0;j<*ptrc;j++)
11707             tmp*=*ptr;
11708           *ptr=tmp;
11709         }
11710       else
11711         {
11712           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
11713           throw INTERP_KERNEL::Exception(oss.str().c_str());
11714         }
11715     }
11716   declareAsNew();
11717 }
11718
11719 /*!
11720  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
11721  * This map, if applied to \a start array, would make it sorted. For example, if
11722  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
11723  * [5,6,0,3,2,7,1,4].
11724  *  \param [in] start - pointer to the first element of the array for which the
11725  *         permutation map is computed.
11726  *  \param [in] end - pointer specifying the end of the array \a start, so that
11727  *         the last value of \a start is \a end[ -1 ].
11728  *  \return int * - the result permutation array that the caller is to delete as it is no
11729  *         more needed.
11730  *  \throw If there are equal values in the input array.
11731  */
11732 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
11733 {
11734   std::size_t sz=std::distance(start,end);
11735   int *ret=(int *)malloc(sz*sizeof(int));
11736   int *work=new int[sz];
11737   std::copy(start,end,work);
11738   std::sort(work,work+sz);
11739   if(std::unique(work,work+sz)!=work+sz)
11740     {
11741       delete [] work;
11742       free(ret);
11743       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
11744     }
11745   std::map<int,int> m;
11746   for(int *workPt=work;workPt!=work+sz;workPt++)
11747     m[*workPt]=(int)std::distance(work,workPt);
11748   int *iter2=ret;
11749   for(const int *iter=start;iter!=end;iter++,iter2++)
11750     *iter2=m[*iter];
11751   delete [] work;
11752   return ret;
11753 }
11754
11755 /*!
11756  * Returns a new DataArrayInt containing an arithmetic progression
11757  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
11758  * function.
11759  *  \param [in] begin - the start value of the result sequence.
11760  *  \param [in] end - limiting value, so that every value of the result array is less than
11761  *              \a end.
11762  *  \param [in] step - specifies the increment or decrement.
11763  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
11764  *          array using decrRef() as it is no more needed.
11765  *  \throw If \a step == 0.
11766  *  \throw If \a end < \a begin && \a step > 0.
11767  *  \throw If \a end > \a begin && \a step < 0.
11768  */
11769 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
11770 {
11771   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
11772   MCAuto<DataArrayInt> ret=DataArrayInt::New();
11773   ret->alloc(nbOfTuples,1);
11774   int *ptr=ret->getPointer();
11775   if(step>0)
11776     {
11777       for(int i=begin;i<end;i+=step,ptr++)
11778         *ptr=i;
11779     }
11780   else
11781     {
11782       for(int i=begin;i>end;i+=step,ptr++)
11783         *ptr=i;
11784     }
11785   return ret.retn();
11786 }
11787
11788 /*!
11789  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11790  * Server side.
11791  */
11792 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
11793 {
11794   tinyInfo.resize(2);
11795   if(isAllocated())
11796     {
11797       tinyInfo[0]=getNumberOfTuples();
11798       tinyInfo[1]=getNumberOfComponents();
11799     }
11800   else
11801     {
11802       tinyInfo[0]=-1;
11803       tinyInfo[1]=-1;
11804     }
11805 }
11806
11807 /*!
11808  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11809  * Server side.
11810  */
11811 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
11812 {
11813   if(isAllocated())
11814     {
11815       int nbOfCompo=getNumberOfComponents();
11816       tinyInfo.resize(nbOfCompo+1);
11817       tinyInfo[0]=getName();
11818       for(int i=0;i<nbOfCompo;i++)
11819         tinyInfo[i+1]=getInfoOnComponent(i);
11820     }
11821   else
11822     {
11823       tinyInfo.resize(1);
11824       tinyInfo[0]=getName();
11825     }
11826 }
11827
11828 /*!
11829  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11830  * This method returns if a feeding is needed.
11831  */
11832 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11833 {
11834   int nbOfTuple=tinyInfoI[0];
11835   int nbOfComp=tinyInfoI[1];
11836   if(nbOfTuple!=-1 || nbOfComp!=-1)
11837     {
11838       alloc(nbOfTuple,nbOfComp);
11839       return true;
11840     }
11841   return false;
11842 }
11843
11844 /*!
11845  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11846  * This method returns if a feeding is needed.
11847  */
11848 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11849 {
11850   setName(tinyInfoS[0]);
11851   if(isAllocated())
11852     {
11853       int nbOfCompo=tinyInfoI[1];
11854       for(int i=0;i<nbOfCompo;i++)
11855         setInfoOnComponent(i,tinyInfoS[i+1]);
11856     }
11857 }
11858
11859 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11860 {
11861   if(_da)
11862     {
11863       _da->incrRef();
11864       if(_da->isAllocated())
11865         {
11866           _nb_comp=da->getNumberOfComponents();
11867           _nb_tuple=da->getNumberOfTuples();
11868           _pt=da->getPointer();
11869         }
11870     }
11871 }
11872
11873 DataArrayIntIterator::~DataArrayIntIterator()
11874 {
11875   if(_da)
11876     _da->decrRef();
11877 }
11878
11879 DataArrayIntTuple *DataArrayIntIterator::nextt()
11880 {
11881   if(_tuple_id<_nb_tuple)
11882     {
11883       _tuple_id++;
11884       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11885       _pt+=_nb_comp;
11886       return ret;
11887     }
11888   else
11889     return 0;
11890 }
11891
11892 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11893 {
11894 }
11895
11896 std::string DataArrayIntTuple::repr() const
11897 {
11898   std::ostringstream oss; oss << "(";
11899   for(int i=0;i<_nb_of_compo-1;i++)
11900     oss << _pt[i] << ", ";
11901   oss << _pt[_nb_of_compo-1] << ")";
11902   return oss.str();
11903 }
11904
11905 int DataArrayIntTuple::intValue() const
11906 {
11907   if(_nb_of_compo==1)
11908     return *_pt;
11909   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11910 }
11911
11912 /*!
11913  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
11914  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
11915  * 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
11916  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11917  */
11918 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11919 {
11920   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11921     {
11922       DataArrayInt *ret=DataArrayInt::New();
11923       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11924       return ret;
11925     }
11926   else
11927     {
11928       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11929       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11930       throw INTERP_KERNEL::Exception(oss.str().c_str());
11931     }
11932 }