Salome HOME
28806d19d08a755c9ca918e3c3d427940c22decf
[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  *  \sa DataArrayInt::switchOnTupleNotEqualTo.
6921  */
6922 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
6923 {
6924   checkAllocated();
6925   if(getNumberOfComponents()!=1)
6926     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
6927   int nbOfTuples(getNumberOfTuples());
6928   if(nbOfTuples!=(int)vec.size())
6929     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
6930   const int *pt(begin());
6931   for(int i=0;i<nbOfTuples;i++)
6932     if(pt[i]==val)
6933       vec[i]=true;
6934 }
6935
6936 /*!
6937  * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple different from \a val
6938  * put True to the corresponding entry in \a vec.
6939  * \a vec is expected to be with the same size than the number of tuples of \a this.
6940  * 
6941  *  \sa DataArrayInt::switchOnTupleEqualTo.
6942  */
6943 void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const
6944 {
6945   checkAllocated();
6946   if(getNumberOfComponents()!=1)
6947     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !");
6948   int nbOfTuples(getNumberOfTuples());
6949   if(nbOfTuples!=(int)vec.size())
6950     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !");
6951   const int *pt(begin());
6952   for(int i=0;i<nbOfTuples;i++)
6953     if(pt[i]!=val)
6954       vec[i]=true;
6955 }
6956
6957 /*!
6958  * Sorts values of the array.
6959  *  \param [in] asc - \a true means ascending order, \a false, descending.
6960  *  \throw If \a this is not allocated.
6961  *  \throw If \a this->getNumberOfComponents() != 1.
6962  */
6963 void DataArrayInt::sort(bool asc)
6964 {
6965   checkAllocated();
6966   if(getNumberOfComponents()!=1)
6967     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6968   _mem.sort(asc);
6969   declareAsNew();
6970 }
6971
6972 /*!
6973  * Computes for each tuple the sum of number of components values in the tuple and return it.
6974  * 
6975  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6976  *          same number of tuples as \a this array and one component.
6977  *          The caller is to delete this result array using decrRef() as it is no more
6978  *          needed.
6979  *  \throw If \a this is not allocated.
6980  */
6981 DataArrayInt *DataArrayInt::sumPerTuple() const
6982 {
6983   checkAllocated();
6984   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6985   MCAuto<DataArrayInt> ret(DataArrayInt::New());
6986   ret->alloc(nbOfTuple,1);
6987   const int *src(getConstPointer());
6988   int *dest(ret->getPointer());
6989   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6990     *dest=std::accumulate(src,src+nbOfComp,0);
6991   return ret.retn();
6992 }
6993
6994 /*!
6995  * Reverse the array values.
6996  *  \throw If \a this->getNumberOfComponents() < 1.
6997  *  \throw If \a this is not allocated.
6998  */
6999 void DataArrayInt::reverse()
7000 {
7001   checkAllocated();
7002   _mem.reverse(getNumberOfComponents());
7003   declareAsNew();
7004 }
7005
7006 /*!
7007  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
7008  * If not an exception is thrown.
7009  *  \param [in] increasing - if \a true, the array values should be increasing.
7010  *  \throw If sequence of values is not strictly monotonic in agreement with \a
7011  *         increasing arg.
7012  *  \throw If \a this->getNumberOfComponents() != 1.
7013  *  \throw If \a this is not allocated.
7014  */
7015 void DataArrayInt::checkMonotonic(bool increasing) const
7016 {
7017   if(!isMonotonic(increasing))
7018     {
7019       if (increasing)
7020         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
7021       else
7022         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
7023     }
7024 }
7025
7026 /*!
7027  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
7028  *  \param [in] increasing - if \a true, array values should be increasing.
7029  *  \return bool - \a true if values change in accordance with \a increasing arg.
7030  *  \throw If \a this->getNumberOfComponents() != 1.
7031  *  \throw If \a this is not allocated.
7032  */
7033 bool DataArrayInt::isMonotonic(bool increasing) const
7034 {
7035   checkAllocated();
7036   if(getNumberOfComponents()!=1)
7037     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
7038   int nbOfElements=getNumberOfTuples();
7039   const int *ptr=getConstPointer();
7040   if(nbOfElements==0)
7041     return true;
7042   int ref=ptr[0];
7043   if(increasing)
7044     {
7045       for(int i=1;i<nbOfElements;i++)
7046         {
7047           if(ptr[i]>=ref)
7048             ref=ptr[i];
7049           else
7050             return false;
7051         }
7052     }
7053   else
7054     {
7055       for(int i=1;i<nbOfElements;i++)
7056         {
7057           if(ptr[i]<=ref)
7058             ref=ptr[i];
7059           else
7060             return false;
7061         }
7062     }
7063   return true;
7064 }
7065
7066 /*!
7067  * This method check that array consistently INCREASING or DECREASING in value.
7068  */
7069 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
7070 {
7071   checkAllocated();
7072   if(getNumberOfComponents()!=1)
7073     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
7074   int nbOfElements=getNumberOfTuples();
7075   const int *ptr=getConstPointer();
7076   if(nbOfElements==0)
7077     return true;
7078   int ref=ptr[0];
7079   if(increasing)
7080     {
7081       for(int i=1;i<nbOfElements;i++)
7082         {
7083           if(ptr[i]>ref)
7084             ref=ptr[i];
7085           else
7086             return false;
7087         }
7088     }
7089   else
7090     {
7091       for(int i=1;i<nbOfElements;i++)
7092         {
7093           if(ptr[i]<ref)
7094             ref=ptr[i];
7095           else
7096             return false;
7097         }
7098     }
7099   return true;
7100 }
7101
7102 /*!
7103  * This method check that array consistently INCREASING or DECREASING in value.
7104  */
7105 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
7106 {
7107   if(!isStrictlyMonotonic(increasing))
7108     {
7109       if (increasing)
7110         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
7111       else
7112         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
7113     }
7114 }
7115
7116 /*!
7117  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
7118  * one-dimensional arrays that must be of the same length. The result array describes
7119  * correspondence between \a this and \a other arrays, so that 
7120  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
7121  * not possible because some element in \a other is not in \a this, an exception is thrown.
7122  *  \param [in] other - an array to compute permutation to.
7123  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
7124  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
7125  * no more needed.
7126  *  \throw If \a this->getNumberOfComponents() != 1.
7127  *  \throw If \a other->getNumberOfComponents() != 1.
7128  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
7129  *  \throw If \a other includes a value which is not in \a this array.
7130  * 
7131  *  \if ENABLE_EXAMPLES
7132  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
7133  *
7134  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
7135  *  \endif
7136  */
7137 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
7138 {
7139   checkAllocated();
7140   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
7141     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
7142   int nbTuple=getNumberOfTuples();
7143   other.checkAllocated();
7144   if(nbTuple!=other.getNumberOfTuples())
7145     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
7146   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7147   ret->alloc(nbTuple,1);
7148   ret->fillWithValue(-1);
7149   const int *pt=getConstPointer();
7150   std::map<int,int> mm;
7151   for(int i=0;i<nbTuple;i++)
7152     mm[pt[i]]=i;
7153   pt=other.getConstPointer();
7154   int *retToFill=ret->getPointer();
7155   for(int i=0;i<nbTuple;i++)
7156     {
7157       std::map<int,int>::const_iterator it=mm.find(pt[i]);
7158       if(it==mm.end())
7159         {
7160           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
7161           throw INTERP_KERNEL::Exception(oss.str().c_str());
7162         }
7163       retToFill[i]=(*it).second;
7164     }
7165   return ret.retn();
7166 }
7167
7168 /*!
7169  * Sets a C array to be used as raw data of \a this. The previously set info
7170  *  of components is retained and re-sized. 
7171  * For more info see \ref MEDCouplingArraySteps1.
7172  *  \param [in] array - the C array to be used as raw data of \a this.
7173  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
7174  *  \param [in] type - specifies how to deallocate \a array. If \a type == MEDCoupling::CPP_DEALLOC,
7175  *                     \c delete [] \c array; will be called. If \a type == MEDCoupling::C_DEALLOC,
7176  *                     \c free(\c array ) will be called.
7177  *  \param [in] nbOfTuple - new number of tuples in \a this.
7178  *  \param [in] nbOfCompo - new number of components in \a this.
7179  */
7180 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
7181 {
7182   _info_on_compo.resize(nbOfCompo);
7183   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
7184   declareAsNew();
7185 }
7186
7187 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
7188 {
7189   _info_on_compo.resize(nbOfCompo);
7190   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
7191   declareAsNew();
7192 }
7193
7194 void DataArrayInt::aggregate(const DataArrayInt *other)
7195 {
7196   if(!other)
7197     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : null pointer !");
7198   if(getNumberOfComponents()!=other->getNumberOfComponents())
7199     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : mismatch number of components !");
7200   _mem.insertAtTheEnd(other->begin(),other->end());
7201 }
7202
7203 /*!
7204  * Returns a new DataArrayInt holding the same values as \a this array but differently
7205  * arranged in memory. If \a this array holds 2 components of 3 values:
7206  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
7207  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
7208  *  \warning Do not confuse this method with transpose()!
7209  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7210  *          is to delete using decrRef() as it is no more needed.
7211  *  \throw If \a this is not allocated.
7212  */
7213 DataArrayInt *DataArrayInt::fromNoInterlace() const
7214 {
7215   checkAllocated();
7216   if(_mem.isNull())
7217     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
7218   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
7219   DataArrayInt *ret=DataArrayInt::New();
7220   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
7221   return ret;
7222 }
7223
7224 /*!
7225  * Returns a new DataArrayInt holding the same values as \a this array but differently
7226  * arranged in memory. If \a this array holds 2 components of 3 values:
7227  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
7228  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
7229  *  \warning Do not confuse this method with transpose()!
7230  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7231  *          is to delete using decrRef() as it is no more needed.
7232  *  \throw If \a this is not allocated.
7233  */
7234 DataArrayInt *DataArrayInt::toNoInterlace() const
7235 {
7236   checkAllocated();
7237   if(_mem.isNull())
7238     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
7239   int *tab=_mem.toNoInterlace(getNumberOfComponents());
7240   DataArrayInt *ret=DataArrayInt::New();
7241   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
7242   return ret;
7243 }
7244
7245 /*!
7246  * Permutes values of \a this array as required by \a old2New array. The values are
7247  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
7248  * the same as in \c this one.
7249  * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
7250  * For more info on renumbering see \ref numbering.
7251  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7252  *     giving a new position for i-th old value.
7253  */
7254 void DataArrayInt::renumberInPlace(const int *old2New)
7255 {
7256   checkAllocated();
7257   int nbTuples=getNumberOfTuples();
7258   int nbOfCompo=getNumberOfComponents();
7259   int *tmp=new int[nbTuples*nbOfCompo];
7260   const int *iptr=getConstPointer();
7261   for(int i=0;i<nbTuples;i++)
7262     {
7263       int v=old2New[i];
7264       if(v>=0 && v<nbTuples)
7265         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
7266       else
7267         {
7268           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7269           throw INTERP_KERNEL::Exception(oss.str().c_str());
7270         }
7271     }
7272   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7273   delete [] tmp;
7274   declareAsNew();
7275 }
7276
7277 /*!
7278  * Permutes values of \a this array as required by \a new2Old array. The values are
7279  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
7280  * the same as in \c this one.
7281  * For more info on renumbering see \ref numbering.
7282  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7283  *     giving a previous position of i-th new value.
7284  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7285  *          is to delete using decrRef() as it is no more needed.
7286  */
7287 void DataArrayInt::renumberInPlaceR(const int *new2Old)
7288 {
7289   checkAllocated();
7290   int nbTuples=getNumberOfTuples();
7291   int nbOfCompo=getNumberOfComponents();
7292   int *tmp=new int[nbTuples*nbOfCompo];
7293   const int *iptr=getConstPointer();
7294   for(int i=0;i<nbTuples;i++)
7295     {
7296       int v=new2Old[i];
7297       if(v>=0 && v<nbTuples)
7298         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
7299       else
7300         {
7301           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
7302           throw INTERP_KERNEL::Exception(oss.str().c_str());
7303         }
7304     }
7305   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
7306   delete [] tmp;
7307   declareAsNew();
7308 }
7309
7310 /*!
7311  * Returns a copy of \a this array with values permuted as required by \a old2New array.
7312  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
7313  * Number of tuples in the result array remains the same as in \c this one.
7314  * If a permutation reduction is needed, renumberAndReduce() should be used.
7315  * For more info on renumbering see \ref numbering.
7316  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7317  *          giving a new position for i-th old value.
7318  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7319  *          is to delete using decrRef() as it is no more needed.
7320  *  \throw If \a this is not allocated.
7321  */
7322 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
7323 {
7324   checkAllocated();
7325   int nbTuples=getNumberOfTuples();
7326   int nbOfCompo=getNumberOfComponents();
7327   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7328   ret->alloc(nbTuples,nbOfCompo);
7329   ret->copyStringInfoFrom(*this);
7330   const int *iptr=getConstPointer();
7331   int *optr=ret->getPointer();
7332   for(int i=0;i<nbTuples;i++)
7333     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
7334   ret->copyStringInfoFrom(*this);
7335   return ret.retn();
7336 }
7337
7338 /*!
7339  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
7340  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
7341  * tuples in the result array remains the same as in \c this one.
7342  * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
7343  * For more info on renumbering see \ref numbering.
7344  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
7345  *     giving a previous position of i-th new value.
7346  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7347  *          is to delete using decrRef() as it is no more needed.
7348  */
7349 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
7350 {
7351   checkAllocated();
7352   int nbTuples=getNumberOfTuples();
7353   int nbOfCompo=getNumberOfComponents();
7354   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7355   ret->alloc(nbTuples,nbOfCompo);
7356   ret->copyStringInfoFrom(*this);
7357   const int *iptr=getConstPointer();
7358   int *optr=ret->getPointer();
7359   for(int i=0;i<nbTuples;i++)
7360     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
7361   ret->copyStringInfoFrom(*this);
7362   return ret.retn();
7363 }
7364
7365 /*!
7366  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7367  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
7368  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
7369  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
7370  * \a old2New[ i ] is negative, is missing from the result array.
7371  * For more info on renumbering see \ref numbering.
7372  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
7373  *     giving a new position for i-th old tuple and giving negative position for
7374  *     for i-th old tuple that should be omitted.
7375  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7376  *          is to delete using decrRef() as it is no more needed.
7377  */
7378 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
7379 {
7380   checkAllocated();
7381   int nbTuples=getNumberOfTuples();
7382   int nbOfCompo=getNumberOfComponents();
7383   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7384   ret->alloc(newNbOfTuple,nbOfCompo);
7385   const int *iptr=getConstPointer();
7386   int *optr=ret->getPointer();
7387   for(int i=0;i<nbTuples;i++)
7388     {
7389       int w=old2New[i];
7390       if(w>=0)
7391         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
7392     }
7393   ret->copyStringInfoFrom(*this);
7394   return ret.retn();
7395 }
7396
7397 /*!
7398  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7399  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7400  * \a new2OldBg array.
7401  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7402  * This method is equivalent to renumberAndReduce() except that convention in input is
7403  * \c new2old and \b not \c old2new.
7404  * For more info on renumbering see \ref numbering.
7405  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7406  *              tuple index in \a this array to fill the i-th tuple in the new array.
7407  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7408  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7409  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7410  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7411  *          is to delete using decrRef() as it is no more needed.
7412  */
7413 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
7414 {
7415   checkAllocated();
7416   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7417   int nbComp=getNumberOfComponents();
7418   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7419   ret->copyStringInfoFrom(*this);
7420   int *pt=ret->getPointer();
7421   const int *srcPt=getConstPointer();
7422   int i=0;
7423   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7424     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7425   ret->copyStringInfoFrom(*this);
7426   return ret.retn();
7427 }
7428
7429 /*!
7430  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7431  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7432  * \a new2OldBg array.
7433  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7434  * This method is equivalent to renumberAndReduce() except that convention in input is
7435  * \c new2old and \b not \c old2new.
7436  * This method is equivalent to selectByTupleId() except that it prevents coping data
7437  * from behind the end of \a this array.
7438  * For more info on renumbering see \ref numbering.
7439  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7440  *              tuple index in \a this array to fill the i-th tuple in the new array.
7441  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7442  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7443  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7444  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7445  *          is to delete using decrRef() as it is no more needed.
7446  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
7447  */
7448 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
7449 {
7450   checkAllocated();
7451   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7452   int nbComp=getNumberOfComponents();
7453   int oldNbOfTuples=getNumberOfTuples();
7454   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7455   ret->copyStringInfoFrom(*this);
7456   int *pt=ret->getPointer();
7457   const int *srcPt=getConstPointer();
7458   int i=0;
7459   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7460     if(*w>=0 && *w<oldNbOfTuples)
7461       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7462     else
7463       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
7464   ret->copyStringInfoFrom(*this);
7465   return ret.retn();
7466 }
7467
7468 /*!
7469  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
7470  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
7471  * tuple. Indices of the selected tuples are the same as ones returned by the Python
7472  * command \c range( \a bg, \a end2, \a step ).
7473  * This method is equivalent to selectByTupleIdSafe() except that the input array is
7474  * not constructed explicitly.
7475  * For more info on renumbering see \ref numbering.
7476  *  \param [in] bg - index of the first tuple to copy from \a this array.
7477  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
7478  *  \param [in] step - index increment to get index of the next tuple to copy.
7479  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7480  *          is to delete using decrRef() as it is no more needed.
7481  *  \sa DataArrayInt::subArray.
7482  */
7483 DataArrayInt *DataArrayInt::selectByTupleIdSafeSlice(int bg, int end2, int step) const
7484 {
7485   checkAllocated();
7486   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7487   int nbComp=getNumberOfComponents();
7488   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleIdSafeSlice : ");
7489   ret->alloc(newNbOfTuples,nbComp);
7490   int *pt=ret->getPointer();
7491   const int *srcPt=getConstPointer()+bg*nbComp;
7492   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
7493     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
7494   ret->copyStringInfoFrom(*this);
7495   return ret.retn();
7496 }
7497
7498 /*!
7499  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
7500  * of tuples specified by \a ranges parameter.
7501  * For more info on renumbering see \ref numbering.
7502  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
7503  *              of tuples in [\c begin,\c end) format.
7504  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7505  *          is to delete using decrRef() as it is no more needed.
7506  *  \throw If \a end < \a begin.
7507  *  \throw If \a end > \a this->getNumberOfTuples().
7508  *  \throw If \a this is not allocated.
7509  */
7510 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
7511 {
7512   checkAllocated();
7513   int nbOfComp=getNumberOfComponents();
7514   int nbOfTuplesThis=getNumberOfTuples();
7515   if(ranges.empty())
7516     {
7517       MCAuto<DataArrayInt> ret=DataArrayInt::New();
7518       ret->alloc(0,nbOfComp);
7519       ret->copyStringInfoFrom(*this);
7520       return ret.retn();
7521     }
7522   int ref=ranges.front().first;
7523   int nbOfTuples=0;
7524   bool isIncreasing=true;
7525   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7526     {
7527       if((*it).first<=(*it).second)
7528         {
7529           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
7530             {
7531               nbOfTuples+=(*it).second-(*it).first;
7532               if(isIncreasing)
7533                 isIncreasing=ref<=(*it).first;
7534               ref=(*it).second;
7535             }
7536           else
7537             {
7538               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7539               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
7540               throw INTERP_KERNEL::Exception(oss.str().c_str());
7541             }
7542         }
7543       else
7544         {
7545           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7546           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7547           throw INTERP_KERNEL::Exception(oss.str().c_str());
7548         }
7549     }
7550   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7551     return deepCopy();
7552   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7553   ret->alloc(nbOfTuples,nbOfComp);
7554   ret->copyStringInfoFrom(*this);
7555   const int *src=getConstPointer();
7556   int *work=ret->getPointer();
7557   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7558     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7559   return ret.retn();
7560 }
7561
7562 /*!
7563  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7564  * This map, if applied to \a this array, would make it sorted. For example, if
7565  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7566  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7567  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7568  * This method is useful for renumbering (in MED file for example). For more info
7569  * on renumbering see \ref numbering.
7570  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7571  *          array using decrRef() as it is no more needed.
7572  *  \throw If \a this is not allocated.
7573  *  \throw If \a this->getNumberOfComponents() != 1.
7574  *  \throw If there are equal values in \a this array.
7575  */
7576 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7577 {
7578   checkAllocated();
7579   if(getNumberOfComponents()!=1)
7580     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7581   int nbTuples=getNumberOfTuples();
7582   const int *pt=getConstPointer();
7583   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7584   DataArrayInt *ret=DataArrayInt::New();
7585   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7586   return ret;
7587 }
7588
7589 /*!
7590  * 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
7591  * input array \a ids2.
7592  * \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.
7593  * 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
7594  * inversely.
7595  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7596  *
7597  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7598  *          array using decrRef() as it is no more needed.
7599  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7600  * 
7601  */
7602 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7603 {
7604   if(!ids1 || !ids2)
7605     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7606   if(!ids1->isAllocated() || !ids2->isAllocated())
7607     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7608   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7609     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7610   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7611     {
7612       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 !";
7613       throw INTERP_KERNEL::Exception(oss.str().c_str());
7614     }
7615   MCAuto<DataArrayInt> p1(ids1->deepCopy());
7616   MCAuto<DataArrayInt> p2(ids2->deepCopy());
7617   p1->sort(true); p2->sort(true);
7618   if(!p1->isEqualWithoutConsideringStr(*p2))
7619     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7620   p1=ids1->checkAndPreparePermutation();
7621   p2=ids2->checkAndPreparePermutation();
7622   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7623   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7624   return p2.retn();
7625 }
7626
7627 /*!
7628  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7629  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7630  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7631  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7632  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7633  * The first of out arrays returns indices of elements of \a this array, grouped by their
7634  * place in the set \a B. The second out array is the index of the first one; it shows how
7635  * many elements of \a A are mapped into each element of \a B. <br>
7636  * For more info on
7637  * mapping and its usage in renumbering see \ref numbering. <br>
7638  * \b Example:
7639  * - \a this: [0,3,2,3,2,2,1,2]
7640  * - \a targetNb: 4
7641  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7642  * - \a arrI: [0,1,2,6,8]
7643  *
7644  * This result means: <br>
7645  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7646  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7647  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7648  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7649  * \a arrI[ 2+1 ]]); <br> etc.
7650  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7651  *         than the maximal value of \a A.
7652  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7653  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7654  *         this array using decrRef() as it is no more needed.
7655  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7656  *         elements of \a this. The caller is to delete this array using decrRef() as it
7657  *         is no more needed.
7658  *  \throw If \a this is not allocated.
7659  *  \throw If \a this->getNumberOfComponents() != 1.
7660  *  \throw If any value in \a this is more or equal to \a targetNb.
7661  */
7662 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7663 {
7664   checkAllocated();
7665   if(getNumberOfComponents()!=1)
7666     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7667   int nbOfTuples=getNumberOfTuples();
7668   MCAuto<DataArrayInt> ret(DataArrayInt::New());
7669   MCAuto<DataArrayInt> retI(DataArrayInt::New());
7670   retI->alloc(targetNb+1,1);
7671   const int *input=getConstPointer();
7672   std::vector< std::vector<int> > tmp(targetNb);
7673   for(int i=0;i<nbOfTuples;i++)
7674     {
7675       int tmp2=input[i];
7676       if(tmp2>=0 && tmp2<targetNb)
7677         tmp[tmp2].push_back(i);
7678       else
7679         {
7680           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7681           throw INTERP_KERNEL::Exception(oss.str().c_str());
7682         }
7683     }
7684   int *retIPtr=retI->getPointer();
7685   *retIPtr=0;
7686   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7687     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7688   if(nbOfTuples!=retI->getIJ(targetNb,0))
7689     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7690   ret->alloc(nbOfTuples,1);
7691   int *retPtr=ret->getPointer();
7692   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7693     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7694   arr=ret.retn();
7695   arrI=retI.retn();
7696 }
7697
7698
7699 /*!
7700  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7701  * from a zip representation of a surjective format (returned e.g. by
7702  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7703  * for example). The result array minimizes the permutation. <br>
7704  * For more info on renumbering see \ref numbering. <br>
7705  * \b Example: <br>
7706  * - \a nbOfOldTuples: 10 
7707  * - \a arr          : [0,3, 5,7,9]
7708  * - \a arrIBg       : [0,2,5]
7709  * - \a newNbOfTuples: 7
7710  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7711  *
7712  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7713  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7714  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7715  *         (indices of) equal values. Its every element (except the last one) points to
7716  *         the first element of a group of equal values.
7717  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7718  *          arrIBg is \a arrIEnd[ -1 ].
7719  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7720  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7721  *          array using decrRef() as it is no more needed.
7722  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7723  */
7724 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7725 {
7726   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7727   ret->alloc(nbOfOldTuples,1);
7728   int *pt=ret->getPointer();
7729   std::fill(pt,pt+nbOfOldTuples,-1);
7730   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7731   const int *cIPtr=arrIBg;
7732   for(int i=0;i<nbOfGrps;i++)
7733     pt[arr[cIPtr[i]]]=-(i+2);
7734   int newNb=0;
7735   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7736     {
7737       if(pt[iNode]<0)
7738         {
7739           if(pt[iNode]==-1)
7740             pt[iNode]=newNb++;
7741           else
7742             {
7743               int grpId=-(pt[iNode]+2);
7744               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7745                 {
7746                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7747                     pt[arr[j]]=newNb;
7748                   else
7749                     {
7750                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7751                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7752                     }
7753                 }
7754               newNb++;
7755             }
7756         }
7757     }
7758   newNbOfTuples=newNb;
7759   return ret.retn();
7760 }
7761
7762 /*!
7763  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7764  * which if applied to \a this array would make it sorted ascendingly.
7765  * For more info on renumbering see \ref numbering. <br>
7766  * \b Example: <br>
7767  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7768  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7769  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7770  *
7771  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7772  *          array using decrRef() as it is no more needed.
7773  *  \throw If \a this is not allocated.
7774  *  \throw If \a this->getNumberOfComponents() != 1.
7775  */
7776 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7777 {
7778   checkAllocated();
7779   if(getNumberOfComponents()!=1)
7780     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7781   int nbOfTuples=getNumberOfTuples();
7782   const int *pt=getConstPointer();
7783   std::map<int,int> m;
7784   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7785   ret->alloc(nbOfTuples,1);
7786   int *opt=ret->getPointer();
7787   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7788     {
7789       int val=*pt;
7790       std::map<int,int>::iterator it=m.find(val);
7791       if(it!=m.end())
7792         {
7793           *opt=(*it).second;
7794           (*it).second++;
7795         }
7796       else
7797         {
7798           *opt=0;
7799           m.insert(std::pair<int,int>(val,1));
7800         }
7801     }
7802   int sum=0;
7803   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7804     {
7805       int vt=(*it).second;
7806       (*it).second=sum;
7807       sum+=vt;
7808     }
7809   pt=getConstPointer();
7810   opt=ret->getPointer();
7811   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7812     *opt+=m[*pt];
7813   //
7814   return ret.retn();
7815 }
7816
7817 /*!
7818  * Checks if contents of \a this array are equal to that of an array filled with
7819  * iota(). This method is particularly useful for DataArrayInt instances that represent
7820  * a renumbering array to check the real need in renumbering. This method checks than \a this can be considered as an identity function
7821  * of a set having \a sizeExpected elements into itself.
7822  *
7823  *  \param [in] sizeExpected - The number of elements expected.
7824  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7825  *  \throw If \a this is not allocated.
7826  *  \throw If \a this->getNumberOfComponents() != 1.
7827  */
7828 bool DataArrayInt::isIota(int sizeExpected) const
7829 {
7830   checkAllocated();
7831   if(getNumberOfComponents()!=1)
7832     return false;
7833   int nbOfTuples(getNumberOfTuples());
7834   if(nbOfTuples!=sizeExpected)
7835     return false;
7836   const int *pt=getConstPointer();
7837   for(int i=0;i<nbOfTuples;i++,pt++)
7838     if(*pt!=i)
7839       return false;
7840   return true;
7841 }
7842
7843 /*!
7844  * Checks if all values in \a this array are equal to \a val.
7845  *  \param [in] val - value to check equality of array values to.
7846  *  \return bool - \a true if all values are \a val.
7847  *  \throw If \a this is not allocated.
7848  *  \throw If \a this->getNumberOfComponents() != 1
7849  */
7850 bool DataArrayInt::isUniform(int val) const
7851 {
7852   checkAllocated();
7853   if(getNumberOfComponents()!=1)
7854     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7855   int nbOfTuples=getNumberOfTuples();
7856   const int *w=getConstPointer();
7857   const int *end2=w+nbOfTuples;
7858   for(;w!=end2;w++)
7859     if(*w!=val)
7860       return false;
7861   return true;
7862 }
7863
7864 /*!
7865  * Checks if all values in \a this array are unique.
7866  *  \return bool - \a true if condition above is true
7867  *  \throw If \a this is not allocated.
7868  *  \throw If \a this->getNumberOfComponents() != 1
7869  */
7870 bool DataArrayInt::hasUniqueValues() const
7871 {
7872   checkAllocated();
7873   if(getNumberOfComponents()!=1)
7874     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7875   int nbOfTuples(getNumberOfTuples());
7876   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
7877   if (s.size() != nbOfTuples)
7878     return false;
7879   return true;
7880 }
7881
7882 /*!
7883  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7884  * array to the new one.
7885  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7886  */
7887 DataArrayDouble *DataArrayInt::convertToDblArr() const
7888 {
7889   checkAllocated();
7890   DataArrayDouble *ret=DataArrayDouble::New();
7891   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7892   std::size_t nbOfVals=getNbOfElems();
7893   const int *src=getConstPointer();
7894   double *dest=ret->getPointer();
7895   std::copy(src,src+nbOfVals,dest);
7896   ret->copyStringInfoFrom(*this);
7897   return ret;
7898 }
7899
7900 /*!
7901  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7902  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7903  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7904  * This method is a specialization of selectByTupleIdSafeSlice().
7905  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7906  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7907  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7908  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7909  *          is to delete using decrRef() as it is no more needed.
7910  *  \throw If \a tupleIdBg < 0.
7911  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7912     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7913  *  \sa DataArrayInt::selectByTupleIdSafeSlice
7914  */
7915 DataArrayInt *DataArrayInt::subArray(int tupleIdBg, int tupleIdEnd) const
7916 {
7917   checkAllocated();
7918   int nbt=getNumberOfTuples();
7919   if(tupleIdBg<0)
7920     throw INTERP_KERNEL::Exception("DataArrayInt::subArray : The tupleIdBg parameter must be greater than 0 !");
7921   if(tupleIdBg>nbt)
7922     throw INTERP_KERNEL::Exception("DataArrayInt::subArray : The tupleIdBg parameter is greater than number of tuples !");
7923   int trueEnd=tupleIdEnd;
7924   if(tupleIdEnd!=-1)
7925     {
7926       if(tupleIdEnd>nbt)
7927         throw INTERP_KERNEL::Exception("DataArrayInt::subArray : The tupleIdBg parameter is greater or equal than number of tuples !");
7928     }
7929   else
7930     trueEnd=nbt;
7931   int nbComp=getNumberOfComponents();
7932   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7933   ret->alloc(trueEnd-tupleIdBg,nbComp);
7934   ret->copyStringInfoFrom(*this);
7935   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7936   return ret.retn();
7937 }
7938
7939 /*!
7940  * Changes the number of components within \a this array so that its raw data **does
7941  * not** change, instead splitting this data into tuples changes.
7942  *  \warning This method erases all (name and unit) component info set before!
7943  *  \param [in] newNbOfComp - number of components for \a this array to have.
7944  *  \throw If \a this is not allocated
7945  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7946  *  \throw If \a newNbOfCompo is lower than 1.
7947  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7948  *  \warning This method erases all (name and unit) component info set before!
7949  */
7950 void DataArrayInt::rearrange(int newNbOfCompo)
7951 {
7952   checkAllocated();
7953   if(newNbOfCompo<1)
7954     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7955   std::size_t nbOfElems=getNbOfElems();
7956   if(nbOfElems%newNbOfCompo!=0)
7957     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7958   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7959     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7960   _info_on_compo.clear();
7961   _info_on_compo.resize(newNbOfCompo);
7962   declareAsNew();
7963 }
7964
7965 /*!
7966  * Changes the number of components within \a this array to be equal to its number
7967  * of tuples, and inversely its number of tuples to become equal to its number of 
7968  * components. So that its raw data **does not** change, instead splitting this
7969  * data into tuples changes.
7970  *  \warning This method erases all (name and unit) component info set before!
7971  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7972  *  \throw If \a this is not allocated.
7973  *  \sa rearrange()
7974  */
7975 void DataArrayInt::transpose()
7976 {
7977   checkAllocated();
7978   int nbOfTuples=getNumberOfTuples();
7979   rearrange(nbOfTuples);
7980 }
7981
7982 /*!
7983  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7984  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7985  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7986  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7987  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7988  * components.  
7989  *  \param [in] newNbOfComp - number of components for the new array to have.
7990  *  \param [in] dftValue - value assigned to new values added to the new array.
7991  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7992  *          is to delete using decrRef() as it is no more needed.
7993  *  \throw If \a this is not allocated.
7994  */
7995 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7996 {
7997   checkAllocated();
7998   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7999   ret->alloc(getNumberOfTuples(),newNbOfComp);
8000   const int *oldc=getConstPointer();
8001   int *nc=ret->getPointer();
8002   int nbOfTuples=getNumberOfTuples();
8003   int oldNbOfComp=getNumberOfComponents();
8004   int dim=std::min(oldNbOfComp,newNbOfComp);
8005   for(int i=0;i<nbOfTuples;i++)
8006     {
8007       int j=0;
8008       for(;j<dim;j++)
8009         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
8010       for(;j<newNbOfComp;j++)
8011         nc[newNbOfComp*i+j]=dftValue;
8012     }
8013   ret->setName(getName());
8014   for(int i=0;i<dim;i++)
8015     ret->setInfoOnComponent(i,getInfoOnComponent(i));
8016   ret->setName(getName());
8017   return ret.retn();
8018 }
8019
8020 /*!
8021  * Changes number of tuples in the array. If the new number of tuples is smaller
8022  * than the current number the array is truncated, otherwise the array is extended.
8023  *  \param [in] nbOfTuples - new number of tuples. 
8024  *  \throw If \a this is not allocated.
8025  *  \throw If \a nbOfTuples is negative.
8026  */
8027 void DataArrayInt::reAlloc(int nbOfTuples)
8028 {
8029   if(nbOfTuples<0)
8030     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
8031   checkAllocated();
8032   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
8033   declareAsNew();
8034 }
8035
8036
8037 /*!
8038  * Returns a copy of \a this array composed of selected components.
8039  * The new DataArrayInt has the same number of tuples but includes components
8040  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
8041  * can be either less, same or more than \a this->getNbOfElems().
8042  *  \param [in] compoIds - sequence of zero based indices of components to include
8043  *              into the new array.
8044  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
8045  *          is to delete using decrRef() as it is no more needed.
8046  *  \throw If \a this is not allocated.
8047  *  \throw If a component index (\a i) is not valid: 
8048  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
8049  *
8050  *  \if ENABLE_EXAMPLES
8051  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
8052  *  \endif
8053  */
8054 DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
8055 {
8056   checkAllocated();
8057   MCAuto<DataArrayInt> ret(DataArrayInt::New());
8058   int newNbOfCompo=(int)compoIds.size();
8059   int oldNbOfCompo=getNumberOfComponents();
8060   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
8061     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
8062   int nbOfTuples=getNumberOfTuples();
8063   ret->alloc(nbOfTuples,newNbOfCompo);
8064   ret->copyPartOfStringInfoFrom(*this,compoIds);
8065   const int *oldc=getConstPointer();
8066   int *nc=ret->getPointer();
8067   for(int i=0;i<nbOfTuples;i++)
8068     for(int j=0;j<newNbOfCompo;j++,nc++)
8069       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
8070   return ret.retn();
8071 }
8072
8073 /*!
8074  * Appends components of another array to components of \a this one, tuple by tuple.
8075  * So that the number of tuples of \a this array remains the same and the number of 
8076  * components increases.
8077  *  \param [in] other - the DataArrayInt to append to \a this one.
8078  *  \throw If \a this is not allocated.
8079  *  \throw If \a this and \a other arrays have different number of tuples.
8080  *
8081  *  \if ENABLE_EXAMPLES
8082  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
8083  *
8084  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
8085  *  \endif
8086  */
8087 void DataArrayInt::meldWith(const DataArrayInt *other)
8088 {
8089   if(!other)
8090     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
8091   checkAllocated();
8092   other->checkAllocated();
8093   int nbOfTuples=getNumberOfTuples();
8094   if(nbOfTuples!=other->getNumberOfTuples())
8095     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
8096   int nbOfComp1=getNumberOfComponents();
8097   int nbOfComp2=other->getNumberOfComponents();
8098   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
8099   int *w=newArr;
8100   const int *inp1=getConstPointer();
8101   const int *inp2=other->getConstPointer();
8102   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
8103     {
8104       w=std::copy(inp1,inp1+nbOfComp1,w);
8105       w=std::copy(inp2,inp2+nbOfComp2,w);
8106     }
8107   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
8108   std::vector<int> compIds(nbOfComp2);
8109   for(int i=0;i<nbOfComp2;i++)
8110     compIds[i]=nbOfComp1+i;
8111   copyPartOfStringInfoFrom2(compIds,*other);
8112 }
8113
8114 /*!
8115  * Copy all components in a specified order from another DataArrayInt.
8116  * The specified components become the first ones in \a this array.
8117  * Both numerical and textual data is copied. The number of tuples in \a this and
8118  * the other array can be different.
8119  *  \param [in] a - the array to copy data from.
8120  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
8121  *              to be copied.
8122  *  \throw If \a a is NULL.
8123  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
8124  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
8125  *
8126  *  \if ENABLE_EXAMPLES
8127  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
8128  *  \endif
8129  */
8130 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
8131 {
8132   if(!a)
8133     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
8134   checkAllocated();
8135   a->checkAllocated();
8136   copyPartOfStringInfoFrom2(compoIds,*a);
8137   std::size_t partOfCompoSz=compoIds.size();
8138   int nbOfCompo=getNumberOfComponents();
8139   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
8140   const int *ac=a->getConstPointer();
8141   int *nc=getPointer();
8142   for(int i=0;i<nbOfTuples;i++)
8143     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
8144       nc[nbOfCompo*i+compoIds[j]]=*ac;
8145 }
8146
8147 /*!
8148  * Copy all values from another DataArrayInt into specified tuples and components
8149  * of \a this array. Textual data is not copied.
8150  * The tree parameters defining set of indices of tuples and components are similar to
8151  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
8152  *  \param [in] a - the array to copy values from.
8153  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
8154  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
8155  *              are located.
8156  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
8157  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
8158  *  \param [in] endComp - index of the component before which the components to assign
8159  *              to are located.
8160  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8161  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
8162  *              must be equal to the number of columns to assign to, else an
8163  *              exception is thrown; if \a false, then it is only required that \a
8164  *              a->getNbOfElems() equals to number of values to assign to (this condition
8165  *              must be respected even if \a strictCompoCompare is \a true). The number of 
8166  *              values to assign to is given by following Python expression:
8167  *              \a nbTargetValues = 
8168  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
8169  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
8170  *  \throw If \a a is NULL.
8171  *  \throw If \a a is not allocated.
8172  *  \throw If \a this is not allocated.
8173  *  \throw If parameters specifying tuples and components to assign to do not give a
8174  *            non-empty range of increasing indices.
8175  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
8176  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
8177  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
8178  *
8179  *  \if ENABLE_EXAMPLES
8180  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
8181  *  \endif
8182  */
8183 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8184 {
8185   if(!a)
8186     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
8187   const char msg[]="DataArrayInt::setPartOfValues1";
8188   checkAllocated();
8189   a->checkAllocated();
8190   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8191   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8192   int nbComp=getNumberOfComponents();
8193   int nbOfTuples=getNumberOfTuples();
8194   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8195   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8196   bool assignTech=true;
8197   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8198     {
8199       if(strictCompoCompare)
8200         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8201     }
8202   else
8203     {
8204       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8205       assignTech=false;
8206     }
8207   int *pt=getPointer()+bgTuples*nbComp+bgComp;
8208   const int *srcPt=a->getConstPointer();
8209   if(assignTech)
8210     {
8211       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8212         for(int j=0;j<newNbOfComp;j++,srcPt++)
8213           pt[j*stepComp]=*srcPt;
8214     }
8215   else
8216     {
8217       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8218         {
8219           const int *srcPt2=srcPt;
8220           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8221             pt[j*stepComp]=*srcPt2;
8222         }
8223     }
8224 }
8225
8226 /*!
8227  * Assign a given value to values at specified tuples and components of \a this array.
8228  * The tree parameters defining set of indices of tuples and components are similar to
8229  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
8230  *  \param [in] a - the value to assign.
8231  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
8232  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
8233  *              are located.
8234  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
8235  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8236  *  \param [in] endComp - index of the component before which the components to assign
8237  *              to are located.
8238  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8239  *  \throw If \a this is not allocated.
8240  *  \throw If parameters specifying tuples and components to assign to, do not give a
8241  *            non-empty range of increasing indices or indices are out of a valid range
8242  *            for \c this array.
8243  *
8244  *  \if ENABLE_EXAMPLES
8245  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
8246  *  \endif
8247  */
8248 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
8249 {
8250   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
8251   checkAllocated();
8252   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8253   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8254   int nbComp=getNumberOfComponents();
8255   int nbOfTuples=getNumberOfTuples();
8256   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8257   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8258   int *pt=getPointer()+bgTuples*nbComp+bgComp;
8259   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8260     for(int j=0;j<newNbOfComp;j++)
8261       pt[j*stepComp]=a;
8262 }
8263
8264
8265 /*!
8266  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8267  * components of \a this array. Textual data is not copied.
8268  * The tuples and components to assign to are defined by C arrays of indices.
8269  * There are two *modes of usage*:
8270  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8271  *   of \a a is assigned to its own location within \a this array. 
8272  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8273  *   components of every specified tuple of \a this array. In this mode it is required
8274  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8275  * 
8276  *  \param [in] a - the array to copy values from.
8277  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8278  *              assign values of \a a to.
8279  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8280  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8281  *              \a bgTuples <= \a pi < \a endTuples.
8282  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8283  *              assign values of \a a to.
8284  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8285  *              pointer to a component index <em>(pi)</em> varies as this: 
8286  *              \a bgComp <= \a pi < \a endComp.
8287  *  \param [in] strictCompoCompare - this parameter is checked only if the
8288  *               *mode of usage* is the first; if it is \a true (default), 
8289  *               then \a a->getNumberOfComponents() must be equal 
8290  *               to the number of specified columns, else this is not required.
8291  *  \throw If \a a is NULL.
8292  *  \throw If \a a is not allocated.
8293  *  \throw If \a this is not allocated.
8294  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8295  *         out of a valid range for \a this array.
8296  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8297  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
8298  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8299  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
8300  *
8301  *  \if ENABLE_EXAMPLES
8302  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
8303  *  \endif
8304  */
8305 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8306 {
8307   if(!a)
8308     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
8309   const char msg[]="DataArrayInt::setPartOfValues2";
8310   checkAllocated();
8311   a->checkAllocated();
8312   int nbComp=getNumberOfComponents();
8313   int nbOfTuples=getNumberOfTuples();
8314   for(const int *z=bgComp;z!=endComp;z++)
8315     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8316   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8317   int newNbOfComp=(int)std::distance(bgComp,endComp);
8318   bool assignTech=true;
8319   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8320     {
8321       if(strictCompoCompare)
8322         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8323     }
8324   else
8325     {
8326       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8327       assignTech=false;
8328     }
8329   int *pt=getPointer();
8330   const int *srcPt=a->getConstPointer();
8331   if(assignTech)
8332     {    
8333       for(const int *w=bgTuples;w!=endTuples;w++)
8334         {
8335           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8336           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8337             {    
8338               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
8339             }
8340         }
8341     }
8342   else
8343     {
8344       for(const int *w=bgTuples;w!=endTuples;w++)
8345         {
8346           const int *srcPt2=srcPt;
8347           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8348           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8349             {    
8350               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
8351             }
8352         }
8353     }
8354 }
8355
8356 /*!
8357  * Assign a given value to values at specified tuples and components of \a this array.
8358  * The tuples and components to assign to are defined by C arrays of indices.
8359  *  \param [in] a - the value to assign.
8360  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8361  *              assign \a a to.
8362  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8363  *              pointer to a tuple index (\a pi) varies as this: 
8364  *              \a bgTuples <= \a pi < \a endTuples.
8365  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
8366  *              assign \a a to.
8367  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
8368  *              pointer to a component index (\a pi) varies as this: 
8369  *              \a bgComp <= \a pi < \a endComp.
8370  *  \throw If \a this is not allocated.
8371  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
8372  *         out of a valid range for \a this array.
8373  *
8374  *  \if ENABLE_EXAMPLES
8375  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
8376  *  \endif
8377  */
8378 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
8379 {
8380   checkAllocated();
8381   int nbComp=getNumberOfComponents();
8382   int nbOfTuples=getNumberOfTuples();
8383   for(const int *z=bgComp;z!=endComp;z++)
8384     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8385   int *pt=getPointer();
8386   for(const int *w=bgTuples;w!=endTuples;w++)
8387     for(const int *z=bgComp;z!=endComp;z++)
8388       {
8389         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8390         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
8391       }
8392 }
8393
8394 /*!
8395  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
8396  * components of \a this array. Textual data is not copied.
8397  * The tuples to assign to are defined by a C array of indices.
8398  * The components to assign to are defined by three values similar to parameters of
8399  * the Python function \c range(\c start,\c stop,\c step).
8400  * There are two *modes of usage*:
8401  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8402  *   of \a a is assigned to its own location within \a this array. 
8403  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8404  *   components of every specified tuple of \a this array. In this mode it is required
8405  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8406  *
8407  *  \param [in] a - the array to copy values from.
8408  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8409  *              assign values of \a a to.
8410  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8411  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8412  *              \a bgTuples <= \a pi < \a endTuples.
8413  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8414  *  \param [in] endComp - index of the component before which the components to assign
8415  *              to are located.
8416  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8417  *  \param [in] strictCompoCompare - this parameter is checked only in the first
8418  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
8419  *               then \a a->getNumberOfComponents() must be equal 
8420  *               to the number of specified columns, else this is not required.
8421  *  \throw If \a a is NULL.
8422  *  \throw If \a a is not allocated.
8423  *  \throw If \a this is not allocated.
8424  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8425  *         \a this array.
8426  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8427  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
8428  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8429  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8430  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
8431  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8432  *  \throw If parameters specifying components to assign to, do not give a
8433  *            non-empty range of increasing indices or indices are out of a valid range
8434  *            for \c this array.
8435  *
8436  *  \if ENABLE_EXAMPLES
8437  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
8438  *  \endif
8439  */
8440 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8441 {
8442   if(!a)
8443     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
8444   const char msg[]="DataArrayInt::setPartOfValues3";
8445   checkAllocated();
8446   a->checkAllocated();
8447   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8448   int nbComp=getNumberOfComponents();
8449   int nbOfTuples=getNumberOfTuples();
8450   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8451   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8452   bool assignTech=true;
8453   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8454     {
8455       if(strictCompoCompare)
8456         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8457     }
8458   else
8459     {
8460       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8461       assignTech=false;
8462     }
8463   int *pt=getPointer()+bgComp;
8464   const int *srcPt=a->getConstPointer();
8465   if(assignTech)
8466     {
8467       for(const int *w=bgTuples;w!=endTuples;w++)
8468         for(int j=0;j<newNbOfComp;j++,srcPt++)
8469           {
8470             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8471             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
8472           }
8473     }
8474   else
8475     {
8476       for(const int *w=bgTuples;w!=endTuples;w++)
8477         {
8478           const int *srcPt2=srcPt;
8479           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8480             {
8481               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8482               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
8483             }
8484         }
8485     }
8486 }
8487
8488 /*!
8489  * Assign a given value to values at specified tuples and components of \a this array.
8490  * The tuples to assign to are defined by a C array of indices.
8491  * The components to assign to are defined by three values similar to parameters of
8492  * the Python function \c range(\c start,\c stop,\c step).
8493  *  \param [in] a - the value to assign.
8494  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8495  *              assign \a a to.
8496  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8497  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8498  *              \a bgTuples <= \a pi < \a endTuples.
8499  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8500  *  \param [in] endComp - index of the component before which the components to assign
8501  *              to are located.
8502  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8503  *  \throw If \a this is not allocated.
8504  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8505  *         \a this array.
8506  *  \throw If parameters specifying components to assign to, do not give a
8507  *            non-empty range of increasing indices or indices are out of a valid range
8508  *            for \c this array.
8509  *
8510  *  \if ENABLE_EXAMPLES
8511  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
8512  *  \endif
8513  */
8514 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
8515 {
8516   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
8517   checkAllocated();
8518   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8519   int nbComp=getNumberOfComponents();
8520   int nbOfTuples=getNumberOfTuples();
8521   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8522   int *pt=getPointer()+bgComp;
8523   for(const int *w=bgTuples;w!=endTuples;w++)
8524     for(int j=0;j<newNbOfComp;j++)
8525       {
8526         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8527         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
8528       }
8529 }
8530
8531 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8532 {
8533   if(!a)
8534     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
8535   const char msg[]="DataArrayInt::setPartOfValues4";
8536   checkAllocated();
8537   a->checkAllocated();
8538   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8539   int newNbOfComp=(int)std::distance(bgComp,endComp);
8540   int nbComp=getNumberOfComponents();
8541   for(const int *z=bgComp;z!=endComp;z++)
8542     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8543   int nbOfTuples=getNumberOfTuples();
8544   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8545   bool assignTech=true;
8546   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8547     {
8548       if(strictCompoCompare)
8549         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8550     }
8551   else
8552     {
8553       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8554       assignTech=false;
8555     }
8556   const int *srcPt=a->getConstPointer();
8557   int *pt=getPointer()+bgTuples*nbComp;
8558   if(assignTech)
8559     {
8560       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8561         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8562           pt[*z]=*srcPt;
8563     }
8564   else
8565     {
8566       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8567         {
8568           const int *srcPt2=srcPt;
8569           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8570             pt[*z]=*srcPt2;
8571         }
8572     }
8573 }
8574
8575 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
8576 {
8577   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
8578   checkAllocated();
8579   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8580   int nbComp=getNumberOfComponents();
8581   for(const int *z=bgComp;z!=endComp;z++)
8582     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8583   int nbOfTuples=getNumberOfTuples();
8584   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8585   int *pt=getPointer()+bgTuples*nbComp;
8586   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8587     for(const int *z=bgComp;z!=endComp;z++)
8588       pt[*z]=a;
8589 }
8590
8591 /*!
8592  * Copy some tuples from another DataArrayInt into specified tuples
8593  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8594  * components.
8595  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8596  * All components of selected tuples are copied.
8597  *  \param [in] a - the array to copy values from.
8598  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8599  *              target tuples of \a this. \a tuplesSelec has two components, and the
8600  *              first component specifies index of the source tuple and the second
8601  *              one specifies index of the target tuple.
8602  *  \throw If \a this is not allocated.
8603  *  \throw If \a a is NULL.
8604  *  \throw If \a a is not allocated.
8605  *  \throw If \a tuplesSelec is NULL.
8606  *  \throw If \a tuplesSelec is not allocated.
8607  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8608  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8609  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8610  *         the corresponding (\a this or \a a) array.
8611  */
8612 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8613 {
8614   if(!a || !tuplesSelec)
8615     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8616   checkAllocated();
8617   a->checkAllocated();
8618   tuplesSelec->checkAllocated();
8619   int nbOfComp=getNumberOfComponents();
8620   if(nbOfComp!=a->getNumberOfComponents())
8621     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8622   if(tuplesSelec->getNumberOfComponents()!=2)
8623     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8624   int thisNt=getNumberOfTuples();
8625   int aNt=a->getNumberOfTuples();
8626   int *valsToSet=getPointer();
8627   const int *valsSrc=a->getConstPointer();
8628   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8629     {
8630       if(tuple[1]>=0 && tuple[1]<aNt)
8631         {
8632           if(tuple[0]>=0 && tuple[0]<thisNt)
8633             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8634           else
8635             {
8636               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8637               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8638               throw INTERP_KERNEL::Exception(oss.str().c_str());
8639             }
8640         }
8641       else
8642         {
8643           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8644           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8645           throw INTERP_KERNEL::Exception(oss.str().c_str());
8646         }
8647     }
8648 }
8649
8650 /*!
8651  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8652  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8653  * components.
8654  * The tuples to assign to are defined by index of the first tuple, and
8655  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8656  * The tuples to copy are defined by values of a DataArrayInt.
8657  * All components of selected tuples are copied.
8658  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8659  *              values to.
8660  *  \param [in] aBase - the array to copy values from.
8661  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8662  *  \throw If \a this is not allocated.
8663  *  \throw If \a aBase is NULL.
8664  *  \throw If \a aBase is not allocated.
8665  *  \throw If \a tuplesSelec is NULL.
8666  *  \throw If \a tuplesSelec is not allocated.
8667  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8668  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8669  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8670  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8671  *         \a aBase array.
8672  */
8673 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8674 {
8675   if(!aBase || !tuplesSelec)
8676     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8677   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8678   if(!a)
8679     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8680   checkAllocated();
8681   a->checkAllocated();
8682   tuplesSelec->checkAllocated();
8683   int nbOfComp=getNumberOfComponents();
8684   if(nbOfComp!=a->getNumberOfComponents())
8685     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8686   if(tuplesSelec->getNumberOfComponents()!=1)
8687     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8688   int thisNt=getNumberOfTuples();
8689   int aNt=a->getNumberOfTuples();
8690   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8691   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8692   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8693     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8694   const int *valsSrc=a->getConstPointer();
8695   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8696     {
8697       if(*tuple>=0 && *tuple<aNt)
8698         {
8699           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8700         }
8701       else
8702         {
8703           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8704           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8705           throw INTERP_KERNEL::Exception(oss.str().c_str());
8706         }
8707     }
8708 }
8709
8710 /*!
8711  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8712  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8713  * components.
8714  * The tuples to copy are defined by three values similar to parameters of
8715  * the Python function \c range(\c start,\c stop,\c step).
8716  * The tuples to assign to are defined by index of the first tuple, and
8717  * their number is defined by number of tuples to copy.
8718  * All components of selected tuples are copied.
8719  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8720  *              values to.
8721  *  \param [in] aBase - the array to copy values from.
8722  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8723  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8724  *              are located.
8725  *  \param [in] step - index increment to get index of the next tuple to copy.
8726  *  \throw If \a this is not allocated.
8727  *  \throw If \a aBase is NULL.
8728  *  \throw If \a aBase is not allocated.
8729  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8730  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8731  *  \throw If parameters specifying tuples to copy, do not give a
8732  *            non-empty range of increasing indices or indices are out of a valid range
8733  *            for the array \a aBase.
8734  */
8735 void DataArrayInt::setContigPartOfSelectedValuesSlice(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8736 {
8737   if(!aBase)
8738     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : input DataArray is NULL !");
8739   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8740   if(!a)
8741     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : input DataArray aBase is not a DataArrayInt !");
8742   checkAllocated();
8743   a->checkAllocated();
8744   int nbOfComp=getNumberOfComponents();
8745   const char msg[]="DataArrayInt::setContigPartOfSelectedValuesSlice";
8746   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8747   if(nbOfComp!=a->getNumberOfComponents())
8748     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : This and a do not have the same number of components !");
8749   int thisNt=getNumberOfTuples();
8750   int aNt=a->getNumberOfTuples();
8751   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8752   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8753     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : invalid number range of values to write !");
8754   if(end2>aNt)
8755     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValuesSlice : invalid range of values to read !");
8756   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8757   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8758     {
8759       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8760     }
8761 }
8762
8763 /*!
8764  * Returns a value located at specified tuple and component.
8765  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8766  * parameters is checked. So this method is safe but expensive if used to go through
8767  * all values of \a this.
8768  *  \param [in] tupleId - index of tuple of interest.
8769  *  \param [in] compoId - index of component of interest.
8770  *  \return double - value located by \a tupleId and \a compoId.
8771  *  \throw If \a this is not allocated.
8772  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8773  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8774  */
8775 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8776 {
8777   checkAllocated();
8778   if(tupleId<0 || tupleId>=getNumberOfTuples())
8779     {
8780       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8781       throw INTERP_KERNEL::Exception(oss.str().c_str());
8782     }
8783   if(compoId<0 || compoId>=getNumberOfComponents())
8784     {
8785       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8786       throw INTERP_KERNEL::Exception(oss.str().c_str());
8787     }
8788   return _mem[tupleId*_info_on_compo.size()+compoId];
8789 }
8790
8791 /*!
8792  * Returns the first value of \a this. 
8793  *  \return int - the last value of \a this array.
8794  *  \throw If \a this is not allocated.
8795  *  \throw If \a this->getNumberOfComponents() != 1.
8796  *  \throw If \a this->getNumberOfTuples() < 1.
8797  */
8798 int DataArrayInt::front() const
8799 {
8800   checkAllocated();
8801   if(getNumberOfComponents()!=1)
8802     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8803   int nbOfTuples=getNumberOfTuples();
8804   if(nbOfTuples<1)
8805     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8806   return *(getConstPointer());
8807 }
8808
8809 /*!
8810  * Returns the last value of \a this. 
8811  *  \return int - the last value of \a this array.
8812  *  \throw If \a this is not allocated.
8813  *  \throw If \a this->getNumberOfComponents() != 1.
8814  *  \throw If \a this->getNumberOfTuples() < 1.
8815  */
8816 int DataArrayInt::back() const
8817 {
8818   checkAllocated();
8819   if(getNumberOfComponents()!=1)
8820     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8821   int nbOfTuples=getNumberOfTuples();
8822   if(nbOfTuples<1)
8823     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8824   return *(getConstPointer()+nbOfTuples-1);
8825 }
8826
8827 /*!
8828  * Assign pointer to one array to a pointer to another appay. Reference counter of
8829  * \a arrayToSet is incremented / decremented.
8830  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8831  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8832  */
8833 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8834 {
8835   if(newArray!=arrayToSet)
8836     {
8837       if(arrayToSet)
8838         arrayToSet->decrRef();
8839       arrayToSet=newArray;
8840       if(arrayToSet)
8841         arrayToSet->incrRef();
8842     }
8843 }
8844
8845 DataArrayIntIterator *DataArrayInt::iterator()
8846 {
8847   return new DataArrayIntIterator(this);
8848 }
8849
8850 /*!
8851  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8852  * given one. The ids are sorted in the ascending order.
8853  *  \param [in] val - the value to find within \a this.
8854  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8855  *          array using decrRef() as it is no more needed.
8856  *  \throw If \a this is not allocated.
8857  *  \throw If \a this->getNumberOfComponents() != 1.
8858  *  \sa DataArrayInt::findIdsEqualTuple
8859  */
8860 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
8861 {
8862   checkAllocated();
8863   if(getNumberOfComponents()!=1)
8864     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : 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 value \b not
8876  * equal to a given one. 
8877  *  \param [in] val - the value to ignore within \a this.
8878  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8879  *          array using decrRef() as it is no more needed.
8880  *  \throw If \a this is not allocated.
8881  *  \throw If \a this->getNumberOfComponents() != 1.
8882  */
8883 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
8884 {
8885   checkAllocated();
8886   if(getNumberOfComponents()!=1)
8887     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8888   const int *cptr(getConstPointer());
8889   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8890   int nbOfTuples=getNumberOfTuples();
8891   for(int i=0;i<nbOfTuples;i++,cptr++)
8892     if(*cptr!=val)
8893       ret->pushBackSilent(i);
8894   return ret.retn();
8895 }
8896
8897 /*!
8898  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
8899  * This method is an extension of  DataArrayInt::findIdsEqual method.
8900  *
8901  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
8902  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
8903  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8904  *          array using decrRef() as it is no more needed.
8905  *  \throw If \a this is not allocated.
8906  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
8907  * \throw If \a this->getNumberOfComponents() is equal to 0.
8908  * \sa DataArrayInt::findIdsEqual
8909  */
8910 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
8911 {
8912   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
8913   checkAllocated();
8914   if(getNumberOfComponents()!=(int)nbOfCompoExp)
8915     {
8916       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
8917       throw INTERP_KERNEL::Exception(oss.str().c_str());
8918     }
8919   if(nbOfCompoExp==0)
8920     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
8921   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8922   const int *bg(begin()),*end2(end()),*work(begin());
8923   while(work!=end2)
8924     {
8925       work=std::search(work,end2,tupleBg,tupleEnd);
8926       if(work!=end2)
8927         {
8928           std::size_t pos(std::distance(bg,work));
8929           if(pos%nbOfCompoExp==0)
8930             ret->pushBackSilent(pos/nbOfCompoExp);
8931           work++;
8932         }
8933     }
8934   return ret.retn();
8935 }
8936
8937 /*!
8938  * Assigns \a newValue to all elements holding \a oldValue within \a this
8939  * one-dimensional array.
8940  *  \param [in] oldValue - the value to replace.
8941  *  \param [in] newValue - the value to assign.
8942  *  \return int - number of replacements performed.
8943  *  \throw If \a this is not allocated.
8944  *  \throw If \a this->getNumberOfComponents() != 1.
8945  */
8946 int DataArrayInt::changeValue(int oldValue, int newValue)
8947 {
8948   checkAllocated();
8949   if(getNumberOfComponents()!=1)
8950     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8951   if(oldValue==newValue)
8952     return 0;
8953   int *start(getPointer()),*end2(start+getNbOfElems());
8954   int ret(0);
8955   for(int *val=start;val!=end2;val++)
8956     {
8957       if(*val==oldValue)
8958         {
8959           *val=newValue;
8960           ret++;
8961         }
8962     }
8963   if(ret>0)
8964     declareAsNew();
8965   return ret;
8966 }
8967
8968 /*!
8969  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8970  * one of given values.
8971  *  \param [in] valsBg - an array of values to find within \a this array.
8972  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8973  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8974  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8975  *          array using decrRef() as it is no more needed.
8976  *  \throw If \a this->getNumberOfComponents() != 1.
8977  */
8978 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
8979 {
8980   if(getNumberOfComponents()!=1)
8981     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8982   std::set<int> vals2(valsBg,valsEnd);
8983   const int *cptr(getConstPointer());
8984   std::vector<int> res;
8985   int nbOfTuples(getNumberOfTuples());
8986   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8987   for(int i=0;i<nbOfTuples;i++,cptr++)
8988     if(vals2.find(*cptr)!=vals2.end())
8989       ret->pushBackSilent(i);
8990   return ret.retn();
8991 }
8992
8993 /*!
8994  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8995  * equal to any of given values.
8996  *  \param [in] valsBg - an array of values to ignore within \a this array.
8997  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8998  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8999  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9000  *          array using decrRef() as it is no more needed.
9001  *  \throw If \a this->getNumberOfComponents() != 1.
9002  */
9003 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
9004 {
9005   if(getNumberOfComponents()!=1)
9006     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
9007   std::set<int> vals2(valsBg,valsEnd);
9008   const int *cptr=getConstPointer();
9009   std::vector<int> res;
9010   int nbOfTuples=getNumberOfTuples();
9011   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9012   for(int i=0;i<nbOfTuples;i++,cptr++)
9013     if(vals2.find(*cptr)==vals2.end())
9014       ret->pushBackSilent(i);
9015   return ret.retn();
9016 }
9017
9018 /*!
9019  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
9020  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
9021  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
9022  * If any the tuple id is returned. If not -1 is returned.
9023  * 
9024  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
9025  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
9026  *
9027  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
9028  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
9029  */
9030 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
9031 {
9032   checkAllocated();
9033   int nbOfCompo=getNumberOfComponents();
9034   if(nbOfCompo==0)
9035     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
9036   if(nbOfCompo!=(int)tupl.size())
9037     {
9038       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
9039       throw INTERP_KERNEL::Exception(oss.str().c_str());
9040     }
9041   const int *cptr=getConstPointer();
9042   std::size_t nbOfVals=getNbOfElems();
9043   for(const int *work=cptr;work!=cptr+nbOfVals;)
9044     {
9045       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
9046       if(work!=cptr+nbOfVals)
9047         {
9048           if(std::distance(cptr,work)%nbOfCompo!=0)
9049             work++;
9050           else
9051             return std::distance(cptr,work)/nbOfCompo;
9052         }
9053     }
9054   return -1;
9055 }
9056
9057 /*!
9058  * This method searches the sequence specified in input parameter \b vals in \b this.
9059  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
9060  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
9061  * \sa DataArrayInt::findIdFirstEqualTuple
9062  */
9063 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
9064 {
9065   checkAllocated();
9066   int nbOfCompo=getNumberOfComponents();
9067   if(nbOfCompo!=1)
9068     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
9069   const int *cptr=getConstPointer();
9070   std::size_t nbOfVals=getNbOfElems();
9071   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
9072   if(loc!=cptr+nbOfVals)
9073     return std::distance(cptr,loc);
9074   return -1;
9075 }
9076
9077 /*!
9078  * This method expects to be called when number of components of this is equal to one.
9079  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
9080  * If not any tuple contains \b value -1 is returned.
9081  * \sa DataArrayInt::presenceOfValue
9082  */
9083 int DataArrayInt::findIdFirstEqual(int value) const
9084 {
9085   checkAllocated();
9086   if(getNumberOfComponents()!=1)
9087     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
9088   const int *cptr=getConstPointer();
9089   int nbOfTuples=getNumberOfTuples();
9090   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
9091   if(ret!=cptr+nbOfTuples)
9092     return std::distance(cptr,ret);
9093   return -1;
9094 }
9095
9096 /*!
9097  * This method expects to be called when number of components of this is equal to one.
9098  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
9099  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
9100  * \sa DataArrayInt::presenceOfValue
9101  */
9102 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
9103 {
9104   checkAllocated();
9105   if(getNumberOfComponents()!=1)
9106     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
9107   std::set<int> vals2(vals.begin(),vals.end());
9108   const int *cptr=getConstPointer();
9109   int nbOfTuples=getNumberOfTuples();
9110   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
9111     if(vals2.find(*w)!=vals2.end())
9112       return std::distance(cptr,w);
9113   return -1;
9114 }
9115
9116 /*!
9117  * This method returns the number of values in \a this that are equals to input parameter \a value.
9118  * This method only works for single component array.
9119  *
9120  * \return a value in [ 0, \c this->getNumberOfTuples() )
9121  *
9122  * \throw If \a this is not allocated
9123  *
9124  */
9125 int DataArrayInt::count(int value) const
9126 {
9127   int ret=0;
9128   checkAllocated();
9129   if(getNumberOfComponents()!=1)
9130     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
9131   const int *vals=begin();
9132   int nbOfTuples=getNumberOfTuples();
9133   for(int i=0;i<nbOfTuples;i++,vals++)
9134     if(*vals==value)
9135       ret++;
9136   return ret;
9137 }
9138
9139 /*!
9140  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
9141  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
9142  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
9143  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
9144  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
9145  * \sa DataArrayInt::findIdFirstEqualTuple
9146  */
9147 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
9148 {
9149   return findIdFirstEqualTuple(tupl)!=-1;
9150 }
9151
9152
9153 /*!
9154  * Returns \a true if a given value is present within \a this one-dimensional array.
9155  *  \param [in] value - the value to find within \a this array.
9156  *  \return bool - \a true in case if \a value is present within \a this array.
9157  *  \throw If \a this is not allocated.
9158  *  \throw If \a this->getNumberOfComponents() != 1.
9159  *  \sa findIdFirstEqual()
9160  */
9161 bool DataArrayInt::presenceOfValue(int value) const
9162 {
9163   return findIdFirstEqual(value)!=-1;
9164 }
9165
9166 /*!
9167  * This method expects to be called when number of components of this is equal to one.
9168  * This method returns true if it exists a tuple so that the value is contained in \b vals.
9169  * If not any tuple contains one of the values contained in 'vals' false is returned.
9170  * \sa DataArrayInt::findIdFirstEqual
9171  */
9172 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
9173 {
9174   return findIdFirstEqual(vals)!=-1;
9175 }
9176
9177 /*!
9178  * Accumulates values of each component of \a this array.
9179  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
9180  *         by the caller, that is filled by this method with sum value for each
9181  *         component.
9182  *  \throw If \a this is not allocated.
9183  */
9184 void DataArrayInt::accumulate(int *res) const
9185 {
9186   checkAllocated();
9187   const int *ptr=getConstPointer();
9188   int nbTuple=getNumberOfTuples();
9189   int nbComps=getNumberOfComponents();
9190   std::fill(res,res+nbComps,0);
9191   for(int i=0;i<nbTuple;i++)
9192     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
9193 }
9194
9195 int DataArrayInt::accumulate(int compId) const
9196 {
9197   checkAllocated();
9198   const int *ptr=getConstPointer();
9199   int nbTuple=getNumberOfTuples();
9200   int nbComps=getNumberOfComponents();
9201   if(compId<0 || compId>=nbComps)
9202     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
9203   int ret=0;
9204   for(int i=0;i<nbTuple;i++)
9205     ret+=ptr[i*nbComps+compId];
9206   return ret;
9207 }
9208
9209 /*!
9210  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
9211  * The returned array will have same number of components than \a this and number of tuples equal to
9212  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
9213  *
9214  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
9215  *
9216  * \param [in] bgOfIndex - begin (included) of the input index array.
9217  * \param [in] endOfIndex - end (excluded) of the input index array.
9218  * \return DataArrayInt * - the new instance having the same number of components than \a this.
9219  * 
9220  * \throw If bgOfIndex or end is NULL.
9221  * \throw If input index array is not ascendingly sorted.
9222  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
9223  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
9224  */
9225 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
9226 {
9227   if(!bgOfIndex || !endOfIndex)
9228     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
9229   checkAllocated();
9230   int nbCompo=getNumberOfComponents();
9231   int nbOfTuples=getNumberOfTuples();
9232   int sz=(int)std::distance(bgOfIndex,endOfIndex);
9233   if(sz<1)
9234     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
9235   sz--;
9236   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
9237   const int *w=bgOfIndex;
9238   if(*w<0 || *w>=nbOfTuples)
9239     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
9240   const int *srcPt=begin()+(*w)*nbCompo;
9241   int *tmp=ret->getPointer();
9242   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
9243     {
9244       std::fill(tmp,tmp+nbCompo,0);
9245       if(w[1]>=w[0])
9246         {
9247           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
9248             {
9249               if(j>=0 && j<nbOfTuples)
9250                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
9251               else
9252                 {
9253                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
9254                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9255                 }
9256             }
9257         }
9258       else
9259         {
9260           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
9261           throw INTERP_KERNEL::Exception(oss.str().c_str());
9262         }
9263     }
9264   ret->copyStringInfoFrom(*this);
9265   return ret.retn();
9266 }
9267
9268 /*!
9269  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
9270  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
9271  * offsetA2</em> and (2)
9272  * the number of component in the result array is same as that of each of given arrays.
9273  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
9274  * Info on components is copied from the first of the given arrays. Number of components
9275  * in the given arrays must be the same.
9276  *  \param [in] a1 - an array to include in the result array.
9277  *  \param [in] a2 - another array to include in the result array.
9278  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
9279  *  \return DataArrayInt * - the new instance of DataArrayInt.
9280  *          The caller is to delete this result array using decrRef() as it is no more
9281  *          needed.
9282  *  \throw If either \a a1 or \a a2 is NULL.
9283  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
9284  */
9285 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
9286 {
9287   if(!a1 || !a2)
9288     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
9289   int nbOfComp=a1->getNumberOfComponents();
9290   if(nbOfComp!=a2->getNumberOfComponents())
9291     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
9292   int nbOfTuple1=a1->getNumberOfTuples();
9293   int nbOfTuple2=a2->getNumberOfTuples();
9294   DataArrayInt *ret=DataArrayInt::New();
9295   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
9296   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
9297   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
9298   ret->copyStringInfoFrom(*a1);
9299   return ret;
9300 }
9301
9302 /*!
9303  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
9304  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
9305  * the number of component in the result array is same as that of each of given arrays.
9306  * Info on components is copied from the first of the given arrays. Number of components
9307  * in the given arrays must be  the same.
9308  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
9309  * not the object itself.
9310  *  \param [in] arr - a sequence of arrays to include in the result array.
9311  *  \return DataArrayInt * - the new instance of DataArrayInt.
9312  *          The caller is to delete this result array using decrRef() as it is no more
9313  *          needed.
9314  *  \throw If all arrays within \a arr are NULL.
9315  *  \throw If getNumberOfComponents() of arrays within \a arr.
9316  */
9317 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
9318 {
9319   std::vector<const DataArrayInt *> a;
9320   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9321     if(*it4)
9322       a.push_back(*it4);
9323   if(a.empty())
9324     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
9325   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
9326   int nbOfComp=(*it)->getNumberOfComponents();
9327   int nbt=(*it++)->getNumberOfTuples();
9328   for(int i=1;it!=a.end();it++,i++)
9329     {
9330       if((*it)->getNumberOfComponents()!=nbOfComp)
9331         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
9332       nbt+=(*it)->getNumberOfTuples();
9333     }
9334   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9335   ret->alloc(nbt,nbOfComp);
9336   int *pt=ret->getPointer();
9337   for(it=a.begin();it!=a.end();it++)
9338     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
9339   ret->copyStringInfoFrom(*(a[0]));
9340   return ret.retn();
9341 }
9342
9343 /*!
9344  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
9345  * A packed index array is an allocated array with one component, and at least one tuple. The first element
9346  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
9347  * 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.
9348  * 
9349  * \return DataArrayInt * - a new object to be managed by the caller.
9350  */
9351 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
9352 {
9353   int retSz=1;
9354   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
9355     {
9356       if(*it4)
9357         {
9358           (*it4)->checkAllocated();
9359           if((*it4)->getNumberOfComponents()!=1)
9360             {
9361               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9362               throw INTERP_KERNEL::Exception(oss.str().c_str());
9363             }
9364           int nbTupl=(*it4)->getNumberOfTuples();
9365           if(nbTupl<1)
9366             {
9367               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
9368               throw INTERP_KERNEL::Exception(oss.str().c_str());
9369             }
9370           if((*it4)->front()!=0)
9371             {
9372               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
9373               throw INTERP_KERNEL::Exception(oss.str().c_str());
9374             }
9375           retSz+=nbTupl-1;
9376         }
9377       else
9378         {
9379           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
9380           throw INTERP_KERNEL::Exception(oss.str().c_str());
9381         }
9382     }
9383   if(arrs.empty())
9384     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
9385   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9386   ret->alloc(retSz,1);
9387   int *pt=ret->getPointer(); *pt++=0;
9388   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
9389     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
9390   ret->copyStringInfoFrom(*(arrs[0]));
9391   return ret.retn();
9392 }
9393
9394 /*!
9395  * Returns the maximal value and its location within \a this one-dimensional array.
9396  *  \param [out] tupleId - index of the tuple holding the maximal value.
9397  *  \return int - the maximal value among all values of \a this array.
9398  *  \throw If \a this->getNumberOfComponents() != 1
9399  *  \throw If \a this->getNumberOfTuples() < 1
9400  */
9401 int DataArrayInt::getMaxValue(int& tupleId) const
9402 {
9403   checkAllocated();
9404   if(getNumberOfComponents()!=1)
9405     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9406   int nbOfTuples=getNumberOfTuples();
9407   if(nbOfTuples<=0)
9408     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9409   const int *vals=getConstPointer();
9410   const int *loc=std::max_element(vals,vals+nbOfTuples);
9411   tupleId=(int)std::distance(vals,loc);
9412   return *loc;
9413 }
9414
9415 /*!
9416  * Returns the maximal value within \a this array that is allowed to have more than
9417  *  one component.
9418  *  \return int - the maximal value among all values of \a this array.
9419  *  \throw If \a this is not allocated.
9420  */
9421 int DataArrayInt::getMaxValueInArray() const
9422 {
9423   checkAllocated();
9424   const int *loc=std::max_element(begin(),end());
9425   return *loc;
9426 }
9427
9428 /*!
9429  * Returns the minimal value and its location within \a this one-dimensional array.
9430  *  \param [out] tupleId - index of the tuple holding the minimal value.
9431  *  \return int - the minimal value among all values of \a this array.
9432  *  \throw If \a this->getNumberOfComponents() != 1
9433  *  \throw If \a this->getNumberOfTuples() < 1
9434  */
9435 int DataArrayInt::getMinValue(int& tupleId) const
9436 {
9437   checkAllocated();
9438   if(getNumberOfComponents()!=1)
9439     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9440   int nbOfTuples=getNumberOfTuples();
9441   if(nbOfTuples<=0)
9442     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9443   const int *vals=getConstPointer();
9444   const int *loc=std::min_element(vals,vals+nbOfTuples);
9445   tupleId=(int)std::distance(vals,loc);
9446   return *loc;
9447 }
9448
9449 /*!
9450  * Returns the minimal value within \a this array that is allowed to have more than
9451  *  one component.
9452  *  \return int - the minimal value among all values of \a this array.
9453  *  \throw If \a this is not allocated.
9454  */
9455 int DataArrayInt::getMinValueInArray() const
9456 {
9457   checkAllocated();
9458   const int *loc=std::min_element(begin(),end());
9459   return *loc;
9460 }
9461
9462 /*!
9463  * Returns in a single walk in \a this the min value and the max value in \a this.
9464  * \a this is expected to be single component array.
9465  *
9466  * \param [out] minValue - the min value in \a this.
9467  * \param [out] maxValue - the max value in \a this.
9468  *
9469  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
9470  */
9471 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
9472 {
9473   checkAllocated();
9474   if(getNumberOfComponents()!=1)
9475     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
9476   int nbTuples(getNumberOfTuples());
9477   const int *pt(begin());
9478   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
9479   for(int i=0;i<nbTuples;i++,pt++)
9480     {
9481       if(*pt<minValue)
9482         minValue=*pt;
9483       if(*pt>maxValue)
9484         maxValue=*pt;
9485     }
9486 }
9487
9488 /*!
9489  * Converts every value of \a this array to its absolute value.
9490  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
9491  * should be called instead.
9492  *
9493  * \throw If \a this is not allocated.
9494  * \sa DataArrayInt::computeAbs
9495  */
9496 void DataArrayInt::abs()
9497 {
9498   checkAllocated();
9499   int *ptr(getPointer());
9500   std::size_t nbOfElems(getNbOfElems());
9501   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
9502   declareAsNew();
9503 }
9504
9505 /*!
9506  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
9507  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
9508  *
9509  * \return DataArrayInt * - the new instance of DataArrayInt containing the
9510  *         same number of tuples and component as \a this array.
9511  *         The caller is to delete this result array using decrRef() as it is no more
9512  *         needed.
9513  * \throw If \a this is not allocated.
9514  * \sa DataArrayInt::abs
9515  */
9516 DataArrayInt *DataArrayInt::computeAbs() const
9517 {
9518   checkAllocated();
9519   DataArrayInt *newArr(DataArrayInt::New());
9520   int nbOfTuples(getNumberOfTuples());
9521   int nbOfComp(getNumberOfComponents());
9522   newArr->alloc(nbOfTuples,nbOfComp);
9523   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
9524   newArr->copyStringInfoFrom(*this);
9525   return newArr;
9526 }
9527
9528 /*!
9529  * Apply a liner function to a given component of \a this array, so that
9530  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
9531  *  \param [in] a - the first coefficient of the function.
9532  *  \param [in] b - the second coefficient of the function.
9533  *  \param [in] compoId - the index of component to modify.
9534  *  \throw If \a this is not allocated.
9535  */
9536 void DataArrayInt::applyLin(int a, int b, int compoId)
9537 {
9538   checkAllocated();
9539   int *ptr=getPointer()+compoId;
9540   int nbOfComp=getNumberOfComponents();
9541   int nbOfTuple=getNumberOfTuples();
9542   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
9543     *ptr=a*(*ptr)+b;
9544   declareAsNew();
9545 }
9546
9547 /*!
9548  * Apply a liner function to all elements of \a this array, so that
9549  * an element _x_ becomes \f$ a * x + b \f$.
9550  *  \param [in] a - the first coefficient of the function.
9551  *  \param [in] b - the second coefficient of the function.
9552  *  \throw If \a this is not allocated.
9553  */
9554 void DataArrayInt::applyLin(int a, int b)
9555 {
9556   checkAllocated();
9557   int *ptr=getPointer();
9558   std::size_t nbOfElems=getNbOfElems();
9559   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9560     *ptr=a*(*ptr)+b;
9561   declareAsNew();
9562 }
9563
9564 /*!
9565  * Returns a full copy of \a this array except that sign of all elements is reversed.
9566  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
9567  *          same number of tuples and component as \a this array.
9568  *          The caller is to delete this result array using decrRef() as it is no more
9569  *          needed.
9570  *  \throw If \a this is not allocated.
9571  */
9572 DataArrayInt *DataArrayInt::negate() const
9573 {
9574   checkAllocated();
9575   DataArrayInt *newArr=DataArrayInt::New();
9576   int nbOfTuples=getNumberOfTuples();
9577   int nbOfComp=getNumberOfComponents();
9578   newArr->alloc(nbOfTuples,nbOfComp);
9579   const int *cptr=getConstPointer();
9580   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
9581   newArr->copyStringInfoFrom(*this);
9582   return newArr;
9583 }
9584
9585 /*!
9586  * Modify all elements of \a this array, so that
9587  * an element _x_ becomes \f$ numerator / x \f$.
9588  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9589  *           array, all elements processed before detection of the zero element remain
9590  *           modified.
9591  *  \param [in] numerator - the numerator used to modify array elements.
9592  *  \throw If \a this is not allocated.
9593  *  \throw If there is an element equal to 0 in \a this array.
9594  */
9595 void DataArrayInt::applyInv(int numerator)
9596 {
9597   checkAllocated();
9598   int *ptr=getPointer();
9599   std::size_t nbOfElems=getNbOfElems();
9600   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9601     {
9602       if(*ptr!=0)
9603         {
9604           *ptr=numerator/(*ptr);
9605         }
9606       else
9607         {
9608           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9609           oss << " !";
9610           throw INTERP_KERNEL::Exception(oss.str().c_str());
9611         }
9612     }
9613   declareAsNew();
9614 }
9615
9616 /*!
9617  * Modify all elements of \a this array, so that
9618  * an element _x_ becomes \f$ x / val \f$.
9619  *  \param [in] val - the denominator used to modify array elements.
9620  *  \throw If \a this is not allocated.
9621  *  \throw If \a val == 0.
9622  */
9623 void DataArrayInt::applyDivideBy(int val)
9624 {
9625   if(val==0)
9626     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
9627   checkAllocated();
9628   int *ptr=getPointer();
9629   std::size_t nbOfElems=getNbOfElems();
9630   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
9631   declareAsNew();
9632 }
9633
9634 /*!
9635  * Modify all elements of \a this array, so that
9636  * an element _x_ becomes  <em> x % val </em>.
9637  *  \param [in] val - the divisor used to modify array elements.
9638  *  \throw If \a this is not allocated.
9639  *  \throw If \a val <= 0.
9640  */
9641 void DataArrayInt::applyModulus(int val)
9642 {
9643   if(val<=0)
9644     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
9645   checkAllocated();
9646   int *ptr=getPointer();
9647   std::size_t nbOfElems=getNbOfElems();
9648   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
9649   declareAsNew();
9650 }
9651
9652 /*!
9653  * This method works only on data array with one component.
9654  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9655  * this[*id] in [\b vmin,\b vmax)
9656  * 
9657  * \param [in] vmin begin of range. This value is included in range (included).
9658  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9659  * \return a newly allocated data array that the caller should deal with.
9660  *
9661  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
9662  */
9663 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
9664 {
9665   checkAllocated();
9666   if(getNumberOfComponents()!=1)
9667     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsInRange : this must have exactly one component !");
9668   const int *cptr(begin());
9669   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9670   int nbOfTuples(getNumberOfTuples());
9671   for(int i=0;i<nbOfTuples;i++,cptr++)
9672     if(*cptr>=vmin && *cptr<vmax)
9673       ret->pushBackSilent(i);
9674   return ret.retn();
9675 }
9676
9677 /*!
9678  * This method works only on data array with one component.
9679  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9680  * this[*id] \b not in [\b vmin,\b vmax)
9681  * 
9682  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
9683  * \param [in] vmax end of range. This value is included in range (included).
9684  * \return a newly allocated data array that the caller should deal with.
9685  * 
9686  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
9687  */
9688 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
9689 {
9690   checkAllocated();
9691   if(getNumberOfComponents()!=1)
9692     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotInRange : this must have exactly one component !");
9693   const int *cptr(getConstPointer());
9694   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9695   int nbOfTuples(getNumberOfTuples());
9696   for(int i=0;i<nbOfTuples;i++,cptr++)
9697     if(*cptr<vmin || *cptr>=vmax)
9698       ret->pushBackSilent(i);
9699   return ret.retn();
9700 }
9701
9702 /*!
9703  * 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.
9704  *
9705  * \return a newly allocated data array that the caller should deal with.
9706  * \sa DataArrayInt::findIdsInRange
9707  */
9708 DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
9709 {
9710   checkAllocated();
9711   if(getNumberOfComponents()!=1)
9712     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsStricltyNegative : this must have exactly one component !");
9713   const int *cptr(getConstPointer());
9714   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9715   int nbOfTuples(getNumberOfTuples());
9716   for(int i=0;i<nbOfTuples;i++,cptr++)
9717     if(*cptr<0)
9718       ret->pushBackSilent(i);
9719   return ret.retn();
9720 }
9721
9722 /*!
9723  * This method works only on data array with one component.
9724  * 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.
9725  * 
9726  * \param [in] vmin begin of range. This value is included in range (included).
9727  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9728  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
9729 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
9730 {
9731   checkAllocated();
9732   if(getNumberOfComponents()!=1)
9733     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9734   int nbOfTuples=getNumberOfTuples();
9735   bool ret=true;
9736   const int *cptr=getConstPointer();
9737   for(int i=0;i<nbOfTuples;i++,cptr++)
9738     {
9739       if(*cptr>=vmin && *cptr<vmax)
9740         { ret=ret && *cptr==i; }
9741       else
9742         {
9743           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9744           throw INTERP_KERNEL::Exception(oss.str().c_str());
9745         }
9746     }
9747   return ret;
9748 }
9749
9750 /*!
9751  * Modify all elements of \a this array, so that
9752  * an element _x_ becomes <em> val % x </em>.
9753  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9754  *           array, all elements processed before detection of the zero element remain
9755  *           modified.
9756  *  \param [in] val - the divident used to modify array elements.
9757  *  \throw If \a this is not allocated.
9758  *  \throw If there is an element equal to or less than 0 in \a this array.
9759  */
9760 void DataArrayInt::applyRModulus(int val)
9761 {
9762   checkAllocated();
9763   int *ptr=getPointer();
9764   std::size_t nbOfElems=getNbOfElems();
9765   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9766     {
9767       if(*ptr>0)
9768         {
9769           *ptr=val%(*ptr);
9770         }
9771       else
9772         {
9773           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9774           oss << " !";
9775           throw INTERP_KERNEL::Exception(oss.str().c_str());
9776         }
9777     }
9778   declareAsNew();
9779 }
9780
9781 /*!
9782  * Modify all elements of \a this array, so that
9783  * an element _x_ becomes <em> val ^ x </em>.
9784  *  \param [in] val - the value used to apply pow on all array elements.
9785  *  \throw If \a this is not allocated.
9786  *  \throw If \a val < 0.
9787  */
9788 void DataArrayInt::applyPow(int val)
9789 {
9790   checkAllocated();
9791   if(val<0)
9792     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9793   int *ptr=getPointer();
9794   std::size_t nbOfElems=getNbOfElems();
9795   if(val==0)
9796     {
9797       std::fill(ptr,ptr+nbOfElems,1);
9798       return ;
9799     }
9800   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9801     {
9802       int tmp=1;
9803       for(int j=0;j<val;j++)
9804         tmp*=*ptr;
9805       *ptr=tmp;
9806     }
9807   declareAsNew();
9808 }
9809
9810 /*!
9811  * Modify all elements of \a this array, so that
9812  * an element _x_ becomes \f$ val ^ x \f$.
9813  *  \param [in] val - the value used to apply pow on all array elements.
9814  *  \throw If \a this is not allocated.
9815  *  \throw If there is an element < 0 in \a this array.
9816  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9817  *           array, all elements processed before detection of the zero element remain
9818  *           modified.
9819  */
9820 void DataArrayInt::applyRPow(int val)
9821 {
9822   checkAllocated();
9823   int *ptr=getPointer();
9824   std::size_t nbOfElems=getNbOfElems();
9825   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9826     {
9827       if(*ptr>=0)
9828         {
9829           int tmp=1;
9830           for(int j=0;j<*ptr;j++)
9831             tmp*=val;
9832           *ptr=tmp;
9833         }
9834       else
9835         {
9836           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9837           oss << " !";
9838           throw INTERP_KERNEL::Exception(oss.str().c_str());
9839         }
9840     }
9841   declareAsNew();
9842 }
9843
9844 /*!
9845  * Returns a new DataArrayInt by aggregating two 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] a1 - an array to include in the result array.
9852  *  \param [in] a2 - another array to include in the result array.
9853  *  \return DataArrayInt * - the new instance of DataArrayInt.
9854  *          The caller is to delete this result array using decrRef() as it is no more
9855  *          needed.
9856  *  \throw If both \a a1 and \a a2 are NULL.
9857  *  \throw If any given array is not allocated.
9858  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9859  */
9860 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9861 {
9862   std::vector<const DataArrayInt *> arr(2);
9863   arr[0]=a1; arr[1]=a2;
9864   return Meld(arr);
9865 }
9866
9867 /*!
9868  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9869  * of components in the result array is a sum of the number of components of given arrays
9870  * and (2) the number of tuples in the result array is same as that of each of given
9871  * arrays. In other words the i-th tuple of result array includes all components of
9872  * i-th tuples of all given arrays.
9873  * Number of tuples in the given arrays must be  the same.
9874  *  \param [in] arr - a sequence of arrays to include in the result array.
9875  *  \return DataArrayInt * - the new instance of DataArrayInt.
9876  *          The caller is to delete this result array using decrRef() as it is no more
9877  *          needed.
9878  *  \throw If all arrays within \a arr are NULL.
9879  *  \throw If any given array is not allocated.
9880  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9881  */
9882 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9883 {
9884   std::vector<const DataArrayInt *> a;
9885   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9886     if(*it4)
9887       a.push_back(*it4);
9888   if(a.empty())
9889     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9890   std::vector<const DataArrayInt *>::const_iterator it;
9891   for(it=a.begin();it!=a.end();it++)
9892     (*it)->checkAllocated();
9893   it=a.begin();
9894   int nbOfTuples=(*it)->getNumberOfTuples();
9895   std::vector<int> nbc(a.size());
9896   std::vector<const int *> pts(a.size());
9897   nbc[0]=(*it)->getNumberOfComponents();
9898   pts[0]=(*it++)->getConstPointer();
9899   for(int i=1;it!=a.end();it++,i++)
9900     {
9901       if(nbOfTuples!=(*it)->getNumberOfTuples())
9902         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9903       nbc[i]=(*it)->getNumberOfComponents();
9904       pts[i]=(*it)->getConstPointer();
9905     }
9906   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9907   DataArrayInt *ret=DataArrayInt::New();
9908   ret->alloc(nbOfTuples,totalNbOfComp);
9909   int *retPtr=ret->getPointer();
9910   for(int i=0;i<nbOfTuples;i++)
9911     for(int j=0;j<(int)a.size();j++)
9912       {
9913         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9914         pts[j]+=nbc[j];
9915       }
9916   int k=0;
9917   for(int i=0;i<(int)a.size();i++)
9918     for(int j=0;j<nbc[i];j++,k++)
9919       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
9920   return ret;
9921 }
9922
9923 /*!
9924  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9925  * The i-th item of the result array is an ID of a set of elements belonging to a
9926  * unique set of groups, which the i-th element is a part of. This set of elements
9927  * belonging to a unique set of groups is called \a family, so the result array contains
9928  * IDs of families each element belongs to.
9929  *
9930  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9931  * then there are 3 families:
9932  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9933  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9934  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9935  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9936  * stands for the element #3 which is in none of groups.
9937  *
9938  *  \param [in] groups - sequence of groups of element IDs.
9939  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9940  *         in \a groups.
9941  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9942  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9943  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9944  *         delete this array using decrRef() as it is no more needed.
9945  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9946  */
9947 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9948 {
9949   std::vector<const DataArrayInt *> groups2;
9950   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9951     if(*it4)
9952       groups2.push_back(*it4);
9953   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9954   ret->alloc(newNb,1);
9955   int *retPtr=ret->getPointer();
9956   std::fill(retPtr,retPtr+newNb,0);
9957   int fid=1;
9958   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9959     {
9960       const int *ptr=(*iter)->getConstPointer();
9961       std::size_t nbOfElem=(*iter)->getNbOfElems();
9962       int sfid=fid;
9963       for(int j=0;j<sfid;j++)
9964         {
9965           bool found=false;
9966           for(std::size_t i=0;i<nbOfElem;i++)
9967             {
9968               if(ptr[i]>=0 && ptr[i]<newNb)
9969                 {
9970                   if(retPtr[ptr[i]]==j)
9971                     {
9972                       retPtr[ptr[i]]=fid;
9973                       found=true;
9974                     }
9975                 }
9976               else
9977                 {
9978                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9979                   oss << ") !";
9980                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9981                 }
9982             }
9983           if(found)
9984             fid++;
9985         }
9986     }
9987   fidsOfGroups.clear();
9988   fidsOfGroups.resize(groups2.size());
9989   int grId=0;
9990   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9991     {
9992       std::set<int> tmp;
9993       const int *ptr=(*iter)->getConstPointer();
9994       std::size_t nbOfElem=(*iter)->getNbOfElems();
9995       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9996         tmp.insert(retPtr[*p]);
9997       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9998     }
9999   return ret.retn();
10000 }
10001
10002 /*!
10003  * Returns a new DataArrayInt which contains all elements of given one-dimensional
10004  * arrays. The result array does not contain any duplicates and its values
10005  * are sorted in ascending order.
10006  *  \param [in] arr - sequence of DataArrayInt's to unite.
10007  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10008  *         array using decrRef() as it is no more needed.
10009  *  \throw If any \a arr[i] is not allocated.
10010  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
10011  */
10012 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
10013 {
10014   std::vector<const DataArrayInt *> a;
10015   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
10016     if(*it4)
10017       a.push_back(*it4);
10018   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
10019     {
10020       (*it)->checkAllocated();
10021       if((*it)->getNumberOfComponents()!=1)
10022         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
10023     }
10024   //
10025   std::set<int> r;
10026   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
10027     {
10028       const int *pt=(*it)->getConstPointer();
10029       int nbOfTuples=(*it)->getNumberOfTuples();
10030       r.insert(pt,pt+nbOfTuples);
10031     }
10032   DataArrayInt *ret=DataArrayInt::New();
10033   ret->alloc((int)r.size(),1);
10034   std::copy(r.begin(),r.end(),ret->getPointer());
10035   return ret;
10036 }
10037
10038 /*!
10039  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
10040  * arrays. The result array does not contain any duplicates and its values
10041  * are sorted in ascending order.
10042  *  \param [in] arr - sequence of DataArrayInt's to intersect.
10043  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10044  *         array using decrRef() as it is no more needed.
10045  *  \throw If any \a arr[i] is not allocated.
10046  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
10047  */
10048 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
10049 {
10050   std::vector<const DataArrayInt *> a;
10051   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
10052     if(*it4)
10053       a.push_back(*it4);
10054   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
10055     {
10056       (*it)->checkAllocated();
10057       if((*it)->getNumberOfComponents()!=1)
10058         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
10059     }
10060   //
10061   std::set<int> r;
10062   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
10063     {
10064       const int *pt=(*it)->getConstPointer();
10065       int nbOfTuples=(*it)->getNumberOfTuples();
10066       std::set<int> s1(pt,pt+nbOfTuples);
10067       if(it!=a.begin())
10068         {
10069           std::set<int> r2;
10070           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
10071           r=r2;
10072         }
10073       else
10074         r=s1;
10075     }
10076   DataArrayInt *ret(DataArrayInt::New());
10077   ret->alloc((int)r.size(),1);
10078   std::copy(r.begin(),r.end(),ret->getPointer());
10079   return ret;
10080 }
10081
10082 /// @cond INTERNAL
10083 namespace MEDCouplingImpl
10084 {
10085   class OpSwitchedOn
10086   {
10087   public:
10088     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
10089     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
10090   private:
10091     int *_pt;
10092     int _cnt;
10093   };
10094
10095   class OpSwitchedOff
10096   {
10097   public:
10098     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
10099     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
10100   private:
10101     int *_pt;
10102     int _cnt;
10103   };
10104 }
10105 /// @endcond
10106
10107 /*!
10108  * This method returns the list of ids in ascending mode so that v[id]==true.
10109  */
10110 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
10111 {
10112   int sz((int)std::count(v.begin(),v.end(),true));
10113   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10114   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
10115   return ret.retn();
10116 }
10117
10118 /*!
10119  * This method returns the list of ids in ascending mode so that v[id]==false.
10120  */
10121 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
10122 {
10123   int sz((int)std::count(v.begin(),v.end(),false));
10124   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10125   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
10126   return ret.retn();
10127 }
10128
10129 /*!
10130  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
10131  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
10132  *
10133  * \param [in] v the input data structure to be translate into skyline format.
10134  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
10135  * \param [out] dataIndex the second element of the skyline format.
10136  */
10137 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
10138 {
10139   int sz((int)v.size());
10140   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
10141   ret1->alloc(sz+1,1);
10142   int *pt(ret1->getPointer()); *pt=0;
10143   for(int i=0;i<sz;i++,pt++)
10144     pt[1]=pt[0]+(int)v[i].size();
10145   ret0->alloc(ret1->back(),1);
10146   pt=ret0->getPointer();
10147   for(int i=0;i<sz;i++)
10148     pt=std::copy(v[i].begin(),v[i].end(),pt);
10149   data=ret0.retn(); dataIndex=ret1.retn();
10150 }
10151
10152 /*!
10153  * Returns a new DataArrayInt which contains a complement of elements of \a this
10154  * one-dimensional array. I.e. the result array contains all elements from the range [0,
10155  * \a nbOfElement) not present in \a this array.
10156  *  \param [in] nbOfElement - maximal size of the result array.
10157  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10158  *         array using decrRef() as it is no more needed.
10159  *  \throw If \a this is not allocated.
10160  *  \throw If \a this->getNumberOfComponents() != 1.
10161  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
10162  *         nbOfElement ).
10163  */
10164 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
10165 {
10166   checkAllocated();
10167   if(getNumberOfComponents()!=1)
10168     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
10169   std::vector<bool> tmp(nbOfElement);
10170   const int *pt=getConstPointer();
10171   int nbOfTuples=getNumberOfTuples();
10172   for(const int *w=pt;w!=pt+nbOfTuples;w++)
10173     if(*w>=0 && *w<nbOfElement)
10174       tmp[*w]=true;
10175     else
10176       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
10177   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
10178   DataArrayInt *ret=DataArrayInt::New();
10179   ret->alloc(nbOfRetVal,1);
10180   int j=0;
10181   int *retPtr=ret->getPointer();
10182   for(int i=0;i<nbOfElement;i++)
10183     if(!tmp[i])
10184       retPtr[j++]=i;
10185   return ret;
10186 }
10187
10188 /*!
10189  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
10190  * from an \a other one-dimensional array.
10191  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
10192  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
10193  *         caller is to delete this array using decrRef() as it is no more needed.
10194  *  \throw If \a other is NULL.
10195  *  \throw If \a other is not allocated.
10196  *  \throw If \a other->getNumberOfComponents() != 1.
10197  *  \throw If \a this is not allocated.
10198  *  \throw If \a this->getNumberOfComponents() != 1.
10199  *  \sa DataArrayInt::buildSubstractionOptimized()
10200  */
10201 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
10202 {
10203   if(!other)
10204     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
10205   checkAllocated();
10206   other->checkAllocated();
10207   if(getNumberOfComponents()!=1)
10208     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
10209   if(other->getNumberOfComponents()!=1)
10210     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
10211   const int *pt=getConstPointer();
10212   int nbOfTuples=getNumberOfTuples();
10213   std::set<int> s1(pt,pt+nbOfTuples);
10214   pt=other->getConstPointer();
10215   nbOfTuples=other->getNumberOfTuples();
10216   std::set<int> s2(pt,pt+nbOfTuples);
10217   std::vector<int> r;
10218   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
10219   DataArrayInt *ret=DataArrayInt::New();
10220   ret->alloc((int)r.size(),1);
10221   std::copy(r.begin(),r.end(),ret->getPointer());
10222   return ret;
10223 }
10224
10225 /*!
10226  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
10227  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
10228  * 
10229  * \param [in] other an array with one component and expected to be sorted ascendingly.
10230  * \ret list of ids in \a this but not in \a other.
10231  * \sa DataArrayInt::buildSubstraction
10232  */
10233 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
10234 {
10235   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
10236   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
10237   checkAllocated(); other->checkAllocated();
10238   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
10239   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
10240   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
10241   const int *work1(pt1Bg),*work2(pt2Bg);
10242   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
10243   for(;work1!=pt1End;work1++)
10244     {
10245       if(work2!=pt2End && *work1==*work2)
10246         work2++;
10247       else
10248         ret->pushBackSilent(*work1);
10249     }
10250   return ret.retn();
10251 }
10252
10253
10254 /*!
10255  * Returns a new DataArrayInt which contains all elements of \a this and a given
10256  * one-dimensional arrays. The result array does not contain any duplicates
10257  * and its values are sorted in ascending order.
10258  *  \param [in] other - an array to unite with \a this one.
10259  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10260  *         array using decrRef() as it is no more needed.
10261  *  \throw If \a this or \a other is not allocated.
10262  *  \throw If \a this->getNumberOfComponents() != 1.
10263  *  \throw If \a other->getNumberOfComponents() != 1.
10264  */
10265 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
10266 {
10267   std::vector<const DataArrayInt *>arrs(2);
10268   arrs[0]=this; arrs[1]=other;
10269   return BuildUnion(arrs);
10270 }
10271
10272
10273 /*!
10274  * Returns a new DataArrayInt which contains elements present in both \a this and a given
10275  * one-dimensional arrays. The result array does not contain any duplicates
10276  * and its values are sorted in ascending order.
10277  *  \param [in] other - an array to intersect with \a this one.
10278  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10279  *         array using decrRef() as it is no more needed.
10280  *  \throw If \a this or \a other is not allocated.
10281  *  \throw If \a this->getNumberOfComponents() != 1.
10282  *  \throw If \a other->getNumberOfComponents() != 1.
10283  */
10284 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
10285 {
10286   std::vector<const DataArrayInt *>arrs(2);
10287   arrs[0]=this; arrs[1]=other;
10288   return BuildIntersection(arrs);
10289 }
10290
10291 /*!
10292  * This method can be applied on allocated with one component DataArrayInt instance.
10293  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
10294  * 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]
10295  * 
10296  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
10297  * \throw if \a this is not allocated or if \a this has not exactly one component.
10298  * \sa DataArrayInt::buildUniqueNotSorted
10299  */
10300 DataArrayInt *DataArrayInt::buildUnique() const
10301 {
10302   checkAllocated();
10303   if(getNumberOfComponents()!=1)
10304     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
10305   int nbOfTuples=getNumberOfTuples();
10306   MCAuto<DataArrayInt> tmp=deepCopy();
10307   int *data=tmp->getPointer();
10308   int *last=std::unique(data,data+nbOfTuples);
10309   MCAuto<DataArrayInt> ret=DataArrayInt::New();
10310   ret->alloc(std::distance(data,last),1);
10311   std::copy(data,last,ret->getPointer());
10312   return ret.retn();
10313 }
10314
10315 /*!
10316  * This method can be applied on allocated with one component DataArrayInt instance.
10317  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
10318  *
10319  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
10320  *
10321  * \throw if \a this is not allocated or if \a this has not exactly one component.
10322  *
10323  * \sa DataArrayInt::buildUnique
10324  */
10325 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
10326 {
10327   checkAllocated();
10328     if(getNumberOfComponents()!=1)
10329       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
10330   int minVal,maxVal;
10331   getMinMaxValues(minVal,maxVal);
10332   std::vector<bool> b(maxVal-minVal+1,false);
10333   const int *ptBg(begin()),*endBg(end());
10334   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
10335   for(const int *pt=ptBg;pt!=endBg;pt++)
10336     {
10337       if(!b[*pt-minVal])
10338         {
10339           ret->pushBackSilent(*pt);
10340           b[*pt-minVal]=true;
10341         }
10342     }
10343   ret->copyStringInfoFrom(*this);
10344   return ret.retn();
10345 }
10346
10347 /*!
10348  * Returns a new DataArrayInt which contains size of every of groups described by \a this
10349  * "index" array. Such "index" array is returned for example by 
10350  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
10351  * "MEDCouplingUMesh::buildDescendingConnectivity" and
10352  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
10353  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
10354  * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
10355  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
10356  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
10357  *          The caller is to delete this array using decrRef() as it is no more needed. 
10358  *  \throw If \a this is not allocated.
10359  *  \throw If \a this->getNumberOfComponents() != 1.
10360  *  \throw If \a this->getNumberOfTuples() < 2.
10361  *
10362  *  \b Example: <br> 
10363  *         - this contains [1,3,6,7,7,9,15]
10364  *         - result array contains [2,3,1,0,2,6],
10365  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
10366  *
10367  * \sa DataArrayInt::computeOffsetsFull
10368  */
10369 DataArrayInt *DataArrayInt::deltaShiftIndex() const
10370 {
10371   checkAllocated();
10372   if(getNumberOfComponents()!=1)
10373     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
10374   int nbOfTuples=getNumberOfTuples();
10375   if(nbOfTuples<2)
10376     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
10377   const int *ptr=getConstPointer();
10378   DataArrayInt *ret=DataArrayInt::New();
10379   ret->alloc(nbOfTuples-1,1);
10380   int *out=ret->getPointer();
10381   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
10382   return ret;
10383 }
10384
10385 /*!
10386  * Modifies \a this one-dimensional array so that value of each element \a x
10387  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10388  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
10389  * and components remains the same.<br>
10390  * This method is useful for allToAllV in MPI with contiguous policy. This method
10391  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
10392  * this one.
10393  *  \throw If \a this is not allocated.
10394  *  \throw If \a this->getNumberOfComponents() != 1.
10395  *
10396  *  \b Example: <br>
10397  *          - Before \a this contains [3,5,1,2,0,8]
10398  *          - After \a this contains  [0,3,8,9,11,11]<br>
10399  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
10400  *          array is retained and thus there is no space to store the last element.
10401  */
10402 void DataArrayInt::computeOffsets()
10403 {
10404   checkAllocated();
10405   if(getNumberOfComponents()!=1)
10406     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
10407   int nbOfTuples=getNumberOfTuples();
10408   if(nbOfTuples==0)
10409     return ;
10410   int *work=getPointer();
10411   int tmp=work[0];
10412   work[0]=0;
10413   for(int i=1;i<nbOfTuples;i++)
10414     {
10415       int tmp2=work[i];
10416       work[i]=work[i-1]+tmp;
10417       tmp=tmp2;
10418     }
10419   declareAsNew();
10420 }
10421
10422
10423 /*!
10424  * Modifies \a this one-dimensional array so that value of each element \a x
10425  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
10426  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
10427  * components remains the same and number of tuples is inceamented by one.<br>
10428  * This method is useful for allToAllV in MPI with contiguous policy. This method
10429  * differs from computeOffsets() in that the number of tuples is changed by this one.
10430  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
10431  *  \throw If \a this is not allocated.
10432  *  \throw If \a this->getNumberOfComponents() != 1.
10433  *
10434  *  \b Example: <br>
10435  *          - Before \a this contains [3,5,1,2,0,8]
10436  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
10437  * \sa DataArrayInt::deltaShiftIndex
10438  */
10439 void DataArrayInt::computeOffsetsFull()
10440 {
10441   checkAllocated();
10442   if(getNumberOfComponents()!=1)
10443     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
10444   int nbOfTuples=getNumberOfTuples();
10445   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
10446   const int *work=getConstPointer();
10447   ret[0]=0;
10448   for(int i=0;i<nbOfTuples;i++)
10449     ret[i+1]=work[i]+ret[i];
10450   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
10451   declareAsNew();
10452 }
10453
10454 /*!
10455  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
10456  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
10457  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
10458  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
10459  * filling completely one of the ranges in \a this.
10460  *
10461  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
10462  * \param [out] rangeIdsFetched the range ids fetched
10463  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
10464  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
10465  *
10466  * \sa DataArrayInt::computeOffsetsFull
10467  *
10468  *  \b Example: <br>
10469  *          - \a this : [0,3,7,9,15,18]
10470  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
10471  *          - \a rangeIdsFetched result array: [0,2,4]
10472  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
10473  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
10474  * <br>
10475  */
10476 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
10477 {
10478   if(!listOfIds)
10479     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
10480   listOfIds->checkAllocated(); checkAllocated();
10481   if(listOfIds->getNumberOfComponents()!=1)
10482     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
10483   if(getNumberOfComponents()!=1)
10484     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
10485   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
10486   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
10487   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
10488   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
10489   while(tupPtr!=tupEnd && offPtr!=offEnd)
10490     {
10491       if(*tupPtr==*offPtr)
10492         {
10493           int i=offPtr[0];
10494           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
10495           if(i==offPtr[1])
10496             {
10497               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
10498               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
10499               offPtr++;
10500             }
10501         }
10502       else
10503         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
10504     }
10505   rangeIdsFetched=ret0.retn();
10506   idsInInputListThatFetch=ret1.retn();
10507 }
10508
10509 /*!
10510  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
10511  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10512  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10513  * beginning within the "iota" array. And \a this is a one-dimensional array
10514  * considered as a selector of groups described by \a offsets to include into the result array.
10515  *  \throw If \a offsets is NULL.
10516  *  \throw If \a offsets is not allocated.
10517  *  \throw If \a offsets->getNumberOfComponents() != 1.
10518  *  \throw If \a offsets is not monotonically increasing.
10519  *  \throw If \a this is not allocated.
10520  *  \throw If \a this->getNumberOfComponents() != 1.
10521  *  \throw If any element of \a this is not a valid index for \a offsets array.
10522  *
10523  *  \b Example: <br>
10524  *          - \a this: [0,2,3]
10525  *          - \a offsets: [0,3,6,10,14,20]
10526  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
10527  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
10528  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
10529  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
10530  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
10531  */
10532 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
10533 {
10534   if(!offsets)
10535     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
10536   checkAllocated();
10537   if(getNumberOfComponents()!=1)
10538     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
10539   offsets->checkAllocated();
10540   if(offsets->getNumberOfComponents()!=1)
10541     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
10542   int othNbTuples=offsets->getNumberOfTuples()-1;
10543   int nbOfTuples=getNumberOfTuples();
10544   int retNbOftuples=0;
10545   const int *work=getConstPointer();
10546   const int *offPtr=offsets->getConstPointer();
10547   for(int i=0;i<nbOfTuples;i++)
10548     {
10549       int val=work[i];
10550       if(val>=0 && val<othNbTuples)
10551         {
10552           int delta=offPtr[val+1]-offPtr[val];
10553           if(delta>=0)
10554             retNbOftuples+=delta;
10555           else
10556             {
10557               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
10558               throw INTERP_KERNEL::Exception(oss.str().c_str());
10559             }
10560         }
10561       else
10562         {
10563           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
10564           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
10565           throw INTERP_KERNEL::Exception(oss.str().c_str());
10566         }
10567     }
10568   MCAuto<DataArrayInt> ret=DataArrayInt::New();
10569   ret->alloc(retNbOftuples,1);
10570   int *retPtr=ret->getPointer();
10571   for(int i=0;i<nbOfTuples;i++)
10572     {
10573       int val=work[i];
10574       int start=offPtr[val];
10575       int off=offPtr[val+1]-start;
10576       for(int j=0;j<off;j++,retPtr++)
10577         *retPtr=start+j;
10578     }
10579   return ret.retn();
10580 }
10581
10582 /*!
10583  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
10584  * scaled array (monotonically increasing).
10585 from that of \a this and \a
10586  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10587  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10588  * beginning within the "iota" array. And \a this is a one-dimensional array
10589  * considered as a selector of groups described by \a offsets to include into the result array.
10590  *  \throw If \a  is NULL.
10591  *  \throw If \a this is not allocated.
10592  *  \throw If \a this->getNumberOfComponents() != 1.
10593  *  \throw If \a this->getNumberOfTuples() == 0.
10594  *  \throw If \a this is not monotonically increasing.
10595  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
10596  *
10597  *  \b Example: <br>
10598  *          - \a bg , \a stop and \a step : (0,5,2)
10599  *          - \a this: [0,3,6,10,14,20]
10600  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
10601  */
10602 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
10603 {
10604   if(!isAllocated())
10605     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
10606   if(getNumberOfComponents()!=1)
10607     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
10608   int nbOfTuples(getNumberOfTuples());
10609   if(nbOfTuples==0)
10610     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
10611   const int *ids(begin());
10612   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
10613   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10614     {
10615       if(pos>=0 && pos<nbOfTuples-1)
10616         {
10617           int delta(ids[pos+1]-ids[pos]);
10618           sz+=delta;
10619           if(delta<0)
10620             {
10621               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
10622               throw INTERP_KERNEL::Exception(oss.str().c_str());
10623             }          
10624         }
10625       else
10626         {
10627           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
10628           throw INTERP_KERNEL::Exception(oss.str().c_str());
10629         }
10630     }
10631   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10632   int *retPtr(ret->getPointer());
10633   pos=bg;
10634   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10635     {
10636       int delta(ids[pos+1]-ids[pos]);
10637       for(int j=0;j<delta;j++,retPtr++)
10638         *retPtr=pos;
10639     }
10640   return ret.retn();
10641 }
10642
10643 /*!
10644  * 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.
10645  * 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
10646  * in tuple **i** of returned DataArrayInt.
10647  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
10648  *
10649  * 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)]
10650  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
10651  * 
10652  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10653  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10654  * \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
10655  *        is thrown if no ranges in \a ranges contains value in \a this.
10656  * 
10657  * \sa DataArrayInt::findIdInRangeForEachTuple
10658  */
10659 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
10660 {
10661   if(!ranges)
10662     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
10663   if(ranges->getNumberOfComponents()!=2)
10664     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
10665   checkAllocated();
10666   if(getNumberOfComponents()!=1)
10667     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
10668   int nbTuples=getNumberOfTuples();
10669   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10670   int nbOfRanges=ranges->getNumberOfTuples();
10671   const int *rangesPtr=ranges->getConstPointer();
10672   int *retPtr=ret->getPointer();
10673   const int *inPtr=getConstPointer();
10674   for(int i=0;i<nbTuples;i++,retPtr++)
10675     {
10676       int val=inPtr[i];
10677       bool found=false;
10678       for(int j=0;j<nbOfRanges && !found;j++)
10679         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10680           { *retPtr=j; found=true; }
10681       if(found)
10682         continue;
10683       else
10684         {
10685           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
10686           throw INTERP_KERNEL::Exception(oss.str().c_str());
10687         }
10688     }
10689   return ret.retn();
10690 }
10691
10692 /*!
10693  * 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.
10694  * 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
10695  * in tuple **i** of returned DataArrayInt.
10696  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
10697  *
10698  * 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)]
10699  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
10700  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
10701  * 
10702  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10703  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10704  * \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
10705  *        is thrown if no ranges in \a ranges contains value in \a this.
10706  * \sa DataArrayInt::findRangeIdForEachTuple
10707  */
10708 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
10709 {
10710   if(!ranges)
10711     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
10712   if(ranges->getNumberOfComponents()!=2)
10713     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
10714   checkAllocated();
10715   if(getNumberOfComponents()!=1)
10716     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
10717   int nbTuples=getNumberOfTuples();
10718   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10719   int nbOfRanges=ranges->getNumberOfTuples();
10720   const int *rangesPtr=ranges->getConstPointer();
10721   int *retPtr=ret->getPointer();
10722   const int *inPtr=getConstPointer();
10723   for(int i=0;i<nbTuples;i++,retPtr++)
10724     {
10725       int val=inPtr[i];
10726       bool found=false;
10727       for(int j=0;j<nbOfRanges && !found;j++)
10728         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10729           { *retPtr=val-rangesPtr[2*j]; found=true; }
10730       if(found)
10731         continue;
10732       else
10733         {
10734           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
10735           throw INTERP_KERNEL::Exception(oss.str().c_str());
10736         }
10737     }
10738   return ret.retn();
10739 }
10740
10741 /*!
10742  * \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).
10743  * 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).
10744  * 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 !
10745  * If this method has correctly worked, \a this will be able to be considered as a linked list.
10746  * This method does nothing if number of tuples is lower of equal to 1.
10747  *
10748  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
10749  *
10750  * \sa MEDCouplingUMesh::orderConsecutiveCells1D
10751  */
10752 void DataArrayInt::sortEachPairToMakeALinkedList()
10753 {
10754   checkAllocated();
10755   if(getNumberOfComponents()!=2)
10756     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
10757   int nbOfTuples(getNumberOfTuples());
10758   if(nbOfTuples<=1)
10759     return ;
10760   int *conn(getPointer());
10761   for(int i=1;i<nbOfTuples;i++,conn+=2)
10762     {
10763       if(i>1)
10764         {
10765           if(conn[2]==conn[3])
10766             {
10767               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
10768               throw INTERP_KERNEL::Exception(oss.str().c_str());
10769             }
10770           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
10771             std::swap(conn[2],conn[3]);
10772           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
10773           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
10774             {
10775               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
10776               throw INTERP_KERNEL::Exception(oss.str().c_str());
10777             }
10778         }
10779       else
10780         {
10781           if(conn[0]==conn[1] || conn[2]==conn[3])
10782             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
10783           int tmp[4];
10784           std::set<int> s;
10785           s.insert(conn,conn+4);
10786           if(s.size()!=3)
10787             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
10788           if(std::count(conn,conn+4,conn[0])==2)
10789             {
10790               tmp[0]=conn[1];
10791               tmp[1]=conn[0];
10792               tmp[2]=conn[0];
10793               if(conn[2]==conn[0])
10794                 { tmp[3]=conn[3]; }
10795               else
10796                 { tmp[3]=conn[2];}
10797               std::copy(tmp,tmp+4,conn);
10798             }
10799           else
10800             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
10801               if(conn[1]==conn[3])
10802                 std::swap(conn[2],conn[3]);
10803             }
10804         }
10805     }
10806 }
10807
10808 /*!
10809  * 
10810  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
10811  *             \a nbTimes  should be at least equal to 1.
10812  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
10813  * \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.
10814  */
10815 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
10816 {
10817   checkAllocated();
10818   if(getNumberOfComponents()!=1)
10819     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
10820   if(nbTimes<1)
10821     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
10822   int nbTuples=getNumberOfTuples();
10823   const int *inPtr=getConstPointer();
10824   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
10825   int *retPtr=ret->getPointer();
10826   for(int i=0;i<nbTuples;i++,inPtr++)
10827     {
10828       int val=*inPtr;
10829       for(int j=0;j<nbTimes;j++,retPtr++)
10830         *retPtr=val;
10831     }
10832   ret->copyStringInfoFrom(*this);
10833   return ret.retn();
10834 }
10835
10836 /*!
10837  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
10838  * But the number of components can be different from one.
10839  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
10840  */
10841 DataArrayInt *DataArrayInt::getDifferentValues() const
10842 {
10843   checkAllocated();
10844   std::set<int> ret;
10845   ret.insert(begin(),end());
10846   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
10847   std::copy(ret.begin(),ret.end(),ret2->getPointer());
10848   return ret2.retn();
10849 }
10850
10851 /*!
10852  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
10853  * them it tells which tuple id have this id.
10854  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
10855  * This method returns two arrays having same size.
10856  * 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.
10857  * 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]]
10858  */
10859 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10860 {
10861   checkAllocated();
10862   if(getNumberOfComponents()!=1)
10863     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10864   int id=0;
10865   std::map<int,int> m,m2,m3;
10866   for(const int *w=begin();w!=end();w++)
10867     m[*w]++;
10868   differentIds.resize(m.size());
10869   std::vector<DataArrayInt *> ret(m.size());
10870   std::vector<int *> retPtr(m.size());
10871   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10872     {
10873       m2[(*it).first]=id;
10874       ret[id]=DataArrayInt::New();
10875       ret[id]->alloc((*it).second,1);
10876       retPtr[id]=ret[id]->getPointer();
10877       differentIds[id]=(*it).first;
10878     }
10879   id=0;
10880   for(const int *w=begin();w!=end();w++,id++)
10881     {
10882       retPtr[m2[*w]][m3[*w]++]=id;
10883     }
10884   return ret;
10885 }
10886
10887 /*!
10888  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10889  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10890  *
10891  * \param [in] nbOfSlices - number of slices expected.
10892  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10893  * 
10894  * \sa DataArray::GetSlice
10895  * \throw If \a this is not allocated or not with exactly one component.
10896  * \throw If an element in \a this if < 0.
10897  */
10898 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10899 {
10900   if(!isAllocated() || getNumberOfComponents()!=1)
10901     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10902   if(nbOfSlices<=0)
10903     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10904   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10905   int sumPerSlc(sum/nbOfSlices),pos(0);
10906   const int *w(begin());
10907   std::vector< std::pair<int,int> > ret(nbOfSlices);
10908   for(int i=0;i<nbOfSlices;i++)
10909     {
10910       std::pair<int,int> p(pos,-1);
10911       int locSum(0);
10912       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10913       if(i!=nbOfSlices-1)
10914         p.second=pos;
10915       else
10916         p.second=nbOfTuples;
10917       ret[i]=p;
10918     }
10919   return ret;
10920 }
10921
10922 /*!
10923  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10924  * valid cases.
10925  * 1.  The arrays have same number of tuples and components. Then each value of
10926  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10927  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10928  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10929  *   component. Then
10930  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10931  * 3.  The arrays have same number of components and one array, say _a2_, has one
10932  *   tuple. Then
10933  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10934  *
10935  * Info on components is copied either from the first array (in the first case) or from
10936  * the array with maximal number of elements (getNbOfElems()).
10937  *  \param [in] a1 - an array to sum up.
10938  *  \param [in] a2 - another array to sum up.
10939  *  \return DataArrayInt * - the new instance of DataArrayInt.
10940  *          The caller is to delete this result array using decrRef() as it is no more
10941  *          needed.
10942  *  \throw If either \a a1 or \a a2 is NULL.
10943  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10944  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10945  *         none of them has number of tuples or components equal to 1.
10946  */
10947 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10948 {
10949   if(!a1 || !a2)
10950     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10951   int nbOfTuple=a1->getNumberOfTuples();
10952   int nbOfTuple2=a2->getNumberOfTuples();
10953   int nbOfComp=a1->getNumberOfComponents();
10954   int nbOfComp2=a2->getNumberOfComponents();
10955   MCAuto<DataArrayInt> ret=0;
10956   if(nbOfTuple==nbOfTuple2)
10957     {
10958       if(nbOfComp==nbOfComp2)
10959         {
10960           ret=DataArrayInt::New();
10961           ret->alloc(nbOfTuple,nbOfComp);
10962           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10963           ret->copyStringInfoFrom(*a1);
10964         }
10965       else
10966         {
10967           int nbOfCompMin,nbOfCompMax;
10968           const DataArrayInt *aMin, *aMax;
10969           if(nbOfComp>nbOfComp2)
10970             {
10971               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10972               aMin=a2; aMax=a1;
10973             }
10974           else
10975             {
10976               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10977               aMin=a1; aMax=a2;
10978             }
10979           if(nbOfCompMin==1)
10980             {
10981               ret=DataArrayInt::New();
10982               ret->alloc(nbOfTuple,nbOfCompMax);
10983               const int *aMinPtr=aMin->getConstPointer();
10984               const int *aMaxPtr=aMax->getConstPointer();
10985               int *res=ret->getPointer();
10986               for(int i=0;i<nbOfTuple;i++)
10987                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10988               ret->copyStringInfoFrom(*aMax);
10989             }
10990           else
10991             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10992         }
10993     }
10994   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10995     {
10996       if(nbOfComp==nbOfComp2)
10997         {
10998           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10999           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
11000           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
11001           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
11002           ret=DataArrayInt::New();
11003           ret->alloc(nbOfTupleMax,nbOfComp);
11004           int *res=ret->getPointer();
11005           for(int i=0;i<nbOfTupleMax;i++)
11006             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
11007           ret->copyStringInfoFrom(*aMax);
11008         }
11009       else
11010         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
11011     }
11012   else
11013     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
11014   return ret.retn();
11015 }
11016
11017 /*!
11018  * Adds values of another DataArrayInt to values of \a this one. There are 3
11019  * valid cases.
11020  * 1.  The arrays have same number of tuples and components. Then each value of
11021  *   \a other array is added to the corresponding value of \a this array, i.e.:
11022  *   _a_ [ i, j ] += _other_ [ i, j ].
11023  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11024  *   _a_ [ i, j ] += _other_ [ i, 0 ].
11025  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11026  *   _a_ [ i, j ] += _a2_ [ 0, j ].
11027  *
11028  *  \param [in] other - an array to add to \a this one.
11029  *  \throw If \a other is NULL.
11030  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11031  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11032  *         \a other has number of both tuples and components not equal to 1.
11033  */
11034 void DataArrayInt::addEqual(const DataArrayInt *other)
11035 {
11036   if(!other)
11037     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
11038   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
11039   checkAllocated(); other->checkAllocated();
11040   int nbOfTuple=getNumberOfTuples();
11041   int nbOfTuple2=other->getNumberOfTuples();
11042   int nbOfComp=getNumberOfComponents();
11043   int nbOfComp2=other->getNumberOfComponents();
11044   if(nbOfTuple==nbOfTuple2)
11045     {
11046       if(nbOfComp==nbOfComp2)
11047         {
11048           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
11049         }
11050       else if(nbOfComp2==1)
11051         {
11052           int *ptr=getPointer();
11053           const int *ptrc=other->getConstPointer();
11054           for(int i=0;i<nbOfTuple;i++)
11055             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
11056         }
11057       else
11058         throw INTERP_KERNEL::Exception(msg);
11059     }
11060   else if(nbOfTuple2==1)
11061     {
11062       if(nbOfComp2==nbOfComp)
11063         {
11064           int *ptr=getPointer();
11065           const int *ptrc=other->getConstPointer();
11066           for(int i=0;i<nbOfTuple;i++)
11067             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
11068         }
11069       else
11070         throw INTERP_KERNEL::Exception(msg);
11071     }
11072   else
11073     throw INTERP_KERNEL::Exception(msg);
11074   declareAsNew();
11075 }
11076
11077 /*!
11078  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
11079  * valid cases.
11080  * 1.  The arrays have same number of tuples and components. Then each value of
11081  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
11082  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
11083  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11084  *   component. Then
11085  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
11086  * 3.  The arrays have same number of components and one array, say _a2_, has one
11087  *   tuple. Then
11088  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
11089  *
11090  * Info on components is copied either from the first array (in the first case) or from
11091  * the array with maximal number of elements (getNbOfElems()).
11092  *  \param [in] a1 - an array to subtract from.
11093  *  \param [in] a2 - an array to subtract.
11094  *  \return DataArrayInt * - the new instance of DataArrayInt.
11095  *          The caller is to delete this result array using decrRef() as it is no more
11096  *          needed.
11097  *  \throw If either \a a1 or \a a2 is NULL.
11098  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11099  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11100  *         none of them has number of tuples or components equal to 1.
11101  */
11102 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
11103 {
11104   if(!a1 || !a2)
11105     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
11106   int nbOfTuple1=a1->getNumberOfTuples();
11107   int nbOfTuple2=a2->getNumberOfTuples();
11108   int nbOfComp1=a1->getNumberOfComponents();
11109   int nbOfComp2=a2->getNumberOfComponents();
11110   if(nbOfTuple2==nbOfTuple1)
11111     {
11112       if(nbOfComp1==nbOfComp2)
11113         {
11114           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11115           ret->alloc(nbOfTuple2,nbOfComp1);
11116           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
11117           ret->copyStringInfoFrom(*a1);
11118           return ret.retn();
11119         }
11120       else if(nbOfComp2==1)
11121         {
11122           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11123           ret->alloc(nbOfTuple1,nbOfComp1);
11124           const int *a2Ptr=a2->getConstPointer();
11125           const int *a1Ptr=a1->getConstPointer();
11126           int *res=ret->getPointer();
11127           for(int i=0;i<nbOfTuple1;i++)
11128             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
11129           ret->copyStringInfoFrom(*a1);
11130           return ret.retn();
11131         }
11132       else
11133         {
11134           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
11135           return 0;
11136         }
11137     }
11138   else if(nbOfTuple2==1)
11139     {
11140       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
11141       MCAuto<DataArrayInt> ret=DataArrayInt::New();
11142       ret->alloc(nbOfTuple1,nbOfComp1);
11143       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11144       int *pt=ret->getPointer();
11145       for(int i=0;i<nbOfTuple1;i++)
11146         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
11147       ret->copyStringInfoFrom(*a1);
11148       return ret.retn();
11149     }
11150   else
11151     {
11152       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
11153       return 0;
11154     }
11155 }
11156
11157 /*!
11158  * Subtract values of another DataArrayInt from values of \a this one. There are 3
11159  * valid cases.
11160  * 1.  The arrays have same number of tuples and components. Then each value of
11161  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
11162  *   _a_ [ i, j ] -= _other_ [ i, j ].
11163  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11164  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
11165  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11166  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
11167  *
11168  *  \param [in] other - an array to subtract from \a this one.
11169  *  \throw If \a other is NULL.
11170  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11171  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11172  *         \a other has number of both tuples and components not equal to 1.
11173  */
11174 void DataArrayInt::substractEqual(const DataArrayInt *other)
11175 {
11176   if(!other)
11177     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
11178   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
11179   checkAllocated(); other->checkAllocated();
11180   int nbOfTuple=getNumberOfTuples();
11181   int nbOfTuple2=other->getNumberOfTuples();
11182   int nbOfComp=getNumberOfComponents();
11183   int nbOfComp2=other->getNumberOfComponents();
11184   if(nbOfTuple==nbOfTuple2)
11185     {
11186       if(nbOfComp==nbOfComp2)
11187         {
11188           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
11189         }
11190       else if(nbOfComp2==1)
11191         {
11192           int *ptr=getPointer();
11193           const int *ptrc=other->getConstPointer();
11194           for(int i=0;i<nbOfTuple;i++)
11195             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
11196         }
11197       else
11198         throw INTERP_KERNEL::Exception(msg);
11199     }
11200   else if(nbOfTuple2==1)
11201     {
11202       int *ptr=getPointer();
11203       const int *ptrc=other->getConstPointer();
11204       for(int i=0;i<nbOfTuple;i++)
11205         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
11206     }
11207   else
11208     throw INTERP_KERNEL::Exception(msg);
11209   declareAsNew();
11210 }
11211
11212 /*!
11213  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
11214  * valid cases.
11215  * 1.  The arrays have same number of tuples and components. Then each value of
11216  *   the result array (_a_) is a product of the corresponding values of \a a1 and
11217  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
11218  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11219  *   component. Then
11220  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
11221  * 3.  The arrays have same number of components and one array, say _a2_, has one
11222  *   tuple. Then
11223  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
11224  *
11225  * Info on components is copied either from the first array (in the first case) or from
11226  * the array with maximal number of elements (getNbOfElems()).
11227  *  \param [in] a1 - a factor array.
11228  *  \param [in] a2 - another factor array.
11229  *  \return DataArrayInt * - the new instance of DataArrayInt.
11230  *          The caller is to delete this result array using decrRef() as it is no more
11231  *          needed.
11232  *  \throw If either \a a1 or \a a2 is NULL.
11233  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11234  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11235  *         none of them has number of tuples or components equal to 1.
11236  */
11237 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
11238 {
11239   if(!a1 || !a2)
11240     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
11241   int nbOfTuple=a1->getNumberOfTuples();
11242   int nbOfTuple2=a2->getNumberOfTuples();
11243   int nbOfComp=a1->getNumberOfComponents();
11244   int nbOfComp2=a2->getNumberOfComponents();
11245   MCAuto<DataArrayInt> ret=0;
11246   if(nbOfTuple==nbOfTuple2)
11247     {
11248       if(nbOfComp==nbOfComp2)
11249         {
11250           ret=DataArrayInt::New();
11251           ret->alloc(nbOfTuple,nbOfComp);
11252           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
11253           ret->copyStringInfoFrom(*a1);
11254         }
11255       else
11256         {
11257           int nbOfCompMin,nbOfCompMax;
11258           const DataArrayInt *aMin, *aMax;
11259           if(nbOfComp>nbOfComp2)
11260             {
11261               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
11262               aMin=a2; aMax=a1;
11263             }
11264           else
11265             {
11266               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
11267               aMin=a1; aMax=a2;
11268             }
11269           if(nbOfCompMin==1)
11270             {
11271               ret=DataArrayInt::New();
11272               ret->alloc(nbOfTuple,nbOfCompMax);
11273               const int *aMinPtr=aMin->getConstPointer();
11274               const int *aMaxPtr=aMax->getConstPointer();
11275               int *res=ret->getPointer();
11276               for(int i=0;i<nbOfTuple;i++)
11277                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
11278               ret->copyStringInfoFrom(*aMax);
11279             }
11280           else
11281             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
11282         }
11283     }
11284   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
11285     {
11286       if(nbOfComp==nbOfComp2)
11287         {
11288           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
11289           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
11290           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
11291           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
11292           ret=DataArrayInt::New();
11293           ret->alloc(nbOfTupleMax,nbOfComp);
11294           int *res=ret->getPointer();
11295           for(int i=0;i<nbOfTupleMax;i++)
11296             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
11297           ret->copyStringInfoFrom(*aMax);
11298         }
11299       else
11300         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
11301     }
11302   else
11303     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
11304   return ret.retn();
11305 }
11306
11307
11308 /*!
11309  * Multiply values of another DataArrayInt to values of \a this one. There are 3
11310  * valid cases.
11311  * 1.  The arrays have same number of tuples and components. Then each value of
11312  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
11313  *   _a_ [ i, j ] *= _other_ [ i, j ].
11314  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11315  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
11316  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11317  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
11318  *
11319  *  \param [in] other - an array to multiply to \a this one.
11320  *  \throw If \a other is NULL.
11321  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11322  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11323  *         \a other has number of both tuples and components not equal to 1.
11324  */
11325 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
11326 {
11327   if(!other)
11328     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
11329   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
11330   checkAllocated(); other->checkAllocated();
11331   int nbOfTuple=getNumberOfTuples();
11332   int nbOfTuple2=other->getNumberOfTuples();
11333   int nbOfComp=getNumberOfComponents();
11334   int nbOfComp2=other->getNumberOfComponents();
11335   if(nbOfTuple==nbOfTuple2)
11336     {
11337       if(nbOfComp==nbOfComp2)
11338         {
11339           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
11340         }
11341       else if(nbOfComp2==1)
11342         {
11343           int *ptr=getPointer();
11344           const int *ptrc=other->getConstPointer();
11345           for(int i=0;i<nbOfTuple;i++)
11346             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
11347         }
11348       else
11349         throw INTERP_KERNEL::Exception(msg);
11350     }
11351   else if(nbOfTuple2==1)
11352     {
11353       if(nbOfComp2==nbOfComp)
11354         {
11355           int *ptr=getPointer();
11356           const int *ptrc=other->getConstPointer();
11357           for(int i=0;i<nbOfTuple;i++)
11358             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
11359         }
11360       else
11361         throw INTERP_KERNEL::Exception(msg);
11362     }
11363   else
11364     throw INTERP_KERNEL::Exception(msg);
11365   declareAsNew();
11366 }
11367
11368
11369 /*!
11370  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
11371  * valid cases.
11372  * 1.  The arrays have same number of tuples and components. Then each value of
11373  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11374  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
11375  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11376  *   component. Then
11377  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
11378  * 3.  The arrays have same number of components and one array, say _a2_, has one
11379  *   tuple. Then
11380  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
11381  *
11382  * Info on components is copied either from the first array (in the first case) or from
11383  * the array with maximal number of elements (getNbOfElems()).
11384  *  \warning No check of division by zero is performed!
11385  *  \param [in] a1 - a numerator array.
11386  *  \param [in] a2 - a denominator array.
11387  *  \return DataArrayInt * - the new instance of DataArrayInt.
11388  *          The caller is to delete this result array using decrRef() as it is no more
11389  *          needed.
11390  *  \throw If either \a a1 or \a a2 is NULL.
11391  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11392  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11393  *         none of them has number of tuples or components equal to 1.
11394  */
11395 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
11396 {
11397   if(!a1 || !a2)
11398     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
11399   int nbOfTuple1=a1->getNumberOfTuples();
11400   int nbOfTuple2=a2->getNumberOfTuples();
11401   int nbOfComp1=a1->getNumberOfComponents();
11402   int nbOfComp2=a2->getNumberOfComponents();
11403   if(nbOfTuple2==nbOfTuple1)
11404     {
11405       if(nbOfComp1==nbOfComp2)
11406         {
11407           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11408           ret->alloc(nbOfTuple2,nbOfComp1);
11409           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
11410           ret->copyStringInfoFrom(*a1);
11411           return ret.retn();
11412         }
11413       else if(nbOfComp2==1)
11414         {
11415           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11416           ret->alloc(nbOfTuple1,nbOfComp1);
11417           const int *a2Ptr=a2->getConstPointer();
11418           const int *a1Ptr=a1->getConstPointer();
11419           int *res=ret->getPointer();
11420           for(int i=0;i<nbOfTuple1;i++)
11421             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
11422           ret->copyStringInfoFrom(*a1);
11423           return ret.retn();
11424         }
11425       else
11426         {
11427           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11428           return 0;
11429         }
11430     }
11431   else if(nbOfTuple2==1)
11432     {
11433       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
11434       MCAuto<DataArrayInt> ret=DataArrayInt::New();
11435       ret->alloc(nbOfTuple1,nbOfComp1);
11436       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11437       int *pt=ret->getPointer();
11438       for(int i=0;i<nbOfTuple1;i++)
11439         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
11440       ret->copyStringInfoFrom(*a1);
11441       return ret.retn();
11442     }
11443   else
11444     {
11445       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
11446       return 0;
11447     }
11448 }
11449
11450 /*!
11451  * Divide values of \a this array by values of another DataArrayInt. There are 3
11452  * valid cases.
11453  * 1.  The arrays have same number of tuples and components. Then each value of
11454  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11455  *   _a_ [ i, j ] /= _other_ [ i, j ].
11456  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11457  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
11458  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11459  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
11460  *
11461  *  \warning No check of division by zero is performed!
11462  *  \param [in] other - an array to divide \a this one by.
11463  *  \throw If \a other is NULL.
11464  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11465  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11466  *         \a other has number of both tuples and components not equal to 1.
11467  */
11468 void DataArrayInt::divideEqual(const DataArrayInt *other)
11469 {
11470   if(!other)
11471     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
11472   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
11473   checkAllocated(); other->checkAllocated();
11474   int nbOfTuple=getNumberOfTuples();
11475   int nbOfTuple2=other->getNumberOfTuples();
11476   int nbOfComp=getNumberOfComponents();
11477   int nbOfComp2=other->getNumberOfComponents();
11478   if(nbOfTuple==nbOfTuple2)
11479     {
11480       if(nbOfComp==nbOfComp2)
11481         {
11482           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
11483         }
11484       else if(nbOfComp2==1)
11485         {
11486           int *ptr=getPointer();
11487           const int *ptrc=other->getConstPointer();
11488           for(int i=0;i<nbOfTuple;i++)
11489             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
11490         }
11491       else
11492         throw INTERP_KERNEL::Exception(msg);
11493     }
11494   else if(nbOfTuple2==1)
11495     {
11496       if(nbOfComp2==nbOfComp)
11497         {
11498           int *ptr=getPointer();
11499           const int *ptrc=other->getConstPointer();
11500           for(int i=0;i<nbOfTuple;i++)
11501             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
11502         }
11503       else
11504         throw INTERP_KERNEL::Exception(msg);
11505     }
11506   else
11507     throw INTERP_KERNEL::Exception(msg);
11508   declareAsNew();
11509 }
11510
11511
11512 /*!
11513  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
11514  * valid cases.
11515  * 1.  The arrays have same number of tuples and components. Then each value of
11516  *   the result array (_a_) is a division of the corresponding values of \a a1 and
11517  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
11518  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
11519  *   component. Then
11520  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
11521  * 3.  The arrays have same number of components and one array, say _a2_, has one
11522  *   tuple. Then
11523  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
11524  *
11525  * Info on components is copied either from the first array (in the first case) or from
11526  * the array with maximal number of elements (getNbOfElems()).
11527  *  \warning No check of division by zero is performed!
11528  *  \param [in] a1 - a dividend array.
11529  *  \param [in] a2 - a divisor array.
11530  *  \return DataArrayInt * - the new instance of DataArrayInt.
11531  *          The caller is to delete this result array using decrRef() as it is no more
11532  *          needed.
11533  *  \throw If either \a a1 or \a a2 is NULL.
11534  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
11535  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
11536  *         none of them has number of tuples or components equal to 1.
11537  */
11538 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
11539 {
11540   if(!a1 || !a2)
11541     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
11542   int nbOfTuple1=a1->getNumberOfTuples();
11543   int nbOfTuple2=a2->getNumberOfTuples();
11544   int nbOfComp1=a1->getNumberOfComponents();
11545   int nbOfComp2=a2->getNumberOfComponents();
11546   if(nbOfTuple2==nbOfTuple1)
11547     {
11548       if(nbOfComp1==nbOfComp2)
11549         {
11550           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11551           ret->alloc(nbOfTuple2,nbOfComp1);
11552           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
11553           ret->copyStringInfoFrom(*a1);
11554           return ret.retn();
11555         }
11556       else if(nbOfComp2==1)
11557         {
11558           MCAuto<DataArrayInt> ret=DataArrayInt::New();
11559           ret->alloc(nbOfTuple1,nbOfComp1);
11560           const int *a2Ptr=a2->getConstPointer();
11561           const int *a1Ptr=a1->getConstPointer();
11562           int *res=ret->getPointer();
11563           for(int i=0;i<nbOfTuple1;i++)
11564             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
11565           ret->copyStringInfoFrom(*a1);
11566           return ret.retn();
11567         }
11568       else
11569         {
11570           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11571           return 0;
11572         }
11573     }
11574   else if(nbOfTuple2==1)
11575     {
11576       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11577       MCAuto<DataArrayInt> ret=DataArrayInt::New();
11578       ret->alloc(nbOfTuple1,nbOfComp1);
11579       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11580       int *pt=ret->getPointer();
11581       for(int i=0;i<nbOfTuple1;i++)
11582         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
11583       ret->copyStringInfoFrom(*a1);
11584       return ret.retn();
11585     }
11586   else
11587     {
11588       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
11589       return 0;
11590     }
11591 }
11592
11593 /*!
11594  * Modify \a this array so that each value becomes a modulus of division of this value by
11595  * a value of another DataArrayInt. There are 3 valid cases.
11596  * 1.  The arrays have same number of tuples and components. Then each value of
11597  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11598  *   _a_ [ i, j ] %= _other_ [ i, j ].
11599  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11600  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
11601  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11602  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
11603  *
11604  *  \warning No check of division by zero is performed!
11605  *  \param [in] other - a divisor array.
11606  *  \throw If \a other is NULL.
11607  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11608  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11609  *         \a other has number of both tuples and components not equal to 1.
11610  */
11611 void DataArrayInt::modulusEqual(const DataArrayInt *other)
11612 {
11613   if(!other)
11614     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
11615   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
11616   checkAllocated(); other->checkAllocated();
11617   int nbOfTuple=getNumberOfTuples();
11618   int nbOfTuple2=other->getNumberOfTuples();
11619   int nbOfComp=getNumberOfComponents();
11620   int nbOfComp2=other->getNumberOfComponents();
11621   if(nbOfTuple==nbOfTuple2)
11622     {
11623       if(nbOfComp==nbOfComp2)
11624         {
11625           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
11626         }
11627       else if(nbOfComp2==1)
11628         {
11629           if(nbOfComp2==nbOfComp)
11630             {
11631               int *ptr=getPointer();
11632               const int *ptrc=other->getConstPointer();
11633               for(int i=0;i<nbOfTuple;i++)
11634                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
11635             }
11636           else
11637             throw INTERP_KERNEL::Exception(msg);
11638         }
11639       else
11640         throw INTERP_KERNEL::Exception(msg);
11641     }
11642   else if(nbOfTuple2==1)
11643     {
11644       int *ptr=getPointer();
11645       const int *ptrc=other->getConstPointer();
11646       for(int i=0;i<nbOfTuple;i++)
11647         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
11648     }
11649   else
11650     throw INTERP_KERNEL::Exception(msg);
11651   declareAsNew();
11652 }
11653
11654 /*!
11655  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
11656  * valid cases.
11657  *
11658  *  \param [in] a1 - an array to pow up.
11659  *  \param [in] a2 - another array to sum up.
11660  *  \return DataArrayInt * - the new instance of DataArrayInt.
11661  *          The caller is to delete this result array using decrRef() as it is no more
11662  *          needed.
11663  *  \throw If either \a a1 or \a a2 is NULL.
11664  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
11665  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
11666  *  \throw If there is a negative value in \a a2.
11667  */
11668 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
11669 {
11670   if(!a1 || !a2)
11671     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
11672   int nbOfTuple=a1->getNumberOfTuples();
11673   int nbOfTuple2=a2->getNumberOfTuples();
11674   int nbOfComp=a1->getNumberOfComponents();
11675   int nbOfComp2=a2->getNumberOfComponents();
11676   if(nbOfTuple!=nbOfTuple2)
11677     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
11678   if(nbOfComp!=1 || nbOfComp2!=1)
11679     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
11680   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
11681   const int *ptr1(a1->begin()),*ptr2(a2->begin());
11682   int *ptr=ret->getPointer();
11683   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
11684     {
11685       if(*ptr2>=0)
11686         {
11687           int tmp=1;
11688           for(int j=0;j<*ptr2;j++)
11689             tmp*=*ptr1;
11690           *ptr=tmp;
11691         }
11692       else
11693         {
11694           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
11695           throw INTERP_KERNEL::Exception(oss.str().c_str());
11696         }
11697     }
11698   return ret.retn();
11699 }
11700
11701 /*!
11702  * Apply pow on values of another DataArrayInt to values of \a this one.
11703  *
11704  *  \param [in] other - an array to pow to \a this one.
11705  *  \throw If \a other is NULL.
11706  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
11707  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
11708  *  \throw If there is a negative value in \a other.
11709  */
11710 void DataArrayInt::powEqual(const DataArrayInt *other)
11711 {
11712   if(!other)
11713     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
11714   int nbOfTuple=getNumberOfTuples();
11715   int nbOfTuple2=other->getNumberOfTuples();
11716   int nbOfComp=getNumberOfComponents();
11717   int nbOfComp2=other->getNumberOfComponents();
11718   if(nbOfTuple!=nbOfTuple2)
11719     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
11720   if(nbOfComp!=1 || nbOfComp2!=1)
11721     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
11722   int *ptr=getPointer();
11723   const int *ptrc=other->begin();
11724   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
11725     {
11726       if(*ptrc>=0)
11727         {
11728           int tmp=1;
11729           for(int j=0;j<*ptrc;j++)
11730             tmp*=*ptr;
11731           *ptr=tmp;
11732         }
11733       else
11734         {
11735           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
11736           throw INTERP_KERNEL::Exception(oss.str().c_str());
11737         }
11738     }
11739   declareAsNew();
11740 }
11741
11742 /*!
11743  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
11744  * This map, if applied to \a start array, would make it sorted. For example, if
11745  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
11746  * [5,6,0,3,2,7,1,4].
11747  *  \param [in] start - pointer to the first element of the array for which the
11748  *         permutation map is computed.
11749  *  \param [in] end - pointer specifying the end of the array \a start, so that
11750  *         the last value of \a start is \a end[ -1 ].
11751  *  \return int * - the result permutation array that the caller is to delete as it is no
11752  *         more needed.
11753  *  \throw If there are equal values in the input array.
11754  */
11755 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
11756 {
11757   std::size_t sz=std::distance(start,end);
11758   int *ret=(int *)malloc(sz*sizeof(int));
11759   int *work=new int[sz];
11760   std::copy(start,end,work);
11761   std::sort(work,work+sz);
11762   if(std::unique(work,work+sz)!=work+sz)
11763     {
11764       delete [] work;
11765       free(ret);
11766       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
11767     }
11768   std::map<int,int> m;
11769   for(int *workPt=work;workPt!=work+sz;workPt++)
11770     m[*workPt]=(int)std::distance(work,workPt);
11771   int *iter2=ret;
11772   for(const int *iter=start;iter!=end;iter++,iter2++)
11773     *iter2=m[*iter];
11774   delete [] work;
11775   return ret;
11776 }
11777
11778 /*!
11779  * Returns a new DataArrayInt containing an arithmetic progression
11780  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
11781  * function.
11782  *  \param [in] begin - the start value of the result sequence.
11783  *  \param [in] end - limiting value, so that every value of the result array is less than
11784  *              \a end.
11785  *  \param [in] step - specifies the increment or decrement.
11786  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
11787  *          array using decrRef() as it is no more needed.
11788  *  \throw If \a step == 0.
11789  *  \throw If \a end < \a begin && \a step > 0.
11790  *  \throw If \a end > \a begin && \a step < 0.
11791  */
11792 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
11793 {
11794   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
11795   MCAuto<DataArrayInt> ret=DataArrayInt::New();
11796   ret->alloc(nbOfTuples,1);
11797   int *ptr=ret->getPointer();
11798   if(step>0)
11799     {
11800       for(int i=begin;i<end;i+=step,ptr++)
11801         *ptr=i;
11802     }
11803   else
11804     {
11805       for(int i=begin;i>end;i+=step,ptr++)
11806         *ptr=i;
11807     }
11808   return ret.retn();
11809 }
11810
11811 /*!
11812  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11813  * Server side.
11814  */
11815 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
11816 {
11817   tinyInfo.resize(2);
11818   if(isAllocated())
11819     {
11820       tinyInfo[0]=getNumberOfTuples();
11821       tinyInfo[1]=getNumberOfComponents();
11822     }
11823   else
11824     {
11825       tinyInfo[0]=-1;
11826       tinyInfo[1]=-1;
11827     }
11828 }
11829
11830 /*!
11831  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11832  * Server side.
11833  */
11834 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
11835 {
11836   if(isAllocated())
11837     {
11838       int nbOfCompo=getNumberOfComponents();
11839       tinyInfo.resize(nbOfCompo+1);
11840       tinyInfo[0]=getName();
11841       for(int i=0;i<nbOfCompo;i++)
11842         tinyInfo[i+1]=getInfoOnComponent(i);
11843     }
11844   else
11845     {
11846       tinyInfo.resize(1);
11847       tinyInfo[0]=getName();
11848     }
11849 }
11850
11851 /*!
11852  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11853  * This method returns if a feeding is needed.
11854  */
11855 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11856 {
11857   int nbOfTuple=tinyInfoI[0];
11858   int nbOfComp=tinyInfoI[1];
11859   if(nbOfTuple!=-1 || nbOfComp!=-1)
11860     {
11861       alloc(nbOfTuple,nbOfComp);
11862       return true;
11863     }
11864   return false;
11865 }
11866
11867 /*!
11868  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11869  * This method returns if a feeding is needed.
11870  */
11871 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11872 {
11873   setName(tinyInfoS[0]);
11874   if(isAllocated())
11875     {
11876       int nbOfCompo=tinyInfoI[1];
11877       for(int i=0;i<nbOfCompo;i++)
11878         setInfoOnComponent(i,tinyInfoS[i+1]);
11879     }
11880 }
11881
11882 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11883 {
11884   if(_da)
11885     {
11886       _da->incrRef();
11887       if(_da->isAllocated())
11888         {
11889           _nb_comp=da->getNumberOfComponents();
11890           _nb_tuple=da->getNumberOfTuples();
11891           _pt=da->getPointer();
11892         }
11893     }
11894 }
11895
11896 DataArrayIntIterator::~DataArrayIntIterator()
11897 {
11898   if(_da)
11899     _da->decrRef();
11900 }
11901
11902 DataArrayIntTuple *DataArrayIntIterator::nextt()
11903 {
11904   if(_tuple_id<_nb_tuple)
11905     {
11906       _tuple_id++;
11907       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11908       _pt+=_nb_comp;
11909       return ret;
11910     }
11911   else
11912     return 0;
11913 }
11914
11915 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11916 {
11917 }
11918
11919 std::string DataArrayIntTuple::repr() const
11920 {
11921   std::ostringstream oss; oss << "(";
11922   for(int i=0;i<_nb_of_compo-1;i++)
11923     oss << _pt[i] << ", ";
11924   oss << _pt[_nb_of_compo-1] << ")";
11925   return oss.str();
11926 }
11927
11928 int DataArrayIntTuple::intValue() const
11929 {
11930   if(_nb_of_compo==1)
11931     return *_pt;
11932   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11933 }
11934
11935 /*!
11936  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
11937  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
11938  * 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
11939  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11940  */
11941 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11942 {
11943   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11944     {
11945       DataArrayInt *ret=DataArrayInt::New();
11946       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11947       return ret;
11948     }
11949   else
11950     {
11951       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11952       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11953       throw INTERP_KERNEL::Exception(oss.str().c_str());
11954     }
11955 }