Salome HOME
424a2098654b44c644a9cff89287ae819a56dd7c
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2013  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.
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 "MEDCouplingAutoRefCountObjectPtr.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 ParaMEDMEM;
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::getHeapMemorySize() 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 /*!
124  * Sets the attribute \a _name of \a this array.
125  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
126  *  \param [in] name - new array name
127  */
128 void DataArray::setName(const char *name)
129 {
130   _name=name;
131 }
132
133 /*!
134  * Copies textual data from an \a other DataArray. The copied data are
135  * - the name attribute,
136  * - the information of components.
137  *
138  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
139  *
140  *  \param [in] other - another instance of DataArray to copy the textual data from.
141  *  \throw If number of components of \a this array differs from that of the \a other.
142  */
143 void DataArray::copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception)
144 {
145   if(_info_on_compo.size()!=other._info_on_compo.size())
146     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
147   _name=other._name;
148   _info_on_compo=other._info_on_compo;
149 }
150
151 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
152 {
153   int nbOfCompoOth=other.getNumberOfComponents();
154   std::size_t newNbOfCompo=compoIds.size();
155   for(std::size_t i=0;i<newNbOfCompo;i++)
156     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
157       {
158         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
159         throw INTERP_KERNEL::Exception(oss.str().c_str());
160       }
161   for(std::size_t i=0;i<newNbOfCompo;i++)
162     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]).c_str());
163 }
164
165 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception)
166 {
167   int nbOfCompo=getNumberOfComponents();
168   std::size_t partOfCompoToSet=compoIds.size();
169   if((int)partOfCompoToSet!=other.getNumberOfComponents())
170     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
171   for(std::size_t i=0;i<partOfCompoToSet;i++)
172     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
173       {
174         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
175         throw INTERP_KERNEL::Exception(oss.str().c_str());
176       }
177   for(std::size_t i=0;i<partOfCompoToSet;i++)
178     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i).c_str());
179 }
180
181 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
182 {
183   std::ostringstream oss;
184   if(_name!=other._name)
185     {
186       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
187       reason=oss.str();
188       return false;
189     }
190   if(_info_on_compo!=other._info_on_compo)
191     {
192       oss << "Components DataArray mismatch : \nThis components=";
193       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
194         oss << "\"" << *it << "\",";
195       oss << "\nOther components=";
196       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
197         oss << "\"" << *it << "\",";
198       reason=oss.str();
199       return false;
200     }
201   return true;
202 }
203
204 /*!
205  * Compares textual information of \a this DataArray with that of an \a other one.
206  * The compared data are
207  * - the name attribute,
208  * - the information of components.
209  *
210  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
211  *  \param [in] other - another instance of DataArray to compare the textual data of.
212  *  \return bool - \a true if the textual information is same, \a false else.
213  */
214 bool DataArray::areInfoEquals(const DataArray& other) const throw(INTERP_KERNEL::Exception)
215 {
216   std::string tmp;
217   return areInfoEqualsIfNotWhy(other,tmp);
218 }
219
220 void DataArray::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
221 {
222   stream << "Number of components : "<< getNumberOfComponents() << "\n";
223   stream << "Info of these components : ";
224   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
225     stream << "\"" << *iter << "\"   ";
226   stream << "\n";
227 }
228
229 std::string DataArray::cppRepr(const char *varName) const throw(INTERP_KERNEL::Exception)
230 {
231   std::ostringstream ret;
232   reprCppStream(varName,ret);
233   return ret.str();
234 }
235
236 /*!
237  * Sets information on all components. To know more on format of this information
238  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
239  *  \param [in] info - a vector of strings.
240  *  \throw If size of \a info differs from the number of components of \a this.
241  */
242 void DataArray::setInfoOnComponents(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
243 {
244   if(getNumberOfComponents()!=(int)info.size())
245     {
246       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
247       throw INTERP_KERNEL::Exception(oss.str().c_str());
248     }
249   _info_on_compo=info;
250 }
251
252 /*!
253  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
254  * type of \a this and \a aBase.
255  *
256  * \throw If \a aBase and \a this do not have the same type.
257  *
258  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
259  */
260 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
261 {
262   if(!aBase)
263     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
264   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
265   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
266   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
267   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
268   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
269   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
270   if(this1 && a1)
271     {
272       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
273       return ;
274     }
275   if(this2 && a2)
276     {
277       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
278       return ;
279     }
280   if(this3 && a3)
281     {
282       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
283       return ;
284     }
285   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
286 }
287
288 std::vector<std::string> DataArray::getVarsOnComponent() const throw(INTERP_KERNEL::Exception)
289 {
290   int nbOfCompo=(int)_info_on_compo.size();
291   std::vector<std::string> ret(nbOfCompo);
292   for(int i=0;i<nbOfCompo;i++)
293     ret[i]=getVarOnComponent(i);
294   return ret;
295 }
296
297 std::vector<std::string> DataArray::getUnitsOnComponent() const throw(INTERP_KERNEL::Exception)
298 {
299   int nbOfCompo=(int)_info_on_compo.size();
300   std::vector<std::string> ret(nbOfCompo);
301   for(int i=0;i<nbOfCompo;i++)
302     ret[i]=getUnitOnComponent(i);
303   return ret;
304 }
305
306 /*!
307  * Returns information on a component specified by an index.
308  * To know more on format of this information
309  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
310  *  \param [in] i - the index (zero based) of the component of interest.
311  *  \return std::string - a string containing the information on \a i-th component.
312  *  \throw If \a i is not a valid component index.
313  */
314 std::string DataArray::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception)
315 {
316   if(i<(int)_info_on_compo.size() && i>=0)
317     return _info_on_compo[i];
318   else
319     {
320       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();
321       throw INTERP_KERNEL::Exception(oss.str().c_str());
322     }
323 }
324
325 /*!
326  * Returns the var part of the full information of the \a i-th component.
327  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
328  * \c getVarOnComponent(0) returns "SIGXY".
329  * If a unit part of information is not detected by presence of
330  * two square brackets, then the full information is returned.
331  * To read more about the component information format, see
332  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
333  *  \param [in] i - the index (zero based) of the component of interest.
334  *  \return std::string - a string containing the var information, or the full info.
335  *  \throw If \a i is not a valid component index.
336  */
337 std::string DataArray::getVarOnComponent(int i) const throw(INTERP_KERNEL::Exception)
338 {
339   if(i<(int)_info_on_compo.size() && i>=0)
340     {
341       return GetVarNameFromInfo(_info_on_compo[i]);
342     }
343   else
344     {
345       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();
346       throw INTERP_KERNEL::Exception(oss.str().c_str());
347     }
348 }
349
350 /*!
351  * Returns the unit part of the full information of the \a i-th component.
352  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
353  * \c getUnitOnComponent(0) returns " N/m^2".
354  * If a unit part of information is not detected by presence of
355  * two square brackets, then an empty string is returned.
356  * To read more about the component information format, see
357  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
358  *  \param [in] i - the index (zero based) of the component of interest.
359  *  \return std::string - a string containing the unit information, if any, or "".
360  *  \throw If \a i is not a valid component index.
361  */
362 std::string DataArray::getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception)
363 {
364   if(i<(int)_info_on_compo.size() && i>=0)
365     {
366       return GetUnitFromInfo(_info_on_compo[i]);
367     }
368   else
369     {
370       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();
371       throw INTERP_KERNEL::Exception(oss.str().c_str());
372     }
373 }
374
375 /*!
376  * Returns the var part of the full component information.
377  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
378  * If a unit part of information is not detected by presence of
379  * two square brackets, then the whole \a info is returned.
380  * To read more about the component information format, see
381  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
382  *  \param [in] info - the full component information.
383  *  \return std::string - a string containing only var information, or the \a info.
384  */
385 std::string DataArray::GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
386 {
387   std::size_t p1=info.find_last_of('[');
388   std::size_t p2=info.find_last_of(']');
389   if(p1==std::string::npos || p2==std::string::npos)
390     return info;
391   if(p1>p2)
392     return info;
393   if(p1==0)
394     return std::string();
395   std::size_t p3=info.find_last_not_of(' ',p1-1);
396   return info.substr(0,p3+1);
397 }
398
399 /*!
400  * Returns the unit part of the full component information.
401  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
402  * If a unit part of information is not detected by presence of
403  * two square brackets, then an empty string is returned.
404  * To read more about the component information format, see
405  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
406  *  \param [in] info - the full component information.
407  *  \return std::string - a string containing only unit information, if any, or "".
408  */
409 std::string DataArray::GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
410 {
411   std::size_t p1=info.find_last_of('[');
412   std::size_t p2=info.find_last_of(']');
413   if(p1==std::string::npos || p2==std::string::npos)
414     return std::string();
415   if(p1>p2)
416     return std::string();
417   return info.substr(p1+1,p2-p1-1);
418 }
419
420 /*!
421  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
422  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
423  * the number of component in the result array is same as that of each of given arrays.
424  * Info on components is copied from the first of the given arrays. Number of components
425  * in the given arrays must be  the same.
426  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
427  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
428  *          The caller is to delete this result array using decrRef() as it is no more
429  *          needed.
430  *  \throw If all arrays within \a arrs are NULL.
431  *  \throw If all not null arrays in \a arrs have not the same type.
432  *  \throw If getNumberOfComponents() of arrays within \a arrs.
433  */
434 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs) throw(INTERP_KERNEL::Exception)
435 {
436   std::vector<const DataArray *> arr2;
437   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
438     if(*it)
439       arr2.push_back(*it);
440   if(arr2.empty())
441     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
442   std::vector<const DataArrayDouble *> arrd;
443   std::vector<const DataArrayInt *> arri;
444   std::vector<const DataArrayChar *> arrc;
445   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
446     {
447       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
448       if(a)
449         { arrd.push_back(a); continue; }
450       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
451       if(b)
452         { arri.push_back(b); continue; }
453       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
454       if(c)
455         { arrc.push_back(c); continue; }
456       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
457     }
458   if(arr2.size()==arrd.size())
459     return DataArrayDouble::Aggregate(arrd);
460   if(arr2.size()==arri.size())
461     return DataArrayInt::Aggregate(arri);
462   if(arr2.size()==arrc.size())
463     return DataArrayChar::Aggregate(arrc);
464   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
465 }
466
467 /*!
468  * Sets information on a component specified by an index.
469  * To know more on format of this information
470  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
471  *  \warning Don't pass NULL as \a info!
472  *  \param [in] i - the index (zero based) of the component of interest.
473  *  \param [in] info - the string containing the information.
474  *  \throw If \a i is not a valid component index.
475  */
476 void DataArray::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception)
477 {
478   if(i<(int)_info_on_compo.size() && i>=0)
479     _info_on_compo[i]=info;
480   else
481     {
482       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();
483       throw INTERP_KERNEL::Exception(oss.str().c_str());
484     }
485 }
486
487 /*!
488  * Sets information on all components. This method can change number of components
489  * at certain conditions; if the conditions are not respected, an exception is thrown.
490  * The number of components can be changed in \a this only if \a this is not allocated.
491  * The condition of number of components must not be changed.
492  *
493  * To know more on format of the component information see
494  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
495  *  \param [in] info - a vector of component infos.
496  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
497  */
498 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
499 {
500   if(getNumberOfComponents()!=(int)info.size())
501     {
502       if(!isAllocated())
503         _info_on_compo=info;
504       else
505         {
506           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 !";
507           throw INTERP_KERNEL::Exception(oss.str().c_str());
508         }
509     }
510   else
511     _info_on_compo=info;
512 }
513
514 void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const throw(INTERP_KERNEL::Exception)
515 {
516   if(getNumberOfTuples()!=nbOfTuples)
517     {
518       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
519       throw INTERP_KERNEL::Exception(oss.str().c_str());
520     }
521 }
522
523 void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
524 {
525   if(getNumberOfComponents()!=nbOfCompo)
526     {
527       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
528       throw INTERP_KERNEL::Exception(oss.str().c_str());
529     }
530 }
531
532 void DataArray::checkNbOfElems(std::size_t nbOfElems, const char *msg) const throw(INTERP_KERNEL::Exception)
533 {
534   if(getNbOfElems()!=nbOfElems)
535     {
536       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
537       throw INTERP_KERNEL::Exception(oss.str().c_str());
538     }
539 }
540
541 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception)
542 {
543    if(getNumberOfTuples()!=other.getNumberOfTuples())
544     {
545       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
546       throw INTERP_KERNEL::Exception(oss.str().c_str());
547     }
548   if(getNumberOfComponents()!=other.getNumberOfComponents())
549     {
550       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
551       throw INTERP_KERNEL::Exception(oss.str().c_str());
552     }
553 }
554
555 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
556 {
557   checkNbOfTuples(nbOfTuples,msg);
558   checkNbOfComps(nbOfCompo,msg);
559 }
560
561 /*!
562  * Simply this method checks that \b value is in [0,\b ref).
563  */
564 void DataArray::CheckValueInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
565 {
566   if(value<0 || value>=ref)
567     {
568       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
569       throw INTERP_KERNEL::Exception(oss.str().c_str());
570     }
571 }
572
573 /*!
574  * This method checks that [\b start, \b end) is compliant with ref length \b value.
575  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
576  */
577 void DataArray::CheckValueInRangeEx(int value, int start, int end, const char *msg) throw(INTERP_KERNEL::Exception)
578 {
579   if(start<0 || start>=value)
580     {
581       if(value!=start || end!=start)
582         {
583           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
584           throw INTERP_KERNEL::Exception(oss.str().c_str());
585         }
586     }
587   if(end<0 || end>value)
588     {
589       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
590       throw INTERP_KERNEL::Exception(oss.str().c_str());
591     }
592 }
593
594 void DataArray::CheckClosingParInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
595 {
596   if(value<0 || value>ref)
597     {
598       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
599       throw INTERP_KERNEL::Exception(oss.str().c_str());
600     }
601 }
602
603 /*!
604  * 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, 
605  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
606  *
607  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
608  *
609  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
610  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
611  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
612  * \param [in] sliceId - the slice id considered
613  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
614  * \param [out] startSlice - the start of the slice considered
615  * \param [out] stopSlice - the stop of the slice consided
616  * 
617  * \throw If \a step == 0
618  * \throw If \a nbOfSlices not > 0
619  * \throw If \a sliceId not in [0,nbOfSlices)
620  */
621 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice) throw(INTERP_KERNEL::Exception)
622 {
623   if(nbOfSlices<=0)
624     {
625       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
626       throw INTERP_KERNEL::Exception(oss.str().c_str());
627     }
628   if(sliceId<0 || sliceId>=nbOfSlices)
629     {
630       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
631       throw INTERP_KERNEL::Exception(oss.str().c_str());
632     }
633   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
634   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
635   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
636   if(sliceId<nbOfSlices-1)
637     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
638   else
639     stopSlice=stop;
640 }
641
642 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
643 {
644   if(end<begin)
645     {
646       std::ostringstream oss; oss << msg << " : end before begin !";
647       throw INTERP_KERNEL::Exception(oss.str().c_str());
648     }
649   if(end==begin)
650     return 0;
651   if(step<=0)
652     {
653       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
654       throw INTERP_KERNEL::Exception(oss.str().c_str());
655     }
656   return (end-1-begin)/step+1;
657 }
658
659 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
660 {
661   if(step==0)
662     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
663   if(end<begin && step>0)
664     {
665       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
666       throw INTERP_KERNEL::Exception(oss.str().c_str());
667     }
668   if(begin<end && step<0)
669     {
670       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
671       throw INTERP_KERNEL::Exception(oss.str().c_str());
672     }
673   if(begin!=end)
674     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
675   else
676     return 0;
677 }
678
679 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) throw(INTERP_KERNEL::Exception)
680 {
681   if(step!=0)
682     {
683       if(step>0)
684         {
685           if(begin<=value && value<end)
686             {
687               if((value-begin)%step==0)
688                 return (value-begin)/step;
689               else
690                 return -1;
691             }
692           else
693             return -1;
694         }
695       else
696         {
697           if(begin>=value && value>end)
698             {
699               if((begin-value)%(-step)==0)
700                 return (begin-value)/(-step);
701               else
702                 return -1;
703             }
704           else
705             return -1;
706         }
707     }
708   else
709     return -1;
710 }
711
712 /*!
713  * Returns a new instance of DataArrayDouble. The caller is to delete this array
714  * using decrRef() as it is no more needed. 
715  */
716 DataArrayDouble *DataArrayDouble::New()
717 {
718   return new DataArrayDouble;
719 }
720
721 /*!
722  * Checks if raw data is allocated. Read more on the raw data
723  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
724  *  \return bool - \a true if the raw data is allocated, \a false else.
725  */
726 bool DataArrayDouble::isAllocated() const throw(INTERP_KERNEL::Exception)
727 {
728   return getConstPointer()!=0;
729 }
730
731 /*!
732  * Checks if raw data is allocated and throws an exception if it is not the case.
733  *  \throw If the raw data is not allocated.
734  */
735 void DataArrayDouble::checkAllocated() const throw(INTERP_KERNEL::Exception)
736 {
737   if(!isAllocated())
738     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
739 }
740
741 /*!
742  * This method desallocated \a this without modification of informations relative to the components.
743  * After call of this method, DataArrayDouble::isAllocated will return false.
744  * If \a this is already not allocated, \a this is let unchanged.
745  */
746 void DataArrayDouble::desallocate() throw(INTERP_KERNEL::Exception)
747 {
748   _mem.destroy();
749 }
750
751 std::size_t DataArrayDouble::getHeapMemorySize() const
752 {
753   std::size_t sz=_mem.getNbOfElemAllocated();
754   sz*=sizeof(double);
755   return DataArray::getHeapMemorySize()+sz;
756 }
757
758 /*!
759  * Returns the only one value in \a this, if and only if number of elements
760  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
761  *  \return double - the sole value stored in \a this array.
762  *  \throw If at least one of conditions stated above is not fulfilled.
763  */
764 double DataArrayDouble::doubleValue() const throw(INTERP_KERNEL::Exception)
765 {
766   if(isAllocated())
767     {
768       if(getNbOfElems()==1)
769         {
770           return *getConstPointer();
771         }
772       else
773         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
774     }
775   else
776     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
777 }
778
779 /*!
780  * Checks the number of tuples.
781  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
782  *  \throw If \a this is not allocated.
783  */
784 bool DataArrayDouble::empty() const throw(INTERP_KERNEL::Exception)
785 {
786   checkAllocated();
787   return getNumberOfTuples()==0;
788 }
789
790 /*!
791  * Returns a full copy of \a this. For more info on copying data arrays see
792  * \ref MEDCouplingArrayBasicsCopyDeep.
793  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
794  *          delete this array using decrRef() as it is no more needed. 
795  */
796 DataArrayDouble *DataArrayDouble::deepCpy() const throw(INTERP_KERNEL::Exception)
797 {
798   return new DataArrayDouble(*this);
799 }
800
801 /*!
802  * Returns either a \a deep or \a shallow copy of this array. For more info see
803  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
804  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
805  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
806  *          == \a true) or \a this instance (if \a dCpy == \a false).
807  */
808 DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
809 {
810   if(dCpy)
811     return deepCpy();
812   else
813     {
814       incrRef();
815       return const_cast<DataArrayDouble *>(this);
816     }
817 }
818
819 /*!
820  * Copies all the data from another DataArrayDouble. For more info see
821  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
822  *  \param [in] other - another instance of DataArrayDouble to copy data from.
823  *  \throw If the \a other is not allocated.
824  */
825 void DataArrayDouble::cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL::Exception)
826 {
827   other.checkAllocated();
828   int nbOfTuples=other.getNumberOfTuples();
829   int nbOfComp=other.getNumberOfComponents();
830   allocIfNecessary(nbOfTuples,nbOfComp);
831   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
832   double *pt=getPointer();
833   const double *ptI=other.getConstPointer();
834   for(std::size_t i=0;i<nbOfElems;i++)
835     pt[i]=ptI[i];
836   copyStringInfoFrom(other);
837 }
838
839 /*!
840  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
841  * 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.
842  * If \a this has not already been allocated, number of components is set to one.
843  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
844  * 
845  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
846  */
847 void DataArrayDouble::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
848 {
849   int nbCompo=getNumberOfComponents();
850   if(nbCompo==1)
851     {
852       _mem.reserve(nbOfElems);
853     }
854   else if(nbCompo==0)
855     {
856       _mem.reserve(nbOfElems);
857       _info_on_compo.resize(1);
858     }
859   else
860     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
861 }
862
863 /*!
864  * 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
865  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
866  *
867  * \param [in] val the value to be added in \a this
868  * \throw If \a this has already been allocated with number of components different from one.
869  * \sa DataArrayDouble::pushBackValsSilent
870  */
871 void DataArrayDouble::pushBackSilent(double val) throw(INTERP_KERNEL::Exception)
872 {
873   int nbCompo=getNumberOfComponents();
874   if(nbCompo==1)
875     _mem.pushBack(val);
876   else if(nbCompo==0)
877     {
878       _info_on_compo.resize(1);
879       _mem.pushBack(val);
880     }
881   else
882     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
883 }
884
885 /*!
886  * 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
887  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
888  *
889  *  \param [in] valsBg - an array of values to push at the end of \this.
890  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
891  *              the last value of \a valsBg is \a valsEnd[ -1 ].
892  * \throw If \a this has already been allocated with number of components different from one.
893  * \sa DataArrayDouble::pushBackSilent
894  */
895 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd) throw(INTERP_KERNEL::Exception)
896 {
897   int nbCompo=getNumberOfComponents();
898   if(nbCompo==1)
899     _mem.insertAtTheEnd(valsBg,valsEnd);
900   else if(nbCompo==0)
901     {
902       _info_on_compo.resize(1);
903       _mem.insertAtTheEnd(valsBg,valsEnd);
904     }
905   else
906     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
907 }
908
909 /*!
910  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
911  * \throw If \a this is already empty.
912  * \throw If \a this has number of components different from one.
913  */
914 double DataArrayDouble::popBackSilent() throw(INTERP_KERNEL::Exception)
915 {
916   if(getNumberOfComponents()==1)
917     return _mem.popBack();
918   else
919     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
920 }
921
922 /*!
923  * 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.
924  *
925  * \sa DataArrayDouble::getHeapMemorySize, DataArrayDouble::reserve
926  */
927 void DataArrayDouble::pack() const throw(INTERP_KERNEL::Exception)
928 {
929   _mem.pack();
930 }
931
932 /*!
933  * Allocates the raw data in memory. If exactly same memory as needed already
934  * allocated, it is not re-allocated.
935  *  \param [in] nbOfTuple - number of tuples of data to allocate.
936  *  \param [in] nbOfCompo - number of components of data to allocate.
937  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
938  */
939 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
940 {
941   if(isAllocated())
942     {
943       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
944         alloc(nbOfTuple,nbOfCompo);
945     }
946   else
947     alloc(nbOfTuple,nbOfCompo);
948 }
949
950 /*!
951  * Allocates the raw data in memory. If the memory was already allocated, then it is
952  * freed and re-allocated. See an example of this method use
953  * \ref MEDCouplingArraySteps1WC "here".
954  *  \param [in] nbOfTuple - number of tuples of data to allocate.
955  *  \param [in] nbOfCompo - number of components of data to allocate.
956  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
957  */
958 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
959 {
960   if(nbOfTuple<0 || nbOfCompo<0)
961     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
962   _info_on_compo.resize(nbOfCompo);
963   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
964   declareAsNew();
965 }
966
967 /*!
968  * Assign zero to all values in \a this array. To know more on filling arrays see
969  * \ref MEDCouplingArrayFill.
970  * \throw If \a this is not allocated.
971  */
972 void DataArrayDouble::fillWithZero() throw(INTERP_KERNEL::Exception)
973 {
974   checkAllocated();
975   _mem.fillWithValue(0.);
976   declareAsNew();
977 }
978
979 /*!
980  * Assign \a val to all values in \a this array. To know more on filling arrays see
981  * \ref MEDCouplingArrayFill.
982  *  \param [in] val - the value to fill with.
983  *  \throw If \a this is not allocated.
984  */
985 void DataArrayDouble::fillWithValue(double val) throw(INTERP_KERNEL::Exception)
986 {
987   checkAllocated();
988   _mem.fillWithValue(val);
989   declareAsNew();
990 }
991
992 /*!
993  * Set all values in \a this array so that the i-th element equals to \a init + i
994  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
995  *  \param [in] init - value to assign to the first element of array.
996  *  \throw If \a this->getNumberOfComponents() != 1
997  *  \throw If \a this is not allocated.
998  */
999 void DataArrayDouble::iota(double init) throw(INTERP_KERNEL::Exception)
1000 {
1001   checkAllocated();
1002   if(getNumberOfComponents()!=1)
1003     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
1004   double *ptr=getPointer();
1005   int ntuples=getNumberOfTuples();
1006   for(int i=0;i<ntuples;i++)
1007     ptr[i]=init+double(i);
1008   declareAsNew();
1009 }
1010
1011 /*!
1012  * Checks if all values in \a this array are equal to \a val at precision \a eps.
1013  *  \param [in] val - value to check equality of array values to.
1014  *  \param [in] eps - precision to check the equality.
1015  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
1016  *                 \a false else.
1017  *  \throw If \a this->getNumberOfComponents() != 1
1018  *  \throw If \a this is not allocated.
1019  */
1020 bool DataArrayDouble::isUniform(double val, double eps) const throw(INTERP_KERNEL::Exception)
1021 {
1022   checkAllocated();
1023   if(getNumberOfComponents()!=1)
1024     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1025   int nbOfTuples=getNumberOfTuples();
1026   const double *w=getConstPointer();
1027   const double *end2=w+nbOfTuples;
1028   const double vmin=val-eps;
1029   const double vmax=val+eps;
1030   for(;w!=end2;w++)
1031     if(*w<vmin || *w>vmax)
1032       return false;
1033   return true;
1034 }
1035
1036 /*!
1037  * Sorts values of the array.
1038  *  \param [in] asc - \a true means ascending order, \a false, descending.
1039  *  \throw If \a this is not allocated.
1040  *  \throw If \a this->getNumberOfComponents() != 1.
1041  */
1042 void DataArrayDouble::sort(bool asc) throw(INTERP_KERNEL::Exception)
1043 {
1044   checkAllocated();
1045   if(getNumberOfComponents()!=1)
1046     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
1047   _mem.sort(asc);
1048   declareAsNew();
1049 }
1050
1051 /*!
1052  * Reverse the array values.
1053  *  \throw If \a this->getNumberOfComponents() < 1.
1054  *  \throw If \a this is not allocated.
1055  */
1056 void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception)
1057 {
1058   checkAllocated();
1059   _mem.reverse(getNumberOfComponents());
1060   declareAsNew();
1061 }
1062
1063 /*!
1064  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1065  * with at least absolute difference value of |\a eps| at each step.
1066  * If not an exception is thrown.
1067  *  \param [in] increasing - if \a true, the array values should be increasing.
1068  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1069  *                    the values are considered different.
1070  *  \throw If sequence of values is not strictly monotonic in agreement with \a
1071  *         increasing arg.
1072  *  \throw If \a this->getNumberOfComponents() != 1.
1073  *  \throw If \a this is not allocated.
1074  */
1075 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
1076 {
1077   if(!isMonotonic(increasing,eps))
1078     {
1079       if (increasing)
1080         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
1081       else
1082         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
1083     }
1084 }
1085
1086 /*!
1087  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1088  * with at least absolute difference value of |\a eps| at each step.
1089  *  \param [in] increasing - if \a true, array values should be increasing.
1090  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1091  *                    the values are considered different.
1092  *  \return bool - \a true if values change in accordance with \a increasing arg.
1093  *  \throw If \a this->getNumberOfComponents() != 1.
1094  *  \throw If \a this is not allocated.
1095  */
1096 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
1097 {
1098   checkAllocated();
1099   if(getNumberOfComponents()!=1)
1100     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
1101   int nbOfElements=getNumberOfTuples();
1102   const double *ptr=getConstPointer();
1103   if(nbOfElements==0)
1104     return true;
1105   double ref=ptr[0];
1106   double absEps=fabs(eps);
1107   if(increasing)
1108     {
1109       for(int i=1;i<nbOfElements;i++)
1110         {
1111           if(ptr[i]<(ref+absEps))
1112             return false;
1113           ref=ptr[i];
1114         }
1115       return true;
1116     }
1117   else
1118     {
1119       for(int i=1;i<nbOfElements;i++)
1120         {
1121           if(ptr[i]>(ref-absEps))
1122             return false;
1123           ref=ptr[i];
1124         }
1125       return true;
1126     }
1127 }
1128
1129 /*!
1130  * Returns a textual and human readable representation of \a this instance of
1131  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
1132  *  \return std::string - text describing \a this DataArrayDouble.
1133  */
1134 std::string DataArrayDouble::repr() const throw(INTERP_KERNEL::Exception)
1135 {
1136   std::ostringstream ret;
1137   reprStream(ret);
1138   return ret.str();
1139 }
1140
1141 std::string DataArrayDouble::reprZip() const throw(INTERP_KERNEL::Exception)
1142 {
1143   std::ostringstream ret;
1144   reprZipStream(ret);
1145   return ret.str();
1146 }
1147
1148 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char *nameInFile, DataArrayByte *byteArr) const throw(INTERP_KERNEL::Exception)
1149 {
1150   static const char SPACE[4]={' ',' ',' ',' '};
1151   checkAllocated();
1152   std::string idt(indent,' ');
1153   ofs.precision(17);
1154   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1155   if(byteArr)
1156     {
1157       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
1158       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
1159       std::copy(begin(),end(),(float *)tmp);
1160       const char *data(reinterpret_cast<const char *>((float *)tmp));
1161       std::size_t sz(getNbOfElems()*sizeof(float));
1162       byteArr->insertAtTheEnd(data,data+sz);
1163       byteArr->insertAtTheEnd(SPACE,SPACE+4);
1164     }
1165   else
1166     {
1167       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
1168       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1169     }
1170   ofs << std::endl << idt << "</DataArray>\n";
1171 }
1172
1173 void DataArrayDouble::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1174 {
1175   stream << "Name of double array : \"" << _name << "\"\n";
1176   reprWithoutNameStream(stream);
1177 }
1178
1179 void DataArrayDouble::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1180 {
1181   stream << "Name of double array : \"" << _name << "\"\n";
1182   reprZipWithoutNameStream(stream);
1183 }
1184
1185 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1186 {
1187   DataArray::reprWithoutNameStream(stream);
1188   stream.precision(17);
1189   _mem.repr(getNumberOfComponents(),stream);
1190 }
1191
1192 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1193 {
1194   DataArray::reprWithoutNameStream(stream);
1195   stream.precision(17);
1196   _mem.reprZip(getNumberOfComponents(),stream);
1197 }
1198
1199 void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1200 {
1201   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1202   const double *data=getConstPointer();
1203   stream.precision(17);
1204   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1205   if(nbTuples*nbComp>=1)
1206     {
1207       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1208       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1209       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1210       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1211     }
1212   else
1213     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1214   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1215 }
1216
1217 /*!
1218  * Method that gives a quick overvien of \a this for python.
1219  */
1220 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1221 {
1222   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1223   stream << "DataArrayDouble C++ instance at " << this << ". ";
1224   if(isAllocated())
1225     {
1226       int nbOfCompo=(int)_info_on_compo.size();
1227       if(nbOfCompo>=1)
1228         {
1229           int nbOfTuples=getNumberOfTuples();
1230           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1231           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1232         }
1233       else
1234         stream << "Number of components : 0.";
1235     }
1236   else
1237     stream << "*** No data allocated ****";
1238 }
1239
1240 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
1241 {
1242   const double *data=begin();
1243   int nbOfTuples=getNumberOfTuples();
1244   int nbOfCompo=(int)_info_on_compo.size();
1245   std::ostringstream oss2; oss2 << "[";
1246   oss2.precision(17);
1247   std::string oss2Str(oss2.str());
1248   bool isFinished=true;
1249   for(int i=0;i<nbOfTuples && isFinished;i++)
1250     {
1251       if(nbOfCompo>1)
1252         {
1253           oss2 << "(";
1254           for(int j=0;j<nbOfCompo;j++,data++)
1255             {
1256               oss2 << *data;
1257               if(j!=nbOfCompo-1) oss2 << ", ";
1258             }
1259           oss2 << ")";
1260         }
1261       else
1262         oss2 << *data++;
1263       if(i!=nbOfTuples-1) oss2 << ", ";
1264       std::string oss3Str(oss2.str());
1265       if(oss3Str.length()<maxNbOfByteInRepr)
1266         oss2Str=oss3Str;
1267       else
1268         isFinished=false;
1269     }
1270   stream << oss2Str;
1271   if(!isFinished)
1272     stream << "... ";
1273   stream << "]";
1274 }
1275
1276 /*!
1277  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1278  * mismatch is given.
1279  * 
1280  * \param [in] other the instance to be compared with \a this
1281  * \param [in] prec the precision to compare numeric data of the arrays.
1282  * \param [out] reason In case of inequality returns the reason.
1283  * \sa DataArrayDouble::isEqual
1284  */
1285 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1286 {
1287   if(!areInfoEqualsIfNotWhy(other,reason))
1288     return false;
1289   return _mem.isEqual(other._mem,prec,reason);
1290 }
1291
1292 /*!
1293  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1294  * \ref MEDCouplingArrayBasicsCompare.
1295  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1296  *  \param [in] prec - precision value to compare numeric data of the arrays.
1297  *  \return bool - \a true if the two arrays are equal, \a false else.
1298  */
1299 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1300 {
1301   std::string tmp;
1302   return isEqualIfNotWhy(other,prec,tmp);
1303 }
1304
1305 /*!
1306  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1307  * \ref MEDCouplingArrayBasicsCompare.
1308  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1309  *  \param [in] prec - precision value to compare numeric data of the arrays.
1310  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1311  */
1312 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1313 {
1314   std::string tmp;
1315   return _mem.isEqual(other._mem,prec,tmp);
1316 }
1317
1318 /*!
1319  * Changes number of tuples in the array. If the new number of tuples is smaller
1320  * than the current number the array is truncated, otherwise the array is extended.
1321  *  \param [in] nbOfTuples - new number of tuples. 
1322  *  \throw If \a this is not allocated.
1323  *  \throw If \a nbOfTuples is negative.
1324  */
1325 void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
1326 {
1327   if(nbOfTuples<0)
1328     throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
1329   checkAllocated();
1330   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1331   declareAsNew();
1332 }
1333
1334 /*!
1335  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1336  * array to the new one.
1337  *  \return DataArrayInt * - the new instance of DataArrayInt.
1338  */
1339 DataArrayInt *DataArrayDouble::convertToIntArr() const
1340 {
1341   DataArrayInt *ret=DataArrayInt::New();
1342   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1343   std::size_t nbOfVals=getNbOfElems();
1344   const double *src=getConstPointer();
1345   int *dest=ret->getPointer();
1346   std::copy(src,src+nbOfVals,dest);
1347   ret->copyStringInfoFrom(*this);
1348   return ret;
1349 }
1350
1351 /*!
1352  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1353  * arranged in memory. If \a this array holds 2 components of 3 values:
1354  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1355  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1356  *  \warning Do not confuse this method with transpose()!
1357  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1358  *          is to delete using decrRef() as it is no more needed.
1359  *  \throw If \a this is not allocated.
1360  */
1361 DataArrayDouble *DataArrayDouble::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
1362 {
1363   if(_mem.isNull())
1364     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1365   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1366   DataArrayDouble *ret=DataArrayDouble::New();
1367   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1368   return ret;
1369 }
1370
1371 /*!
1372  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1373  * arranged in memory. If \a this array holds 2 components of 3 values:
1374  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1375  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1376  *  \warning Do not confuse this method with transpose()!
1377  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1378  *          is to delete using decrRef() as it is no more needed.
1379  *  \throw If \a this is not allocated.
1380  */
1381 DataArrayDouble *DataArrayDouble::toNoInterlace() const throw(INTERP_KERNEL::Exception)
1382 {
1383   if(_mem.isNull())
1384     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1385   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1386   DataArrayDouble *ret=DataArrayDouble::New();
1387   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1388   return ret;
1389 }
1390
1391 /*!
1392  * Permutes values of \a this array as required by \a old2New array. The values are
1393  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1394  * the same as in \this one.
1395  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1396  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1397  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1398  *     giving a new position for i-th old value.
1399  */
1400 void DataArrayDouble::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
1401 {
1402   checkAllocated();
1403   int nbTuples=getNumberOfTuples();
1404   int nbOfCompo=getNumberOfComponents();
1405   double *tmp=new double[nbTuples*nbOfCompo];
1406   const double *iptr=getConstPointer();
1407   for(int i=0;i<nbTuples;i++)
1408     {
1409       int v=old2New[i];
1410       if(v>=0 && v<nbTuples)
1411         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1412       else
1413         {
1414           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1415           throw INTERP_KERNEL::Exception(oss.str().c_str());
1416         }
1417     }
1418   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1419   delete [] tmp;
1420   declareAsNew();
1421 }
1422
1423 /*!
1424  * Permutes values of \a this array as required by \a new2Old array. The values are
1425  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1426  * the same as in \this one.
1427  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1428  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1429  *     giving a previous position of i-th new value.
1430  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1431  *          is to delete using decrRef() as it is no more needed.
1432  */
1433 void DataArrayDouble::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
1434 {
1435   checkAllocated();
1436   int nbTuples=getNumberOfTuples();
1437   int nbOfCompo=getNumberOfComponents();
1438   double *tmp=new double[nbTuples*nbOfCompo];
1439   const double *iptr=getConstPointer();
1440   for(int i=0;i<nbTuples;i++)
1441     {
1442       int v=new2Old[i];
1443       if(v>=0 && v<nbTuples)
1444         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1445       else
1446         {
1447           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1448           throw INTERP_KERNEL::Exception(oss.str().c_str());
1449         }
1450     }
1451   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1452   delete [] tmp;
1453   declareAsNew();
1454 }
1455
1456 /*!
1457  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1458  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1459  * Number of tuples in the result array remains the same as in \this one.
1460  * If a permutation reduction is needed, renumberAndReduce() should be used.
1461  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1462  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1463  *          giving a new position for i-th old value.
1464  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1465  *          is to delete using decrRef() as it is no more needed.
1466  *  \throw If \a this is not allocated.
1467  */
1468 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
1469 {
1470   checkAllocated();
1471   int nbTuples=getNumberOfTuples();
1472   int nbOfCompo=getNumberOfComponents();
1473   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1474   ret->alloc(nbTuples,nbOfCompo);
1475   ret->copyStringInfoFrom(*this);
1476   const double *iptr=getConstPointer();
1477   double *optr=ret->getPointer();
1478   for(int i=0;i<nbTuples;i++)
1479     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1480   ret->copyStringInfoFrom(*this);
1481   return ret.retn();
1482 }
1483
1484 /*!
1485  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1486  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1487  * tuples in the result array remains the same as in \this one.
1488  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1489  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1490  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1491  *     giving a previous position of i-th new value.
1492  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1493  *          is to delete using decrRef() as it is no more needed.
1494  */
1495 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
1496 {
1497   checkAllocated();
1498   int nbTuples=getNumberOfTuples();
1499   int nbOfCompo=getNumberOfComponents();
1500   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1501   ret->alloc(nbTuples,nbOfCompo);
1502   ret->copyStringInfoFrom(*this);
1503   const double *iptr=getConstPointer();
1504   double *optr=ret->getPointer();
1505   for(int i=0;i<nbTuples;i++)
1506     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1507   ret->copyStringInfoFrom(*this);
1508   return ret.retn();
1509 }
1510
1511 /*!
1512  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1513  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1514  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1515  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1516  * \a old2New[ i ] is negative, is missing from the result array.
1517  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1518  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1519  *     giving a new position for i-th old tuple and giving negative position for
1520  *     for i-th old tuple that should be omitted.
1521  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1522  *          is to delete using decrRef() as it is no more needed.
1523  */
1524 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
1525 {
1526   checkAllocated();
1527   int nbTuples=getNumberOfTuples();
1528   int nbOfCompo=getNumberOfComponents();
1529   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1530   ret->alloc(newNbOfTuple,nbOfCompo);
1531   const double *iptr=getConstPointer();
1532   double *optr=ret->getPointer();
1533   for(int i=0;i<nbTuples;i++)
1534     {
1535       int w=old2New[i];
1536       if(w>=0)
1537         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1538     }
1539   ret->copyStringInfoFrom(*this);
1540   return ret.retn();
1541 }
1542
1543 /*!
1544  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1545  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1546  * \a new2OldBg array.
1547  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1548  * This method is equivalent to renumberAndReduce() except that convention in input is
1549  * \c new2old and \b not \c old2new.
1550  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1551  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1552  *              tuple index in \a this array to fill the i-th tuple in the new array.
1553  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1554  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1555  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1556  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1557  *          is to delete using decrRef() as it is no more needed.
1558  */
1559 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1560 {
1561   checkAllocated();
1562   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1563   int nbComp=getNumberOfComponents();
1564   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1565   ret->copyStringInfoFrom(*this);
1566   double *pt=ret->getPointer();
1567   const double *srcPt=getConstPointer();
1568   int i=0;
1569   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1570     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1571   ret->copyStringInfoFrom(*this);
1572   return ret.retn();
1573 }
1574
1575 /*!
1576  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1577  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1578  * \a new2OldBg array.
1579  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1580  * This method is equivalent to renumberAndReduce() except that convention in input is
1581  * \c new2old and \b not \c old2new.
1582  * This method is equivalent to selectByTupleId() except that it prevents coping data
1583  * from behind the end of \a this array.
1584  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1585  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1586  *              tuple index in \a this array to fill the i-th tuple in the new array.
1587  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1588  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1589  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1590  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1591  *          is to delete using decrRef() as it is no more needed.
1592  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1593  */
1594 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
1595 {
1596   checkAllocated();
1597   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1598   int nbComp=getNumberOfComponents();
1599   int oldNbOfTuples=getNumberOfTuples();
1600   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1601   ret->copyStringInfoFrom(*this);
1602   double *pt=ret->getPointer();
1603   const double *srcPt=getConstPointer();
1604   int i=0;
1605   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1606     if(*w>=0 && *w<oldNbOfTuples)
1607       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1608     else
1609       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1610   ret->copyStringInfoFrom(*this);
1611   return ret.retn();
1612 }
1613
1614 /*!
1615  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1616  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1617  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1618  * command \c range( \a bg, \a end2, \a step ).
1619  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1620  * not constructed explicitly.
1621  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1622  *  \param [in] bg - index of the first tuple to copy from \a this array.
1623  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1624  *  \param [in] step - index increment to get index of the next tuple to copy.
1625  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1626  *          is to delete using decrRef() as it is no more needed.
1627  *  \sa DataArrayDouble::substr.
1628  */
1629 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
1630 {
1631   checkAllocated();
1632   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1633   int nbComp=getNumberOfComponents();
1634   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1635   ret->alloc(newNbOfTuples,nbComp);
1636   double *pt=ret->getPointer();
1637   const double *srcPt=getConstPointer()+bg*nbComp;
1638   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1639     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1640   ret->copyStringInfoFrom(*this);
1641   return ret.retn();
1642 }
1643
1644 /*!
1645  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1646  * of tuples specified by \a ranges parameter.
1647  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1648  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1649  *              of tuples in [\c begin,\c end) format.
1650  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1651  *          is to delete using decrRef() as it is no more needed.
1652  *  \throw If \a end < \a begin.
1653  *  \throw If \a end > \a this->getNumberOfTuples().
1654  *  \throw If \a this is not allocated.
1655  */
1656 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
1657 {
1658   checkAllocated();
1659   int nbOfComp=getNumberOfComponents();
1660   int nbOfTuplesThis=getNumberOfTuples();
1661   if(ranges.empty())
1662     {
1663       DataArrayDouble *ret=DataArrayDouble::New();
1664       ret->alloc(0,nbOfComp);
1665       ret->copyStringInfoFrom(*this);
1666       return ret;
1667     }
1668   int ref=ranges.front().first;
1669   int nbOfTuples=0;
1670   bool isIncreasing=true;
1671   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1672     {
1673       if((*it).first<=(*it).second)
1674         {
1675           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1676             {
1677               nbOfTuples+=(*it).second-(*it).first;
1678               if(isIncreasing)
1679                 isIncreasing=ref<=(*it).first;
1680               ref=(*it).second;
1681             }
1682           else
1683             {
1684               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1685               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1686               throw INTERP_KERNEL::Exception(oss.str().c_str());
1687             }
1688         }
1689       else
1690         {
1691           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1692           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1693           throw INTERP_KERNEL::Exception(oss.str().c_str());
1694         }
1695     }
1696   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1697     return deepCpy();
1698   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1699   ret->alloc(nbOfTuples,nbOfComp);
1700   ret->copyStringInfoFrom(*this);
1701   const double *src=getConstPointer();
1702   double *work=ret->getPointer();
1703   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1704     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1705   return ret.retn();
1706 }
1707
1708 /*!
1709  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1710  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1711  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1712  * This method is a specialization of selectByTupleId2().
1713  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1714  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1715  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1716  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1717  *          is to delete using decrRef() as it is no more needed.
1718  *  \throw If \a tupleIdBg < 0.
1719  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1720     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1721  *  \sa DataArrayDouble::selectByTupleId2
1722  */
1723 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
1724 {
1725   checkAllocated();
1726   int nbt=getNumberOfTuples();
1727   if(tupleIdBg<0)
1728     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1729   if(tupleIdBg>nbt)
1730     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1731   int trueEnd=tupleIdEnd;
1732   if(tupleIdEnd!=-1)
1733     {
1734       if(tupleIdEnd>nbt)
1735         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1736     }
1737   else
1738     trueEnd=nbt;
1739   int nbComp=getNumberOfComponents();
1740   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1741   ret->alloc(trueEnd-tupleIdBg,nbComp);
1742   ret->copyStringInfoFrom(*this);
1743   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1744   return ret.retn();
1745 }
1746
1747 /*!
1748  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1749  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1750  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1751  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1752  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1753  * components.  
1754  *  \param [in] newNbOfComp - number of components for the new array to have.
1755  *  \param [in] dftValue - value assigned to new values added to the new array.
1756  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1757  *          is to delete using decrRef() as it is no more needed.
1758  *  \throw If \a this is not allocated.
1759  */
1760 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception)
1761 {
1762   checkAllocated();
1763   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1764   ret->alloc(getNumberOfTuples(),newNbOfComp);
1765   const double *oldc=getConstPointer();
1766   double *nc=ret->getPointer();
1767   int nbOfTuples=getNumberOfTuples();
1768   int oldNbOfComp=getNumberOfComponents();
1769   int dim=std::min(oldNbOfComp,newNbOfComp);
1770   for(int i=0;i<nbOfTuples;i++)
1771     {
1772       int j=0;
1773       for(;j<dim;j++)
1774         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1775       for(;j<newNbOfComp;j++)
1776         nc[newNbOfComp*i+j]=dftValue;
1777     }
1778   ret->setName(getName().c_str());
1779   for(int i=0;i<dim;i++)
1780     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
1781   ret->setName(getName().c_str());
1782   return ret.retn();
1783 }
1784
1785 /*!
1786  * Changes the number of components within \a this array so that its raw data **does
1787  * not** change, instead splitting this data into tuples changes.
1788  *  \warning This method erases all (name and unit) component info set before!
1789  *  \param [in] newNbOfComp - number of components for \a this array to have.
1790  *  \throw If \a this is not allocated
1791  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1792  *  \throw If \a newNbOfCompo is lower than 1.
1793  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1794  *  \warning This method erases all (name and unit) component info set before!
1795  */
1796 void DataArrayDouble::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
1797 {
1798   checkAllocated();
1799   if(newNbOfCompo<1)
1800     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1801   std::size_t nbOfElems=getNbOfElems();
1802   if(nbOfElems%newNbOfCompo!=0)
1803     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1804   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1805     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1806   _info_on_compo.clear();
1807   _info_on_compo.resize(newNbOfCompo);
1808   declareAsNew();
1809 }
1810
1811 /*!
1812  * Changes the number of components within \a this array to be equal to its number
1813  * of tuples, and inversely its number of tuples to become equal to its number of 
1814  * components. So that its raw data **does not** change, instead splitting this
1815  * data into tuples changes.
1816  *  \warning This method erases all (name and unit) component info set before!
1817  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1818  *  \throw If \a this is not allocated.
1819  *  \sa rearrange()
1820  */
1821 void DataArrayDouble::transpose() throw(INTERP_KERNEL::Exception)
1822 {
1823   checkAllocated();
1824   int nbOfTuples=getNumberOfTuples();
1825   rearrange(nbOfTuples);
1826 }
1827
1828 /*!
1829  * Returns a copy of \a this array composed of selected components.
1830  * The new DataArrayDouble has the same number of tuples but includes components
1831  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1832  * can be either less, same or more than \a this->getNbOfElems().
1833  *  \param [in] compoIds - sequence of zero based indices of components to include
1834  *              into the new array.
1835  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1836  *          is to delete using decrRef() as it is no more needed.
1837  *  \throw If \a this is not allocated.
1838  *  \throw If a component index (\a i) is not valid: 
1839  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1840  *
1841  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1842  */
1843 DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
1844 {
1845   checkAllocated();
1846   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1847   std::size_t newNbOfCompo=compoIds.size();
1848   int oldNbOfCompo=getNumberOfComponents();
1849   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1850     if((*it)<0 || (*it)>=oldNbOfCompo)
1851       {
1852         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1853         throw INTERP_KERNEL::Exception(oss.str().c_str());
1854       }
1855   int nbOfTuples=getNumberOfTuples();
1856   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1857   ret->copyPartOfStringInfoFrom(*this,compoIds);
1858   const double *oldc=getConstPointer();
1859   double *nc=ret->getPointer();
1860   for(int i=0;i<nbOfTuples;i++)
1861     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1862       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1863   return ret.retn();
1864 }
1865
1866 /*!
1867  * Appends components of another array to components of \a this one, tuple by tuple.
1868  * So that the number of tuples of \a this array remains the same and the number of 
1869  * components increases.
1870  *  \param [in] other - the DataArrayDouble to append to \a this one.
1871  *  \throw If \a this is not allocated.
1872  *  \throw If \a this and \a other arrays have different number of tuples.
1873  *
1874  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1875  *
1876  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1877  */
1878 void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
1879 {
1880   checkAllocated();
1881   other->checkAllocated();
1882   int nbOfTuples=getNumberOfTuples();
1883   if(nbOfTuples!=other->getNumberOfTuples())
1884     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1885   int nbOfComp1=getNumberOfComponents();
1886   int nbOfComp2=other->getNumberOfComponents();
1887   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1888   double *w=newArr;
1889   const double *inp1=getConstPointer();
1890   const double *inp2=other->getConstPointer();
1891   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1892     {
1893       w=std::copy(inp1,inp1+nbOfComp1,w);
1894       w=std::copy(inp2,inp2+nbOfComp2,w);
1895     }
1896   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1897   std::vector<int> compIds(nbOfComp2);
1898   for(int i=0;i<nbOfComp2;i++)
1899     compIds[i]=nbOfComp1+i;
1900   copyPartOfStringInfoFrom2(compIds,*other);
1901 }
1902
1903 /*!
1904  * This method checks that all tuples in \a other are in \a this.
1905  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1906  * 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.
1907  *
1908  * \param [in] other - the array having the same number of components than \a this.
1909  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1910  * \sa DataArrayDouble::findCommonTuples
1911  */
1912 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const throw(INTERP_KERNEL::Exception)
1913 {
1914   if(!other)
1915     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1916   checkAllocated(); other->checkAllocated();
1917   if(getNumberOfComponents()!=other->getNumberOfComponents())
1918     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1919   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1920   DataArrayInt *c=0,*ci=0;
1921   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1922   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1923   int newNbOfTuples=-1;
1924   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1925   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1926   tupleIds=ret1.retn();
1927   return newNbOfTuples==getNumberOfTuples();
1928 }
1929
1930 /*!
1931  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1932  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1933  * distance separating two points is computed with the infinite norm.
1934  *
1935  * Indices of coincident tuples are stored in output arrays.
1936  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1937  *
1938  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1939  * MEDCouplingUMesh::mergeNodes().
1940  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1941  *              considered not coincident.
1942  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1943  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1944  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1945  *               \a comm->getNumberOfComponents() == 1. 
1946  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1947  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1948  *               groups of (indices of) coincident tuples. Its every value is a tuple
1949  *               index where a next group of tuples begins. For example the second
1950  *               group of tuples in \a comm is described by following range of indices:
1951  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1952  *               gives the number of groups of coincident tuples.
1953  *  \throw If \a this is not allocated.
1954  *  \throw If the number of components is not in [1,2,3].
1955  *
1956  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1957  *
1958  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1959  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
1960  */
1961 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception)
1962 {
1963   checkAllocated();
1964   int nbOfCompo=getNumberOfComponents();
1965   if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work
1966     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
1967   
1968   int nbOfTuples=getNumberOfTuples();
1969   //
1970   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1971   switch(nbOfCompo)
1972     {
1973     case 3:
1974       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1975       break;
1976     case 2:
1977       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1978       break;
1979     case 1:
1980       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1981       break;
1982     default:
1983       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
1984     }
1985   comm=c.retn();
1986   commIndex=cI.retn();
1987 }
1988
1989 /*!
1990  * 
1991  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1992  *             \a nbTimes  should be at least equal to 1.
1993  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1994  * \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.
1995  */
1996 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
1997 {
1998   checkAllocated();
1999   if(getNumberOfComponents()!=1)
2000     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
2001   if(nbTimes<1)
2002     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
2003   int nbTuples=getNumberOfTuples();
2004   const double *inPtr=getConstPointer();
2005   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
2006   double *retPtr=ret->getPointer();
2007   for(int i=0;i<nbTuples;i++,inPtr++)
2008     {
2009       double val=*inPtr;
2010       for(int j=0;j<nbTimes;j++,retPtr++)
2011         *retPtr=val;
2012     }
2013   ret->copyStringInfoFrom(*this);
2014   return ret.retn();
2015 }
2016
2017 /*!
2018  * This methods returns the minimal distance between the two set of points \a this and \a other.
2019  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2020  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2021  *
2022  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2023  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2024  * \return the minimal distance between the two set of points \a this and \a other.
2025  * \sa DataArrayDouble::findClosestTupleId
2026  */
2027 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const throw(INTERP_KERNEL::Exception)
2028 {
2029   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
2030   int nbOfCompo(getNumberOfComponents());
2031   int otherNbTuples(other->getNumberOfTuples());
2032   const double *thisPt(begin()),*otherPt(other->begin());
2033   const int *part1Pt(part1->begin());
2034   double ret=std::numeric_limits<double>::max();
2035   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2036     {
2037       double tmp(0.);
2038       for(int j=0;j<nbOfCompo;j++)
2039         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2040       if(tmp<ret)
2041         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2042     }
2043   return sqrt(ret);
2044 }
2045
2046 /*!
2047  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2048  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2049  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2050  *
2051  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2052  * \sa DataArrayDouble::minimalDistanceTo
2053  */
2054 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
2055 {
2056   if(!other)
2057     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2058   checkAllocated(); other->checkAllocated();
2059   int nbOfCompo=getNumberOfComponents();
2060   if(nbOfCompo!=other->getNumberOfComponents())
2061     {
2062       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2063       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2064       throw INTERP_KERNEL::Exception(oss.str().c_str());
2065     }
2066   int nbOfTuples=other->getNumberOfTuples();
2067   int thisNbOfTuples=getNumberOfTuples();
2068   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2069   double bounds[6];
2070   getMinMaxPerComponent(bounds);
2071   switch(nbOfCompo)
2072     {
2073     case 3:
2074       {
2075         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2076         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2077         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2078         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2079         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2080         break;
2081       }
2082     case 2:
2083       {
2084         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2085         double delta=std::max(xDelta,yDelta);
2086         double characSize=sqrt(delta/(double)thisNbOfTuples);
2087         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2088         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2089         break;
2090       }
2091     case 1:
2092       {
2093         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2094         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2095         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2096         break;
2097       }
2098     default:
2099       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2100     }
2101   return ret.retn();
2102 }
2103
2104 /*!
2105  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
2106  * 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
2107  * how many bounding boxes in \a otherBBoxFrmt.
2108  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
2109  *
2110  * \param [in] otherBBoxFrmt - It is an array .
2111  * \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.
2112  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
2113  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
2114  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
2115  */
2116 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const throw(INTERP_KERNEL::Exception)
2117 {
2118   if(!otherBBoxFrmt)
2119     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
2120   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
2121     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
2122   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
2123   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
2124     {
2125       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
2126       throw INTERP_KERNEL::Exception(oss.str().c_str());
2127     }
2128   if(nbOfComp%2!=0)
2129     {
2130       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
2131       throw INTERP_KERNEL::Exception(oss.str().c_str());
2132     }
2133   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
2134   const double *thisBBPtr(begin());
2135   int *retPtr(ret->getPointer());
2136   switch(nbOfComp/2)
2137     {
2138     case 3:
2139       {
2140         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2141         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2142           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2143         break;
2144       }
2145     case 2:
2146       {
2147         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2148         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2149           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2150         break;
2151       }
2152     case 1:
2153       {
2154         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2155         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2156           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2157         break;
2158       }
2159     defaut:
2160       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
2161     }
2162   
2163   return ret.retn();
2164 }
2165
2166 /*!
2167  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2168  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2169  * space. The distance between tuples is computed using norm2. If several tuples are
2170  * not far each from other than \a prec, only one of them remains in the result
2171  * array. The order of tuples in the result array is same as in \a this one except
2172  * that coincident tuples are excluded.
2173  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2174  *              considered not coincident.
2175  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2176  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2177  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2178  *          is to delete using decrRef() as it is no more needed.
2179  *  \throw If \a this is not allocated.
2180  *  \throw If the number of components is not in [1,2,3].
2181  *
2182  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2183  */
2184 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception)
2185 {
2186   checkAllocated();
2187   DataArrayInt *c0=0,*cI0=0;
2188   findCommonTuples(prec,limitTupleId,c0,cI0);
2189   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2190   int newNbOfTuples=-1;
2191   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2192   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2193 }
2194
2195 /*!
2196  * Copy all components in a specified order from another DataArrayDouble.
2197  * Both numerical and textual data is copied. The number of tuples in \a this and
2198  * the other array can be different.
2199  *  \param [in] a - the array to copy data from.
2200  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2201  *              to be copied.
2202  *  \throw If \a a is NULL.
2203  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2204  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2205  *
2206  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2207  */
2208 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
2209 {
2210   if(!a)
2211     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2212   checkAllocated();
2213   copyPartOfStringInfoFrom2(compoIds,*a);
2214   std::size_t partOfCompoSz=compoIds.size();
2215   int nbOfCompo=getNumberOfComponents();
2216   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2217   const double *ac=a->getConstPointer();
2218   double *nc=getPointer();
2219   for(int i=0;i<nbOfTuples;i++)
2220     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2221       nc[nbOfCompo*i+compoIds[j]]=*ac;
2222 }
2223
2224 /*!
2225  * Copy all values from another DataArrayDouble into specified tuples and components
2226  * of \a this array. Textual data is not copied.
2227  * The tree parameters defining set of indices of tuples and components are similar to
2228  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2229  *  \param [in] a - the array to copy values from.
2230  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2231  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2232  *              are located.
2233  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2234  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2235  *  \param [in] endComp - index of the component before which the components to assign
2236  *              to are located.
2237  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2238  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2239  *              must be equal to the number of columns to assign to, else an
2240  *              exception is thrown; if \a false, then it is only required that \a
2241  *              a->getNbOfElems() equals to number of values to assign to (this condition
2242  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2243  *              values to assign to is given by following Python expression:
2244  *              \a nbTargetValues = 
2245  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2246  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2247  *  \throw If \a a is NULL.
2248  *  \throw If \a a is not allocated.
2249  *  \throw If \a this is not allocated.
2250  *  \throw If parameters specifying tuples and components to assign to do not give a
2251  *            non-empty range of increasing indices.
2252  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2253  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2254  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2255  *
2256  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2257  */
2258 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2259 {
2260   if(!a)
2261     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2262   const char msg[]="DataArrayDouble::setPartOfValues1";
2263   checkAllocated();
2264   a->checkAllocated();
2265   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2266   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2267   int nbComp=getNumberOfComponents();
2268   int nbOfTuples=getNumberOfTuples();
2269   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2270   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2271   bool assignTech=true;
2272   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2273     {
2274       if(strictCompoCompare)
2275         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2276     }
2277   else
2278     {
2279       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2280       assignTech=false;
2281     }
2282   const double *srcPt=a->getConstPointer();
2283   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2284   if(assignTech)
2285     {
2286       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2287         for(int j=0;j<newNbOfComp;j++,srcPt++)
2288           pt[j*stepComp]=*srcPt;
2289     }
2290   else
2291     {
2292       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2293         {
2294           const double *srcPt2=srcPt;
2295           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2296             pt[j*stepComp]=*srcPt2;
2297         }
2298     }
2299 }
2300
2301 /*!
2302  * Assign a given value to values at specified tuples and components of \a this array.
2303  * The tree parameters defining set of indices of tuples and components are similar to
2304  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2305  *  \param [in] a - the value to assign.
2306  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2307  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2308  *              are located.
2309  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2310  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2311  *  \param [in] endComp - index of the component before which the components to assign
2312  *              to are located.
2313  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2314  *  \throw If \a this is not allocated.
2315  *  \throw If parameters specifying tuples and components to assign to, do not give a
2316  *            non-empty range of increasing indices or indices are out of a valid range
2317  *            for \this array.
2318  *
2319  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2320  */
2321 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2322 {
2323   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2324   checkAllocated();
2325   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2326   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2327   int nbComp=getNumberOfComponents();
2328   int nbOfTuples=getNumberOfTuples();
2329   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2330   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2331   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2332   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2333     for(int j=0;j<newNbOfComp;j++)
2334       pt[j*stepComp]=a;
2335 }
2336
2337 /*!
2338  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2339  * components of \a this array. Textual data is not copied.
2340  * The tuples and components to assign to are defined by C arrays of indices.
2341  * There are two *modes of usage*:
2342  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2343  *   of \a a is assigned to its own location within \a this array. 
2344  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2345  *   components of every specified tuple of \a this array. In this mode it is required
2346  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2347  *
2348  *  \param [in] a - the array to copy values from.
2349  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2350  *              assign values of \a a to.
2351  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2352  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2353  *              \a bgTuples <= \a pi < \a endTuples.
2354  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2355  *              assign values of \a a to.
2356  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2357  *              pointer to a component index <em>(pi)</em> varies as this: 
2358  *              \a bgComp <= \a pi < \a endComp.
2359  *  \param [in] strictCompoCompare - this parameter is checked only if the
2360  *               *mode of usage* is the first; if it is \a true (default), 
2361  *               then \a a->getNumberOfComponents() must be equal 
2362  *               to the number of specified columns, else this is not required.
2363  *  \throw If \a a is NULL.
2364  *  \throw If \a a is not allocated.
2365  *  \throw If \a this is not allocated.
2366  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2367  *         out of a valid range for \a this array.
2368  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2369  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2370  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2371  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2372  *
2373  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2374  */
2375 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2376 {
2377   if(!a)
2378     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2379   const char msg[]="DataArrayDouble::setPartOfValues2";
2380   checkAllocated();
2381   a->checkAllocated();
2382   int nbComp=getNumberOfComponents();
2383   int nbOfTuples=getNumberOfTuples();
2384   for(const int *z=bgComp;z!=endComp;z++)
2385     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2386   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2387   int newNbOfComp=(int)std::distance(bgComp,endComp);
2388   bool assignTech=true;
2389   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2390     {
2391       if(strictCompoCompare)
2392         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2393     }
2394   else
2395     {
2396       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2397       assignTech=false;
2398     }
2399   double *pt=getPointer();
2400   const double *srcPt=a->getConstPointer();
2401   if(assignTech)
2402     {    
2403       for(const int *w=bgTuples;w!=endTuples;w++)
2404         {
2405           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2406           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2407             {    
2408               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2409             }
2410         }
2411     }
2412   else
2413     {
2414       for(const int *w=bgTuples;w!=endTuples;w++)
2415         {
2416           const double *srcPt2=srcPt;
2417           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2418           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2419             {    
2420               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2421             }
2422         }
2423     }
2424 }
2425
2426 /*!
2427  * Assign a given value to values at specified tuples and components of \a this array.
2428  * The tuples and components to assign to are defined by C arrays of indices.
2429  *  \param [in] a - the value to assign.
2430  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2431  *              assign \a a to.
2432  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2433  *              pointer to a tuple index (\a pi) varies as this: 
2434  *              \a bgTuples <= \a pi < \a endTuples.
2435  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2436  *              assign \a a to.
2437  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2438  *              pointer to a component index (\a pi) varies as this: 
2439  *              \a bgComp <= \a pi < \a endComp.
2440  *  \throw If \a this is not allocated.
2441  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2442  *         out of a valid range for \a this array.
2443  *
2444  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2445  */
2446 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2447 {
2448   checkAllocated();
2449   int nbComp=getNumberOfComponents();
2450   int nbOfTuples=getNumberOfTuples();
2451   for(const int *z=bgComp;z!=endComp;z++)
2452     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2453   double *pt=getPointer();
2454   for(const int *w=bgTuples;w!=endTuples;w++)
2455     for(const int *z=bgComp;z!=endComp;z++)
2456       {
2457         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2458         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2459       }
2460 }
2461
2462 /*!
2463  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2464  * components of \a this array. Textual data is not copied.
2465  * The tuples to assign to are defined by a C array of indices.
2466  * The components to assign to are defined by three values similar to parameters of
2467  * the Python function \c range(\c start,\c stop,\c step).
2468  * There are two *modes of usage*:
2469  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2470  *   of \a a is assigned to its own location within \a this array. 
2471  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2472  *   components of every specified tuple of \a this array. In this mode it is required
2473  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2474  *
2475  *  \param [in] a - the array to copy values from.
2476  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2477  *              assign values of \a a to.
2478  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2479  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2480  *              \a bgTuples <= \a pi < \a endTuples.
2481  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2482  *  \param [in] endComp - index of the component before which the components to assign
2483  *              to are located.
2484  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2485  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2486  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2487  *               then \a a->getNumberOfComponents() must be equal 
2488  *               to the number of specified columns, else this is not required.
2489  *  \throw If \a a is NULL.
2490  *  \throw If \a a is not allocated.
2491  *  \throw If \a this is not allocated.
2492  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2493  *         \a this array.
2494  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2495  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2496  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2497  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2498  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2499  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2500  *  \throw If parameters specifying components to assign to, do not give a
2501  *            non-empty range of increasing indices or indices are out of a valid range
2502  *            for \this array.
2503  *
2504  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2505  */
2506 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2507 {
2508   if(!a)
2509     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2510   const char msg[]="DataArrayDouble::setPartOfValues3";
2511   checkAllocated();
2512   a->checkAllocated();
2513   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2514   int nbComp=getNumberOfComponents();
2515   int nbOfTuples=getNumberOfTuples();
2516   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2517   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2518   bool assignTech=true;
2519   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2520     {
2521       if(strictCompoCompare)
2522         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2523     }
2524   else
2525     {
2526       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2527       assignTech=false;
2528     }
2529   double *pt=getPointer()+bgComp;
2530   const double *srcPt=a->getConstPointer();
2531   if(assignTech)
2532     {
2533       for(const int *w=bgTuples;w!=endTuples;w++)
2534         for(int j=0;j<newNbOfComp;j++,srcPt++)
2535           {
2536             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2537             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2538           }
2539     }
2540   else
2541     {
2542       for(const int *w=bgTuples;w!=endTuples;w++)
2543         {
2544           const double *srcPt2=srcPt;
2545           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2546             {
2547               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2548               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2549             }
2550         }
2551     }
2552 }
2553
2554 /*!
2555  * Assign a given value to values at specified tuples and components of \a this array.
2556  * The tuples to assign to are defined by a C array of indices.
2557  * The components to assign to are defined by three values similar to parameters of
2558  * the Python function \c range(\c start,\c stop,\c step).
2559  *  \param [in] a - the value to assign.
2560  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2561  *              assign \a a to.
2562  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2563  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2564  *              \a bgTuples <= \a pi < \a endTuples.
2565  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2566  *  \param [in] endComp - index of the component before which the components to assign
2567  *              to are located.
2568  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2569  *  \throw If \a this is not allocated.
2570  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2571  *         \a this array.
2572  *  \throw If parameters specifying components to assign to, do not give a
2573  *            non-empty range of increasing indices or indices are out of a valid range
2574  *            for \this array.
2575  *
2576  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2577  */
2578 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2579 {
2580   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2581   checkAllocated();
2582   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2583   int nbComp=getNumberOfComponents();
2584   int nbOfTuples=getNumberOfTuples();
2585   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2586   double *pt=getPointer()+bgComp;
2587   for(const int *w=bgTuples;w!=endTuples;w++)
2588     for(int j=0;j<newNbOfComp;j++)
2589       {
2590         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2591         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2592       }
2593 }
2594
2595 /*!
2596  * Copy all values from another DataArrayDouble into specified tuples and components
2597  * of \a this array. Textual data is not copied.
2598  * The tree parameters defining set of indices of tuples and components are similar to
2599  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2600  *  \param [in] a - the array to copy values from.
2601  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2602  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2603  *              are located.
2604  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2605  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2606  *              assign \a a to.
2607  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2608  *              pointer to a component index (\a pi) varies as this: 
2609  *              \a bgComp <= \a pi < \a endComp.
2610  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2611  *              must be equal to the number of columns to assign to, else an
2612  *              exception is thrown; if \a false, then it is only required that \a
2613  *              a->getNbOfElems() equals to number of values to assign to (this condition
2614  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2615  *              values to assign to is given by following Python expression:
2616  *              \a nbTargetValues = 
2617  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2618  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2619  *  \throw If \a a is NULL.
2620  *  \throw If \a a is not allocated.
2621  *  \throw If \a this is not allocated.
2622  *  \throw If parameters specifying tuples and components to assign to do not give a
2623  *            non-empty range of increasing indices.
2624  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2625  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2626  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2627  *
2628  */
2629 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2630 {
2631   if(!a)
2632     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2633   const char msg[]="DataArrayDouble::setPartOfValues4";
2634   checkAllocated();
2635   a->checkAllocated();
2636   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2637   int newNbOfComp=(int)std::distance(bgComp,endComp);
2638   int nbComp=getNumberOfComponents();
2639   for(const int *z=bgComp;z!=endComp;z++)
2640     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2641   int nbOfTuples=getNumberOfTuples();
2642   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2643   bool assignTech=true;
2644   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2645     {
2646       if(strictCompoCompare)
2647         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2648     }
2649   else
2650     {
2651       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2652       assignTech=false;
2653     }
2654   const double *srcPt=a->getConstPointer();
2655   double *pt=getPointer()+bgTuples*nbComp;
2656   if(assignTech)
2657     {
2658       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2659         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2660           pt[*z]=*srcPt;
2661     }
2662   else
2663     {
2664       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2665         {
2666           const double *srcPt2=srcPt;
2667           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2668             pt[*z]=*srcPt2;
2669         }
2670     }
2671 }
2672
2673 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2674 {
2675   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2676   checkAllocated();
2677   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2678   int nbComp=getNumberOfComponents();
2679   for(const int *z=bgComp;z!=endComp;z++)
2680     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2681   int nbOfTuples=getNumberOfTuples();
2682   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2683   double *pt=getPointer()+bgTuples*nbComp;
2684   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2685     for(const int *z=bgComp;z!=endComp;z++)
2686       pt[*z]=a;
2687 }
2688
2689 /*!
2690  * Copy some tuples from another DataArrayDouble into specified tuples
2691  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2692  * components.
2693  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2694  * All components of selected tuples are copied.
2695  *  \param [in] a - the array to copy values from.
2696  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2697  *              target tuples of \a this. \a tuplesSelec has two components, and the
2698  *              first component specifies index of the source tuple and the second
2699  *              one specifies index of the target tuple.
2700  *  \throw If \a this is not allocated.
2701  *  \throw If \a a is NULL.
2702  *  \throw If \a a is not allocated.
2703  *  \throw If \a tuplesSelec is NULL.
2704  *  \throw If \a tuplesSelec is not allocated.
2705  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2706  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2707  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2708  *         the corresponding (\a this or \a a) array.
2709  */
2710 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2711 {
2712   if(!a || !tuplesSelec)
2713     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2714   checkAllocated();
2715   a->checkAllocated();
2716   tuplesSelec->checkAllocated();
2717   int nbOfComp=getNumberOfComponents();
2718   if(nbOfComp!=a->getNumberOfComponents())
2719     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2720   if(tuplesSelec->getNumberOfComponents()!=2)
2721     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2722   int thisNt=getNumberOfTuples();
2723   int aNt=a->getNumberOfTuples();
2724   double *valsToSet=getPointer();
2725   const double *valsSrc=a->getConstPointer();
2726   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2727     {
2728       if(tuple[1]>=0 && tuple[1]<aNt)
2729         {
2730           if(tuple[0]>=0 && tuple[0]<thisNt)
2731             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2732           else
2733             {
2734               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2735               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2736               throw INTERP_KERNEL::Exception(oss.str().c_str());
2737             }
2738         }
2739       else
2740         {
2741           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2742           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2743           throw INTERP_KERNEL::Exception(oss.str().c_str());
2744         }
2745     }
2746 }
2747
2748 /*!
2749  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2750  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2751  * components.
2752  * The tuples to assign to are defined by index of the first tuple, and
2753  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2754  * The tuples to copy are defined by values of a DataArrayInt.
2755  * All components of selected tuples are copied.
2756  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2757  *              values to.
2758  *  \param [in] aBase - the array to copy values from.
2759  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2760  *  \throw If \a this is not allocated.
2761  *  \throw If \a aBase is NULL.
2762  *  \throw If \a aBase is not allocated.
2763  *  \throw If \a tuplesSelec is NULL.
2764  *  \throw If \a tuplesSelec is not allocated.
2765  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2766  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2767  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2768  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2769  *         \a aBase array.
2770  */
2771 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2772 {
2773   if(!aBase || !tuplesSelec)
2774     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2775   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2776   if(!a)
2777     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2778   checkAllocated();
2779   a->checkAllocated();
2780   tuplesSelec->checkAllocated();
2781   int nbOfComp=getNumberOfComponents();
2782   if(nbOfComp!=a->getNumberOfComponents())
2783     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2784   if(tuplesSelec->getNumberOfComponents()!=1)
2785     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2786   int thisNt=getNumberOfTuples();
2787   int aNt=a->getNumberOfTuples();
2788   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2789   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2790   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2791     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2792   const double *valsSrc=a->getConstPointer();
2793   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2794     {
2795       if(*tuple>=0 && *tuple<aNt)
2796         {
2797           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2798         }
2799       else
2800         {
2801           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2802           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2803           throw INTERP_KERNEL::Exception(oss.str().c_str());
2804         }
2805     }
2806 }
2807
2808 /*!
2809  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2810  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2811  * components.
2812  * The tuples to copy are defined by three values similar to parameters of
2813  * the Python function \c range(\c start,\c stop,\c step).
2814  * The tuples to assign to are defined by index of the first tuple, and
2815  * their number is defined by number of tuples to copy.
2816  * All components of selected tuples are copied.
2817  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2818  *              values to.
2819  *  \param [in] aBase - the array to copy values from.
2820  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2821  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2822  *              are located.
2823  *  \param [in] step - index increment to get index of the next tuple to copy.
2824  *  \throw If \a this is not allocated.
2825  *  \throw If \a aBase is NULL.
2826  *  \throw If \a aBase is not allocated.
2827  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2828  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2829  *  \throw If parameters specifying tuples to copy, do not give a
2830  *            non-empty range of increasing indices or indices are out of a valid range
2831  *            for the array \a aBase.
2832  */
2833 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
2834 {
2835   if(!aBase)
2836     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2837   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2838   if(!a)
2839     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2840   checkAllocated();
2841   a->checkAllocated();
2842   int nbOfComp=getNumberOfComponents();
2843   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2844   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2845   if(nbOfComp!=a->getNumberOfComponents())
2846     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2847   int thisNt=getNumberOfTuples();
2848   int aNt=a->getNumberOfTuples();
2849   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2850   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2851     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2852   if(end2>aNt)
2853     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2854   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2855   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2856     {
2857       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2858     }
2859 }
2860
2861 /*!
2862  * Returns a value located at specified tuple and component.
2863  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2864  * parameters is checked. So this method is safe but expensive if used to go through
2865  * all values of \a this.
2866  *  \param [in] tupleId - index of tuple of interest.
2867  *  \param [in] compoId - index of component of interest.
2868  *  \return double - value located by \a tupleId and \a compoId.
2869  *  \throw If \a this is not allocated.
2870  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2871  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2872  */
2873 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
2874 {
2875   checkAllocated();
2876   if(tupleId<0 || tupleId>=getNumberOfTuples())
2877     {
2878       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2879       throw INTERP_KERNEL::Exception(oss.str().c_str());
2880     }
2881   if(compoId<0 || compoId>=getNumberOfComponents())
2882     {
2883       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2884       throw INTERP_KERNEL::Exception(oss.str().c_str());
2885     }
2886   return _mem[tupleId*_info_on_compo.size()+compoId];
2887 }
2888
2889 /*!
2890  * Returns the first value of \a this. 
2891  *  \return double - the last value of \a this array.
2892  *  \throw If \a this is not allocated.
2893  *  \throw If \a this->getNumberOfComponents() != 1.
2894  *  \throw If \a this->getNumberOfTuples() < 1.
2895  */
2896 double DataArrayDouble::front() const throw(INTERP_KERNEL::Exception)
2897 {
2898   checkAllocated();
2899   if(getNumberOfComponents()!=1)
2900     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2901   int nbOfTuples=getNumberOfTuples();
2902   if(nbOfTuples<1)
2903     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2904   return *(getConstPointer());
2905 }
2906
2907 /*!
2908  * Returns the last value of \a this. 
2909  *  \return double - the last value of \a this array.
2910  *  \throw If \a this is not allocated.
2911  *  \throw If \a this->getNumberOfComponents() != 1.
2912  *  \throw If \a this->getNumberOfTuples() < 1.
2913  */
2914 double DataArrayDouble::back() const throw(INTERP_KERNEL::Exception)
2915 {
2916   checkAllocated();
2917   if(getNumberOfComponents()!=1)
2918     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2919   int nbOfTuples=getNumberOfTuples();
2920   if(nbOfTuples<1)
2921     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2922   return *(getConstPointer()+nbOfTuples-1);
2923 }
2924
2925 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2926 {
2927   if(newArray!=arrayToSet)
2928     {
2929       if(arrayToSet)
2930         arrayToSet->decrRef();
2931       arrayToSet=newArray;
2932       if(arrayToSet)
2933         arrayToSet->incrRef();
2934     }
2935 }
2936
2937 /*!
2938  * Sets a C array to be used as raw data of \a this. The previously set info
2939  *  of components is retained and re-sized. 
2940  * For more info see \ref MEDCouplingArraySteps1.
2941  *  \param [in] array - the C array to be used as raw data of \a this.
2942  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2943  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2944  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2945  *                     \c free(\c array ) will be called.
2946  *  \param [in] nbOfTuple - new number of tuples in \a this.
2947  *  \param [in] nbOfCompo - new number of components in \a this.
2948  */
2949 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2950 {
2951   _info_on_compo.resize(nbOfCompo);
2952   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2953   declareAsNew();
2954 }
2955
2956 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2957 {
2958   _info_on_compo.resize(nbOfCompo);
2959   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
2960   declareAsNew();
2961 }
2962
2963 /*!
2964  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2965  * is thrown.
2966  * \throw If zero is found in \a this array.
2967  */
2968 void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception)
2969 {
2970   const double *tmp=getConstPointer();
2971   std::size_t nbOfElems=getNbOfElems();
2972   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2973   if(where!=tmp+nbOfElems)
2974     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2975 }
2976
2977 /*!
2978  * Computes minimal and maximal value in each component. An output array is filled
2979  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2980  * enough memory before calling this method.
2981  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2982  *               It is filled as follows:<br>
2983  *               \a bounds[0] = \c min_of_component_0 <br>
2984  *               \a bounds[1] = \c max_of_component_0 <br>
2985  *               \a bounds[2] = \c min_of_component_1 <br>
2986  *               \a bounds[3] = \c max_of_component_1 <br>
2987  *               ...
2988  */
2989 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception)
2990 {
2991   checkAllocated();
2992   int dim=getNumberOfComponents();
2993   for (int idim=0; idim<dim; idim++)
2994     {
2995       bounds[idim*2]=std::numeric_limits<double>::max();
2996       bounds[idim*2+1]=-std::numeric_limits<double>::max();
2997     } 
2998   const double *ptr=getConstPointer();
2999   int nbOfTuples=getNumberOfTuples();
3000   for(int i=0;i<nbOfTuples;i++)
3001     {
3002       for(int idim=0;idim<dim;idim++)
3003         {
3004           if(bounds[idim*2]>ptr[i*dim+idim])
3005             {
3006               bounds[idim*2]=ptr[i*dim+idim];
3007             }
3008           if(bounds[idim*2+1]<ptr[i*dim+idim])
3009             {
3010               bounds[idim*2+1]=ptr[i*dim+idim];
3011             }
3012         }
3013     }
3014 }
3015
3016 /*!
3017  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3018  * to store both the min and max per component of each tuples. 
3019  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3020  *
3021  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3022  *
3023  * \throw If \a this is not allocated yet.
3024  */
3025 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw(INTERP_KERNEL::Exception)
3026 {
3027   checkAllocated();
3028   const double *dataPtr=getConstPointer();
3029   int nbOfCompo=getNumberOfComponents();
3030   int nbTuples=getNumberOfTuples();
3031   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
3032   bbox->alloc(nbTuples,2*nbOfCompo);
3033   double *bboxPtr=bbox->getPointer();
3034   for(int i=0;i<nbTuples;i++)
3035     {
3036       for(int j=0;j<nbOfCompo;j++)
3037         {
3038           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3039           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3040         }
3041     }
3042   return bbox.retn();
3043 }
3044
3045 /*!
3046  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3047  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3048  * 
3049  * \param [in] other a DataArrayDouble having same number of components than \a this.
3050  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3051  * \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.
3052  *             \a cI allows to extract information in \a c.
3053  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3054  *
3055  * \throw In case of:
3056  *  - \a this is not allocated
3057  *  - \a other is not allocated or null
3058  *  - \a this and \a other do not have the same number of components
3059  *  - if number of components of \a this is not in [1,2,3]
3060  *
3061  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3062  */
3063 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception)
3064 {
3065   if(!other)
3066     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3067   checkAllocated();
3068   other->checkAllocated();
3069   int nbOfCompo=getNumberOfComponents();
3070   int otherNbOfCompo=other->getNumberOfComponents();
3071   if(nbOfCompo!=otherNbOfCompo)
3072     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3073   int nbOfTuplesOther=other->getNumberOfTuples();
3074   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3075   switch(nbOfCompo)
3076     {
3077     case 3:
3078       {
3079         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3080         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3081         break;
3082       }
3083     case 2:
3084       {
3085         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3086         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3087         break;
3088       }
3089     case 1:
3090       {
3091         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3092         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3093         break;
3094       }
3095     default:
3096       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3097     }
3098   c=cArr.retn(); cI=cIArr.retn();
3099 }
3100
3101 /*!
3102  * 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
3103  * around origin of 'radius' 1.
3104  * 
3105  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3106  */
3107 void DataArrayDouble::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception)
3108 {
3109   checkAllocated();
3110   int dim=getNumberOfComponents();
3111   std::vector<double> bounds(2*dim);
3112   getMinMaxPerComponent(&bounds[0]);
3113   for(int i=0;i<dim;i++)
3114     {
3115       double delta=bounds[2*i+1]-bounds[2*i];
3116       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3117       if(delta>eps)
3118         applyLin(1./delta,-offset/delta,i);
3119       else
3120         applyLin(1.,-offset,i);
3121     }
3122 }
3123
3124 /*!
3125  * Returns the maximal value and its location within \a this one-dimensional array.
3126  *  \param [out] tupleId - index of the tuple holding the maximal value.
3127  *  \return double - the maximal value among all values of \a this array.
3128  *  \throw If \a this->getNumberOfComponents() != 1
3129  *  \throw If \a this->getNumberOfTuples() < 1
3130  */
3131 double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
3132 {
3133   checkAllocated();
3134   if(getNumberOfComponents()!=1)
3135     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 !");
3136   int nbOfTuples=getNumberOfTuples();
3137   if(nbOfTuples<=0)
3138     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3139   const double *vals=getConstPointer();
3140   const double *loc=std::max_element(vals,vals+nbOfTuples);
3141   tupleId=(int)std::distance(vals,loc);
3142   return *loc;
3143 }
3144
3145 /*!
3146  * Returns the maximal value within \a this array that is allowed to have more than
3147  *  one component.
3148  *  \return double - the maximal value among all values of \a this array.
3149  *  \throw If \a this is not allocated.
3150  */
3151 double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
3152 {
3153   checkAllocated();
3154   const double *loc=std::max_element(begin(),end());
3155   return *loc;
3156 }
3157
3158 /*!
3159  * Returns the maximal value and all its locations within \a this one-dimensional array.
3160  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3161  *               tuples holding the maximal value. The caller is to delete it using
3162  *               decrRef() as it is no more needed.
3163  *  \return double - the maximal value among all values of \a this array.
3164  *  \throw If \a this->getNumberOfComponents() != 1
3165  *  \throw If \a this->getNumberOfTuples() < 1
3166  */
3167 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
3168 {
3169   int tmp;
3170   tupleIds=0;
3171   double ret=getMaxValue(tmp);
3172   tupleIds=getIdsInRange(ret,ret);
3173   return ret;
3174 }
3175
3176 /*!
3177  * Returns the minimal value and its location within \a this one-dimensional array.
3178  *  \param [out] tupleId - index of the tuple holding the minimal value.
3179  *  \return double - the minimal value among all values of \a this array.
3180  *  \throw If \a this->getNumberOfComponents() != 1
3181  *  \throw If \a this->getNumberOfTuples() < 1
3182  */
3183 double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
3184 {
3185   checkAllocated();
3186   if(getNumberOfComponents()!=1)
3187     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3188   int nbOfTuples=getNumberOfTuples();
3189   if(nbOfTuples<=0)
3190     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3191   const double *vals=getConstPointer();
3192   const double *loc=std::min_element(vals,vals+nbOfTuples);
3193   tupleId=(int)std::distance(vals,loc);
3194   return *loc;
3195 }
3196
3197 /*!
3198  * Returns the minimal value within \a this array that is allowed to have more than
3199  *  one component.
3200  *  \return double - the minimal value among all values of \a this array.
3201  *  \throw If \a this is not allocated.
3202  */
3203 double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
3204 {
3205   checkAllocated();
3206   const double *loc=std::min_element(begin(),end());
3207   return *loc;
3208 }
3209
3210 /*!
3211  * Returns the minimal value and all its locations within \a this one-dimensional array.
3212  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3213  *               tuples holding the minimal value. The caller is to delete it using
3214  *               decrRef() as it is no more needed.
3215  *  \return double - the minimal value among all values of \a this array.
3216  *  \throw If \a this->getNumberOfComponents() != 1
3217  *  \throw If \a this->getNumberOfTuples() < 1
3218  */
3219 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
3220 {
3221   int tmp;
3222   tupleIds=0;
3223   double ret=getMinValue(tmp);
3224   tupleIds=getIdsInRange(ret,ret);
3225   return ret;
3226 }
3227
3228 /*!
3229  * 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.
3230  * This method only works for single component array.
3231  *
3232  * \return a value in [ 0, \c this->getNumberOfTuples() )
3233  *
3234  * \throw If \a this is not allocated
3235  *
3236  */
3237 int DataArrayDouble::count(double value, double eps) const throw(INTERP_KERNEL::Exception)
3238 {
3239   int ret=0;
3240   checkAllocated();
3241   if(getNumberOfComponents()!=1)
3242     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3243   const double *vals=begin();
3244   int nbOfTuples=getNumberOfTuples();
3245   for(int i=0;i<nbOfTuples;i++,vals++)
3246     if(fabs(*vals-value)<=eps)
3247       ret++;
3248   return ret;
3249 }
3250
3251 /*!
3252  * Returns the average value of \a this one-dimensional array.
3253  *  \return double - the average value over all values of \a this array.
3254  *  \throw If \a this->getNumberOfComponents() != 1
3255  *  \throw If \a this->getNumberOfTuples() < 1
3256  */
3257 double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
3258 {
3259   if(getNumberOfComponents()!=1)
3260     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3261   int nbOfTuples=getNumberOfTuples();
3262   if(nbOfTuples<=0)
3263     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3264   const double *vals=getConstPointer();
3265   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3266   return ret/nbOfTuples;
3267 }
3268
3269 /*!
3270  * Returns the Euclidean norm of the vector defined by \a this array.
3271  *  \return double - the value of the Euclidean norm, i.e.
3272  *          the square root of the inner product of vector.
3273  *  \throw If \a this is not allocated.
3274  */
3275 double DataArrayDouble::norm2() const throw(INTERP_KERNEL::Exception)
3276 {
3277   checkAllocated();
3278   double ret=0.;
3279   std::size_t nbOfElems=getNbOfElems();
3280   const double *pt=getConstPointer();
3281   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3282     ret+=(*pt)*(*pt);
3283   return sqrt(ret);
3284 }
3285
3286 /*!
3287  * Returns the maximum norm of the vector defined by \a this array.
3288  *  \return double - the value of the maximum norm, i.e.
3289  *          the maximal absolute value among values of \a this array.
3290  *  \throw If \a this is not allocated.
3291  */
3292 double DataArrayDouble::normMax() const throw(INTERP_KERNEL::Exception)
3293 {
3294   checkAllocated();
3295   double ret=-1.;
3296   std::size_t nbOfElems=getNbOfElems();
3297   const double *pt=getConstPointer();
3298   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3299     {
3300       double val=std::abs(*pt);
3301       if(val>ret)
3302         ret=val;
3303     }
3304   return ret;
3305 }
3306
3307 /*!
3308  * Accumulates values of each component of \a this array.
3309  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3310  *         by the caller, that is filled by this method with sum value for each
3311  *         component.
3312  *  \throw If \a this is not allocated.
3313  */
3314 void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Exception)
3315 {
3316   checkAllocated();
3317   const double *ptr=getConstPointer();
3318   int nbTuple=getNumberOfTuples();
3319   int nbComps=getNumberOfComponents();
3320   std::fill(res,res+nbComps,0.);
3321   for(int i=0;i<nbTuple;i++)
3322     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3323 }
3324
3325 /*!
3326  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3327  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3328  *
3329  *
3330  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3331  * \a tupleEnd. If not an exception will be thrown.
3332  *
3333  * \param [in] tupleBg start pointer (included) of input external tuple
3334  * \param [in] tupleEnd end pointer (not included) of input external tuple
3335  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3336  * \return the min distance.
3337  * \sa MEDCouplingUMesh::distanceToPoint
3338  */
3339 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception)
3340 {
3341   checkAllocated();
3342   int nbTuple=getNumberOfTuples();
3343   int nbComps=getNumberOfComponents();
3344   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3345     { 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()); }
3346   if(nbTuple==0)
3347     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3348   double ret0=std::numeric_limits<double>::max();
3349   tupleId=-1;
3350   const double *work=getConstPointer();
3351   for(int i=0;i<nbTuple;i++)
3352     {
3353       double val=0.;
3354       for(int j=0;j<nbComps;j++,work++) 
3355         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3356       if(val>=ret0)
3357         continue;
3358       else
3359         { ret0=val; tupleId=i; }
3360     }
3361   return sqrt(ret0);
3362 }
3363
3364 /*!
3365  * Accumulate values of the given component of \a this array.
3366  *  \param [in] compId - the index of the component of interest.
3367  *  \return double - a sum value of \a compId-th component.
3368  *  \throw If \a this is not allocated.
3369  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3370  *         not respected.
3371  */
3372 double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
3373 {
3374   checkAllocated();
3375   const double *ptr=getConstPointer();
3376   int nbTuple=getNumberOfTuples();
3377   int nbComps=getNumberOfComponents();
3378   if(compId<0 || compId>=nbComps)
3379     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3380   double ret=0.;
3381   for(int i=0;i<nbTuple;i++)
3382     ret+=ptr[i*nbComps+compId];
3383   return ret;
3384 }
3385
3386 /*!
3387  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3388  * The returned array will have same number of components than \a this and number of tuples equal to
3389  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3390  *
3391  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3392  * 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.
3393  *
3394  * \param [in] bgOfIndex - begin (included) of the input index array.
3395  * \param [in] endOfIndex - end (excluded) of the input index array.
3396  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3397  * 
3398  * \throw If bgOfIndex or end is NULL.
3399  * \throw If input index array is not ascendingly sorted.
3400  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3401  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3402  */
3403 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
3404 {
3405   if(!bgOfIndex || !endOfIndex)
3406     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3407   checkAllocated();
3408   int nbCompo=getNumberOfComponents();
3409   int nbOfTuples=getNumberOfTuples();
3410   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3411   if(sz<1)
3412     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3413   sz--;
3414   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3415   const int *w=bgOfIndex;
3416   if(*w<0 || *w>=nbOfTuples)
3417     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3418   const double *srcPt=begin()+(*w)*nbCompo;
3419   double *tmp=ret->getPointer();
3420   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3421     {
3422       std::fill(tmp,tmp+nbCompo,0.);
3423       if(w[1]>=w[0])
3424         {
3425           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3426             {
3427               if(j>=0 && j<nbOfTuples)
3428                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3429               else
3430                 {
3431                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3432                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3433                 }
3434             }
3435         }
3436       else
3437         {
3438           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3439           throw INTERP_KERNEL::Exception(oss.str().c_str());
3440         }
3441     }
3442   ret->copyStringInfoFrom(*this);
3443   return ret.retn();
3444 }
3445
3446 /*!
3447  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3448  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3449  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3450  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3451  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3452  *          is to delete this array using decrRef() as it is no more needed. The array
3453  *          does not contain any textual info on components.
3454  *  \throw If \a this->getNumberOfComponents() != 2.
3455  */
3456 DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::Exception)
3457 {
3458   checkAllocated();
3459   int nbOfComp=getNumberOfComponents();
3460   if(nbOfComp!=2)
3461     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3462   int nbOfTuple=getNumberOfTuples();
3463   DataArrayDouble *ret=DataArrayDouble::New();
3464   ret->alloc(nbOfTuple,2);
3465   double *w=ret->getPointer();
3466   const double *wIn=getConstPointer();
3467   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3468     {
3469       w[0]=wIn[0]*cos(wIn[1]);
3470       w[1]=wIn[0]*sin(wIn[1]);
3471     }
3472   return ret;
3473 }
3474
3475 /*!
3476  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3477  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3478  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3479  * the Cylindrical CS.
3480  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3481  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3482  *          on the third component is copied from \a this array. The caller
3483  *          is to delete this array using decrRef() as it is no more needed. 
3484  *  \throw If \a this->getNumberOfComponents() != 3.
3485  */
3486 DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exception)
3487 {
3488   checkAllocated();
3489   int nbOfComp=getNumberOfComponents();
3490   if(nbOfComp!=3)
3491     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3492   int nbOfTuple=getNumberOfTuples();
3493   DataArrayDouble *ret=DataArrayDouble::New();
3494   ret->alloc(getNumberOfTuples(),3);
3495   double *w=ret->getPointer();
3496   const double *wIn=getConstPointer();
3497   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3498     {
3499       w[0]=wIn[0]*cos(wIn[1]);
3500       w[1]=wIn[0]*sin(wIn[1]);
3501       w[2]=wIn[2];
3502     }
3503   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3504   return ret;
3505 }
3506
3507 /*!
3508  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3509  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3510  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3511  * point in the Cylindrical CS.
3512  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3513  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3514  *          on the third component is copied from \a this array. The caller
3515  *          is to delete this array using decrRef() as it is no more needed.
3516  *  \throw If \a this->getNumberOfComponents() != 3.
3517  */
3518 DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::Exception)
3519 {
3520   checkAllocated();
3521   int nbOfComp=getNumberOfComponents();
3522   if(nbOfComp!=3)
3523     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3524   int nbOfTuple=getNumberOfTuples();
3525   DataArrayDouble *ret=DataArrayDouble::New();
3526   ret->alloc(getNumberOfTuples(),3);
3527   double *w=ret->getPointer();
3528   const double *wIn=getConstPointer();
3529   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3530     {
3531       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3532       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3533       w[2]=wIn[0]*cos(wIn[1]);
3534     }
3535   return ret;
3536 }
3537
3538 /*!
3539  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3540  * array contating 6 components.
3541  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3542  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3543  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3544  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3545  *  \throw If \a this->getNumberOfComponents() != 6.
3546  */
3547 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
3548 {
3549   checkAllocated();
3550   int nbOfComp=getNumberOfComponents();
3551   if(nbOfComp!=6)
3552     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3553   DataArrayDouble *ret=DataArrayDouble::New();
3554   int nbOfTuple=getNumberOfTuples();
3555   ret->alloc(nbOfTuple,1);
3556   const double *src=getConstPointer();
3557   double *dest=ret->getPointer();
3558   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3559     *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];
3560   return ret;
3561 }
3562
3563 /*!
3564  * Computes the determinant of every square matrix defined by the tuple of \a this
3565  * array, which contains either 4, 6 or 9 components. The case of 6 components
3566  * corresponds to that of the upper triangular matrix.
3567  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3568  *          is the determinant of matrix of the corresponding tuple of \a this array.
3569  *          The caller is to delete this result array using decrRef() as it is no more
3570  *          needed. 
3571  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3572  */
3573 DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Exception)
3574 {
3575   checkAllocated();
3576   DataArrayDouble *ret=DataArrayDouble::New();
3577   int nbOfTuple=getNumberOfTuples();
3578   ret->alloc(nbOfTuple,1);
3579   const double *src=getConstPointer();
3580   double *dest=ret->getPointer();
3581   switch(getNumberOfComponents())
3582     {
3583     case 6:
3584       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3585         *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];
3586       return ret;
3587     case 4:
3588       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3589         *dest=src[0]*src[3]-src[1]*src[2];
3590       return ret;
3591     case 9:
3592       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3593         *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];
3594       return ret;
3595     default:
3596       ret->decrRef();
3597       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3598     }
3599 }
3600
3601 /*!
3602  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3603  * \a this array, which contains 6 components.
3604  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3605  *          components, whose each tuple contains the eigenvalues of the matrix of
3606  *          corresponding tuple of \a this array. 
3607  *          The caller is to delete this result array using decrRef() as it is no more
3608  *          needed. 
3609  *  \throw If \a this->getNumberOfComponents() != 6.
3610  */
3611 DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
3612 {
3613   checkAllocated();
3614   int nbOfComp=getNumberOfComponents();
3615   if(nbOfComp!=6)
3616     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3617   DataArrayDouble *ret=DataArrayDouble::New();
3618   int nbOfTuple=getNumberOfTuples();
3619   ret->alloc(nbOfTuple,3);
3620   const double *src=getConstPointer();
3621   double *dest=ret->getPointer();
3622   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3623     INTERP_KERNEL::computeEigenValues6(src,dest);
3624   return ret;
3625 }
3626
3627 /*!
3628  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3629  * \a this array, which contains 6 components.
3630  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3631  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3632  *          corresponding tuple of \a this array.
3633  *          The caller is to delete this result array using decrRef() as it is no more
3634  *          needed.
3635  *  \throw If \a this->getNumberOfComponents() != 6.
3636  */
3637 DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
3638 {
3639   checkAllocated();
3640   int nbOfComp=getNumberOfComponents();
3641   if(nbOfComp!=6)
3642     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3643   DataArrayDouble *ret=DataArrayDouble::New();
3644   int nbOfTuple=getNumberOfTuples();
3645   ret->alloc(nbOfTuple,9);
3646   const double *src=getConstPointer();
3647   double *dest=ret->getPointer();
3648   for(int i=0;i<nbOfTuple;i++,src+=6)
3649     {
3650       double tmp[3];
3651       INTERP_KERNEL::computeEigenValues6(src,tmp);
3652       for(int j=0;j<3;j++,dest+=3)
3653         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3654     }
3655   return ret;
3656 }
3657
3658 /*!
3659  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3660  * array, which contains either 4, 6 or 9 components. The case of 6 components
3661  * corresponds to that of the upper triangular matrix.
3662  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3663  *          same number of components as \a this one, whose each tuple is the inverse
3664  *          matrix of the matrix of corresponding tuple of \a this array. 
3665  *          The caller is to delete this result array using decrRef() as it is no more
3666  *          needed. 
3667  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3668  */
3669 DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception)
3670 {
3671   checkAllocated();
3672   int nbOfComp=getNumberOfComponents();
3673   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3674     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3675   DataArrayDouble *ret=DataArrayDouble::New();
3676   int nbOfTuple=getNumberOfTuples();
3677   ret->alloc(nbOfTuple,nbOfComp);
3678   const double *src=getConstPointer();
3679   double *dest=ret->getPointer();
3680 if(nbOfComp==6)
3681     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3682       {
3683         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];
3684         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3685         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3686         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3687         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3688         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3689         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3690       }
3691   else if(nbOfComp==4)
3692     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3693       {
3694         double det=src[0]*src[3]-src[1]*src[2];
3695         dest[0]=src[3]/det;
3696         dest[1]=-src[1]/det;
3697         dest[2]=-src[2]/det;
3698         dest[3]=src[0]/det;
3699       }
3700   else
3701     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3702       {
3703         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];
3704         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3705         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3706         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3707         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3708         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3709         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3710         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3711         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3712         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3713       }
3714   return ret;
3715 }
3716
3717 /*!
3718  * Computes the trace of every matrix defined by the tuple of \a this
3719  * array, which contains either 4, 6 or 9 components. The case of 6 components
3720  * corresponds to that of the upper triangular matrix.
3721  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3722  *          1 component, whose each tuple is the trace of
3723  *          the matrix of corresponding tuple of \a this array. 
3724  *          The caller is to delete this result array using decrRef() as it is no more
3725  *          needed. 
3726  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3727  */
3728 DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception)
3729 {
3730   checkAllocated();
3731   int nbOfComp=getNumberOfComponents();
3732   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3733     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3734   DataArrayDouble *ret=DataArrayDouble::New();
3735   int nbOfTuple=getNumberOfTuples();
3736   ret->alloc(nbOfTuple,1);
3737   const double *src=getConstPointer();
3738   double *dest=ret->getPointer();
3739   if(nbOfComp==6)
3740     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3741       *dest=src[0]+src[1]+src[2];
3742   else if(nbOfComp==4)
3743     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3744       *dest=src[0]+src[3];
3745   else
3746     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3747       *dest=src[0]+src[4]+src[8];
3748   return ret;
3749 }
3750
3751 /*!
3752  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3753  * \a this array, which contains 6 components.
3754  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3755  *          same number of components and tuples as \a this array.
3756  *          The caller is to delete this result array using decrRef() as it is no more
3757  *          needed.
3758  *  \throw If \a this->getNumberOfComponents() != 6.
3759  */
3760 DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception)
3761 {
3762   checkAllocated();
3763   int nbOfComp=getNumberOfComponents();
3764   if(nbOfComp!=6)
3765     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3766   DataArrayDouble *ret=DataArrayDouble::New();
3767   int nbOfTuple=getNumberOfTuples();
3768   ret->alloc(nbOfTuple,6);
3769   const double *src=getConstPointer();
3770   double *dest=ret->getPointer();
3771   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3772     {
3773       double tr=(src[0]+src[1]+src[2])/3.;
3774       dest[0]=src[0]-tr;
3775       dest[1]=src[1]-tr;
3776       dest[2]=src[2]-tr;
3777       dest[3]=src[3];
3778       dest[4]=src[4];
3779       dest[5]=src[5];
3780     }
3781   return ret;
3782 }
3783
3784 /*!
3785  * Computes the magnitude of every vector defined by the tuple of
3786  * \a this array.
3787  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3788  *          same number of tuples as \a this array and one component.
3789  *          The caller is to delete this result array using decrRef() as it is no more
3790  *          needed.
3791  *  \throw If \a this is not allocated.
3792  */
3793 DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Exception)
3794 {
3795   checkAllocated();
3796   int nbOfComp=getNumberOfComponents();
3797   DataArrayDouble *ret=DataArrayDouble::New();
3798   int nbOfTuple=getNumberOfTuples();
3799   ret->alloc(nbOfTuple,1);
3800   const double *src=getConstPointer();
3801   double *dest=ret->getPointer();
3802   for(int i=0;i<nbOfTuple;i++,dest++)
3803     {
3804       double sum=0.;
3805       for(int j=0;j<nbOfComp;j++,src++)
3806         sum+=(*src)*(*src);
3807       *dest=sqrt(sum);
3808     }
3809   return ret;
3810 }
3811
3812 /*!
3813  * Computes the maximal value within every tuple of \a this array.
3814  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3815  *          same number of tuples as \a this array and one component.
3816  *          The caller is to delete this result array using decrRef() as it is no more
3817  *          needed.
3818  *  \throw If \a this is not allocated.
3819  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3820  */
3821 DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
3822 {
3823   checkAllocated();
3824   int nbOfComp=getNumberOfComponents();
3825   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3826   int nbOfTuple=getNumberOfTuples();
3827   ret->alloc(nbOfTuple,1);
3828   const double *src=getConstPointer();
3829   double *dest=ret->getPointer();
3830   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3831     *dest=*std::max_element(src,src+nbOfComp);
3832   return ret.retn();
3833 }
3834
3835 /*!
3836  * Computes the maximal value within every tuple of \a this array and it returns the first component
3837  * id for each tuple that corresponds to the maximal value within the tuple.
3838  * 
3839  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3840  *          same number of tuples and only one component.
3841  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3842  *          same number of tuples as \a this array and one component.
3843  *          The caller is to delete this result array using decrRef() as it is no more
3844  *          needed.
3845  *  \throw If \a this is not allocated.
3846  *  \sa DataArrayDouble::maxPerTuple
3847  */
3848 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const throw(INTERP_KERNEL::Exception)
3849 {
3850   checkAllocated();
3851   int nbOfComp=getNumberOfComponents();
3852   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3853   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3854   int nbOfTuple=getNumberOfTuples();
3855   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3856   const double *src=getConstPointer();
3857   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3858   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3859     {
3860       const double *loc=std::max_element(src,src+nbOfComp);
3861       *dest=*loc;
3862       *dest1=(int)std::distance(src,loc);
3863     }
3864   compoIdOfMaxPerTuple=ret1.retn();
3865   return ret0.retn();
3866 }
3867
3868 /*!
3869  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3870  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3871  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3872  * \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)
3873  *
3874  * \warning use this method with care because it can leads to big amount of consumed memory !
3875  * 
3876  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3877  *
3878  * \throw If \a this is not allocated.
3879  *
3880  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3881  */
3882 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception)
3883 {
3884   checkAllocated();
3885   int nbOfComp=getNumberOfComponents();
3886   int nbOfTuples=getNumberOfTuples();
3887   const double *inData=getConstPointer();
3888   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3889   ret->alloc(nbOfTuples*nbOfTuples,1);
3890   double *outData=ret->getPointer();
3891   for(int i=0;i<nbOfTuples;i++)
3892     {
3893       outData[i*nbOfTuples+i]=0.;
3894       for(int j=i+1;j<nbOfTuples;j++)
3895         {
3896           double dist=0.;
3897           for(int k=0;k<nbOfComp;k++)
3898             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3899           dist=sqrt(dist);
3900           outData[i*nbOfTuples+j]=dist;
3901           outData[j*nbOfTuples+i]=dist;
3902         }
3903     }
3904   return ret.retn();
3905 }
3906
3907 /*!
3908  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3909  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3910  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3911  * \n Output rectangular matrix is sorted along rows.
3912  * \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)
3913  *
3914  * \warning use this method with care because it can leads to big amount of consumed memory !
3915  * 
3916  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3917  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3918  *
3919  * \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.
3920  *
3921  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3922  */
3923 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
3924 {
3925   if(!other)
3926     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3927   checkAllocated();
3928   other->checkAllocated();
3929   int nbOfComp=getNumberOfComponents();
3930   int otherNbOfComp=other->getNumberOfComponents();
3931   if(nbOfComp!=otherNbOfComp)
3932     {
3933       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3934       throw INTERP_KERNEL::Exception(oss.str().c_str());
3935     }
3936   int nbOfTuples=getNumberOfTuples();
3937   int otherNbOfTuples=other->getNumberOfTuples();
3938   const double *inData=getConstPointer();
3939   const double *inDataOther=other->getConstPointer();
3940   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3941   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3942   double *outData=ret->getPointer();
3943   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3944     {
3945       for(int j=0;j<nbOfTuples;j++)
3946         {
3947           double dist=0.;
3948           for(int k=0;k<nbOfComp;k++)
3949             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3950           dist=sqrt(dist);
3951           outData[i*nbOfTuples+j]=dist;
3952         }
3953     }
3954   return ret.retn();
3955 }
3956
3957 /*!
3958  * Sorts value within every tuple of \a this array.
3959  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3960  *              in descending order.
3961  *  \throw If \a this is not allocated.
3962  */
3963 void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
3964 {
3965   checkAllocated();
3966   double *pt=getPointer();
3967   int nbOfTuple=getNumberOfTuples();
3968   int nbOfComp=getNumberOfComponents();
3969   if(asc)
3970     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3971       std::sort(pt,pt+nbOfComp);
3972   else
3973     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3974       std::sort(pt,pt+nbOfComp,std::greater<double>());
3975   declareAsNew();
3976 }
3977
3978 /*!
3979  * Converts every value of \a this array to its absolute value.
3980  *  \throw If \a this is not allocated.
3981  */
3982 void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception)
3983 {
3984   checkAllocated();
3985   double *ptr=getPointer();
3986   std::size_t nbOfElems=getNbOfElems();
3987   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
3988   declareAsNew();
3989 }
3990
3991 /*!
3992  * Apply a liner function to a given component of \a this array, so that
3993  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
3994  *  \param [in] a - the first coefficient of the function.
3995  *  \param [in] b - the second coefficient of the function.
3996  *  \param [in] compoId - the index of component to modify.
3997  *  \throw If \a this is not allocated.
3998  */
3999 void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception)
4000 {
4001   checkAllocated();
4002   double *ptr=getPointer()+compoId;
4003   int nbOfComp=getNumberOfComponents();
4004   int nbOfTuple=getNumberOfTuples();
4005   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
4006     *ptr=a*(*ptr)+b;
4007   declareAsNew();
4008 }
4009
4010 /*!
4011  * Apply a liner function to all elements of \a this array, so that
4012  * an element _x_ becomes \f$ a * x + b \f$.
4013  *  \param [in] a - the first coefficient of the function.
4014  *  \param [in] b - the second coefficient of the function.
4015  *  \throw If \a this is not allocated.
4016  */
4017 void DataArrayDouble::applyLin(double a, double b) throw(INTERP_KERNEL::Exception)
4018 {
4019   checkAllocated();
4020   double *ptr=getPointer();
4021   std::size_t nbOfElems=getNbOfElems();
4022   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4023     *ptr=a*(*ptr)+b;
4024   declareAsNew();
4025 }
4026
4027 /*!
4028  * Modify all elements of \a this array, so that
4029  * an element _x_ becomes \f$ numerator / x \f$.
4030  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4031  *           array, all elements processed before detection of the zero element remain
4032  *           modified.
4033  *  \param [in] numerator - the numerator used to modify array elements.
4034  *  \throw If \a this is not allocated.
4035  *  \throw If there is an element equal to 0.0 in \a this array.
4036  */
4037 void DataArrayDouble::applyInv(double numerator) throw(INTERP_KERNEL::Exception)
4038 {
4039   checkAllocated();
4040   double *ptr=getPointer();
4041   std::size_t nbOfElems=getNbOfElems();
4042   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4043     {
4044       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4045         {
4046           *ptr=numerator/(*ptr);
4047         }
4048       else
4049         {
4050           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4051           oss << " !";
4052           throw INTERP_KERNEL::Exception(oss.str().c_str());
4053         }
4054     }
4055   declareAsNew();
4056 }
4057
4058 /*!
4059  * Returns a full copy of \a this array except that sign of all elements is reversed.
4060  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4061  *          same number of tuples and component as \a this array.
4062  *          The caller is to delete this result array using decrRef() as it is no more
4063  *          needed.
4064  *  \throw If \a this is not allocated.
4065  */
4066 DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception)
4067 {
4068   checkAllocated();
4069   DataArrayDouble *newArr=DataArrayDouble::New();
4070   int nbOfTuples=getNumberOfTuples();
4071   int nbOfComp=getNumberOfComponents();
4072   newArr->alloc(nbOfTuples,nbOfComp);
4073   const double *cptr=getConstPointer();
4074   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4075   newArr->copyStringInfoFrom(*this);
4076   return newArr;
4077 }
4078
4079 /*!
4080  * Modify all elements of \a this array, so that
4081  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4082  * all values in \a this have to be >= 0 if val is \b not integer.
4083  *  \param [in] val - the value used to apply pow on all array elements.
4084  *  \throw If \a this is not allocated.
4085  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4086  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4087  *           modified.
4088  */
4089 void DataArrayDouble::applyPow(double val) throw(INTERP_KERNEL::Exception)
4090 {
4091   checkAllocated();
4092   double *ptr=getPointer();
4093   std::size_t nbOfElems=getNbOfElems();
4094   int val2=(int)val;
4095   bool isInt=((double)val2)==val;
4096   if(!isInt)
4097     {
4098       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4099         {
4100           if(*ptr>=0)
4101             *ptr=pow(*ptr,val);
4102           else
4103             {
4104               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4105               throw INTERP_KERNEL::Exception(oss.str().c_str());
4106             }
4107         }
4108     }
4109   else
4110     {
4111       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4112         *ptr=pow(*ptr,val2);
4113     }
4114   declareAsNew();
4115 }
4116
4117 /*!
4118  * Modify all elements of \a this array, so that
4119  * an element _x_ becomes \f$ val ^ x \f$.
4120  *  \param [in] val - the value used to apply pow on all array elements.
4121  *  \throw If \a this is not allocated.
4122  *  \throw If \a val < 0.
4123  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4124  *           array, all elements processed before detection of the zero element remain
4125  *           modified.
4126  */
4127 void DataArrayDouble::applyRPow(double val) throw(INTERP_KERNEL::Exception)
4128 {
4129   checkAllocated();
4130   if(val<0.)
4131     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4132   double *ptr=getPointer();
4133   std::size_t nbOfElems=getNbOfElems();
4134   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4135     *ptr=pow(val,*ptr);
4136   declareAsNew();
4137 }
4138
4139 /*!
4140  * Returns a new DataArrayDouble created from \a this one by applying \a
4141  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4142  * For more info see \ref MEDCouplingArrayApplyFunc
4143  *  \param [in] nbOfComp - number of components in the result array.
4144  *  \param [in] func - the \a FunctionToEvaluate declared as 
4145  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4146  *              where \a pos points to the first component of a tuple of \a this array
4147  *              and \a res points to the first component of a tuple of the result array.
4148  *              Note that length (number of components) of \a pos can differ from
4149  *              that of \a res.
4150  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4151  *          same number of tuples as \a this array.
4152  *          The caller is to delete this result array using decrRef() as it is no more
4153  *          needed.
4154  *  \throw If \a this is not allocated.
4155  *  \throw If \a func returns \a false.
4156  */
4157 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception)
4158 {
4159   checkAllocated();
4160   DataArrayDouble *newArr=DataArrayDouble::New();
4161   int nbOfTuples=getNumberOfTuples();
4162   int oldNbOfComp=getNumberOfComponents();
4163   newArr->alloc(nbOfTuples,nbOfComp);
4164   const double *ptr=getConstPointer();
4165   double *ptrToFill=newArr->getPointer();
4166   for(int i=0;i<nbOfTuples;i++)
4167     {
4168       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4169         {
4170           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4171           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4172           oss << ") : Evaluation of function failed !";
4173           newArr->decrRef();
4174           throw INTERP_KERNEL::Exception(oss.str().c_str());
4175         }
4176     }
4177   return newArr;
4178 }
4179
4180 /*!
4181  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4182  * tuple of \a this array. Textual data is not copied.
4183  * For more info see \ref MEDCouplingArrayApplyFunc1.
4184  *  \param [in] nbOfComp - number of components in the result array.
4185  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4186  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4187  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4188  *          same number of tuples as \a this array and \a nbOfComp components.
4189  *          The caller is to delete this result array using decrRef() as it is no more
4190  *          needed.
4191  *  \throw If \a this is not allocated.
4192  *  \throw If computing \a func fails.
4193  */
4194 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
4195 {
4196   checkAllocated();
4197   INTERP_KERNEL::ExprParser expr(func);
4198   expr.parse();
4199   std::set<std::string> vars;
4200   expr.getTrueSetOfVars(vars);
4201   int oldNbOfComp=getNumberOfComponents();
4202   if((int)vars.size()>oldNbOfComp)
4203     {
4204       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4205       oss << vars.size() << " variables : ";
4206       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4207       throw INTERP_KERNEL::Exception(oss.str().c_str());
4208     }
4209   std::vector<std::string> varsV(vars.begin(),vars.end());
4210   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
4211   //
4212   DataArrayDouble *newArr=DataArrayDouble::New();
4213   int nbOfTuples=getNumberOfTuples();
4214   newArr->alloc(nbOfTuples,nbOfComp);
4215   const double *ptr=getConstPointer();
4216   double *ptrToFill=newArr->getPointer();
4217   for(int i=0;i<nbOfTuples;i++)
4218     {
4219       try
4220         {
4221           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4222         }
4223       catch(INTERP_KERNEL::Exception& e)
4224         {
4225           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4226           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4227           oss << ") : Evaluation of function failed !" << e.what();
4228           newArr->decrRef();
4229           throw INTERP_KERNEL::Exception(oss.str().c_str());
4230         }
4231     }
4232   return newArr;
4233 }
4234
4235 /*!
4236  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4237  * tuple of \a this array. Textual data is not copied.
4238  * For more info see \ref MEDCouplingArrayApplyFunc0.
4239  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4240  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4241  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4242  *          same number of tuples and components as \a this array.
4243  *          The caller is to delete this result array using decrRef() as it is no more
4244  *          needed.
4245  *  \throw If \a this is not allocated.
4246  *  \throw If computing \a func fails.
4247  */
4248 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception)
4249 {
4250   checkAllocated();
4251   INTERP_KERNEL::ExprParser expr(func);
4252   expr.parse();
4253   expr.prepareExprEvaluationVec();
4254   //
4255   DataArrayDouble *newArr=DataArrayDouble::New();
4256   int nbOfTuples=getNumberOfTuples();
4257   int nbOfComp=getNumberOfComponents();
4258   newArr->alloc(nbOfTuples,nbOfComp);
4259   const double *ptr=getConstPointer();
4260   double *ptrToFill=newArr->getPointer();
4261   for(int i=0;i<nbOfTuples;i++)
4262     {
4263       try
4264         {
4265           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
4266         }
4267       catch(INTERP_KERNEL::Exception& e)
4268         {
4269           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4270           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4271           oss << ") : Evaluation of function failed ! " << e.what();
4272           newArr->decrRef();
4273           throw INTERP_KERNEL::Exception(oss.str().c_str());
4274         }
4275     }
4276   return newArr;
4277 }
4278
4279 /*!
4280  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4281  * tuple of \a this array. Textual data is not copied.
4282  * For more info see \ref MEDCouplingArrayApplyFunc2.
4283  *  \param [in] nbOfComp - number of components in the result array.
4284  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4285  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4286  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4287  *          same number of tuples as \a this array.
4288  *          The caller is to delete this result array using decrRef() as it is no more
4289  *          needed.
4290  *  \throw If \a this is not allocated.
4291  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4292  *  \throw If computing \a func fails.
4293  */
4294 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
4295 {
4296   checkAllocated();
4297   INTERP_KERNEL::ExprParser expr(func);
4298   expr.parse();
4299   std::set<std::string> vars;
4300   expr.getTrueSetOfVars(vars);
4301   int oldNbOfComp=getNumberOfComponents();
4302   if((int)vars.size()>oldNbOfComp)
4303     {
4304       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4305       oss << vars.size() << " variables : ";
4306       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4307       throw INTERP_KERNEL::Exception(oss.str().c_str());
4308     }
4309   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
4310   //
4311   DataArrayDouble *newArr=DataArrayDouble::New();
4312   int nbOfTuples=getNumberOfTuples();
4313   newArr->alloc(nbOfTuples,nbOfComp);
4314   const double *ptr=getConstPointer();
4315   double *ptrToFill=newArr->getPointer();
4316   for(int i=0;i<nbOfTuples;i++)
4317     {
4318       try
4319         {
4320           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4321         }
4322       catch(INTERP_KERNEL::Exception& e)
4323         {
4324           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4325           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4326           oss << ") : Evaluation of function failed !" << e.what();
4327           newArr->decrRef();
4328           throw INTERP_KERNEL::Exception(oss.str().c_str());
4329         }
4330     }
4331   return newArr;
4332 }
4333
4334 /*!
4335  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4336  * tuple of \a this array. Textual data is not copied.
4337  * For more info see \ref MEDCouplingArrayApplyFunc3.
4338  *  \param [in] nbOfComp - number of components in the result array.
4339  *  \param [in] varsOrder - sequence of vars defining their order.
4340  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4341  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4342  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4343  *          same number of tuples as \a this array.
4344  *          The caller is to delete this result array using decrRef() as it is no more
4345  *          needed.
4346  *  \throw If \a this is not allocated.
4347  *  \throw If \a func contains vars not in \a varsOrder.
4348  *  \throw If computing \a func fails.
4349  */
4350 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const throw(INTERP_KERNEL::Exception)
4351 {
4352   checkAllocated();
4353   INTERP_KERNEL::ExprParser expr(func);
4354   expr.parse();
4355   std::set<std::string> vars;
4356   expr.getTrueSetOfVars(vars);
4357   int oldNbOfComp=getNumberOfComponents();
4358   if((int)vars.size()>oldNbOfComp)
4359     {
4360       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4361       oss << vars.size() << " variables : ";
4362       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4363       throw INTERP_KERNEL::Exception(oss.str().c_str());
4364     }
4365   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
4366   //
4367   DataArrayDouble *newArr=DataArrayDouble::New();
4368   int nbOfTuples=getNumberOfTuples();
4369   newArr->alloc(nbOfTuples,nbOfComp);
4370   const double *ptr=getConstPointer();
4371   double *ptrToFill=newArr->getPointer();
4372   for(int i=0;i<nbOfTuples;i++)
4373     {
4374       try
4375         {
4376           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4377         }
4378       catch(INTERP_KERNEL::Exception& e)
4379         {
4380           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4381           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4382           oss << ") : Evaluation of function failed !" << e.what();
4383           newArr->decrRef();
4384           throw INTERP_KERNEL::Exception(oss.str().c_str());
4385         }
4386     }
4387   return newArr;
4388 }
4389
4390 void DataArrayDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
4391 {
4392   checkAllocated();
4393   INTERP_KERNEL::ExprParser expr(func);
4394   expr.parse();
4395   char *funcStr=expr.compileX86();
4396   MYFUNCPTR funcPtr;
4397   *((void **)&funcPtr)=funcStr;//he he...
4398   //
4399   double *ptr=getPointer();
4400   int nbOfComp=getNumberOfComponents();
4401   int nbOfTuples=getNumberOfTuples();
4402   int nbOfElems=nbOfTuples*nbOfComp;
4403   for(int i=0;i<nbOfElems;i++,ptr++)
4404     *ptr=funcPtr(*ptr);
4405   declareAsNew();
4406 }
4407
4408 void DataArrayDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
4409 {
4410   checkAllocated();
4411   INTERP_KERNEL::ExprParser expr(func);
4412   expr.parse();
4413   char *funcStr=expr.compileX86_64();
4414   MYFUNCPTR funcPtr;
4415   *((void **)&funcPtr)=funcStr;//he he...
4416   //
4417   double *ptr=getPointer();
4418   int nbOfComp=getNumberOfComponents();
4419   int nbOfTuples=getNumberOfTuples();
4420   int nbOfElems=nbOfTuples*nbOfComp;
4421   for(int i=0;i<nbOfElems;i++,ptr++)
4422     *ptr=funcPtr(*ptr);
4423   declareAsNew();
4424 }
4425
4426 DataArrayDoubleIterator *DataArrayDouble::iterator() throw(INTERP_KERNEL::Exception)
4427 {
4428   return new DataArrayDoubleIterator(this);
4429 }
4430
4431 /*!
4432  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4433  * array whose values are within a given range. Textual data is not copied.
4434  *  \param [in] vmin - a lowest acceptable value (included).
4435  *  \param [in] vmax - a greatest acceptable value (included).
4436  *  \return DataArrayInt * - the new instance of DataArrayInt.
4437  *          The caller is to delete this result array using decrRef() as it is no more
4438  *          needed.
4439  *  \throw If \a this->getNumberOfComponents() != 1.
4440  *
4441  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4442  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4443  */
4444 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
4445 {
4446   checkAllocated();
4447   if(getNumberOfComponents()!=1)
4448     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4449   const double *cptr=getConstPointer();
4450   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
4451   int nbOfTuples=getNumberOfTuples();
4452   for(int i=0;i<nbOfTuples;i++,cptr++)
4453     if(*cptr>=vmin && *cptr<=vmax)
4454       ret->pushBackSilent(i);
4455   return ret.retn();
4456 }
4457
4458 /*!
4459  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4460  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4461  * the number of component in the result array is same as that of each of given arrays.
4462  * Info on components is copied from the first of the given arrays. Number of components
4463  * in the given arrays must be  the same.
4464  *  \param [in] a1 - an array to include in the result array.
4465  *  \param [in] a2 - another array to include in the result array.
4466  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4467  *          The caller is to delete this result array using decrRef() as it is no more
4468  *          needed.
4469  *  \throw If both \a a1 and \a a2 are NULL.
4470  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4471  */
4472 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4473 {
4474   std::vector<const DataArrayDouble *> tmp(2);
4475   tmp[0]=a1; tmp[1]=a2;
4476   return Aggregate(tmp);
4477 }
4478
4479 /*!
4480  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4481  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4482  * the number of component in the result array is same as that of each of given arrays.
4483  * Info on components is copied from the first of the given arrays. Number of components
4484  * in the given arrays must be  the same.
4485  *  \param [in] arr - a sequence of arrays to include in the result array.
4486  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4487  *          The caller is to delete this result array using decrRef() as it is no more
4488  *          needed.
4489  *  \throw If all arrays within \a arr are NULL.
4490  *  \throw If getNumberOfComponents() of arrays within \a arr.
4491  */
4492 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4493 {
4494   std::vector<const DataArrayDouble *> a;
4495   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4496     if(*it4)
4497       a.push_back(*it4);
4498   if(a.empty())
4499     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4500   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4501   int nbOfComp=(*it)->getNumberOfComponents();
4502   int nbt=(*it++)->getNumberOfTuples();
4503   for(int i=1;it!=a.end();it++,i++)
4504     {
4505       if((*it)->getNumberOfComponents()!=nbOfComp)
4506         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4507       nbt+=(*it)->getNumberOfTuples();
4508     }
4509   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4510   ret->alloc(nbt,nbOfComp);
4511   double *pt=ret->getPointer();
4512   for(it=a.begin();it!=a.end();it++)
4513     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4514   ret->copyStringInfoFrom(*(a[0]));
4515   return ret.retn();
4516 }
4517
4518 /*!
4519  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4520  * of components in the result array is a sum of the number of components of given arrays
4521  * and (2) the number of tuples in the result array is same as that of each of given
4522  * arrays. In other words the i-th tuple of result array includes all components of
4523  * i-th tuples of all given arrays.
4524  * Number of tuples in the given arrays must be  the same.
4525  *  \param [in] a1 - an array to include in the result array.
4526  *  \param [in] a2 - another array to include in the result array.
4527  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4528  *          The caller is to delete this result array using decrRef() as it is no more
4529  *          needed.
4530  *  \throw If both \a a1 and \a a2 are NULL.
4531  *  \throw If any given array is not allocated.
4532  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4533  */
4534 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4535 {
4536   std::vector<const DataArrayDouble *> arr(2);
4537   arr[0]=a1; arr[1]=a2;
4538   return Meld(arr);
4539 }
4540
4541 /*!
4542  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4543  * of components in the result array is a sum of the number of components of given arrays
4544  * and (2) the number of tuples in the result array is same as that of each of given
4545  * arrays. In other words the i-th tuple of result array includes all components of
4546  * i-th tuples of all given arrays.
4547  * Number of tuples in the given arrays must be  the same.
4548  *  \param [in] arr - a sequence of arrays to include in the result array.
4549  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4550  *          The caller is to delete this result array using decrRef() as it is no more
4551  *          needed.
4552  *  \throw If all arrays within \a arr are NULL.
4553  *  \throw If any given array is not allocated.
4554  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4555  */
4556 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4557 {
4558   std::vector<const DataArrayDouble *> a;
4559   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4560     if(*it4)
4561       a.push_back(*it4);
4562   if(a.empty())
4563     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4564   std::vector<const DataArrayDouble *>::const_iterator it;
4565   for(it=a.begin();it!=a.end();it++)
4566     (*it)->checkAllocated();
4567   it=a.begin();
4568   int nbOfTuples=(*it)->getNumberOfTuples();
4569   std::vector<int> nbc(a.size());
4570   std::vector<const double *> pts(a.size());
4571   nbc[0]=(*it)->getNumberOfComponents();
4572   pts[0]=(*it++)->getConstPointer();
4573   for(int i=1;it!=a.end();it++,i++)
4574     {
4575       if(nbOfTuples!=(*it)->getNumberOfTuples())
4576         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4577       nbc[i]=(*it)->getNumberOfComponents();
4578       pts[i]=(*it)->getConstPointer();
4579     }
4580   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4581   DataArrayDouble *ret=DataArrayDouble::New();
4582   ret->alloc(nbOfTuples,totalNbOfComp);
4583   double *retPtr=ret->getPointer();
4584   for(int i=0;i<nbOfTuples;i++)
4585     for(int j=0;j<(int)a.size();j++)
4586       {
4587         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4588         pts[j]+=nbc[j];
4589       }
4590   int k=0;
4591   for(int i=0;i<(int)a.size();i++)
4592     for(int j=0;j<nbc[i];j++,k++)
4593       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4594   return ret;
4595 }
4596
4597 /*!
4598  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4599  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4600  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4601  * Info on components and name is copied from the first of the given arrays.
4602  * Number of tuples and components in the given arrays must be the same.
4603  *  \param [in] a1 - a given array.
4604  *  \param [in] a2 - another given array.
4605  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4606  *          The caller is to delete this result array using decrRef() as it is no more
4607  *          needed.
4608  *  \throw If either \a a1 or \a a2 is NULL.
4609  *  \throw If any given array is not allocated.
4610  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4611  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4612  */
4613 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4614 {
4615   if(!a1 || !a2)
4616     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4617   a1->checkAllocated();
4618   a2->checkAllocated();
4619   int nbOfComp=a1->getNumberOfComponents();
4620   if(nbOfComp!=a2->getNumberOfComponents())
4621     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4622   int nbOfTuple=a1->getNumberOfTuples();
4623   if(nbOfTuple!=a2->getNumberOfTuples())
4624     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4625   DataArrayDouble *ret=DataArrayDouble::New();
4626   ret->alloc(nbOfTuple,1);
4627   double *retPtr=ret->getPointer();
4628   const double *a1Ptr=a1->getConstPointer();
4629   const double *a2Ptr=a2->getConstPointer();
4630   for(int i=0;i<nbOfTuple;i++)
4631     {
4632       double sum=0.;
4633       for(int j=0;j<nbOfComp;j++)
4634         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4635       retPtr[i]=sum;
4636     }
4637   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4638   ret->setName(a1->getName().c_str());
4639   return ret;
4640 }
4641
4642 /*!
4643  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4644  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4645  * product of two vectors defined by the i-th tuples of given arrays.
4646  * Info on components is copied from the first of the given arrays.
4647  * Number of tuples in the given arrays must be the same.
4648  * Number of components in the given arrays must be 3.
4649  *  \param [in] a1 - a given array.
4650  *  \param [in] a2 - another given array.
4651  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4652  *          The caller is to delete this result array using decrRef() as it is no more
4653  *          needed.
4654  *  \throw If either \a a1 or \a a2 is NULL.
4655  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4656  *  \throw If \a a1->getNumberOfComponents() != 3
4657  *  \throw If \a a2->getNumberOfComponents() != 3
4658  */
4659 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4660 {
4661   if(!a1 || !a2)
4662     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4663   int nbOfComp=a1->getNumberOfComponents();
4664   if(nbOfComp!=a2->getNumberOfComponents())
4665     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4666   if(nbOfComp!=3)
4667     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4668   int nbOfTuple=a1->getNumberOfTuples();
4669   if(nbOfTuple!=a2->getNumberOfTuples())
4670     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4671   DataArrayDouble *ret=DataArrayDouble::New();
4672   ret->alloc(nbOfTuple,3);
4673   double *retPtr=ret->getPointer();
4674   const double *a1Ptr=a1->getConstPointer();
4675   const double *a2Ptr=a2->getConstPointer();
4676   for(int i=0;i<nbOfTuple;i++)
4677     {
4678       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4679       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4680       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4681     }
4682   ret->copyStringInfoFrom(*a1);
4683   return ret;
4684 }
4685
4686 /*!
4687  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4688  * Info on components is copied from the first of the given arrays.
4689  * Number of tuples and components in the given arrays must be the same.
4690  *  \param [in] a1 - an array to compare values with another one.
4691  *  \param [in] a2 - another array to compare values with the first one.
4692  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4693  *          The caller is to delete this result array using decrRef() as it is no more
4694  *          needed.
4695  *  \throw If either \a a1 or \a a2 is NULL.
4696  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4697  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4698  */
4699 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4700 {
4701   if(!a1 || !a2)
4702     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4703   int nbOfComp=a1->getNumberOfComponents();
4704   if(nbOfComp!=a2->getNumberOfComponents())
4705     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4706   int nbOfTuple=a1->getNumberOfTuples();
4707   if(nbOfTuple!=a2->getNumberOfTuples())
4708     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4709   DataArrayDouble *ret=DataArrayDouble::New();
4710   ret->alloc(nbOfTuple,nbOfComp);
4711   double *retPtr=ret->getPointer();
4712   const double *a1Ptr=a1->getConstPointer();
4713   const double *a2Ptr=a2->getConstPointer();
4714   int nbElem=nbOfTuple*nbOfComp;
4715   for(int i=0;i<nbElem;i++)
4716     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4717   ret->copyStringInfoFrom(*a1);
4718   return ret;
4719 }
4720
4721 /*!
4722  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4723  * Info on components is copied from the first of the given arrays.
4724  * Number of tuples and components in the given arrays must be the same.
4725  *  \param [in] a1 - an array to compare values with another one.
4726  *  \param [in] a2 - another array to compare values with the first one.
4727  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4728  *          The caller is to delete this result array using decrRef() as it is no more
4729  *          needed.
4730  *  \throw If either \a a1 or \a a2 is NULL.
4731  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4732  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4733  */
4734 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4735 {
4736   if(!a1 || !a2)
4737     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4738   int nbOfComp=a1->getNumberOfComponents();
4739   if(nbOfComp!=a2->getNumberOfComponents())
4740     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4741   int nbOfTuple=a1->getNumberOfTuples();
4742   if(nbOfTuple!=a2->getNumberOfTuples())
4743     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4744   DataArrayDouble *ret=DataArrayDouble::New();
4745   ret->alloc(nbOfTuple,nbOfComp);
4746   double *retPtr=ret->getPointer();
4747   const double *a1Ptr=a1->getConstPointer();
4748   const double *a2Ptr=a2->getConstPointer();
4749   int nbElem=nbOfTuple*nbOfComp;
4750   for(int i=0;i<nbElem;i++)
4751     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4752   ret->copyStringInfoFrom(*a1);
4753   return ret;
4754 }
4755
4756 /*!
4757  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4758  * valid cases.
4759  * 1.  The arrays have same number of tuples and components. Then each value of
4760  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4761  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4762  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4763  *   component. Then
4764  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4765  * 3.  The arrays have same number of components and one array, say _a2_, has one
4766  *   tuple. Then
4767  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4768  *
4769  * Info on components is copied either from the first array (in the first case) or from
4770  * the array with maximal number of elements (getNbOfElems()).
4771  *  \param [in] a1 - an array to sum up.
4772  *  \param [in] a2 - another array to sum up.
4773  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4774  *          The caller is to delete this result array using decrRef() as it is no more
4775  *          needed.
4776  *  \throw If either \a a1 or \a a2 is NULL.
4777  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4778  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4779  *         none of them has number of tuples or components equal to 1.
4780  */
4781 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4782 {
4783   if(!a1 || !a2)
4784     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4785   int nbOfTuple=a1->getNumberOfTuples();
4786   int nbOfTuple2=a2->getNumberOfTuples();
4787   int nbOfComp=a1->getNumberOfComponents();
4788   int nbOfComp2=a2->getNumberOfComponents();
4789   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4790   if(nbOfTuple==nbOfTuple2)
4791     {
4792       if(nbOfComp==nbOfComp2)
4793         {
4794           ret=DataArrayDouble::New();
4795           ret->alloc(nbOfTuple,nbOfComp);
4796           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4797           ret->copyStringInfoFrom(*a1);
4798         }
4799       else
4800         {
4801           int nbOfCompMin,nbOfCompMax;
4802           const DataArrayDouble *aMin, *aMax;
4803           if(nbOfComp>nbOfComp2)
4804             {
4805               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4806               aMin=a2; aMax=a1;
4807             }
4808           else
4809             {
4810               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4811               aMin=a1; aMax=a2;
4812             }
4813           if(nbOfCompMin==1)
4814             {
4815               ret=DataArrayDouble::New();
4816               ret->alloc(nbOfTuple,nbOfCompMax);
4817               const double *aMinPtr=aMin->getConstPointer();
4818               const double *aMaxPtr=aMax->getConstPointer();
4819               double *res=ret->getPointer();
4820               for(int i=0;i<nbOfTuple;i++)
4821                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4822               ret->copyStringInfoFrom(*aMax);
4823             }
4824           else
4825             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4826         }
4827     }
4828   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4829     {
4830       if(nbOfComp==nbOfComp2)
4831         {
4832           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4833           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4834           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4835           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4836           ret=DataArrayDouble::New();
4837           ret->alloc(nbOfTupleMax,nbOfComp);
4838           double *res=ret->getPointer();
4839           for(int i=0;i<nbOfTupleMax;i++)
4840             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4841           ret->copyStringInfoFrom(*aMax);
4842         }
4843       else
4844         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4845     }
4846   else
4847     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4848   return ret.retn();
4849 }
4850
4851 /*!
4852  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4853  * valid cases.
4854  * 1.  The arrays have same number of tuples and components. Then each value of
4855  *   \a other array is added to the corresponding value of \a this array, i.e.:
4856  *   _a_ [ i, j ] += _other_ [ i, j ].
4857  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4858  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4859  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4860  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4861  *
4862  *  \param [in] other - an array to add to \a this one.
4863  *  \throw If \a other is NULL.
4864  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4865  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4866  *         \a other has number of both tuples and components not equal to 1.
4867  */
4868 void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4869 {
4870   if(!other)
4871     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4872   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4873   checkAllocated();
4874   other->checkAllocated();
4875   int nbOfTuple=getNumberOfTuples();
4876   int nbOfTuple2=other->getNumberOfTuples();
4877   int nbOfComp=getNumberOfComponents();
4878   int nbOfComp2=other->getNumberOfComponents();
4879   if(nbOfTuple==nbOfTuple2)
4880     {
4881       if(nbOfComp==nbOfComp2)
4882         {
4883           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4884         }
4885       else if(nbOfComp2==1)
4886         {
4887           double *ptr=getPointer();
4888           const double *ptrc=other->getConstPointer();
4889           for(int i=0;i<nbOfTuple;i++)
4890             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4891         }
4892       else
4893         throw INTERP_KERNEL::Exception(msg);
4894     }
4895   else if(nbOfTuple2==1)
4896     {
4897       if(nbOfComp2==nbOfComp)
4898         {
4899           double *ptr=getPointer();
4900           const double *ptrc=other->getConstPointer();
4901           for(int i=0;i<nbOfTuple;i++)
4902             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4903         }
4904       else
4905         throw INTERP_KERNEL::Exception(msg);
4906     }
4907   else
4908     throw INTERP_KERNEL::Exception(msg);
4909   declareAsNew();
4910 }
4911
4912 /*!
4913  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4914  * valid cases.
4915  * 1.  The arrays have same number of tuples and components. Then each value of
4916  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4917  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4918  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4919  *   component. Then
4920  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4921  * 3.  The arrays have same number of components and one array, say _a2_, has one
4922  *   tuple. Then
4923  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4924  *
4925  * Info on components is copied either from the first array (in the first case) or from
4926  * the array with maximal number of elements (getNbOfElems()).
4927  *  \param [in] a1 - an array to subtract from.
4928  *  \param [in] a2 - an array to subtract.
4929  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4930  *          The caller is to delete this result array using decrRef() as it is no more
4931  *          needed.
4932  *  \throw If either \a a1 or \a a2 is NULL.
4933  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4934  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4935  *         none of them has number of tuples or components equal to 1.
4936  */
4937 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4938 {
4939   if(!a1 || !a2)
4940     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
4941   int nbOfTuple1=a1->getNumberOfTuples();
4942   int nbOfTuple2=a2->getNumberOfTuples();
4943   int nbOfComp1=a1->getNumberOfComponents();
4944   int nbOfComp2=a2->getNumberOfComponents();
4945   if(nbOfTuple2==nbOfTuple1)
4946     {
4947       if(nbOfComp1==nbOfComp2)
4948         {
4949           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4950           ret->alloc(nbOfTuple2,nbOfComp1);
4951           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
4952           ret->copyStringInfoFrom(*a1);
4953           return ret.retn();
4954         }
4955       else if(nbOfComp2==1)
4956         {
4957           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4958           ret->alloc(nbOfTuple1,nbOfComp1);
4959           const double *a2Ptr=a2->getConstPointer();
4960           const double *a1Ptr=a1->getConstPointer();
4961           double *res=ret->getPointer();
4962           for(int i=0;i<nbOfTuple1;i++)
4963             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
4964           ret->copyStringInfoFrom(*a1);
4965           return ret.retn();
4966         }
4967       else
4968         {
4969           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4970           return 0;
4971         }
4972     }
4973   else if(nbOfTuple2==1)
4974     {
4975       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4976       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4977       ret->alloc(nbOfTuple1,nbOfComp1);
4978       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4979       double *pt=ret->getPointer();
4980       for(int i=0;i<nbOfTuple1;i++)
4981         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
4982       ret->copyStringInfoFrom(*a1);
4983       return ret.retn();
4984     }
4985   else
4986     {
4987       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
4988       return 0;
4989     }
4990 }
4991
4992 /*!
4993  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
4994  * valid cases.
4995  * 1.  The arrays have same number of tuples and components. Then each value of
4996  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
4997  *   _a_ [ i, j ] -= _other_ [ i, j ].
4998  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4999  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
5000  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5001  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
5002  *
5003  *  \param [in] other - an array to subtract from \a this one.
5004  *  \throw If \a other is NULL.
5005  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5006  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5007  *         \a other has number of both tuples and components not equal to 1.
5008  */
5009 void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5010 {
5011   if(!other)
5012     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
5013   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
5014   checkAllocated();
5015   other->checkAllocated();
5016   int nbOfTuple=getNumberOfTuples();
5017   int nbOfTuple2=other->getNumberOfTuples();
5018   int nbOfComp=getNumberOfComponents();
5019   int nbOfComp2=other->getNumberOfComponents();
5020   if(nbOfTuple==nbOfTuple2)
5021     {
5022       if(nbOfComp==nbOfComp2)
5023         {
5024           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5025         }
5026       else if(nbOfComp2==1)
5027         {
5028           double *ptr=getPointer();
5029           const double *ptrc=other->getConstPointer();
5030           for(int i=0;i<nbOfTuple;i++)
5031             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5032         }
5033       else
5034         throw INTERP_KERNEL::Exception(msg);
5035     }
5036   else if(nbOfTuple2==1)
5037     {
5038       if(nbOfComp2==nbOfComp)
5039         {
5040           double *ptr=getPointer();
5041           const double *ptrc=other->getConstPointer();
5042           for(int i=0;i<nbOfTuple;i++)
5043             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5044         }
5045       else
5046         throw INTERP_KERNEL::Exception(msg);
5047     }
5048   else
5049     throw INTERP_KERNEL::Exception(msg);
5050   declareAsNew();
5051 }
5052
5053 /*!
5054  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5055  * valid cases.
5056  * 1.  The arrays have same number of tuples and components. Then each value of
5057  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5058  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5059  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5060  *   component. Then
5061  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5062  * 3.  The arrays have same number of components and one array, say _a2_, has one
5063  *   tuple. Then
5064  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5065  *
5066  * Info on components is copied either from the first array (in the first case) or from
5067  * the array with maximal number of elements (getNbOfElems()).
5068  *  \param [in] a1 - a factor array.
5069  *  \param [in] a2 - another factor array.
5070  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5071  *          The caller is to delete this result array using decrRef() as it is no more
5072  *          needed.
5073  *  \throw If either \a a1 or \a a2 is NULL.
5074  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5075  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5076  *         none of them has number of tuples or components equal to 1.
5077  */
5078 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5079 {
5080   if(!a1 || !a2)
5081     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5082   int nbOfTuple=a1->getNumberOfTuples();
5083   int nbOfTuple2=a2->getNumberOfTuples();
5084   int nbOfComp=a1->getNumberOfComponents();
5085   int nbOfComp2=a2->getNumberOfComponents();
5086   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5087   if(nbOfTuple==nbOfTuple2)
5088     {
5089       if(nbOfComp==nbOfComp2)
5090         {
5091           ret=DataArrayDouble::New();
5092           ret->alloc(nbOfTuple,nbOfComp);
5093           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5094           ret->copyStringInfoFrom(*a1);
5095         }
5096       else
5097         {
5098           int nbOfCompMin,nbOfCompMax;
5099           const DataArrayDouble *aMin, *aMax;
5100           if(nbOfComp>nbOfComp2)
5101             {
5102               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5103               aMin=a2; aMax=a1;
5104             }
5105           else
5106             {
5107               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5108               aMin=a1; aMax=a2;
5109             }
5110           if(nbOfCompMin==1)
5111             {
5112               ret=DataArrayDouble::New();
5113               ret->alloc(nbOfTuple,nbOfCompMax);
5114               const double *aMinPtr=aMin->getConstPointer();
5115               const double *aMaxPtr=aMax->getConstPointer();
5116               double *res=ret->getPointer();
5117               for(int i=0;i<nbOfTuple;i++)
5118                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5119               ret->copyStringInfoFrom(*aMax);
5120             }
5121           else
5122             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5123         }
5124     }
5125   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5126     {
5127       if(nbOfComp==nbOfComp2)
5128         {
5129           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5130           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5131           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5132           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5133           ret=DataArrayDouble::New();
5134           ret->alloc(nbOfTupleMax,nbOfComp);
5135           double *res=ret->getPointer();
5136           for(int i=0;i<nbOfTupleMax;i++)
5137             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5138           ret->copyStringInfoFrom(*aMax);
5139         }
5140       else
5141         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5142     }
5143   else
5144     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5145   return ret.retn();
5146 }
5147
5148 /*!
5149  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5150  * valid cases.
5151  * 1.  The arrays have same number of tuples and components. Then each value of
5152  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5153  *   _this_ [ i, j ] *= _other_ [ i, j ].
5154  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5155  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5156  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5157  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5158  *
5159  *  \param [in] other - an array to multiply to \a this one.
5160  *  \throw If \a other is NULL.
5161  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5162  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5163  *         \a other has number of both tuples and components not equal to 1.
5164  */
5165 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5166 {
5167   if(!other)
5168     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5169   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5170   checkAllocated();
5171   other->checkAllocated();
5172   int nbOfTuple=getNumberOfTuples();
5173   int nbOfTuple2=other->getNumberOfTuples();
5174   int nbOfComp=getNumberOfComponents();
5175   int nbOfComp2=other->getNumberOfComponents();
5176   if(nbOfTuple==nbOfTuple2)
5177     {
5178       if(nbOfComp==nbOfComp2)
5179         {
5180           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5181         }
5182       else if(nbOfComp2==1)
5183         {
5184           double *ptr=getPointer();
5185           const double *ptrc=other->getConstPointer();
5186           for(int i=0;i<nbOfTuple;i++)
5187             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5188         }
5189       else
5190         throw INTERP_KERNEL::Exception(msg);
5191     }
5192   else if(nbOfTuple2==1)
5193     {
5194       if(nbOfComp2==nbOfComp)
5195         {
5196           double *ptr=getPointer();
5197           const double *ptrc=other->getConstPointer();
5198           for(int i=0;i<nbOfTuple;i++)
5199             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5200         }
5201       else
5202         throw INTERP_KERNEL::Exception(msg);
5203     }
5204   else
5205     throw INTERP_KERNEL::Exception(msg);
5206   declareAsNew();
5207 }
5208
5209 /*!
5210  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5211  * valid cases.
5212  * 1.  The arrays have same number of tuples and components. Then each value of
5213  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5214  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5215  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5216  *   component. Then
5217  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5218  * 3.  The arrays have same number of components and one array, say _a2_, has one
5219  *   tuple. Then
5220  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5221  *
5222  * Info on components is copied either from the first array (in the first case) or from
5223  * the array with maximal number of elements (getNbOfElems()).
5224  *  \warning No check of division by zero is performed!
5225  *  \param [in] a1 - a numerator array.
5226  *  \param [in] a2 - a denominator array.
5227  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5228  *          The caller is to delete this result array using decrRef() as it is no more
5229  *          needed.
5230  *  \throw If either \a a1 or \a a2 is NULL.
5231  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5232  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5233  *         none of them has number of tuples or components equal to 1.
5234  */
5235 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5236 {
5237   if(!a1 || !a2)
5238     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5239   int nbOfTuple1=a1->getNumberOfTuples();
5240   int nbOfTuple2=a2->getNumberOfTuples();
5241   int nbOfComp1=a1->getNumberOfComponents();
5242   int nbOfComp2=a2->getNumberOfComponents();
5243   if(nbOfTuple2==nbOfTuple1)
5244     {
5245       if(nbOfComp1==nbOfComp2)
5246         {
5247           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5248           ret->alloc(nbOfTuple2,nbOfComp1);
5249           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5250           ret->copyStringInfoFrom(*a1);
5251           return ret.retn();
5252         }
5253       else if(nbOfComp2==1)
5254         {
5255           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5256           ret->alloc(nbOfTuple1,nbOfComp1);
5257           const double *a2Ptr=a2->getConstPointer();
5258           const double *a1Ptr=a1->getConstPointer();
5259           double *res=ret->getPointer();
5260           for(int i=0;i<nbOfTuple1;i++)
5261             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5262           ret->copyStringInfoFrom(*a1);
5263           return ret.retn();
5264         }
5265       else
5266         {
5267           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5268           return 0;
5269         }
5270     }
5271   else if(nbOfTuple2==1)
5272     {
5273       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5274       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5275       ret->alloc(nbOfTuple1,nbOfComp1);
5276       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5277       double *pt=ret->getPointer();
5278       for(int i=0;i<nbOfTuple1;i++)
5279         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5280       ret->copyStringInfoFrom(*a1);
5281       return ret.retn();
5282     }
5283   else
5284     {
5285       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5286       return 0;
5287     }
5288 }
5289
5290 /*!
5291  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5292  * valid cases.
5293  * 1.  The arrays have same number of tuples and components. Then each value of
5294  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5295  *   _a_ [ i, j ] /= _other_ [ i, j ].
5296  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5297  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5298  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5299  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5300  *
5301  *  \warning No check of division by zero is performed!
5302  *  \param [in] other - an array to divide \a this one by.
5303  *  \throw If \a other is NULL.
5304  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5305  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5306  *         \a other has number of both tuples and components not equal to 1.
5307  */
5308 void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5309 {
5310   if(!other)
5311     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5312   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5313   checkAllocated();
5314   other->checkAllocated();
5315   int nbOfTuple=getNumberOfTuples();
5316   int nbOfTuple2=other->getNumberOfTuples();
5317   int nbOfComp=getNumberOfComponents();
5318   int nbOfComp2=other->getNumberOfComponents();
5319   if(nbOfTuple==nbOfTuple2)
5320     {
5321       if(nbOfComp==nbOfComp2)
5322         {
5323           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5324         }
5325       else if(nbOfComp2==1)
5326         {
5327           double *ptr=getPointer();
5328           const double *ptrc=other->getConstPointer();
5329           for(int i=0;i<nbOfTuple;i++)
5330             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5331         }
5332       else
5333         throw INTERP_KERNEL::Exception(msg);
5334     }
5335   else if(nbOfTuple2==1)
5336     {
5337       if(nbOfComp2==nbOfComp)
5338         {
5339           double *ptr=getPointer();
5340           const double *ptrc=other->getConstPointer();
5341           for(int i=0;i<nbOfTuple;i++)
5342             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5343         }
5344       else
5345         throw INTERP_KERNEL::Exception(msg);
5346     }
5347   else
5348     throw INTERP_KERNEL::Exception(msg);
5349   declareAsNew();
5350 }
5351
5352 /*!
5353  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5354  * valid cases.
5355  *
5356  *  \param [in] a1 - an array to pow up.
5357  *  \param [in] a2 - another array to sum up.
5358  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5359  *          The caller is to delete this result array using decrRef() as it is no more
5360  *          needed.
5361  *  \throw If either \a a1 or \a a2 is NULL.
5362  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5363  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5364  *  \throw If there is a negative value in \a a1.
5365  */
5366 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5367 {
5368   if(!a1 || !a2)
5369     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5370   int nbOfTuple=a1->getNumberOfTuples();
5371   int nbOfTuple2=a2->getNumberOfTuples();
5372   int nbOfComp=a1->getNumberOfComponents();
5373   int nbOfComp2=a2->getNumberOfComponents();
5374   if(nbOfTuple!=nbOfTuple2)
5375     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5376   if(nbOfComp!=1 || nbOfComp2!=1)
5377     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5378   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5379   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5380   double *ptr=ret->getPointer();
5381   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5382     {
5383       if(*ptr1>=0)
5384         {
5385           *ptr=pow(*ptr1,*ptr2);
5386         }
5387       else
5388         {
5389           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5390           throw INTERP_KERNEL::Exception(oss.str().c_str());
5391         }
5392     }
5393   return ret.retn();
5394 }
5395
5396 /*!
5397  * Apply pow on values of another DataArrayDouble to values of \a this one.
5398  *
5399  *  \param [in] other - an array to pow to \a this one.
5400  *  \throw If \a other is NULL.
5401  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5402  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5403  *  \throw If there is a negative value in \a this.
5404  */
5405 void DataArrayDouble::powEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5406 {
5407   if(!other)
5408     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5409   int nbOfTuple=getNumberOfTuples();
5410   int nbOfTuple2=other->getNumberOfTuples();
5411   int nbOfComp=getNumberOfComponents();
5412   int nbOfComp2=other->getNumberOfComponents();
5413   if(nbOfTuple!=nbOfTuple2)
5414     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5415   if(nbOfComp!=1 || nbOfComp2!=1)
5416     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5417   double *ptr=getPointer();
5418   const double *ptrc=other->begin();
5419   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5420     {
5421       if(*ptr>=0)
5422         *ptr=pow(*ptr,*ptrc);
5423       else
5424         {
5425           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5426           throw INTERP_KERNEL::Exception(oss.str().c_str());
5427         }
5428     }
5429   declareAsNew();
5430 }
5431
5432 /*!
5433  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5434  * Server side.
5435  */
5436 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5437 {
5438   tinyInfo.resize(2);
5439   if(isAllocated())
5440     {
5441       tinyInfo[0]=getNumberOfTuples();
5442       tinyInfo[1]=getNumberOfComponents();
5443     }
5444   else
5445     {
5446       tinyInfo[0]=-1;
5447       tinyInfo[1]=-1;
5448     }
5449 }
5450
5451 /*!
5452  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5453  * Server side.
5454  */
5455 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5456 {
5457   if(isAllocated())
5458     {
5459       int nbOfCompo=getNumberOfComponents();
5460       tinyInfo.resize(nbOfCompo+1);
5461       tinyInfo[0]=getName();
5462       for(int i=0;i<nbOfCompo;i++)
5463         tinyInfo[i+1]=getInfoOnComponent(i);
5464     }
5465   else
5466     {
5467       tinyInfo.resize(1);
5468       tinyInfo[0]=getName();
5469     }
5470 }
5471
5472 /*!
5473  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5474  * This method returns if a feeding is needed.
5475  */
5476 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5477 {
5478   int nbOfTuple=tinyInfoI[0];
5479   int nbOfComp=tinyInfoI[1];
5480   if(nbOfTuple!=-1 || nbOfComp!=-1)
5481     {
5482       alloc(nbOfTuple,nbOfComp);
5483       return true;
5484     }
5485   return false;
5486 }
5487
5488 /*!
5489  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5490  */
5491 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5492 {
5493   setName(tinyInfoS[0].c_str());
5494   if(isAllocated())
5495     {
5496       int nbOfCompo=getNumberOfComponents();
5497       for(int i=0;i<nbOfCompo;i++)
5498         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
5499     }
5500 }
5501
5502 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5503 {
5504   if(_da)
5505     {
5506       _da->incrRef();
5507       if(_da->isAllocated())
5508         {
5509           _nb_comp=da->getNumberOfComponents();
5510           _nb_tuple=da->getNumberOfTuples();
5511           _pt=da->getPointer();
5512         }
5513     }
5514 }
5515
5516 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5517 {
5518   if(_da)
5519     _da->decrRef();
5520 }
5521
5522 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() throw(INTERP_KERNEL::Exception)
5523 {
5524   if(_tuple_id<_nb_tuple)
5525     {
5526       _tuple_id++;
5527       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5528       _pt+=_nb_comp;
5529       return ret;
5530     }
5531   else
5532     return 0;
5533 }
5534
5535 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5536 {
5537 }
5538
5539
5540 std::string DataArrayDoubleTuple::repr() const throw(INTERP_KERNEL::Exception)
5541 {
5542   std::ostringstream oss; oss.precision(17); oss << "(";
5543   for(int i=0;i<_nb_of_compo-1;i++)
5544     oss << _pt[i] << ", ";
5545   oss << _pt[_nb_of_compo-1] << ")";
5546   return oss.str();
5547 }
5548
5549 double DataArrayDoubleTuple::doubleValue() const throw(INTERP_KERNEL::Exception)
5550 {
5551   if(_nb_of_compo==1)
5552     return *_pt;
5553   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5554 }
5555
5556 /*!
5557  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5558  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5559  * 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
5560  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5561  */
5562 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
5563 {
5564   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5565     {
5566       DataArrayDouble *ret=DataArrayDouble::New();
5567       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5568       return ret;
5569     }
5570   else
5571     {
5572       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5573       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5574       throw INTERP_KERNEL::Exception(oss.str().c_str());
5575     }
5576 }
5577
5578 /*!
5579  * Returns a new instance of DataArrayInt. The caller is to delete this array
5580  * using decrRef() as it is no more needed. 
5581  */
5582 DataArrayInt *DataArrayInt::New()
5583 {
5584   return new DataArrayInt;
5585 }
5586
5587 /*!
5588  * Checks if raw data is allocated. Read more on the raw data
5589  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5590  *  \return bool - \a true if the raw data is allocated, \a false else.
5591  */
5592 bool DataArrayInt::isAllocated() const throw(INTERP_KERNEL::Exception)
5593 {
5594   return getConstPointer()!=0;
5595 }
5596
5597 /*!
5598  * Checks if raw data is allocated and throws an exception if it is not the case.
5599  *  \throw If the raw data is not allocated.
5600  */
5601 void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception)
5602 {
5603   if(!isAllocated())
5604     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5605 }
5606
5607 /*!
5608  * This method desallocated \a this without modification of informations relative to the components.
5609  * After call of this method, DataArrayInt::isAllocated will return false.
5610  * If \a this is already not allocated, \a this is let unchanged.
5611  */
5612 void DataArrayInt::desallocate() throw(INTERP_KERNEL::Exception)
5613 {
5614   _mem.destroy();
5615 }
5616
5617 std::size_t DataArrayInt::getHeapMemorySize() const
5618 {
5619   std::size_t sz=_mem.getNbOfElemAllocated();
5620   sz*=sizeof(int);
5621   return DataArray::getHeapMemorySize()+sz;
5622 }
5623
5624 /*!
5625  * Returns the only one value in \a this, if and only if number of elements
5626  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5627  *  \return double - the sole value stored in \a this array.
5628  *  \throw If at least one of conditions stated above is not fulfilled.
5629  */
5630 int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception)
5631 {
5632   if(isAllocated())
5633     {
5634       if(getNbOfElems()==1)
5635         {
5636           return *getConstPointer();
5637         }
5638       else
5639         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5640     }
5641   else
5642     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5643 }
5644
5645 /*!
5646  * Returns an integer value characterizing \a this array, which is useful for a quick
5647  * comparison of many instances of DataArrayInt.
5648  *  \return int - the hash value.
5649  *  \throw If \a this is not allocated.
5650  */
5651 int DataArrayInt::getHashCode() const throw(INTERP_KERNEL::Exception)
5652 {
5653   checkAllocated();
5654   std::size_t nbOfElems=getNbOfElems();
5655   int ret=nbOfElems*65536;
5656   int delta=3;
5657   if(nbOfElems>48)
5658     delta=nbOfElems/8;
5659   int ret0=0;
5660   const int *pt=begin();
5661   for(std::size_t i=0;i<nbOfElems;i+=delta)
5662     ret0+=pt[i] & 0x1FFF;
5663   return ret+ret0;
5664 }
5665
5666 /*!
5667  * Checks the number of tuples.
5668  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5669  *  \throw If \a this is not allocated.
5670  */
5671 bool DataArrayInt::empty() const throw(INTERP_KERNEL::Exception)
5672 {
5673   checkAllocated();
5674   return getNumberOfTuples()==0;
5675 }
5676
5677 /*!
5678  * Returns a full copy of \a this. For more info on copying data arrays see
5679  * \ref MEDCouplingArrayBasicsCopyDeep.
5680  *  \return DataArrayInt * - a new instance of DataArrayInt.
5681  */
5682 DataArrayInt *DataArrayInt::deepCpy() const throw(INTERP_KERNEL::Exception)
5683 {
5684   return new DataArrayInt(*this);
5685 }
5686
5687 /*!
5688  * Returns either a \a deep or \a shallow copy of this array. For more info see
5689  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5690  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5691  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5692  *          == \a true) or \a this instance (if \a dCpy == \a false).
5693  */
5694 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
5695 {
5696   if(dCpy)
5697     return deepCpy();
5698   else
5699     {
5700       incrRef();
5701       return const_cast<DataArrayInt *>(this);
5702     }
5703 }
5704
5705 /*!
5706  * Copies all the data from another DataArrayInt. For more info see
5707  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5708  *  \param [in] other - another instance of DataArrayInt to copy data from.
5709  *  \throw If the \a other is not allocated.
5710  */
5711 void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception)
5712 {
5713   other.checkAllocated();
5714   int nbOfTuples=other.getNumberOfTuples();
5715   int nbOfComp=other.getNumberOfComponents();
5716   allocIfNecessary(nbOfTuples,nbOfComp);
5717   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5718   int *pt=getPointer();
5719   const int *ptI=other.getConstPointer();
5720   for(std::size_t i=0;i<nbOfElems;i++)
5721     pt[i]=ptI[i];
5722   copyStringInfoFrom(other);
5723 }
5724
5725 /*!
5726  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5727  * 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.
5728  * If \a this has not already been allocated, number of components is set to one.
5729  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5730  * 
5731  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5732  */
5733 void DataArrayInt::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
5734 {
5735   int nbCompo=getNumberOfComponents();
5736   if(nbCompo==1)
5737     {
5738       _mem.reserve(nbOfElems);
5739     }
5740   else if(nbCompo==0)
5741     {
5742       _mem.reserve(nbOfElems);
5743       _info_on_compo.resize(1);
5744     }
5745   else
5746     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5747 }
5748
5749 /*!
5750  * 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
5751  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5752  *
5753  * \param [in] val the value to be added in \a this
5754  * \throw If \a this has already been allocated with number of components different from one.
5755  * \sa DataArrayInt::pushBackValsSilent
5756  */
5757 void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception)
5758 {
5759   int nbCompo=getNumberOfComponents();
5760   if(nbCompo==1)
5761     _mem.pushBack(val);
5762   else if(nbCompo==0)
5763     {
5764       _info_on_compo.resize(1);
5765       _mem.pushBack(val);
5766     }
5767   else
5768     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5769 }
5770
5771 /*!
5772  * 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
5773  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5774  *
5775  *  \param [in] valsBg - an array of values to push at the end of \this.
5776  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5777  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5778  * \throw If \a this has already been allocated with number of components different from one.
5779  * \sa DataArrayInt::pushBackSilent
5780  */
5781 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd) throw(INTERP_KERNEL::Exception)
5782 {
5783   int nbCompo=getNumberOfComponents();
5784   if(nbCompo==1)
5785     _mem.insertAtTheEnd(valsBg,valsEnd);
5786   else if(nbCompo==0)
5787     {
5788       _info_on_compo.resize(1);
5789       _mem.insertAtTheEnd(valsBg,valsEnd);
5790     }
5791   else
5792     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5793 }
5794
5795 /*!
5796  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5797  * \throw If \a this is already empty.
5798  * \throw If \a this has number of components different from one.
5799  */
5800 int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception)
5801 {
5802   if(getNumberOfComponents()==1)
5803     return _mem.popBack();
5804   else
5805     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5806 }
5807
5808 /*!
5809  * 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.
5810  *
5811  * \sa DataArrayInt::getHeapMemorySize, DataArrayInt::reserve
5812  */
5813 void DataArrayInt::pack() const throw(INTERP_KERNEL::Exception)
5814 {
5815   _mem.pack();
5816 }
5817
5818 /*!
5819  * Allocates the raw data in memory. If exactly as same memory as needed already
5820  * allocated, it is not re-allocated.
5821  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5822  *  \param [in] nbOfCompo - number of components of data to allocate.
5823  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5824  */
5825 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5826 {
5827   if(isAllocated())
5828     {
5829       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5830         alloc(nbOfTuple,nbOfCompo);
5831     }
5832   else
5833     alloc(nbOfTuple,nbOfCompo);
5834 }
5835
5836 /*!
5837  * Allocates the raw data in memory. If the memory was already allocated, then it is
5838  * freed and re-allocated. See an example of this method use
5839  * \ref MEDCouplingArraySteps1WC "here".
5840  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5841  *  \param [in] nbOfCompo - number of components of data to allocate.
5842  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5843  */
5844 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5845 {
5846   if(nbOfTuple<0 || nbOfCompo<0)
5847     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5848   _info_on_compo.resize(nbOfCompo);
5849   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
5850   declareAsNew();
5851 }
5852
5853 /*!
5854  * Assign zero to all values in \a this array. To know more on filling arrays see
5855  * \ref MEDCouplingArrayFill.
5856  * \throw If \a this is not allocated.
5857  */
5858 void DataArrayInt::fillWithZero() throw(INTERP_KERNEL::Exception)
5859 {
5860   checkAllocated();
5861   _mem.fillWithValue(0);
5862   declareAsNew();
5863 }
5864
5865 /*!
5866  * Assign \a val to all values in \a this array. To know more on filling arrays see
5867  * \ref MEDCouplingArrayFill.
5868  *  \param [in] val - the value to fill with.
5869  *  \throw If \a this is not allocated.
5870  */
5871 void DataArrayInt::fillWithValue(int val) throw(INTERP_KERNEL::Exception)
5872 {
5873   checkAllocated();
5874   _mem.fillWithValue(val);
5875   declareAsNew();
5876 }
5877
5878 /*!
5879  * Set all values in \a this array so that the i-th element equals to \a init + i
5880  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5881  *  \param [in] init - value to assign to the first element of array.
5882  *  \throw If \a this->getNumberOfComponents() != 1
5883  *  \throw If \a this is not allocated.
5884  */
5885 void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception)
5886 {
5887   checkAllocated();
5888   if(getNumberOfComponents()!=1)
5889     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5890   int *ptr=getPointer();
5891   int ntuples=getNumberOfTuples();
5892   for(int i=0;i<ntuples;i++)
5893     ptr[i]=init+i;
5894   declareAsNew();
5895 }
5896
5897 /*!
5898  * Returns a textual and human readable representation of \a this instance of
5899  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5900  *  \return std::string - text describing \a this DataArrayInt.
5901  */
5902 std::string DataArrayInt::repr() const throw(INTERP_KERNEL::Exception)
5903 {
5904   std::ostringstream ret;
5905   reprStream(ret);
5906   return ret.str();
5907 }
5908
5909 std::string DataArrayInt::reprZip() const throw(INTERP_KERNEL::Exception)
5910 {
5911   std::ostringstream ret;
5912   reprZipStream(ret);
5913   return ret.str();
5914 }
5915
5916 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile, DataArrayByte *byteArr) const throw(INTERP_KERNEL::Exception)
5917 {
5918   static const char SPACE[4]={' ',' ',' ',' '};
5919   checkAllocated();
5920   std::string idt(indent,' ');
5921   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5922   if(byteArr)
5923     {
5924       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
5925       if(std::string(type)=="Int32")
5926         {
5927           const char *data(reinterpret_cast<const char *>(begin()));
5928           std::size_t sz(getNbOfElems()*sizeof(int));
5929           byteArr->insertAtTheEnd(data,data+sz);
5930           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5931         }
5932       else if(std::string(type)=="Int8")
5933         {
5934           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
5935           std::copy(begin(),end(),(char *)tmp);
5936           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
5937           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5938         }
5939       else if(std::string(type)=="UInt8")
5940         {
5941           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
5942           std::copy(begin(),end(),(unsigned char *)tmp);
5943           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
5944           byteArr->insertAtTheEnd(SPACE,SPACE+4);
5945         }
5946       else
5947         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
5948     }
5949   else
5950     {
5951       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
5952       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
5953     }
5954   ofs << std::endl << idt << "</DataArray>\n";
5955 }
5956
5957 void DataArrayInt::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5958 {
5959   stream << "Name of int array : \"" << _name << "\"\n";
5960   reprWithoutNameStream(stream);
5961 }
5962
5963 void DataArrayInt::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5964 {
5965   stream << "Name of int array : \"" << _name << "\"\n";
5966   reprZipWithoutNameStream(stream);
5967 }
5968
5969 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5970 {
5971   DataArray::reprWithoutNameStream(stream);
5972   _mem.repr(getNumberOfComponents(),stream);
5973 }
5974
5975 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5976 {
5977   DataArray::reprWithoutNameStream(stream);
5978   _mem.reprZip(getNumberOfComponents(),stream);
5979 }
5980
5981 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5982 {
5983   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
5984   const int *data=getConstPointer();
5985   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
5986   if(nbTuples*nbComp>=1)
5987     {
5988       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
5989       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
5990       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
5991       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
5992     }
5993   else
5994     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
5995   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
5996 }
5997
5998 /*!
5999  * Method that gives a quick overvien of \a this for python.
6000  */
6001 void DataArrayInt::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
6002 {
6003   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6004   stream << "DataArrayInt C++ instance at " << this << ". ";
6005   if(isAllocated())
6006     {
6007       int nbOfCompo=(int)_info_on_compo.size();
6008       if(nbOfCompo>=1)
6009         {
6010           int nbOfTuples=getNumberOfTuples();
6011           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6012           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6013         }
6014       else
6015         stream << "Number of components : 0.";
6016     }
6017   else
6018     stream << "*** No data allocated ****";
6019 }
6020
6021 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
6022 {
6023   const int *data=begin();
6024   int nbOfTuples=getNumberOfTuples();
6025   int nbOfCompo=(int)_info_on_compo.size();
6026   std::ostringstream oss2; oss2 << "[";
6027   std::string oss2Str(oss2.str());
6028   bool isFinished=true;
6029   for(int i=0;i<nbOfTuples && isFinished;i++)
6030     {
6031       if(nbOfCompo>1)
6032         {
6033           oss2 << "(";
6034           for(int j=0;j<nbOfCompo;j++,data++)
6035             {
6036               oss2 << *data;
6037               if(j!=nbOfCompo-1) oss2 << ", ";
6038             }
6039           oss2 << ")";
6040         }
6041       else
6042         oss2 << *data++;
6043       if(i!=nbOfTuples-1) oss2 << ", ";
6044       std::string oss3Str(oss2.str());
6045       if(oss3Str.length()<maxNbOfByteInRepr)
6046         oss2Str=oss3Str;
6047       else
6048         isFinished=false;
6049     }
6050   stream << oss2Str;
6051   if(!isFinished)
6052     stream << "... ";
6053   stream << "]";
6054 }
6055
6056 /*!
6057  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6058  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6059  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6060  *         to \a this array.
6061  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6062  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6063  *  \throw If \a this->getNumberOfComponents() != 1
6064  *  \throw If any value of \a this can't be used as a valid index for 
6065  *         [\a indArrBg, \a indArrEnd).
6066  */
6067 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception)
6068 {
6069   checkAllocated();
6070   if(getNumberOfComponents()!=1)
6071     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6072   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6073   int nbOfTuples=getNumberOfTuples();
6074   int *pt=getPointer();
6075   for(int i=0;i<nbOfTuples;i++,pt++)
6076     {
6077       if(*pt>=0 && *pt<nbElemsIn)
6078         *pt=indArrBg[*pt];
6079       else
6080         {
6081           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6082           throw INTERP_KERNEL::Exception(oss.str().c_str());
6083         }
6084     }
6085   declareAsNew();
6086 }
6087
6088 /*!
6089  * Computes distribution of values of \a this one-dimensional array between given value
6090  * ranges (casts). This method is typically useful for entity number spliting by types,
6091  * for example. 
6092  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6093  *           check of this is be done. If not, the result is not warranted. 
6094  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6095  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6096  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6097  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6098  *         should be more than every value in \a this array.
6099  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6100  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6101  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6102  *         (same number of tuples and components), the caller is to delete 
6103  *         using decrRef() as it is no more needed.
6104  *         This array contains indices of ranges for every value of \a this array. I.e.
6105  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6106  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6107  *         this in which cast it holds.
6108  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6109  *         array, the caller is to delete using decrRef() as it is no more needed.
6110  *         This array contains ranks of values of \a this array within ranges
6111  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6112  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6113  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6114  *         for each tuple its rank inside its cast. The rank is computed as difference
6115  *         between the value and the lowest value of range.
6116  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6117  *         ranges (casts) to which at least one value of \a this array belongs.
6118  *         Or, in other words, this param contains the casts that \a this contains.
6119  *         The caller is to delete this array using decrRef() as it is no more needed.
6120  *
6121  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6122  *            the output of this method will be : 
6123  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6124  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6125  * - \a castsPresent  : [0,1]
6126  *
6127  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6128  * range #1 and its rank within this range is 2; etc.
6129  *
6130  *  \throw If \a this->getNumberOfComponents() != 1.
6131  *  \throw If \a arrEnd - arrBg < 2.
6132  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6133  */
6134 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6135                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
6136 {
6137   checkAllocated();
6138   if(getNumberOfComponents()!=1)
6139     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6140   int nbOfTuples=getNumberOfTuples();
6141   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6142   if(nbOfCast<2)
6143     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6144   nbOfCast--;
6145   const int *work=getConstPointer();
6146   typedef std::reverse_iterator<const int *> rintstart;
6147   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6148   rintstart end2(arrBg);
6149   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6150   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6151   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6152   ret1->alloc(nbOfTuples,1);
6153   ret2->alloc(nbOfTuples,1);
6154   int *ret1Ptr=ret1->getPointer();
6155   int *ret2Ptr=ret2->getPointer();
6156   std::set<std::size_t> castsDetected;
6157   for(int i=0;i<nbOfTuples;i++)
6158     {
6159       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6160       std::size_t pos=std::distance(bg,res);
6161       std::size_t pos2=nbOfCast-pos;
6162       if(pos2<nbOfCast)
6163         {
6164           ret1Ptr[i]=(int)pos2;
6165           ret2Ptr[i]=work[i]-arrBg[pos2];
6166           castsDetected.insert(pos2);
6167         }
6168       else
6169         {
6170           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6171           throw INTERP_KERNEL::Exception(oss.str().c_str());
6172         }
6173     }
6174   ret3->alloc((int)castsDetected.size(),1);
6175   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6176   castArr=ret1.retn();
6177   rankInsideCast=ret2.retn();
6178   castsPresent=ret3.retn();
6179 }
6180
6181 /*!
6182  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6183  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6184  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6185  * new value in place \a indArr[ \a v ] is i.
6186  *  \param [in] indArrBg - the array holding indices within the result array to assign
6187  *         indices of values of \a this array pointing to values of \a indArrBg.
6188  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6189  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6190  *  \return DataArrayInt * - the new instance of DataArrayInt.
6191  *          The caller is to delete this result array using decrRef() as it is no more
6192  *          needed.
6193  *  \throw If \a this->getNumberOfComponents() != 1.
6194  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6195  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6196  */
6197 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception)
6198 {
6199   checkAllocated();
6200   if(getNumberOfComponents()!=1)
6201     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6202   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6203   int nbOfTuples=getNumberOfTuples();
6204   const int *pt=getConstPointer();
6205   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6206   ret->alloc(nbOfTuples,1);
6207   ret->fillWithValue(-1);
6208   int *tmp=ret->getPointer();
6209   for(int i=0;i<nbOfTuples;i++,pt++)
6210     {
6211       if(*pt>=0 && *pt<nbElemsIn)
6212         {
6213           int pos=indArrBg[*pt];
6214           if(pos>=0 && pos<nbOfTuples)
6215             tmp[pos]=i;
6216           else
6217             {
6218               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6219               throw INTERP_KERNEL::Exception(oss.str().c_str());
6220             }
6221         }
6222       else
6223         {
6224           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6225           throw INTERP_KERNEL::Exception(oss.str().c_str());
6226         }
6227     }
6228   return ret.retn();
6229 }
6230
6231 /*!
6232  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6233  * from values of \a this array, which is supposed to contain a renumbering map in 
6234  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6235  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6236  *  \param [in] newNbOfElem - the number of tuples in the result array.
6237  *  \return DataArrayInt * - the new instance of DataArrayInt.
6238  *          The caller is to delete this result array using decrRef() as it is no more
6239  *          needed.
6240  * 
6241  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6242  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6243  */
6244 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6245 {
6246   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6247   ret->alloc(newNbOfElem,1);
6248   int nbOfOldNodes=getNumberOfTuples();
6249   const int *old2New=getConstPointer();
6250   int *pt=ret->getPointer();
6251   for(int i=0;i!=nbOfOldNodes;i++)
6252     {
6253       int newp(old2New[i]);
6254       if(newp!=-1)
6255         {
6256           if(newp>=0 && newp<newNbOfElem)
6257             pt[newp]=i;
6258           else
6259             {
6260               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6261               throw INTERP_KERNEL::Exception(oss.str().c_str());
6262             }
6263         }
6264     }
6265   return ret.retn();
6266 }
6267
6268 /*!
6269  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6270  * 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]
6271  */
6272 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception)
6273 {
6274   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6275   ret->alloc(newNbOfElem,1);
6276   int nbOfOldNodes=getNumberOfTuples();
6277   const int *old2New=getConstPointer();
6278   int *pt=ret->getPointer();
6279   for(int i=nbOfOldNodes-1;i>=0;i--)
6280     {
6281       int newp(old2New[i]);
6282       if(newp!=-1)
6283         {
6284           if(newp>=0 && newp<newNbOfElem)
6285             pt[newp]=i;
6286           else
6287             {
6288               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6289               throw INTERP_KERNEL::Exception(oss.str().c_str());
6290             }
6291         }
6292     }
6293   return ret.retn();
6294 }
6295
6296 /*!
6297  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6298  * from values of \a this array, which is supposed to contain a renumbering map in 
6299  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6300  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6301  *  \param [in] newNbOfElem - the number of tuples in the result array.
6302  *  \return DataArrayInt * - the new instance of DataArrayInt.
6303  *          The caller is to delete this result array using decrRef() as it is no more
6304  *          needed.
6305  * 
6306  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6307  *
6308  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6309  */
6310 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6311 {
6312   checkAllocated();
6313   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6314   ret->alloc(oldNbOfElem,1);
6315   const int *new2Old=getConstPointer();
6316   int *pt=ret->getPointer();
6317   std::fill(pt,pt+oldNbOfElem,-1);
6318   int nbOfNewElems=getNumberOfTuples();
6319   for(int i=0;i<nbOfNewElems;i++)
6320     {
6321       int v(new2Old[i]);
6322       if(v>=0 && v<oldNbOfElem)
6323          pt[v]=i;
6324       else
6325         {
6326           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6327           throw INTERP_KERNEL::Exception(oss.str().c_str());
6328         }
6329     }
6330   return ret.retn();
6331 }
6332
6333 /*!
6334  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6335  * mismatch is given.
6336  * 
6337  * \param [in] other the instance to be compared with \a this
6338  * \param [out] reason In case of inequality returns the reason.
6339  * \sa DataArrayInt::isEqual
6340  */
6341 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
6342 {
6343   if(!areInfoEqualsIfNotWhy(other,reason))
6344     return false;
6345   return _mem.isEqual(other._mem,0,reason);
6346 }
6347
6348 /*!
6349  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6350  * \ref MEDCouplingArrayBasicsCompare.
6351  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6352  *  \return bool - \a true if the two arrays are equal, \a false else.
6353  */
6354 bool DataArrayInt::isEqual(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6355 {
6356   std::string tmp;
6357   return isEqualIfNotWhy(other,tmp);
6358 }
6359
6360 /*!
6361  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6362  * \ref MEDCouplingArrayBasicsCompare.
6363  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6364  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6365  */
6366 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6367 {
6368   std::string tmp;
6369   return _mem.isEqual(other._mem,0,tmp);
6370 }
6371
6372 /*!
6373  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6374  * performed on sorted value sequences.
6375  * For more info see\ref MEDCouplingArrayBasicsCompare.
6376  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6377  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6378  */
6379 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6380 {
6381   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6382   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6383   a->sort();
6384   b->sort();
6385   return a->isEqualWithoutConsideringStr(*b);
6386 }
6387
6388 /*!
6389  * This method compares content of input vector \a v and \a this.
6390  * 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.
6391  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6392  *
6393  * \param [in] v - the vector of 'flags' to be compared with \a this.
6394  *
6395  * \throw If \a this is not sorted ascendingly.
6396  * \throw If \a this has not exactly one component.
6397  * \throw If \a this is not allocated.
6398  */
6399 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const throw(INTERP_KERNEL::Exception)
6400 {
6401   checkAllocated();
6402   if(getNumberOfComponents()!=1)
6403     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6404   int nbOfTuples(getNumberOfTuples());
6405   const int *w(begin()),*end2(end());
6406   int refVal=-std::numeric_limits<int>::max();
6407   int i=0;
6408   std::vector<bool>::const_iterator it(v.begin());
6409   for(;it!=v.end();it++,i++)
6410     {
6411       if(*it)
6412         {
6413           if(w!=end2)
6414             {
6415               if(*w++==i)
6416                 {
6417                   if(i>refVal)
6418                     refVal=i;
6419                   else
6420                     {
6421                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6422                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6423                     }
6424                 }
6425               else
6426                 return false;
6427             }
6428           else
6429             return false;
6430         }
6431     }
6432   return w==end2;
6433 }
6434
6435 /*!
6436  * Sorts values of the array.
6437  *  \param [in] asc - \a true means ascending order, \a false, descending.
6438  *  \throw If \a this is not allocated.
6439  *  \throw If \a this->getNumberOfComponents() != 1.
6440  */
6441 void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception)
6442 {
6443   checkAllocated();
6444   if(getNumberOfComponents()!=1)
6445     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6446   _mem.sort(asc);
6447   declareAsNew();
6448 }
6449
6450 /*!
6451  * Reverse the array values.
6452  *  \throw If \a this->getNumberOfComponents() < 1.
6453  *  \throw If \a this is not allocated.
6454  */
6455 void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
6456 {
6457   checkAllocated();
6458   _mem.reverse(getNumberOfComponents());
6459   declareAsNew();
6460 }
6461
6462 /*!
6463  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6464  * If not an exception is thrown.
6465  *  \param [in] increasing - if \a true, the array values should be increasing.
6466  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6467  *         increasing arg.
6468  *  \throw If \a this->getNumberOfComponents() != 1.
6469  *  \throw If \a this is not allocated.
6470  */
6471 void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6472 {
6473   if(!isMonotonic(increasing))
6474     {
6475       if (increasing)
6476         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6477       else
6478         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6479     }
6480 }
6481
6482 /*!
6483  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6484  *  \param [in] increasing - if \a true, array values should be increasing.
6485  *  \return bool - \a true if values change in accordance with \a increasing arg.
6486  *  \throw If \a this->getNumberOfComponents() != 1.
6487  *  \throw If \a this is not allocated.
6488  */
6489 bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6490 {
6491   checkAllocated();
6492   if(getNumberOfComponents()!=1)
6493     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6494   int nbOfElements=getNumberOfTuples();
6495   const int *ptr=getConstPointer();
6496   if(nbOfElements==0)
6497     return true;
6498   int ref=ptr[0];
6499   if(increasing)
6500     {
6501       for(int i=1;i<nbOfElements;i++)
6502         {
6503           if(ptr[i]>=ref)
6504             ref=ptr[i];
6505           else
6506             return false;
6507         }
6508     }
6509   else
6510     {
6511       for(int i=1;i<nbOfElements;i++)
6512         {
6513           if(ptr[i]<=ref)
6514             ref=ptr[i];
6515           else
6516             return false;
6517         }
6518     }
6519   return true;
6520 }
6521
6522 /*!
6523  * This method check that array consistently INCREASING or DECREASING in value.
6524  */
6525 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6526 {
6527   checkAllocated();
6528   if(getNumberOfComponents()!=1)
6529     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6530   int nbOfElements=getNumberOfTuples();
6531   const int *ptr=getConstPointer();
6532   if(nbOfElements==0)
6533     return true;
6534   int ref=ptr[0];
6535   if(increasing)
6536     {
6537       for(int i=1;i<nbOfElements;i++)
6538         {
6539           if(ptr[i]>ref)
6540             ref=ptr[i];
6541           else
6542             return false;
6543         }
6544     }
6545   else
6546     {
6547       for(int i=1;i<nbOfElements;i++)
6548         {
6549           if(ptr[i]<ref)
6550             ref=ptr[i];
6551           else
6552             return false;
6553         }
6554     }
6555   return true;
6556 }
6557
6558 /*!
6559  * This method check that array consistently INCREASING or DECREASING in value.
6560  */
6561 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6562 {
6563   if(!isStrictlyMonotonic(increasing))
6564     {
6565       if (increasing)
6566         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6567       else
6568         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6569     }
6570 }
6571
6572 /*!
6573  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6574  * one-dimensional arrays that must be of the same length. The result array describes
6575  * correspondence between \a this and \a other arrays, so that 
6576  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6577  * not possible because some element in \a other is not in \a this, an exception is thrown.
6578  *  \param [in] other - an array to compute permutation to.
6579  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6580  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6581  * no more needed.
6582  *  \throw If \a this->getNumberOfComponents() != 1.
6583  *  \throw If \a other->getNumberOfComponents() != 1.
6584  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6585  *  \throw If \a other includes a value which is not in \a this array.
6586  * 
6587  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6588  *
6589  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6590  */
6591 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6592 {
6593   checkAllocated();
6594   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6595     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6596   int nbTuple=getNumberOfTuples();
6597   other.checkAllocated();
6598   if(nbTuple!=other.getNumberOfTuples())
6599     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6600   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6601   ret->alloc(nbTuple,1);
6602   ret->fillWithValue(-1);
6603   const int *pt=getConstPointer();
6604   std::map<int,int> mm;
6605   for(int i=0;i<nbTuple;i++)
6606     mm[pt[i]]=i;
6607   pt=other.getConstPointer();
6608   int *retToFill=ret->getPointer();
6609   for(int i=0;i<nbTuple;i++)
6610     {
6611       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6612       if(it==mm.end())
6613         {
6614           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6615           throw INTERP_KERNEL::Exception(oss.str().c_str());
6616         }
6617       retToFill[i]=(*it).second;
6618     }
6619   return ret.retn();
6620 }
6621
6622 /*!
6623  * Sets a C array to be used as raw data of \a this. The previously set info
6624  *  of components is retained and re-sized. 
6625  * For more info see \ref MEDCouplingArraySteps1.
6626  *  \param [in] array - the C array to be used as raw data of \a this.
6627  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6628  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6629  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6630  *                     \c free(\c array ) will be called.
6631  *  \param [in] nbOfTuple - new number of tuples in \a this.
6632  *  \param [in] nbOfCompo - new number of components in \a this.
6633  */
6634 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6635 {
6636   _info_on_compo.resize(nbOfCompo);
6637   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6638   declareAsNew();
6639 }
6640
6641 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6642 {
6643   _info_on_compo.resize(nbOfCompo);
6644   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6645   declareAsNew();
6646 }
6647
6648 /*!
6649  * Returns a new DataArrayInt holding the same values as \a this array but differently
6650  * arranged in memory. If \a this array holds 2 components of 3 values:
6651  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6652  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6653  *  \warning Do not confuse this method with transpose()!
6654  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6655  *          is to delete using decrRef() as it is no more needed.
6656  *  \throw If \a this is not allocated.
6657  */
6658 DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
6659 {
6660   checkAllocated();
6661   if(_mem.isNull())
6662     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6663   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6664   DataArrayInt *ret=DataArrayInt::New();
6665   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6666   return ret;
6667 }
6668
6669 /*!
6670  * Returns a new DataArrayInt holding the same values as \a this array but differently
6671  * arranged in memory. If \a this array holds 2 components of 3 values:
6672  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6673  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6674  *  \warning Do not confuse this method with transpose()!
6675  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6676  *          is to delete using decrRef() as it is no more needed.
6677  *  \throw If \a this is not allocated.
6678  */
6679 DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception)
6680 {
6681   checkAllocated();
6682   if(_mem.isNull())
6683     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6684   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6685   DataArrayInt *ret=DataArrayInt::New();
6686   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6687   return ret;
6688 }
6689
6690 /*!
6691  * Permutes values of \a this array as required by \a old2New array. The values are
6692  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6693  * the same as in \this one.
6694  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6695  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6696  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6697  *     giving a new position for i-th old value.
6698  */
6699 void DataArrayInt::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
6700 {
6701   checkAllocated();
6702   int nbTuples=getNumberOfTuples();
6703   int nbOfCompo=getNumberOfComponents();
6704   int *tmp=new int[nbTuples*nbOfCompo];
6705   const int *iptr=getConstPointer();
6706   for(int i=0;i<nbTuples;i++)
6707     {
6708       int v=old2New[i];
6709       if(v>=0 && v<nbTuples)
6710         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6711       else
6712         {
6713           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6714           throw INTERP_KERNEL::Exception(oss.str().c_str());
6715         }
6716     }
6717   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6718   delete [] tmp;
6719   declareAsNew();
6720 }
6721
6722 /*!
6723  * Permutes values of \a this array as required by \a new2Old array. The values are
6724  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6725  * the same as in \this one.
6726  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6727  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6728  *     giving a previous position of i-th new value.
6729  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6730  *          is to delete using decrRef() as it is no more needed.
6731  */
6732 void DataArrayInt::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
6733 {
6734   checkAllocated();
6735   int nbTuples=getNumberOfTuples();
6736   int nbOfCompo=getNumberOfComponents();
6737   int *tmp=new int[nbTuples*nbOfCompo];
6738   const int *iptr=getConstPointer();
6739   for(int i=0;i<nbTuples;i++)
6740     {
6741       int v=new2Old[i];
6742       if(v>=0 && v<nbTuples)
6743         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6744       else
6745         {
6746           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6747           throw INTERP_KERNEL::Exception(oss.str().c_str());
6748         }
6749     }
6750   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6751   delete [] tmp;
6752   declareAsNew();
6753 }
6754
6755 /*!
6756  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6757  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6758  * Number of tuples in the result array remains the same as in \this one.
6759  * If a permutation reduction is needed, renumberAndReduce() should be used.
6760  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6761  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6762  *          giving a new position for i-th old value.
6763  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6764  *          is to delete using decrRef() as it is no more needed.
6765  *  \throw If \a this is not allocated.
6766  */
6767 DataArrayInt *DataArrayInt::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
6768 {
6769   checkAllocated();
6770   int nbTuples=getNumberOfTuples();
6771   int nbOfCompo=getNumberOfComponents();
6772   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6773   ret->alloc(nbTuples,nbOfCompo);
6774   ret->copyStringInfoFrom(*this);
6775   const int *iptr=getConstPointer();
6776   int *optr=ret->getPointer();
6777   for(int i=0;i<nbTuples;i++)
6778     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6779   ret->copyStringInfoFrom(*this);
6780   return ret.retn();
6781 }
6782
6783 /*!
6784  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6785  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6786  * tuples in the result array remains the same as in \this one.
6787  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6788  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6789  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6790  *     giving a previous position of i-th new value.
6791  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6792  *          is to delete using decrRef() as it is no more needed.
6793  */
6794 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
6795 {
6796   checkAllocated();
6797   int nbTuples=getNumberOfTuples();
6798   int nbOfCompo=getNumberOfComponents();
6799   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6800   ret->alloc(nbTuples,nbOfCompo);
6801   ret->copyStringInfoFrom(*this);
6802   const int *iptr=getConstPointer();
6803   int *optr=ret->getPointer();
6804   for(int i=0;i<nbTuples;i++)
6805     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6806   ret->copyStringInfoFrom(*this);
6807   return ret.retn();
6808 }
6809
6810 /*!
6811  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6812  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6813  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6814  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6815  * \a old2New[ i ] is negative, is missing from the result array.
6816  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6817  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6818  *     giving a new position for i-th old tuple and giving negative position for
6819  *     for i-th old tuple that should be omitted.
6820  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6821  *          is to delete using decrRef() as it is no more needed.
6822  */
6823 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
6824 {
6825   checkAllocated();
6826   int nbTuples=getNumberOfTuples();
6827   int nbOfCompo=getNumberOfComponents();
6828   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6829   ret->alloc(newNbOfTuple,nbOfCompo);
6830   const int *iptr=getConstPointer();
6831   int *optr=ret->getPointer();
6832   for(int i=0;i<nbTuples;i++)
6833     {
6834       int w=old2New[i];
6835       if(w>=0)
6836         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6837     }
6838   ret->copyStringInfoFrom(*this);
6839   return ret.retn();
6840 }
6841
6842 /*!
6843  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6844  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6845  * \a new2OldBg array.
6846  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6847  * This method is equivalent to renumberAndReduce() except that convention in input is
6848  * \c new2old and \b not \c old2new.
6849  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6850  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6851  *              tuple index in \a this array to fill the i-th tuple in the new array.
6852  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6853  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6854  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6855  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6856  *          is to delete using decrRef() as it is no more needed.
6857  */
6858 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6859 {
6860   checkAllocated();
6861   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6862   int nbComp=getNumberOfComponents();
6863   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6864   ret->copyStringInfoFrom(*this);
6865   int *pt=ret->getPointer();
6866   const int *srcPt=getConstPointer();
6867   int i=0;
6868   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6869     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6870   ret->copyStringInfoFrom(*this);
6871   return ret.retn();
6872 }
6873
6874 /*!
6875  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6876  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6877  * \a new2OldBg array.
6878  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6879  * This method is equivalent to renumberAndReduce() except that convention in input is
6880  * \c new2old and \b not \c old2new.
6881  * This method is equivalent to selectByTupleId() except that it prevents coping data
6882  * from behind the end of \a this array.
6883  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6884  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6885  *              tuple index in \a this array to fill the i-th tuple in the new array.
6886  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6887  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6888  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6889  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6890  *          is to delete using decrRef() as it is no more needed.
6891  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6892  */
6893 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
6894 {
6895   checkAllocated();
6896   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6897   int nbComp=getNumberOfComponents();
6898   int oldNbOfTuples=getNumberOfTuples();
6899   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6900   ret->copyStringInfoFrom(*this);
6901   int *pt=ret->getPointer();
6902   const int *srcPt=getConstPointer();
6903   int i=0;
6904   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6905     if(*w>=0 && *w<oldNbOfTuples)
6906       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6907     else
6908       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6909   ret->copyStringInfoFrom(*this);
6910   return ret.retn();
6911 }
6912
6913 /*!
6914  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6915  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6916  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6917  * command \c range( \a bg, \a end2, \a step ).
6918  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6919  * not constructed explicitly.
6920  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6921  *  \param [in] bg - index of the first tuple to copy from \a this array.
6922  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
6923  *  \param [in] step - index increment to get index of the next tuple to copy.
6924  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6925  *          is to delete using decrRef() as it is no more needed.
6926  *  \sa DataArrayInt::substr.
6927  */
6928 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
6929 {
6930   checkAllocated();
6931   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6932   int nbComp=getNumberOfComponents();
6933   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
6934   ret->alloc(newNbOfTuples,nbComp);
6935   int *pt=ret->getPointer();
6936   const int *srcPt=getConstPointer()+bg*nbComp;
6937   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
6938     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
6939   ret->copyStringInfoFrom(*this);
6940   return ret.retn();
6941 }
6942
6943 /*!
6944  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
6945  * of tuples specified by \a ranges parameter.
6946  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6947  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
6948  *              of tuples in [\c begin,\c end) format.
6949  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6950  *          is to delete using decrRef() as it is no more needed.
6951  *  \throw If \a end < \a begin.
6952  *  \throw If \a end > \a this->getNumberOfTuples().
6953  *  \throw If \a this is not allocated.
6954  */
6955 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
6956 {
6957   checkAllocated();
6958   int nbOfComp=getNumberOfComponents();
6959   int nbOfTuplesThis=getNumberOfTuples();
6960   if(ranges.empty())
6961     {
6962       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6963       ret->alloc(0,nbOfComp);
6964       ret->copyStringInfoFrom(*this);
6965       return ret.retn();
6966     }
6967   int ref=ranges.front().first;
6968   int nbOfTuples=0;
6969   bool isIncreasing=true;
6970   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6971     {
6972       if((*it).first<=(*it).second)
6973         {
6974           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
6975             {
6976               nbOfTuples+=(*it).second-(*it).first;
6977               if(isIncreasing)
6978                 isIncreasing=ref<=(*it).first;
6979               ref=(*it).second;
6980             }
6981           else
6982             {
6983               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6984               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
6985               throw INTERP_KERNEL::Exception(oss.str().c_str());
6986             }
6987         }
6988       else
6989         {
6990           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6991           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
6992           throw INTERP_KERNEL::Exception(oss.str().c_str());
6993         }
6994     }
6995   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
6996     return deepCpy();
6997   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6998   ret->alloc(nbOfTuples,nbOfComp);
6999   ret->copyStringInfoFrom(*this);
7000   const int *src=getConstPointer();
7001   int *work=ret->getPointer();
7002   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7003     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7004   return ret.retn();
7005 }
7006
7007 /*!
7008  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7009  * This map, if applied to \a this array, would make it sorted. For example, if
7010  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7011  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7012  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7013  * This method is useful for renumbering (in MED file for example). For more info
7014  * on renumbering see \ref MEDCouplingArrayRenumbering.
7015  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7016  *          array using decrRef() as it is no more needed.
7017  *  \throw If \a this is not allocated.
7018  *  \throw If \a this->getNumberOfComponents() != 1.
7019  *  \throw If there are equal values in \a this array.
7020  */
7021 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception)
7022 {
7023   checkAllocated();
7024   if(getNumberOfComponents()!=1)
7025     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7026   int nbTuples=getNumberOfTuples();
7027   const int *pt=getConstPointer();
7028   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7029   DataArrayInt *ret=DataArrayInt::New();
7030   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7031   return ret;
7032 }
7033
7034 /*!
7035  * 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
7036  * input array \a ids2.
7037  * \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.
7038  * 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
7039  * inversely.
7040  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7041  *
7042  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7043  *          array using decrRef() as it is no more needed.
7044  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7045  * 
7046  */
7047 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2) throw(INTERP_KERNEL::Exception)
7048 {
7049   if(!ids1 || !ids2)
7050     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7051   if(!ids1->isAllocated() || !ids2->isAllocated())
7052     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7053   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7054     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7055   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7056     {
7057       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 !";
7058       throw INTERP_KERNEL::Exception(oss.str().c_str());
7059     }
7060   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
7061   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
7062   p1->sort(true); p2->sort(true);
7063   if(!p1->isEqualWithoutConsideringStr(*p2))
7064     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7065   p1=ids1->checkAndPreparePermutation();
7066   p2=ids2->checkAndPreparePermutation();
7067   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7068   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7069   return p2.retn();
7070 }
7071
7072 /*!
7073  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7074  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7075  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7076  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7077  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7078  * The first of out arrays returns indices of elements of \a this array, grouped by their
7079  * place in the set \a B. The second out array is the index of the first one; it shows how
7080  * many elements of \a A are mapped into each element of \a B. <br>
7081  * For more info on
7082  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
7083  * \b Example:
7084  * - \a this: [0,3,2,3,2,2,1,2]
7085  * - \a targetNb: 4
7086  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7087  * - \a arrI: [0,1,2,6,8]
7088  *
7089  * This result means: <br>
7090  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7091  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7092  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7093  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7094  * \a arrI[ 2+1 ]]); <br> etc.
7095  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7096  *         than the maximal value of \a A.
7097  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7098  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7099  *         this array using decrRef() as it is no more needed.
7100  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7101  *         elements of \a this. The caller is to delete this array using decrRef() as it
7102  *         is no more needed.
7103  *  \throw If \a this is not allocated.
7104  *  \throw If \a this->getNumberOfComponents() != 1.
7105  *  \throw If any value in \a this is more or equal to \a targetNb.
7106  */
7107 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception)
7108 {
7109   checkAllocated();
7110   if(getNumberOfComponents()!=1)
7111     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7112   int nbOfTuples=getNumberOfTuples();
7113   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7114   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7115   retI->alloc(targetNb+1,1);
7116   const int *input=getConstPointer();
7117   std::vector< std::vector<int> > tmp(targetNb);
7118   for(int i=0;i<nbOfTuples;i++)
7119     {
7120       int tmp2=input[i];
7121       if(tmp2>=0 && tmp2<targetNb)
7122         tmp[tmp2].push_back(i);
7123       else
7124         {
7125           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7126           throw INTERP_KERNEL::Exception(oss.str().c_str());
7127         }
7128     }
7129   int *retIPtr=retI->getPointer();
7130   *retIPtr=0;
7131   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7132     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7133   if(nbOfTuples!=retI->getIJ(targetNb,0))
7134     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7135   ret->alloc(nbOfTuples,1);
7136   int *retPtr=ret->getPointer();
7137   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7138     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7139   arr=ret.retn();
7140   arrI=retI.retn();
7141 }
7142
7143
7144 /*!
7145  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7146  * from a zip representation of a surjective format (returned e.g. by
7147  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7148  * for example). The result array minimizes the permutation. <br>
7149  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7150  * \b Example: <br>
7151  * - \a nbOfOldTuples: 10 
7152  * - \a arr          : [0,3, 5,7,9]
7153  * - \a arrIBg       : [0,2,5]
7154  * - \a newNbOfTuples: 7
7155  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7156  *
7157  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7158  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7159  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7160  *         (indices of) equal values. Its every element (except the last one) points to
7161  *         the first element of a group of equal values.
7162  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7163  *          arrIBg is \a arrIEnd[ -1 ].
7164  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7165  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7166  *          array using decrRef() as it is no more needed.
7167  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7168  */
7169 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
7170 {
7171   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7172   ret->alloc(nbOfOldTuples,1);
7173   int *pt=ret->getPointer();
7174   std::fill(pt,pt+nbOfOldTuples,-1);
7175   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7176   const int *cIPtr=arrIBg;
7177   for(int i=0;i<nbOfGrps;i++)
7178     pt[arr[cIPtr[i]]]=-(i+2);
7179   int newNb=0;
7180   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7181     {
7182       if(pt[iNode]<0)
7183         {
7184           if(pt[iNode]==-1)
7185             pt[iNode]=newNb++;
7186           else
7187             {
7188               int grpId=-(pt[iNode]+2);
7189               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7190                 {
7191                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7192                     pt[arr[j]]=newNb;
7193                   else
7194                     {
7195                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7196                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7197                     }
7198                 }
7199               newNb++;
7200             }
7201         }
7202     }
7203   newNbOfTuples=newNb;
7204   return ret.retn();
7205 }
7206
7207 /*!
7208  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7209  * which if applied to \a this array would make it sorted ascendingly.
7210  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7211  * \b Example: <br>
7212  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7213  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7214  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7215  *
7216  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7217  *          array using decrRef() as it is no more needed.
7218  *  \throw If \a this is not allocated.
7219  *  \throw If \a this->getNumberOfComponents() != 1.
7220  */
7221 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception)
7222 {
7223   checkAllocated();
7224   if(getNumberOfComponents()!=1)
7225     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7226   int nbOfTuples=getNumberOfTuples();
7227   const int *pt=getConstPointer();
7228   std::map<int,int> m;
7229   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7230   ret->alloc(nbOfTuples,1);
7231   int *opt=ret->getPointer();
7232   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7233     {
7234       int val=*pt;
7235       std::map<int,int>::iterator it=m.find(val);
7236       if(it!=m.end())
7237         {
7238           *opt=(*it).second;
7239           (*it).second++;
7240         }
7241       else
7242         {
7243           *opt=0;
7244           m.insert(std::pair<int,int>(val,1));
7245         }
7246     }
7247   int sum=0;
7248   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7249     {
7250       int vt=(*it).second;
7251       (*it).second=sum;
7252       sum+=vt;
7253     }
7254   pt=getConstPointer();
7255   opt=ret->getPointer();
7256   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7257     *opt+=m[*pt];
7258   //
7259   return ret.retn();
7260 }
7261
7262 /*!
7263  * Checks if contents of \a this array are equal to that of an array filled with
7264  * iota(). This method is particularly useful for DataArrayInt instances that represent
7265  * a renumbering array to check the real need in renumbering. 
7266  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7267  *  \throw If \a this is not allocated.
7268  *  \throw If \a this->getNumberOfComponents() != 1.
7269  */
7270 bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception)
7271 {
7272   checkAllocated();
7273   if(getNumberOfComponents()!=1)
7274     return false;
7275   int nbOfTuples=getNumberOfTuples();
7276   const int *pt=getConstPointer();
7277   for(int i=0;i<nbOfTuples;i++,pt++)
7278     if(*pt!=i)
7279       return false;
7280   return true;
7281 }
7282
7283 /*!
7284  * Checks if all values in \a this array are equal to \a val.
7285  *  \param [in] val - value to check equality of array values to.
7286  *  \return bool - \a true if all values are \a val.
7287  *  \throw If \a this is not allocated.
7288  *  \throw If \a this->getNumberOfComponents() != 1
7289  */
7290 bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception)
7291 {
7292   checkAllocated();
7293   if(getNumberOfComponents()!=1)
7294     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7295   int nbOfTuples=getNumberOfTuples();
7296   const int *w=getConstPointer();
7297   const int *end2=w+nbOfTuples;
7298   for(;w!=end2;w++)
7299     if(*w!=val)
7300       return false;
7301   return true;
7302 }
7303
7304 /*!
7305  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7306  * array to the new one.
7307  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7308  */
7309 DataArrayDouble *DataArrayInt::convertToDblArr() const
7310 {
7311   checkAllocated();
7312   DataArrayDouble *ret=DataArrayDouble::New();
7313   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7314   std::size_t nbOfVals=getNbOfElems();
7315   const int *src=getConstPointer();
7316   double *dest=ret->getPointer();
7317   std::copy(src,src+nbOfVals,dest);
7318   ret->copyStringInfoFrom(*this);
7319   return ret;
7320 }
7321
7322 /*!
7323  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7324  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7325  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7326  * This method is a specialization of selectByTupleId2().
7327  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7328  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7329  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7330  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7331  *          is to delete using decrRef() as it is no more needed.
7332  *  \throw If \a tupleIdBg < 0.
7333  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7334     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7335  *  \sa DataArrayInt::selectByTupleId2
7336  */
7337 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
7338 {
7339   checkAllocated();
7340   int nbt=getNumberOfTuples();
7341   if(tupleIdBg<0)
7342     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7343   if(tupleIdBg>nbt)
7344     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7345   int trueEnd=tupleIdEnd;
7346   if(tupleIdEnd!=-1)
7347     {
7348       if(tupleIdEnd>nbt)
7349         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7350     }
7351   else
7352     trueEnd=nbt;
7353   int nbComp=getNumberOfComponents();
7354   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7355   ret->alloc(trueEnd-tupleIdBg,nbComp);
7356   ret->copyStringInfoFrom(*this);
7357   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7358   return ret.retn();
7359 }
7360
7361 /*!
7362  * Changes the number of components within \a this array so that its raw data **does
7363  * not** change, instead splitting this data into tuples changes.
7364  *  \warning This method erases all (name and unit) component info set before!
7365  *  \param [in] newNbOfComp - number of components for \a this array to have.
7366  *  \throw If \a this is not allocated
7367  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7368  *  \throw If \a newNbOfCompo is lower than 1.
7369  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7370  *  \warning This method erases all (name and unit) component info set before!
7371  */
7372 void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
7373 {
7374   checkAllocated();
7375   if(newNbOfCompo<1)
7376     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7377   std::size_t nbOfElems=getNbOfElems();
7378   if(nbOfElems%newNbOfCompo!=0)
7379     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7380   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7381     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7382   _info_on_compo.clear();
7383   _info_on_compo.resize(newNbOfCompo);
7384   declareAsNew();
7385 }
7386
7387 /*!
7388  * Changes the number of components within \a this array to be equal to its number
7389  * of tuples, and inversely its number of tuples to become equal to its number of 
7390  * components. So that its raw data **does not** change, instead splitting this
7391  * data into tuples changes.
7392  *  \warning This method erases all (name and unit) component info set before!
7393  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7394  *  \throw If \a this is not allocated.
7395  *  \sa rearrange()
7396  */
7397 void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception)
7398 {
7399   checkAllocated();
7400   int nbOfTuples=getNumberOfTuples();
7401   rearrange(nbOfTuples);
7402 }
7403
7404 /*!
7405  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7406  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7407  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7408  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7409  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7410  * components.  
7411  *  \param [in] newNbOfComp - number of components for the new array to have.
7412  *  \param [in] dftValue - value assigned to new values added to the new array.
7413  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7414  *          is to delete using decrRef() as it is no more needed.
7415  *  \throw If \a this is not allocated.
7416  */
7417 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception)
7418 {
7419   checkAllocated();
7420   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7421   ret->alloc(getNumberOfTuples(),newNbOfComp);
7422   const int *oldc=getConstPointer();
7423   int *nc=ret->getPointer();
7424   int nbOfTuples=getNumberOfTuples();
7425   int oldNbOfComp=getNumberOfComponents();
7426   int dim=std::min(oldNbOfComp,newNbOfComp);
7427   for(int i=0;i<nbOfTuples;i++)
7428     {
7429       int j=0;
7430       for(;j<dim;j++)
7431         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7432       for(;j<newNbOfComp;j++)
7433         nc[newNbOfComp*i+j]=dftValue;
7434     }
7435   ret->setName(getName().c_str());
7436   for(int i=0;i<dim;i++)
7437     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
7438   ret->setName(getName().c_str());
7439   return ret.retn();
7440 }
7441
7442 /*!
7443  * Changes number of tuples in the array. If the new number of tuples is smaller
7444  * than the current number the array is truncated, otherwise the array is extended.
7445  *  \param [in] nbOfTuples - new number of tuples. 
7446  *  \throw If \a this is not allocated.
7447  *  \throw If \a nbOfTuples is negative.
7448  */
7449 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
7450 {
7451   if(nbOfTuples<0)
7452     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7453   checkAllocated();
7454   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7455   declareAsNew();
7456 }
7457
7458
7459 /*!
7460  * Returns a copy of \a this array composed of selected components.
7461  * The new DataArrayInt has the same number of tuples but includes components
7462  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7463  * can be either less, same or more than \a this->getNbOfElems().
7464  *  \param [in] compoIds - sequence of zero based indices of components to include
7465  *              into the new array.
7466  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7467  *          is to delete using decrRef() as it is no more needed.
7468  *  \throw If \a this is not allocated.
7469  *  \throw If a component index (\a i) is not valid: 
7470  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7471  *
7472  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7473  */
7474 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
7475 {
7476   checkAllocated();
7477   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7478   int newNbOfCompo=(int)compoIds.size();
7479   int oldNbOfCompo=getNumberOfComponents();
7480   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7481     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7482   int nbOfTuples=getNumberOfTuples();
7483   ret->alloc(nbOfTuples,newNbOfCompo);
7484   ret->copyPartOfStringInfoFrom(*this,compoIds);
7485   const int *oldc=getConstPointer();
7486   int *nc=ret->getPointer();
7487   for(int i=0;i<nbOfTuples;i++)
7488     for(int j=0;j<newNbOfCompo;j++,nc++)
7489       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7490   return ret.retn();
7491 }
7492
7493 /*!
7494  * Appends components of another array to components of \a this one, tuple by tuple.
7495  * So that the number of tuples of \a this array remains the same and the number of 
7496  * components increases.
7497  *  \param [in] other - the DataArrayInt to append to \a this one.
7498  *  \throw If \a this is not allocated.
7499  *  \throw If \a this and \a other arrays have different number of tuples.
7500  *
7501  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7502  *
7503  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7504  */
7505 void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
7506 {
7507   if(!other)
7508     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7509   checkAllocated();
7510   other->checkAllocated();
7511   int nbOfTuples=getNumberOfTuples();
7512   if(nbOfTuples!=other->getNumberOfTuples())
7513     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7514   int nbOfComp1=getNumberOfComponents();
7515   int nbOfComp2=other->getNumberOfComponents();
7516   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7517   int *w=newArr;
7518   const int *inp1=getConstPointer();
7519   const int *inp2=other->getConstPointer();
7520   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7521     {
7522       w=std::copy(inp1,inp1+nbOfComp1,w);
7523       w=std::copy(inp2,inp2+nbOfComp2,w);
7524     }
7525   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7526   std::vector<int> compIds(nbOfComp2);
7527   for(int i=0;i<nbOfComp2;i++)
7528     compIds[i]=nbOfComp1+i;
7529   copyPartOfStringInfoFrom2(compIds,*other);
7530 }
7531
7532 /*!
7533  * Copy all components in a specified order from another DataArrayInt.
7534  * The specified components become the first ones in \a this array.
7535  * Both numerical and textual data is copied. The number of tuples in \a this and
7536  * the other array can be different.
7537  *  \param [in] a - the array to copy data from.
7538  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7539  *              to be copied.
7540  *  \throw If \a a is NULL.
7541  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7542  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7543  *
7544  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7545  */
7546 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
7547 {
7548   if(!a)
7549     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7550   checkAllocated();
7551   a->checkAllocated();
7552   copyPartOfStringInfoFrom2(compoIds,*a);
7553   std::size_t partOfCompoSz=compoIds.size();
7554   int nbOfCompo=getNumberOfComponents();
7555   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7556   const int *ac=a->getConstPointer();
7557   int *nc=getPointer();
7558   for(int i=0;i<nbOfTuples;i++)
7559     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7560       nc[nbOfCompo*i+compoIds[j]]=*ac;
7561 }
7562
7563 /*!
7564  * Copy all values from another DataArrayInt into specified tuples and components
7565  * of \a this array. Textual data is not copied.
7566  * The tree parameters defining set of indices of tuples and components are similar to
7567  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7568  *  \param [in] a - the array to copy values from.
7569  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7570  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7571  *              are located.
7572  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7573  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7574  *  \param [in] endComp - index of the component before which the components to assign
7575  *              to are located.
7576  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7577  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7578  *              must be equal to the number of columns to assign to, else an
7579  *              exception is thrown; if \a false, then it is only required that \a
7580  *              a->getNbOfElems() equals to number of values to assign to (this condition
7581  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7582  *              values to assign to is given by following Python expression:
7583  *              \a nbTargetValues = 
7584  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7585  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7586  *  \throw If \a a is NULL.
7587  *  \throw If \a a is not allocated.
7588  *  \throw If \a this is not allocated.
7589  *  \throw If parameters specifying tuples and components to assign to do not give a
7590  *            non-empty range of increasing indices.
7591  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7592  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7593  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7594  *
7595  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7596  */
7597 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7598 {
7599   if(!a)
7600     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7601   const char msg[]="DataArrayInt::setPartOfValues1";
7602   checkAllocated();
7603   a->checkAllocated();
7604   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7605   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7606   int nbComp=getNumberOfComponents();
7607   int nbOfTuples=getNumberOfTuples();
7608   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7609   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7610   bool assignTech=true;
7611   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7612     {
7613       if(strictCompoCompare)
7614         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7615     }
7616   else
7617     {
7618       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7619       assignTech=false;
7620     }
7621   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7622   const int *srcPt=a->getConstPointer();
7623   if(assignTech)
7624     {
7625       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7626         for(int j=0;j<newNbOfComp;j++,srcPt++)
7627           pt[j*stepComp]=*srcPt;
7628     }
7629   else
7630     {
7631       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7632         {
7633           const int *srcPt2=srcPt;
7634           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7635             pt[j*stepComp]=*srcPt2;
7636         }
7637     }
7638 }
7639
7640 /*!
7641  * Assign a given value to values at specified tuples and components of \a this array.
7642  * The tree parameters defining set of indices of tuples and components are similar to
7643  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7644  *  \param [in] a - the value to assign.
7645  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7646  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7647  *              are located.
7648  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7649  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7650  *  \param [in] endComp - index of the component before which the components to assign
7651  *              to are located.
7652  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7653  *  \throw If \a this is not allocated.
7654  *  \throw If parameters specifying tuples and components to assign to, do not give a
7655  *            non-empty range of increasing indices or indices are out of a valid range
7656  *            for \this array.
7657  *
7658  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7659  */
7660 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7661 {
7662   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7663   checkAllocated();
7664   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7665   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7666   int nbComp=getNumberOfComponents();
7667   int nbOfTuples=getNumberOfTuples();
7668   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7669   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7670   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7671   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7672     for(int j=0;j<newNbOfComp;j++)
7673       pt[j*stepComp]=a;
7674 }
7675
7676
7677 /*!
7678  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7679  * components of \a this array. Textual data is not copied.
7680  * The tuples and components to assign to are defined by C arrays of indices.
7681  * There are two *modes of usage*:
7682  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7683  *   of \a a is assigned to its own location within \a this array. 
7684  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7685  *   components of every specified tuple of \a this array. In this mode it is required
7686  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7687  * 
7688  *  \param [in] a - the array to copy values from.
7689  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7690  *              assign values of \a a to.
7691  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7692  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7693  *              \a bgTuples <= \a pi < \a endTuples.
7694  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7695  *              assign values of \a a to.
7696  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7697  *              pointer to a component index <em>(pi)</em> varies as this: 
7698  *              \a bgComp <= \a pi < \a endComp.
7699  *  \param [in] strictCompoCompare - this parameter is checked only if the
7700  *               *mode of usage* is the first; if it is \a true (default), 
7701  *               then \a a->getNumberOfComponents() must be equal 
7702  *               to the number of specified columns, else this is not required.
7703  *  \throw If \a a is NULL.
7704  *  \throw If \a a is not allocated.
7705  *  \throw If \a this is not allocated.
7706  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7707  *         out of a valid range for \a this array.
7708  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7709  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7710  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7711  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7712  *
7713  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7714  */
7715 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7716 {
7717   if(!a)
7718     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7719   const char msg[]="DataArrayInt::setPartOfValues2";
7720   checkAllocated();
7721   a->checkAllocated();
7722   int nbComp=getNumberOfComponents();
7723   int nbOfTuples=getNumberOfTuples();
7724   for(const int *z=bgComp;z!=endComp;z++)
7725     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7726   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7727   int newNbOfComp=(int)std::distance(bgComp,endComp);
7728   bool assignTech=true;
7729   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7730     {
7731       if(strictCompoCompare)
7732         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7733     }
7734   else
7735     {
7736       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7737       assignTech=false;
7738     }
7739   int *pt=getPointer();
7740   const int *srcPt=a->getConstPointer();
7741   if(assignTech)
7742     {    
7743       for(const int *w=bgTuples;w!=endTuples;w++)
7744         {
7745           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7746           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7747             {    
7748               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7749             }
7750         }
7751     }
7752   else
7753     {
7754       for(const int *w=bgTuples;w!=endTuples;w++)
7755         {
7756           const int *srcPt2=srcPt;
7757           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7758           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7759             {    
7760               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7761             }
7762         }
7763     }
7764 }
7765
7766 /*!
7767  * Assign a given value to values at specified tuples and components of \a this array.
7768  * The tuples and components to assign to are defined by C arrays of indices.
7769  *  \param [in] a - the value to assign.
7770  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7771  *              assign \a a to.
7772  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7773  *              pointer to a tuple index (\a pi) varies as this: 
7774  *              \a bgTuples <= \a pi < \a endTuples.
7775  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7776  *              assign \a a to.
7777  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7778  *              pointer to a component index (\a pi) varies as this: 
7779  *              \a bgComp <= \a pi < \a endComp.
7780  *  \throw If \a this is not allocated.
7781  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7782  *         out of a valid range for \a this array.
7783  *
7784  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7785  */
7786 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7787 {
7788   checkAllocated();
7789   int nbComp=getNumberOfComponents();
7790   int nbOfTuples=getNumberOfTuples();
7791   for(const int *z=bgComp;z!=endComp;z++)
7792     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7793   int *pt=getPointer();
7794   for(const int *w=bgTuples;w!=endTuples;w++)
7795     for(const int *z=bgComp;z!=endComp;z++)
7796       {
7797         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7798         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7799       }
7800 }
7801
7802 /*!
7803  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7804  * components of \a this array. Textual data is not copied.
7805  * The tuples to assign to are defined by a C array of indices.
7806  * The components to assign to are defined by three values similar to parameters of
7807  * the Python function \c range(\c start,\c stop,\c step).
7808  * There are two *modes of usage*:
7809  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7810  *   of \a a is assigned to its own location within \a this array. 
7811  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7812  *   components of every specified tuple of \a this array. In this mode it is required
7813  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7814  *
7815  *  \param [in] a - the array to copy values from.
7816  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7817  *              assign values of \a a to.
7818  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7819  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7820  *              \a bgTuples <= \a pi < \a endTuples.
7821  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7822  *  \param [in] endComp - index of the component before which the components to assign
7823  *              to are located.
7824  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7825  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7826  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7827  *               then \a a->getNumberOfComponents() must be equal 
7828  *               to the number of specified columns, else this is not required.
7829  *  \throw If \a a is NULL.
7830  *  \throw If \a a is not allocated.
7831  *  \throw If \a this is not allocated.
7832  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7833  *         \a this array.
7834  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7835  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7836  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7837  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7838  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7839  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7840  *  \throw If parameters specifying components to assign to, do not give a
7841  *            non-empty range of increasing indices or indices are out of a valid range
7842  *            for \this array.
7843  *
7844  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7845  */
7846 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7847 {
7848   if(!a)
7849     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7850   const char msg[]="DataArrayInt::setPartOfValues3";
7851   checkAllocated();
7852   a->checkAllocated();
7853   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7854   int nbComp=getNumberOfComponents();
7855   int nbOfTuples=getNumberOfTuples();
7856   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7857   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7858   bool assignTech=true;
7859   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7860     {
7861       if(strictCompoCompare)
7862         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7863     }
7864   else
7865     {
7866       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7867       assignTech=false;
7868     }
7869   int *pt=getPointer()+bgComp;
7870   const int *srcPt=a->getConstPointer();
7871   if(assignTech)
7872     {
7873       for(const int *w=bgTuples;w!=endTuples;w++)
7874         for(int j=0;j<newNbOfComp;j++,srcPt++)
7875           {
7876             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7877             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7878           }
7879     }
7880   else
7881     {
7882       for(const int *w=bgTuples;w!=endTuples;w++)
7883         {
7884           const int *srcPt2=srcPt;
7885           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7886             {
7887               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7888               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7889             }
7890         }
7891     }
7892 }
7893
7894 /*!
7895  * Assign a given value to values at specified tuples and components of \a this array.
7896  * The tuples to assign to are defined by a C array of indices.
7897  * The components to assign to are defined by three values similar to parameters of
7898  * the Python function \c range(\c start,\c stop,\c step).
7899  *  \param [in] a - the value to assign.
7900  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7901  *              assign \a a to.
7902  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7903  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7904  *              \a bgTuples <= \a pi < \a endTuples.
7905  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7906  *  \param [in] endComp - index of the component before which the components to assign
7907  *              to are located.
7908  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7909  *  \throw If \a this is not allocated.
7910  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7911  *         \a this array.
7912  *  \throw If parameters specifying components to assign to, do not give a
7913  *            non-empty range of increasing indices or indices are out of a valid range
7914  *            for \this array.
7915  *
7916  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7917  */
7918 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7919 {
7920   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
7921   checkAllocated();
7922   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7923   int nbComp=getNumberOfComponents();
7924   int nbOfTuples=getNumberOfTuples();
7925   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7926   int *pt=getPointer()+bgComp;
7927   for(const int *w=bgTuples;w!=endTuples;w++)
7928     for(int j=0;j<newNbOfComp;j++)
7929       {
7930         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7931         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
7932       }
7933 }
7934
7935 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7936 {
7937   if(!a)
7938     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
7939   const char msg[]="DataArrayInt::setPartOfValues4";
7940   checkAllocated();
7941   a->checkAllocated();
7942   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7943   int newNbOfComp=(int)std::distance(bgComp,endComp);
7944   int nbComp=getNumberOfComponents();
7945   for(const int *z=bgComp;z!=endComp;z++)
7946     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7947   int nbOfTuples=getNumberOfTuples();
7948   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7949   bool assignTech=true;
7950   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7951     {
7952       if(strictCompoCompare)
7953         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7954     }
7955   else
7956     {
7957       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7958       assignTech=false;
7959     }
7960   const int *srcPt=a->getConstPointer();
7961   int *pt=getPointer()+bgTuples*nbComp;
7962   if(assignTech)
7963     {
7964       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7965         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7966           pt[*z]=*srcPt;
7967     }
7968   else
7969     {
7970       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7971         {
7972           const int *srcPt2=srcPt;
7973           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7974             pt[*z]=*srcPt2;
7975         }
7976     }
7977 }
7978
7979 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7980 {
7981   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
7982   checkAllocated();
7983   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7984   int nbComp=getNumberOfComponents();
7985   for(const int *z=bgComp;z!=endComp;z++)
7986     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7987   int nbOfTuples=getNumberOfTuples();
7988   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7989   int *pt=getPointer()+bgTuples*nbComp;
7990   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7991     for(const int *z=bgComp;z!=endComp;z++)
7992       pt[*z]=a;
7993 }
7994
7995 /*!
7996  * Copy some tuples from another DataArrayInt into specified tuples
7997  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7998  * components.
7999  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8000  * All components of selected tuples are copied.
8001  *  \param [in] a - the array to copy values from.
8002  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8003  *              target tuples of \a this. \a tuplesSelec has two components, and the
8004  *              first component specifies index of the source tuple and the second
8005  *              one specifies index of the target tuple.
8006  *  \throw If \a this is not allocated.
8007  *  \throw If \a a is NULL.
8008  *  \throw If \a a is not allocated.
8009  *  \throw If \a tuplesSelec is NULL.
8010  *  \throw If \a tuplesSelec is not allocated.
8011  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8012  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8013  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8014  *         the corresponding (\a this or \a a) array.
8015  */
8016 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
8017 {
8018   if(!a || !tuplesSelec)
8019     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8020   checkAllocated();
8021   a->checkAllocated();
8022   tuplesSelec->checkAllocated();
8023   int nbOfComp=getNumberOfComponents();
8024   if(nbOfComp!=a->getNumberOfComponents())
8025     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8026   if(tuplesSelec->getNumberOfComponents()!=2)
8027     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8028   int thisNt=getNumberOfTuples();
8029   int aNt=a->getNumberOfTuples();
8030   int *valsToSet=getPointer();
8031   const int *valsSrc=a->getConstPointer();
8032   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8033     {
8034       if(tuple[1]>=0 && tuple[1]<aNt)
8035         {
8036           if(tuple[0]>=0 && tuple[0]<thisNt)
8037             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8038           else
8039             {
8040               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8041               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8042               throw INTERP_KERNEL::Exception(oss.str().c_str());
8043             }
8044         }
8045       else
8046         {
8047           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8048           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8049           throw INTERP_KERNEL::Exception(oss.str().c_str());
8050         }
8051     }
8052 }
8053
8054 /*!
8055  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8056  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8057  * components.
8058  * The tuples to assign to are defined by index of the first tuple, and
8059  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8060  * The tuples to copy are defined by values of a DataArrayInt.
8061  * All components of selected tuples are copied.
8062  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8063  *              values to.
8064  *  \param [in] aBase - the array to copy values from.
8065  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8066  *  \throw If \a this is not allocated.
8067  *  \throw If \a aBase is NULL.
8068  *  \throw If \a aBase is not allocated.
8069  *  \throw If \a tuplesSelec is NULL.
8070  *  \throw If \a tuplesSelec is not allocated.
8071  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8072  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8073  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8074  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8075  *         \a aBase array.
8076  */
8077 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
8078 {
8079   if(!aBase || !tuplesSelec)
8080     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8081   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8082   if(!a)
8083     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8084   checkAllocated();
8085   a->checkAllocated();
8086   tuplesSelec->checkAllocated();
8087   int nbOfComp=getNumberOfComponents();
8088   if(nbOfComp!=a->getNumberOfComponents())
8089     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8090   if(tuplesSelec->getNumberOfComponents()!=1)
8091     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8092   int thisNt=getNumberOfTuples();
8093   int aNt=a->getNumberOfTuples();
8094   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8095   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8096   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8097     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8098   const int *valsSrc=a->getConstPointer();
8099   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8100     {
8101       if(*tuple>=0 && *tuple<aNt)
8102         {
8103           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8104         }
8105       else
8106         {
8107           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8108           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8109           throw INTERP_KERNEL::Exception(oss.str().c_str());
8110         }
8111     }
8112 }
8113
8114 /*!
8115  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8116  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8117  * components.
8118  * The tuples to copy are defined by three values similar to parameters of
8119  * the Python function \c range(\c start,\c stop,\c step).
8120  * The tuples to assign to are defined by index of the first tuple, and
8121  * their number is defined by number of tuples to copy.
8122  * All components of selected tuples are copied.
8123  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8124  *              values to.
8125  *  \param [in] aBase - the array to copy values from.
8126  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8127  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8128  *              are located.
8129  *  \param [in] step - index increment to get index of the next tuple to copy.
8130  *  \throw If \a this is not allocated.
8131  *  \throw If \a aBase is NULL.
8132  *  \throw If \a aBase is not allocated.
8133  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8134  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8135  *  \throw If parameters specifying tuples to copy, do not give a
8136  *            non-empty range of increasing indices or indices are out of a valid range
8137  *            for the array \a aBase.
8138  */
8139 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
8140 {
8141   if(!aBase)
8142     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8143   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8144   if(!a)
8145     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8146   checkAllocated();
8147   a->checkAllocated();
8148   int nbOfComp=getNumberOfComponents();
8149   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8150   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8151   if(nbOfComp!=a->getNumberOfComponents())
8152     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8153   int thisNt=getNumberOfTuples();
8154   int aNt=a->getNumberOfTuples();
8155   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8156   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8157     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8158   if(end2>aNt)
8159     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8160   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8161   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8162     {
8163       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8164     }
8165 }
8166
8167 /*!
8168  * Returns a value located at specified tuple and component.
8169  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8170  * parameters is checked. So this method is safe but expensive if used to go through
8171  * all values of \a this.
8172  *  \param [in] tupleId - index of tuple of interest.
8173  *  \param [in] compoId - index of component of interest.
8174  *  \return double - value located by \a tupleId and \a compoId.
8175  *  \throw If \a this is not allocated.
8176  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8177  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8178  */
8179 int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
8180 {
8181   checkAllocated();
8182   if(tupleId<0 || tupleId>=getNumberOfTuples())
8183     {
8184       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8185       throw INTERP_KERNEL::Exception(oss.str().c_str());
8186     }
8187   if(compoId<0 || compoId>=getNumberOfComponents())
8188     {
8189       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8190       throw INTERP_KERNEL::Exception(oss.str().c_str());
8191     }
8192   return _mem[tupleId*_info_on_compo.size()+compoId];
8193 }
8194
8195 /*!
8196  * Returns the first value of \a this. 
8197  *  \return int - the last value of \a this array.
8198  *  \throw If \a this is not allocated.
8199  *  \throw If \a this->getNumberOfComponents() != 1.
8200  *  \throw If \a this->getNumberOfTuples() < 1.
8201  */
8202 int DataArrayInt::front() const throw(INTERP_KERNEL::Exception)
8203 {
8204   checkAllocated();
8205   if(getNumberOfComponents()!=1)
8206     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8207   int nbOfTuples=getNumberOfTuples();
8208   if(nbOfTuples<1)
8209     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8210   return *(getConstPointer());
8211 }
8212
8213 /*!
8214  * Returns the last value of \a this. 
8215  *  \return int - the last value of \a this array.
8216  *  \throw If \a this is not allocated.
8217  *  \throw If \a this->getNumberOfComponents() != 1.
8218  *  \throw If \a this->getNumberOfTuples() < 1.
8219  */
8220 int DataArrayInt::back() const throw(INTERP_KERNEL::Exception)
8221 {
8222   checkAllocated();
8223   if(getNumberOfComponents()!=1)
8224     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8225   int nbOfTuples=getNumberOfTuples();
8226   if(nbOfTuples<1)
8227     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8228   return *(getConstPointer()+nbOfTuples-1);
8229 }
8230
8231 /*!
8232  * Assign pointer to one array to a pointer to another appay. Reference counter of
8233  * \a arrayToSet is incremented / decremented.
8234  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8235  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8236  */
8237 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8238 {
8239   if(newArray!=arrayToSet)
8240     {
8241       if(arrayToSet)
8242         arrayToSet->decrRef();
8243       arrayToSet=newArray;
8244       if(arrayToSet)
8245         arrayToSet->incrRef();
8246     }
8247 }
8248
8249 DataArrayIntIterator *DataArrayInt::iterator() throw(INTERP_KERNEL::Exception)
8250 {
8251   return new DataArrayIntIterator(this);
8252 }
8253
8254 /*!
8255  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8256  * given one.
8257  *  \param [in] val - the value to find within \a this.
8258  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8259  *          array using decrRef() as it is no more needed.
8260  *  \throw If \a this is not allocated.
8261  *  \throw If \a this->getNumberOfComponents() != 1.
8262  */
8263 DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception)
8264 {
8265   checkAllocated();
8266   if(getNumberOfComponents()!=1)
8267     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8268   const int *cptr=getConstPointer();
8269   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8270   int nbOfTuples=getNumberOfTuples();
8271   for(int i=0;i<nbOfTuples;i++,cptr++)
8272     if(*cptr==val)
8273       ret->pushBackSilent(i);
8274   return ret.retn();
8275 }
8276
8277 /*!
8278  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8279  * equal to a given one. 
8280  *  \param [in] val - the value to ignore within \a this.
8281  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8282  *          array using decrRef() as it is no more needed.
8283  *  \throw If \a this is not allocated.
8284  *  \throw If \a this->getNumberOfComponents() != 1.
8285  */
8286 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception)
8287 {
8288   checkAllocated();
8289   if(getNumberOfComponents()!=1)
8290     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8291   const int *cptr=getConstPointer();
8292   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8293   int nbOfTuples=getNumberOfTuples();
8294   for(int i=0;i<nbOfTuples;i++,cptr++)
8295     if(*cptr!=val)
8296       ret->pushBackSilent(i);
8297   return ret.retn();
8298 }
8299
8300
8301 /*!
8302  * Assigns \a newValue to all elements holding \a oldValue within \a this
8303  * one-dimensional array.
8304  *  \param [in] oldValue - the value to replace.
8305  *  \param [in] newValue - the value to assign.
8306  *  \return int - number of replacements performed.
8307  *  \throw If \a this is not allocated.
8308  *  \throw If \a this->getNumberOfComponents() != 1.
8309  */
8310 int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception)
8311 {
8312   checkAllocated();
8313   if(getNumberOfComponents()!=1)
8314     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8315   int *start=getPointer();
8316   int *end2=start+getNbOfElems();
8317   int ret=0;
8318   for(int *val=start;val!=end2;val++)
8319     {
8320       if(*val==oldValue)
8321         {
8322           *val=newValue;
8323           ret++;
8324         }
8325     }
8326   return ret;
8327 }
8328
8329 /*!
8330  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8331  * one of given values.
8332  *  \param [in] valsBg - an array of values to find within \a this array.
8333  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8334  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8335  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8336  *          array using decrRef() as it is no more needed.
8337  *  \throw If \a this->getNumberOfComponents() != 1.
8338  */
8339 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
8340 {
8341   if(getNumberOfComponents()!=1)
8342     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8343   std::set<int> vals2(valsBg,valsEnd);
8344   const int *cptr=getConstPointer();
8345   std::vector<int> res;
8346   int nbOfTuples=getNumberOfTuples();
8347   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8348   for(int i=0;i<nbOfTuples;i++,cptr++)
8349     if(vals2.find(*cptr)!=vals2.end())
8350       ret->pushBackSilent(i);
8351   return ret.retn();
8352 }
8353
8354 /*!
8355  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8356  * equal to any of given values.
8357  *  \param [in] valsBg - an array of values to ignore within \a this array.
8358  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8359  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8360  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8361  *          array using decrRef() as it is no more needed.
8362  *  \throw If \a this->getNumberOfComponents() != 1.
8363  */
8364 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
8365 {
8366   if(getNumberOfComponents()!=1)
8367     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8368   std::set<int> vals2(valsBg,valsEnd);
8369   const int *cptr=getConstPointer();
8370   std::vector<int> res;
8371   int nbOfTuples=getNumberOfTuples();
8372   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8373   for(int i=0;i<nbOfTuples;i++,cptr++)
8374     if(vals2.find(*cptr)==vals2.end())
8375       ret->pushBackSilent(i);
8376   return ret.retn();
8377 }
8378
8379 /*!
8380  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8381  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8382  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8383  * If any the tuple id is returned. If not -1 is returned.
8384  * 
8385  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8386  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8387  *
8388  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8389  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8390  */
8391 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8392 {
8393   checkAllocated();
8394   int nbOfCompo=getNumberOfComponents();
8395   if(nbOfCompo==0)
8396     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8397   if(nbOfCompo!=(int)tupl.size())
8398     {
8399       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8400       throw INTERP_KERNEL::Exception(oss.str().c_str());
8401     }
8402   const int *cptr=getConstPointer();
8403   std::size_t nbOfVals=getNbOfElems();
8404   for(const int *work=cptr;work!=cptr+nbOfVals;)
8405     {
8406       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8407       if(work!=cptr+nbOfVals)
8408         {
8409           if(std::distance(cptr,work)%nbOfCompo!=0)
8410             work++;
8411           else
8412             return std::distance(cptr,work)/nbOfCompo;
8413         }
8414     }
8415   return -1;
8416 }
8417
8418 /*!
8419  * This method searches the sequence specified in input parameter \b vals in \b this.
8420  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8421  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8422  * \sa DataArrayInt::locateTuple
8423  */
8424 int DataArrayInt::search(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8425 {
8426   checkAllocated();
8427   int nbOfCompo=getNumberOfComponents();
8428   if(nbOfCompo!=1)
8429     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8430   const int *cptr=getConstPointer();
8431   std::size_t nbOfVals=getNbOfElems();
8432   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8433   if(loc!=cptr+nbOfVals)
8434     return std::distance(cptr,loc);
8435   return -1;
8436 }
8437
8438 /*!
8439  * This method expects to be called when number of components of this is equal to one.
8440  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8441  * If not any tuple contains \b value -1 is returned.
8442  * \sa DataArrayInt::presenceOfValue
8443  */
8444 int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception)
8445 {
8446   checkAllocated();
8447   if(getNumberOfComponents()!=1)
8448     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8449   const int *cptr=getConstPointer();
8450   int nbOfTuples=getNumberOfTuples();
8451   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8452   if(ret!=cptr+nbOfTuples)
8453     return std::distance(cptr,ret);
8454   return -1;
8455 }
8456
8457 /*!
8458  * This method expects to be called when number of components of this is equal to one.
8459  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8460  * If not any tuple contains one of the values contained in 'vals' false is returned.
8461  * \sa DataArrayInt::presenceOfValue
8462  */
8463 int DataArrayInt::locateValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8464 {
8465   checkAllocated();
8466   if(getNumberOfComponents()!=1)
8467     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8468   std::set<int> vals2(vals.begin(),vals.end());
8469   const int *cptr=getConstPointer();
8470   int nbOfTuples=getNumberOfTuples();
8471   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8472     if(vals2.find(*w)!=vals2.end())
8473       return std::distance(cptr,w);
8474   return -1;
8475 }
8476
8477 /*!
8478  * This method returns the number of values in \a this that are equals to input parameter \a value.
8479  * This method only works for single component array.
8480  *
8481  * \return a value in [ 0, \c this->getNumberOfTuples() )
8482  *
8483  * \throw If \a this is not allocated
8484  *
8485  */
8486 int DataArrayInt::count(int value) const throw(INTERP_KERNEL::Exception)
8487 {
8488   int ret=0;
8489   checkAllocated();
8490   if(getNumberOfComponents()!=1)
8491     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8492   const int *vals=begin();
8493   int nbOfTuples=getNumberOfTuples();
8494   for(int i=0;i<nbOfTuples;i++,vals++)
8495     if(*vals==value)
8496       ret++;
8497   return ret;
8498 }
8499
8500 /*!
8501  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8502  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8503  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8504  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8505  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8506  * \sa DataArrayInt::locateTuple
8507  */
8508 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8509 {
8510   return locateTuple(tupl)!=-1;
8511 }
8512
8513
8514 /*!
8515  * Returns \a true if a given value is present within \a this one-dimensional array.
8516  *  \param [in] value - the value to find within \a this array.
8517  *  \return bool - \a true in case if \a value is present within \a this array.
8518  *  \throw If \a this is not allocated.
8519  *  \throw If \a this->getNumberOfComponents() != 1.
8520  *  \sa locateValue()
8521  */
8522 bool DataArrayInt::presenceOfValue(int value) const throw(INTERP_KERNEL::Exception)
8523 {
8524   return locateValue(value)!=-1;
8525 }
8526
8527 /*!
8528  * This method expects to be called when number of components of this is equal to one.
8529  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8530  * If not any tuple contains one of the values contained in 'vals' false is returned.
8531  * \sa DataArrayInt::locateValue
8532  */
8533 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8534 {
8535   return locateValue(vals)!=-1;
8536 }
8537
8538 /*!
8539  * Accumulates values of each component of \a this array.
8540  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8541  *         by the caller, that is filled by this method with sum value for each
8542  *         component.
8543  *  \throw If \a this is not allocated.
8544  */
8545 void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception)
8546 {
8547   checkAllocated();
8548   const int *ptr=getConstPointer();
8549   int nbTuple=getNumberOfTuples();
8550   int nbComps=getNumberOfComponents();
8551   std::fill(res,res+nbComps,0);
8552   for(int i=0;i<nbTuple;i++)
8553     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8554 }
8555
8556 int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
8557 {
8558   checkAllocated();
8559   const int *ptr=getConstPointer();
8560   int nbTuple=getNumberOfTuples();
8561   int nbComps=getNumberOfComponents();
8562   if(compId<0 || compId>=nbComps)
8563     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8564   int ret=0;
8565   for(int i=0;i<nbTuple;i++)
8566     ret+=ptr[i*nbComps+compId];
8567   return ret;
8568 }
8569
8570 /*!
8571  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8572  * The returned array will have same number of components than \a this and number of tuples equal to
8573  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8574  *
8575  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8576  *
8577  * \param [in] bgOfIndex - begin (included) of the input index array.
8578  * \param [in] endOfIndex - end (excluded) of the input index array.
8579  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8580  * 
8581  * \throw If bgOfIndex or end is NULL.
8582  * \throw If input index array is not ascendingly sorted.
8583  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8584  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8585  */
8586 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
8587 {
8588   if(!bgOfIndex || !endOfIndex)
8589     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8590   checkAllocated();
8591   int nbCompo=getNumberOfComponents();
8592   int nbOfTuples=getNumberOfTuples();
8593   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8594   if(sz<1)
8595     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8596   sz--;
8597   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8598   const int *w=bgOfIndex;
8599   if(*w<0 || *w>=nbOfTuples)
8600     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8601   const int *srcPt=begin()+(*w)*nbCompo;
8602   int *tmp=ret->getPointer();
8603   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8604     {
8605       std::fill(tmp,tmp+nbCompo,0.);
8606       if(w[1]>=w[0])
8607         {
8608           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8609             {
8610               if(j>=0 && j<nbOfTuples)
8611                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8612               else
8613                 {
8614                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8615                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8616                 }
8617             }
8618         }
8619       else
8620         {
8621           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8622           throw INTERP_KERNEL::Exception(oss.str().c_str());
8623         }
8624     }
8625   ret->copyStringInfoFrom(*this);
8626   return ret.retn();
8627 }
8628
8629 /*!
8630  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8631  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8632  * offsetA2</em> and (2)
8633  * the number of component in the result array is same as that of each of given arrays.
8634  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8635  * Info on components is copied from the first of the given arrays. Number of components
8636  * in the given arrays must be the same.
8637  *  \param [in] a1 - an array to include in the result array.
8638  *  \param [in] a2 - another array to include in the result array.
8639  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8640  *  \return DataArrayInt * - the new instance of DataArrayInt.
8641  *          The caller is to delete this result array using decrRef() as it is no more
8642  *          needed.
8643  *  \throw If either \a a1 or \a a2 is NULL.
8644  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8645  */
8646 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8647 {
8648   if(!a1 || !a2)
8649     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8650   int nbOfComp=a1->getNumberOfComponents();
8651   if(nbOfComp!=a2->getNumberOfComponents())
8652     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8653   int nbOfTuple1=a1->getNumberOfTuples();
8654   int nbOfTuple2=a2->getNumberOfTuples();
8655   DataArrayInt *ret=DataArrayInt::New();
8656   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8657   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8658   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8659   ret->copyStringInfoFrom(*a1);
8660   return ret;
8661 }
8662
8663 /*!
8664  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8665  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8666  * the number of component in the result array is same as that of each of given arrays.
8667  * Info on components is copied from the first of the given arrays. Number of components
8668  * in the given arrays must be  the same.
8669  *  \param [in] arr - a sequence of arrays to include in the result array.
8670  *  \return DataArrayInt * - the new instance of DataArrayInt.
8671  *          The caller is to delete this result array using decrRef() as it is no more
8672  *          needed.
8673  *  \throw If all arrays within \a arr are NULL.
8674  *  \throw If getNumberOfComponents() of arrays within \a arr.
8675  */
8676 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8677 {
8678   std::vector<const DataArrayInt *> a;
8679   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8680     if(*it4)
8681       a.push_back(*it4);
8682   if(a.empty())
8683     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8684   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8685   int nbOfComp=(*it)->getNumberOfComponents();
8686   int nbt=(*it++)->getNumberOfTuples();
8687   for(int i=1;it!=a.end();it++,i++)
8688     {
8689       if((*it)->getNumberOfComponents()!=nbOfComp)
8690         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8691       nbt+=(*it)->getNumberOfTuples();
8692     }
8693   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8694   ret->alloc(nbt,nbOfComp);
8695   int *pt=ret->getPointer();
8696   for(it=a.begin();it!=a.end();it++)
8697     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8698   ret->copyStringInfoFrom(*(a[0]));
8699   return ret.retn();
8700 }
8701
8702 /*!
8703  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8704  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8705  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8706  * 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.
8707  * 
8708  * \return DataArrayInt * - a new object to be managed by the caller.
8709  */
8710 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs) throw(INTERP_KERNEL::Exception)
8711 {
8712   int retSz=1;
8713   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8714     {
8715       if(*it4)
8716         {
8717           (*it4)->checkAllocated();
8718           if((*it4)->getNumberOfComponents()!=1)
8719             {
8720               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8721               throw INTERP_KERNEL::Exception(oss.str().c_str());
8722             }
8723           int nbTupl=(*it4)->getNumberOfTuples();
8724           if(nbTupl<1)
8725             {
8726               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8727               throw INTERP_KERNEL::Exception(oss.str().c_str());
8728             }
8729           if((*it4)->front()!=0)
8730             {
8731               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
8732               throw INTERP_KERNEL::Exception(oss.str().c_str());
8733             }
8734           retSz+=nbTupl-1;
8735         }
8736       else
8737         {
8738           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
8739           throw INTERP_KERNEL::Exception(oss.str().c_str());
8740         }
8741     }
8742   if(arrs.empty())
8743     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
8744   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8745   ret->alloc(retSz,1);
8746   int *pt=ret->getPointer(); *pt++=0;
8747   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
8748     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
8749   ret->copyStringInfoFrom(*(arrs[0]));
8750   return ret.retn();
8751 }
8752
8753 /*!
8754  * Returns the maximal value and its location within \a this one-dimensional array.
8755  *  \param [out] tupleId - index of the tuple holding the maximal value.
8756  *  \return int - the maximal value among all values of \a this array.
8757  *  \throw If \a this->getNumberOfComponents() != 1
8758  *  \throw If \a this->getNumberOfTuples() < 1
8759  */
8760 int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8761 {
8762   checkAllocated();
8763   if(getNumberOfComponents()!=1)
8764     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8765   int nbOfTuples=getNumberOfTuples();
8766   if(nbOfTuples<=0)
8767     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8768   const int *vals=getConstPointer();
8769   const int *loc=std::max_element(vals,vals+nbOfTuples);
8770   tupleId=(int)std::distance(vals,loc);
8771   return *loc;
8772 }
8773
8774 /*!
8775  * Returns the maximal value within \a this array that is allowed to have more than
8776  *  one component.
8777  *  \return int - the maximal value among all values of \a this array.
8778  *  \throw If \a this is not allocated.
8779  */
8780 int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
8781 {
8782   checkAllocated();
8783   const int *loc=std::max_element(begin(),end());
8784   return *loc;
8785 }
8786
8787 /*!
8788  * Returns the minimal value and its location within \a this one-dimensional array.
8789  *  \param [out] tupleId - index of the tuple holding the minimal value.
8790  *  \return int - the minimal value among all values of \a this array.
8791  *  \throw If \a this->getNumberOfComponents() != 1
8792  *  \throw If \a this->getNumberOfTuples() < 1
8793  */
8794 int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8795 {
8796   checkAllocated();
8797   if(getNumberOfComponents()!=1)
8798     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8799   int nbOfTuples=getNumberOfTuples();
8800   if(nbOfTuples<=0)
8801     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8802   const int *vals=getConstPointer();
8803   const int *loc=std::min_element(vals,vals+nbOfTuples);
8804   tupleId=(int)std::distance(vals,loc);
8805   return *loc;
8806 }
8807
8808 /*!
8809  * Returns the minimal value within \a this array that is allowed to have more than
8810  *  one component.
8811  *  \return int - the minimal value among all values of \a this array.
8812  *  \throw If \a this is not allocated.
8813  */
8814 int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
8815 {
8816   checkAllocated();
8817   const int *loc=std::min_element(begin(),end());
8818   return *loc;
8819 }
8820
8821 /*!
8822  * Converts every value of \a this array to its absolute value.
8823  *  \throw If \a this is not allocated.
8824  */
8825 void DataArrayInt::abs() throw(INTERP_KERNEL::Exception)
8826 {
8827   checkAllocated();
8828   int *ptr=getPointer();
8829   std::size_t nbOfElems=getNbOfElems();
8830   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8831   declareAsNew();
8832 }
8833
8834 /*!
8835  * Apply a liner function to a given component of \a this array, so that
8836  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8837  *  \param [in] a - the first coefficient of the function.
8838  *  \param [in] b - the second coefficient of the function.
8839  *  \param [in] compoId - the index of component to modify.
8840  *  \throw If \a this is not allocated.
8841  */
8842 void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception)
8843 {
8844   checkAllocated();
8845   int *ptr=getPointer()+compoId;
8846   int nbOfComp=getNumberOfComponents();
8847   int nbOfTuple=getNumberOfTuples();
8848   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8849     *ptr=a*(*ptr)+b;
8850   declareAsNew();
8851 }
8852
8853 /*!
8854  * Apply a liner function to all elements of \a this array, so that
8855  * an element _x_ becomes \f$ a * x + b \f$.
8856  *  \param [in] a - the first coefficient of the function.
8857  *  \param [in] b - the second coefficient of the function.
8858  *  \throw If \a this is not allocated.
8859  */
8860 void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception)
8861 {
8862   checkAllocated();
8863   int *ptr=getPointer();
8864   std::size_t nbOfElems=getNbOfElems();
8865   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8866     *ptr=a*(*ptr)+b;
8867   declareAsNew();
8868 }
8869
8870 /*!
8871  * Returns a full copy of \a this array except that sign of all elements is reversed.
8872  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8873  *          same number of tuples and component as \a this array.
8874  *          The caller is to delete this result array using decrRef() as it is no more
8875  *          needed.
8876  *  \throw If \a this is not allocated.
8877  */
8878 DataArrayInt *DataArrayInt::negate() const throw(INTERP_KERNEL::Exception)
8879 {
8880   checkAllocated();
8881   DataArrayInt *newArr=DataArrayInt::New();
8882   int nbOfTuples=getNumberOfTuples();
8883   int nbOfComp=getNumberOfComponents();
8884   newArr->alloc(nbOfTuples,nbOfComp);
8885   const int *cptr=getConstPointer();
8886   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8887   newArr->copyStringInfoFrom(*this);
8888   return newArr;
8889 }
8890
8891 /*!
8892  * Modify all elements of \a this array, so that
8893  * an element _x_ becomes \f$ numerator / x \f$.
8894  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8895  *           array, all elements processed before detection of the zero element remain
8896  *           modified.
8897  *  \param [in] numerator - the numerator used to modify array elements.
8898  *  \throw If \a this is not allocated.
8899  *  \throw If there is an element equal to 0 in \a this array.
8900  */
8901 void DataArrayInt::applyInv(int numerator) throw(INTERP_KERNEL::Exception)
8902 {
8903   checkAllocated();
8904   int *ptr=getPointer();
8905   std::size_t nbOfElems=getNbOfElems();
8906   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8907     {
8908       if(*ptr!=0)
8909         {
8910           *ptr=numerator/(*ptr);
8911         }
8912       else
8913         {
8914           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8915           oss << " !";
8916           throw INTERP_KERNEL::Exception(oss.str().c_str());
8917         }
8918     }
8919   declareAsNew();
8920 }
8921
8922 /*!
8923  * Modify all elements of \a this array, so that
8924  * an element _x_ becomes \f$ x / val \f$.
8925  *  \param [in] val - the denominator used to modify array elements.
8926  *  \throw If \a this is not allocated.
8927  *  \throw If \a val == 0.
8928  */
8929 void DataArrayInt::applyDivideBy(int val) throw(INTERP_KERNEL::Exception)
8930 {
8931   if(val==0)
8932     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
8933   checkAllocated();
8934   int *ptr=getPointer();
8935   std::size_t nbOfElems=getNbOfElems();
8936   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
8937   declareAsNew();
8938 }
8939
8940 /*!
8941  * Modify all elements of \a this array, so that
8942  * an element _x_ becomes  <em> x % val </em>.
8943  *  \param [in] val - the divisor used to modify array elements.
8944  *  \throw If \a this is not allocated.
8945  *  \throw If \a val <= 0.
8946  */
8947 void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception)
8948 {
8949   if(val<=0)
8950     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
8951   checkAllocated();
8952   int *ptr=getPointer();
8953   std::size_t nbOfElems=getNbOfElems();
8954   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
8955   declareAsNew();
8956 }
8957
8958 /*!
8959  * This method works only on data array with one component.
8960  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
8961  * this[*id] in [\b vmin,\b vmax)
8962  * 
8963  * \param [in] vmin begin of range. This value is included in range (included).
8964  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8965  * \return a newly allocated data array that the caller should deal with.
8966  */
8967 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8968 {
8969   checkAllocated();
8970   if(getNumberOfComponents()!=1)
8971     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
8972   const int *cptr=getConstPointer();
8973   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
8974   int nbOfTuples=getNumberOfTuples();
8975   for(int i=0;i<nbOfTuples;i++,cptr++)
8976     if(*cptr>=vmin && *cptr<vmax)
8977       ret->pushBackSilent(i);
8978   return ret.retn();
8979 }
8980
8981 /*!
8982  * This method works only on data array with one component.
8983  * 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.
8984  * 
8985  * \param [in] vmin begin of range. This value is included in range (included).
8986  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8987  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ).
8988  */
8989 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8990 {
8991   checkAllocated();
8992   if(getNumberOfComponents()!=1)
8993     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
8994   int nbOfTuples=getNumberOfTuples();
8995   bool ret=true;
8996   const int *cptr=getConstPointer();
8997   for(int i=0;i<nbOfTuples;i++,cptr++)
8998     {
8999       if(*cptr>=vmin && *cptr<vmax)
9000         { ret=ret && *cptr==i; }
9001       else
9002         {
9003           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9004           throw INTERP_KERNEL::Exception(oss.str().c_str());
9005         }
9006     }
9007   return ret;
9008 }
9009
9010 /*!
9011  * Modify all elements of \a this array, so that
9012  * an element _x_ becomes <em> val % x </em>.
9013  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9014  *           array, all elements processed before detection of the zero element remain
9015  *           modified.
9016  *  \param [in] val - the divident used to modify array elements.
9017  *  \throw If \a this is not allocated.
9018  *  \throw If there is an element equal to or less than 0 in \a this array.
9019  */
9020 void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception)
9021 {
9022   checkAllocated();
9023   int *ptr=getPointer();
9024   std::size_t nbOfElems=getNbOfElems();
9025   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9026     {
9027       if(*ptr>0)
9028         {
9029           *ptr=val%(*ptr);
9030         }
9031       else
9032         {
9033           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9034           oss << " !";
9035           throw INTERP_KERNEL::Exception(oss.str().c_str());
9036         }
9037     }
9038   declareAsNew();
9039 }
9040
9041 /*!
9042  * Modify all elements of \a this array, so that
9043  * an element _x_ becomes <em> val ^ x </em>.
9044  *  \param [in] val - the value used to apply pow on all array elements.
9045  *  \throw If \a this is not allocated.
9046  *  \throw If \a val < 0.
9047  */
9048 void DataArrayInt::applyPow(int val) throw(INTERP_KERNEL::Exception)
9049 {
9050   checkAllocated();
9051   if(val<0)
9052     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9053   int *ptr=getPointer();
9054   std::size_t nbOfElems=getNbOfElems();
9055   if(val==0)
9056     {
9057       std::fill(ptr,ptr+nbOfElems,1.);
9058       return ;
9059     }
9060   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9061     {
9062       int tmp=1;
9063       for(int j=0;j<val;j++)
9064         tmp*=*ptr;
9065       *ptr=tmp;
9066     }
9067   declareAsNew();
9068 }
9069
9070 /*!
9071  * Modify all elements of \a this array, so that
9072  * an element _x_ becomes \f$ val ^ x \f$.
9073  *  \param [in] val - the value used to apply pow on all array elements.
9074  *  \throw If \a this is not allocated.
9075  *  \throw If there is an element < 0 in \a this array.
9076  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9077  *           array, all elements processed before detection of the zero element remain
9078  *           modified.
9079  */
9080 void DataArrayInt::applyRPow(int val) throw(INTERP_KERNEL::Exception)
9081 {
9082   checkAllocated();
9083   int *ptr=getPointer();
9084   std::size_t nbOfElems=getNbOfElems();
9085   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9086     {
9087       if(*ptr>=0)
9088         {
9089           int tmp=1;
9090           for(int j=0;j<*ptr;j++)
9091             tmp*=val;
9092           *ptr=tmp;
9093         }
9094       else
9095         {
9096           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9097           oss << " !";
9098           throw INTERP_KERNEL::Exception(oss.str().c_str());
9099         }
9100     }
9101   declareAsNew();
9102 }
9103
9104 /*!
9105  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9106  * of components in the result array is a sum of the number of components of given arrays
9107  * and (2) the number of tuples in the result array is same as that of each of given
9108  * arrays. In other words the i-th tuple of result array includes all components of
9109  * i-th tuples of all given arrays.
9110  * Number of tuples in the given arrays must be the same.
9111  *  \param [in] a1 - an array to include in the result array.
9112  *  \param [in] a2 - another array to include in the result array.
9113  *  \return DataArrayInt * - the new instance of DataArrayInt.
9114  *          The caller is to delete this result array using decrRef() as it is no more
9115  *          needed.
9116  *  \throw If both \a a1 and \a a2 are NULL.
9117  *  \throw If any given array is not allocated.
9118  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9119  */
9120 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9121 {
9122   std::vector<const DataArrayInt *> arr(2);
9123   arr[0]=a1; arr[1]=a2;
9124   return Meld(arr);
9125 }
9126
9127 /*!
9128  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9129  * of components in the result array is a sum of the number of components of given arrays
9130  * and (2) the number of tuples in the result array is same as that of each of given
9131  * arrays. In other words the i-th tuple of result array includes all components of
9132  * i-th tuples of all given arrays.
9133  * Number of tuples in the given arrays must be  the same.
9134  *  \param [in] arr - a sequence of arrays to include in the result array.
9135  *  \return DataArrayInt * - the new instance of DataArrayInt.
9136  *          The caller is to delete this result array using decrRef() as it is no more
9137  *          needed.
9138  *  \throw If all arrays within \a arr are NULL.
9139  *  \throw If any given array is not allocated.
9140  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9141  */
9142 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
9143 {
9144   std::vector<const DataArrayInt *> a;
9145   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9146     if(*it4)
9147       a.push_back(*it4);
9148   if(a.empty())
9149     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9150   std::vector<const DataArrayInt *>::const_iterator it;
9151   for(it=a.begin();it!=a.end();it++)
9152     (*it)->checkAllocated();
9153   it=a.begin();
9154   int nbOfTuples=(*it)->getNumberOfTuples();
9155   std::vector<int> nbc(a.size());
9156   std::vector<const int *> pts(a.size());
9157   nbc[0]=(*it)->getNumberOfComponents();
9158   pts[0]=(*it++)->getConstPointer();
9159   for(int i=1;it!=a.end();it++,i++)
9160     {
9161       if(nbOfTuples!=(*it)->getNumberOfTuples())
9162         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9163       nbc[i]=(*it)->getNumberOfComponents();
9164       pts[i]=(*it)->getConstPointer();
9165     }
9166   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9167   DataArrayInt *ret=DataArrayInt::New();
9168   ret->alloc(nbOfTuples,totalNbOfComp);
9169   int *retPtr=ret->getPointer();
9170   for(int i=0;i<nbOfTuples;i++)
9171     for(int j=0;j<(int)a.size();j++)
9172       {
9173         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9174         pts[j]+=nbc[j];
9175       }
9176   int k=0;
9177   for(int i=0;i<(int)a.size();i++)
9178     for(int j=0;j<nbc[i];j++,k++)
9179       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
9180   return ret;
9181 }
9182
9183 /*!
9184  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9185  * The i-th item of the result array is an ID of a set of elements belonging to a
9186  * unique set of groups, which the i-th element is a part of. This set of elements
9187  * belonging to a unique set of groups is called \a family, so the result array contains
9188  * IDs of families each element belongs to.
9189  *
9190  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9191  * then there are 3 families:
9192  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9193  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9194  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9195  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9196  * stands for the element #3 which is in none of groups.
9197  *
9198  *  \param [in] groups - sequence of groups of element IDs.
9199  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9200  *         in \a groups.
9201  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9202  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9203  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9204  *         delete this array using decrRef() as it is no more needed.
9205  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9206  */
9207 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) throw(INTERP_KERNEL::Exception)
9208 {
9209   std::vector<const DataArrayInt *> groups2;
9210   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9211     if(*it4)
9212       groups2.push_back(*it4);
9213   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9214   ret->alloc(newNb,1);
9215   int *retPtr=ret->getPointer();
9216   std::fill(retPtr,retPtr+newNb,0);
9217   int fid=1;
9218   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9219     {
9220       const int *ptr=(*iter)->getConstPointer();
9221       std::size_t nbOfElem=(*iter)->getNbOfElems();
9222       int sfid=fid;
9223       for(int j=0;j<sfid;j++)
9224         {
9225           bool found=false;
9226           for(std::size_t i=0;i<nbOfElem;i++)
9227             {
9228               if(ptr[i]>=0 && ptr[i]<newNb)
9229                 {
9230                   if(retPtr[ptr[i]]==j)
9231                     {
9232                       retPtr[ptr[i]]=fid;
9233                       found=true;
9234                     }
9235                 }
9236               else
9237                 {
9238                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9239                   oss << ") !";
9240                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9241                 }
9242             }
9243           if(found)
9244             fid++;
9245         }
9246     }
9247   fidsOfGroups.clear();
9248   fidsOfGroups.resize(groups2.size());
9249   int grId=0;
9250   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9251     {
9252       std::set<int> tmp;
9253       const int *ptr=(*iter)->getConstPointer();
9254       std::size_t nbOfElem=(*iter)->getNbOfElems();
9255       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9256         tmp.insert(retPtr[*p]);
9257       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9258     }
9259   return ret.retn();
9260 }
9261
9262 /*!
9263  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9264  * arrays. The result array does not contain any duplicates and its values
9265  * are sorted in ascending order.
9266  *  \param [in] arr - sequence of DataArrayInt's to unite.
9267  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9268  *         array using decrRef() as it is no more needed.
9269  *  \throw If any \a arr[i] is not allocated.
9270  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9271  */
9272 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
9273 {
9274   std::vector<const DataArrayInt *> a;
9275   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9276     if(*it4)
9277       a.push_back(*it4);
9278   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9279     {
9280       (*it)->checkAllocated();
9281       if((*it)->getNumberOfComponents()!=1)
9282         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9283     }
9284   //
9285   std::set<int> r;
9286   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9287     {
9288       const int *pt=(*it)->getConstPointer();
9289       int nbOfTuples=(*it)->getNumberOfTuples();
9290       r.insert(pt,pt+nbOfTuples);
9291     }
9292   DataArrayInt *ret=DataArrayInt::New();
9293   ret->alloc((int)r.size(),1);
9294   std::copy(r.begin(),r.end(),ret->getPointer());
9295   return ret;
9296 }
9297
9298 /*!
9299  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9300  * arrays. The result array does not contain any duplicates and its values
9301  * are sorted in ascending order.
9302  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9303  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9304  *         array using decrRef() as it is no more needed.
9305  *  \throw If any \a arr[i] is not allocated.
9306  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9307  */
9308 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
9309 {
9310   std::vector<const DataArrayInt *> a;
9311   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9312     if(*it4)
9313       a.push_back(*it4);
9314   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9315     {
9316       (*it)->checkAllocated();
9317       if((*it)->getNumberOfComponents()!=1)
9318         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9319     }
9320   //
9321   std::set<int> r;
9322   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9323     {
9324       const int *pt=(*it)->getConstPointer();
9325       int nbOfTuples=(*it)->getNumberOfTuples();
9326       std::set<int> s1(pt,pt+nbOfTuples);
9327       if(it!=a.begin())
9328         {
9329           std::set<int> r2;
9330           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9331           r=r2;
9332         }
9333       else
9334         r=s1;
9335     }
9336   DataArrayInt *ret=DataArrayInt::New();
9337   ret->alloc((int)r.size(),1);
9338   std::copy(r.begin(),r.end(),ret->getPointer());
9339   return ret;
9340 }
9341
9342 /*!
9343  * Returns a new DataArrayInt which contains a complement of elements of \a this
9344  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9345  * \a nbOfElement) not present in \a this array.
9346  *  \param [in] nbOfElement - maximal size of the result array.
9347  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9348  *         array using decrRef() as it is no more needed.
9349  *  \throw If \a this is not allocated.
9350  *  \throw If \a this->getNumberOfComponents() != 1.
9351  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9352  *         nbOfElement ).
9353  */
9354 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception)
9355 {
9356    checkAllocated();
9357    if(getNumberOfComponents()!=1)
9358      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9359    std::vector<bool> tmp(nbOfElement);
9360    const int *pt=getConstPointer();
9361    int nbOfTuples=getNumberOfTuples();
9362    for(const int *w=pt;w!=pt+nbOfTuples;w++)
9363      if(*w>=0 && *w<nbOfElement)
9364        tmp[*w]=true;
9365      else
9366        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9367    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9368    DataArrayInt *ret=DataArrayInt::New();
9369    ret->alloc(nbOfRetVal,1);
9370    int j=0;
9371    int *retPtr=ret->getPointer();
9372    for(int i=0;i<nbOfElement;i++)
9373      if(!tmp[i])
9374        retPtr[j++]=i;
9375    return ret;
9376 }
9377
9378 /*!
9379  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9380  * from an \a other one-dimensional array.
9381  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9382  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9383  *         caller is to delete this array using decrRef() as it is no more needed.
9384  *  \throw If \a other is NULL.
9385  *  \throw If \a other is not allocated.
9386  *  \throw If \a other->getNumberOfComponents() != 1.
9387  *  \throw If \a this is not allocated.
9388  *  \throw If \a this->getNumberOfComponents() != 1.
9389  *  \sa DataArrayInt::buildSubstractionOptimized()
9390  */
9391 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9392 {
9393   if(!other)
9394     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9395   checkAllocated();
9396   other->checkAllocated();
9397   if(getNumberOfComponents()!=1)
9398      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9399   if(other->getNumberOfComponents()!=1)
9400      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9401   const int *pt=getConstPointer();
9402   int nbOfTuples=getNumberOfTuples();
9403   std::set<int> s1(pt,pt+nbOfTuples);
9404   pt=other->getConstPointer();
9405   nbOfTuples=other->getNumberOfTuples();
9406   std::set<int> s2(pt,pt+nbOfTuples);
9407   std::vector<int> r;
9408   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9409   DataArrayInt *ret=DataArrayInt::New();
9410   ret->alloc((int)r.size(),1);
9411   std::copy(r.begin(),r.end(),ret->getPointer());
9412   return ret;
9413 }
9414
9415 /*!
9416  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9417  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9418  * 
9419  * \param [in] other an array with one component and expected to be sorted ascendingly.
9420  * \ret list of ids in \a this but not in \a other.
9421  * \sa DataArrayInt::buildSubstraction
9422  */
9423 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9424 {
9425   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9426   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9427   checkAllocated(); other->checkAllocated();
9428   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9429   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9430   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
9431   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9432   for(;work1!=pt1End;work1++)
9433     {
9434       if(work2!=pt2End && *work1==*work2)
9435         work2++;
9436       else
9437         ret->pushBackSilent(*work1);
9438     }
9439   return ret.retn();
9440 }
9441
9442
9443 /*!
9444  * Returns a new DataArrayInt which contains all elements of \a this and a given
9445  * one-dimensional arrays. The result array does not contain any duplicates
9446  * and its values are sorted in ascending order.
9447  *  \param [in] other - an array to unite with \a this one.
9448  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9449  *         array using decrRef() as it is no more needed.
9450  *  \throw If \a this or \a other is not allocated.
9451  *  \throw If \a this->getNumberOfComponents() != 1.
9452  *  \throw If \a other->getNumberOfComponents() != 1.
9453  */
9454 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9455 {
9456   std::vector<const DataArrayInt *>arrs(2);
9457   arrs[0]=this; arrs[1]=other;
9458   return BuildUnion(arrs);
9459 }
9460
9461
9462 /*!
9463  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9464  * one-dimensional arrays. The result array does not contain any duplicates
9465  * and its values are sorted in ascending order.
9466  *  \param [in] other - an array to intersect with \a this one.
9467  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9468  *         array using decrRef() as it is no more needed.
9469  *  \throw If \a this or \a other is not allocated.
9470  *  \throw If \a this->getNumberOfComponents() != 1.
9471  *  \throw If \a other->getNumberOfComponents() != 1.
9472  */
9473 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9474 {
9475   std::vector<const DataArrayInt *>arrs(2);
9476   arrs[0]=this; arrs[1]=other;
9477   return BuildIntersection(arrs);
9478 }
9479
9480 /*!
9481  * This method can be applied on allocated with one component DataArrayInt instance.
9482  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9483  * 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]
9484  * 
9485  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9486  * \throw if \a this is not allocated or if \a this has not exactly one component.
9487  */
9488 DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
9489 {
9490   checkAllocated();
9491   if(getNumberOfComponents()!=1)
9492      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9493   int nbOfTuples=getNumberOfTuples();
9494   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9495   int *data=tmp->getPointer();
9496   int *last=std::unique(data,data+nbOfTuples);
9497   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9498   ret->alloc(std::distance(data,last),1);
9499   std::copy(data,last,ret->getPointer());
9500   return ret.retn();
9501 }
9502
9503 /*!
9504  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9505  * "index" array. Such "index" array is returned for example by 
9506  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9507  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9508  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9509  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9510  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
9511  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9512  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9513  *          The caller is to delete this array using decrRef() as it is no more needed. 
9514  *  \throw If \a this is not allocated.
9515  *  \throw If \a this->getNumberOfComponents() != 1.
9516  *  \throw If \a this->getNumberOfTuples() < 2.
9517  *
9518  *  \b Example: <br> 
9519  *         - this contains [1,3,6,7,7,9,15]
9520  *         - result array contains [2,3,1,0,2,6],
9521  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9522  *
9523  * \sa DataArrayInt::computeOffsets2
9524  */
9525 DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception)
9526 {
9527   checkAllocated();
9528   if(getNumberOfComponents()!=1)
9529      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9530   int nbOfTuples=getNumberOfTuples();
9531   if(nbOfTuples<2)
9532     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9533   const int *ptr=getConstPointer();
9534   DataArrayInt *ret=DataArrayInt::New();
9535   ret->alloc(nbOfTuples-1,1);
9536   int *out=ret->getPointer();
9537   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9538   return ret;
9539 }
9540
9541 /*!
9542  * Modifies \a this one-dimensional array so that value of each element \a x
9543  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9544  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9545  * and components remains the same.<br>
9546  * This method is useful for allToAllV in MPI with contiguous policy. This method
9547  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9548  * this one.
9549  *  \throw If \a this is not allocated.
9550  *  \throw If \a this->getNumberOfComponents() != 1.
9551  *
9552  *  \b Example: <br>
9553  *          - Before \a this contains [3,5,1,2,0,8]
9554  *          - After \a this contains  [0,3,8,9,11,11]<br>
9555  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9556  *          array is retained and thus there is no space to store the last element.
9557  */
9558 void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception)
9559 {
9560   checkAllocated();
9561   if(getNumberOfComponents()!=1)
9562      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9563   int nbOfTuples=getNumberOfTuples();
9564   if(nbOfTuples==0)
9565     return ;
9566   int *work=getPointer();
9567   int tmp=work[0];
9568   work[0]=0;
9569   for(int i=1;i<nbOfTuples;i++)
9570     {
9571       int tmp2=work[i];
9572       work[i]=work[i-1]+tmp;
9573       tmp=tmp2;
9574     }
9575   declareAsNew();
9576 }
9577
9578
9579 /*!
9580  * Modifies \a this one-dimensional array so that value of each element \a x
9581  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9582  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9583  * components remains the same and number of tuples is inceamented by one.<br>
9584  * This method is useful for allToAllV in MPI with contiguous policy. This method
9585  * differs from computeOffsets() in that the number of tuples is changed by this one.
9586  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9587  *  \throw If \a this is not allocated.
9588  *  \throw If \a this->getNumberOfComponents() != 1.
9589  *
9590  *  \b Example: <br>
9591  *          - Before \a this contains [3,5,1,2,0,8]
9592  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9593  * \sa DataArrayInt::deltaShiftIndex
9594  */
9595 void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
9596 {
9597   checkAllocated();
9598   if(getNumberOfComponents()!=1)
9599     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9600   int nbOfTuples=getNumberOfTuples();
9601   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9602   if(nbOfTuples==0)
9603     return ;
9604   const int *work=getConstPointer();
9605   ret[0]=0;
9606   for(int i=0;i<nbOfTuples;i++)
9607     ret[i+1]=work[i]+ret[i];
9608   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9609   declareAsNew();
9610 }
9611
9612 /*!
9613  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9614  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9615  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9616  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9617  * filling completely one of the ranges in \a this.
9618  *
9619  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9620  * \param [out] rangeIdsFetched the range ids fetched
9621  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9622  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9623  *
9624  * \sa DataArrayInt::computeOffsets2
9625  *
9626  *  \b Example: <br>
9627  *          - \a this : [0,3,7,9,15,18]
9628  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9629  *          - \a rangeIdsFetched result array: [0,2,4]
9630  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9631  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9632  * <br>
9633  */
9634 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const throw(INTERP_KERNEL::Exception)
9635 {
9636   if(!listOfIds)
9637     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
9638   listOfIds->checkAllocated(); checkAllocated();
9639   if(listOfIds->getNumberOfComponents()!=1)
9640     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
9641   if(getNumberOfComponents()!=1)
9642     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
9643   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
9644   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
9645   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
9646   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
9647   while(tupPtr!=tupEnd && offPtr!=offEnd)
9648     {
9649       if(*tupPtr==*offPtr)
9650         {
9651           int i=offPtr[0];
9652           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
9653           if(i==offPtr[1])
9654             {
9655               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
9656               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
9657               offPtr++;
9658             }
9659         }
9660       else
9661         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
9662     }
9663   rangeIdsFetched=ret0.retn();
9664   idsInInputListThatFetch=ret1.retn();
9665 }
9666
9667 /*!
9668  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
9669  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9670  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9671  * beginning within the "iota" array. And \a this is a one-dimensional array
9672  * considered as a selector of groups described by \a offsets to include into the result array.
9673  *  \throw If \a offsets is NULL.
9674  *  \throw If \a offsets is not allocated.
9675  *  \throw If \a offsets->getNumberOfComponents() != 1.
9676  *  \throw If \a offsets is not monotonically increasing.
9677  *  \throw If \a this is not allocated.
9678  *  \throw If \a this->getNumberOfComponents() != 1.
9679  *  \throw If any element of \a this is not a valid index for \a offsets array.
9680  *
9681  *  \b Example: <br>
9682  *          - \a this: [0,2,3]
9683  *          - \a offsets: [0,3,6,10,14,20]
9684  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
9685  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
9686  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
9687  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
9688  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
9689  */
9690 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception)
9691 {
9692   if(!offsets)
9693     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
9694   checkAllocated();
9695   if(getNumberOfComponents()!=1)
9696      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
9697   offsets->checkAllocated();
9698   if(offsets->getNumberOfComponents()!=1)
9699      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
9700   int othNbTuples=offsets->getNumberOfTuples()-1;
9701   int nbOfTuples=getNumberOfTuples();
9702   int retNbOftuples=0;
9703   const int *work=getConstPointer();
9704   const int *offPtr=offsets->getConstPointer();
9705   for(int i=0;i<nbOfTuples;i++)
9706     {
9707       int val=work[i];
9708       if(val>=0 && val<othNbTuples)
9709         {
9710           int delta=offPtr[val+1]-offPtr[val];
9711           if(delta>=0)
9712             retNbOftuples+=delta;
9713           else
9714             {
9715               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
9716               throw INTERP_KERNEL::Exception(oss.str().c_str());
9717             }
9718         }
9719       else
9720         {
9721           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
9722           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
9723           throw INTERP_KERNEL::Exception(oss.str().c_str());
9724         }
9725     }
9726   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9727   ret->alloc(retNbOftuples,1);
9728   int *retPtr=ret->getPointer();
9729   for(int i=0;i<nbOfTuples;i++)
9730     {
9731       int val=work[i];
9732       int start=offPtr[val];
9733       int off=offPtr[val+1]-start;
9734       for(int j=0;j<off;j++,retPtr++)
9735         *retPtr=start+j;
9736     }
9737   return ret.retn();
9738 }
9739
9740 /*!
9741  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
9742  * scaled array (monotonically increasing).
9743 from that of \a this and \a
9744  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9745  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9746  * beginning within the "iota" array. And \a this is a one-dimensional array
9747  * considered as a selector of groups described by \a offsets to include into the result array.
9748  *  \throw If \a  is NULL.
9749  *  \throw If \a this is not allocated.
9750  *  \throw If \a this->getNumberOfComponents() != 1.
9751  *  \throw If \a this->getNumberOfTuples() == 0.
9752  *  \throw If \a this is not monotonically increasing.
9753  *  \throw If any element of ids in ( \a gb \a end \a step ) points outside the scale in \a this.
9754  *
9755  *  \b Example: <br>
9756  *          - \a bg , \a end and \a step : (0,5,2)
9757  *          - \a this: [0,3,6,10,14,20]
9758  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
9759  */
9760 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int end, int step) const throw(INTERP_KERNEL::Exception)
9761 {
9762   if(!isAllocated())
9763     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
9764   if(getNumberOfComponents()!=1)
9765     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
9766   int nbOfTuples(getNumberOfTuples());
9767   if(nbOfTuples==0)
9768     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
9769   const int *ids(begin());
9770   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,end,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
9771   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9772     {
9773       if(pos>=0 && pos<nbOfTuples-1)
9774         {
9775           int delta(ids[pos+1]-ids[pos]);
9776           sz+=delta;
9777           if(delta<0)
9778             {
9779               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
9780               throw INTERP_KERNEL::Exception(oss.str().c_str());
9781             }          
9782         }
9783       else
9784         {
9785           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
9786           throw INTERP_KERNEL::Exception(oss.str().c_str());
9787         }
9788     }
9789   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9790   int *retPtr(ret->getPointer());
9791   pos=bg;
9792   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9793     {
9794       int delta(ids[pos+1]-ids[pos]);
9795       for(int j=0;j<delta;j++,retPtr++)
9796         *retPtr=pos;
9797     }
9798   return ret.retn();
9799 }
9800
9801 /*!
9802  * 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.
9803  * 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
9804  * in tuple **i** of returned DataArrayInt.
9805  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9806  *
9807  * 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)]
9808  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9809  * 
9810  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9811  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9812  * \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
9813  *        is thrown if no ranges in \a ranges contains value in \a this.
9814  * 
9815  * \sa DataArrayInt::findIdInRangeForEachTuple
9816  */
9817 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9818 {
9819   if(!ranges)
9820     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9821   if(ranges->getNumberOfComponents()!=2)
9822     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9823   checkAllocated();
9824   if(getNumberOfComponents()!=1)
9825     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9826   int nbTuples=getNumberOfTuples();
9827   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9828   int nbOfRanges=ranges->getNumberOfTuples();
9829   const int *rangesPtr=ranges->getConstPointer();
9830   int *retPtr=ret->getPointer();
9831   const int *inPtr=getConstPointer();
9832   for(int i=0;i<nbTuples;i++,retPtr++)
9833     {
9834       int val=inPtr[i];
9835       bool found=false;
9836       for(int j=0;j<nbOfRanges && !found;j++)
9837         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9838           { *retPtr=j; found=true; }
9839       if(found)
9840         continue;
9841       else
9842         {
9843           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9844           throw INTERP_KERNEL::Exception(oss.str().c_str());
9845         }
9846     }
9847   return ret.retn();
9848 }
9849
9850 /*!
9851  * 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.
9852  * 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
9853  * in tuple **i** of returned DataArrayInt.
9854  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9855  *
9856  * 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)]
9857  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9858  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9859  * 
9860  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9861  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9862  * \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
9863  *        is thrown if no ranges in \a ranges contains value in \a this.
9864  * \sa DataArrayInt::findRangeIdForEachTuple
9865  */
9866 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9867 {
9868   if(!ranges)
9869     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9870   if(ranges->getNumberOfComponents()!=2)
9871     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9872   checkAllocated();
9873   if(getNumberOfComponents()!=1)
9874     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9875   int nbTuples=getNumberOfTuples();
9876   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9877   int nbOfRanges=ranges->getNumberOfTuples();
9878   const int *rangesPtr=ranges->getConstPointer();
9879   int *retPtr=ret->getPointer();
9880   const int *inPtr=getConstPointer();
9881   for(int i=0;i<nbTuples;i++,retPtr++)
9882     {
9883       int val=inPtr[i];
9884       bool found=false;
9885       for(int j=0;j<nbOfRanges && !found;j++)
9886         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9887           { *retPtr=val-rangesPtr[2*j]; found=true; }
9888       if(found)
9889         continue;
9890       else
9891         {
9892           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
9893           throw INTERP_KERNEL::Exception(oss.str().c_str());
9894         }
9895     }
9896   return ret.retn();
9897 }
9898
9899 /*!
9900  * 
9901  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
9902  *             \a nbTimes  should be at least equal to 1.
9903  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
9904  * \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.
9905  */
9906 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
9907 {
9908   checkAllocated();
9909   if(getNumberOfComponents()!=1)
9910     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
9911   if(nbTimes<1)
9912     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
9913   int nbTuples=getNumberOfTuples();
9914   const int *inPtr=getConstPointer();
9915   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
9916   int *retPtr=ret->getPointer();
9917   for(int i=0;i<nbTuples;i++,inPtr++)
9918     {
9919       int val=*inPtr;
9920       for(int j=0;j<nbTimes;j++,retPtr++)
9921         *retPtr=val;
9922     }
9923   ret->copyStringInfoFrom(*this);
9924   return ret.retn();
9925 }
9926
9927 /*!
9928  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
9929  * But the number of components can be different from one.
9930  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
9931  */
9932 DataArrayInt *DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception)
9933 {
9934   checkAllocated();
9935   std::set<int> ret;
9936   ret.insert(begin(),end());
9937   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
9938   std::copy(ret.begin(),ret.end(),ret2->getPointer());
9939   return ret2.retn();
9940 }
9941
9942 /*!
9943  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
9944  * them it tells which tuple id have this id.
9945  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
9946  * This method returns two arrays having same size.
9947  * 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.
9948  * 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]]
9949  */
9950 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception)
9951 {
9952   checkAllocated();
9953   if(getNumberOfComponents()!=1)
9954     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
9955   int id=0;
9956   std::map<int,int> m,m2,m3;
9957   for(const int *w=begin();w!=end();w++)
9958     m[*w]++;
9959   differentIds.resize(m.size());
9960   std::vector<DataArrayInt *> ret(m.size());
9961   std::vector<int *> retPtr(m.size());
9962   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
9963     {
9964       m2[(*it).first]=id;
9965       ret[id]=DataArrayInt::New();
9966       ret[id]->alloc((*it).second,1);
9967       retPtr[id]=ret[id]->getPointer();
9968       differentIds[id]=(*it).first;
9969     }
9970   id=0;
9971   for(const int *w=begin();w!=end();w++,id++)
9972     {
9973       retPtr[m2[*w]][m3[*w]++]=id;
9974     }
9975   return ret;
9976 }
9977
9978 /*!
9979  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
9980  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
9981  *
9982  * \param [in] nbOfSlices - number of slices expected.
9983  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
9984  * 
9985  * \sa DataArray::GetSlice
9986  * \throw If \a this is not allocated or not with exactly one component.
9987  * \throw If an element in \a this if < 0.
9988  */
9989 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const throw(INTERP_KERNEL::Exception)
9990 {
9991   if(!isAllocated() || getNumberOfComponents()!=1)
9992     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
9993   if(nbOfSlices<=0)
9994     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
9995   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
9996   int sumPerSlc(sum/nbOfSlices),pos(0);
9997   const int *w(begin());
9998   std::vector< std::pair<int,int> > ret(nbOfSlices);
9999   for(int i=0;i<nbOfSlices;i++)
10000     {
10001       std::pair<int,int> p(pos,-1);
10002       int locSum(0);
10003       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10004       if(i!=nbOfSlices-1)
10005         p.second=pos;
10006       else
10007         p.second=nbOfTuples;
10008       ret[i]=p;
10009     }
10010   return ret;
10011 }
10012
10013 /*!
10014  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10015  * valid cases.
10016  * 1.  The arrays have same number of tuples and components. Then each value of
10017  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10018  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10019  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10020  *   component. Then
10021  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10022  * 3.  The arrays have same number of components and one array, say _a2_, has one
10023  *   tuple. Then
10024  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10025  *
10026  * Info on components is copied either from the first array (in the first case) or from
10027  * the array with maximal number of elements (getNbOfElems()).
10028  *  \param [in] a1 - an array to sum up.
10029  *  \param [in] a2 - another array to sum up.
10030  *  \return DataArrayInt * - the new instance of DataArrayInt.
10031  *          The caller is to delete this result array using decrRef() as it is no more
10032  *          needed.
10033  *  \throw If either \a a1 or \a a2 is NULL.
10034  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10035  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10036  *         none of them has number of tuples or components equal to 1.
10037  */
10038 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10039 {
10040   if(!a1 || !a2)
10041     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10042   int nbOfTuple=a1->getNumberOfTuples();
10043   int nbOfTuple2=a2->getNumberOfTuples();
10044   int nbOfComp=a1->getNumberOfComponents();
10045   int nbOfComp2=a2->getNumberOfComponents();
10046   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10047   if(nbOfTuple==nbOfTuple2)
10048     {
10049       if(nbOfComp==nbOfComp2)
10050         {
10051           ret=DataArrayInt::New();
10052           ret->alloc(nbOfTuple,nbOfComp);
10053           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10054           ret->copyStringInfoFrom(*a1);
10055         }
10056       else
10057         {
10058           int nbOfCompMin,nbOfCompMax;
10059           const DataArrayInt *aMin, *aMax;
10060           if(nbOfComp>nbOfComp2)
10061             {
10062               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10063               aMin=a2; aMax=a1;
10064             }
10065           else
10066             {
10067               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10068               aMin=a1; aMax=a2;
10069             }
10070           if(nbOfCompMin==1)
10071             {
10072               ret=DataArrayInt::New();
10073               ret->alloc(nbOfTuple,nbOfCompMax);
10074               const int *aMinPtr=aMin->getConstPointer();
10075               const int *aMaxPtr=aMax->getConstPointer();
10076               int *res=ret->getPointer();
10077               for(int i=0;i<nbOfTuple;i++)
10078                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10079               ret->copyStringInfoFrom(*aMax);
10080             }
10081           else
10082             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10083         }
10084     }
10085   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10086     {
10087       if(nbOfComp==nbOfComp2)
10088         {
10089           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10090           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10091           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10092           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10093           ret=DataArrayInt::New();
10094           ret->alloc(nbOfTupleMax,nbOfComp);
10095           int *res=ret->getPointer();
10096           for(int i=0;i<nbOfTupleMax;i++)
10097             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10098           ret->copyStringInfoFrom(*aMax);
10099         }
10100       else
10101         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10102     }
10103   else
10104     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10105   return ret.retn();
10106 }
10107
10108 /*!
10109  * Adds values of another DataArrayInt to values of \a this one. There are 3
10110  * valid cases.
10111  * 1.  The arrays have same number of tuples and components. Then each value of
10112  *   \a other array is added to the corresponding value of \a this array, i.e.:
10113  *   _a_ [ i, j ] += _other_ [ i, j ].
10114  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10115  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10116  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10117  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10118  *
10119  *  \param [in] other - an array to add to \a this one.
10120  *  \throw If \a other is NULL.
10121  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10122  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10123  *         \a other has number of both tuples and components not equal to 1.
10124  */
10125 void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10126 {
10127   if(!other)
10128     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10129   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10130   checkAllocated(); other->checkAllocated();
10131   int nbOfTuple=getNumberOfTuples();
10132   int nbOfTuple2=other->getNumberOfTuples();
10133   int nbOfComp=getNumberOfComponents();
10134   int nbOfComp2=other->getNumberOfComponents();
10135   if(nbOfTuple==nbOfTuple2)
10136     {
10137       if(nbOfComp==nbOfComp2)
10138         {
10139           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10140         }
10141       else if(nbOfComp2==1)
10142         {
10143           int *ptr=getPointer();
10144           const int *ptrc=other->getConstPointer();
10145           for(int i=0;i<nbOfTuple;i++)
10146             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10147         }
10148       else
10149         throw INTERP_KERNEL::Exception(msg);
10150     }
10151   else if(nbOfTuple2==1)
10152     {
10153       if(nbOfComp2==nbOfComp)
10154         {
10155           int *ptr=getPointer();
10156           const int *ptrc=other->getConstPointer();
10157           for(int i=0;i<nbOfTuple;i++)
10158             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
10159         }
10160       else
10161         throw INTERP_KERNEL::Exception(msg);
10162     }
10163   else
10164     throw INTERP_KERNEL::Exception(msg);
10165   declareAsNew();
10166 }
10167
10168 /*!
10169  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
10170  * valid cases.
10171  * 1.  The arrays have same number of tuples and components. Then each value of
10172  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
10173  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
10174  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10175  *   component. Then
10176  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
10177  * 3.  The arrays have same number of components and one array, say _a2_, has one
10178  *   tuple. Then
10179  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
10180  *
10181  * Info on components is copied either from the first array (in the first case) or from
10182  * the array with maximal number of elements (getNbOfElems()).
10183  *  \param [in] a1 - an array to subtract from.
10184  *  \param [in] a2 - an array to subtract.
10185  *  \return DataArrayInt * - the new instance of DataArrayInt.
10186  *          The caller is to delete this result array using decrRef() as it is no more
10187  *          needed.
10188  *  \throw If either \a a1 or \a a2 is NULL.
10189  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10190  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10191  *         none of them has number of tuples or components equal to 1.
10192  */
10193 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10194 {
10195   if(!a1 || !a2)
10196     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
10197   int nbOfTuple1=a1->getNumberOfTuples();
10198   int nbOfTuple2=a2->getNumberOfTuples();
10199   int nbOfComp1=a1->getNumberOfComponents();
10200   int nbOfComp2=a2->getNumberOfComponents();
10201   if(nbOfTuple2==nbOfTuple1)
10202     {
10203       if(nbOfComp1==nbOfComp2)
10204         {
10205           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10206           ret->alloc(nbOfTuple2,nbOfComp1);
10207           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
10208           ret->copyStringInfoFrom(*a1);
10209           return ret.retn();
10210         }
10211       else if(nbOfComp2==1)
10212         {
10213           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10214           ret->alloc(nbOfTuple1,nbOfComp1);
10215           const int *a2Ptr=a2->getConstPointer();
10216           const int *a1Ptr=a1->getConstPointer();
10217           int *res=ret->getPointer();
10218           for(int i=0;i<nbOfTuple1;i++)
10219             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
10220           ret->copyStringInfoFrom(*a1);
10221           return ret.retn();
10222         }
10223       else
10224         {
10225           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10226           return 0;
10227         }
10228     }
10229   else if(nbOfTuple2==1)
10230     {
10231       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10232       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10233       ret->alloc(nbOfTuple1,nbOfComp1);
10234       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10235       int *pt=ret->getPointer();
10236       for(int i=0;i<nbOfTuple1;i++)
10237         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
10238       ret->copyStringInfoFrom(*a1);
10239       return ret.retn();
10240     }
10241   else
10242     {
10243       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
10244       return 0;
10245     }
10246 }
10247
10248 /*!
10249  * Subtract values of another DataArrayInt from values of \a this one. There are 3
10250  * valid cases.
10251  * 1.  The arrays have same number of tuples and components. Then each value of
10252  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
10253  *   _a_ [ i, j ] -= _other_ [ i, j ].
10254  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10255  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
10256  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10257  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
10258  *
10259  *  \param [in] other - an array to subtract from \a this one.
10260  *  \throw If \a other is NULL.
10261  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10262  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10263  *         \a other has number of both tuples and components not equal to 1.
10264  */
10265 void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10266 {
10267   if(!other)
10268     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
10269   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
10270   checkAllocated(); other->checkAllocated();
10271   int nbOfTuple=getNumberOfTuples();
10272   int nbOfTuple2=other->getNumberOfTuples();
10273   int nbOfComp=getNumberOfComponents();
10274   int nbOfComp2=other->getNumberOfComponents();
10275   if(nbOfTuple==nbOfTuple2)
10276     {
10277       if(nbOfComp==nbOfComp2)
10278         {
10279           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
10280         }
10281       else if(nbOfComp2==1)
10282         {
10283           int *ptr=getPointer();
10284           const int *ptrc=other->getConstPointer();
10285           for(int i=0;i<nbOfTuple;i++)
10286             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
10287         }
10288       else
10289         throw INTERP_KERNEL::Exception(msg);
10290     }
10291   else if(nbOfTuple2==1)
10292     {
10293       int *ptr=getPointer();
10294       const int *ptrc=other->getConstPointer();
10295       for(int i=0;i<nbOfTuple;i++)
10296         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
10297     }
10298   else
10299     throw INTERP_KERNEL::Exception(msg);
10300   declareAsNew();
10301 }
10302
10303 /*!
10304  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
10305  * valid cases.
10306  * 1.  The arrays have same number of tuples and components. Then each value of
10307  *   the result array (_a_) is a product of the corresponding values of \a a1 and
10308  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
10309  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10310  *   component. Then
10311  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
10312  * 3.  The arrays have same number of components and one array, say _a2_, has one
10313  *   tuple. Then
10314  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
10315  *
10316  * Info on components is copied either from the first array (in the first case) or from
10317  * the array with maximal number of elements (getNbOfElems()).
10318  *  \param [in] a1 - a factor array.
10319  *  \param [in] a2 - another factor array.
10320  *  \return DataArrayInt * - the new instance of DataArrayInt.
10321  *          The caller is to delete this result array using decrRef() as it is no more
10322  *          needed.
10323  *  \throw If either \a a1 or \a a2 is NULL.
10324  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10325  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10326  *         none of them has number of tuples or components equal to 1.
10327  */
10328 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10329 {
10330   if(!a1 || !a2)
10331     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
10332   int nbOfTuple=a1->getNumberOfTuples();
10333   int nbOfTuple2=a2->getNumberOfTuples();
10334   int nbOfComp=a1->getNumberOfComponents();
10335   int nbOfComp2=a2->getNumberOfComponents();
10336   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10337   if(nbOfTuple==nbOfTuple2)
10338     {
10339       if(nbOfComp==nbOfComp2)
10340         {
10341           ret=DataArrayInt::New();
10342           ret->alloc(nbOfTuple,nbOfComp);
10343           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
10344           ret->copyStringInfoFrom(*a1);
10345         }
10346       else
10347         {
10348           int nbOfCompMin,nbOfCompMax;
10349           const DataArrayInt *aMin, *aMax;
10350           if(nbOfComp>nbOfComp2)
10351             {
10352               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10353               aMin=a2; aMax=a1;
10354             }
10355           else
10356             {
10357               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10358               aMin=a1; aMax=a2;
10359             }
10360           if(nbOfCompMin==1)
10361             {
10362               ret=DataArrayInt::New();
10363               ret->alloc(nbOfTuple,nbOfCompMax);
10364               const int *aMinPtr=aMin->getConstPointer();
10365               const int *aMaxPtr=aMax->getConstPointer();
10366               int *res=ret->getPointer();
10367               for(int i=0;i<nbOfTuple;i++)
10368                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
10369               ret->copyStringInfoFrom(*aMax);
10370             }
10371           else
10372             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10373         }
10374     }
10375   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10376     {
10377       if(nbOfComp==nbOfComp2)
10378         {
10379           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10380           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10381           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10382           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10383           ret=DataArrayInt::New();
10384           ret->alloc(nbOfTupleMax,nbOfComp);
10385           int *res=ret->getPointer();
10386           for(int i=0;i<nbOfTupleMax;i++)
10387             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
10388           ret->copyStringInfoFrom(*aMax);
10389         }
10390       else
10391         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10392     }
10393   else
10394     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
10395   return ret.retn();
10396 }
10397
10398
10399 /*!
10400  * Multiply values of another DataArrayInt to values of \a this one. There are 3
10401  * valid cases.
10402  * 1.  The arrays have same number of tuples and components. Then each value of
10403  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
10404  *   _a_ [ i, j ] *= _other_ [ i, j ].
10405  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10406  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
10407  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10408  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
10409  *
10410  *  \param [in] other - an array to multiply to \a this one.
10411  *  \throw If \a other is NULL.
10412  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10413  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10414  *         \a other has number of both tuples and components not equal to 1.
10415  */
10416 void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10417 {
10418   if(!other)
10419     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
10420   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
10421   checkAllocated(); other->checkAllocated();
10422   int nbOfTuple=getNumberOfTuples();
10423   int nbOfTuple2=other->getNumberOfTuples();
10424   int nbOfComp=getNumberOfComponents();
10425   int nbOfComp2=other->getNumberOfComponents();
10426   if(nbOfTuple==nbOfTuple2)
10427     {
10428       if(nbOfComp==nbOfComp2)
10429         {
10430           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
10431         }
10432       else if(nbOfComp2==1)
10433         {
10434           int *ptr=getPointer();
10435           const int *ptrc=other->getConstPointer();
10436           for(int i=0;i<nbOfTuple;i++)
10437             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10438         }
10439       else
10440         throw INTERP_KERNEL::Exception(msg);
10441     }
10442   else if(nbOfTuple2==1)
10443     {
10444       if(nbOfComp2==nbOfComp)
10445         {
10446           int *ptr=getPointer();
10447           const int *ptrc=other->getConstPointer();
10448           for(int i=0;i<nbOfTuple;i++)
10449             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10450         }
10451       else
10452         throw INTERP_KERNEL::Exception(msg);
10453     }
10454   else
10455     throw INTERP_KERNEL::Exception(msg);
10456   declareAsNew();
10457 }
10458
10459
10460 /*!
10461  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10462  * valid cases.
10463  * 1.  The arrays have same number of tuples and components. Then each value of
10464  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10465  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10466  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10467  *   component. Then
10468  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10469  * 3.  The arrays have same number of components and one array, say _a2_, has one
10470  *   tuple. Then
10471  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10472  *
10473  * Info on components is copied either from the first array (in the first case) or from
10474  * the array with maximal number of elements (getNbOfElems()).
10475  *  \warning No check of division by zero is performed!
10476  *  \param [in] a1 - a numerator array.
10477  *  \param [in] a2 - a denominator array.
10478  *  \return DataArrayInt * - the new instance of DataArrayInt.
10479  *          The caller is to delete this result array using decrRef() as it is no more
10480  *          needed.
10481  *  \throw If either \a a1 or \a a2 is NULL.
10482  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10483  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10484  *         none of them has number of tuples or components equal to 1.
10485  */
10486 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10487 {
10488   if(!a1 || !a2)
10489     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10490   int nbOfTuple1=a1->getNumberOfTuples();
10491   int nbOfTuple2=a2->getNumberOfTuples();
10492   int nbOfComp1=a1->getNumberOfComponents();
10493   int nbOfComp2=a2->getNumberOfComponents();
10494   if(nbOfTuple2==nbOfTuple1)
10495     {
10496       if(nbOfComp1==nbOfComp2)
10497         {
10498           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10499           ret->alloc(nbOfTuple2,nbOfComp1);
10500           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10501           ret->copyStringInfoFrom(*a1);
10502           return ret.retn();
10503         }
10504       else if(nbOfComp2==1)
10505         {
10506           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10507           ret->alloc(nbOfTuple1,nbOfComp1);
10508           const int *a2Ptr=a2->getConstPointer();
10509           const int *a1Ptr=a1->getConstPointer();
10510           int *res=ret->getPointer();
10511           for(int i=0;i<nbOfTuple1;i++)
10512             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10513           ret->copyStringInfoFrom(*a1);
10514           return ret.retn();
10515         }
10516       else
10517         {
10518           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10519           return 0;
10520         }
10521     }
10522   else if(nbOfTuple2==1)
10523     {
10524       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10525       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10526       ret->alloc(nbOfTuple1,nbOfComp1);
10527       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10528       int *pt=ret->getPointer();
10529       for(int i=0;i<nbOfTuple1;i++)
10530         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10531       ret->copyStringInfoFrom(*a1);
10532       return ret.retn();
10533     }
10534   else
10535     {
10536       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10537       return 0;
10538     }
10539 }
10540
10541 /*!
10542  * Divide values of \a this array by values of another DataArrayInt. There are 3
10543  * valid cases.
10544  * 1.  The arrays have same number of tuples and components. Then each value of
10545  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10546  *   _a_ [ i, j ] /= _other_ [ i, j ].
10547  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10548  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10549  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10550  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10551  *
10552  *  \warning No check of division by zero is performed!
10553  *  \param [in] other - an array to divide \a this one by.
10554  *  \throw If \a other is NULL.
10555  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10556  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10557  *         \a other has number of both tuples and components not equal to 1.
10558  */
10559 void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10560 {
10561   if(!other)
10562     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10563   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10564   checkAllocated(); other->checkAllocated();
10565   int nbOfTuple=getNumberOfTuples();
10566   int nbOfTuple2=other->getNumberOfTuples();
10567   int nbOfComp=getNumberOfComponents();
10568   int nbOfComp2=other->getNumberOfComponents();
10569   if(nbOfTuple==nbOfTuple2)
10570     {
10571       if(nbOfComp==nbOfComp2)
10572         {
10573           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10574         }
10575       else if(nbOfComp2==1)
10576         {
10577           int *ptr=getPointer();
10578           const int *ptrc=other->getConstPointer();
10579           for(int i=0;i<nbOfTuple;i++)
10580             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10581         }
10582       else
10583         throw INTERP_KERNEL::Exception(msg);
10584     }
10585   else if(nbOfTuple2==1)
10586     {
10587       if(nbOfComp2==nbOfComp)
10588         {
10589           int *ptr=getPointer();
10590           const int *ptrc=other->getConstPointer();
10591           for(int i=0;i<nbOfTuple;i++)
10592             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10593         }
10594       else
10595         throw INTERP_KERNEL::Exception(msg);
10596     }
10597   else
10598     throw INTERP_KERNEL::Exception(msg);
10599   declareAsNew();
10600 }
10601
10602
10603 /*!
10604  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10605  * valid cases.
10606  * 1.  The arrays have same number of tuples and components. Then each value of
10607  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10608  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10609  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10610  *   component. Then
10611  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10612  * 3.  The arrays have same number of components and one array, say _a2_, has one
10613  *   tuple. Then
10614  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10615  *
10616  * Info on components is copied either from the first array (in the first case) or from
10617  * the array with maximal number of elements (getNbOfElems()).
10618  *  \warning No check of division by zero is performed!
10619  *  \param [in] a1 - a dividend array.
10620  *  \param [in] a2 - a divisor array.
10621  *  \return DataArrayInt * - the new instance of DataArrayInt.
10622  *          The caller is to delete this result array using decrRef() as it is no more
10623  *          needed.
10624  *  \throw If either \a a1 or \a a2 is NULL.
10625  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10626  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10627  *         none of them has number of tuples or components equal to 1.
10628  */
10629 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10630 {
10631     if(!a1 || !a2)
10632     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10633   int nbOfTuple1=a1->getNumberOfTuples();
10634   int nbOfTuple2=a2->getNumberOfTuples();
10635   int nbOfComp1=a1->getNumberOfComponents();
10636   int nbOfComp2=a2->getNumberOfComponents();
10637   if(nbOfTuple2==nbOfTuple1)
10638     {
10639       if(nbOfComp1==nbOfComp2)
10640         {
10641           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10642           ret->alloc(nbOfTuple2,nbOfComp1);
10643           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
10644           ret->copyStringInfoFrom(*a1);
10645           return ret.retn();
10646         }
10647       else if(nbOfComp2==1)
10648         {
10649           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10650           ret->alloc(nbOfTuple1,nbOfComp1);
10651           const int *a2Ptr=a2->getConstPointer();
10652           const int *a1Ptr=a1->getConstPointer();
10653           int *res=ret->getPointer();
10654           for(int i=0;i<nbOfTuple1;i++)
10655             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
10656           ret->copyStringInfoFrom(*a1);
10657           return ret.retn();
10658         }
10659       else
10660         {
10661           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10662           return 0;
10663         }
10664     }
10665   else if(nbOfTuple2==1)
10666     {
10667       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10668       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10669       ret->alloc(nbOfTuple1,nbOfComp1);
10670       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10671       int *pt=ret->getPointer();
10672       for(int i=0;i<nbOfTuple1;i++)
10673         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
10674       ret->copyStringInfoFrom(*a1);
10675       return ret.retn();
10676     }
10677   else
10678     {
10679       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
10680       return 0;
10681     }
10682 }
10683
10684 /*!
10685  * Modify \a this array so that each value becomes a modulus of division of this value by
10686  * a value of another DataArrayInt. There are 3 valid cases.
10687  * 1.  The arrays have same number of tuples and components. Then each value of
10688  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10689  *   _a_ [ i, j ] %= _other_ [ i, j ].
10690  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10691  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
10692  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10693  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
10694  *
10695  *  \warning No check of division by zero is performed!
10696  *  \param [in] other - a divisor array.
10697  *  \throw If \a other is NULL.
10698  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10699  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10700  *         \a other has number of both tuples and components not equal to 1.
10701  */
10702 void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10703 {
10704   if(!other)
10705     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
10706   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
10707   checkAllocated(); other->checkAllocated();
10708   int nbOfTuple=getNumberOfTuples();
10709   int nbOfTuple2=other->getNumberOfTuples();
10710   int nbOfComp=getNumberOfComponents();
10711   int nbOfComp2=other->getNumberOfComponents();
10712   if(nbOfTuple==nbOfTuple2)
10713     {
10714       if(nbOfComp==nbOfComp2)
10715         {
10716           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
10717         }
10718       else if(nbOfComp2==1)
10719         {
10720           if(nbOfComp2==nbOfComp)
10721             {
10722               int *ptr=getPointer();
10723               const int *ptrc=other->getConstPointer();
10724               for(int i=0;i<nbOfTuple;i++)
10725                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
10726             }
10727           else
10728             throw INTERP_KERNEL::Exception(msg);
10729         }
10730       else
10731         throw INTERP_KERNEL::Exception(msg);
10732     }
10733   else if(nbOfTuple2==1)
10734     {
10735       int *ptr=getPointer();
10736       const int *ptrc=other->getConstPointer();
10737       for(int i=0;i<nbOfTuple;i++)
10738         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
10739     }
10740   else
10741     throw INTERP_KERNEL::Exception(msg);
10742   declareAsNew();
10743 }
10744
10745 /*!
10746  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
10747  * valid cases.
10748  *
10749  *  \param [in] a1 - an array to pow up.
10750  *  \param [in] a2 - another array to sum up.
10751  *  \return DataArrayInt * - the new instance of DataArrayInt.
10752  *          The caller is to delete this result array using decrRef() as it is no more
10753  *          needed.
10754  *  \throw If either \a a1 or \a a2 is NULL.
10755  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
10756  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
10757  *  \throw If there is a negative value in \a a2.
10758  */
10759 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10760 {
10761   if(!a1 || !a2)
10762     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
10763   int nbOfTuple=a1->getNumberOfTuples();
10764   int nbOfTuple2=a2->getNumberOfTuples();
10765   int nbOfComp=a1->getNumberOfComponents();
10766   int nbOfComp2=a2->getNumberOfComponents();
10767   if(nbOfTuple!=nbOfTuple2)
10768     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
10769   if(nbOfComp!=1 || nbOfComp2!=1)
10770     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
10771   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
10772   const int *ptr1(a1->begin()),*ptr2(a2->begin());
10773   int *ptr=ret->getPointer();
10774   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
10775     {
10776       if(*ptr2>=0)
10777         {
10778           int tmp=1;
10779           for(int j=0;j<*ptr2;j++)
10780             tmp*=*ptr1;
10781           *ptr=tmp;
10782         }
10783       else
10784         {
10785           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
10786           throw INTERP_KERNEL::Exception(oss.str().c_str());
10787         }
10788     }
10789   return ret.retn();
10790 }
10791
10792 /*!
10793  * Apply pow on values of another DataArrayInt to values of \a this one.
10794  *
10795  *  \param [in] other - an array to pow to \a this one.
10796  *  \throw If \a other is NULL.
10797  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
10798  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
10799  *  \throw If there is a negative value in \a other.
10800  */
10801 void DataArrayInt::powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10802 {
10803   if(!other)
10804     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
10805   int nbOfTuple=getNumberOfTuples();
10806   int nbOfTuple2=other->getNumberOfTuples();
10807   int nbOfComp=getNumberOfComponents();
10808   int nbOfComp2=other->getNumberOfComponents();
10809   if(nbOfTuple!=nbOfTuple2)
10810     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
10811   if(nbOfComp!=1 || nbOfComp2!=1)
10812     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
10813   int *ptr=getPointer();
10814   const int *ptrc=other->begin();
10815   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
10816     {
10817       if(*ptrc>=0)
10818         {
10819           int tmp=1;
10820           for(int j=0;j<*ptrc;j++)
10821             tmp*=*ptr;
10822           *ptr=tmp;
10823         }
10824       else
10825         {
10826           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
10827           throw INTERP_KERNEL::Exception(oss.str().c_str());
10828         }
10829     }
10830   declareAsNew();
10831 }
10832
10833 /*!
10834  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10835  * This map, if applied to \a start array, would make it sorted. For example, if
10836  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10837  * [5,6,0,3,2,7,1,4].
10838  *  \param [in] start - pointer to the first element of the array for which the
10839  *         permutation map is computed.
10840  *  \param [in] end - pointer specifying the end of the array \a start, so that
10841  *         the last value of \a start is \a end[ -1 ].
10842  *  \return int * - the result permutation array that the caller is to delete as it is no
10843  *         more needed.
10844  *  \throw If there are equal values in the input array.
10845  */
10846 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10847 {
10848   std::size_t sz=std::distance(start,end);
10849   int *ret=(int *)malloc(sz*sizeof(int));
10850   int *work=new int[sz];
10851   std::copy(start,end,work);
10852   std::sort(work,work+sz);
10853   if(std::unique(work,work+sz)!=work+sz)
10854     {
10855       delete [] work;
10856       free(ret);
10857       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10858     }
10859   std::map<int,int> m;
10860   for(int *workPt=work;workPt!=work+sz;workPt++)
10861     m[*workPt]=(int)std::distance(work,workPt);
10862   int *iter2=ret;
10863   for(const int *iter=start;iter!=end;iter++,iter2++)
10864     *iter2=m[*iter];
10865   delete [] work;
10866   return ret;
10867 }
10868
10869 /*!
10870  * Returns a new DataArrayInt containing an arithmetic progression
10871  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10872  * function.
10873  *  \param [in] begin - the start value of the result sequence.
10874  *  \param [in] end - limiting value, so that every value of the result array is less than
10875  *              \a end.
10876  *  \param [in] step - specifies the increment or decrement.
10877  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10878  *          array using decrRef() as it is no more needed.
10879  *  \throw If \a step == 0.
10880  *  \throw If \a end < \a begin && \a step > 0.
10881  *  \throw If \a end > \a begin && \a step < 0.
10882  */
10883 DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception)
10884 {
10885   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10886   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10887   ret->alloc(nbOfTuples,1);
10888   int *ptr=ret->getPointer();
10889   if(step>0)
10890     {
10891       for(int i=begin;i<end;i+=step,ptr++)
10892         *ptr=i;
10893     }
10894   else
10895     {
10896       for(int i=begin;i>end;i+=step,ptr++)
10897         *ptr=i;
10898     }
10899   return ret.retn();
10900 }
10901
10902 /*!
10903  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10904  * Server side.
10905  */
10906 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
10907 {
10908   tinyInfo.resize(2);
10909   if(isAllocated())
10910     {
10911       tinyInfo[0]=getNumberOfTuples();
10912       tinyInfo[1]=getNumberOfComponents();
10913     }
10914   else
10915     {
10916       tinyInfo[0]=-1;
10917       tinyInfo[1]=-1;
10918     }
10919 }
10920
10921 /*!
10922  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10923  * Server side.
10924  */
10925 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
10926 {
10927   if(isAllocated())
10928     {
10929       int nbOfCompo=getNumberOfComponents();
10930       tinyInfo.resize(nbOfCompo+1);
10931       tinyInfo[0]=getName();
10932       for(int i=0;i<nbOfCompo;i++)
10933         tinyInfo[i+1]=getInfoOnComponent(i);
10934     }
10935   else
10936     {
10937       tinyInfo.resize(1);
10938       tinyInfo[0]=getName();
10939     }
10940 }
10941
10942 /*!
10943  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10944  * This method returns if a feeding is needed.
10945  */
10946 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
10947 {
10948   int nbOfTuple=tinyInfoI[0];
10949   int nbOfComp=tinyInfoI[1];
10950   if(nbOfTuple!=-1 || nbOfComp!=-1)
10951     {
10952       alloc(nbOfTuple,nbOfComp);
10953       return true;
10954     }
10955   return false;
10956 }
10957
10958 /*!
10959  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10960  * This method returns if a feeding is needed.
10961  */
10962 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
10963 {
10964   setName(tinyInfoS[0].c_str());
10965   if(isAllocated())
10966     {
10967       int nbOfCompo=tinyInfoI[1];
10968       for(int i=0;i<nbOfCompo;i++)
10969         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
10970     }
10971 }
10972
10973 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
10974 {
10975   if(_da)
10976     {
10977       _da->incrRef();
10978       if(_da->isAllocated())
10979         {
10980           _nb_comp=da->getNumberOfComponents();
10981           _nb_tuple=da->getNumberOfTuples();
10982           _pt=da->getPointer();
10983         }
10984     }
10985 }
10986
10987 DataArrayIntIterator::~DataArrayIntIterator()
10988 {
10989   if(_da)
10990     _da->decrRef();
10991 }
10992
10993 DataArrayIntTuple *DataArrayIntIterator::nextt() throw(INTERP_KERNEL::Exception)
10994 {
10995   if(_tuple_id<_nb_tuple)
10996     {
10997       _tuple_id++;
10998       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
10999       _pt+=_nb_comp;
11000       return ret;
11001     }
11002   else
11003     return 0;
11004 }
11005
11006 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11007 {
11008 }
11009
11010 std::string DataArrayIntTuple::repr() const throw(INTERP_KERNEL::Exception)
11011 {
11012   std::ostringstream oss; oss << "(";
11013   for(int i=0;i<_nb_of_compo-1;i++)
11014     oss << _pt[i] << ", ";
11015   oss << _pt[_nb_of_compo-1] << ")";
11016   return oss.str();
11017 }
11018
11019 int DataArrayIntTuple::intValue() const throw(INTERP_KERNEL::Exception)
11020 {
11021   if(_nb_of_compo==1)
11022     return *_pt;
11023   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11024 }
11025
11026 /*!
11027  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
11028  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
11029  * 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
11030  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11031  */
11032 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
11033 {
11034   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11035     {
11036       DataArrayInt *ret=DataArrayInt::New();
11037       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11038       return ret;
11039     }
11040   else
11041     {
11042       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11043       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11044       throw INTERP_KERNEL::Exception(oss.str().c_str());
11045     }
11046 }