Salome HOME
92777b41972c3fbc8b9243e3b1290cb1da84c41b
[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 "InterpKernelExprParser.hxx"
27
28 #include <set>
29 #include <cmath>
30 #include <limits>
31 #include <numeric>
32 #include <algorithm>
33 #include <functional>
34
35 typedef double (*MYFUNCPTR)(double);
36
37 using namespace ParaMEDMEM;
38
39 template<int SPACEDIM>
40 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
41 {
42   const double *coordsPtr=getConstPointer();
43   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
44   std::vector<bool> isDone(nbNodes);
45   for(int i=0;i<nbNodes;i++)
46     {
47       if(!isDone[i])
48         {
49           std::vector<int> intersectingElems;
50           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
51           if(intersectingElems.size()>1)
52             {
53               std::vector<int> commonNodes;
54               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
55                 if(*it!=i)
56                   if(*it>=limitNodeId)
57                     {
58                       commonNodes.push_back(*it);
59                       isDone[*it]=true;
60                     }
61               if(!commonNodes.empty())
62                 {
63                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
64                   c->pushBackSilent(i);
65                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
66                 }
67             }
68         }
69     }
70 }
71
72 template<int SPACEDIM>
73 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
74                                                 DataArrayInt *c, DataArrayInt *cI)
75 {
76   for(int i=0;i<nbOfTuples;i++)
77     {
78       std::vector<int> intersectingElems;
79       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
80       std::vector<int> commonNodes;
81       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
82         commonNodes.push_back(*it);
83       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
84       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
85     }
86 }
87
88 template<int SPACEDIM>
89 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
90 {
91   double distOpt(dist);
92   const double *p(pos);
93   int *r(res);
94   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
95     {
96       while(true)
97         {
98           int elem=-1;
99           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
100           if(ret!=std::numeric_limits<double>::max())
101             {
102               distOpt=std::max(ret,1e-4);
103               *r=elem;
104               break;
105             }
106           else
107             { distOpt=2*distOpt; continue; }
108         }
109     }
110 }
111
112 std::size_t DataArray::getHeapMemorySize() const
113 {
114   std::size_t sz1=_name.capacity();
115   std::size_t sz2=_info_on_compo.capacity();
116   std::size_t sz3=0;
117   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
118     sz3+=(*it).capacity();
119   return sz1+sz2+sz3;
120 }
121
122 /*!
123  * Sets the attribute \a _name of \a this array.
124  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
125  *  \param [in] name - new array name
126  */
127 void DataArray::setName(const char *name)
128 {
129   _name=name;
130 }
131
132 /*!
133  * Copies textual data from an \a other DataArray. The copied data are
134  * - the name attribute,
135  * - the information of components.
136  *
137  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
138  *
139  *  \param [in] other - another instance of DataArray to copy the textual data from.
140  *  \throw If number of components of \a this array differs from that of the \a other.
141  */
142 void DataArray::copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception)
143 {
144   if(_info_on_compo.size()!=other._info_on_compo.size())
145     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
146   _name=other._name;
147   _info_on_compo=other._info_on_compo;
148 }
149
150 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
151 {
152   int nbOfCompoOth=other.getNumberOfComponents();
153   std::size_t newNbOfCompo=compoIds.size();
154   for(std::size_t i=0;i<newNbOfCompo;i++)
155     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
156       {
157         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
158         throw INTERP_KERNEL::Exception(oss.str().c_str());
159       }
160   for(std::size_t i=0;i<newNbOfCompo;i++)
161     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]).c_str());
162 }
163
164 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception)
165 {
166   int nbOfCompo=getNumberOfComponents();
167   std::size_t partOfCompoToSet=compoIds.size();
168   if((int)partOfCompoToSet!=other.getNumberOfComponents())
169     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
170   for(std::size_t i=0;i<partOfCompoToSet;i++)
171     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
172       {
173         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
174         throw INTERP_KERNEL::Exception(oss.str().c_str());
175       }
176   for(std::size_t i=0;i<partOfCompoToSet;i++)
177     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i).c_str());
178 }
179
180 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
181 {
182   std::ostringstream oss;
183   if(_name!=other._name)
184     {
185       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
186       reason=oss.str();
187       return false;
188     }
189   if(_info_on_compo!=other._info_on_compo)
190     {
191       oss << "Components DataArray mismatch : \nThis components=";
192       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
193         oss << "\"" << *it << "\",";
194       oss << "\nOther components=";
195       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
196         oss << "\"" << *it << "\",";
197       reason=oss.str();
198       return false;
199     }
200   return true;
201 }
202
203 /*!
204  * Compares textual information of \a this DataArray with that of an \a other one.
205  * The compared data are
206  * - the name attribute,
207  * - the information of components.
208  *
209  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
210  *  \param [in] other - another instance of DataArray to compare the textual data of.
211  *  \return bool - \a true if the textual information is same, \a false else.
212  */
213 bool DataArray::areInfoEquals(const DataArray& other) const throw(INTERP_KERNEL::Exception)
214 {
215   std::string tmp;
216   return areInfoEqualsIfNotWhy(other,tmp);
217 }
218
219 void DataArray::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
220 {
221   stream << "Number of components : "<< getNumberOfComponents() << "\n";
222   stream << "Info of these components : ";
223   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
224     stream << "\"" << *iter << "\"   ";
225   stream << "\n";
226 }
227
228 std::string DataArray::cppRepr(const char *varName) const throw(INTERP_KERNEL::Exception)
229 {
230   std::ostringstream ret;
231   reprCppStream(varName,ret);
232   return ret.str();
233 }
234
235 /*!
236  * Sets information on all components. To know more on format of this information
237  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
238  *  \param [in] info - a vector of strings.
239  *  \throw If size of \a info differs from the number of components of \a this.
240  */
241 void DataArray::setInfoOnComponents(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
242 {
243   if(getNumberOfComponents()!=(int)info.size())
244     {
245       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
246       throw INTERP_KERNEL::Exception(oss.str().c_str());
247     }
248   _info_on_compo=info;
249 }
250
251 /*!
252  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
253  * type of \a this and \a aBase.
254  *
255  * \throw If \a aBase and \a this do not have the same type.
256  *
257  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
258  */
259 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
260 {
261   if(!aBase)
262     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
263   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
264   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
265   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
266   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
267   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
268   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
269   if(this1 && a1)
270     {
271       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
272       return ;
273     }
274   if(this2 && a2)
275     {
276       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
277       return ;
278     }
279   if(this3 && a3)
280     {
281       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
282       return ;
283     }
284   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
285 }
286
287 std::vector<std::string> DataArray::getVarsOnComponent() const throw(INTERP_KERNEL::Exception)
288 {
289   int nbOfCompo=(int)_info_on_compo.size();
290   std::vector<std::string> ret(nbOfCompo);
291   for(int i=0;i<nbOfCompo;i++)
292     ret[i]=getVarOnComponent(i);
293   return ret;
294 }
295
296 std::vector<std::string> DataArray::getUnitsOnComponent() const throw(INTERP_KERNEL::Exception)
297 {
298   int nbOfCompo=(int)_info_on_compo.size();
299   std::vector<std::string> ret(nbOfCompo);
300   for(int i=0;i<nbOfCompo;i++)
301     ret[i]=getUnitOnComponent(i);
302   return ret;
303 }
304
305 /*!
306  * Returns information on a component specified by an index.
307  * To know more on format of this information
308  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
309  *  \param [in] i - the index (zero based) of the component of interest.
310  *  \return std::string - a string containing the information on \a i-th component.
311  *  \throw If \a i is not a valid component index.
312  */
313 std::string DataArray::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception)
314 {
315   if(i<(int)_info_on_compo.size() && i>=0)
316     return _info_on_compo[i];
317   else
318     {
319       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();
320       throw INTERP_KERNEL::Exception(oss.str().c_str());
321     }
322 }
323
324 /*!
325  * Returns the var part of the full information of the \a i-th component.
326  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
327  * \c getVarOnComponent(0) returns "SIGXY".
328  * If a unit part of information is not detected by presence of
329  * two square brackets, then the full information is returned.
330  * To read more about the component information format, see
331  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
332  *  \param [in] i - the index (zero based) of the component of interest.
333  *  \return std::string - a string containing the var information, or the full info.
334  *  \throw If \a i is not a valid component index.
335  */
336 std::string DataArray::getVarOnComponent(int i) const throw(INTERP_KERNEL::Exception)
337 {
338   if(i<(int)_info_on_compo.size() && i>=0)
339     {
340       return GetVarNameFromInfo(_info_on_compo[i]);
341     }
342   else
343     {
344       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();
345       throw INTERP_KERNEL::Exception(oss.str().c_str());
346     }
347 }
348
349 /*!
350  * Returns the unit part of the full information of the \a i-th component.
351  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
352  * \c getUnitOnComponent(0) returns " N/m^2".
353  * If a unit part of information is not detected by presence of
354  * two square brackets, then an empty string is returned.
355  * To read more about the component information format, see
356  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
357  *  \param [in] i - the index (zero based) of the component of interest.
358  *  \return std::string - a string containing the unit information, if any, or "".
359  *  \throw If \a i is not a valid component index.
360  */
361 std::string DataArray::getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception)
362 {
363   if(i<(int)_info_on_compo.size() && i>=0)
364     {
365       return GetUnitFromInfo(_info_on_compo[i]);
366     }
367   else
368     {
369       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();
370       throw INTERP_KERNEL::Exception(oss.str().c_str());
371     }
372 }
373
374 /*!
375  * Returns the var part of the full component information.
376  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
377  * If a unit part of information is not detected by presence of
378  * two square brackets, then the whole \a info is returned.
379  * To read more about the component information format, see
380  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
381  *  \param [in] info - the full component information.
382  *  \return std::string - a string containing only var information, or the \a info.
383  */
384 std::string DataArray::GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
385 {
386   std::size_t p1=info.find_last_of('[');
387   std::size_t p2=info.find_last_of(']');
388   if(p1==std::string::npos || p2==std::string::npos)
389     return info;
390   if(p1>p2)
391     return info;
392   if(p1==0)
393     return std::string();
394   std::size_t p3=info.find_last_not_of(' ',p1-1);
395   return info.substr(0,p3+1);
396 }
397
398 /*!
399  * Returns the unit part of the full component information.
400  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
401  * If a unit part of information is not detected by presence of
402  * two square brackets, then an empty string is returned.
403  * To read more about the component information format, see
404  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
405  *  \param [in] info - the full component information.
406  *  \return std::string - a string containing only unit information, if any, or "".
407  */
408 std::string DataArray::GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
409 {
410   std::size_t p1=info.find_last_of('[');
411   std::size_t p2=info.find_last_of(']');
412   if(p1==std::string::npos || p2==std::string::npos)
413     return std::string();
414   if(p1>p2)
415     return std::string();
416   return info.substr(p1+1,p2-p1-1);
417 }
418
419 /*!
420  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
421  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
422  * the number of component in the result array is same as that of each of given arrays.
423  * Info on components is copied from the first of the given arrays. Number of components
424  * in the given arrays must be  the same.
425  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
426  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
427  *          The caller is to delete this result array using decrRef() as it is no more
428  *          needed.
429  *  \throw If all arrays within \a arrs are NULL.
430  *  \throw If all not null arrays in \a arrs have not the same type.
431  *  \throw If getNumberOfComponents() of arrays within \a arrs.
432  */
433 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs) throw(INTERP_KERNEL::Exception)
434 {
435   std::vector<const DataArray *> arr2;
436   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
437     if(*it)
438       arr2.push_back(*it);
439   if(arr2.empty())
440     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
441   std::vector<const DataArrayDouble *> arrd;
442   std::vector<const DataArrayInt *> arri;
443   std::vector<const DataArrayChar *> arrc;
444   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
445     {
446       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
447       if(a)
448         { arrd.push_back(a); continue; }
449       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
450       if(b)
451         { arri.push_back(b); continue; }
452       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
453       if(c)
454         { arrc.push_back(c); continue; }
455       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
456     }
457   if(arr2.size()==arrd.size())
458     return DataArrayDouble::Aggregate(arrd);
459   if(arr2.size()==arri.size())
460     return DataArrayInt::Aggregate(arri);
461   if(arr2.size()==arrc.size())
462     return DataArrayChar::Aggregate(arrc);
463   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
464 }
465
466 /*!
467  * Sets information on a component specified by an index.
468  * To know more on format of this information
469  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
470  *  \warning Don't pass NULL as \a info!
471  *  \param [in] i - the index (zero based) of the component of interest.
472  *  \param [in] info - the string containing the information.
473  *  \throw If \a i is not a valid component index.
474  */
475 void DataArray::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception)
476 {
477   if(i<(int)_info_on_compo.size() && i>=0)
478     _info_on_compo[i]=info;
479   else
480     {
481       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();
482       throw INTERP_KERNEL::Exception(oss.str().c_str());
483     }
484 }
485
486 /*!
487  * Sets information on all components. This method can change number of components
488  * at certain conditions; if the conditions are not respected, an exception is thrown.
489  * The number of components can be changed in \a this only if \a this is not allocated.
490  * The condition of number of components must not be changed.
491  *
492  * To know more on format of the component information see
493  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
494  *  \param [in] info - a vector of component infos.
495  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
496  */
497 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
498 {
499   if(getNumberOfComponents()!=(int)info.size())
500     {
501       if(!isAllocated())
502         _info_on_compo=info;
503       else
504         {
505           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 !";
506           throw INTERP_KERNEL::Exception(oss.str().c_str());
507         }
508     }
509   else
510     _info_on_compo=info;
511 }
512
513 void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const throw(INTERP_KERNEL::Exception)
514 {
515   if(getNumberOfTuples()!=nbOfTuples)
516     {
517       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
518       throw INTERP_KERNEL::Exception(oss.str().c_str());
519     }
520 }
521
522 void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
523 {
524   if(getNumberOfComponents()!=nbOfCompo)
525     {
526       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
527       throw INTERP_KERNEL::Exception(oss.str().c_str());
528     }
529 }
530
531 void DataArray::checkNbOfElems(std::size_t nbOfElems, const char *msg) const throw(INTERP_KERNEL::Exception)
532 {
533   if(getNbOfElems()!=nbOfElems)
534     {
535       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
536       throw INTERP_KERNEL::Exception(oss.str().c_str());
537     }
538 }
539
540 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception)
541 {
542    if(getNumberOfTuples()!=other.getNumberOfTuples())
543     {
544       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
545       throw INTERP_KERNEL::Exception(oss.str().c_str());
546     }
547   if(getNumberOfComponents()!=other.getNumberOfComponents())
548     {
549       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
550       throw INTERP_KERNEL::Exception(oss.str().c_str());
551     }
552 }
553
554 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
555 {
556   checkNbOfTuples(nbOfTuples,msg);
557   checkNbOfComps(nbOfCompo,msg);
558 }
559
560 /*!
561  * Simply this method checks that \b value is in [0,\b ref).
562  */
563 void DataArray::CheckValueInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
564 {
565   if(value<0 || value>=ref)
566     {
567       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
568       throw INTERP_KERNEL::Exception(oss.str().c_str());
569     }
570 }
571
572 /*!
573  * This method checks that [\b start, \b end) is compliant with ref length \b value.
574  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
575  */
576 void DataArray::CheckValueInRangeEx(int value, int start, int end, const char *msg) throw(INTERP_KERNEL::Exception)
577 {
578   if(start<0 || start>=value)
579     {
580       if(value!=start || end!=start)
581         {
582           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
583           throw INTERP_KERNEL::Exception(oss.str().c_str());
584         }
585     }
586   if(end<0 || end>value)
587     {
588       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
589       throw INTERP_KERNEL::Exception(oss.str().c_str());
590     }
591 }
592
593 void DataArray::CheckClosingParInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
594 {
595   if(value<0 || value>ref)
596     {
597       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
598       throw INTERP_KERNEL::Exception(oss.str().c_str());
599     }
600 }
601
602 /*!
603  * 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, 
604  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
605  *
606  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
607  *
608  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
609  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
610  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
611  * \param [in] sliceId - the slice id considered
612  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
613  * \param [out] startSlice - the start of the slice considered
614  * \param [out] stopSlice - the stop of the slice consided
615  * 
616  * \throw If \a step == 0
617  * \throw If \a nbOfSlices not > 0
618  * \throw If \a sliceId not in [0,nbOfSlices)
619  */
620 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice) throw(INTERP_KERNEL::Exception)
621 {
622   if(nbOfSlices<=0)
623     {
624       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
625       throw INTERP_KERNEL::Exception(oss.str().c_str());
626     }
627   if(sliceId<0 || sliceId>=nbOfSlices)
628     {
629       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
630       throw INTERP_KERNEL::Exception(oss.str().c_str());
631     }
632   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
633   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
634   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
635   if(sliceId<nbOfSlices-1)
636     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
637   else
638     stopSlice=stop;
639 }
640
641 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
642 {
643   if(end<begin)
644     {
645       std::ostringstream oss; oss << msg << " : end before begin !";
646       throw INTERP_KERNEL::Exception(oss.str().c_str());
647     }
648   if(end==begin)
649     return 0;
650   if(step<=0)
651     {
652       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
653       throw INTERP_KERNEL::Exception(oss.str().c_str());
654     }
655   return (end-1-begin)/step+1;
656 }
657
658 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
659 {
660   if(step==0)
661     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
662   if(end<begin && step>0)
663     {
664       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
665       throw INTERP_KERNEL::Exception(oss.str().c_str());
666     }
667   if(begin<end && step<0)
668     {
669       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
670       throw INTERP_KERNEL::Exception(oss.str().c_str());
671     }
672   if(begin!=end)
673     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
674   else
675     return 0;
676 }
677
678 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) throw(INTERP_KERNEL::Exception)
679 {
680   if(step!=0)
681     {
682       if(step>0)
683         {
684           if(begin<=value && value<end)
685             {
686               if((value-begin)%step==0)
687                 return (value-begin)/step;
688               else
689                 return -1;
690             }
691           else
692             return -1;
693         }
694       else
695         {
696           if(begin>=value && value>end)
697             {
698               if((begin-value)%(-step)==0)
699                 return (begin-value)/(-step);
700               else
701                 return -1;
702             }
703           else
704             return -1;
705         }
706     }
707   else
708     return -1;
709 }
710
711 /*!
712  * Returns a new instance of DataArrayDouble. The caller is to delete this array
713  * using decrRef() as it is no more needed. 
714  */
715 DataArrayDouble *DataArrayDouble::New()
716 {
717   return new DataArrayDouble;
718 }
719
720 /*!
721  * Checks if raw data is allocated. Read more on the raw data
722  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
723  *  \return bool - \a true if the raw data is allocated, \a false else.
724  */
725 bool DataArrayDouble::isAllocated() const throw(INTERP_KERNEL::Exception)
726 {
727   return getConstPointer()!=0;
728 }
729
730 /*!
731  * Checks if raw data is allocated and throws an exception if it is not the case.
732  *  \throw If the raw data is not allocated.
733  */
734 void DataArrayDouble::checkAllocated() const throw(INTERP_KERNEL::Exception)
735 {
736   if(!isAllocated())
737     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
738 }
739
740 /*!
741  * This method desallocated \a this without modification of informations relative to the components.
742  * After call of this method, DataArrayDouble::isAllocated will return false.
743  * If \a this is already not allocated, \a this is let unchanged.
744  */
745 void DataArrayDouble::desallocate() throw(INTERP_KERNEL::Exception)
746 {
747   _mem.destroy();
748 }
749
750 std::size_t DataArrayDouble::getHeapMemorySize() const
751 {
752   std::size_t sz=_mem.getNbOfElemAllocated();
753   sz*=sizeof(double);
754   return DataArray::getHeapMemorySize()+sz;
755 }
756
757 /*!
758  * Returns the only one value in \a this, if and only if number of elements
759  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
760  *  \return double - the sole value stored in \a this array.
761  *  \throw If at least one of conditions stated above is not fulfilled.
762  */
763 double DataArrayDouble::doubleValue() const throw(INTERP_KERNEL::Exception)
764 {
765   if(isAllocated())
766     {
767       if(getNbOfElems()==1)
768         {
769           return *getConstPointer();
770         }
771       else
772         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
773     }
774   else
775     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
776 }
777
778 /*!
779  * Checks the number of tuples.
780  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
781  *  \throw If \a this is not allocated.
782  */
783 bool DataArrayDouble::empty() const throw(INTERP_KERNEL::Exception)
784 {
785   checkAllocated();
786   return getNumberOfTuples()==0;
787 }
788
789 /*!
790  * Returns a full copy of \a this. For more info on copying data arrays see
791  * \ref MEDCouplingArrayBasicsCopyDeep.
792  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
793  *          delete this array using decrRef() as it is no more needed. 
794  */
795 DataArrayDouble *DataArrayDouble::deepCpy() const throw(INTERP_KERNEL::Exception)
796 {
797   return new DataArrayDouble(*this);
798 }
799
800 /*!
801  * Returns either a \a deep or \a shallow copy of this array. For more info see
802  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
803  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
804  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
805  *          == \a true) or \a this instance (if \a dCpy == \a false).
806  */
807 DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
808 {
809   if(dCpy)
810     return deepCpy();
811   else
812     {
813       incrRef();
814       return const_cast<DataArrayDouble *>(this);
815     }
816 }
817
818 /*!
819  * Copies all the data from another DataArrayDouble. For more info see
820  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
821  *  \param [in] other - another instance of DataArrayDouble to copy data from.
822  *  \throw If the \a other is not allocated.
823  */
824 void DataArrayDouble::cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL::Exception)
825 {
826   other.checkAllocated();
827   int nbOfTuples=other.getNumberOfTuples();
828   int nbOfComp=other.getNumberOfComponents();
829   allocIfNecessary(nbOfTuples,nbOfComp);
830   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
831   double *pt=getPointer();
832   const double *ptI=other.getConstPointer();
833   for(std::size_t i=0;i<nbOfElems;i++)
834     pt[i]=ptI[i];
835   copyStringInfoFrom(other);
836 }
837
838 /*!
839  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
840  * 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.
841  * If \a this has not already been allocated, number of components is set to one.
842  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
843  * 
844  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
845  */
846 void DataArrayDouble::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
847 {
848   int nbCompo=getNumberOfComponents();
849   if(nbCompo==1)
850     {
851       _mem.reserve(nbOfElems);
852     }
853   else if(nbCompo==0)
854     {
855       _mem.reserve(nbOfElems);
856       _info_on_compo.resize(1);
857     }
858   else
859     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
860 }
861
862 /*!
863  * 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
864  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
865  *
866  * \param [in] val the value to be added in \a this
867  * \throw If \a this has already been allocated with number of components different from one.
868  * \sa DataArrayDouble::pushBackValsSilent
869  */
870 void DataArrayDouble::pushBackSilent(double val) throw(INTERP_KERNEL::Exception)
871 {
872   int nbCompo=getNumberOfComponents();
873   if(nbCompo==1)
874     _mem.pushBack(val);
875   else if(nbCompo==0)
876     {
877       _info_on_compo.resize(1);
878       _mem.pushBack(val);
879     }
880   else
881     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
882 }
883
884 /*!
885  * 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
886  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
887  *
888  *  \param [in] valsBg - an array of values to push at the end of \this.
889  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
890  *              the last value of \a valsBg is \a valsEnd[ -1 ].
891  * \throw If \a this has already been allocated with number of components different from one.
892  * \sa DataArrayDouble::pushBackSilent
893  */
894 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd) throw(INTERP_KERNEL::Exception)
895 {
896   int nbCompo=getNumberOfComponents();
897   if(nbCompo==1)
898     _mem.insertAtTheEnd(valsBg,valsEnd);
899   else if(nbCompo==0)
900     {
901       _info_on_compo.resize(1);
902       _mem.insertAtTheEnd(valsBg,valsEnd);
903     }
904   else
905     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
906 }
907
908 /*!
909  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
910  * \throw If \a this is already empty.
911  * \throw If \a this has number of components different from one.
912  */
913 double DataArrayDouble::popBackSilent() throw(INTERP_KERNEL::Exception)
914 {
915   if(getNumberOfComponents()==1)
916     return _mem.popBack();
917   else
918     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
919 }
920
921 /*!
922  * 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.
923  *
924  * \sa DataArrayDouble::getHeapMemorySize, DataArrayDouble::reserve
925  */
926 void DataArrayDouble::pack() const throw(INTERP_KERNEL::Exception)
927 {
928   _mem.pack();
929 }
930
931 /*!
932  * Allocates the raw data in memory. If exactly same memory as needed already
933  * allocated, it is not re-allocated.
934  *  \param [in] nbOfTuple - number of tuples of data to allocate.
935  *  \param [in] nbOfCompo - number of components of data to allocate.
936  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
937  */
938 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
939 {
940   if(isAllocated())
941     {
942       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
943         alloc(nbOfTuple,nbOfCompo);
944     }
945   else
946     alloc(nbOfTuple,nbOfCompo);
947 }
948
949 /*!
950  * Allocates the raw data in memory. If the memory was already allocated, then it is
951  * freed and re-allocated. See an example of this method use
952  * \ref MEDCouplingArraySteps1WC "here".
953  *  \param [in] nbOfTuple - number of tuples of data to allocate.
954  *  \param [in] nbOfCompo - number of components of data to allocate.
955  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
956  */
957 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
958 {
959   if(nbOfTuple<0 || nbOfCompo<0)
960     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
961   _info_on_compo.resize(nbOfCompo);
962   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
963   declareAsNew();
964 }
965
966 /*!
967  * Assign zero to all values in \a this array. To know more on filling arrays see
968  * \ref MEDCouplingArrayFill.
969  * \throw If \a this is not allocated.
970  */
971 void DataArrayDouble::fillWithZero() throw(INTERP_KERNEL::Exception)
972 {
973   checkAllocated();
974   _mem.fillWithValue(0.);
975   declareAsNew();
976 }
977
978 /*!
979  * Assign \a val to all values in \a this array. To know more on filling arrays see
980  * \ref MEDCouplingArrayFill.
981  *  \param [in] val - the value to fill with.
982  *  \throw If \a this is not allocated.
983  */
984 void DataArrayDouble::fillWithValue(double val) throw(INTERP_KERNEL::Exception)
985 {
986   checkAllocated();
987   _mem.fillWithValue(val);
988   declareAsNew();
989 }
990
991 /*!
992  * Set all values in \a this array so that the i-th element equals to \a init + i
993  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
994  *  \param [in] init - value to assign to the first element of array.
995  *  \throw If \a this->getNumberOfComponents() != 1
996  *  \throw If \a this is not allocated.
997  */
998 void DataArrayDouble::iota(double init) throw(INTERP_KERNEL::Exception)
999 {
1000   checkAllocated();
1001   if(getNumberOfComponents()!=1)
1002     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
1003   double *ptr=getPointer();
1004   int ntuples=getNumberOfTuples();
1005   for(int i=0;i<ntuples;i++)
1006     ptr[i]=init+double(i);
1007   declareAsNew();
1008 }
1009
1010 /*!
1011  * Checks if all values in \a this array are equal to \a val at precision \a eps.
1012  *  \param [in] val - value to check equality of array values to.
1013  *  \param [in] eps - precision to check the equality.
1014  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
1015  *                 \a false else.
1016  *  \throw If \a this->getNumberOfComponents() != 1
1017  *  \throw If \a this is not allocated.
1018  */
1019 bool DataArrayDouble::isUniform(double val, double eps) const throw(INTERP_KERNEL::Exception)
1020 {
1021   checkAllocated();
1022   if(getNumberOfComponents()!=1)
1023     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1024   int nbOfTuples=getNumberOfTuples();
1025   const double *w=getConstPointer();
1026   const double *end2=w+nbOfTuples;
1027   const double vmin=val-eps;
1028   const double vmax=val+eps;
1029   for(;w!=end2;w++)
1030     if(*w<vmin || *w>vmax)
1031       return false;
1032   return true;
1033 }
1034
1035 /*!
1036  * Sorts values of the array.
1037  *  \param [in] asc - \a true means ascending order, \a false, descending.
1038  *  \throw If \a this is not allocated.
1039  *  \throw If \a this->getNumberOfComponents() != 1.
1040  */
1041 void DataArrayDouble::sort(bool asc) throw(INTERP_KERNEL::Exception)
1042 {
1043   checkAllocated();
1044   if(getNumberOfComponents()!=1)
1045     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
1046   _mem.sort(asc);
1047   declareAsNew();
1048 }
1049
1050 /*!
1051  * Reverse the array values.
1052  *  \throw If \a this->getNumberOfComponents() < 1.
1053  *  \throw If \a this is not allocated.
1054  */
1055 void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception)
1056 {
1057   checkAllocated();
1058   _mem.reverse(getNumberOfComponents());
1059   declareAsNew();
1060 }
1061
1062 /*!
1063  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1064  * with at least absolute difference value of |\a eps| at each step.
1065  * If not an exception is thrown.
1066  *  \param [in] increasing - if \a true, the array values should be increasing.
1067  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1068  *                    the values are considered different.
1069  *  \throw If sequence of values is not strictly monotonic in agreement with \a
1070  *         increasing arg.
1071  *  \throw If \a this->getNumberOfComponents() != 1.
1072  *  \throw If \a this is not allocated.
1073  */
1074 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
1075 {
1076   if(!isMonotonic(increasing,eps))
1077     {
1078       if (increasing)
1079         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
1080       else
1081         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
1082     }
1083 }
1084
1085 /*!
1086  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1087  * with at least absolute difference value of |\a eps| at each step.
1088  *  \param [in] increasing - if \a true, array values should be increasing.
1089  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1090  *                    the values are considered different.
1091  *  \return bool - \a true if values change in accordance with \a increasing arg.
1092  *  \throw If \a this->getNumberOfComponents() != 1.
1093  *  \throw If \a this is not allocated.
1094  */
1095 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
1096 {
1097   checkAllocated();
1098   if(getNumberOfComponents()!=1)
1099     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
1100   int nbOfElements=getNumberOfTuples();
1101   const double *ptr=getConstPointer();
1102   if(nbOfElements==0)
1103     return true;
1104   double ref=ptr[0];
1105   double absEps=fabs(eps);
1106   if(increasing)
1107     {
1108       for(int i=1;i<nbOfElements;i++)
1109         {
1110           if(ptr[i]<(ref+absEps))
1111             return false;
1112           ref=ptr[i];
1113         }
1114       return true;
1115     }
1116   else
1117     {
1118       for(int i=1;i<nbOfElements;i++)
1119         {
1120           if(ptr[i]>(ref-absEps))
1121             return false;
1122           ref=ptr[i];
1123         }
1124       return true;
1125     }
1126 }
1127
1128 /*!
1129  * Returns a textual and human readable representation of \a this instance of
1130  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
1131  *  \return std::string - text describing \a this DataArrayDouble.
1132  */
1133 std::string DataArrayDouble::repr() const throw(INTERP_KERNEL::Exception)
1134 {
1135   std::ostringstream ret;
1136   reprStream(ret);
1137   return ret.str();
1138 }
1139
1140 std::string DataArrayDouble::reprZip() const throw(INTERP_KERNEL::Exception)
1141 {
1142   std::ostringstream ret;
1143   reprZipStream(ret);
1144   return ret.str();
1145 }
1146
1147 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
1148 {
1149   std::string idt(indent,' ');
1150   ofs.precision(17);
1151   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1152   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
1153   std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1154   ofs << std::endl << idt << "</DataArray>\n";
1155 }
1156
1157 void DataArrayDouble::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1158 {
1159   stream << "Name of double array : \"" << _name << "\"\n";
1160   reprWithoutNameStream(stream);
1161 }
1162
1163 void DataArrayDouble::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1164 {
1165   stream << "Name of double array : \"" << _name << "\"\n";
1166   reprZipWithoutNameStream(stream);
1167 }
1168
1169 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1170 {
1171   DataArray::reprWithoutNameStream(stream);
1172   stream.precision(17);
1173   _mem.repr(getNumberOfComponents(),stream);
1174 }
1175
1176 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1177 {
1178   DataArray::reprWithoutNameStream(stream);
1179   stream.precision(17);
1180   _mem.reprZip(getNumberOfComponents(),stream);
1181 }
1182
1183 void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1184 {
1185   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1186   const double *data=getConstPointer();
1187   stream.precision(17);
1188   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1189   if(nbTuples*nbComp>=1)
1190     {
1191       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1192       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1193       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1194       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1195     }
1196   else
1197     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1198   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1199 }
1200
1201 /*!
1202  * Method that gives a quick overvien of \a this for python.
1203  */
1204 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1205 {
1206   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1207   stream << "DataArrayDouble C++ instance at " << this << ". ";
1208   if(isAllocated())
1209     {
1210       int nbOfCompo=(int)_info_on_compo.size();
1211       if(nbOfCompo>=1)
1212         {
1213           int nbOfTuples=getNumberOfTuples();
1214           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1215           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1216         }
1217       else
1218         stream << "Number of components : 0.";
1219     }
1220   else
1221     stream << "*** No data allocated ****";
1222 }
1223
1224 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
1225 {
1226   const double *data=begin();
1227   int nbOfTuples=getNumberOfTuples();
1228   int nbOfCompo=(int)_info_on_compo.size();
1229   std::ostringstream oss2; oss2 << "[";
1230   oss2.precision(17);
1231   std::string oss2Str(oss2.str());
1232   bool isFinished=true;
1233   for(int i=0;i<nbOfTuples && isFinished;i++)
1234     {
1235       if(nbOfCompo>1)
1236         {
1237           oss2 << "(";
1238           for(int j=0;j<nbOfCompo;j++,data++)
1239             {
1240               oss2 << *data;
1241               if(j!=nbOfCompo-1) oss2 << ", ";
1242             }
1243           oss2 << ")";
1244         }
1245       else
1246         oss2 << *data++;
1247       if(i!=nbOfTuples-1) oss2 << ", ";
1248       std::string oss3Str(oss2.str());
1249       if(oss3Str.length()<maxNbOfByteInRepr)
1250         oss2Str=oss3Str;
1251       else
1252         isFinished=false;
1253     }
1254   stream << oss2Str;
1255   if(!isFinished)
1256     stream << "... ";
1257   stream << "]";
1258 }
1259
1260 /*!
1261  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1262  * mismatch is given.
1263  * 
1264  * \param [in] other the instance to be compared with \a this
1265  * \param [in] prec the precision to compare numeric data of the arrays.
1266  * \param [out] reason In case of inequality returns the reason.
1267  * \sa DataArrayDouble::isEqual
1268  */
1269 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1270 {
1271   if(!areInfoEqualsIfNotWhy(other,reason))
1272     return false;
1273   return _mem.isEqual(other._mem,prec,reason);
1274 }
1275
1276 /*!
1277  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1278  * \ref MEDCouplingArrayBasicsCompare.
1279  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1280  *  \param [in] prec - precision value to compare numeric data of the arrays.
1281  *  \return bool - \a true if the two arrays are equal, \a false else.
1282  */
1283 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1284 {
1285   std::string tmp;
1286   return isEqualIfNotWhy(other,prec,tmp);
1287 }
1288
1289 /*!
1290  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1291  * \ref MEDCouplingArrayBasicsCompare.
1292  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1293  *  \param [in] prec - precision value to compare numeric data of the arrays.
1294  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1295  */
1296 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1297 {
1298   std::string tmp;
1299   return _mem.isEqual(other._mem,prec,tmp);
1300 }
1301
1302 /*!
1303  * Changes number of tuples in the array. If the new number of tuples is smaller
1304  * than the current number the array is truncated, otherwise the array is extended.
1305  *  \param [in] nbOfTuples - new number of tuples. 
1306  *  \throw If \a this is not allocated.
1307  *  \throw If \a nbOfTuples is negative.
1308  */
1309 void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
1310 {
1311   if(nbOfTuples<0)
1312     throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
1313   checkAllocated();
1314   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1315   declareAsNew();
1316 }
1317
1318 /*!
1319  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1320  * array to the new one.
1321  *  \return DataArrayInt * - the new instance of DataArrayInt.
1322  */
1323 DataArrayInt *DataArrayDouble::convertToIntArr() const
1324 {
1325   DataArrayInt *ret=DataArrayInt::New();
1326   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1327   std::size_t nbOfVals=getNbOfElems();
1328   const double *src=getConstPointer();
1329   int *dest=ret->getPointer();
1330   std::copy(src,src+nbOfVals,dest);
1331   ret->copyStringInfoFrom(*this);
1332   return ret;
1333 }
1334
1335 /*!
1336  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1337  * arranged in memory. If \a this array holds 2 components of 3 values:
1338  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1339  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1340  *  \warning Do not confuse this method with transpose()!
1341  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1342  *          is to delete using decrRef() as it is no more needed.
1343  *  \throw If \a this is not allocated.
1344  */
1345 DataArrayDouble *DataArrayDouble::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
1346 {
1347   if(_mem.isNull())
1348     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1349   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1350   DataArrayDouble *ret=DataArrayDouble::New();
1351   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1352   return ret;
1353 }
1354
1355 /*!
1356  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1357  * arranged in memory. If \a this array holds 2 components of 3 values:
1358  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1359  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1360  *  \warning Do not confuse this method with transpose()!
1361  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1362  *          is to delete using decrRef() as it is no more needed.
1363  *  \throw If \a this is not allocated.
1364  */
1365 DataArrayDouble *DataArrayDouble::toNoInterlace() const throw(INTERP_KERNEL::Exception)
1366 {
1367   if(_mem.isNull())
1368     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1369   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1370   DataArrayDouble *ret=DataArrayDouble::New();
1371   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1372   return ret;
1373 }
1374
1375 /*!
1376  * Permutes values of \a this array as required by \a old2New array. The values are
1377  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1378  * the same as in \this one.
1379  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1380  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1381  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1382  *     giving a new position for i-th old value.
1383  */
1384 void DataArrayDouble::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
1385 {
1386   checkAllocated();
1387   int nbTuples=getNumberOfTuples();
1388   int nbOfCompo=getNumberOfComponents();
1389   double *tmp=new double[nbTuples*nbOfCompo];
1390   const double *iptr=getConstPointer();
1391   for(int i=0;i<nbTuples;i++)
1392     {
1393       int v=old2New[i];
1394       if(v>=0 && v<nbTuples)
1395         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1396       else
1397         {
1398           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1399           throw INTERP_KERNEL::Exception(oss.str().c_str());
1400         }
1401     }
1402   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1403   delete [] tmp;
1404   declareAsNew();
1405 }
1406
1407 /*!
1408  * Permutes values of \a this array as required by \a new2Old array. The values are
1409  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1410  * the same as in \this one.
1411  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1412  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1413  *     giving a previous position of i-th new value.
1414  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1415  *          is to delete using decrRef() as it is no more needed.
1416  */
1417 void DataArrayDouble::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
1418 {
1419   checkAllocated();
1420   int nbTuples=getNumberOfTuples();
1421   int nbOfCompo=getNumberOfComponents();
1422   double *tmp=new double[nbTuples*nbOfCompo];
1423   const double *iptr=getConstPointer();
1424   for(int i=0;i<nbTuples;i++)
1425     {
1426       int v=new2Old[i];
1427       if(v>=0 && v<nbTuples)
1428         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1429       else
1430         {
1431           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1432           throw INTERP_KERNEL::Exception(oss.str().c_str());
1433         }
1434     }
1435   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1436   delete [] tmp;
1437   declareAsNew();
1438 }
1439
1440 /*!
1441  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1442  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1443  * Number of tuples in the result array remains the same as in \this one.
1444  * If a permutation reduction is needed, renumberAndReduce() should be used.
1445  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1446  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1447  *          giving a new position for i-th old value.
1448  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1449  *          is to delete using decrRef() as it is no more needed.
1450  *  \throw If \a this is not allocated.
1451  */
1452 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
1453 {
1454   checkAllocated();
1455   int nbTuples=getNumberOfTuples();
1456   int nbOfCompo=getNumberOfComponents();
1457   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1458   ret->alloc(nbTuples,nbOfCompo);
1459   ret->copyStringInfoFrom(*this);
1460   const double *iptr=getConstPointer();
1461   double *optr=ret->getPointer();
1462   for(int i=0;i<nbTuples;i++)
1463     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1464   ret->copyStringInfoFrom(*this);
1465   return ret.retn();
1466 }
1467
1468 /*!
1469  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1470  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1471  * tuples in the result array remains the same as in \this one.
1472  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1473  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1474  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1475  *     giving a previous position of i-th new value.
1476  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1477  *          is to delete using decrRef() as it is no more needed.
1478  */
1479 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
1480 {
1481   checkAllocated();
1482   int nbTuples=getNumberOfTuples();
1483   int nbOfCompo=getNumberOfComponents();
1484   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1485   ret->alloc(nbTuples,nbOfCompo);
1486   ret->copyStringInfoFrom(*this);
1487   const double *iptr=getConstPointer();
1488   double *optr=ret->getPointer();
1489   for(int i=0;i<nbTuples;i++)
1490     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1491   ret->copyStringInfoFrom(*this);
1492   return ret.retn();
1493 }
1494
1495 /*!
1496  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1497  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1498  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1499  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1500  * \a old2New[ i ] is negative, is missing from the result array.
1501  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1502  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1503  *     giving a new position for i-th old tuple and giving negative position for
1504  *     for i-th old tuple that should be omitted.
1505  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1506  *          is to delete using decrRef() as it is no more needed.
1507  */
1508 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
1509 {
1510   checkAllocated();
1511   int nbTuples=getNumberOfTuples();
1512   int nbOfCompo=getNumberOfComponents();
1513   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1514   ret->alloc(newNbOfTuple,nbOfCompo);
1515   const double *iptr=getConstPointer();
1516   double *optr=ret->getPointer();
1517   for(int i=0;i<nbTuples;i++)
1518     {
1519       int w=old2New[i];
1520       if(w>=0)
1521         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1522     }
1523   ret->copyStringInfoFrom(*this);
1524   return ret.retn();
1525 }
1526
1527 /*!
1528  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1529  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1530  * \a new2OldBg array.
1531  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1532  * This method is equivalent to renumberAndReduce() except that convention in input is
1533  * \c new2old and \b not \c old2new.
1534  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1535  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1536  *              tuple index in \a this array to fill the i-th tuple in the new array.
1537  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1538  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1539  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1540  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1541  *          is to delete using decrRef() as it is no more needed.
1542  */
1543 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1544 {
1545   checkAllocated();
1546   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1547   int nbComp=getNumberOfComponents();
1548   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1549   ret->copyStringInfoFrom(*this);
1550   double *pt=ret->getPointer();
1551   const double *srcPt=getConstPointer();
1552   int i=0;
1553   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1554     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1555   ret->copyStringInfoFrom(*this);
1556   return ret.retn();
1557 }
1558
1559 /*!
1560  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1561  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1562  * \a new2OldBg array.
1563  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1564  * This method is equivalent to renumberAndReduce() except that convention in input is
1565  * \c new2old and \b not \c old2new.
1566  * This method is equivalent to selectByTupleId() except that it prevents coping data
1567  * from behind the end of \a this array.
1568  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1569  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1570  *              tuple index in \a this array to fill the i-th tuple in the new array.
1571  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1572  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1573  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1574  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1575  *          is to delete using decrRef() as it is no more needed.
1576  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1577  */
1578 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
1579 {
1580   checkAllocated();
1581   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1582   int nbComp=getNumberOfComponents();
1583   int oldNbOfTuples=getNumberOfTuples();
1584   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1585   ret->copyStringInfoFrom(*this);
1586   double *pt=ret->getPointer();
1587   const double *srcPt=getConstPointer();
1588   int i=0;
1589   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1590     if(*w>=0 && *w<oldNbOfTuples)
1591       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1592     else
1593       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1594   ret->copyStringInfoFrom(*this);
1595   return ret.retn();
1596 }
1597
1598 /*!
1599  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1600  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1601  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1602  * command \c range( \a bg, \a end2, \a step ).
1603  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1604  * not constructed explicitly.
1605  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1606  *  \param [in] bg - index of the first tuple to copy from \a this array.
1607  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1608  *  \param [in] step - index increment to get index of the next tuple to copy.
1609  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1610  *          is to delete using decrRef() as it is no more needed.
1611  *  \sa DataArrayDouble::substr.
1612  */
1613 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
1614 {
1615   checkAllocated();
1616   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1617   int nbComp=getNumberOfComponents();
1618   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1619   ret->alloc(newNbOfTuples,nbComp);
1620   double *pt=ret->getPointer();
1621   const double *srcPt=getConstPointer()+bg*nbComp;
1622   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1623     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1624   ret->copyStringInfoFrom(*this);
1625   return ret.retn();
1626 }
1627
1628 /*!
1629  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1630  * of tuples specified by \a ranges parameter.
1631  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1632  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1633  *              of tuples in [\c begin,\c end) format.
1634  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1635  *          is to delete using decrRef() as it is no more needed.
1636  *  \throw If \a end < \a begin.
1637  *  \throw If \a end > \a this->getNumberOfTuples().
1638  *  \throw If \a this is not allocated.
1639  */
1640 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
1641 {
1642   checkAllocated();
1643   int nbOfComp=getNumberOfComponents();
1644   int nbOfTuplesThis=getNumberOfTuples();
1645   if(ranges.empty())
1646     {
1647       DataArrayDouble *ret=DataArrayDouble::New();
1648       ret->alloc(0,nbOfComp);
1649       ret->copyStringInfoFrom(*this);
1650       return ret;
1651     }
1652   int ref=ranges.front().first;
1653   int nbOfTuples=0;
1654   bool isIncreasing=true;
1655   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1656     {
1657       if((*it).first<=(*it).second)
1658         {
1659           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1660             {
1661               nbOfTuples+=(*it).second-(*it).first;
1662               if(isIncreasing)
1663                 isIncreasing=ref<=(*it).first;
1664               ref=(*it).second;
1665             }
1666           else
1667             {
1668               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1669               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1670               throw INTERP_KERNEL::Exception(oss.str().c_str());
1671             }
1672         }
1673       else
1674         {
1675           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1676           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1677           throw INTERP_KERNEL::Exception(oss.str().c_str());
1678         }
1679     }
1680   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1681     return deepCpy();
1682   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1683   ret->alloc(nbOfTuples,nbOfComp);
1684   ret->copyStringInfoFrom(*this);
1685   const double *src=getConstPointer();
1686   double *work=ret->getPointer();
1687   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1688     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1689   return ret.retn();
1690 }
1691
1692 /*!
1693  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1694  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1695  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1696  * This method is a specialization of selectByTupleId2().
1697  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1698  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1699  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1700  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1701  *          is to delete using decrRef() as it is no more needed.
1702  *  \throw If \a tupleIdBg < 0.
1703  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1704     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1705  *  \sa DataArrayDouble::selectByTupleId2
1706  */
1707 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
1708 {
1709   checkAllocated();
1710   int nbt=getNumberOfTuples();
1711   if(tupleIdBg<0)
1712     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1713   if(tupleIdBg>nbt)
1714     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1715   int trueEnd=tupleIdEnd;
1716   if(tupleIdEnd!=-1)
1717     {
1718       if(tupleIdEnd>nbt)
1719         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1720     }
1721   else
1722     trueEnd=nbt;
1723   int nbComp=getNumberOfComponents();
1724   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1725   ret->alloc(trueEnd-tupleIdBg,nbComp);
1726   ret->copyStringInfoFrom(*this);
1727   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1728   return ret.retn();
1729 }
1730
1731 /*!
1732  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1733  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1734  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1735  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1736  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1737  * components.  
1738  *  \param [in] newNbOfComp - number of components for the new array to have.
1739  *  \param [in] dftValue - value assigned to new values added to the new array.
1740  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1741  *          is to delete using decrRef() as it is no more needed.
1742  *  \throw If \a this is not allocated.
1743  */
1744 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception)
1745 {
1746   checkAllocated();
1747   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1748   ret->alloc(getNumberOfTuples(),newNbOfComp);
1749   const double *oldc=getConstPointer();
1750   double *nc=ret->getPointer();
1751   int nbOfTuples=getNumberOfTuples();
1752   int oldNbOfComp=getNumberOfComponents();
1753   int dim=std::min(oldNbOfComp,newNbOfComp);
1754   for(int i=0;i<nbOfTuples;i++)
1755     {
1756       int j=0;
1757       for(;j<dim;j++)
1758         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1759       for(;j<newNbOfComp;j++)
1760         nc[newNbOfComp*i+j]=dftValue;
1761     }
1762   ret->setName(getName().c_str());
1763   for(int i=0;i<dim;i++)
1764     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
1765   ret->setName(getName().c_str());
1766   return ret.retn();
1767 }
1768
1769 /*!
1770  * Changes the number of components within \a this array so that its raw data **does
1771  * not** change, instead splitting this data into tuples changes.
1772  *  \warning This method erases all (name and unit) component info set before!
1773  *  \param [in] newNbOfComp - number of components for \a this array to have.
1774  *  \throw If \a this is not allocated
1775  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1776  *  \throw If \a newNbOfCompo is lower than 1.
1777  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1778  *  \warning This method erases all (name and unit) component info set before!
1779  */
1780 void DataArrayDouble::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
1781 {
1782   checkAllocated();
1783   if(newNbOfCompo<1)
1784     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1785   std::size_t nbOfElems=getNbOfElems();
1786   if(nbOfElems%newNbOfCompo!=0)
1787     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1788   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1789     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1790   _info_on_compo.clear();
1791   _info_on_compo.resize(newNbOfCompo);
1792   declareAsNew();
1793 }
1794
1795 /*!
1796  * Changes the number of components within \a this array to be equal to its number
1797  * of tuples, and inversely its number of tuples to become equal to its number of 
1798  * components. So that its raw data **does not** change, instead splitting this
1799  * data into tuples changes.
1800  *  \warning This method erases all (name and unit) component info set before!
1801  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1802  *  \throw If \a this is not allocated.
1803  *  \sa rearrange()
1804  */
1805 void DataArrayDouble::transpose() throw(INTERP_KERNEL::Exception)
1806 {
1807   checkAllocated();
1808   int nbOfTuples=getNumberOfTuples();
1809   rearrange(nbOfTuples);
1810 }
1811
1812 /*!
1813  * Returns a copy of \a this array composed of selected components.
1814  * The new DataArrayDouble has the same number of tuples but includes components
1815  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1816  * can be either less, same or more than \a this->getNbOfElems().
1817  *  \param [in] compoIds - sequence of zero based indices of components to include
1818  *              into the new array.
1819  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1820  *          is to delete using decrRef() as it is no more needed.
1821  *  \throw If \a this is not allocated.
1822  *  \throw If a component index (\a i) is not valid: 
1823  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1824  *
1825  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1826  */
1827 DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
1828 {
1829   checkAllocated();
1830   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1831   std::size_t newNbOfCompo=compoIds.size();
1832   int oldNbOfCompo=getNumberOfComponents();
1833   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1834     if((*it)<0 || (*it)>=oldNbOfCompo)
1835       {
1836         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1837         throw INTERP_KERNEL::Exception(oss.str().c_str());
1838       }
1839   int nbOfTuples=getNumberOfTuples();
1840   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1841   ret->copyPartOfStringInfoFrom(*this,compoIds);
1842   const double *oldc=getConstPointer();
1843   double *nc=ret->getPointer();
1844   for(int i=0;i<nbOfTuples;i++)
1845     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1846       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1847   return ret.retn();
1848 }
1849
1850 /*!
1851  * Appends components of another array to components of \a this one, tuple by tuple.
1852  * So that the number of tuples of \a this array remains the same and the number of 
1853  * components increases.
1854  *  \param [in] other - the DataArrayDouble to append to \a this one.
1855  *  \throw If \a this is not allocated.
1856  *  \throw If \a this and \a other arrays have different number of tuples.
1857  *
1858  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1859  *
1860  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1861  */
1862 void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
1863 {
1864   checkAllocated();
1865   other->checkAllocated();
1866   int nbOfTuples=getNumberOfTuples();
1867   if(nbOfTuples!=other->getNumberOfTuples())
1868     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1869   int nbOfComp1=getNumberOfComponents();
1870   int nbOfComp2=other->getNumberOfComponents();
1871   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1872   double *w=newArr;
1873   const double *inp1=getConstPointer();
1874   const double *inp2=other->getConstPointer();
1875   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1876     {
1877       w=std::copy(inp1,inp1+nbOfComp1,w);
1878       w=std::copy(inp2,inp2+nbOfComp2,w);
1879     }
1880   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1881   std::vector<int> compIds(nbOfComp2);
1882   for(int i=0;i<nbOfComp2;i++)
1883     compIds[i]=nbOfComp1+i;
1884   copyPartOfStringInfoFrom2(compIds,*other);
1885 }
1886
1887 /*!
1888  * This method checks that all tuples in \a other are in \a this.
1889  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1890  * 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.
1891  *
1892  * \param [in] other - the array having the same number of components than \a this.
1893  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1894  * \sa DataArrayDouble::findCommonTuples
1895  */
1896 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const throw(INTERP_KERNEL::Exception)
1897 {
1898   if(!other)
1899     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1900   checkAllocated(); other->checkAllocated();
1901   if(getNumberOfComponents()!=other->getNumberOfComponents())
1902     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1903   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1904   DataArrayInt *c=0,*ci=0;
1905   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1906   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1907   int newNbOfTuples=-1;
1908   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1909   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1910   tupleIds=ret1.retn();
1911   return newNbOfTuples==getNumberOfTuples();
1912 }
1913
1914 /*!
1915  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1916  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1917  * distance separating two points is computed with the infinite norm.
1918  *
1919  * Indices of coincident tuples are stored in output arrays.
1920  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1921  *
1922  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1923  * MEDCouplingUMesh::mergeNodes().
1924  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1925  *              considered not coincident.
1926  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1927  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1928  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1929  *               \a comm->getNumberOfComponents() == 1. 
1930  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1931  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1932  *               groups of (indices of) coincident tuples. Its every value is a tuple
1933  *               index where a next group of tuples begins. For example the second
1934  *               group of tuples in \a comm is described by following range of indices:
1935  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1936  *               gives the number of groups of coincident tuples.
1937  *  \throw If \a this is not allocated.
1938  *  \throw If the number of components is not in [1,2,3].
1939  *
1940  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1941  *
1942  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1943  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
1944  */
1945 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception)
1946 {
1947   checkAllocated();
1948   int nbOfCompo=getNumberOfComponents();
1949   if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work
1950     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
1951   
1952   int nbOfTuples=getNumberOfTuples();
1953   //
1954   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1955   switch(nbOfCompo)
1956     {
1957     case 3:
1958       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1959       break;
1960     case 2:
1961       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1962       break;
1963     case 1:
1964       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1965       break;
1966     default:
1967       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
1968     }
1969   comm=c.retn();
1970   commIndex=cI.retn();
1971 }
1972
1973 /*!
1974  * 
1975  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1976  *             \a nbTimes  should be at least equal to 1.
1977  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1978  * \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.
1979  */
1980 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
1981 {
1982   checkAllocated();
1983   if(getNumberOfComponents()!=1)
1984     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1985   if(nbTimes<1)
1986     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1987   int nbTuples=getNumberOfTuples();
1988   const double *inPtr=getConstPointer();
1989   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1990   double *retPtr=ret->getPointer();
1991   for(int i=0;i<nbTuples;i++,inPtr++)
1992     {
1993       double val=*inPtr;
1994       for(int j=0;j<nbTimes;j++,retPtr++)
1995         *retPtr=val;
1996     }
1997   ret->copyStringInfoFrom(*this);
1998   return ret.retn();
1999 }
2000
2001 /*!
2002  * This methods returns the minimal distance between the two set of points \a this and \a other.
2003  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2004  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2005  *
2006  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2007  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2008  * \return the minimal distance between the two set of points \a this and \a other.
2009  * \sa DataArrayDouble::findClosestTupleId
2010  */
2011 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const throw(INTERP_KERNEL::Exception)
2012 {
2013   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
2014   int nbOfCompo(getNumberOfComponents());
2015   int otherNbTuples(other->getNumberOfTuples());
2016   const double *thisPt(begin()),*otherPt(other->begin());
2017   const int *part1Pt(part1->begin());
2018   double ret=std::numeric_limits<double>::max();
2019   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2020     {
2021       double tmp(0.);
2022       for(int j=0;j<nbOfCompo;j++)
2023         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2024       if(tmp<ret)
2025         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2026     }
2027   return sqrt(ret);
2028 }
2029
2030 /*!
2031  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2032  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2033  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2034  *
2035  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2036  * \sa DataArrayDouble::minimalDistanceTo
2037  */
2038 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
2039 {
2040   if(!other)
2041     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2042   checkAllocated(); other->checkAllocated();
2043   int nbOfCompo=getNumberOfComponents();
2044   if(nbOfCompo!=other->getNumberOfComponents())
2045     {
2046       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2047       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2048       throw INTERP_KERNEL::Exception(oss.str().c_str());
2049     }
2050   int nbOfTuples=other->getNumberOfTuples();
2051   int thisNbOfTuples=getNumberOfTuples();
2052   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2053   double bounds[6];
2054   getMinMaxPerComponent(bounds);
2055   switch(nbOfCompo)
2056     {
2057     case 3:
2058       {
2059         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2060         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2061         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2062         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2063         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2064         break;
2065       }
2066     case 2:
2067       {
2068         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2069         double delta=std::max(xDelta,yDelta);
2070         double characSize=sqrt(delta/(double)thisNbOfTuples);
2071         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2072         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2073         break;
2074       }
2075     case 1:
2076       {
2077         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2078         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2079         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2080         break;
2081       }
2082     default:
2083       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2084     }
2085   return ret.retn();
2086 }
2087
2088 /*!
2089  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
2090  * 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
2091  * how many bounding boxes in \a otherBBoxFrmt.
2092  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
2093  *
2094  * \param [in] otherBBoxFrmt - It is an array .
2095  * \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.
2096  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
2097  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
2098  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
2099  */
2100 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const throw(INTERP_KERNEL::Exception)
2101 {
2102   if(!otherBBoxFrmt)
2103     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
2104   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
2105     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
2106   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
2107   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
2108     {
2109       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
2110       throw INTERP_KERNEL::Exception(oss.str().c_str());
2111     }
2112   if(nbOfComp%2!=0)
2113     {
2114       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
2115       throw INTERP_KERNEL::Exception(oss.str().c_str());
2116     }
2117   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
2118   const double *thisBBPtr(begin());
2119   int *retPtr(ret->getPointer());
2120   switch(nbOfComp/2)
2121     {
2122     case 3:
2123       {
2124         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2125         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2126           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2127         break;
2128       }
2129     case 2:
2130       {
2131         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2132         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2133           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2134         break;
2135       }
2136     case 1:
2137       {
2138         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2139         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2140           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2141         break;
2142       }
2143     defaut:
2144       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
2145     }
2146   
2147   return ret.retn();
2148 }
2149
2150 /*!
2151  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2152  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2153  * space. The distance between tuples is computed using norm2. If several tuples are
2154  * not far each from other than \a prec, only one of them remains in the result
2155  * array. The order of tuples in the result array is same as in \a this one except
2156  * that coincident tuples are excluded.
2157  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2158  *              considered not coincident.
2159  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2160  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2161  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2162  *          is to delete using decrRef() as it is no more needed.
2163  *  \throw If \a this is not allocated.
2164  *  \throw If the number of components is not in [1,2,3].
2165  *
2166  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2167  */
2168 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception)
2169 {
2170   checkAllocated();
2171   DataArrayInt *c0=0,*cI0=0;
2172   findCommonTuples(prec,limitTupleId,c0,cI0);
2173   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2174   int newNbOfTuples=-1;
2175   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2176   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2177 }
2178
2179 /*!
2180  * Copy all components in a specified order from another DataArrayDouble.
2181  * Both numerical and textual data is copied. The number of tuples in \a this and
2182  * the other array can be different.
2183  *  \param [in] a - the array to copy data from.
2184  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2185  *              to be copied.
2186  *  \throw If \a a is NULL.
2187  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2188  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2189  *
2190  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2191  */
2192 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
2193 {
2194   if(!a)
2195     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2196   checkAllocated();
2197   copyPartOfStringInfoFrom2(compoIds,*a);
2198   std::size_t partOfCompoSz=compoIds.size();
2199   int nbOfCompo=getNumberOfComponents();
2200   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2201   const double *ac=a->getConstPointer();
2202   double *nc=getPointer();
2203   for(int i=0;i<nbOfTuples;i++)
2204     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2205       nc[nbOfCompo*i+compoIds[j]]=*ac;
2206 }
2207
2208 /*!
2209  * Copy all values from another DataArrayDouble into specified tuples and components
2210  * of \a this array. Textual data is not copied.
2211  * The tree parameters defining set of indices of tuples and components are similar to
2212  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2213  *  \param [in] a - the array to copy values from.
2214  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2215  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2216  *              are located.
2217  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2218  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2219  *  \param [in] endComp - index of the component before which the components to assign
2220  *              to are located.
2221  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2222  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2223  *              must be equal to the number of columns to assign to, else an
2224  *              exception is thrown; if \a false, then it is only required that \a
2225  *              a->getNbOfElems() equals to number of values to assign to (this condition
2226  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2227  *              values to assign to is given by following Python expression:
2228  *              \a nbTargetValues = 
2229  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2230  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2231  *  \throw If \a a is NULL.
2232  *  \throw If \a a is not allocated.
2233  *  \throw If \a this is not allocated.
2234  *  \throw If parameters specifying tuples and components to assign to do not give a
2235  *            non-empty range of increasing indices.
2236  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2237  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2238  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2239  *
2240  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2241  */
2242 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2243 {
2244   if(!a)
2245     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2246   const char msg[]="DataArrayDouble::setPartOfValues1";
2247   checkAllocated();
2248   a->checkAllocated();
2249   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2250   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2251   int nbComp=getNumberOfComponents();
2252   int nbOfTuples=getNumberOfTuples();
2253   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2254   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2255   bool assignTech=true;
2256   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2257     {
2258       if(strictCompoCompare)
2259         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2260     }
2261   else
2262     {
2263       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2264       assignTech=false;
2265     }
2266   const double *srcPt=a->getConstPointer();
2267   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2268   if(assignTech)
2269     {
2270       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2271         for(int j=0;j<newNbOfComp;j++,srcPt++)
2272           pt[j*stepComp]=*srcPt;
2273     }
2274   else
2275     {
2276       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2277         {
2278           const double *srcPt2=srcPt;
2279           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2280             pt[j*stepComp]=*srcPt2;
2281         }
2282     }
2283 }
2284
2285 /*!
2286  * Assign a given value to values at specified tuples and components of \a this array.
2287  * The tree parameters defining set of indices of tuples and components are similar to
2288  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2289  *  \param [in] a - the value to assign.
2290  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2291  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2292  *              are located.
2293  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2294  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2295  *  \param [in] endComp - index of the component before which the components to assign
2296  *              to are located.
2297  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2298  *  \throw If \a this is not allocated.
2299  *  \throw If parameters specifying tuples and components to assign to, do not give a
2300  *            non-empty range of increasing indices or indices are out of a valid range
2301  *            for \this array.
2302  *
2303  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2304  */
2305 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2306 {
2307   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2308   checkAllocated();
2309   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2310   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2311   int nbComp=getNumberOfComponents();
2312   int nbOfTuples=getNumberOfTuples();
2313   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2314   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2315   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2316   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2317     for(int j=0;j<newNbOfComp;j++)
2318       pt[j*stepComp]=a;
2319 }
2320
2321 /*!
2322  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2323  * components of \a this array. Textual data is not copied.
2324  * The tuples and components to assign to are defined by C arrays of indices.
2325  * There are two *modes of usage*:
2326  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2327  *   of \a a is assigned to its own location within \a this array. 
2328  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2329  *   components of every specified tuple of \a this array. In this mode it is required
2330  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2331  *
2332  *  \param [in] a - the array to copy values from.
2333  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2334  *              assign values of \a a to.
2335  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2336  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2337  *              \a bgTuples <= \a pi < \a endTuples.
2338  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2339  *              assign values of \a a to.
2340  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2341  *              pointer to a component index <em>(pi)</em> varies as this: 
2342  *              \a bgComp <= \a pi < \a endComp.
2343  *  \param [in] strictCompoCompare - this parameter is checked only if the
2344  *               *mode of usage* is the first; if it is \a true (default), 
2345  *               then \a a->getNumberOfComponents() must be equal 
2346  *               to the number of specified columns, else this is not required.
2347  *  \throw If \a a is NULL.
2348  *  \throw If \a a is not allocated.
2349  *  \throw If \a this is not allocated.
2350  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2351  *         out of a valid range for \a this array.
2352  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2353  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2354  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2355  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2356  *
2357  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2358  */
2359 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2360 {
2361   if(!a)
2362     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2363   const char msg[]="DataArrayDouble::setPartOfValues2";
2364   checkAllocated();
2365   a->checkAllocated();
2366   int nbComp=getNumberOfComponents();
2367   int nbOfTuples=getNumberOfTuples();
2368   for(const int *z=bgComp;z!=endComp;z++)
2369     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2370   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2371   int newNbOfComp=(int)std::distance(bgComp,endComp);
2372   bool assignTech=true;
2373   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2374     {
2375       if(strictCompoCompare)
2376         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2377     }
2378   else
2379     {
2380       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2381       assignTech=false;
2382     }
2383   double *pt=getPointer();
2384   const double *srcPt=a->getConstPointer();
2385   if(assignTech)
2386     {    
2387       for(const int *w=bgTuples;w!=endTuples;w++)
2388         {
2389           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2390           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2391             {    
2392               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2393             }
2394         }
2395     }
2396   else
2397     {
2398       for(const int *w=bgTuples;w!=endTuples;w++)
2399         {
2400           const double *srcPt2=srcPt;
2401           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2402           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2403             {    
2404               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2405             }
2406         }
2407     }
2408 }
2409
2410 /*!
2411  * Assign a given value to values at specified tuples and components of \a this array.
2412  * The tuples and components to assign to are defined by C arrays of indices.
2413  *  \param [in] a - the value to assign.
2414  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2415  *              assign \a a to.
2416  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2417  *              pointer to a tuple index (\a pi) varies as this: 
2418  *              \a bgTuples <= \a pi < \a endTuples.
2419  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2420  *              assign \a a to.
2421  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2422  *              pointer to a component index (\a pi) varies as this: 
2423  *              \a bgComp <= \a pi < \a endComp.
2424  *  \throw If \a this is not allocated.
2425  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2426  *         out of a valid range for \a this array.
2427  *
2428  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2429  */
2430 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2431 {
2432   checkAllocated();
2433   int nbComp=getNumberOfComponents();
2434   int nbOfTuples=getNumberOfTuples();
2435   for(const int *z=bgComp;z!=endComp;z++)
2436     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2437   double *pt=getPointer();
2438   for(const int *w=bgTuples;w!=endTuples;w++)
2439     for(const int *z=bgComp;z!=endComp;z++)
2440       {
2441         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2442         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2443       }
2444 }
2445
2446 /*!
2447  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2448  * components of \a this array. Textual data is not copied.
2449  * The tuples to assign to are defined by a C array of indices.
2450  * The components to assign to are defined by three values similar to parameters of
2451  * the Python function \c range(\c start,\c stop,\c step).
2452  * There are two *modes of usage*:
2453  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2454  *   of \a a is assigned to its own location within \a this array. 
2455  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2456  *   components of every specified tuple of \a this array. In this mode it is required
2457  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2458  *
2459  *  \param [in] a - the array to copy values from.
2460  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2461  *              assign values of \a a to.
2462  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2463  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2464  *              \a bgTuples <= \a pi < \a endTuples.
2465  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2466  *  \param [in] endComp - index of the component before which the components to assign
2467  *              to are located.
2468  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2469  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2470  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2471  *               then \a a->getNumberOfComponents() must be equal 
2472  *               to the number of specified columns, else this is not required.
2473  *  \throw If \a a is NULL.
2474  *  \throw If \a a is not allocated.
2475  *  \throw If \a this is not allocated.
2476  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2477  *         \a this array.
2478  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2479  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2480  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2481  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2482  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2483  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2484  *  \throw If parameters specifying components to assign to, do not give a
2485  *            non-empty range of increasing indices or indices are out of a valid range
2486  *            for \this array.
2487  *
2488  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2489  */
2490 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2491 {
2492   if(!a)
2493     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2494   const char msg[]="DataArrayDouble::setPartOfValues3";
2495   checkAllocated();
2496   a->checkAllocated();
2497   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2498   int nbComp=getNumberOfComponents();
2499   int nbOfTuples=getNumberOfTuples();
2500   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2501   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2502   bool assignTech=true;
2503   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2504     {
2505       if(strictCompoCompare)
2506         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2507     }
2508   else
2509     {
2510       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2511       assignTech=false;
2512     }
2513   double *pt=getPointer()+bgComp;
2514   const double *srcPt=a->getConstPointer();
2515   if(assignTech)
2516     {
2517       for(const int *w=bgTuples;w!=endTuples;w++)
2518         for(int j=0;j<newNbOfComp;j++,srcPt++)
2519           {
2520             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2521             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2522           }
2523     }
2524   else
2525     {
2526       for(const int *w=bgTuples;w!=endTuples;w++)
2527         {
2528           const double *srcPt2=srcPt;
2529           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2530             {
2531               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2532               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2533             }
2534         }
2535     }
2536 }
2537
2538 /*!
2539  * Assign a given value to values at specified tuples and components of \a this array.
2540  * The tuples to assign to are defined by a C array of indices.
2541  * The components to assign to are defined by three values similar to parameters of
2542  * the Python function \c range(\c start,\c stop,\c step).
2543  *  \param [in] a - the value to assign.
2544  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2545  *              assign \a a to.
2546  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2547  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2548  *              \a bgTuples <= \a pi < \a endTuples.
2549  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2550  *  \param [in] endComp - index of the component before which the components to assign
2551  *              to are located.
2552  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2553  *  \throw If \a this is not allocated.
2554  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2555  *         \a this array.
2556  *  \throw If parameters specifying components to assign to, do not give a
2557  *            non-empty range of increasing indices or indices are out of a valid range
2558  *            for \this array.
2559  *
2560  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2561  */
2562 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2563 {
2564   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2565   checkAllocated();
2566   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2567   int nbComp=getNumberOfComponents();
2568   int nbOfTuples=getNumberOfTuples();
2569   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2570   double *pt=getPointer()+bgComp;
2571   for(const int *w=bgTuples;w!=endTuples;w++)
2572     for(int j=0;j<newNbOfComp;j++)
2573       {
2574         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2575         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2576       }
2577 }
2578
2579 /*!
2580  * Copy all values from another DataArrayDouble into specified tuples and components
2581  * of \a this array. Textual data is not copied.
2582  * The tree parameters defining set of indices of tuples and components are similar to
2583  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2584  *  \param [in] a - the array to copy values from.
2585  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2586  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2587  *              are located.
2588  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2589  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2590  *              assign \a a to.
2591  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2592  *              pointer to a component index (\a pi) varies as this: 
2593  *              \a bgComp <= \a pi < \a endComp.
2594  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2595  *              must be equal to the number of columns to assign to, else an
2596  *              exception is thrown; if \a false, then it is only required that \a
2597  *              a->getNbOfElems() equals to number of values to assign to (this condition
2598  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2599  *              values to assign to is given by following Python expression:
2600  *              \a nbTargetValues = 
2601  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2602  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2603  *  \throw If \a a is NULL.
2604  *  \throw If \a a is not allocated.
2605  *  \throw If \a this is not allocated.
2606  *  \throw If parameters specifying tuples and components to assign to do not give a
2607  *            non-empty range of increasing indices.
2608  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2609  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2610  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2611  *
2612  */
2613 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2614 {
2615   if(!a)
2616     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2617   const char msg[]="DataArrayDouble::setPartOfValues4";
2618   checkAllocated();
2619   a->checkAllocated();
2620   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2621   int newNbOfComp=(int)std::distance(bgComp,endComp);
2622   int nbComp=getNumberOfComponents();
2623   for(const int *z=bgComp;z!=endComp;z++)
2624     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2625   int nbOfTuples=getNumberOfTuples();
2626   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2627   bool assignTech=true;
2628   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2629     {
2630       if(strictCompoCompare)
2631         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2632     }
2633   else
2634     {
2635       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2636       assignTech=false;
2637     }
2638   const double *srcPt=a->getConstPointer();
2639   double *pt=getPointer()+bgTuples*nbComp;
2640   if(assignTech)
2641     {
2642       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2643         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2644           pt[*z]=*srcPt;
2645     }
2646   else
2647     {
2648       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2649         {
2650           const double *srcPt2=srcPt;
2651           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2652             pt[*z]=*srcPt2;
2653         }
2654     }
2655 }
2656
2657 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2658 {
2659   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2660   checkAllocated();
2661   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2662   int nbComp=getNumberOfComponents();
2663   for(const int *z=bgComp;z!=endComp;z++)
2664     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2665   int nbOfTuples=getNumberOfTuples();
2666   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2667   double *pt=getPointer()+bgTuples*nbComp;
2668   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2669     for(const int *z=bgComp;z!=endComp;z++)
2670       pt[*z]=a;
2671 }
2672
2673 /*!
2674  * Copy some tuples from another DataArrayDouble into specified tuples
2675  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2676  * components.
2677  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2678  * All components of selected tuples are copied.
2679  *  \param [in] a - the array to copy values from.
2680  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2681  *              target tuples of \a this. \a tuplesSelec has two components, and the
2682  *              first component specifies index of the source tuple and the second
2683  *              one specifies index of the target tuple.
2684  *  \throw If \a this is not allocated.
2685  *  \throw If \a a is NULL.
2686  *  \throw If \a a is not allocated.
2687  *  \throw If \a tuplesSelec is NULL.
2688  *  \throw If \a tuplesSelec is not allocated.
2689  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2690  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2691  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2692  *         the corresponding (\a this or \a a) array.
2693  */
2694 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2695 {
2696   if(!a || !tuplesSelec)
2697     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2698   checkAllocated();
2699   a->checkAllocated();
2700   tuplesSelec->checkAllocated();
2701   int nbOfComp=getNumberOfComponents();
2702   if(nbOfComp!=a->getNumberOfComponents())
2703     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2704   if(tuplesSelec->getNumberOfComponents()!=2)
2705     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2706   int thisNt=getNumberOfTuples();
2707   int aNt=a->getNumberOfTuples();
2708   double *valsToSet=getPointer();
2709   const double *valsSrc=a->getConstPointer();
2710   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2711     {
2712       if(tuple[1]>=0 && tuple[1]<aNt)
2713         {
2714           if(tuple[0]>=0 && tuple[0]<thisNt)
2715             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2716           else
2717             {
2718               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2719               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2720               throw INTERP_KERNEL::Exception(oss.str().c_str());
2721             }
2722         }
2723       else
2724         {
2725           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2726           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2727           throw INTERP_KERNEL::Exception(oss.str().c_str());
2728         }
2729     }
2730 }
2731
2732 /*!
2733  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2734  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2735  * components.
2736  * The tuples to assign to are defined by index of the first tuple, and
2737  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2738  * The tuples to copy are defined by values of a DataArrayInt.
2739  * All components of selected tuples are copied.
2740  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2741  *              values to.
2742  *  \param [in] aBase - the array to copy values from.
2743  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2744  *  \throw If \a this is not allocated.
2745  *  \throw If \a aBase is NULL.
2746  *  \throw If \a aBase is not allocated.
2747  *  \throw If \a tuplesSelec is NULL.
2748  *  \throw If \a tuplesSelec is not allocated.
2749  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2750  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2751  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2752  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2753  *         \a aBase array.
2754  */
2755 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2756 {
2757   if(!aBase || !tuplesSelec)
2758     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2759   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2760   if(!a)
2761     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2762   checkAllocated();
2763   a->checkAllocated();
2764   tuplesSelec->checkAllocated();
2765   int nbOfComp=getNumberOfComponents();
2766   if(nbOfComp!=a->getNumberOfComponents())
2767     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2768   if(tuplesSelec->getNumberOfComponents()!=1)
2769     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2770   int thisNt=getNumberOfTuples();
2771   int aNt=a->getNumberOfTuples();
2772   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2773   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2774   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2775     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2776   const double *valsSrc=a->getConstPointer();
2777   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2778     {
2779       if(*tuple>=0 && *tuple<aNt)
2780         {
2781           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2782         }
2783       else
2784         {
2785           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2786           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2787           throw INTERP_KERNEL::Exception(oss.str().c_str());
2788         }
2789     }
2790 }
2791
2792 /*!
2793  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2794  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2795  * components.
2796  * The tuples to copy are defined by three values similar to parameters of
2797  * the Python function \c range(\c start,\c stop,\c step).
2798  * The tuples to assign to are defined by index of the first tuple, and
2799  * their number is defined by number of tuples to copy.
2800  * All components of selected tuples are copied.
2801  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2802  *              values to.
2803  *  \param [in] aBase - the array to copy values from.
2804  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2805  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2806  *              are located.
2807  *  \param [in] step - index increment to get index of the next tuple to copy.
2808  *  \throw If \a this is not allocated.
2809  *  \throw If \a aBase is NULL.
2810  *  \throw If \a aBase is not allocated.
2811  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2812  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2813  *  \throw If parameters specifying tuples to copy, do not give a
2814  *            non-empty range of increasing indices or indices are out of a valid range
2815  *            for the array \a aBase.
2816  */
2817 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
2818 {
2819   if(!aBase)
2820     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2821   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2822   if(!a)
2823     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2824   checkAllocated();
2825   a->checkAllocated();
2826   int nbOfComp=getNumberOfComponents();
2827   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2828   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2829   if(nbOfComp!=a->getNumberOfComponents())
2830     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2831   int thisNt=getNumberOfTuples();
2832   int aNt=a->getNumberOfTuples();
2833   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2834   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2835     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2836   if(end2>aNt)
2837     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2838   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2839   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2840     {
2841       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2842     }
2843 }
2844
2845 /*!
2846  * Returns a value located at specified tuple and component.
2847  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2848  * parameters is checked. So this method is safe but expensive if used to go through
2849  * all values of \a this.
2850  *  \param [in] tupleId - index of tuple of interest.
2851  *  \param [in] compoId - index of component of interest.
2852  *  \return double - value located by \a tupleId and \a compoId.
2853  *  \throw If \a this is not allocated.
2854  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2855  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2856  */
2857 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
2858 {
2859   checkAllocated();
2860   if(tupleId<0 || tupleId>=getNumberOfTuples())
2861     {
2862       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2863       throw INTERP_KERNEL::Exception(oss.str().c_str());
2864     }
2865   if(compoId<0 || compoId>=getNumberOfComponents())
2866     {
2867       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2868       throw INTERP_KERNEL::Exception(oss.str().c_str());
2869     }
2870   return _mem[tupleId*_info_on_compo.size()+compoId];
2871 }
2872
2873 /*!
2874  * Returns the first value of \a this. 
2875  *  \return double - the last value of \a this array.
2876  *  \throw If \a this is not allocated.
2877  *  \throw If \a this->getNumberOfComponents() != 1.
2878  *  \throw If \a this->getNumberOfTuples() < 1.
2879  */
2880 double DataArrayDouble::front() const throw(INTERP_KERNEL::Exception)
2881 {
2882   checkAllocated();
2883   if(getNumberOfComponents()!=1)
2884     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2885   int nbOfTuples=getNumberOfTuples();
2886   if(nbOfTuples<1)
2887     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2888   return *(getConstPointer());
2889 }
2890
2891 /*!
2892  * Returns the last value of \a this. 
2893  *  \return double - the last value of \a this array.
2894  *  \throw If \a this is not allocated.
2895  *  \throw If \a this->getNumberOfComponents() != 1.
2896  *  \throw If \a this->getNumberOfTuples() < 1.
2897  */
2898 double DataArrayDouble::back() const throw(INTERP_KERNEL::Exception)
2899 {
2900   checkAllocated();
2901   if(getNumberOfComponents()!=1)
2902     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2903   int nbOfTuples=getNumberOfTuples();
2904   if(nbOfTuples<1)
2905     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2906   return *(getConstPointer()+nbOfTuples-1);
2907 }
2908
2909 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2910 {
2911   if(newArray!=arrayToSet)
2912     {
2913       if(arrayToSet)
2914         arrayToSet->decrRef();
2915       arrayToSet=newArray;
2916       if(arrayToSet)
2917         arrayToSet->incrRef();
2918     }
2919 }
2920
2921 /*!
2922  * Sets a C array to be used as raw data of \a this. The previously set info
2923  *  of components is retained and re-sized. 
2924  * For more info see \ref MEDCouplingArraySteps1.
2925  *  \param [in] array - the C array to be used as raw data of \a this.
2926  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2927  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2928  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2929  *                     \c free(\c array ) will be called.
2930  *  \param [in] nbOfTuple - new number of tuples in \a this.
2931  *  \param [in] nbOfCompo - new number of components in \a this.
2932  */
2933 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2934 {
2935   _info_on_compo.resize(nbOfCompo);
2936   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2937   declareAsNew();
2938 }
2939
2940 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2941 {
2942   _info_on_compo.resize(nbOfCompo);
2943   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
2944   declareAsNew();
2945 }
2946
2947 /*!
2948  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2949  * is thrown.
2950  * \throw If zero is found in \a this array.
2951  */
2952 void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception)
2953 {
2954   const double *tmp=getConstPointer();
2955   std::size_t nbOfElems=getNbOfElems();
2956   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2957   if(where!=tmp+nbOfElems)
2958     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2959 }
2960
2961 /*!
2962  * Computes minimal and maximal value in each component. An output array is filled
2963  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2964  * enough memory before calling this method.
2965  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2966  *               It is filled as follows:<br>
2967  *               \a bounds[0] = \c min_of_component_0 <br>
2968  *               \a bounds[1] = \c max_of_component_0 <br>
2969  *               \a bounds[2] = \c min_of_component_1 <br>
2970  *               \a bounds[3] = \c max_of_component_1 <br>
2971  *               ...
2972  */
2973 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception)
2974 {
2975   checkAllocated();
2976   int dim=getNumberOfComponents();
2977   for (int idim=0; idim<dim; idim++)
2978     {
2979       bounds[idim*2]=std::numeric_limits<double>::max();
2980       bounds[idim*2+1]=-std::numeric_limits<double>::max();
2981     } 
2982   const double *ptr=getConstPointer();
2983   int nbOfTuples=getNumberOfTuples();
2984   for(int i=0;i<nbOfTuples;i++)
2985     {
2986       for(int idim=0;idim<dim;idim++)
2987         {
2988           if(bounds[idim*2]>ptr[i*dim+idim])
2989             {
2990               bounds[idim*2]=ptr[i*dim+idim];
2991             }
2992           if(bounds[idim*2+1]<ptr[i*dim+idim])
2993             {
2994               bounds[idim*2+1]=ptr[i*dim+idim];
2995             }
2996         }
2997     }
2998 }
2999
3000 /*!
3001  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3002  * to store both the min and max per component of each tuples. 
3003  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3004  *
3005  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3006  *
3007  * \throw If \a this is not allocated yet.
3008  */
3009 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw(INTERP_KERNEL::Exception)
3010 {
3011   checkAllocated();
3012   const double *dataPtr=getConstPointer();
3013   int nbOfCompo=getNumberOfComponents();
3014   int nbTuples=getNumberOfTuples();
3015   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
3016   bbox->alloc(nbTuples,2*nbOfCompo);
3017   double *bboxPtr=bbox->getPointer();
3018   for(int i=0;i<nbTuples;i++)
3019     {
3020       for(int j=0;j<nbOfCompo;j++)
3021         {
3022           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3023           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3024         }
3025     }
3026   return bbox.retn();
3027 }
3028
3029 /*!
3030  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3031  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3032  * 
3033  * \param [in] other a DataArrayDouble having same number of components than \a this.
3034  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3035  * \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.
3036  *             \a cI allows to extract information in \a c.
3037  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3038  *
3039  * \throw In case of:
3040  *  - \a this is not allocated
3041  *  - \a other is not allocated or null
3042  *  - \a this and \a other do not have the same number of components
3043  *  - if number of components of \a this is not in [1,2,3]
3044  *
3045  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3046  */
3047 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception)
3048 {
3049   if(!other)
3050     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3051   checkAllocated();
3052   other->checkAllocated();
3053   int nbOfCompo=getNumberOfComponents();
3054   int otherNbOfCompo=other->getNumberOfComponents();
3055   if(nbOfCompo!=otherNbOfCompo)
3056     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3057   int nbOfTuplesOther=other->getNumberOfTuples();
3058   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3059   switch(nbOfCompo)
3060     {
3061     case 3:
3062       {
3063         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3064         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3065         break;
3066       }
3067     case 2:
3068       {
3069         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3070         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3071         break;
3072       }
3073     case 1:
3074       {
3075         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3076         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3077         break;
3078       }
3079     default:
3080       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3081     }
3082   c=cArr.retn(); cI=cIArr.retn();
3083 }
3084
3085 /*!
3086  * 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
3087  * around origin of 'radius' 1.
3088  * 
3089  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3090  */
3091 void DataArrayDouble::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception)
3092 {
3093   checkAllocated();
3094   int dim=getNumberOfComponents();
3095   std::vector<double> bounds(2*dim);
3096   getMinMaxPerComponent(&bounds[0]);
3097   for(int i=0;i<dim;i++)
3098     {
3099       double delta=bounds[2*i+1]-bounds[2*i];
3100       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3101       if(delta>eps)
3102         applyLin(1./delta,-offset/delta,i);
3103       else
3104         applyLin(1.,-offset,i);
3105     }
3106 }
3107
3108 /*!
3109  * Returns the maximal value and its location within \a this one-dimensional array.
3110  *  \param [out] tupleId - index of the tuple holding the maximal value.
3111  *  \return double - the maximal value among all values of \a this array.
3112  *  \throw If \a this->getNumberOfComponents() != 1
3113  *  \throw If \a this->getNumberOfTuples() < 1
3114  */
3115 double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
3116 {
3117   checkAllocated();
3118   if(getNumberOfComponents()!=1)
3119     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 !");
3120   int nbOfTuples=getNumberOfTuples();
3121   if(nbOfTuples<=0)
3122     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3123   const double *vals=getConstPointer();
3124   const double *loc=std::max_element(vals,vals+nbOfTuples);
3125   tupleId=(int)std::distance(vals,loc);
3126   return *loc;
3127 }
3128
3129 /*!
3130  * Returns the maximal value within \a this array that is allowed to have more than
3131  *  one component.
3132  *  \return double - the maximal value among all values of \a this array.
3133  *  \throw If \a this is not allocated.
3134  */
3135 double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
3136 {
3137   checkAllocated();
3138   const double *loc=std::max_element(begin(),end());
3139   return *loc;
3140 }
3141
3142 /*!
3143  * Returns the maximal value and all its locations within \a this one-dimensional array.
3144  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3145  *               tuples holding the maximal value. The caller is to delete it using
3146  *               decrRef() as it is no more needed.
3147  *  \return double - the maximal value among all values of \a this array.
3148  *  \throw If \a this->getNumberOfComponents() != 1
3149  *  \throw If \a this->getNumberOfTuples() < 1
3150  */
3151 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
3152 {
3153   int tmp;
3154   tupleIds=0;
3155   double ret=getMaxValue(tmp);
3156   tupleIds=getIdsInRange(ret,ret);
3157   return ret;
3158 }
3159
3160 /*!
3161  * Returns the minimal value and its location within \a this one-dimensional array.
3162  *  \param [out] tupleId - index of the tuple holding the minimal value.
3163  *  \return double - the minimal 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::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
3168 {
3169   checkAllocated();
3170   if(getNumberOfComponents()!=1)
3171     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3172   int nbOfTuples=getNumberOfTuples();
3173   if(nbOfTuples<=0)
3174     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3175   const double *vals=getConstPointer();
3176   const double *loc=std::min_element(vals,vals+nbOfTuples);
3177   tupleId=(int)std::distance(vals,loc);
3178   return *loc;
3179 }
3180
3181 /*!
3182  * Returns the minimal value within \a this array that is allowed to have more than
3183  *  one component.
3184  *  \return double - the minimal value among all values of \a this array.
3185  *  \throw If \a this is not allocated.
3186  */
3187 double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
3188 {
3189   checkAllocated();
3190   const double *loc=std::min_element(begin(),end());
3191   return *loc;
3192 }
3193
3194 /*!
3195  * Returns the minimal value and all its locations within \a this one-dimensional array.
3196  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3197  *               tuples holding the minimal value. The caller is to delete it using
3198  *               decrRef() as it is no more needed.
3199  *  \return double - the minimal value among all values of \a this array.
3200  *  \throw If \a this->getNumberOfComponents() != 1
3201  *  \throw If \a this->getNumberOfTuples() < 1
3202  */
3203 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
3204 {
3205   int tmp;
3206   tupleIds=0;
3207   double ret=getMinValue(tmp);
3208   tupleIds=getIdsInRange(ret,ret);
3209   return ret;
3210 }
3211
3212 /*!
3213  * 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.
3214  * This method only works for single component array.
3215  *
3216  * \return a value in [ 0, \c this->getNumberOfTuples() )
3217  *
3218  * \throw If \a this is not allocated
3219  *
3220  */
3221 int DataArrayDouble::count(double value, double eps) const throw(INTERP_KERNEL::Exception)
3222 {
3223   int ret=0;
3224   checkAllocated();
3225   if(getNumberOfComponents()!=1)
3226     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3227   const double *vals=begin();
3228   int nbOfTuples=getNumberOfTuples();
3229   for(int i=0;i<nbOfTuples;i++,vals++)
3230     if(fabs(*vals-value)<=eps)
3231       ret++;
3232   return ret;
3233 }
3234
3235 /*!
3236  * Returns the average value of \a this one-dimensional array.
3237  *  \return double - the average value over all values of \a this array.
3238  *  \throw If \a this->getNumberOfComponents() != 1
3239  *  \throw If \a this->getNumberOfTuples() < 1
3240  */
3241 double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
3242 {
3243   if(getNumberOfComponents()!=1)
3244     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3245   int nbOfTuples=getNumberOfTuples();
3246   if(nbOfTuples<=0)
3247     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3248   const double *vals=getConstPointer();
3249   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3250   return ret/nbOfTuples;
3251 }
3252
3253 /*!
3254  * Returns the Euclidean norm of the vector defined by \a this array.
3255  *  \return double - the value of the Euclidean norm, i.e.
3256  *          the square root of the inner product of vector.
3257  *  \throw If \a this is not allocated.
3258  */
3259 double DataArrayDouble::norm2() const throw(INTERP_KERNEL::Exception)
3260 {
3261   checkAllocated();
3262   double ret=0.;
3263   std::size_t nbOfElems=getNbOfElems();
3264   const double *pt=getConstPointer();
3265   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3266     ret+=(*pt)*(*pt);
3267   return sqrt(ret);
3268 }
3269
3270 /*!
3271  * Returns the maximum norm of the vector defined by \a this array.
3272  *  \return double - the value of the maximum norm, i.e.
3273  *          the maximal absolute value among values of \a this array.
3274  *  \throw If \a this is not allocated.
3275  */
3276 double DataArrayDouble::normMax() const throw(INTERP_KERNEL::Exception)
3277 {
3278   checkAllocated();
3279   double ret=-1.;
3280   std::size_t nbOfElems=getNbOfElems();
3281   const double *pt=getConstPointer();
3282   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3283     {
3284       double val=std::abs(*pt);
3285       if(val>ret)
3286         ret=val;
3287     }
3288   return ret;
3289 }
3290
3291 /*!
3292  * Accumulates values of each component of \a this array.
3293  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3294  *         by the caller, that is filled by this method with sum value for each
3295  *         component.
3296  *  \throw If \a this is not allocated.
3297  */
3298 void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Exception)
3299 {
3300   checkAllocated();
3301   const double *ptr=getConstPointer();
3302   int nbTuple=getNumberOfTuples();
3303   int nbComps=getNumberOfComponents();
3304   std::fill(res,res+nbComps,0.);
3305   for(int i=0;i<nbTuple;i++)
3306     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3307 }
3308
3309 /*!
3310  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3311  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3312  *
3313  *
3314  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3315  * \a tupleEnd. If not an exception will be thrown.
3316  *
3317  * \param [in] tupleBg start pointer (included) of input external tuple
3318  * \param [in] tupleEnd end pointer (not included) of input external tuple
3319  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3320  * \return the min distance.
3321  * \sa MEDCouplingUMesh::distanceToPoint
3322  */
3323 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception)
3324 {
3325   checkAllocated();
3326   int nbTuple=getNumberOfTuples();
3327   int nbComps=getNumberOfComponents();
3328   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3329     { 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()); }
3330   if(nbTuple==0)
3331     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3332   double ret0=std::numeric_limits<double>::max();
3333   tupleId=-1;
3334   const double *work=getConstPointer();
3335   for(int i=0;i<nbTuple;i++)
3336     {
3337       double val=0.;
3338       for(int j=0;j<nbComps;j++,work++) 
3339         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3340       if(val>=ret0)
3341         continue;
3342       else
3343         { ret0=val; tupleId=i; }
3344     }
3345   return sqrt(ret0);
3346 }
3347
3348 /*!
3349  * Accumulate values of the given component of \a this array.
3350  *  \param [in] compId - the index of the component of interest.
3351  *  \return double - a sum value of \a compId-th component.
3352  *  \throw If \a this is not allocated.
3353  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3354  *         not respected.
3355  */
3356 double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
3357 {
3358   checkAllocated();
3359   const double *ptr=getConstPointer();
3360   int nbTuple=getNumberOfTuples();
3361   int nbComps=getNumberOfComponents();
3362   if(compId<0 || compId>=nbComps)
3363     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3364   double ret=0.;
3365   for(int i=0;i<nbTuple;i++)
3366     ret+=ptr[i*nbComps+compId];
3367   return ret;
3368 }
3369
3370 /*!
3371  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3372  * The returned array will have same number of components than \a this and number of tuples equal to
3373  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3374  *
3375  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3376  * 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.
3377  *
3378  * \param [in] bgOfIndex - begin (included) of the input index array.
3379  * \param [in] endOfIndex - end (excluded) of the input index array.
3380  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3381  * 
3382  * \throw If bgOfIndex or end is NULL.
3383  * \throw If input index array is not ascendingly sorted.
3384  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3385  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3386  */
3387 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
3388 {
3389   if(!bgOfIndex || !endOfIndex)
3390     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3391   checkAllocated();
3392   int nbCompo=getNumberOfComponents();
3393   int nbOfTuples=getNumberOfTuples();
3394   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3395   if(sz<1)
3396     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3397   sz--;
3398   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3399   const int *w=bgOfIndex;
3400   if(*w<0 || *w>=nbOfTuples)
3401     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3402   const double *srcPt=begin()+(*w)*nbCompo;
3403   double *tmp=ret->getPointer();
3404   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3405     {
3406       std::fill(tmp,tmp+nbCompo,0.);
3407       if(w[1]>=w[0])
3408         {
3409           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3410             {
3411               if(j>=0 && j<nbOfTuples)
3412                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3413               else
3414                 {
3415                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3416                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3417                 }
3418             }
3419         }
3420       else
3421         {
3422           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3423           throw INTERP_KERNEL::Exception(oss.str().c_str());
3424         }
3425     }
3426   ret->copyStringInfoFrom(*this);
3427   return ret.retn();
3428 }
3429
3430 /*!
3431  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3432  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3433  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3434  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3435  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3436  *          is to delete this array using decrRef() as it is no more needed. The array
3437  *          does not contain any textual info on components.
3438  *  \throw If \a this->getNumberOfComponents() != 2.
3439  */
3440 DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::Exception)
3441 {
3442   checkAllocated();
3443   int nbOfComp=getNumberOfComponents();
3444   if(nbOfComp!=2)
3445     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3446   int nbOfTuple=getNumberOfTuples();
3447   DataArrayDouble *ret=DataArrayDouble::New();
3448   ret->alloc(nbOfTuple,2);
3449   double *w=ret->getPointer();
3450   const double *wIn=getConstPointer();
3451   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3452     {
3453       w[0]=wIn[0]*cos(wIn[1]);
3454       w[1]=wIn[0]*sin(wIn[1]);
3455     }
3456   return ret;
3457 }
3458
3459 /*!
3460  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3461  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3462  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3463  * the Cylindrical CS.
3464  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3465  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3466  *          on the third component is copied from \a this array. The caller
3467  *          is to delete this array using decrRef() as it is no more needed. 
3468  *  \throw If \a this->getNumberOfComponents() != 3.
3469  */
3470 DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exception)
3471 {
3472   checkAllocated();
3473   int nbOfComp=getNumberOfComponents();
3474   if(nbOfComp!=3)
3475     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3476   int nbOfTuple=getNumberOfTuples();
3477   DataArrayDouble *ret=DataArrayDouble::New();
3478   ret->alloc(getNumberOfTuples(),3);
3479   double *w=ret->getPointer();
3480   const double *wIn=getConstPointer();
3481   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3482     {
3483       w[0]=wIn[0]*cos(wIn[1]);
3484       w[1]=wIn[0]*sin(wIn[1]);
3485       w[2]=wIn[2];
3486     }
3487   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3488   return ret;
3489 }
3490
3491 /*!
3492  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3493  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3494  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3495  * point in the Cylindrical CS.
3496  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3497  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3498  *          on the third component is copied from \a this array. The caller
3499  *          is to delete this array using decrRef() as it is no more needed.
3500  *  \throw If \a this->getNumberOfComponents() != 3.
3501  */
3502 DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::Exception)
3503 {
3504   checkAllocated();
3505   int nbOfComp=getNumberOfComponents();
3506   if(nbOfComp!=3)
3507     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3508   int nbOfTuple=getNumberOfTuples();
3509   DataArrayDouble *ret=DataArrayDouble::New();
3510   ret->alloc(getNumberOfTuples(),3);
3511   double *w=ret->getPointer();
3512   const double *wIn=getConstPointer();
3513   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3514     {
3515       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3516       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3517       w[2]=wIn[0]*cos(wIn[1]);
3518     }
3519   return ret;
3520 }
3521
3522 /*!
3523  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3524  * array contating 6 components.
3525  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3526  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3527  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3528  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3529  *  \throw If \a this->getNumberOfComponents() != 6.
3530  */
3531 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
3532 {
3533   checkAllocated();
3534   int nbOfComp=getNumberOfComponents();
3535   if(nbOfComp!=6)
3536     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3537   DataArrayDouble *ret=DataArrayDouble::New();
3538   int nbOfTuple=getNumberOfTuples();
3539   ret->alloc(nbOfTuple,1);
3540   const double *src=getConstPointer();
3541   double *dest=ret->getPointer();
3542   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3543     *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];
3544   return ret;
3545 }
3546
3547 /*!
3548  * Computes the determinant of every square matrix defined by the tuple of \a this
3549  * array, which contains either 4, 6 or 9 components. The case of 6 components
3550  * corresponds to that of the upper triangular matrix.
3551  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3552  *          is the determinant of matrix of the corresponding tuple of \a this array.
3553  *          The caller is to delete this result array using decrRef() as it is no more
3554  *          needed. 
3555  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3556  */
3557 DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Exception)
3558 {
3559   checkAllocated();
3560   DataArrayDouble *ret=DataArrayDouble::New();
3561   int nbOfTuple=getNumberOfTuples();
3562   ret->alloc(nbOfTuple,1);
3563   const double *src=getConstPointer();
3564   double *dest=ret->getPointer();
3565   switch(getNumberOfComponents())
3566     {
3567     case 6:
3568       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3569         *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];
3570       return ret;
3571     case 4:
3572       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3573         *dest=src[0]*src[3]-src[1]*src[2];
3574       return ret;
3575     case 9:
3576       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3577         *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];
3578       return ret;
3579     default:
3580       ret->decrRef();
3581       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3582     }
3583 }
3584
3585 /*!
3586  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3587  * \a this array, which contains 6 components.
3588  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3589  *          components, whose each tuple contains the eigenvalues of the matrix of
3590  *          corresponding tuple of \a this array. 
3591  *          The caller is to delete this result array using decrRef() as it is no more
3592  *          needed. 
3593  *  \throw If \a this->getNumberOfComponents() != 6.
3594  */
3595 DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
3596 {
3597   checkAllocated();
3598   int nbOfComp=getNumberOfComponents();
3599   if(nbOfComp!=6)
3600     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3601   DataArrayDouble *ret=DataArrayDouble::New();
3602   int nbOfTuple=getNumberOfTuples();
3603   ret->alloc(nbOfTuple,3);
3604   const double *src=getConstPointer();
3605   double *dest=ret->getPointer();
3606   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3607     INTERP_KERNEL::computeEigenValues6(src,dest);
3608   return ret;
3609 }
3610
3611 /*!
3612  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3613  * \a this array, which contains 6 components.
3614  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3615  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3616  *          corresponding tuple of \a this array.
3617  *          The caller is to delete this result array using decrRef() as it is no more
3618  *          needed.
3619  *  \throw If \a this->getNumberOfComponents() != 6.
3620  */
3621 DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
3622 {
3623   checkAllocated();
3624   int nbOfComp=getNumberOfComponents();
3625   if(nbOfComp!=6)
3626     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3627   DataArrayDouble *ret=DataArrayDouble::New();
3628   int nbOfTuple=getNumberOfTuples();
3629   ret->alloc(nbOfTuple,9);
3630   const double *src=getConstPointer();
3631   double *dest=ret->getPointer();
3632   for(int i=0;i<nbOfTuple;i++,src+=6)
3633     {
3634       double tmp[3];
3635       INTERP_KERNEL::computeEigenValues6(src,tmp);
3636       for(int j=0;j<3;j++,dest+=3)
3637         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3638     }
3639   return ret;
3640 }
3641
3642 /*!
3643  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3644  * array, which contains either 4, 6 or 9 components. The case of 6 components
3645  * corresponds to that of the upper triangular matrix.
3646  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3647  *          same number of components as \a this one, whose each tuple is the inverse
3648  *          matrix of the matrix of corresponding tuple of \a this array. 
3649  *          The caller is to delete this result array using decrRef() as it is no more
3650  *          needed. 
3651  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3652  */
3653 DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception)
3654 {
3655   checkAllocated();
3656   int nbOfComp=getNumberOfComponents();
3657   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3658     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3659   DataArrayDouble *ret=DataArrayDouble::New();
3660   int nbOfTuple=getNumberOfTuples();
3661   ret->alloc(nbOfTuple,nbOfComp);
3662   const double *src=getConstPointer();
3663   double *dest=ret->getPointer();
3664 if(nbOfComp==6)
3665     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3666       {
3667         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];
3668         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3669         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3670         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3671         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3672         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3673         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3674       }
3675   else if(nbOfComp==4)
3676     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3677       {
3678         double det=src[0]*src[3]-src[1]*src[2];
3679         dest[0]=src[3]/det;
3680         dest[1]=-src[1]/det;
3681         dest[2]=-src[2]/det;
3682         dest[3]=src[0]/det;
3683       }
3684   else
3685     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3686       {
3687         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];
3688         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3689         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3690         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3691         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3692         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3693         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3694         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3695         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3696         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3697       }
3698   return ret;
3699 }
3700
3701 /*!
3702  * Computes the trace of every matrix defined by the tuple of \a this
3703  * array, which contains either 4, 6 or 9 components. The case of 6 components
3704  * corresponds to that of the upper triangular matrix.
3705  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3706  *          1 component, whose each tuple is the trace of
3707  *          the matrix of corresponding tuple of \a this array. 
3708  *          The caller is to delete this result array using decrRef() as it is no more
3709  *          needed. 
3710  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3711  */
3712 DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception)
3713 {
3714   checkAllocated();
3715   int nbOfComp=getNumberOfComponents();
3716   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3717     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3718   DataArrayDouble *ret=DataArrayDouble::New();
3719   int nbOfTuple=getNumberOfTuples();
3720   ret->alloc(nbOfTuple,1);
3721   const double *src=getConstPointer();
3722   double *dest=ret->getPointer();
3723   if(nbOfComp==6)
3724     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3725       *dest=src[0]+src[1]+src[2];
3726   else if(nbOfComp==4)
3727     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3728       *dest=src[0]+src[3];
3729   else
3730     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3731       *dest=src[0]+src[4]+src[8];
3732   return ret;
3733 }
3734
3735 /*!
3736  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3737  * \a this array, which contains 6 components.
3738  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3739  *          same number of components and tuples as \a this array.
3740  *          The caller is to delete this result array using decrRef() as it is no more
3741  *          needed.
3742  *  \throw If \a this->getNumberOfComponents() != 6.
3743  */
3744 DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception)
3745 {
3746   checkAllocated();
3747   int nbOfComp=getNumberOfComponents();
3748   if(nbOfComp!=6)
3749     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3750   DataArrayDouble *ret=DataArrayDouble::New();
3751   int nbOfTuple=getNumberOfTuples();
3752   ret->alloc(nbOfTuple,6);
3753   const double *src=getConstPointer();
3754   double *dest=ret->getPointer();
3755   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3756     {
3757       double tr=(src[0]+src[1]+src[2])/3.;
3758       dest[0]=src[0]-tr;
3759       dest[1]=src[1]-tr;
3760       dest[2]=src[2]-tr;
3761       dest[3]=src[3];
3762       dest[4]=src[4];
3763       dest[5]=src[5];
3764     }
3765   return ret;
3766 }
3767
3768 /*!
3769  * Computes the magnitude of every vector defined by the tuple of
3770  * \a this array.
3771  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3772  *          same number of tuples as \a this array and one component.
3773  *          The caller is to delete this result array using decrRef() as it is no more
3774  *          needed.
3775  *  \throw If \a this is not allocated.
3776  */
3777 DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Exception)
3778 {
3779   checkAllocated();
3780   int nbOfComp=getNumberOfComponents();
3781   DataArrayDouble *ret=DataArrayDouble::New();
3782   int nbOfTuple=getNumberOfTuples();
3783   ret->alloc(nbOfTuple,1);
3784   const double *src=getConstPointer();
3785   double *dest=ret->getPointer();
3786   for(int i=0;i<nbOfTuple;i++,dest++)
3787     {
3788       double sum=0.;
3789       for(int j=0;j<nbOfComp;j++,src++)
3790         sum+=(*src)*(*src);
3791       *dest=sqrt(sum);
3792     }
3793   return ret;
3794 }
3795
3796 /*!
3797  * Computes the maximal value within every tuple of \a this array.
3798  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3799  *          same number of tuples as \a this array and one component.
3800  *          The caller is to delete this result array using decrRef() as it is no more
3801  *          needed.
3802  *  \throw If \a this is not allocated.
3803  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3804  */
3805 DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
3806 {
3807   checkAllocated();
3808   int nbOfComp=getNumberOfComponents();
3809   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3810   int nbOfTuple=getNumberOfTuples();
3811   ret->alloc(nbOfTuple,1);
3812   const double *src=getConstPointer();
3813   double *dest=ret->getPointer();
3814   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3815     *dest=*std::max_element(src,src+nbOfComp);
3816   return ret.retn();
3817 }
3818
3819 /*!
3820  * Computes the maximal value within every tuple of \a this array and it returns the first component
3821  * id for each tuple that corresponds to the maximal value within the tuple.
3822  * 
3823  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3824  *          same number of tuples and only one component.
3825  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3826  *          same number of tuples as \a this array and one component.
3827  *          The caller is to delete this result array using decrRef() as it is no more
3828  *          needed.
3829  *  \throw If \a this is not allocated.
3830  *  \sa DataArrayDouble::maxPerTuple
3831  */
3832 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const throw(INTERP_KERNEL::Exception)
3833 {
3834   checkAllocated();
3835   int nbOfComp=getNumberOfComponents();
3836   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3837   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3838   int nbOfTuple=getNumberOfTuples();
3839   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3840   const double *src=getConstPointer();
3841   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3842   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3843     {
3844       const double *loc=std::max_element(src,src+nbOfComp);
3845       *dest=*loc;
3846       *dest1=(int)std::distance(src,loc);
3847     }
3848   compoIdOfMaxPerTuple=ret1.retn();
3849   return ret0.retn();
3850 }
3851
3852 /*!
3853  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3854  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3855  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3856  * \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)
3857  *
3858  * \warning use this method with care because it can leads to big amount of consumed memory !
3859  * 
3860  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3861  *
3862  * \throw If \a this is not allocated.
3863  *
3864  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3865  */
3866 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception)
3867 {
3868   checkAllocated();
3869   int nbOfComp=getNumberOfComponents();
3870   int nbOfTuples=getNumberOfTuples();
3871   const double *inData=getConstPointer();
3872   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3873   ret->alloc(nbOfTuples*nbOfTuples,1);
3874   double *outData=ret->getPointer();
3875   for(int i=0;i<nbOfTuples;i++)
3876     {
3877       outData[i*nbOfTuples+i]=0.;
3878       for(int j=i+1;j<nbOfTuples;j++)
3879         {
3880           double dist=0.;
3881           for(int k=0;k<nbOfComp;k++)
3882             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3883           dist=sqrt(dist);
3884           outData[i*nbOfTuples+j]=dist;
3885           outData[j*nbOfTuples+i]=dist;
3886         }
3887     }
3888   return ret.retn();
3889 }
3890
3891 /*!
3892  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3893  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3894  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3895  * \n Output rectangular matrix is sorted along rows.
3896  * \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)
3897  *
3898  * \warning use this method with care because it can leads to big amount of consumed memory !
3899  * 
3900  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3901  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3902  *
3903  * \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.
3904  *
3905  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3906  */
3907 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
3908 {
3909   if(!other)
3910     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3911   checkAllocated();
3912   other->checkAllocated();
3913   int nbOfComp=getNumberOfComponents();
3914   int otherNbOfComp=other->getNumberOfComponents();
3915   if(nbOfComp!=otherNbOfComp)
3916     {
3917       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3918       throw INTERP_KERNEL::Exception(oss.str().c_str());
3919     }
3920   int nbOfTuples=getNumberOfTuples();
3921   int otherNbOfTuples=other->getNumberOfTuples();
3922   const double *inData=getConstPointer();
3923   const double *inDataOther=other->getConstPointer();
3924   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3925   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3926   double *outData=ret->getPointer();
3927   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3928     {
3929       for(int j=0;j<nbOfTuples;j++)
3930         {
3931           double dist=0.;
3932           for(int k=0;k<nbOfComp;k++)
3933             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3934           dist=sqrt(dist);
3935           outData[i*nbOfTuples+j]=dist;
3936         }
3937     }
3938   return ret.retn();
3939 }
3940
3941 /*!
3942  * Sorts value within every tuple of \a this array.
3943  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3944  *              in descending order.
3945  *  \throw If \a this is not allocated.
3946  */
3947 void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
3948 {
3949   checkAllocated();
3950   double *pt=getPointer();
3951   int nbOfTuple=getNumberOfTuples();
3952   int nbOfComp=getNumberOfComponents();
3953   if(asc)
3954     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3955       std::sort(pt,pt+nbOfComp);
3956   else
3957     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3958       std::sort(pt,pt+nbOfComp,std::greater<double>());
3959   declareAsNew();
3960 }
3961
3962 /*!
3963  * Converts every value of \a this array to its absolute value.
3964  *  \throw If \a this is not allocated.
3965  */
3966 void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception)
3967 {
3968   checkAllocated();
3969   double *ptr=getPointer();
3970   std::size_t nbOfElems=getNbOfElems();
3971   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
3972   declareAsNew();
3973 }
3974
3975 /*!
3976  * Apply a liner function to a given component of \a this array, so that
3977  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
3978  *  \param [in] a - the first coefficient of the function.
3979  *  \param [in] b - the second coefficient of the function.
3980  *  \param [in] compoId - the index of component to modify.
3981  *  \throw If \a this is not allocated.
3982  */
3983 void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception)
3984 {
3985   checkAllocated();
3986   double *ptr=getPointer()+compoId;
3987   int nbOfComp=getNumberOfComponents();
3988   int nbOfTuple=getNumberOfTuples();
3989   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
3990     *ptr=a*(*ptr)+b;
3991   declareAsNew();
3992 }
3993
3994 /*!
3995  * Apply a liner function to all elements of \a this array, so that
3996  * an element _x_ becomes \f$ a * x + b \f$.
3997  *  \param [in] a - the first coefficient of the function.
3998  *  \param [in] b - the second coefficient of the function.
3999  *  \throw If \a this is not allocated.
4000  */
4001 void DataArrayDouble::applyLin(double a, double b) throw(INTERP_KERNEL::Exception)
4002 {
4003   checkAllocated();
4004   double *ptr=getPointer();
4005   std::size_t nbOfElems=getNbOfElems();
4006   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4007     *ptr=a*(*ptr)+b;
4008   declareAsNew();
4009 }
4010
4011 /*!
4012  * Modify all elements of \a this array, so that
4013  * an element _x_ becomes \f$ numerator / x \f$.
4014  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4015  *           array, all elements processed before detection of the zero element remain
4016  *           modified.
4017  *  \param [in] numerator - the numerator used to modify array elements.
4018  *  \throw If \a this is not allocated.
4019  *  \throw If there is an element equal to 0.0 in \a this array.
4020  */
4021 void DataArrayDouble::applyInv(double numerator) throw(INTERP_KERNEL::Exception)
4022 {
4023   checkAllocated();
4024   double *ptr=getPointer();
4025   std::size_t nbOfElems=getNbOfElems();
4026   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4027     {
4028       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4029         {
4030           *ptr=numerator/(*ptr);
4031         }
4032       else
4033         {
4034           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4035           oss << " !";
4036           throw INTERP_KERNEL::Exception(oss.str().c_str());
4037         }
4038     }
4039   declareAsNew();
4040 }
4041
4042 /*!
4043  * Returns a full copy of \a this array except that sign of all elements is reversed.
4044  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4045  *          same number of tuples and component as \a this array.
4046  *          The caller is to delete this result array using decrRef() as it is no more
4047  *          needed.
4048  *  \throw If \a this is not allocated.
4049  */
4050 DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception)
4051 {
4052   checkAllocated();
4053   DataArrayDouble *newArr=DataArrayDouble::New();
4054   int nbOfTuples=getNumberOfTuples();
4055   int nbOfComp=getNumberOfComponents();
4056   newArr->alloc(nbOfTuples,nbOfComp);
4057   const double *cptr=getConstPointer();
4058   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4059   newArr->copyStringInfoFrom(*this);
4060   return newArr;
4061 }
4062
4063 /*!
4064  * Modify all elements of \a this array, so that
4065  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4066  * all values in \a this have to be >= 0 if val is \b not integer.
4067  *  \param [in] val - the value used to apply pow on all array elements.
4068  *  \throw If \a this is not allocated.
4069  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4070  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4071  *           modified.
4072  */
4073 void DataArrayDouble::applyPow(double val) throw(INTERP_KERNEL::Exception)
4074 {
4075   checkAllocated();
4076   double *ptr=getPointer();
4077   std::size_t nbOfElems=getNbOfElems();
4078   int val2=(int)val;
4079   bool isInt=((double)val2)==val;
4080   if(!isInt)
4081     {
4082       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4083         {
4084           if(*ptr>=0)
4085             *ptr=pow(*ptr,val);
4086           else
4087             {
4088               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4089               throw INTERP_KERNEL::Exception(oss.str().c_str());
4090             }
4091         }
4092     }
4093   else
4094     {
4095       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4096         *ptr=pow(*ptr,val2);
4097     }
4098   declareAsNew();
4099 }
4100
4101 /*!
4102  * Modify all elements of \a this array, so that
4103  * an element _x_ becomes \f$ val ^ x \f$.
4104  *  \param [in] val - the value used to apply pow on all array elements.
4105  *  \throw If \a this is not allocated.
4106  *  \throw If \a val < 0.
4107  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4108  *           array, all elements processed before detection of the zero element remain
4109  *           modified.
4110  */
4111 void DataArrayDouble::applyRPow(double val) throw(INTERP_KERNEL::Exception)
4112 {
4113   checkAllocated();
4114   if(val<0.)
4115     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4116   double *ptr=getPointer();
4117   std::size_t nbOfElems=getNbOfElems();
4118   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4119     *ptr=pow(val,*ptr);
4120   declareAsNew();
4121 }
4122
4123 /*!
4124  * Returns a new DataArrayDouble created from \a this one by applying \a
4125  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4126  * For more info see \ref MEDCouplingArrayApplyFunc
4127  *  \param [in] nbOfComp - number of components in the result array.
4128  *  \param [in] func - the \a FunctionToEvaluate declared as 
4129  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4130  *              where \a pos points to the first component of a tuple of \a this array
4131  *              and \a res points to the first component of a tuple of the result array.
4132  *              Note that length (number of components) of \a pos can differ from
4133  *              that of \a res.
4134  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4135  *          same number of tuples as \a this array.
4136  *          The caller is to delete this result array using decrRef() as it is no more
4137  *          needed.
4138  *  \throw If \a this is not allocated.
4139  *  \throw If \a func returns \a false.
4140  */
4141 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception)
4142 {
4143   checkAllocated();
4144   DataArrayDouble *newArr=DataArrayDouble::New();
4145   int nbOfTuples=getNumberOfTuples();
4146   int oldNbOfComp=getNumberOfComponents();
4147   newArr->alloc(nbOfTuples,nbOfComp);
4148   const double *ptr=getConstPointer();
4149   double *ptrToFill=newArr->getPointer();
4150   for(int i=0;i<nbOfTuples;i++)
4151     {
4152       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4153         {
4154           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4155           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4156           oss << ") : Evaluation of function failed !";
4157           newArr->decrRef();
4158           throw INTERP_KERNEL::Exception(oss.str().c_str());
4159         }
4160     }
4161   return newArr;
4162 }
4163
4164 /*!
4165  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4166  * tuple of \a this array. Textual data is not copied.
4167  * For more info see \ref MEDCouplingArrayApplyFunc1.
4168  *  \param [in] nbOfComp - number of components in the result array.
4169  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4170  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4171  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4172  *          same number of tuples as \a this array and \a nbOfComp components.
4173  *          The caller is to delete this result array using decrRef() as it is no more
4174  *          needed.
4175  *  \throw If \a this is not allocated.
4176  *  \throw If computing \a func fails.
4177  */
4178 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
4179 {
4180   checkAllocated();
4181   INTERP_KERNEL::ExprParser expr(func);
4182   expr.parse();
4183   std::set<std::string> vars;
4184   expr.getTrueSetOfVars(vars);
4185   int oldNbOfComp=getNumberOfComponents();
4186   if((int)vars.size()>oldNbOfComp)
4187     {
4188       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4189       oss << vars.size() << " variables : ";
4190       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4191       throw INTERP_KERNEL::Exception(oss.str().c_str());
4192     }
4193   std::vector<std::string> varsV(vars.begin(),vars.end());
4194   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
4195   //
4196   DataArrayDouble *newArr=DataArrayDouble::New();
4197   int nbOfTuples=getNumberOfTuples();
4198   newArr->alloc(nbOfTuples,nbOfComp);
4199   const double *ptr=getConstPointer();
4200   double *ptrToFill=newArr->getPointer();
4201   for(int i=0;i<nbOfTuples;i++)
4202     {
4203       try
4204         {
4205           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4206         }
4207       catch(INTERP_KERNEL::Exception& e)
4208         {
4209           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4210           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4211           oss << ") : Evaluation of function failed !" << e.what();
4212           newArr->decrRef();
4213           throw INTERP_KERNEL::Exception(oss.str().c_str());
4214         }
4215     }
4216   return newArr;
4217 }
4218
4219 /*!
4220  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4221  * tuple of \a this array. Textual data is not copied.
4222  * For more info see \ref MEDCouplingArrayApplyFunc0.
4223  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4224  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4225  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4226  *          same number of tuples and components as \a this array.
4227  *          The caller is to delete this result array using decrRef() as it is no more
4228  *          needed.
4229  *  \throw If \a this is not allocated.
4230  *  \throw If computing \a func fails.
4231  */
4232 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception)
4233 {
4234   checkAllocated();
4235   INTERP_KERNEL::ExprParser expr(func);
4236   expr.parse();
4237   expr.prepareExprEvaluationVec();
4238   //
4239   DataArrayDouble *newArr=DataArrayDouble::New();
4240   int nbOfTuples=getNumberOfTuples();
4241   int nbOfComp=getNumberOfComponents();
4242   newArr->alloc(nbOfTuples,nbOfComp);
4243   const double *ptr=getConstPointer();
4244   double *ptrToFill=newArr->getPointer();
4245   for(int i=0;i<nbOfTuples;i++)
4246     {
4247       try
4248         {
4249           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
4250         }
4251       catch(INTERP_KERNEL::Exception& e)
4252         {
4253           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4254           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4255           oss << ") : Evaluation of function failed ! " << e.what();
4256           newArr->decrRef();
4257           throw INTERP_KERNEL::Exception(oss.str().c_str());
4258         }
4259     }
4260   return newArr;
4261 }
4262
4263 /*!
4264  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4265  * tuple of \a this array. Textual data is not copied.
4266  * For more info see \ref MEDCouplingArrayApplyFunc2.
4267  *  \param [in] nbOfComp - number of components in the result array.
4268  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4269  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4270  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4271  *          same number of tuples as \a this array.
4272  *          The caller is to delete this result array using decrRef() as it is no more
4273  *          needed.
4274  *  \throw If \a this is not allocated.
4275  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4276  *  \throw If computing \a func fails.
4277  */
4278 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
4279 {
4280   checkAllocated();
4281   INTERP_KERNEL::ExprParser expr(func);
4282   expr.parse();
4283   std::set<std::string> vars;
4284   expr.getTrueSetOfVars(vars);
4285   int oldNbOfComp=getNumberOfComponents();
4286   if((int)vars.size()>oldNbOfComp)
4287     {
4288       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4289       oss << vars.size() << " variables : ";
4290       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4291       throw INTERP_KERNEL::Exception(oss.str().c_str());
4292     }
4293   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
4294   //
4295   DataArrayDouble *newArr=DataArrayDouble::New();
4296   int nbOfTuples=getNumberOfTuples();
4297   newArr->alloc(nbOfTuples,nbOfComp);
4298   const double *ptr=getConstPointer();
4299   double *ptrToFill=newArr->getPointer();
4300   for(int i=0;i<nbOfTuples;i++)
4301     {
4302       try
4303         {
4304           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4305         }
4306       catch(INTERP_KERNEL::Exception& e)
4307         {
4308           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4309           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4310           oss << ") : Evaluation of function failed !" << e.what();
4311           newArr->decrRef();
4312           throw INTERP_KERNEL::Exception(oss.str().c_str());
4313         }
4314     }
4315   return newArr;
4316 }
4317
4318 /*!
4319  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4320  * tuple of \a this array. Textual data is not copied.
4321  * For more info see \ref MEDCouplingArrayApplyFunc3.
4322  *  \param [in] nbOfComp - number of components in the result array.
4323  *  \param [in] varsOrder - sequence of vars defining their order.
4324  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4325  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4326  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4327  *          same number of tuples as \a this array.
4328  *          The caller is to delete this result array using decrRef() as it is no more
4329  *          needed.
4330  *  \throw If \a this is not allocated.
4331  *  \throw If \a func contains vars not in \a varsOrder.
4332  *  \throw If computing \a func fails.
4333  */
4334 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const throw(INTERP_KERNEL::Exception)
4335 {
4336   checkAllocated();
4337   INTERP_KERNEL::ExprParser expr(func);
4338   expr.parse();
4339   std::set<std::string> vars;
4340   expr.getTrueSetOfVars(vars);
4341   int oldNbOfComp=getNumberOfComponents();
4342   if((int)vars.size()>oldNbOfComp)
4343     {
4344       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4345       oss << vars.size() << " variables : ";
4346       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4347       throw INTERP_KERNEL::Exception(oss.str().c_str());
4348     }
4349   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
4350   //
4351   DataArrayDouble *newArr=DataArrayDouble::New();
4352   int nbOfTuples=getNumberOfTuples();
4353   newArr->alloc(nbOfTuples,nbOfComp);
4354   const double *ptr=getConstPointer();
4355   double *ptrToFill=newArr->getPointer();
4356   for(int i=0;i<nbOfTuples;i++)
4357     {
4358       try
4359         {
4360           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4361         }
4362       catch(INTERP_KERNEL::Exception& e)
4363         {
4364           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4365           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4366           oss << ") : Evaluation of function failed !" << e.what();
4367           newArr->decrRef();
4368           throw INTERP_KERNEL::Exception(oss.str().c_str());
4369         }
4370     }
4371   return newArr;
4372 }
4373
4374 void DataArrayDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
4375 {
4376   checkAllocated();
4377   INTERP_KERNEL::ExprParser expr(func);
4378   expr.parse();
4379   char *funcStr=expr.compileX86();
4380   MYFUNCPTR funcPtr;
4381   *((void **)&funcPtr)=funcStr;//he he...
4382   //
4383   double *ptr=getPointer();
4384   int nbOfComp=getNumberOfComponents();
4385   int nbOfTuples=getNumberOfTuples();
4386   int nbOfElems=nbOfTuples*nbOfComp;
4387   for(int i=0;i<nbOfElems;i++,ptr++)
4388     *ptr=funcPtr(*ptr);
4389   declareAsNew();
4390 }
4391
4392 void DataArrayDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
4393 {
4394   checkAllocated();
4395   INTERP_KERNEL::ExprParser expr(func);
4396   expr.parse();
4397   char *funcStr=expr.compileX86_64();
4398   MYFUNCPTR funcPtr;
4399   *((void **)&funcPtr)=funcStr;//he he...
4400   //
4401   double *ptr=getPointer();
4402   int nbOfComp=getNumberOfComponents();
4403   int nbOfTuples=getNumberOfTuples();
4404   int nbOfElems=nbOfTuples*nbOfComp;
4405   for(int i=0;i<nbOfElems;i++,ptr++)
4406     *ptr=funcPtr(*ptr);
4407   declareAsNew();
4408 }
4409
4410 DataArrayDoubleIterator *DataArrayDouble::iterator() throw(INTERP_KERNEL::Exception)
4411 {
4412   return new DataArrayDoubleIterator(this);
4413 }
4414
4415 /*!
4416  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4417  * array whose values are within a given range. Textual data is not copied.
4418  *  \param [in] vmin - a lowest acceptable value (included).
4419  *  \param [in] vmax - a greatest acceptable value (included).
4420  *  \return DataArrayInt * - the new instance of DataArrayInt.
4421  *          The caller is to delete this result array using decrRef() as it is no more
4422  *          needed.
4423  *  \throw If \a this->getNumberOfComponents() != 1.
4424  *
4425  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4426  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4427  */
4428 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
4429 {
4430   checkAllocated();
4431   if(getNumberOfComponents()!=1)
4432     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4433   const double *cptr=getConstPointer();
4434   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
4435   int nbOfTuples=getNumberOfTuples();
4436   for(int i=0;i<nbOfTuples;i++,cptr++)
4437     if(*cptr>=vmin && *cptr<=vmax)
4438       ret->pushBackSilent(i);
4439   return ret.retn();
4440 }
4441
4442 /*!
4443  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4444  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4445  * the number of component in the result array is same as that of each of given arrays.
4446  * Info on components is copied from the first of the given arrays. Number of components
4447  * in the given arrays must be  the same.
4448  *  \param [in] a1 - an array to include in the result array.
4449  *  \param [in] a2 - another array to include in the result array.
4450  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4451  *          The caller is to delete this result array using decrRef() as it is no more
4452  *          needed.
4453  *  \throw If both \a a1 and \a a2 are NULL.
4454  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4455  */
4456 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4457 {
4458   std::vector<const DataArrayDouble *> tmp(2);
4459   tmp[0]=a1; tmp[1]=a2;
4460   return Aggregate(tmp);
4461 }
4462
4463 /*!
4464  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4465  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4466  * the number of component in the result array is same as that of each of given arrays.
4467  * Info on components is copied from the first of the given arrays. Number of components
4468  * in the given arrays must be  the same.
4469  *  \param [in] arr - a sequence of arrays to include in the result array.
4470  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4471  *          The caller is to delete this result array using decrRef() as it is no more
4472  *          needed.
4473  *  \throw If all arrays within \a arr are NULL.
4474  *  \throw If getNumberOfComponents() of arrays within \a arr.
4475  */
4476 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4477 {
4478   std::vector<const DataArrayDouble *> a;
4479   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4480     if(*it4)
4481       a.push_back(*it4);
4482   if(a.empty())
4483     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4484   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4485   int nbOfComp=(*it)->getNumberOfComponents();
4486   int nbt=(*it++)->getNumberOfTuples();
4487   for(int i=1;it!=a.end();it++,i++)
4488     {
4489       if((*it)->getNumberOfComponents()!=nbOfComp)
4490         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4491       nbt+=(*it)->getNumberOfTuples();
4492     }
4493   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4494   ret->alloc(nbt,nbOfComp);
4495   double *pt=ret->getPointer();
4496   for(it=a.begin();it!=a.end();it++)
4497     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4498   ret->copyStringInfoFrom(*(a[0]));
4499   return ret.retn();
4500 }
4501
4502 /*!
4503  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4504  * of components in the result array is a sum of the number of components of given arrays
4505  * and (2) the number of tuples in the result array is same as that of each of given
4506  * arrays. In other words the i-th tuple of result array includes all components of
4507  * i-th tuples of all given arrays.
4508  * Number of tuples in the given arrays must be  the same.
4509  *  \param [in] a1 - an array to include in the result array.
4510  *  \param [in] a2 - another array to include in the result array.
4511  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4512  *          The caller is to delete this result array using decrRef() as it is no more
4513  *          needed.
4514  *  \throw If both \a a1 and \a a2 are NULL.
4515  *  \throw If any given array is not allocated.
4516  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4517  */
4518 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4519 {
4520   std::vector<const DataArrayDouble *> arr(2);
4521   arr[0]=a1; arr[1]=a2;
4522   return Meld(arr);
4523 }
4524
4525 /*!
4526  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4527  * of components in the result array is a sum of the number of components of given arrays
4528  * and (2) the number of tuples in the result array is same as that of each of given
4529  * arrays. In other words the i-th tuple of result array includes all components of
4530  * i-th tuples of all given arrays.
4531  * Number of tuples in the given arrays must be  the same.
4532  *  \param [in] arr - a sequence of arrays to include in the result array.
4533  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4534  *          The caller is to delete this result array using decrRef() as it is no more
4535  *          needed.
4536  *  \throw If all arrays within \a arr are NULL.
4537  *  \throw If any given array is not allocated.
4538  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4539  */
4540 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4541 {
4542   std::vector<const DataArrayDouble *> a;
4543   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4544     if(*it4)
4545       a.push_back(*it4);
4546   if(a.empty())
4547     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4548   std::vector<const DataArrayDouble *>::const_iterator it;
4549   for(it=a.begin();it!=a.end();it++)
4550     (*it)->checkAllocated();
4551   it=a.begin();
4552   int nbOfTuples=(*it)->getNumberOfTuples();
4553   std::vector<int> nbc(a.size());
4554   std::vector<const double *> pts(a.size());
4555   nbc[0]=(*it)->getNumberOfComponents();
4556   pts[0]=(*it++)->getConstPointer();
4557   for(int i=1;it!=a.end();it++,i++)
4558     {
4559       if(nbOfTuples!=(*it)->getNumberOfTuples())
4560         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4561       nbc[i]=(*it)->getNumberOfComponents();
4562       pts[i]=(*it)->getConstPointer();
4563     }
4564   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4565   DataArrayDouble *ret=DataArrayDouble::New();
4566   ret->alloc(nbOfTuples,totalNbOfComp);
4567   double *retPtr=ret->getPointer();
4568   for(int i=0;i<nbOfTuples;i++)
4569     for(int j=0;j<(int)a.size();j++)
4570       {
4571         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4572         pts[j]+=nbc[j];
4573       }
4574   int k=0;
4575   for(int i=0;i<(int)a.size();i++)
4576     for(int j=0;j<nbc[i];j++,k++)
4577       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4578   return ret;
4579 }
4580
4581 /*!
4582  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4583  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4584  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4585  * Info on components and name is copied from the first of the given arrays.
4586  * Number of tuples and components in the given arrays must be the same.
4587  *  \param [in] a1 - a given array.
4588  *  \param [in] a2 - another given array.
4589  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4590  *          The caller is to delete this result array using decrRef() as it is no more
4591  *          needed.
4592  *  \throw If either \a a1 or \a a2 is NULL.
4593  *  \throw If any given array is not allocated.
4594  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4595  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4596  */
4597 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4598 {
4599   if(!a1 || !a2)
4600     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4601   a1->checkAllocated();
4602   a2->checkAllocated();
4603   int nbOfComp=a1->getNumberOfComponents();
4604   if(nbOfComp!=a2->getNumberOfComponents())
4605     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4606   int nbOfTuple=a1->getNumberOfTuples();
4607   if(nbOfTuple!=a2->getNumberOfTuples())
4608     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4609   DataArrayDouble *ret=DataArrayDouble::New();
4610   ret->alloc(nbOfTuple,1);
4611   double *retPtr=ret->getPointer();
4612   const double *a1Ptr=a1->getConstPointer();
4613   const double *a2Ptr=a2->getConstPointer();
4614   for(int i=0;i<nbOfTuple;i++)
4615     {
4616       double sum=0.;
4617       for(int j=0;j<nbOfComp;j++)
4618         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4619       retPtr[i]=sum;
4620     }
4621   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4622   ret->setName(a1->getName().c_str());
4623   return ret;
4624 }
4625
4626 /*!
4627  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4628  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4629  * product of two vectors defined by the i-th tuples of given arrays.
4630  * Info on components is copied from the first of the given arrays.
4631  * Number of tuples in the given arrays must be the same.
4632  * Number of components in the given arrays must be 3.
4633  *  \param [in] a1 - a given array.
4634  *  \param [in] a2 - another given array.
4635  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4636  *          The caller is to delete this result array using decrRef() as it is no more
4637  *          needed.
4638  *  \throw If either \a a1 or \a a2 is NULL.
4639  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4640  *  \throw If \a a1->getNumberOfComponents() != 3
4641  *  \throw If \a a2->getNumberOfComponents() != 3
4642  */
4643 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4644 {
4645   if(!a1 || !a2)
4646     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4647   int nbOfComp=a1->getNumberOfComponents();
4648   if(nbOfComp!=a2->getNumberOfComponents())
4649     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4650   if(nbOfComp!=3)
4651     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4652   int nbOfTuple=a1->getNumberOfTuples();
4653   if(nbOfTuple!=a2->getNumberOfTuples())
4654     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4655   DataArrayDouble *ret=DataArrayDouble::New();
4656   ret->alloc(nbOfTuple,3);
4657   double *retPtr=ret->getPointer();
4658   const double *a1Ptr=a1->getConstPointer();
4659   const double *a2Ptr=a2->getConstPointer();
4660   for(int i=0;i<nbOfTuple;i++)
4661     {
4662       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4663       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4664       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4665     }
4666   ret->copyStringInfoFrom(*a1);
4667   return ret;
4668 }
4669
4670 /*!
4671  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4672  * Info on components is copied from the first of the given arrays.
4673  * Number of tuples and components in the given arrays must be the same.
4674  *  \param [in] a1 - an array to compare values with another one.
4675  *  \param [in] a2 - another array to compare values with the first one.
4676  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4677  *          The caller is to delete this result array using decrRef() as it is no more
4678  *          needed.
4679  *  \throw If either \a a1 or \a a2 is NULL.
4680  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4681  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4682  */
4683 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4684 {
4685   if(!a1 || !a2)
4686     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4687   int nbOfComp=a1->getNumberOfComponents();
4688   if(nbOfComp!=a2->getNumberOfComponents())
4689     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4690   int nbOfTuple=a1->getNumberOfTuples();
4691   if(nbOfTuple!=a2->getNumberOfTuples())
4692     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4693   DataArrayDouble *ret=DataArrayDouble::New();
4694   ret->alloc(nbOfTuple,nbOfComp);
4695   double *retPtr=ret->getPointer();
4696   const double *a1Ptr=a1->getConstPointer();
4697   const double *a2Ptr=a2->getConstPointer();
4698   int nbElem=nbOfTuple*nbOfComp;
4699   for(int i=0;i<nbElem;i++)
4700     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4701   ret->copyStringInfoFrom(*a1);
4702   return ret;
4703 }
4704
4705 /*!
4706  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4707  * Info on components is copied from the first of the given arrays.
4708  * Number of tuples and components in the given arrays must be the same.
4709  *  \param [in] a1 - an array to compare values with another one.
4710  *  \param [in] a2 - another array to compare values with the first one.
4711  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4712  *          The caller is to delete this result array using decrRef() as it is no more
4713  *          needed.
4714  *  \throw If either \a a1 or \a a2 is NULL.
4715  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4716  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4717  */
4718 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4719 {
4720   if(!a1 || !a2)
4721     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4722   int nbOfComp=a1->getNumberOfComponents();
4723   if(nbOfComp!=a2->getNumberOfComponents())
4724     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4725   int nbOfTuple=a1->getNumberOfTuples();
4726   if(nbOfTuple!=a2->getNumberOfTuples())
4727     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4728   DataArrayDouble *ret=DataArrayDouble::New();
4729   ret->alloc(nbOfTuple,nbOfComp);
4730   double *retPtr=ret->getPointer();
4731   const double *a1Ptr=a1->getConstPointer();
4732   const double *a2Ptr=a2->getConstPointer();
4733   int nbElem=nbOfTuple*nbOfComp;
4734   for(int i=0;i<nbElem;i++)
4735     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4736   ret->copyStringInfoFrom(*a1);
4737   return ret;
4738 }
4739
4740 /*!
4741  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4742  * valid cases.
4743  * 1.  The arrays have same number of tuples and components. Then each value of
4744  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4745  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4746  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4747  *   component. Then
4748  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4749  * 3.  The arrays have same number of components and one array, say _a2_, has one
4750  *   tuple. Then
4751  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4752  *
4753  * Info on components is copied either from the first array (in the first case) or from
4754  * the array with maximal number of elements (getNbOfElems()).
4755  *  \param [in] a1 - an array to sum up.
4756  *  \param [in] a2 - another array to sum up.
4757  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4758  *          The caller is to delete this result array using decrRef() as it is no more
4759  *          needed.
4760  *  \throw If either \a a1 or \a a2 is NULL.
4761  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4762  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4763  *         none of them has number of tuples or components equal to 1.
4764  */
4765 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4766 {
4767   if(!a1 || !a2)
4768     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4769   int nbOfTuple=a1->getNumberOfTuples();
4770   int nbOfTuple2=a2->getNumberOfTuples();
4771   int nbOfComp=a1->getNumberOfComponents();
4772   int nbOfComp2=a2->getNumberOfComponents();
4773   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4774   if(nbOfTuple==nbOfTuple2)
4775     {
4776       if(nbOfComp==nbOfComp2)
4777         {
4778           ret=DataArrayDouble::New();
4779           ret->alloc(nbOfTuple,nbOfComp);
4780           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4781           ret->copyStringInfoFrom(*a1);
4782         }
4783       else
4784         {
4785           int nbOfCompMin,nbOfCompMax;
4786           const DataArrayDouble *aMin, *aMax;
4787           if(nbOfComp>nbOfComp2)
4788             {
4789               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4790               aMin=a2; aMax=a1;
4791             }
4792           else
4793             {
4794               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4795               aMin=a1; aMax=a2;
4796             }
4797           if(nbOfCompMin==1)
4798             {
4799               ret=DataArrayDouble::New();
4800               ret->alloc(nbOfTuple,nbOfCompMax);
4801               const double *aMinPtr=aMin->getConstPointer();
4802               const double *aMaxPtr=aMax->getConstPointer();
4803               double *res=ret->getPointer();
4804               for(int i=0;i<nbOfTuple;i++)
4805                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4806               ret->copyStringInfoFrom(*aMax);
4807             }
4808           else
4809             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4810         }
4811     }
4812   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4813     {
4814       if(nbOfComp==nbOfComp2)
4815         {
4816           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4817           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4818           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4819           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4820           ret=DataArrayDouble::New();
4821           ret->alloc(nbOfTupleMax,nbOfComp);
4822           double *res=ret->getPointer();
4823           for(int i=0;i<nbOfTupleMax;i++)
4824             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4825           ret->copyStringInfoFrom(*aMax);
4826         }
4827       else
4828         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4829     }
4830   else
4831     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4832   return ret.retn();
4833 }
4834
4835 /*!
4836  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4837  * valid cases.
4838  * 1.  The arrays have same number of tuples and components. Then each value of
4839  *   \a other array is added to the corresponding value of \a this array, i.e.:
4840  *   _a_ [ i, j ] += _other_ [ i, j ].
4841  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4842  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4843  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4844  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4845  *
4846  *  \param [in] other - an array to add to \a this one.
4847  *  \throw If \a other is NULL.
4848  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4849  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4850  *         \a other has number of both tuples and components not equal to 1.
4851  */
4852 void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4853 {
4854   if(!other)
4855     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4856   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4857   checkAllocated();
4858   other->checkAllocated();
4859   int nbOfTuple=getNumberOfTuples();
4860   int nbOfTuple2=other->getNumberOfTuples();
4861   int nbOfComp=getNumberOfComponents();
4862   int nbOfComp2=other->getNumberOfComponents();
4863   if(nbOfTuple==nbOfTuple2)
4864     {
4865       if(nbOfComp==nbOfComp2)
4866         {
4867           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4868         }
4869       else if(nbOfComp2==1)
4870         {
4871           double *ptr=getPointer();
4872           const double *ptrc=other->getConstPointer();
4873           for(int i=0;i<nbOfTuple;i++)
4874             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4875         }
4876       else
4877         throw INTERP_KERNEL::Exception(msg);
4878     }
4879   else if(nbOfTuple2==1)
4880     {
4881       if(nbOfComp2==nbOfComp)
4882         {
4883           double *ptr=getPointer();
4884           const double *ptrc=other->getConstPointer();
4885           for(int i=0;i<nbOfTuple;i++)
4886             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4887         }
4888       else
4889         throw INTERP_KERNEL::Exception(msg);
4890     }
4891   else
4892     throw INTERP_KERNEL::Exception(msg);
4893   declareAsNew();
4894 }
4895
4896 /*!
4897  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4898  * valid cases.
4899  * 1.  The arrays have same number of tuples and components. Then each value of
4900  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4901  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4902  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4903  *   component. Then
4904  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4905  * 3.  The arrays have same number of components and one array, say _a2_, has one
4906  *   tuple. Then
4907  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4908  *
4909  * Info on components is copied either from the first array (in the first case) or from
4910  * the array with maximal number of elements (getNbOfElems()).
4911  *  \param [in] a1 - an array to subtract from.
4912  *  \param [in] a2 - an array to subtract.
4913  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4914  *          The caller is to delete this result array using decrRef() as it is no more
4915  *          needed.
4916  *  \throw If either \a a1 or \a a2 is NULL.
4917  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4918  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4919  *         none of them has number of tuples or components equal to 1.
4920  */
4921 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4922 {
4923   if(!a1 || !a2)
4924     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
4925   int nbOfTuple1=a1->getNumberOfTuples();
4926   int nbOfTuple2=a2->getNumberOfTuples();
4927   int nbOfComp1=a1->getNumberOfComponents();
4928   int nbOfComp2=a2->getNumberOfComponents();
4929   if(nbOfTuple2==nbOfTuple1)
4930     {
4931       if(nbOfComp1==nbOfComp2)
4932         {
4933           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4934           ret->alloc(nbOfTuple2,nbOfComp1);
4935           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
4936           ret->copyStringInfoFrom(*a1);
4937           return ret.retn();
4938         }
4939       else if(nbOfComp2==1)
4940         {
4941           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4942           ret->alloc(nbOfTuple1,nbOfComp1);
4943           const double *a2Ptr=a2->getConstPointer();
4944           const double *a1Ptr=a1->getConstPointer();
4945           double *res=ret->getPointer();
4946           for(int i=0;i<nbOfTuple1;i++)
4947             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
4948           ret->copyStringInfoFrom(*a1);
4949           return ret.retn();
4950         }
4951       else
4952         {
4953           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4954           return 0;
4955         }
4956     }
4957   else if(nbOfTuple2==1)
4958     {
4959       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4960       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4961       ret->alloc(nbOfTuple1,nbOfComp1);
4962       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4963       double *pt=ret->getPointer();
4964       for(int i=0;i<nbOfTuple1;i++)
4965         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
4966       ret->copyStringInfoFrom(*a1);
4967       return ret.retn();
4968     }
4969   else
4970     {
4971       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
4972       return 0;
4973     }
4974 }
4975
4976 /*!
4977  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
4978  * valid cases.
4979  * 1.  The arrays have same number of tuples and components. Then each value of
4980  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
4981  *   _a_ [ i, j ] -= _other_ [ i, j ].
4982  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4983  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
4984  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4985  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
4986  *
4987  *  \param [in] other - an array to subtract from \a this one.
4988  *  \throw If \a other is NULL.
4989  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4990  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4991  *         \a other has number of both tuples and components not equal to 1.
4992  */
4993 void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4994 {
4995   if(!other)
4996     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
4997   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
4998   checkAllocated();
4999   other->checkAllocated();
5000   int nbOfTuple=getNumberOfTuples();
5001   int nbOfTuple2=other->getNumberOfTuples();
5002   int nbOfComp=getNumberOfComponents();
5003   int nbOfComp2=other->getNumberOfComponents();
5004   if(nbOfTuple==nbOfTuple2)
5005     {
5006       if(nbOfComp==nbOfComp2)
5007         {
5008           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5009         }
5010       else if(nbOfComp2==1)
5011         {
5012           double *ptr=getPointer();
5013           const double *ptrc=other->getConstPointer();
5014           for(int i=0;i<nbOfTuple;i++)
5015             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5016         }
5017       else
5018         throw INTERP_KERNEL::Exception(msg);
5019     }
5020   else if(nbOfTuple2==1)
5021     {
5022       if(nbOfComp2==nbOfComp)
5023         {
5024           double *ptr=getPointer();
5025           const double *ptrc=other->getConstPointer();
5026           for(int i=0;i<nbOfTuple;i++)
5027             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5028         }
5029       else
5030         throw INTERP_KERNEL::Exception(msg);
5031     }
5032   else
5033     throw INTERP_KERNEL::Exception(msg);
5034   declareAsNew();
5035 }
5036
5037 /*!
5038  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5039  * valid cases.
5040  * 1.  The arrays have same number of tuples and components. Then each value of
5041  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5042  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5043  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5044  *   component. Then
5045  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5046  * 3.  The arrays have same number of components and one array, say _a2_, has one
5047  *   tuple. Then
5048  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5049  *
5050  * Info on components is copied either from the first array (in the first case) or from
5051  * the array with maximal number of elements (getNbOfElems()).
5052  *  \param [in] a1 - a factor array.
5053  *  \param [in] a2 - another factor array.
5054  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5055  *          The caller is to delete this result array using decrRef() as it is no more
5056  *          needed.
5057  *  \throw If either \a a1 or \a a2 is NULL.
5058  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5059  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5060  *         none of them has number of tuples or components equal to 1.
5061  */
5062 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5063 {
5064   if(!a1 || !a2)
5065     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5066   int nbOfTuple=a1->getNumberOfTuples();
5067   int nbOfTuple2=a2->getNumberOfTuples();
5068   int nbOfComp=a1->getNumberOfComponents();
5069   int nbOfComp2=a2->getNumberOfComponents();
5070   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5071   if(nbOfTuple==nbOfTuple2)
5072     {
5073       if(nbOfComp==nbOfComp2)
5074         {
5075           ret=DataArrayDouble::New();
5076           ret->alloc(nbOfTuple,nbOfComp);
5077           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5078           ret->copyStringInfoFrom(*a1);
5079         }
5080       else
5081         {
5082           int nbOfCompMin,nbOfCompMax;
5083           const DataArrayDouble *aMin, *aMax;
5084           if(nbOfComp>nbOfComp2)
5085             {
5086               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5087               aMin=a2; aMax=a1;
5088             }
5089           else
5090             {
5091               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5092               aMin=a1; aMax=a2;
5093             }
5094           if(nbOfCompMin==1)
5095             {
5096               ret=DataArrayDouble::New();
5097               ret->alloc(nbOfTuple,nbOfCompMax);
5098               const double *aMinPtr=aMin->getConstPointer();
5099               const double *aMaxPtr=aMax->getConstPointer();
5100               double *res=ret->getPointer();
5101               for(int i=0;i<nbOfTuple;i++)
5102                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5103               ret->copyStringInfoFrom(*aMax);
5104             }
5105           else
5106             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5107         }
5108     }
5109   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5110     {
5111       if(nbOfComp==nbOfComp2)
5112         {
5113           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5114           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5115           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5116           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5117           ret=DataArrayDouble::New();
5118           ret->alloc(nbOfTupleMax,nbOfComp);
5119           double *res=ret->getPointer();
5120           for(int i=0;i<nbOfTupleMax;i++)
5121             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5122           ret->copyStringInfoFrom(*aMax);
5123         }
5124       else
5125         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5126     }
5127   else
5128     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5129   return ret.retn();
5130 }
5131
5132 /*!
5133  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5134  * valid cases.
5135  * 1.  The arrays have same number of tuples and components. Then each value of
5136  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5137  *   _this_ [ i, j ] *= _other_ [ i, j ].
5138  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5139  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5140  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5141  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5142  *
5143  *  \param [in] other - an array to multiply to \a this one.
5144  *  \throw If \a other is NULL.
5145  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5146  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5147  *         \a other has number of both tuples and components not equal to 1.
5148  */
5149 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5150 {
5151   if(!other)
5152     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5153   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5154   checkAllocated();
5155   other->checkAllocated();
5156   int nbOfTuple=getNumberOfTuples();
5157   int nbOfTuple2=other->getNumberOfTuples();
5158   int nbOfComp=getNumberOfComponents();
5159   int nbOfComp2=other->getNumberOfComponents();
5160   if(nbOfTuple==nbOfTuple2)
5161     {
5162       if(nbOfComp==nbOfComp2)
5163         {
5164           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5165         }
5166       else if(nbOfComp2==1)
5167         {
5168           double *ptr=getPointer();
5169           const double *ptrc=other->getConstPointer();
5170           for(int i=0;i<nbOfTuple;i++)
5171             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5172         }
5173       else
5174         throw INTERP_KERNEL::Exception(msg);
5175     }
5176   else if(nbOfTuple2==1)
5177     {
5178       if(nbOfComp2==nbOfComp)
5179         {
5180           double *ptr=getPointer();
5181           const double *ptrc=other->getConstPointer();
5182           for(int i=0;i<nbOfTuple;i++)
5183             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5184         }
5185       else
5186         throw INTERP_KERNEL::Exception(msg);
5187     }
5188   else
5189     throw INTERP_KERNEL::Exception(msg);
5190   declareAsNew();
5191 }
5192
5193 /*!
5194  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5195  * valid cases.
5196  * 1.  The arrays have same number of tuples and components. Then each value of
5197  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5198  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5199  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5200  *   component. Then
5201  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5202  * 3.  The arrays have same number of components and one array, say _a2_, has one
5203  *   tuple. Then
5204  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5205  *
5206  * Info on components is copied either from the first array (in the first case) or from
5207  * the array with maximal number of elements (getNbOfElems()).
5208  *  \warning No check of division by zero is performed!
5209  *  \param [in] a1 - a numerator array.
5210  *  \param [in] a2 - a denominator array.
5211  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5212  *          The caller is to delete this result array using decrRef() as it is no more
5213  *          needed.
5214  *  \throw If either \a a1 or \a a2 is NULL.
5215  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5216  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5217  *         none of them has number of tuples or components equal to 1.
5218  */
5219 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5220 {
5221   if(!a1 || !a2)
5222     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5223   int nbOfTuple1=a1->getNumberOfTuples();
5224   int nbOfTuple2=a2->getNumberOfTuples();
5225   int nbOfComp1=a1->getNumberOfComponents();
5226   int nbOfComp2=a2->getNumberOfComponents();
5227   if(nbOfTuple2==nbOfTuple1)
5228     {
5229       if(nbOfComp1==nbOfComp2)
5230         {
5231           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5232           ret->alloc(nbOfTuple2,nbOfComp1);
5233           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5234           ret->copyStringInfoFrom(*a1);
5235           return ret.retn();
5236         }
5237       else if(nbOfComp2==1)
5238         {
5239           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5240           ret->alloc(nbOfTuple1,nbOfComp1);
5241           const double *a2Ptr=a2->getConstPointer();
5242           const double *a1Ptr=a1->getConstPointer();
5243           double *res=ret->getPointer();
5244           for(int i=0;i<nbOfTuple1;i++)
5245             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5246           ret->copyStringInfoFrom(*a1);
5247           return ret.retn();
5248         }
5249       else
5250         {
5251           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5252           return 0;
5253         }
5254     }
5255   else if(nbOfTuple2==1)
5256     {
5257       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5258       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5259       ret->alloc(nbOfTuple1,nbOfComp1);
5260       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5261       double *pt=ret->getPointer();
5262       for(int i=0;i<nbOfTuple1;i++)
5263         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5264       ret->copyStringInfoFrom(*a1);
5265       return ret.retn();
5266     }
5267   else
5268     {
5269       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5270       return 0;
5271     }
5272 }
5273
5274 /*!
5275  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5276  * valid cases.
5277  * 1.  The arrays have same number of tuples and components. Then each value of
5278  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5279  *   _a_ [ i, j ] /= _other_ [ i, j ].
5280  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5281  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5282  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5283  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5284  *
5285  *  \warning No check of division by zero is performed!
5286  *  \param [in] other - an array to divide \a this one by.
5287  *  \throw If \a other is NULL.
5288  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5289  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5290  *         \a other has number of both tuples and components not equal to 1.
5291  */
5292 void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5293 {
5294   if(!other)
5295     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5296   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5297   checkAllocated();
5298   other->checkAllocated();
5299   int nbOfTuple=getNumberOfTuples();
5300   int nbOfTuple2=other->getNumberOfTuples();
5301   int nbOfComp=getNumberOfComponents();
5302   int nbOfComp2=other->getNumberOfComponents();
5303   if(nbOfTuple==nbOfTuple2)
5304     {
5305       if(nbOfComp==nbOfComp2)
5306         {
5307           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5308         }
5309       else if(nbOfComp2==1)
5310         {
5311           double *ptr=getPointer();
5312           const double *ptrc=other->getConstPointer();
5313           for(int i=0;i<nbOfTuple;i++)
5314             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5315         }
5316       else
5317         throw INTERP_KERNEL::Exception(msg);
5318     }
5319   else if(nbOfTuple2==1)
5320     {
5321       if(nbOfComp2==nbOfComp)
5322         {
5323           double *ptr=getPointer();
5324           const double *ptrc=other->getConstPointer();
5325           for(int i=0;i<nbOfTuple;i++)
5326             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5327         }
5328       else
5329         throw INTERP_KERNEL::Exception(msg);
5330     }
5331   else
5332     throw INTERP_KERNEL::Exception(msg);
5333   declareAsNew();
5334 }
5335
5336 /*!
5337  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5338  * valid cases.
5339  *
5340  *  \param [in] a1 - an array to pow up.
5341  *  \param [in] a2 - another array to sum up.
5342  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5343  *          The caller is to delete this result array using decrRef() as it is no more
5344  *          needed.
5345  *  \throw If either \a a1 or \a a2 is NULL.
5346  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5347  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5348  *  \throw If there is a negative value in \a a1.
5349  */
5350 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5351 {
5352   if(!a1 || !a2)
5353     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5354   int nbOfTuple=a1->getNumberOfTuples();
5355   int nbOfTuple2=a2->getNumberOfTuples();
5356   int nbOfComp=a1->getNumberOfComponents();
5357   int nbOfComp2=a2->getNumberOfComponents();
5358   if(nbOfTuple!=nbOfTuple2)
5359     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5360   if(nbOfComp!=1 || nbOfComp2!=1)
5361     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5362   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5363   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5364   double *ptr=ret->getPointer();
5365   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5366     {
5367       if(*ptr1>=0)
5368         {
5369           *ptr=pow(*ptr1,*ptr2);
5370         }
5371       else
5372         {
5373           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5374           throw INTERP_KERNEL::Exception(oss.str().c_str());
5375         }
5376     }
5377   return ret.retn();
5378 }
5379
5380 /*!
5381  * Apply pow on values of another DataArrayDouble to values of \a this one.
5382  *
5383  *  \param [in] other - an array to pow to \a this one.
5384  *  \throw If \a other is NULL.
5385  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5386  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5387  *  \throw If there is a negative value in \a this.
5388  */
5389 void DataArrayDouble::powEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5390 {
5391   if(!other)
5392     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5393   int nbOfTuple=getNumberOfTuples();
5394   int nbOfTuple2=other->getNumberOfTuples();
5395   int nbOfComp=getNumberOfComponents();
5396   int nbOfComp2=other->getNumberOfComponents();
5397   if(nbOfTuple!=nbOfTuple2)
5398     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5399   if(nbOfComp!=1 || nbOfComp2!=1)
5400     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5401   double *ptr=getPointer();
5402   const double *ptrc=other->begin();
5403   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5404     {
5405       if(*ptr>=0)
5406         *ptr=pow(*ptr,*ptrc);
5407       else
5408         {
5409           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5410           throw INTERP_KERNEL::Exception(oss.str().c_str());
5411         }
5412     }
5413   declareAsNew();
5414 }
5415
5416 /*!
5417  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5418  * Server side.
5419  */
5420 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5421 {
5422   tinyInfo.resize(2);
5423   if(isAllocated())
5424     {
5425       tinyInfo[0]=getNumberOfTuples();
5426       tinyInfo[1]=getNumberOfComponents();
5427     }
5428   else
5429     {
5430       tinyInfo[0]=-1;
5431       tinyInfo[1]=-1;
5432     }
5433 }
5434
5435 /*!
5436  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5437  * Server side.
5438  */
5439 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5440 {
5441   if(isAllocated())
5442     {
5443       int nbOfCompo=getNumberOfComponents();
5444       tinyInfo.resize(nbOfCompo+1);
5445       tinyInfo[0]=getName();
5446       for(int i=0;i<nbOfCompo;i++)
5447         tinyInfo[i+1]=getInfoOnComponent(i);
5448     }
5449   else
5450     {
5451       tinyInfo.resize(1);
5452       tinyInfo[0]=getName();
5453     }
5454 }
5455
5456 /*!
5457  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5458  * This method returns if a feeding is needed.
5459  */
5460 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5461 {
5462   int nbOfTuple=tinyInfoI[0];
5463   int nbOfComp=tinyInfoI[1];
5464   if(nbOfTuple!=-1 || nbOfComp!=-1)
5465     {
5466       alloc(nbOfTuple,nbOfComp);
5467       return true;
5468     }
5469   return false;
5470 }
5471
5472 /*!
5473  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5474  */
5475 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5476 {
5477   setName(tinyInfoS[0].c_str());
5478   if(isAllocated())
5479     {
5480       int nbOfCompo=getNumberOfComponents();
5481       for(int i=0;i<nbOfCompo;i++)
5482         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
5483     }
5484 }
5485
5486 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5487 {
5488   if(_da)
5489     {
5490       _da->incrRef();
5491       if(_da->isAllocated())
5492         {
5493           _nb_comp=da->getNumberOfComponents();
5494           _nb_tuple=da->getNumberOfTuples();
5495           _pt=da->getPointer();
5496         }
5497     }
5498 }
5499
5500 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5501 {
5502   if(_da)
5503     _da->decrRef();
5504 }
5505
5506 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() throw(INTERP_KERNEL::Exception)
5507 {
5508   if(_tuple_id<_nb_tuple)
5509     {
5510       _tuple_id++;
5511       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5512       _pt+=_nb_comp;
5513       return ret;
5514     }
5515   else
5516     return 0;
5517 }
5518
5519 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5520 {
5521 }
5522
5523
5524 std::string DataArrayDoubleTuple::repr() const throw(INTERP_KERNEL::Exception)
5525 {
5526   std::ostringstream oss; oss.precision(17); oss << "(";
5527   for(int i=0;i<_nb_of_compo-1;i++)
5528     oss << _pt[i] << ", ";
5529   oss << _pt[_nb_of_compo-1] << ")";
5530   return oss.str();
5531 }
5532
5533 double DataArrayDoubleTuple::doubleValue() const throw(INTERP_KERNEL::Exception)
5534 {
5535   if(_nb_of_compo==1)
5536     return *_pt;
5537   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5538 }
5539
5540 /*!
5541  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5542  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5543  * 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
5544  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5545  */
5546 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
5547 {
5548   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5549     {
5550       DataArrayDouble *ret=DataArrayDouble::New();
5551       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5552       return ret;
5553     }
5554   else
5555     {
5556       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5557       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5558       throw INTERP_KERNEL::Exception(oss.str().c_str());
5559     }
5560 }
5561
5562 /*!
5563  * Returns a new instance of DataArrayInt. The caller is to delete this array
5564  * using decrRef() as it is no more needed. 
5565  */
5566 DataArrayInt *DataArrayInt::New()
5567 {
5568   return new DataArrayInt;
5569 }
5570
5571 /*!
5572  * Checks if raw data is allocated. Read more on the raw data
5573  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5574  *  \return bool - \a true if the raw data is allocated, \a false else.
5575  */
5576 bool DataArrayInt::isAllocated() const throw(INTERP_KERNEL::Exception)
5577 {
5578   return getConstPointer()!=0;
5579 }
5580
5581 /*!
5582  * Checks if raw data is allocated and throws an exception if it is not the case.
5583  *  \throw If the raw data is not allocated.
5584  */
5585 void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception)
5586 {
5587   if(!isAllocated())
5588     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5589 }
5590
5591 /*!
5592  * This method desallocated \a this without modification of informations relative to the components.
5593  * After call of this method, DataArrayInt::isAllocated will return false.
5594  * If \a this is already not allocated, \a this is let unchanged.
5595  */
5596 void DataArrayInt::desallocate() throw(INTERP_KERNEL::Exception)
5597 {
5598   _mem.destroy();
5599 }
5600
5601 std::size_t DataArrayInt::getHeapMemorySize() const
5602 {
5603   std::size_t sz=_mem.getNbOfElemAllocated();
5604   sz*=sizeof(int);
5605   return DataArray::getHeapMemorySize()+sz;
5606 }
5607
5608 /*!
5609  * Returns the only one value in \a this, if and only if number of elements
5610  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5611  *  \return double - the sole value stored in \a this array.
5612  *  \throw If at least one of conditions stated above is not fulfilled.
5613  */
5614 int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception)
5615 {
5616   if(isAllocated())
5617     {
5618       if(getNbOfElems()==1)
5619         {
5620           return *getConstPointer();
5621         }
5622       else
5623         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5624     }
5625   else
5626     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5627 }
5628
5629 /*!
5630  * Returns an integer value characterizing \a this array, which is useful for a quick
5631  * comparison of many instances of DataArrayInt.
5632  *  \return int - the hash value.
5633  *  \throw If \a this is not allocated.
5634  */
5635 int DataArrayInt::getHashCode() const throw(INTERP_KERNEL::Exception)
5636 {
5637   checkAllocated();
5638   std::size_t nbOfElems=getNbOfElems();
5639   int ret=nbOfElems*65536;
5640   int delta=3;
5641   if(nbOfElems>48)
5642     delta=nbOfElems/8;
5643   int ret0=0;
5644   const int *pt=begin();
5645   for(std::size_t i=0;i<nbOfElems;i+=delta)
5646     ret0+=pt[i] & 0x1FFF;
5647   return ret+ret0;
5648 }
5649
5650 /*!
5651  * Checks the number of tuples.
5652  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5653  *  \throw If \a this is not allocated.
5654  */
5655 bool DataArrayInt::empty() const throw(INTERP_KERNEL::Exception)
5656 {
5657   checkAllocated();
5658   return getNumberOfTuples()==0;
5659 }
5660
5661 /*!
5662  * Returns a full copy of \a this. For more info on copying data arrays see
5663  * \ref MEDCouplingArrayBasicsCopyDeep.
5664  *  \return DataArrayInt * - a new instance of DataArrayInt.
5665  */
5666 DataArrayInt *DataArrayInt::deepCpy() const throw(INTERP_KERNEL::Exception)
5667 {
5668   return new DataArrayInt(*this);
5669 }
5670
5671 /*!
5672  * Returns either a \a deep or \a shallow copy of this array. For more info see
5673  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5674  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5675  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5676  *          == \a true) or \a this instance (if \a dCpy == \a false).
5677  */
5678 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
5679 {
5680   if(dCpy)
5681     return deepCpy();
5682   else
5683     {
5684       incrRef();
5685       return const_cast<DataArrayInt *>(this);
5686     }
5687 }
5688
5689 /*!
5690  * Copies all the data from another DataArrayInt. For more info see
5691  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5692  *  \param [in] other - another instance of DataArrayInt to copy data from.
5693  *  \throw If the \a other is not allocated.
5694  */
5695 void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception)
5696 {
5697   other.checkAllocated();
5698   int nbOfTuples=other.getNumberOfTuples();
5699   int nbOfComp=other.getNumberOfComponents();
5700   allocIfNecessary(nbOfTuples,nbOfComp);
5701   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5702   int *pt=getPointer();
5703   const int *ptI=other.getConstPointer();
5704   for(std::size_t i=0;i<nbOfElems;i++)
5705     pt[i]=ptI[i];
5706   copyStringInfoFrom(other);
5707 }
5708
5709 /*!
5710  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5711  * 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.
5712  * If \a this has not already been allocated, number of components is set to one.
5713  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5714  * 
5715  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5716  */
5717 void DataArrayInt::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
5718 {
5719   int nbCompo=getNumberOfComponents();
5720   if(nbCompo==1)
5721     {
5722       _mem.reserve(nbOfElems);
5723     }
5724   else if(nbCompo==0)
5725     {
5726       _mem.reserve(nbOfElems);
5727       _info_on_compo.resize(1);
5728     }
5729   else
5730     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5731 }
5732
5733 /*!
5734  * 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
5735  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5736  *
5737  * \param [in] val the value to be added in \a this
5738  * \throw If \a this has already been allocated with number of components different from one.
5739  * \sa DataArrayInt::pushBackValsSilent
5740  */
5741 void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception)
5742 {
5743   int nbCompo=getNumberOfComponents();
5744   if(nbCompo==1)
5745     _mem.pushBack(val);
5746   else if(nbCompo==0)
5747     {
5748       _info_on_compo.resize(1);
5749       _mem.pushBack(val);
5750     }
5751   else
5752     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5753 }
5754
5755 /*!
5756  * 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
5757  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5758  *
5759  *  \param [in] valsBg - an array of values to push at the end of \this.
5760  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5761  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5762  * \throw If \a this has already been allocated with number of components different from one.
5763  * \sa DataArrayInt::pushBackSilent
5764  */
5765 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd) throw(INTERP_KERNEL::Exception)
5766 {
5767   int nbCompo=getNumberOfComponents();
5768   if(nbCompo==1)
5769     _mem.insertAtTheEnd(valsBg,valsEnd);
5770   else if(nbCompo==0)
5771     {
5772       _info_on_compo.resize(1);
5773       _mem.insertAtTheEnd(valsBg,valsEnd);
5774     }
5775   else
5776     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5777 }
5778
5779 /*!
5780  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5781  * \throw If \a this is already empty.
5782  * \throw If \a this has number of components different from one.
5783  */
5784 int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception)
5785 {
5786   if(getNumberOfComponents()==1)
5787     return _mem.popBack();
5788   else
5789     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5790 }
5791
5792 /*!
5793  * 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.
5794  *
5795  * \sa DataArrayInt::getHeapMemorySize, DataArrayInt::reserve
5796  */
5797 void DataArrayInt::pack() const throw(INTERP_KERNEL::Exception)
5798 {
5799   _mem.pack();
5800 }
5801
5802 /*!
5803  * Allocates the raw data in memory. If exactly as same memory as needed already
5804  * allocated, it is not re-allocated.
5805  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5806  *  \param [in] nbOfCompo - number of components of data to allocate.
5807  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5808  */
5809 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5810 {
5811   if(isAllocated())
5812     {
5813       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5814         alloc(nbOfTuple,nbOfCompo);
5815     }
5816   else
5817     alloc(nbOfTuple,nbOfCompo);
5818 }
5819
5820 /*!
5821  * Allocates the raw data in memory. If the memory was already allocated, then it is
5822  * freed and re-allocated. See an example of this method use
5823  * \ref MEDCouplingArraySteps1WC "here".
5824  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5825  *  \param [in] nbOfCompo - number of components of data to allocate.
5826  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5827  */
5828 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5829 {
5830   if(nbOfTuple<0 || nbOfCompo<0)
5831     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5832   _info_on_compo.resize(nbOfCompo);
5833   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
5834   declareAsNew();
5835 }
5836
5837 /*!
5838  * Assign zero to all values in \a this array. To know more on filling arrays see
5839  * \ref MEDCouplingArrayFill.
5840  * \throw If \a this is not allocated.
5841  */
5842 void DataArrayInt::fillWithZero() throw(INTERP_KERNEL::Exception)
5843 {
5844   checkAllocated();
5845   _mem.fillWithValue(0);
5846   declareAsNew();
5847 }
5848
5849 /*!
5850  * Assign \a val to all values in \a this array. To know more on filling arrays see
5851  * \ref MEDCouplingArrayFill.
5852  *  \param [in] val - the value to fill with.
5853  *  \throw If \a this is not allocated.
5854  */
5855 void DataArrayInt::fillWithValue(int val) throw(INTERP_KERNEL::Exception)
5856 {
5857   checkAllocated();
5858   _mem.fillWithValue(val);
5859   declareAsNew();
5860 }
5861
5862 /*!
5863  * Set all values in \a this array so that the i-th element equals to \a init + i
5864  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5865  *  \param [in] init - value to assign to the first element of array.
5866  *  \throw If \a this->getNumberOfComponents() != 1
5867  *  \throw If \a this is not allocated.
5868  */
5869 void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception)
5870 {
5871   checkAllocated();
5872   if(getNumberOfComponents()!=1)
5873     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5874   int *ptr=getPointer();
5875   int ntuples=getNumberOfTuples();
5876   for(int i=0;i<ntuples;i++)
5877     ptr[i]=init+i;
5878   declareAsNew();
5879 }
5880
5881 /*!
5882  * Returns a textual and human readable representation of \a this instance of
5883  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5884  *  \return std::string - text describing \a this DataArrayInt.
5885  */
5886 std::string DataArrayInt::repr() const throw(INTERP_KERNEL::Exception)
5887 {
5888   std::ostringstream ret;
5889   reprStream(ret);
5890   return ret.str();
5891 }
5892
5893 std::string DataArrayInt::reprZip() const throw(INTERP_KERNEL::Exception)
5894 {
5895   std::ostringstream ret;
5896   reprZipStream(ret);
5897   return ret.str();
5898 }
5899
5900 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
5901 {
5902   checkAllocated();
5903   std::string idt(indent,' ');
5904   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5905   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
5906   std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
5907   ofs << std::endl << idt << "</DataArray>\n";
5908 }
5909
5910 void DataArrayInt::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5911 {
5912   stream << "Name of int array : \"" << _name << "\"\n";
5913   reprWithoutNameStream(stream);
5914 }
5915
5916 void DataArrayInt::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5917 {
5918   stream << "Name of int array : \"" << _name << "\"\n";
5919   reprZipWithoutNameStream(stream);
5920 }
5921
5922 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5923 {
5924   DataArray::reprWithoutNameStream(stream);
5925   _mem.repr(getNumberOfComponents(),stream);
5926 }
5927
5928 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5929 {
5930   DataArray::reprWithoutNameStream(stream);
5931   _mem.reprZip(getNumberOfComponents(),stream);
5932 }
5933
5934 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5935 {
5936   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
5937   const int *data=getConstPointer();
5938   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
5939   if(nbTuples*nbComp>=1)
5940     {
5941       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
5942       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
5943       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
5944       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
5945     }
5946   else
5947     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
5948   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
5949 }
5950
5951 /*!
5952  * Method that gives a quick overvien of \a this for python.
5953  */
5954 void DataArrayInt::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5955 {
5956   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
5957   stream << "DataArrayInt C++ instance at " << this << ". ";
5958   if(isAllocated())
5959     {
5960       int nbOfCompo=(int)_info_on_compo.size();
5961       if(nbOfCompo>=1)
5962         {
5963           int nbOfTuples=getNumberOfTuples();
5964           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
5965           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
5966         }
5967       else
5968         stream << "Number of components : 0.";
5969     }
5970   else
5971     stream << "*** No data allocated ****";
5972 }
5973
5974 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
5975 {
5976   const int *data=begin();
5977   int nbOfTuples=getNumberOfTuples();
5978   int nbOfCompo=(int)_info_on_compo.size();
5979   std::ostringstream oss2; oss2 << "[";
5980   std::string oss2Str(oss2.str());
5981   bool isFinished=true;
5982   for(int i=0;i<nbOfTuples && isFinished;i++)
5983     {
5984       if(nbOfCompo>1)
5985         {
5986           oss2 << "(";
5987           for(int j=0;j<nbOfCompo;j++,data++)
5988             {
5989               oss2 << *data;
5990               if(j!=nbOfCompo-1) oss2 << ", ";
5991             }
5992           oss2 << ")";
5993         }
5994       else
5995         oss2 << *data++;
5996       if(i!=nbOfTuples-1) oss2 << ", ";
5997       std::string oss3Str(oss2.str());
5998       if(oss3Str.length()<maxNbOfByteInRepr)
5999         oss2Str=oss3Str;
6000       else
6001         isFinished=false;
6002     }
6003   stream << oss2Str;
6004   if(!isFinished)
6005     stream << "... ";
6006   stream << "]";
6007 }
6008
6009 /*!
6010  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6011  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6012  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6013  *         to \a this array.
6014  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6015  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6016  *  \throw If \a this->getNumberOfComponents() != 1
6017  *  \throw If any value of \a this can't be used as a valid index for 
6018  *         [\a indArrBg, \a indArrEnd).
6019  */
6020 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception)
6021 {
6022   checkAllocated();
6023   if(getNumberOfComponents()!=1)
6024     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6025   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6026   int nbOfTuples=getNumberOfTuples();
6027   int *pt=getPointer();
6028   for(int i=0;i<nbOfTuples;i++,pt++)
6029     {
6030       if(*pt>=0 && *pt<nbElemsIn)
6031         *pt=indArrBg[*pt];
6032       else
6033         {
6034           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6035           throw INTERP_KERNEL::Exception(oss.str().c_str());
6036         }
6037     }
6038   declareAsNew();
6039 }
6040
6041 /*!
6042  * Computes distribution of values of \a this one-dimensional array between given value
6043  * ranges (casts). This method is typically useful for entity number spliting by types,
6044  * for example. 
6045  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6046  *           check of this is be done. If not, the result is not warranted. 
6047  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6048  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6049  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6050  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6051  *         should be more than every value in \a this array.
6052  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6053  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6054  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6055  *         (same number of tuples and components), the caller is to delete 
6056  *         using decrRef() as it is no more needed.
6057  *         This array contains indices of ranges for every value of \a this array. I.e.
6058  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6059  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6060  *         this in which cast it holds.
6061  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6062  *         array, the caller is to delete using decrRef() as it is no more needed.
6063  *         This array contains ranks of values of \a this array within ranges
6064  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6065  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6066  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6067  *         for each tuple its rank inside its cast. The rank is computed as difference
6068  *         between the value and the lowest value of range.
6069  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6070  *         ranges (casts) to which at least one value of \a this array belongs.
6071  *         Or, in other words, this param contains the casts that \a this contains.
6072  *         The caller is to delete this array using decrRef() as it is no more needed.
6073  *
6074  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6075  *            the output of this method will be : 
6076  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6077  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6078  * - \a castsPresent  : [0,1]
6079  *
6080  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6081  * range #1 and its rank within this range is 2; etc.
6082  *
6083  *  \throw If \a this->getNumberOfComponents() != 1.
6084  *  \throw If \a arrEnd - arrBg < 2.
6085  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6086  */
6087 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6088                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
6089 {
6090   checkAllocated();
6091   if(getNumberOfComponents()!=1)
6092     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6093   int nbOfTuples=getNumberOfTuples();
6094   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6095   if(nbOfCast<2)
6096     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6097   nbOfCast--;
6098   const int *work=getConstPointer();
6099   typedef std::reverse_iterator<const int *> rintstart;
6100   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6101   rintstart end2(arrBg);
6102   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6103   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6104   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6105   ret1->alloc(nbOfTuples,1);
6106   ret2->alloc(nbOfTuples,1);
6107   int *ret1Ptr=ret1->getPointer();
6108   int *ret2Ptr=ret2->getPointer();
6109   std::set<std::size_t> castsDetected;
6110   for(int i=0;i<nbOfTuples;i++)
6111     {
6112       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6113       std::size_t pos=std::distance(bg,res);
6114       std::size_t pos2=nbOfCast-pos;
6115       if(pos2<nbOfCast)
6116         {
6117           ret1Ptr[i]=(int)pos2;
6118           ret2Ptr[i]=work[i]-arrBg[pos2];
6119           castsDetected.insert(pos2);
6120         }
6121       else
6122         {
6123           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6124           throw INTERP_KERNEL::Exception(oss.str().c_str());
6125         }
6126     }
6127   ret3->alloc((int)castsDetected.size(),1);
6128   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6129   castArr=ret1.retn();
6130   rankInsideCast=ret2.retn();
6131   castsPresent=ret3.retn();
6132 }
6133
6134 /*!
6135  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6136  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6137  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6138  * new value in place \a indArr[ \a v ] is i.
6139  *  \param [in] indArrBg - the array holding indices within the result array to assign
6140  *         indices of values of \a this array pointing to values of \a indArrBg.
6141  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6142  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6143  *  \return DataArrayInt * - the new instance of DataArrayInt.
6144  *          The caller is to delete this result array using decrRef() as it is no more
6145  *          needed.
6146  *  \throw If \a this->getNumberOfComponents() != 1.
6147  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6148  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6149  */
6150 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception)
6151 {
6152   checkAllocated();
6153   if(getNumberOfComponents()!=1)
6154     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6155   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6156   int nbOfTuples=getNumberOfTuples();
6157   const int *pt=getConstPointer();
6158   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6159   ret->alloc(nbOfTuples,1);
6160   ret->fillWithValue(-1);
6161   int *tmp=ret->getPointer();
6162   for(int i=0;i<nbOfTuples;i++,pt++)
6163     {
6164       if(*pt>=0 && *pt<nbElemsIn)
6165         {
6166           int pos=indArrBg[*pt];
6167           if(pos>=0 && pos<nbOfTuples)
6168             tmp[pos]=i;
6169           else
6170             {
6171               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6172               throw INTERP_KERNEL::Exception(oss.str().c_str());
6173             }
6174         }
6175       else
6176         {
6177           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6178           throw INTERP_KERNEL::Exception(oss.str().c_str());
6179         }
6180     }
6181   return ret.retn();
6182 }
6183
6184 /*!
6185  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6186  * from values of \a this array, which is supposed to contain a renumbering map in 
6187  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6188  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6189  *  \param [in] newNbOfElem - the number of tuples in the result array.
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  * 
6194  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6195  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6196  */
6197 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6198 {
6199   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6200   ret->alloc(newNbOfElem,1);
6201   int nbOfOldNodes=getNumberOfTuples();
6202   const int *old2New=getConstPointer();
6203   int *pt=ret->getPointer();
6204   for(int i=0;i!=nbOfOldNodes;i++)
6205     {
6206       int newp(old2New[i]);
6207       if(newp!=-1)
6208         {
6209           if(newp>=0 && newp<newNbOfElem)
6210             pt[newp]=i;
6211           else
6212             {
6213               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6214               throw INTERP_KERNEL::Exception(oss.str().c_str());
6215             }
6216         }
6217     }
6218   return ret.retn();
6219 }
6220
6221 /*!
6222  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6223  * 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]
6224  */
6225 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception)
6226 {
6227   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6228   ret->alloc(newNbOfElem,1);
6229   int nbOfOldNodes=getNumberOfTuples();
6230   const int *old2New=getConstPointer();
6231   int *pt=ret->getPointer();
6232   for(int i=nbOfOldNodes-1;i>=0;i--)
6233     {
6234       int newp(old2New[i]);
6235       if(newp!=-1)
6236         {
6237           if(newp>=0 && newp<newNbOfElem)
6238             pt[newp]=i;
6239           else
6240             {
6241               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6242               throw INTERP_KERNEL::Exception(oss.str().c_str());
6243             }
6244         }
6245     }
6246   return ret.retn();
6247 }
6248
6249 /*!
6250  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6251  * from values of \a this array, which is supposed to contain a renumbering map in 
6252  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6253  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6254  *  \param [in] newNbOfElem - the number of tuples in the result array.
6255  *  \return DataArrayInt * - the new instance of DataArrayInt.
6256  *          The caller is to delete this result array using decrRef() as it is no more
6257  *          needed.
6258  * 
6259  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6260  *
6261  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6262  */
6263 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6264 {
6265   checkAllocated();
6266   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6267   ret->alloc(oldNbOfElem,1);
6268   const int *new2Old=getConstPointer();
6269   int *pt=ret->getPointer();
6270   std::fill(pt,pt+oldNbOfElem,-1);
6271   int nbOfNewElems=getNumberOfTuples();
6272   for(int i=0;i<nbOfNewElems;i++)
6273     {
6274       int v(new2Old[i]);
6275       if(v>=0 && v<oldNbOfElem)
6276          pt[v]=i;
6277       else
6278         {
6279           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6280           throw INTERP_KERNEL::Exception(oss.str().c_str());
6281         }
6282     }
6283   return ret.retn();
6284 }
6285
6286 /*!
6287  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6288  * mismatch is given.
6289  * 
6290  * \param [in] other the instance to be compared with \a this
6291  * \param [out] reason In case of inequality returns the reason.
6292  * \sa DataArrayInt::isEqual
6293  */
6294 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
6295 {
6296   if(!areInfoEqualsIfNotWhy(other,reason))
6297     return false;
6298   return _mem.isEqual(other._mem,0,reason);
6299 }
6300
6301 /*!
6302  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6303  * \ref MEDCouplingArrayBasicsCompare.
6304  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6305  *  \return bool - \a true if the two arrays are equal, \a false else.
6306  */
6307 bool DataArrayInt::isEqual(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6308 {
6309   std::string tmp;
6310   return isEqualIfNotWhy(other,tmp);
6311 }
6312
6313 /*!
6314  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6315  * \ref MEDCouplingArrayBasicsCompare.
6316  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6317  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6318  */
6319 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6320 {
6321   std::string tmp;
6322   return _mem.isEqual(other._mem,0,tmp);
6323 }
6324
6325 /*!
6326  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6327  * performed on sorted value sequences.
6328  * For more info see\ref MEDCouplingArrayBasicsCompare.
6329  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6330  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6331  */
6332 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6333 {
6334   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6335   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6336   a->sort();
6337   b->sort();
6338   return a->isEqualWithoutConsideringStr(*b);
6339 }
6340
6341 /*!
6342  * This method compares content of input vector \a v and \a this.
6343  * 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.
6344  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6345  *
6346  * \param [in] v - the vector of 'flags' to be compared with \a this.
6347  *
6348  * \throw If \a this is not sorted ascendingly.
6349  * \throw If \a this has not exactly one component.
6350  * \throw If \a this is not allocated.
6351  */
6352 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const throw(INTERP_KERNEL::Exception)
6353 {
6354   checkAllocated();
6355   if(getNumberOfComponents()!=1)
6356     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6357   int nbOfTuples(getNumberOfTuples());
6358   const int *w(begin()),*end2(end());
6359   int refVal=-std::numeric_limits<int>::max();
6360   int i=0;
6361   std::vector<bool>::const_iterator it(v.begin());
6362   for(;it!=v.end();it++,i++)
6363     {
6364       if(*it)
6365         {
6366           if(w!=end2)
6367             {
6368               if(*w++==i)
6369                 {
6370                   if(i>refVal)
6371                     refVal=i;
6372                   else
6373                     {
6374                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6375                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6376                     }
6377                 }
6378               else
6379                 return false;
6380             }
6381           else
6382             return false;
6383         }
6384     }
6385   return w==end2;
6386 }
6387
6388 /*!
6389  * Sorts values of the array.
6390  *  \param [in] asc - \a true means ascending order, \a false, descending.
6391  *  \throw If \a this is not allocated.
6392  *  \throw If \a this->getNumberOfComponents() != 1.
6393  */
6394 void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception)
6395 {
6396   checkAllocated();
6397   if(getNumberOfComponents()!=1)
6398     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6399   _mem.sort(asc);
6400   declareAsNew();
6401 }
6402
6403 /*!
6404  * Reverse the array values.
6405  *  \throw If \a this->getNumberOfComponents() < 1.
6406  *  \throw If \a this is not allocated.
6407  */
6408 void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
6409 {
6410   checkAllocated();
6411   _mem.reverse(getNumberOfComponents());
6412   declareAsNew();
6413 }
6414
6415 /*!
6416  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6417  * If not an exception is thrown.
6418  *  \param [in] increasing - if \a true, the array values should be increasing.
6419  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6420  *         increasing arg.
6421  *  \throw If \a this->getNumberOfComponents() != 1.
6422  *  \throw If \a this is not allocated.
6423  */
6424 void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6425 {
6426   if(!isMonotonic(increasing))
6427     {
6428       if (increasing)
6429         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6430       else
6431         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6432     }
6433 }
6434
6435 /*!
6436  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6437  *  \param [in] increasing - if \a true, array values should be increasing.
6438  *  \return bool - \a true if values change in accordance with \a increasing arg.
6439  *  \throw If \a this->getNumberOfComponents() != 1.
6440  *  \throw If \a this is not allocated.
6441  */
6442 bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6443 {
6444   checkAllocated();
6445   if(getNumberOfComponents()!=1)
6446     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6447   int nbOfElements=getNumberOfTuples();
6448   const int *ptr=getConstPointer();
6449   if(nbOfElements==0)
6450     return true;
6451   int ref=ptr[0];
6452   if(increasing)
6453     {
6454       for(int i=1;i<nbOfElements;i++)
6455         {
6456           if(ptr[i]>=ref)
6457             ref=ptr[i];
6458           else
6459             return false;
6460         }
6461     }
6462   else
6463     {
6464       for(int i=1;i<nbOfElements;i++)
6465         {
6466           if(ptr[i]<=ref)
6467             ref=ptr[i];
6468           else
6469             return false;
6470         }
6471     }
6472   return true;
6473 }
6474
6475 /*!
6476  * This method check that array consistently INCREASING or DECREASING in value.
6477  */
6478 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6479 {
6480   checkAllocated();
6481   if(getNumberOfComponents()!=1)
6482     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6483   int nbOfElements=getNumberOfTuples();
6484   const int *ptr=getConstPointer();
6485   if(nbOfElements==0)
6486     return true;
6487   int ref=ptr[0];
6488   if(increasing)
6489     {
6490       for(int i=1;i<nbOfElements;i++)
6491         {
6492           if(ptr[i]>ref)
6493             ref=ptr[i];
6494           else
6495             return false;
6496         }
6497     }
6498   else
6499     {
6500       for(int i=1;i<nbOfElements;i++)
6501         {
6502           if(ptr[i]<ref)
6503             ref=ptr[i];
6504           else
6505             return false;
6506         }
6507     }
6508   return true;
6509 }
6510
6511 /*!
6512  * This method check that array consistently INCREASING or DECREASING in value.
6513  */
6514 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6515 {
6516   if(!isStrictlyMonotonic(increasing))
6517     {
6518       if (increasing)
6519         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6520       else
6521         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6522     }
6523 }
6524
6525 /*!
6526  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6527  * one-dimensional arrays that must be of the same length. The result array describes
6528  * correspondence between \a this and \a other arrays, so that 
6529  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6530  * not possible because some element in \a other is not in \a this, an exception is thrown.
6531  *  \param [in] other - an array to compute permutation to.
6532  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6533  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6534  * no more needed.
6535  *  \throw If \a this->getNumberOfComponents() != 1.
6536  *  \throw If \a other->getNumberOfComponents() != 1.
6537  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6538  *  \throw If \a other includes a value which is not in \a this array.
6539  * 
6540  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6541  *
6542  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6543  */
6544 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6545 {
6546   checkAllocated();
6547   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6548     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6549   int nbTuple=getNumberOfTuples();
6550   other.checkAllocated();
6551   if(nbTuple!=other.getNumberOfTuples())
6552     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6553   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6554   ret->alloc(nbTuple,1);
6555   ret->fillWithValue(-1);
6556   const int *pt=getConstPointer();
6557   std::map<int,int> mm;
6558   for(int i=0;i<nbTuple;i++)
6559     mm[pt[i]]=i;
6560   pt=other.getConstPointer();
6561   int *retToFill=ret->getPointer();
6562   for(int i=0;i<nbTuple;i++)
6563     {
6564       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6565       if(it==mm.end())
6566         {
6567           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6568           throw INTERP_KERNEL::Exception(oss.str().c_str());
6569         }
6570       retToFill[i]=(*it).second;
6571     }
6572   return ret.retn();
6573 }
6574
6575 /*!
6576  * Sets a C array to be used as raw data of \a this. The previously set info
6577  *  of components is retained and re-sized. 
6578  * For more info see \ref MEDCouplingArraySteps1.
6579  *  \param [in] array - the C array to be used as raw data of \a this.
6580  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6581  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6582  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6583  *                     \c free(\c array ) will be called.
6584  *  \param [in] nbOfTuple - new number of tuples in \a this.
6585  *  \param [in] nbOfCompo - new number of components in \a this.
6586  */
6587 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6588 {
6589   _info_on_compo.resize(nbOfCompo);
6590   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6591   declareAsNew();
6592 }
6593
6594 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6595 {
6596   _info_on_compo.resize(nbOfCompo);
6597   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6598   declareAsNew();
6599 }
6600
6601 /*!
6602  * Returns a new DataArrayInt holding the same values as \a this array but differently
6603  * arranged in memory. If \a this array holds 2 components of 3 values:
6604  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6605  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6606  *  \warning Do not confuse this method with transpose()!
6607  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6608  *          is to delete using decrRef() as it is no more needed.
6609  *  \throw If \a this is not allocated.
6610  */
6611 DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
6612 {
6613   checkAllocated();
6614   if(_mem.isNull())
6615     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6616   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6617   DataArrayInt *ret=DataArrayInt::New();
6618   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6619   return ret;
6620 }
6621
6622 /*!
6623  * Returns a new DataArrayInt holding the same values as \a this array but differently
6624  * arranged in memory. If \a this array holds 2 components of 3 values:
6625  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6626  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6627  *  \warning Do not confuse this method with transpose()!
6628  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6629  *          is to delete using decrRef() as it is no more needed.
6630  *  \throw If \a this is not allocated.
6631  */
6632 DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception)
6633 {
6634   checkAllocated();
6635   if(_mem.isNull())
6636     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6637   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6638   DataArrayInt *ret=DataArrayInt::New();
6639   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6640   return ret;
6641 }
6642
6643 /*!
6644  * Permutes values of \a this array as required by \a old2New array. The values are
6645  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6646  * the same as in \this one.
6647  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6648  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6649  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6650  *     giving a new position for i-th old value.
6651  */
6652 void DataArrayInt::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
6653 {
6654   checkAllocated();
6655   int nbTuples=getNumberOfTuples();
6656   int nbOfCompo=getNumberOfComponents();
6657   int *tmp=new int[nbTuples*nbOfCompo];
6658   const int *iptr=getConstPointer();
6659   for(int i=0;i<nbTuples;i++)
6660     {
6661       int v=old2New[i];
6662       if(v>=0 && v<nbTuples)
6663         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6664       else
6665         {
6666           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6667           throw INTERP_KERNEL::Exception(oss.str().c_str());
6668         }
6669     }
6670   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6671   delete [] tmp;
6672   declareAsNew();
6673 }
6674
6675 /*!
6676  * Permutes values of \a this array as required by \a new2Old array. The values are
6677  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6678  * the same as in \this one.
6679  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6680  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6681  *     giving a previous position of i-th new value.
6682  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6683  *          is to delete using decrRef() as it is no more needed.
6684  */
6685 void DataArrayInt::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
6686 {
6687   checkAllocated();
6688   int nbTuples=getNumberOfTuples();
6689   int nbOfCompo=getNumberOfComponents();
6690   int *tmp=new int[nbTuples*nbOfCompo];
6691   const int *iptr=getConstPointer();
6692   for(int i=0;i<nbTuples;i++)
6693     {
6694       int v=new2Old[i];
6695       if(v>=0 && v<nbTuples)
6696         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6697       else
6698         {
6699           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6700           throw INTERP_KERNEL::Exception(oss.str().c_str());
6701         }
6702     }
6703   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6704   delete [] tmp;
6705   declareAsNew();
6706 }
6707
6708 /*!
6709  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6710  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6711  * Number of tuples in the result array remains the same as in \this one.
6712  * If a permutation reduction is needed, renumberAndReduce() should be used.
6713  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6714  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6715  *          giving a new position for i-th old value.
6716  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6717  *          is to delete using decrRef() as it is no more needed.
6718  *  \throw If \a this is not allocated.
6719  */
6720 DataArrayInt *DataArrayInt::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
6721 {
6722   checkAllocated();
6723   int nbTuples=getNumberOfTuples();
6724   int nbOfCompo=getNumberOfComponents();
6725   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6726   ret->alloc(nbTuples,nbOfCompo);
6727   ret->copyStringInfoFrom(*this);
6728   const int *iptr=getConstPointer();
6729   int *optr=ret->getPointer();
6730   for(int i=0;i<nbTuples;i++)
6731     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6732   ret->copyStringInfoFrom(*this);
6733   return ret.retn();
6734 }
6735
6736 /*!
6737  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6738  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6739  * tuples in the result array remains the same as in \this one.
6740  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6741  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6742  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6743  *     giving a previous position of i-th new value.
6744  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6745  *          is to delete using decrRef() as it is no more needed.
6746  */
6747 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
6748 {
6749   checkAllocated();
6750   int nbTuples=getNumberOfTuples();
6751   int nbOfCompo=getNumberOfComponents();
6752   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6753   ret->alloc(nbTuples,nbOfCompo);
6754   ret->copyStringInfoFrom(*this);
6755   const int *iptr=getConstPointer();
6756   int *optr=ret->getPointer();
6757   for(int i=0;i<nbTuples;i++)
6758     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6759   ret->copyStringInfoFrom(*this);
6760   return ret.retn();
6761 }
6762
6763 /*!
6764  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6765  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6766  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6767  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6768  * \a old2New[ i ] is negative, is missing from the result array.
6769  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6770  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6771  *     giving a new position for i-th old tuple and giving negative position for
6772  *     for i-th old tuple that should be omitted.
6773  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6774  *          is to delete using decrRef() as it is no more needed.
6775  */
6776 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
6777 {
6778   checkAllocated();
6779   int nbTuples=getNumberOfTuples();
6780   int nbOfCompo=getNumberOfComponents();
6781   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6782   ret->alloc(newNbOfTuple,nbOfCompo);
6783   const int *iptr=getConstPointer();
6784   int *optr=ret->getPointer();
6785   for(int i=0;i<nbTuples;i++)
6786     {
6787       int w=old2New[i];
6788       if(w>=0)
6789         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6790     }
6791   ret->copyStringInfoFrom(*this);
6792   return ret.retn();
6793 }
6794
6795 /*!
6796  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6797  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6798  * \a new2OldBg array.
6799  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6800  * This method is equivalent to renumberAndReduce() except that convention in input is
6801  * \c new2old and \b not \c old2new.
6802  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6803  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6804  *              tuple index in \a this array to fill the i-th tuple in the new array.
6805  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6806  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6807  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6808  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6809  *          is to delete using decrRef() as it is no more needed.
6810  */
6811 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6812 {
6813   checkAllocated();
6814   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6815   int nbComp=getNumberOfComponents();
6816   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6817   ret->copyStringInfoFrom(*this);
6818   int *pt=ret->getPointer();
6819   const int *srcPt=getConstPointer();
6820   int i=0;
6821   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6822     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6823   ret->copyStringInfoFrom(*this);
6824   return ret.retn();
6825 }
6826
6827 /*!
6828  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6829  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6830  * \a new2OldBg array.
6831  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6832  * This method is equivalent to renumberAndReduce() except that convention in input is
6833  * \c new2old and \b not \c old2new.
6834  * This method is equivalent to selectByTupleId() except that it prevents coping data
6835  * from behind the end of \a this array.
6836  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6837  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6838  *              tuple index in \a this array to fill the i-th tuple in the new array.
6839  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6840  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6841  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6842  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6843  *          is to delete using decrRef() as it is no more needed.
6844  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6845  */
6846 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
6847 {
6848   checkAllocated();
6849   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6850   int nbComp=getNumberOfComponents();
6851   int oldNbOfTuples=getNumberOfTuples();
6852   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6853   ret->copyStringInfoFrom(*this);
6854   int *pt=ret->getPointer();
6855   const int *srcPt=getConstPointer();
6856   int i=0;
6857   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6858     if(*w>=0 && *w<oldNbOfTuples)
6859       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6860     else
6861       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6862   ret->copyStringInfoFrom(*this);
6863   return ret.retn();
6864 }
6865
6866 /*!
6867  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6868  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6869  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6870  * command \c range( \a bg, \a end2, \a step ).
6871  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6872  * not constructed explicitly.
6873  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6874  *  \param [in] bg - index of the first tuple to copy from \a this array.
6875  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
6876  *  \param [in] step - index increment to get index of the next tuple to copy.
6877  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6878  *          is to delete using decrRef() as it is no more needed.
6879  *  \sa DataArrayInt::substr.
6880  */
6881 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
6882 {
6883   checkAllocated();
6884   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6885   int nbComp=getNumberOfComponents();
6886   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
6887   ret->alloc(newNbOfTuples,nbComp);
6888   int *pt=ret->getPointer();
6889   const int *srcPt=getConstPointer()+bg*nbComp;
6890   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
6891     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
6892   ret->copyStringInfoFrom(*this);
6893   return ret.retn();
6894 }
6895
6896 /*!
6897  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
6898  * of tuples specified by \a ranges parameter.
6899  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6900  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
6901  *              of tuples in [\c begin,\c end) format.
6902  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6903  *          is to delete using decrRef() as it is no more needed.
6904  *  \throw If \a end < \a begin.
6905  *  \throw If \a end > \a this->getNumberOfTuples().
6906  *  \throw If \a this is not allocated.
6907  */
6908 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
6909 {
6910   checkAllocated();
6911   int nbOfComp=getNumberOfComponents();
6912   int nbOfTuplesThis=getNumberOfTuples();
6913   if(ranges.empty())
6914     {
6915       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6916       ret->alloc(0,nbOfComp);
6917       ret->copyStringInfoFrom(*this);
6918       return ret.retn();
6919     }
6920   int ref=ranges.front().first;
6921   int nbOfTuples=0;
6922   bool isIncreasing=true;
6923   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6924     {
6925       if((*it).first<=(*it).second)
6926         {
6927           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
6928             {
6929               nbOfTuples+=(*it).second-(*it).first;
6930               if(isIncreasing)
6931                 isIncreasing=ref<=(*it).first;
6932               ref=(*it).second;
6933             }
6934           else
6935             {
6936               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6937               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
6938               throw INTERP_KERNEL::Exception(oss.str().c_str());
6939             }
6940         }
6941       else
6942         {
6943           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6944           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
6945           throw INTERP_KERNEL::Exception(oss.str().c_str());
6946         }
6947     }
6948   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
6949     return deepCpy();
6950   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6951   ret->alloc(nbOfTuples,nbOfComp);
6952   ret->copyStringInfoFrom(*this);
6953   const int *src=getConstPointer();
6954   int *work=ret->getPointer();
6955   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6956     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
6957   return ret.retn();
6958 }
6959
6960 /*!
6961  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
6962  * This map, if applied to \a this array, would make it sorted. For example, if
6963  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
6964  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
6965  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
6966  * This method is useful for renumbering (in MED file for example). For more info
6967  * on renumbering see \ref MEDCouplingArrayRenumbering.
6968  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6969  *          array using decrRef() as it is no more needed.
6970  *  \throw If \a this is not allocated.
6971  *  \throw If \a this->getNumberOfComponents() != 1.
6972  *  \throw If there are equal values in \a this array.
6973  */
6974 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception)
6975 {
6976   checkAllocated();
6977   if(getNumberOfComponents()!=1)
6978     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
6979   int nbTuples=getNumberOfTuples();
6980   const int *pt=getConstPointer();
6981   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
6982   DataArrayInt *ret=DataArrayInt::New();
6983   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
6984   return ret;
6985 }
6986
6987 /*!
6988  * 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
6989  * input array \a ids2.
6990  * \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.
6991  * 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
6992  * inversely.
6993  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
6994  *
6995  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6996  *          array using decrRef() as it is no more needed.
6997  * \throw If either ids1 or ids2 is null not allocated or not with one components.
6998  * 
6999  */
7000 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2) throw(INTERP_KERNEL::Exception)
7001 {
7002   if(!ids1 || !ids2)
7003     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7004   if(!ids1->isAllocated() || !ids2->isAllocated())
7005     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7006   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7007     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7008   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7009     {
7010       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 !";
7011       throw INTERP_KERNEL::Exception(oss.str().c_str());
7012     }
7013   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
7014   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
7015   p1->sort(true); p2->sort(true);
7016   if(!p1->isEqualWithoutConsideringStr(*p2))
7017     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7018   p1=ids1->checkAndPreparePermutation();
7019   p2=ids2->checkAndPreparePermutation();
7020   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7021   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7022   return p2.retn();
7023 }
7024
7025 /*!
7026  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7027  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7028  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7029  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7030  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7031  * The first of out arrays returns indices of elements of \a this array, grouped by their
7032  * place in the set \a B. The second out array is the index of the first one; it shows how
7033  * many elements of \a A are mapped into each element of \a B. <br>
7034  * For more info on
7035  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
7036  * \b Example:
7037  * - \a this: [0,3,2,3,2,2,1,2]
7038  * - \a targetNb: 4
7039  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7040  * - \a arrI: [0,1,2,6,8]
7041  *
7042  * This result means: <br>
7043  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7044  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7045  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7046  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7047  * \a arrI[ 2+1 ]]); <br> etc.
7048  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7049  *         than the maximal value of \a A.
7050  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7051  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7052  *         this array using decrRef() as it is no more needed.
7053  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7054  *         elements of \a this. The caller is to delete this array using decrRef() as it
7055  *         is no more needed.
7056  *  \throw If \a this is not allocated.
7057  *  \throw If \a this->getNumberOfComponents() != 1.
7058  *  \throw If any value in \a this is more or equal to \a targetNb.
7059  */
7060 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception)
7061 {
7062   checkAllocated();
7063   if(getNumberOfComponents()!=1)
7064     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7065   int nbOfTuples=getNumberOfTuples();
7066   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7067   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7068   retI->alloc(targetNb+1,1);
7069   const int *input=getConstPointer();
7070   std::vector< std::vector<int> > tmp(targetNb);
7071   for(int i=0;i<nbOfTuples;i++)
7072     {
7073       int tmp2=input[i];
7074       if(tmp2>=0 && tmp2<targetNb)
7075         tmp[tmp2].push_back(i);
7076       else
7077         {
7078           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7079           throw INTERP_KERNEL::Exception(oss.str().c_str());
7080         }
7081     }
7082   int *retIPtr=retI->getPointer();
7083   *retIPtr=0;
7084   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7085     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7086   if(nbOfTuples!=retI->getIJ(targetNb,0))
7087     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7088   ret->alloc(nbOfTuples,1);
7089   int *retPtr=ret->getPointer();
7090   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7091     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7092   arr=ret.retn();
7093   arrI=retI.retn();
7094 }
7095
7096
7097 /*!
7098  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7099  * from a zip representation of a surjective format (returned e.g. by
7100  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7101  * for example). The result array minimizes the permutation. <br>
7102  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7103  * \b Example: <br>
7104  * - \a nbOfOldTuples: 10 
7105  * - \a arr          : [0,3, 5,7,9]
7106  * - \a arrIBg       : [0,2,5]
7107  * - \a newNbOfTuples: 7
7108  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7109  *
7110  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7111  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7112  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7113  *         (indices of) equal values. Its every element (except the last one) points to
7114  *         the first element of a group of equal values.
7115  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7116  *          arrIBg is \a arrIEnd[ -1 ].
7117  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7118  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7119  *          array using decrRef() as it is no more needed.
7120  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7121  */
7122 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
7123 {
7124   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7125   ret->alloc(nbOfOldTuples,1);
7126   int *pt=ret->getPointer();
7127   std::fill(pt,pt+nbOfOldTuples,-1);
7128   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7129   const int *cIPtr=arrIBg;
7130   for(int i=0;i<nbOfGrps;i++)
7131     pt[arr[cIPtr[i]]]=-(i+2);
7132   int newNb=0;
7133   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7134     {
7135       if(pt[iNode]<0)
7136         {
7137           if(pt[iNode]==-1)
7138             pt[iNode]=newNb++;
7139           else
7140             {
7141               int grpId=-(pt[iNode]+2);
7142               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7143                 {
7144                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7145                     pt[arr[j]]=newNb;
7146                   else
7147                     {
7148                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7149                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7150                     }
7151                 }
7152               newNb++;
7153             }
7154         }
7155     }
7156   newNbOfTuples=newNb;
7157   return ret.retn();
7158 }
7159
7160 /*!
7161  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7162  * which if applied to \a this array would make it sorted ascendingly.
7163  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7164  * \b Example: <br>
7165  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7166  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7167  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7168  *
7169  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7170  *          array using decrRef() as it is no more needed.
7171  *  \throw If \a this is not allocated.
7172  *  \throw If \a this->getNumberOfComponents() != 1.
7173  */
7174 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception)
7175 {
7176   checkAllocated();
7177   if(getNumberOfComponents()!=1)
7178     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7179   int nbOfTuples=getNumberOfTuples();
7180   const int *pt=getConstPointer();
7181   std::map<int,int> m;
7182   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7183   ret->alloc(nbOfTuples,1);
7184   int *opt=ret->getPointer();
7185   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7186     {
7187       int val=*pt;
7188       std::map<int,int>::iterator it=m.find(val);
7189       if(it!=m.end())
7190         {
7191           *opt=(*it).second;
7192           (*it).second++;
7193         }
7194       else
7195         {
7196           *opt=0;
7197           m.insert(std::pair<int,int>(val,1));
7198         }
7199     }
7200   int sum=0;
7201   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7202     {
7203       int vt=(*it).second;
7204       (*it).second=sum;
7205       sum+=vt;
7206     }
7207   pt=getConstPointer();
7208   opt=ret->getPointer();
7209   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7210     *opt+=m[*pt];
7211   //
7212   return ret.retn();
7213 }
7214
7215 /*!
7216  * Checks if contents of \a this array are equal to that of an array filled with
7217  * iota(). This method is particularly useful for DataArrayInt instances that represent
7218  * a renumbering array to check the real need in renumbering. 
7219  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7220  *  \throw If \a this is not allocated.
7221  *  \throw If \a this->getNumberOfComponents() != 1.
7222  */
7223 bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception)
7224 {
7225   checkAllocated();
7226   if(getNumberOfComponents()!=1)
7227     return false;
7228   int nbOfTuples=getNumberOfTuples();
7229   const int *pt=getConstPointer();
7230   for(int i=0;i<nbOfTuples;i++,pt++)
7231     if(*pt!=i)
7232       return false;
7233   return true;
7234 }
7235
7236 /*!
7237  * Checks if all values in \a this array are equal to \a val.
7238  *  \param [in] val - value to check equality of array values to.
7239  *  \return bool - \a true if all values are \a val.
7240  *  \throw If \a this is not allocated.
7241  *  \throw If \a this->getNumberOfComponents() != 1
7242  */
7243 bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception)
7244 {
7245   checkAllocated();
7246   if(getNumberOfComponents()!=1)
7247     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7248   int nbOfTuples=getNumberOfTuples();
7249   const int *w=getConstPointer();
7250   const int *end2=w+nbOfTuples;
7251   for(;w!=end2;w++)
7252     if(*w!=val)
7253       return false;
7254   return true;
7255 }
7256
7257 /*!
7258  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7259  * array to the new one.
7260  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7261  */
7262 DataArrayDouble *DataArrayInt::convertToDblArr() const
7263 {
7264   checkAllocated();
7265   DataArrayDouble *ret=DataArrayDouble::New();
7266   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7267   std::size_t nbOfVals=getNbOfElems();
7268   const int *src=getConstPointer();
7269   double *dest=ret->getPointer();
7270   std::copy(src,src+nbOfVals,dest);
7271   ret->copyStringInfoFrom(*this);
7272   return ret;
7273 }
7274
7275 /*!
7276  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7277  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7278  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7279  * This method is a specialization of selectByTupleId2().
7280  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7281  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7282  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7283  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7284  *          is to delete using decrRef() as it is no more needed.
7285  *  \throw If \a tupleIdBg < 0.
7286  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7287     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7288  *  \sa DataArrayInt::selectByTupleId2
7289  */
7290 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
7291 {
7292   checkAllocated();
7293   int nbt=getNumberOfTuples();
7294   if(tupleIdBg<0)
7295     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7296   if(tupleIdBg>nbt)
7297     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7298   int trueEnd=tupleIdEnd;
7299   if(tupleIdEnd!=-1)
7300     {
7301       if(tupleIdEnd>nbt)
7302         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7303     }
7304   else
7305     trueEnd=nbt;
7306   int nbComp=getNumberOfComponents();
7307   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7308   ret->alloc(trueEnd-tupleIdBg,nbComp);
7309   ret->copyStringInfoFrom(*this);
7310   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7311   return ret.retn();
7312 }
7313
7314 /*!
7315  * Changes the number of components within \a this array so that its raw data **does
7316  * not** change, instead splitting this data into tuples changes.
7317  *  \warning This method erases all (name and unit) component info set before!
7318  *  \param [in] newNbOfComp - number of components for \a this array to have.
7319  *  \throw If \a this is not allocated
7320  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7321  *  \throw If \a newNbOfCompo is lower than 1.
7322  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7323  *  \warning This method erases all (name and unit) component info set before!
7324  */
7325 void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
7326 {
7327   checkAllocated();
7328   if(newNbOfCompo<1)
7329     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7330   std::size_t nbOfElems=getNbOfElems();
7331   if(nbOfElems%newNbOfCompo!=0)
7332     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7333   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7334     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7335   _info_on_compo.clear();
7336   _info_on_compo.resize(newNbOfCompo);
7337   declareAsNew();
7338 }
7339
7340 /*!
7341  * Changes the number of components within \a this array to be equal to its number
7342  * of tuples, and inversely its number of tuples to become equal to its number of 
7343  * components. So that its raw data **does not** change, instead splitting this
7344  * data into tuples changes.
7345  *  \warning This method erases all (name and unit) component info set before!
7346  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7347  *  \throw If \a this is not allocated.
7348  *  \sa rearrange()
7349  */
7350 void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception)
7351 {
7352   checkAllocated();
7353   int nbOfTuples=getNumberOfTuples();
7354   rearrange(nbOfTuples);
7355 }
7356
7357 /*!
7358  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7359  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7360  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7361  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7362  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7363  * components.  
7364  *  \param [in] newNbOfComp - number of components for the new array to have.
7365  *  \param [in] dftValue - value assigned to new values added to the new array.
7366  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7367  *          is to delete using decrRef() as it is no more needed.
7368  *  \throw If \a this is not allocated.
7369  */
7370 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception)
7371 {
7372   checkAllocated();
7373   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7374   ret->alloc(getNumberOfTuples(),newNbOfComp);
7375   const int *oldc=getConstPointer();
7376   int *nc=ret->getPointer();
7377   int nbOfTuples=getNumberOfTuples();
7378   int oldNbOfComp=getNumberOfComponents();
7379   int dim=std::min(oldNbOfComp,newNbOfComp);
7380   for(int i=0;i<nbOfTuples;i++)
7381     {
7382       int j=0;
7383       for(;j<dim;j++)
7384         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7385       for(;j<newNbOfComp;j++)
7386         nc[newNbOfComp*i+j]=dftValue;
7387     }
7388   ret->setName(getName().c_str());
7389   for(int i=0;i<dim;i++)
7390     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
7391   ret->setName(getName().c_str());
7392   return ret.retn();
7393 }
7394
7395 /*!
7396  * Changes number of tuples in the array. If the new number of tuples is smaller
7397  * than the current number the array is truncated, otherwise the array is extended.
7398  *  \param [in] nbOfTuples - new number of tuples. 
7399  *  \throw If \a this is not allocated.
7400  *  \throw If \a nbOfTuples is negative.
7401  */
7402 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
7403 {
7404   if(nbOfTuples<0)
7405     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7406   checkAllocated();
7407   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7408   declareAsNew();
7409 }
7410
7411
7412 /*!
7413  * Returns a copy of \a this array composed of selected components.
7414  * The new DataArrayInt has the same number of tuples but includes components
7415  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7416  * can be either less, same or more than \a this->getNbOfElems().
7417  *  \param [in] compoIds - sequence of zero based indices of components to include
7418  *              into the new array.
7419  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7420  *          is to delete using decrRef() as it is no more needed.
7421  *  \throw If \a this is not allocated.
7422  *  \throw If a component index (\a i) is not valid: 
7423  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7424  *
7425  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7426  */
7427 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
7428 {
7429   checkAllocated();
7430   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7431   int newNbOfCompo=(int)compoIds.size();
7432   int oldNbOfCompo=getNumberOfComponents();
7433   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7434     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7435   int nbOfTuples=getNumberOfTuples();
7436   ret->alloc(nbOfTuples,newNbOfCompo);
7437   ret->copyPartOfStringInfoFrom(*this,compoIds);
7438   const int *oldc=getConstPointer();
7439   int *nc=ret->getPointer();
7440   for(int i=0;i<nbOfTuples;i++)
7441     for(int j=0;j<newNbOfCompo;j++,nc++)
7442       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7443   return ret.retn();
7444 }
7445
7446 /*!
7447  * Appends components of another array to components of \a this one, tuple by tuple.
7448  * So that the number of tuples of \a this array remains the same and the number of 
7449  * components increases.
7450  *  \param [in] other - the DataArrayInt to append to \a this one.
7451  *  \throw If \a this is not allocated.
7452  *  \throw If \a this and \a other arrays have different number of tuples.
7453  *
7454  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7455  *
7456  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7457  */
7458 void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
7459 {
7460   if(!other)
7461     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7462   checkAllocated();
7463   other->checkAllocated();
7464   int nbOfTuples=getNumberOfTuples();
7465   if(nbOfTuples!=other->getNumberOfTuples())
7466     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7467   int nbOfComp1=getNumberOfComponents();
7468   int nbOfComp2=other->getNumberOfComponents();
7469   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7470   int *w=newArr;
7471   const int *inp1=getConstPointer();
7472   const int *inp2=other->getConstPointer();
7473   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7474     {
7475       w=std::copy(inp1,inp1+nbOfComp1,w);
7476       w=std::copy(inp2,inp2+nbOfComp2,w);
7477     }
7478   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7479   std::vector<int> compIds(nbOfComp2);
7480   for(int i=0;i<nbOfComp2;i++)
7481     compIds[i]=nbOfComp1+i;
7482   copyPartOfStringInfoFrom2(compIds,*other);
7483 }
7484
7485 /*!
7486  * Copy all components in a specified order from another DataArrayInt.
7487  * The specified components become the first ones in \a this array.
7488  * Both numerical and textual data is copied. The number of tuples in \a this and
7489  * the other array can be different.
7490  *  \param [in] a - the array to copy data from.
7491  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7492  *              to be copied.
7493  *  \throw If \a a is NULL.
7494  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7495  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7496  *
7497  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7498  */
7499 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
7500 {
7501   if(!a)
7502     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7503   checkAllocated();
7504   a->checkAllocated();
7505   copyPartOfStringInfoFrom2(compoIds,*a);
7506   std::size_t partOfCompoSz=compoIds.size();
7507   int nbOfCompo=getNumberOfComponents();
7508   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7509   const int *ac=a->getConstPointer();
7510   int *nc=getPointer();
7511   for(int i=0;i<nbOfTuples;i++)
7512     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7513       nc[nbOfCompo*i+compoIds[j]]=*ac;
7514 }
7515
7516 /*!
7517  * Copy all values from another DataArrayInt into specified tuples and components
7518  * of \a this array. Textual data is not copied.
7519  * The tree parameters defining set of indices of tuples and components are similar to
7520  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7521  *  \param [in] a - the array to copy values from.
7522  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7523  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7524  *              are located.
7525  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7526  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7527  *  \param [in] endComp - index of the component before which the components to assign
7528  *              to are located.
7529  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7530  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7531  *              must be equal to the number of columns to assign to, else an
7532  *              exception is thrown; if \a false, then it is only required that \a
7533  *              a->getNbOfElems() equals to number of values to assign to (this condition
7534  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7535  *              values to assign to is given by following Python expression:
7536  *              \a nbTargetValues = 
7537  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7538  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7539  *  \throw If \a a is NULL.
7540  *  \throw If \a a is not allocated.
7541  *  \throw If \a this is not allocated.
7542  *  \throw If parameters specifying tuples and components to assign to do not give a
7543  *            non-empty range of increasing indices.
7544  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7545  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7546  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7547  *
7548  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7549  */
7550 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7551 {
7552   if(!a)
7553     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7554   const char msg[]="DataArrayInt::setPartOfValues1";
7555   checkAllocated();
7556   a->checkAllocated();
7557   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7558   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7559   int nbComp=getNumberOfComponents();
7560   int nbOfTuples=getNumberOfTuples();
7561   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7562   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7563   bool assignTech=true;
7564   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7565     {
7566       if(strictCompoCompare)
7567         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7568     }
7569   else
7570     {
7571       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7572       assignTech=false;
7573     }
7574   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7575   const int *srcPt=a->getConstPointer();
7576   if(assignTech)
7577     {
7578       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7579         for(int j=0;j<newNbOfComp;j++,srcPt++)
7580           pt[j*stepComp]=*srcPt;
7581     }
7582   else
7583     {
7584       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7585         {
7586           const int *srcPt2=srcPt;
7587           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7588             pt[j*stepComp]=*srcPt2;
7589         }
7590     }
7591 }
7592
7593 /*!
7594  * Assign a given value to values at specified tuples and components of \a this array.
7595  * The tree parameters defining set of indices of tuples and components are similar to
7596  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7597  *  \param [in] a - the value to assign.
7598  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7599  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7600  *              are located.
7601  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7602  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7603  *  \param [in] endComp - index of the component before which the components to assign
7604  *              to are located.
7605  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7606  *  \throw If \a this is not allocated.
7607  *  \throw If parameters specifying tuples and components to assign to, do not give a
7608  *            non-empty range of increasing indices or indices are out of a valid range
7609  *            for \this array.
7610  *
7611  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7612  */
7613 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7614 {
7615   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7616   checkAllocated();
7617   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7618   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7619   int nbComp=getNumberOfComponents();
7620   int nbOfTuples=getNumberOfTuples();
7621   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7622   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7623   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7624   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7625     for(int j=0;j<newNbOfComp;j++)
7626       pt[j*stepComp]=a;
7627 }
7628
7629
7630 /*!
7631  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7632  * components of \a this array. Textual data is not copied.
7633  * The tuples and components to assign to are defined by C arrays of indices.
7634  * There are two *modes of usage*:
7635  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7636  *   of \a a is assigned to its own location within \a this array. 
7637  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7638  *   components of every specified tuple of \a this array. In this mode it is required
7639  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7640  * 
7641  *  \param [in] a - the array to copy values from.
7642  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7643  *              assign values of \a a to.
7644  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7645  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7646  *              \a bgTuples <= \a pi < \a endTuples.
7647  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7648  *              assign values of \a a to.
7649  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7650  *              pointer to a component index <em>(pi)</em> varies as this: 
7651  *              \a bgComp <= \a pi < \a endComp.
7652  *  \param [in] strictCompoCompare - this parameter is checked only if the
7653  *               *mode of usage* is the first; if it is \a true (default), 
7654  *               then \a a->getNumberOfComponents() must be equal 
7655  *               to the number of specified columns, else this is not required.
7656  *  \throw If \a a is NULL.
7657  *  \throw If \a a is not allocated.
7658  *  \throw If \a this is not allocated.
7659  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7660  *         out of a valid range for \a this array.
7661  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7662  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7663  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7664  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7665  *
7666  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7667  */
7668 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7669 {
7670   if(!a)
7671     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7672   const char msg[]="DataArrayInt::setPartOfValues2";
7673   checkAllocated();
7674   a->checkAllocated();
7675   int nbComp=getNumberOfComponents();
7676   int nbOfTuples=getNumberOfTuples();
7677   for(const int *z=bgComp;z!=endComp;z++)
7678     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7679   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7680   int newNbOfComp=(int)std::distance(bgComp,endComp);
7681   bool assignTech=true;
7682   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7683     {
7684       if(strictCompoCompare)
7685         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7686     }
7687   else
7688     {
7689       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7690       assignTech=false;
7691     }
7692   int *pt=getPointer();
7693   const int *srcPt=a->getConstPointer();
7694   if(assignTech)
7695     {    
7696       for(const int *w=bgTuples;w!=endTuples;w++)
7697         {
7698           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7699           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7700             {    
7701               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7702             }
7703         }
7704     }
7705   else
7706     {
7707       for(const int *w=bgTuples;w!=endTuples;w++)
7708         {
7709           const int *srcPt2=srcPt;
7710           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7711           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7712             {    
7713               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7714             }
7715         }
7716     }
7717 }
7718
7719 /*!
7720  * Assign a given value to values at specified tuples and components of \a this array.
7721  * The tuples and components to assign to are defined by C arrays of indices.
7722  *  \param [in] a - the value to assign.
7723  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7724  *              assign \a a to.
7725  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7726  *              pointer to a tuple index (\a pi) varies as this: 
7727  *              \a bgTuples <= \a pi < \a endTuples.
7728  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7729  *              assign \a a to.
7730  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7731  *              pointer to a component index (\a pi) varies as this: 
7732  *              \a bgComp <= \a pi < \a endComp.
7733  *  \throw If \a this is not allocated.
7734  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7735  *         out of a valid range for \a this array.
7736  *
7737  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7738  */
7739 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7740 {
7741   checkAllocated();
7742   int nbComp=getNumberOfComponents();
7743   int nbOfTuples=getNumberOfTuples();
7744   for(const int *z=bgComp;z!=endComp;z++)
7745     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7746   int *pt=getPointer();
7747   for(const int *w=bgTuples;w!=endTuples;w++)
7748     for(const int *z=bgComp;z!=endComp;z++)
7749       {
7750         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7751         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7752       }
7753 }
7754
7755 /*!
7756  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7757  * components of \a this array. Textual data is not copied.
7758  * The tuples to assign to are defined by a C array of indices.
7759  * The components to assign to are defined by three values similar to parameters of
7760  * the Python function \c range(\c start,\c stop,\c step).
7761  * There are two *modes of usage*:
7762  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7763  *   of \a a is assigned to its own location within \a this array. 
7764  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7765  *   components of every specified tuple of \a this array. In this mode it is required
7766  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7767  *
7768  *  \param [in] a - the array to copy values from.
7769  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7770  *              assign values of \a a to.
7771  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7772  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7773  *              \a bgTuples <= \a pi < \a endTuples.
7774  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7775  *  \param [in] endComp - index of the component before which the components to assign
7776  *              to are located.
7777  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7778  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7779  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7780  *               then \a a->getNumberOfComponents() must be equal 
7781  *               to the number of specified columns, else this is not required.
7782  *  \throw If \a a is NULL.
7783  *  \throw If \a a is not allocated.
7784  *  \throw If \a this is not allocated.
7785  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7786  *         \a this array.
7787  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7788  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7789  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7790  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7791  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7792  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7793  *  \throw If parameters specifying components to assign to, do not give a
7794  *            non-empty range of increasing indices or indices are out of a valid range
7795  *            for \this array.
7796  *
7797  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7798  */
7799 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7800 {
7801   if(!a)
7802     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7803   const char msg[]="DataArrayInt::setPartOfValues3";
7804   checkAllocated();
7805   a->checkAllocated();
7806   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7807   int nbComp=getNumberOfComponents();
7808   int nbOfTuples=getNumberOfTuples();
7809   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7810   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7811   bool assignTech=true;
7812   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7813     {
7814       if(strictCompoCompare)
7815         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7816     }
7817   else
7818     {
7819       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7820       assignTech=false;
7821     }
7822   int *pt=getPointer()+bgComp;
7823   const int *srcPt=a->getConstPointer();
7824   if(assignTech)
7825     {
7826       for(const int *w=bgTuples;w!=endTuples;w++)
7827         for(int j=0;j<newNbOfComp;j++,srcPt++)
7828           {
7829             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7830             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7831           }
7832     }
7833   else
7834     {
7835       for(const int *w=bgTuples;w!=endTuples;w++)
7836         {
7837           const int *srcPt2=srcPt;
7838           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7839             {
7840               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7841               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7842             }
7843         }
7844     }
7845 }
7846
7847 /*!
7848  * Assign a given value to values at specified tuples and components of \a this array.
7849  * The tuples to assign to are defined by a C array of indices.
7850  * The components to assign to are defined by three values similar to parameters of
7851  * the Python function \c range(\c start,\c stop,\c step).
7852  *  \param [in] a - the value to assign.
7853  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7854  *              assign \a a to.
7855  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7856  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7857  *              \a bgTuples <= \a pi < \a endTuples.
7858  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7859  *  \param [in] endComp - index of the component before which the components to assign
7860  *              to are located.
7861  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7862  *  \throw If \a this is not allocated.
7863  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7864  *         \a this array.
7865  *  \throw If parameters specifying components to assign to, do not give a
7866  *            non-empty range of increasing indices or indices are out of a valid range
7867  *            for \this array.
7868  *
7869  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7870  */
7871 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7872 {
7873   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
7874   checkAllocated();
7875   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7876   int nbComp=getNumberOfComponents();
7877   int nbOfTuples=getNumberOfTuples();
7878   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7879   int *pt=getPointer()+bgComp;
7880   for(const int *w=bgTuples;w!=endTuples;w++)
7881     for(int j=0;j<newNbOfComp;j++)
7882       {
7883         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7884         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
7885       }
7886 }
7887
7888 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7889 {
7890   if(!a)
7891     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
7892   const char msg[]="DataArrayInt::setPartOfValues4";
7893   checkAllocated();
7894   a->checkAllocated();
7895   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7896   int newNbOfComp=(int)std::distance(bgComp,endComp);
7897   int nbComp=getNumberOfComponents();
7898   for(const int *z=bgComp;z!=endComp;z++)
7899     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7900   int nbOfTuples=getNumberOfTuples();
7901   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7902   bool assignTech=true;
7903   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7904     {
7905       if(strictCompoCompare)
7906         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7907     }
7908   else
7909     {
7910       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7911       assignTech=false;
7912     }
7913   const int *srcPt=a->getConstPointer();
7914   int *pt=getPointer()+bgTuples*nbComp;
7915   if(assignTech)
7916     {
7917       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7918         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7919           pt[*z]=*srcPt;
7920     }
7921   else
7922     {
7923       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7924         {
7925           const int *srcPt2=srcPt;
7926           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7927             pt[*z]=*srcPt2;
7928         }
7929     }
7930 }
7931
7932 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7933 {
7934   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
7935   checkAllocated();
7936   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7937   int nbComp=getNumberOfComponents();
7938   for(const int *z=bgComp;z!=endComp;z++)
7939     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7940   int nbOfTuples=getNumberOfTuples();
7941   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7942   int *pt=getPointer()+bgTuples*nbComp;
7943   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7944     for(const int *z=bgComp;z!=endComp;z++)
7945       pt[*z]=a;
7946 }
7947
7948 /*!
7949  * Copy some tuples from another DataArrayInt into specified tuples
7950  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7951  * components.
7952  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
7953  * All components of selected tuples are copied.
7954  *  \param [in] a - the array to copy values from.
7955  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
7956  *              target tuples of \a this. \a tuplesSelec has two components, and the
7957  *              first component specifies index of the source tuple and the second
7958  *              one specifies index of the target tuple.
7959  *  \throw If \a this is not allocated.
7960  *  \throw If \a a is NULL.
7961  *  \throw If \a a is not allocated.
7962  *  \throw If \a tuplesSelec is NULL.
7963  *  \throw If \a tuplesSelec is not allocated.
7964  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7965  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
7966  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7967  *         the corresponding (\a this or \a a) array.
7968  */
7969 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7970 {
7971   if(!a || !tuplesSelec)
7972     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
7973   checkAllocated();
7974   a->checkAllocated();
7975   tuplesSelec->checkAllocated();
7976   int nbOfComp=getNumberOfComponents();
7977   if(nbOfComp!=a->getNumberOfComponents())
7978     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
7979   if(tuplesSelec->getNumberOfComponents()!=2)
7980     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
7981   int thisNt=getNumberOfTuples();
7982   int aNt=a->getNumberOfTuples();
7983   int *valsToSet=getPointer();
7984   const int *valsSrc=a->getConstPointer();
7985   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
7986     {
7987       if(tuple[1]>=0 && tuple[1]<aNt)
7988         {
7989           if(tuple[0]>=0 && tuple[0]<thisNt)
7990             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
7991           else
7992             {
7993               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7994               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
7995               throw INTERP_KERNEL::Exception(oss.str().c_str());
7996             }
7997         }
7998       else
7999         {
8000           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8001           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8002           throw INTERP_KERNEL::Exception(oss.str().c_str());
8003         }
8004     }
8005 }
8006
8007 /*!
8008  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8009  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8010  * components.
8011  * The tuples to assign to are defined by index of the first tuple, and
8012  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8013  * The tuples to copy are defined by values of a DataArrayInt.
8014  * All components of selected tuples are copied.
8015  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8016  *              values to.
8017  *  \param [in] aBase - the array to copy values from.
8018  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8019  *  \throw If \a this is not allocated.
8020  *  \throw If \a aBase is NULL.
8021  *  \throw If \a aBase is not allocated.
8022  *  \throw If \a tuplesSelec is NULL.
8023  *  \throw If \a tuplesSelec is not allocated.
8024  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8025  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8026  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8027  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8028  *         \a aBase array.
8029  */
8030 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
8031 {
8032   if(!aBase || !tuplesSelec)
8033     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8034   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8035   if(!a)
8036     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8037   checkAllocated();
8038   a->checkAllocated();
8039   tuplesSelec->checkAllocated();
8040   int nbOfComp=getNumberOfComponents();
8041   if(nbOfComp!=a->getNumberOfComponents())
8042     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8043   if(tuplesSelec->getNumberOfComponents()!=1)
8044     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8045   int thisNt=getNumberOfTuples();
8046   int aNt=a->getNumberOfTuples();
8047   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8048   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8049   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8050     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8051   const int *valsSrc=a->getConstPointer();
8052   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8053     {
8054       if(*tuple>=0 && *tuple<aNt)
8055         {
8056           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8057         }
8058       else
8059         {
8060           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8061           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8062           throw INTERP_KERNEL::Exception(oss.str().c_str());
8063         }
8064     }
8065 }
8066
8067 /*!
8068  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8069  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8070  * components.
8071  * The tuples to copy are defined by three values similar to parameters of
8072  * the Python function \c range(\c start,\c stop,\c step).
8073  * The tuples to assign to are defined by index of the first tuple, and
8074  * their number is defined by number of tuples to copy.
8075  * All components of selected tuples are copied.
8076  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8077  *              values to.
8078  *  \param [in] aBase - the array to copy values from.
8079  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8080  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8081  *              are located.
8082  *  \param [in] step - index increment to get index of the next tuple to copy.
8083  *  \throw If \a this is not allocated.
8084  *  \throw If \a aBase is NULL.
8085  *  \throw If \a aBase is not allocated.
8086  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8087  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8088  *  \throw If parameters specifying tuples to copy, do not give a
8089  *            non-empty range of increasing indices or indices are out of a valid range
8090  *            for the array \a aBase.
8091  */
8092 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
8093 {
8094   if(!aBase)
8095     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8096   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8097   if(!a)
8098     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8099   checkAllocated();
8100   a->checkAllocated();
8101   int nbOfComp=getNumberOfComponents();
8102   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8103   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8104   if(nbOfComp!=a->getNumberOfComponents())
8105     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8106   int thisNt=getNumberOfTuples();
8107   int aNt=a->getNumberOfTuples();
8108   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8109   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8110     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8111   if(end2>aNt)
8112     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8113   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8114   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8115     {
8116       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8117     }
8118 }
8119
8120 /*!
8121  * Returns a value located at specified tuple and component.
8122  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8123  * parameters is checked. So this method is safe but expensive if used to go through
8124  * all values of \a this.
8125  *  \param [in] tupleId - index of tuple of interest.
8126  *  \param [in] compoId - index of component of interest.
8127  *  \return double - value located by \a tupleId and \a compoId.
8128  *  \throw If \a this is not allocated.
8129  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8130  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8131  */
8132 int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
8133 {
8134   checkAllocated();
8135   if(tupleId<0 || tupleId>=getNumberOfTuples())
8136     {
8137       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8138       throw INTERP_KERNEL::Exception(oss.str().c_str());
8139     }
8140   if(compoId<0 || compoId>=getNumberOfComponents())
8141     {
8142       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8143       throw INTERP_KERNEL::Exception(oss.str().c_str());
8144     }
8145   return _mem[tupleId*_info_on_compo.size()+compoId];
8146 }
8147
8148 /*!
8149  * Returns the first value of \a this. 
8150  *  \return int - the last value of \a this array.
8151  *  \throw If \a this is not allocated.
8152  *  \throw If \a this->getNumberOfComponents() != 1.
8153  *  \throw If \a this->getNumberOfTuples() < 1.
8154  */
8155 int DataArrayInt::front() const throw(INTERP_KERNEL::Exception)
8156 {
8157   checkAllocated();
8158   if(getNumberOfComponents()!=1)
8159     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8160   int nbOfTuples=getNumberOfTuples();
8161   if(nbOfTuples<1)
8162     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8163   return *(getConstPointer());
8164 }
8165
8166 /*!
8167  * Returns the last value of \a this. 
8168  *  \return int - the last value of \a this array.
8169  *  \throw If \a this is not allocated.
8170  *  \throw If \a this->getNumberOfComponents() != 1.
8171  *  \throw If \a this->getNumberOfTuples() < 1.
8172  */
8173 int DataArrayInt::back() const throw(INTERP_KERNEL::Exception)
8174 {
8175   checkAllocated();
8176   if(getNumberOfComponents()!=1)
8177     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8178   int nbOfTuples=getNumberOfTuples();
8179   if(nbOfTuples<1)
8180     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8181   return *(getConstPointer()+nbOfTuples-1);
8182 }
8183
8184 /*!
8185  * Assign pointer to one array to a pointer to another appay. Reference counter of
8186  * \a arrayToSet is incremented / decremented.
8187  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8188  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8189  */
8190 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8191 {
8192   if(newArray!=arrayToSet)
8193     {
8194       if(arrayToSet)
8195         arrayToSet->decrRef();
8196       arrayToSet=newArray;
8197       if(arrayToSet)
8198         arrayToSet->incrRef();
8199     }
8200 }
8201
8202 DataArrayIntIterator *DataArrayInt::iterator() throw(INTERP_KERNEL::Exception)
8203 {
8204   return new DataArrayIntIterator(this);
8205 }
8206
8207 /*!
8208  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8209  * given one.
8210  *  \param [in] val - the value to find within \a this.
8211  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8212  *          array using decrRef() as it is no more needed.
8213  *  \throw If \a this is not allocated.
8214  *  \throw If \a this->getNumberOfComponents() != 1.
8215  */
8216 DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception)
8217 {
8218   checkAllocated();
8219   if(getNumberOfComponents()!=1)
8220     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8221   const int *cptr=getConstPointer();
8222   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8223   int nbOfTuples=getNumberOfTuples();
8224   for(int i=0;i<nbOfTuples;i++,cptr++)
8225     if(*cptr==val)
8226       ret->pushBackSilent(i);
8227   return ret.retn();
8228 }
8229
8230 /*!
8231  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8232  * equal to a given one. 
8233  *  \param [in] val - the value to ignore within \a this.
8234  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8235  *          array using decrRef() as it is no more needed.
8236  *  \throw If \a this is not allocated.
8237  *  \throw If \a this->getNumberOfComponents() != 1.
8238  */
8239 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception)
8240 {
8241   checkAllocated();
8242   if(getNumberOfComponents()!=1)
8243     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8244   const int *cptr=getConstPointer();
8245   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8246   int nbOfTuples=getNumberOfTuples();
8247   for(int i=0;i<nbOfTuples;i++,cptr++)
8248     if(*cptr!=val)
8249       ret->pushBackSilent(i);
8250   return ret.retn();
8251 }
8252
8253
8254 /*!
8255  * Assigns \a newValue to all elements holding \a oldValue within \a this
8256  * one-dimensional array.
8257  *  \param [in] oldValue - the value to replace.
8258  *  \param [in] newValue - the value to assign.
8259  *  \return int - number of replacements performed.
8260  *  \throw If \a this is not allocated.
8261  *  \throw If \a this->getNumberOfComponents() != 1.
8262  */
8263 int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception)
8264 {
8265   checkAllocated();
8266   if(getNumberOfComponents()!=1)
8267     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8268   int *start=getPointer();
8269   int *end2=start+getNbOfElems();
8270   int ret=0;
8271   for(int *val=start;val!=end2;val++)
8272     {
8273       if(*val==oldValue)
8274         {
8275           *val=newValue;
8276           ret++;
8277         }
8278     }
8279   return ret;
8280 }
8281
8282 /*!
8283  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8284  * one of given values.
8285  *  \param [in] valsBg - an array of values to find within \a this array.
8286  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8287  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8288  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8289  *          array using decrRef() as it is no more needed.
8290  *  \throw If \a this->getNumberOfComponents() != 1.
8291  */
8292 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
8293 {
8294   if(getNumberOfComponents()!=1)
8295     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8296   std::set<int> vals2(valsBg,valsEnd);
8297   const int *cptr=getConstPointer();
8298   std::vector<int> res;
8299   int nbOfTuples=getNumberOfTuples();
8300   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8301   for(int i=0;i<nbOfTuples;i++,cptr++)
8302     if(vals2.find(*cptr)!=vals2.end())
8303       ret->pushBackSilent(i);
8304   return ret.retn();
8305 }
8306
8307 /*!
8308  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8309  * equal to any of given values.
8310  *  \param [in] valsBg - an array of values to ignore within \a this array.
8311  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8312  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8313  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8314  *          array using decrRef() as it is no more needed.
8315  *  \throw If \a this->getNumberOfComponents() != 1.
8316  */
8317 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
8318 {
8319   if(getNumberOfComponents()!=1)
8320     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8321   std::set<int> vals2(valsBg,valsEnd);
8322   const int *cptr=getConstPointer();
8323   std::vector<int> res;
8324   int nbOfTuples=getNumberOfTuples();
8325   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8326   for(int i=0;i<nbOfTuples;i++,cptr++)
8327     if(vals2.find(*cptr)==vals2.end())
8328       ret->pushBackSilent(i);
8329   return ret.retn();
8330 }
8331
8332 /*!
8333  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8334  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8335  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8336  * If any the tuple id is returned. If not -1 is returned.
8337  * 
8338  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8339  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8340  *
8341  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8342  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8343  */
8344 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8345 {
8346   checkAllocated();
8347   int nbOfCompo=getNumberOfComponents();
8348   if(nbOfCompo==0)
8349     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8350   if(nbOfCompo!=(int)tupl.size())
8351     {
8352       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8353       throw INTERP_KERNEL::Exception(oss.str().c_str());
8354     }
8355   const int *cptr=getConstPointer();
8356   std::size_t nbOfVals=getNbOfElems();
8357   for(const int *work=cptr;work!=cptr+nbOfVals;)
8358     {
8359       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8360       if(work!=cptr+nbOfVals)
8361         {
8362           if(std::distance(cptr,work)%nbOfCompo!=0)
8363             work++;
8364           else
8365             return std::distance(cptr,work)/nbOfCompo;
8366         }
8367     }
8368   return -1;
8369 }
8370
8371 /*!
8372  * This method searches the sequence specified in input parameter \b vals in \b this.
8373  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8374  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8375  * \sa DataArrayInt::locateTuple
8376  */
8377 int DataArrayInt::search(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8378 {
8379   checkAllocated();
8380   int nbOfCompo=getNumberOfComponents();
8381   if(nbOfCompo!=1)
8382     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8383   const int *cptr=getConstPointer();
8384   std::size_t nbOfVals=getNbOfElems();
8385   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8386   if(loc!=cptr+nbOfVals)
8387     return std::distance(cptr,loc);
8388   return -1;
8389 }
8390
8391 /*!
8392  * This method expects to be called when number of components of this is equal to one.
8393  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8394  * If not any tuple contains \b value -1 is returned.
8395  * \sa DataArrayInt::presenceOfValue
8396  */
8397 int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception)
8398 {
8399   checkAllocated();
8400   if(getNumberOfComponents()!=1)
8401     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8402   const int *cptr=getConstPointer();
8403   int nbOfTuples=getNumberOfTuples();
8404   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8405   if(ret!=cptr+nbOfTuples)
8406     return std::distance(cptr,ret);
8407   return -1;
8408 }
8409
8410 /*!
8411  * This method expects to be called when number of components of this is equal to one.
8412  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8413  * If not any tuple contains one of the values contained in 'vals' false is returned.
8414  * \sa DataArrayInt::presenceOfValue
8415  */
8416 int DataArrayInt::locateValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8417 {
8418   checkAllocated();
8419   if(getNumberOfComponents()!=1)
8420     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8421   std::set<int> vals2(vals.begin(),vals.end());
8422   const int *cptr=getConstPointer();
8423   int nbOfTuples=getNumberOfTuples();
8424   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8425     if(vals2.find(*w)!=vals2.end())
8426       return std::distance(cptr,w);
8427   return -1;
8428 }
8429
8430 /*!
8431  * This method returns the number of values in \a this that are equals to input parameter \a value.
8432  * This method only works for single component array.
8433  *
8434  * \return a value in [ 0, \c this->getNumberOfTuples() )
8435  *
8436  * \throw If \a this is not allocated
8437  *
8438  */
8439 int DataArrayInt::count(int value) const throw(INTERP_KERNEL::Exception)
8440 {
8441   int ret=0;
8442   checkAllocated();
8443   if(getNumberOfComponents()!=1)
8444     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8445   const int *vals=begin();
8446   int nbOfTuples=getNumberOfTuples();
8447   for(int i=0;i<nbOfTuples;i++,vals++)
8448     if(*vals==value)
8449       ret++;
8450   return ret;
8451 }
8452
8453 /*!
8454  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8455  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8456  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8457  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8458  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8459  * \sa DataArrayInt::locateTuple
8460  */
8461 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8462 {
8463   return locateTuple(tupl)!=-1;
8464 }
8465
8466
8467 /*!
8468  * Returns \a true if a given value is present within \a this one-dimensional array.
8469  *  \param [in] value - the value to find within \a this array.
8470  *  \return bool - \a true in case if \a value is present within \a this array.
8471  *  \throw If \a this is not allocated.
8472  *  \throw If \a this->getNumberOfComponents() != 1.
8473  *  \sa locateValue()
8474  */
8475 bool DataArrayInt::presenceOfValue(int value) const throw(INTERP_KERNEL::Exception)
8476 {
8477   return locateValue(value)!=-1;
8478 }
8479
8480 /*!
8481  * This method expects to be called when number of components of this is equal to one.
8482  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8483  * If not any tuple contains one of the values contained in 'vals' false is returned.
8484  * \sa DataArrayInt::locateValue
8485  */
8486 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8487 {
8488   return locateValue(vals)!=-1;
8489 }
8490
8491 /*!
8492  * Accumulates values of each component of \a this array.
8493  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8494  *         by the caller, that is filled by this method with sum value for each
8495  *         component.
8496  *  \throw If \a this is not allocated.
8497  */
8498 void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception)
8499 {
8500   checkAllocated();
8501   const int *ptr=getConstPointer();
8502   int nbTuple=getNumberOfTuples();
8503   int nbComps=getNumberOfComponents();
8504   std::fill(res,res+nbComps,0);
8505   for(int i=0;i<nbTuple;i++)
8506     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8507 }
8508
8509 int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
8510 {
8511   checkAllocated();
8512   const int *ptr=getConstPointer();
8513   int nbTuple=getNumberOfTuples();
8514   int nbComps=getNumberOfComponents();
8515   if(compId<0 || compId>=nbComps)
8516     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8517   int ret=0;
8518   for(int i=0;i<nbTuple;i++)
8519     ret+=ptr[i*nbComps+compId];
8520   return ret;
8521 }
8522
8523 /*!
8524  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8525  * The returned array will have same number of components than \a this and number of tuples equal to
8526  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8527  *
8528  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8529  *
8530  * \param [in] bgOfIndex - begin (included) of the input index array.
8531  * \param [in] endOfIndex - end (excluded) of the input index array.
8532  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8533  * 
8534  * \throw If bgOfIndex or end is NULL.
8535  * \throw If input index array is not ascendingly sorted.
8536  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8537  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8538  */
8539 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
8540 {
8541   if(!bgOfIndex || !endOfIndex)
8542     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8543   checkAllocated();
8544   int nbCompo=getNumberOfComponents();
8545   int nbOfTuples=getNumberOfTuples();
8546   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8547   if(sz<1)
8548     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8549   sz--;
8550   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8551   const int *w=bgOfIndex;
8552   if(*w<0 || *w>=nbOfTuples)
8553     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8554   const int *srcPt=begin()+(*w)*nbCompo;
8555   int *tmp=ret->getPointer();
8556   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8557     {
8558       std::fill(tmp,tmp+nbCompo,0.);
8559       if(w[1]>=w[0])
8560         {
8561           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8562             {
8563               if(j>=0 && j<nbOfTuples)
8564                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8565               else
8566                 {
8567                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8568                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8569                 }
8570             }
8571         }
8572       else
8573         {
8574           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8575           throw INTERP_KERNEL::Exception(oss.str().c_str());
8576         }
8577     }
8578   ret->copyStringInfoFrom(*this);
8579   return ret.retn();
8580 }
8581
8582 /*!
8583  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8584  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8585  * offsetA2</em> and (2)
8586  * the number of component in the result array is same as that of each of given arrays.
8587  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8588  * Info on components is copied from the first of the given arrays. Number of components
8589  * in the given arrays must be the same.
8590  *  \param [in] a1 - an array to include in the result array.
8591  *  \param [in] a2 - another array to include in the result array.
8592  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8593  *  \return DataArrayInt * - the new instance of DataArrayInt.
8594  *          The caller is to delete this result array using decrRef() as it is no more
8595  *          needed.
8596  *  \throw If either \a a1 or \a a2 is NULL.
8597  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8598  */
8599 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8600 {
8601   if(!a1 || !a2)
8602     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8603   int nbOfComp=a1->getNumberOfComponents();
8604   if(nbOfComp!=a2->getNumberOfComponents())
8605     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8606   int nbOfTuple1=a1->getNumberOfTuples();
8607   int nbOfTuple2=a2->getNumberOfTuples();
8608   DataArrayInt *ret=DataArrayInt::New();
8609   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8610   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8611   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8612   ret->copyStringInfoFrom(*a1);
8613   return ret;
8614 }
8615
8616 /*!
8617  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8618  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8619  * the number of component in the result array is same as that of each of given arrays.
8620  * Info on components is copied from the first of the given arrays. Number of components
8621  * in the given arrays must be  the same.
8622  *  \param [in] arr - a sequence of arrays to include in the result array.
8623  *  \return DataArrayInt * - the new instance of DataArrayInt.
8624  *          The caller is to delete this result array using decrRef() as it is no more
8625  *          needed.
8626  *  \throw If all arrays within \a arr are NULL.
8627  *  \throw If getNumberOfComponents() of arrays within \a arr.
8628  */
8629 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8630 {
8631   std::vector<const DataArrayInt *> a;
8632   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8633     if(*it4)
8634       a.push_back(*it4);
8635   if(a.empty())
8636     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8637   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8638   int nbOfComp=(*it)->getNumberOfComponents();
8639   int nbt=(*it++)->getNumberOfTuples();
8640   for(int i=1;it!=a.end();it++,i++)
8641     {
8642       if((*it)->getNumberOfComponents()!=nbOfComp)
8643         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8644       nbt+=(*it)->getNumberOfTuples();
8645     }
8646   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8647   ret->alloc(nbt,nbOfComp);
8648   int *pt=ret->getPointer();
8649   for(it=a.begin();it!=a.end();it++)
8650     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8651   ret->copyStringInfoFrom(*(a[0]));
8652   return ret.retn();
8653 }
8654
8655 /*!
8656  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8657  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8658  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8659  * 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.
8660  * 
8661  * \return DataArrayInt * - a new object to be managed by the caller.
8662  */
8663 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs) throw(INTERP_KERNEL::Exception)
8664 {
8665   int retSz=1;
8666   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8667     {
8668       if(*it4)
8669         {
8670           (*it4)->checkAllocated();
8671           if((*it4)->getNumberOfComponents()!=1)
8672             {
8673               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8674               throw INTERP_KERNEL::Exception(oss.str().c_str());
8675             }
8676           int nbTupl=(*it4)->getNumberOfTuples();
8677           if(nbTupl<1)
8678             {
8679               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8680               throw INTERP_KERNEL::Exception(oss.str().c_str());
8681             }
8682           if((*it4)->front()!=0)
8683             {
8684               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
8685               throw INTERP_KERNEL::Exception(oss.str().c_str());
8686             }
8687           retSz+=nbTupl-1;
8688         }
8689       else
8690         {
8691           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
8692           throw INTERP_KERNEL::Exception(oss.str().c_str());
8693         }
8694     }
8695   if(arrs.empty())
8696     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
8697   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8698   ret->alloc(retSz,1);
8699   int *pt=ret->getPointer(); *pt++=0;
8700   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
8701     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
8702   ret->copyStringInfoFrom(*(arrs[0]));
8703   return ret.retn();
8704 }
8705
8706 /*!
8707  * Returns the maximal value and its location within \a this one-dimensional array.
8708  *  \param [out] tupleId - index of the tuple holding the maximal value.
8709  *  \return int - the maximal value among all values of \a this array.
8710  *  \throw If \a this->getNumberOfComponents() != 1
8711  *  \throw If \a this->getNumberOfTuples() < 1
8712  */
8713 int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8714 {
8715   checkAllocated();
8716   if(getNumberOfComponents()!=1)
8717     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8718   int nbOfTuples=getNumberOfTuples();
8719   if(nbOfTuples<=0)
8720     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8721   const int *vals=getConstPointer();
8722   const int *loc=std::max_element(vals,vals+nbOfTuples);
8723   tupleId=(int)std::distance(vals,loc);
8724   return *loc;
8725 }
8726
8727 /*!
8728  * Returns the maximal value within \a this array that is allowed to have more than
8729  *  one component.
8730  *  \return int - the maximal value among all values of \a this array.
8731  *  \throw If \a this is not allocated.
8732  */
8733 int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
8734 {
8735   checkAllocated();
8736   const int *loc=std::max_element(begin(),end());
8737   return *loc;
8738 }
8739
8740 /*!
8741  * Returns the minimal value and its location within \a this one-dimensional array.
8742  *  \param [out] tupleId - index of the tuple holding the minimal value.
8743  *  \return int - the minimal value among all values of \a this array.
8744  *  \throw If \a this->getNumberOfComponents() != 1
8745  *  \throw If \a this->getNumberOfTuples() < 1
8746  */
8747 int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8748 {
8749   checkAllocated();
8750   if(getNumberOfComponents()!=1)
8751     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8752   int nbOfTuples=getNumberOfTuples();
8753   if(nbOfTuples<=0)
8754     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8755   const int *vals=getConstPointer();
8756   const int *loc=std::min_element(vals,vals+nbOfTuples);
8757   tupleId=(int)std::distance(vals,loc);
8758   return *loc;
8759 }
8760
8761 /*!
8762  * Returns the minimal value within \a this array that is allowed to have more than
8763  *  one component.
8764  *  \return int - the minimal value among all values of \a this array.
8765  *  \throw If \a this is not allocated.
8766  */
8767 int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
8768 {
8769   checkAllocated();
8770   const int *loc=std::min_element(begin(),end());
8771   return *loc;
8772 }
8773
8774 /*!
8775  * Converts every value of \a this array to its absolute value.
8776  *  \throw If \a this is not allocated.
8777  */
8778 void DataArrayInt::abs() throw(INTERP_KERNEL::Exception)
8779 {
8780   checkAllocated();
8781   int *ptr=getPointer();
8782   std::size_t nbOfElems=getNbOfElems();
8783   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8784   declareAsNew();
8785 }
8786
8787 /*!
8788  * Apply a liner function to a given component of \a this array, so that
8789  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8790  *  \param [in] a - the first coefficient of the function.
8791  *  \param [in] b - the second coefficient of the function.
8792  *  \param [in] compoId - the index of component to modify.
8793  *  \throw If \a this is not allocated.
8794  */
8795 void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception)
8796 {
8797   checkAllocated();
8798   int *ptr=getPointer()+compoId;
8799   int nbOfComp=getNumberOfComponents();
8800   int nbOfTuple=getNumberOfTuples();
8801   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8802     *ptr=a*(*ptr)+b;
8803   declareAsNew();
8804 }
8805
8806 /*!
8807  * Apply a liner function to all elements of \a this array, so that
8808  * an element _x_ becomes \f$ a * x + b \f$.
8809  *  \param [in] a - the first coefficient of the function.
8810  *  \param [in] b - the second coefficient of the function.
8811  *  \throw If \a this is not allocated.
8812  */
8813 void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception)
8814 {
8815   checkAllocated();
8816   int *ptr=getPointer();
8817   std::size_t nbOfElems=getNbOfElems();
8818   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8819     *ptr=a*(*ptr)+b;
8820   declareAsNew();
8821 }
8822
8823 /*!
8824  * Returns a full copy of \a this array except that sign of all elements is reversed.
8825  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8826  *          same number of tuples and component as \a this array.
8827  *          The caller is to delete this result array using decrRef() as it is no more
8828  *          needed.
8829  *  \throw If \a this is not allocated.
8830  */
8831 DataArrayInt *DataArrayInt::negate() const throw(INTERP_KERNEL::Exception)
8832 {
8833   checkAllocated();
8834   DataArrayInt *newArr=DataArrayInt::New();
8835   int nbOfTuples=getNumberOfTuples();
8836   int nbOfComp=getNumberOfComponents();
8837   newArr->alloc(nbOfTuples,nbOfComp);
8838   const int *cptr=getConstPointer();
8839   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8840   newArr->copyStringInfoFrom(*this);
8841   return newArr;
8842 }
8843
8844 /*!
8845  * Modify all elements of \a this array, so that
8846  * an element _x_ becomes \f$ numerator / x \f$.
8847  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8848  *           array, all elements processed before detection of the zero element remain
8849  *           modified.
8850  *  \param [in] numerator - the numerator used to modify array elements.
8851  *  \throw If \a this is not allocated.
8852  *  \throw If there is an element equal to 0 in \a this array.
8853  */
8854 void DataArrayInt::applyInv(int numerator) throw(INTERP_KERNEL::Exception)
8855 {
8856   checkAllocated();
8857   int *ptr=getPointer();
8858   std::size_t nbOfElems=getNbOfElems();
8859   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8860     {
8861       if(*ptr!=0)
8862         {
8863           *ptr=numerator/(*ptr);
8864         }
8865       else
8866         {
8867           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8868           oss << " !";
8869           throw INTERP_KERNEL::Exception(oss.str().c_str());
8870         }
8871     }
8872   declareAsNew();
8873 }
8874
8875 /*!
8876  * Modify all elements of \a this array, so that
8877  * an element _x_ becomes \f$ x / val \f$.
8878  *  \param [in] val - the denominator used to modify array elements.
8879  *  \throw If \a this is not allocated.
8880  *  \throw If \a val == 0.
8881  */
8882 void DataArrayInt::applyDivideBy(int val) throw(INTERP_KERNEL::Exception)
8883 {
8884   if(val==0)
8885     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
8886   checkAllocated();
8887   int *ptr=getPointer();
8888   std::size_t nbOfElems=getNbOfElems();
8889   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
8890   declareAsNew();
8891 }
8892
8893 /*!
8894  * Modify all elements of \a this array, so that
8895  * an element _x_ becomes  <em> x % val </em>.
8896  *  \param [in] val - the divisor used to modify array elements.
8897  *  \throw If \a this is not allocated.
8898  *  \throw If \a val <= 0.
8899  */
8900 void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception)
8901 {
8902   if(val<=0)
8903     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
8904   checkAllocated();
8905   int *ptr=getPointer();
8906   std::size_t nbOfElems=getNbOfElems();
8907   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
8908   declareAsNew();
8909 }
8910
8911 /*!
8912  * This method works only on data array with one component.
8913  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
8914  * this[*id] in [\b vmin,\b vmax)
8915  * 
8916  * \param [in] vmin begin of range. This value is included in range (included).
8917  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8918  * \return a newly allocated data array that the caller should deal with.
8919  */
8920 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8921 {
8922   checkAllocated();
8923   if(getNumberOfComponents()!=1)
8924     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
8925   const int *cptr=getConstPointer();
8926   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
8927   int nbOfTuples=getNumberOfTuples();
8928   for(int i=0;i<nbOfTuples;i++,cptr++)
8929     if(*cptr>=vmin && *cptr<vmax)
8930       ret->pushBackSilent(i);
8931   return ret.retn();
8932 }
8933
8934 /*!
8935  * This method works only on data array with one component.
8936  * 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.
8937  * 
8938  * \param [in] vmin begin of range. This value is included in range (included).
8939  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8940  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ).
8941  */
8942 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8943 {
8944   checkAllocated();
8945   if(getNumberOfComponents()!=1)
8946     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
8947   int nbOfTuples=getNumberOfTuples();
8948   bool ret=true;
8949   const int *cptr=getConstPointer();
8950   for(int i=0;i<nbOfTuples;i++,cptr++)
8951     {
8952       if(*cptr>=vmin && *cptr<vmax)
8953         { ret=ret && *cptr==i; }
8954       else
8955         {
8956           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
8957           throw INTERP_KERNEL::Exception(oss.str().c_str());
8958         }
8959     }
8960   return ret;
8961 }
8962
8963 /*!
8964  * Modify all elements of \a this array, so that
8965  * an element _x_ becomes <em> val % x </em>.
8966  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
8967  *           array, all elements processed before detection of the zero element remain
8968  *           modified.
8969  *  \param [in] val - the divident used to modify array elements.
8970  *  \throw If \a this is not allocated.
8971  *  \throw If there is an element equal to or less than 0 in \a this array.
8972  */
8973 void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception)
8974 {
8975   checkAllocated();
8976   int *ptr=getPointer();
8977   std::size_t nbOfElems=getNbOfElems();
8978   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8979     {
8980       if(*ptr>0)
8981         {
8982           *ptr=val%(*ptr);
8983         }
8984       else
8985         {
8986           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8987           oss << " !";
8988           throw INTERP_KERNEL::Exception(oss.str().c_str());
8989         }
8990     }
8991   declareAsNew();
8992 }
8993
8994 /*!
8995  * Modify all elements of \a this array, so that
8996  * an element _x_ becomes <em> val ^ x </em>.
8997  *  \param [in] val - the value used to apply pow on all array elements.
8998  *  \throw If \a this is not allocated.
8999  *  \throw If \a val < 0.
9000  */
9001 void DataArrayInt::applyPow(int val) throw(INTERP_KERNEL::Exception)
9002 {
9003   checkAllocated();
9004   if(val<0)
9005     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9006   int *ptr=getPointer();
9007   std::size_t nbOfElems=getNbOfElems();
9008   if(val==0)
9009     {
9010       std::fill(ptr,ptr+nbOfElems,1.);
9011       return ;
9012     }
9013   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9014     {
9015       int tmp=1;
9016       for(int j=0;j<val;j++)
9017         tmp*=*ptr;
9018       *ptr=tmp;
9019     }
9020   declareAsNew();
9021 }
9022
9023 /*!
9024  * Modify all elements of \a this array, so that
9025  * an element _x_ becomes \f$ val ^ x \f$.
9026  *  \param [in] val - the value used to apply pow on all array elements.
9027  *  \throw If \a this is not allocated.
9028  *  \throw If there is an element < 0 in \a this array.
9029  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9030  *           array, all elements processed before detection of the zero element remain
9031  *           modified.
9032  */
9033 void DataArrayInt::applyRPow(int val) throw(INTERP_KERNEL::Exception)
9034 {
9035   checkAllocated();
9036   int *ptr=getPointer();
9037   std::size_t nbOfElems=getNbOfElems();
9038   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9039     {
9040       if(*ptr>=0)
9041         {
9042           int tmp=1;
9043           for(int j=0;j<*ptr;j++)
9044             tmp*=val;
9045           *ptr=tmp;
9046         }
9047       else
9048         {
9049           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9050           oss << " !";
9051           throw INTERP_KERNEL::Exception(oss.str().c_str());
9052         }
9053     }
9054   declareAsNew();
9055 }
9056
9057 /*!
9058  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9059  * of components in the result array is a sum of the number of components of given arrays
9060  * and (2) the number of tuples in the result array is same as that of each of given
9061  * arrays. In other words the i-th tuple of result array includes all components of
9062  * i-th tuples of all given arrays.
9063  * Number of tuples in the given arrays must be the same.
9064  *  \param [in] a1 - an array to include in the result array.
9065  *  \param [in] a2 - another array to include in the result array.
9066  *  \return DataArrayInt * - the new instance of DataArrayInt.
9067  *          The caller is to delete this result array using decrRef() as it is no more
9068  *          needed.
9069  *  \throw If both \a a1 and \a a2 are NULL.
9070  *  \throw If any given array is not allocated.
9071  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9072  */
9073 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9074 {
9075   std::vector<const DataArrayInt *> arr(2);
9076   arr[0]=a1; arr[1]=a2;
9077   return Meld(arr);
9078 }
9079
9080 /*!
9081  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9082  * of components in the result array is a sum of the number of components of given arrays
9083  * and (2) the number of tuples in the result array is same as that of each of given
9084  * arrays. In other words the i-th tuple of result array includes all components of
9085  * i-th tuples of all given arrays.
9086  * Number of tuples in the given arrays must be  the same.
9087  *  \param [in] arr - a sequence of arrays to include in the result array.
9088  *  \return DataArrayInt * - the new instance of DataArrayInt.
9089  *          The caller is to delete this result array using decrRef() as it is no more
9090  *          needed.
9091  *  \throw If all arrays within \a arr are NULL.
9092  *  \throw If any given array is not allocated.
9093  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9094  */
9095 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
9096 {
9097   std::vector<const DataArrayInt *> a;
9098   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9099     if(*it4)
9100       a.push_back(*it4);
9101   if(a.empty())
9102     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9103   std::vector<const DataArrayInt *>::const_iterator it;
9104   for(it=a.begin();it!=a.end();it++)
9105     (*it)->checkAllocated();
9106   it=a.begin();
9107   int nbOfTuples=(*it)->getNumberOfTuples();
9108   std::vector<int> nbc(a.size());
9109   std::vector<const int *> pts(a.size());
9110   nbc[0]=(*it)->getNumberOfComponents();
9111   pts[0]=(*it++)->getConstPointer();
9112   for(int i=1;it!=a.end();it++,i++)
9113     {
9114       if(nbOfTuples!=(*it)->getNumberOfTuples())
9115         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9116       nbc[i]=(*it)->getNumberOfComponents();
9117       pts[i]=(*it)->getConstPointer();
9118     }
9119   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9120   DataArrayInt *ret=DataArrayInt::New();
9121   ret->alloc(nbOfTuples,totalNbOfComp);
9122   int *retPtr=ret->getPointer();
9123   for(int i=0;i<nbOfTuples;i++)
9124     for(int j=0;j<(int)a.size();j++)
9125       {
9126         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9127         pts[j]+=nbc[j];
9128       }
9129   int k=0;
9130   for(int i=0;i<(int)a.size();i++)
9131     for(int j=0;j<nbc[i];j++,k++)
9132       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
9133   return ret;
9134 }
9135
9136 /*!
9137  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9138  * The i-th item of the result array is an ID of a set of elements belonging to a
9139  * unique set of groups, which the i-th element is a part of. This set of elements
9140  * belonging to a unique set of groups is called \a family, so the result array contains
9141  * IDs of families each element belongs to.
9142  *
9143  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9144  * then there are 3 families:
9145  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9146  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9147  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9148  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9149  * stands for the element #3 which is in none of groups.
9150  *
9151  *  \param [in] groups - sequence of groups of element IDs.
9152  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9153  *         in \a groups.
9154  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9155  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9156  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9157  *         delete this array using decrRef() as it is no more needed.
9158  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9159  */
9160 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) throw(INTERP_KERNEL::Exception)
9161 {
9162   std::vector<const DataArrayInt *> groups2;
9163   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9164     if(*it4)
9165       groups2.push_back(*it4);
9166   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9167   ret->alloc(newNb,1);
9168   int *retPtr=ret->getPointer();
9169   std::fill(retPtr,retPtr+newNb,0);
9170   int fid=1;
9171   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9172     {
9173       const int *ptr=(*iter)->getConstPointer();
9174       std::size_t nbOfElem=(*iter)->getNbOfElems();
9175       int sfid=fid;
9176       for(int j=0;j<sfid;j++)
9177         {
9178           bool found=false;
9179           for(std::size_t i=0;i<nbOfElem;i++)
9180             {
9181               if(ptr[i]>=0 && ptr[i]<newNb)
9182                 {
9183                   if(retPtr[ptr[i]]==j)
9184                     {
9185                       retPtr[ptr[i]]=fid;
9186                       found=true;
9187                     }
9188                 }
9189               else
9190                 {
9191                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9192                   oss << ") !";
9193                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9194                 }
9195             }
9196           if(found)
9197             fid++;
9198         }
9199     }
9200   fidsOfGroups.clear();
9201   fidsOfGroups.resize(groups2.size());
9202   int grId=0;
9203   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9204     {
9205       std::set<int> tmp;
9206       const int *ptr=(*iter)->getConstPointer();
9207       std::size_t nbOfElem=(*iter)->getNbOfElems();
9208       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9209         tmp.insert(retPtr[*p]);
9210       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9211     }
9212   return ret.retn();
9213 }
9214
9215 /*!
9216  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9217  * arrays. The result array does not contain any duplicates and its values
9218  * are sorted in ascending order.
9219  *  \param [in] arr - sequence of DataArrayInt's to unite.
9220  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9221  *         array using decrRef() as it is no more needed.
9222  *  \throw If any \a arr[i] is not allocated.
9223  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9224  */
9225 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
9226 {
9227   std::vector<const DataArrayInt *> a;
9228   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9229     if(*it4)
9230       a.push_back(*it4);
9231   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9232     {
9233       (*it)->checkAllocated();
9234       if((*it)->getNumberOfComponents()!=1)
9235         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9236     }
9237   //
9238   std::set<int> r;
9239   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9240     {
9241       const int *pt=(*it)->getConstPointer();
9242       int nbOfTuples=(*it)->getNumberOfTuples();
9243       r.insert(pt,pt+nbOfTuples);
9244     }
9245   DataArrayInt *ret=DataArrayInt::New();
9246   ret->alloc((int)r.size(),1);
9247   std::copy(r.begin(),r.end(),ret->getPointer());
9248   return ret;
9249 }
9250
9251 /*!
9252  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9253  * arrays. The result array does not contain any duplicates and its values
9254  * are sorted in ascending order.
9255  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9256  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9257  *         array using decrRef() as it is no more needed.
9258  *  \throw If any \a arr[i] is not allocated.
9259  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9260  */
9261 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
9262 {
9263   std::vector<const DataArrayInt *> a;
9264   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9265     if(*it4)
9266       a.push_back(*it4);
9267   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9268     {
9269       (*it)->checkAllocated();
9270       if((*it)->getNumberOfComponents()!=1)
9271         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9272     }
9273   //
9274   std::set<int> r;
9275   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9276     {
9277       const int *pt=(*it)->getConstPointer();
9278       int nbOfTuples=(*it)->getNumberOfTuples();
9279       std::set<int> s1(pt,pt+nbOfTuples);
9280       if(it!=a.begin())
9281         {
9282           std::set<int> r2;
9283           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9284           r=r2;
9285         }
9286       else
9287         r=s1;
9288     }
9289   DataArrayInt *ret=DataArrayInt::New();
9290   ret->alloc((int)r.size(),1);
9291   std::copy(r.begin(),r.end(),ret->getPointer());
9292   return ret;
9293 }
9294
9295 /*!
9296  * Returns a new DataArrayInt which contains a complement of elements of \a this
9297  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9298  * \a nbOfElement) not present in \a this array.
9299  *  \param [in] nbOfElement - maximal size of the result array.
9300  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9301  *         array using decrRef() as it is no more needed.
9302  *  \throw If \a this is not allocated.
9303  *  \throw If \a this->getNumberOfComponents() != 1.
9304  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9305  *         nbOfElement ).
9306  */
9307 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception)
9308 {
9309    checkAllocated();
9310    if(getNumberOfComponents()!=1)
9311      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9312    std::vector<bool> tmp(nbOfElement);
9313    const int *pt=getConstPointer();
9314    int nbOfTuples=getNumberOfTuples();
9315    for(const int *w=pt;w!=pt+nbOfTuples;w++)
9316      if(*w>=0 && *w<nbOfElement)
9317        tmp[*w]=true;
9318      else
9319        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9320    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9321    DataArrayInt *ret=DataArrayInt::New();
9322    ret->alloc(nbOfRetVal,1);
9323    int j=0;
9324    int *retPtr=ret->getPointer();
9325    for(int i=0;i<nbOfElement;i++)
9326      if(!tmp[i])
9327        retPtr[j++]=i;
9328    return ret;
9329 }
9330
9331 /*!
9332  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9333  * from an \a other one-dimensional array.
9334  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9335  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9336  *         caller is to delete this array using decrRef() as it is no more needed.
9337  *  \throw If \a other is NULL.
9338  *  \throw If \a other is not allocated.
9339  *  \throw If \a other->getNumberOfComponents() != 1.
9340  *  \throw If \a this is not allocated.
9341  *  \throw If \a this->getNumberOfComponents() != 1.
9342  *  \sa DataArrayInt::buildSubstractionOptimized()
9343  */
9344 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9345 {
9346   if(!other)
9347     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9348   checkAllocated();
9349   other->checkAllocated();
9350   if(getNumberOfComponents()!=1)
9351      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9352   if(other->getNumberOfComponents()!=1)
9353      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9354   const int *pt=getConstPointer();
9355   int nbOfTuples=getNumberOfTuples();
9356   std::set<int> s1(pt,pt+nbOfTuples);
9357   pt=other->getConstPointer();
9358   nbOfTuples=other->getNumberOfTuples();
9359   std::set<int> s2(pt,pt+nbOfTuples);
9360   std::vector<int> r;
9361   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9362   DataArrayInt *ret=DataArrayInt::New();
9363   ret->alloc((int)r.size(),1);
9364   std::copy(r.begin(),r.end(),ret->getPointer());
9365   return ret;
9366 }
9367
9368 /*!
9369  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9370  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9371  * 
9372  * \param [in] other an array with one component and expected to be sorted ascendingly.
9373  * \ret list of ids in \a this but not in \a other.
9374  * \sa DataArrayInt::buildSubstraction
9375  */
9376 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9377 {
9378   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9379   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9380   checkAllocated(); other->checkAllocated();
9381   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9382   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9383   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
9384   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9385   for(;work1!=pt1End;work1++)
9386     {
9387       if(work2!=pt2End && *work1==*work2)
9388         work2++;
9389       else
9390         ret->pushBackSilent(*work1);
9391     }
9392   return ret.retn();
9393 }
9394
9395
9396 /*!
9397  * Returns a new DataArrayInt which contains all elements of \a this and a given
9398  * one-dimensional arrays. The result array does not contain any duplicates
9399  * and its values are sorted in ascending order.
9400  *  \param [in] other - an array to unite with \a this one.
9401  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9402  *         array using decrRef() as it is no more needed.
9403  *  \throw If \a this or \a other is not allocated.
9404  *  \throw If \a this->getNumberOfComponents() != 1.
9405  *  \throw If \a other->getNumberOfComponents() != 1.
9406  */
9407 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9408 {
9409   std::vector<const DataArrayInt *>arrs(2);
9410   arrs[0]=this; arrs[1]=other;
9411   return BuildUnion(arrs);
9412 }
9413
9414
9415 /*!
9416  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9417  * one-dimensional arrays. The result array does not contain any duplicates
9418  * and its values are sorted in ascending order.
9419  *  \param [in] other - an array to intersect with \a this one.
9420  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9421  *         array using decrRef() as it is no more needed.
9422  *  \throw If \a this or \a other is not allocated.
9423  *  \throw If \a this->getNumberOfComponents() != 1.
9424  *  \throw If \a other->getNumberOfComponents() != 1.
9425  */
9426 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9427 {
9428   std::vector<const DataArrayInt *>arrs(2);
9429   arrs[0]=this; arrs[1]=other;
9430   return BuildIntersection(arrs);
9431 }
9432
9433 /*!
9434  * This method can be applied on allocated with one component DataArrayInt instance.
9435  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9436  * 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]
9437  * 
9438  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9439  * \throw if \a this is not allocated or if \a this has not exactly one component.
9440  */
9441 DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
9442 {
9443   checkAllocated();
9444   if(getNumberOfComponents()!=1)
9445      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9446   int nbOfTuples=getNumberOfTuples();
9447   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9448   int *data=tmp->getPointer();
9449   int *last=std::unique(data,data+nbOfTuples);
9450   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9451   ret->alloc(std::distance(data,last),1);
9452   std::copy(data,last,ret->getPointer());
9453   return ret.retn();
9454 }
9455
9456 /*!
9457  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9458  * "index" array. Such "index" array is returned for example by 
9459  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9460  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9461  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9462  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9463  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
9464  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9465  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9466  *          The caller is to delete this array using decrRef() as it is no more needed. 
9467  *  \throw If \a this is not allocated.
9468  *  \throw If \a this->getNumberOfComponents() != 1.
9469  *  \throw If \a this->getNumberOfTuples() < 2.
9470  *
9471  *  \b Example: <br> 
9472  *         - this contains [1,3,6,7,7,9,15]
9473  *         - result array contains [2,3,1,0,2,6],
9474  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9475  *
9476  * \sa DataArrayInt::computeOffsets2
9477  */
9478 DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception)
9479 {
9480   checkAllocated();
9481   if(getNumberOfComponents()!=1)
9482      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9483   int nbOfTuples=getNumberOfTuples();
9484   if(nbOfTuples<2)
9485     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9486   const int *ptr=getConstPointer();
9487   DataArrayInt *ret=DataArrayInt::New();
9488   ret->alloc(nbOfTuples-1,1);
9489   int *out=ret->getPointer();
9490   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9491   return ret;
9492 }
9493
9494 /*!
9495  * Modifies \a this one-dimensional array so that value of each element \a x
9496  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9497  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9498  * and components remains the same.<br>
9499  * This method is useful for allToAllV in MPI with contiguous policy. This method
9500  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9501  * this one.
9502  *  \throw If \a this is not allocated.
9503  *  \throw If \a this->getNumberOfComponents() != 1.
9504  *
9505  *  \b Example: <br>
9506  *          - Before \a this contains [3,5,1,2,0,8]
9507  *          - After \a this contains  [0,3,8,9,11,11]<br>
9508  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9509  *          array is retained and thus there is no space to store the last element.
9510  */
9511 void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception)
9512 {
9513   checkAllocated();
9514   if(getNumberOfComponents()!=1)
9515      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9516   int nbOfTuples=getNumberOfTuples();
9517   if(nbOfTuples==0)
9518     return ;
9519   int *work=getPointer();
9520   int tmp=work[0];
9521   work[0]=0;
9522   for(int i=1;i<nbOfTuples;i++)
9523     {
9524       int tmp2=work[i];
9525       work[i]=work[i-1]+tmp;
9526       tmp=tmp2;
9527     }
9528   declareAsNew();
9529 }
9530
9531
9532 /*!
9533  * Modifies \a this one-dimensional array so that value of each element \a x
9534  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9535  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9536  * components remains the same and number of tuples is inceamented by one.<br>
9537  * This method is useful for allToAllV in MPI with contiguous policy. This method
9538  * differs from computeOffsets() in that the number of tuples is changed by this one.
9539  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9540  *  \throw If \a this is not allocated.
9541  *  \throw If \a this->getNumberOfComponents() != 1.
9542  *
9543  *  \b Example: <br>
9544  *          - Before \a this contains [3,5,1,2,0,8]
9545  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9546  * \sa DataArrayInt::deltaShiftIndex
9547  */
9548 void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
9549 {
9550   checkAllocated();
9551   if(getNumberOfComponents()!=1)
9552     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9553   int nbOfTuples=getNumberOfTuples();
9554   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9555   if(nbOfTuples==0)
9556     return ;
9557   const int *work=getConstPointer();
9558   ret[0]=0;
9559   for(int i=0;i<nbOfTuples;i++)
9560     ret[i+1]=work[i]+ret[i];
9561   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9562   declareAsNew();
9563 }
9564
9565 /*!
9566  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9567  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9568  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9569  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9570  * filling completely one of the ranges in \a this.
9571  *
9572  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9573  * \param [out] rangeIdsFetched the range ids fetched
9574  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9575  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9576  *
9577  * \sa DataArrayInt::computeOffsets2
9578  *
9579  *  \b Example: <br>
9580  *          - \a this : [0,3,7,9,15,18]
9581  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9582  *          - \a rangeIdsFetched result array: [0,2,4]
9583  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9584  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9585  * <br>
9586  */
9587 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const throw(INTERP_KERNEL::Exception)
9588 {
9589   if(!listOfIds)
9590     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
9591   listOfIds->checkAllocated(); checkAllocated();
9592   if(listOfIds->getNumberOfComponents()!=1)
9593     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
9594   if(getNumberOfComponents()!=1)
9595     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
9596   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
9597   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
9598   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
9599   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
9600   while(tupPtr!=tupEnd && offPtr!=offEnd)
9601     {
9602       if(*tupPtr==*offPtr)
9603         {
9604           int i=offPtr[0];
9605           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
9606           if(i==offPtr[1])
9607             {
9608               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
9609               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
9610               offPtr++;
9611             }
9612         }
9613       else
9614         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
9615     }
9616   rangeIdsFetched=ret0.retn();
9617   idsInInputListThatFetch=ret1.retn();
9618 }
9619
9620 /*!
9621  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
9622  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9623  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9624  * beginning within the "iota" array. And \a this is a one-dimensional array
9625  * considered as a selector of groups described by \a offsets to include into the result array.
9626  *  \throw If \a offsets is NULL.
9627  *  \throw If \a offsets is not allocated.
9628  *  \throw If \a offsets->getNumberOfComponents() != 1.
9629  *  \throw If \a offsets is not monotonically increasing.
9630  *  \throw If \a this is not allocated.
9631  *  \throw If \a this->getNumberOfComponents() != 1.
9632  *  \throw If any element of \a this is not a valid index for \a offsets array.
9633  *
9634  *  \b Example: <br>
9635  *          - \a this: [0,2,3]
9636  *          - \a offsets: [0,3,6,10,14,20]
9637  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
9638  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
9639  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
9640  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
9641  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
9642  */
9643 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception)
9644 {
9645   if(!offsets)
9646     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
9647   checkAllocated();
9648   if(getNumberOfComponents()!=1)
9649      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
9650   offsets->checkAllocated();
9651   if(offsets->getNumberOfComponents()!=1)
9652      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
9653   int othNbTuples=offsets->getNumberOfTuples()-1;
9654   int nbOfTuples=getNumberOfTuples();
9655   int retNbOftuples=0;
9656   const int *work=getConstPointer();
9657   const int *offPtr=offsets->getConstPointer();
9658   for(int i=0;i<nbOfTuples;i++)
9659     {
9660       int val=work[i];
9661       if(val>=0 && val<othNbTuples)
9662         {
9663           int delta=offPtr[val+1]-offPtr[val];
9664           if(delta>=0)
9665             retNbOftuples+=delta;
9666           else
9667             {
9668               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
9669               throw INTERP_KERNEL::Exception(oss.str().c_str());
9670             }
9671         }
9672       else
9673         {
9674           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
9675           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
9676           throw INTERP_KERNEL::Exception(oss.str().c_str());
9677         }
9678     }
9679   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9680   ret->alloc(retNbOftuples,1);
9681   int *retPtr=ret->getPointer();
9682   for(int i=0;i<nbOfTuples;i++)
9683     {
9684       int val=work[i];
9685       int start=offPtr[val];
9686       int off=offPtr[val+1]-start;
9687       for(int j=0;j<off;j++,retPtr++)
9688         *retPtr=start+j;
9689     }
9690   return ret.retn();
9691 }
9692
9693 /*!
9694  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
9695  * scaled array (monotonically increasing).
9696 from that of \a this and \a
9697  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9698  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9699  * beginning within the "iota" array. And \a this is a one-dimensional array
9700  * considered as a selector of groups described by \a offsets to include into the result array.
9701  *  \throw If \a  is NULL.
9702  *  \throw If \a this is not allocated.
9703  *  \throw If \a this->getNumberOfComponents() != 1.
9704  *  \throw If \a this->getNumberOfTuples() == 0.
9705  *  \throw If \a this is not monotonically increasing.
9706  *  \throw If any element of ids in ( \a gb \a end \a step ) points outside the scale in \a this.
9707  *
9708  *  \b Example: <br>
9709  *          - \a bg , \a end and \a step : (0,5,2)
9710  *          - \a this: [0,3,6,10,14,20]
9711  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
9712  */
9713 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int end, int step) const throw(INTERP_KERNEL::Exception)
9714 {
9715   if(!isAllocated())
9716     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
9717   if(getNumberOfComponents()!=1)
9718     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
9719   int nbOfTuples(getNumberOfTuples());
9720   if(nbOfTuples==0)
9721     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
9722   const int *ids(begin());
9723   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,end,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
9724   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9725     {
9726       if(pos>=0 && pos<nbOfTuples-1)
9727         {
9728           int delta(ids[pos+1]-ids[pos]);
9729           sz+=delta;
9730           if(delta<0)
9731             {
9732               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
9733               throw INTERP_KERNEL::Exception(oss.str().c_str());
9734             }          
9735         }
9736       else
9737         {
9738           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
9739           throw INTERP_KERNEL::Exception(oss.str().c_str());
9740         }
9741     }
9742   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9743   int *retPtr(ret->getPointer());
9744   pos=bg;
9745   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
9746     {
9747       int delta(ids[pos+1]-ids[pos]);
9748       for(int j=0;j<delta;j++,retPtr++)
9749         *retPtr=pos;
9750     }
9751   return ret.retn();
9752 }
9753
9754 /*!
9755  * 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.
9756  * 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
9757  * in tuple **i** of returned DataArrayInt.
9758  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9759  *
9760  * 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)]
9761  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9762  * 
9763  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9764  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9765  * \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
9766  *        is thrown if no ranges in \a ranges contains value in \a this.
9767  * 
9768  * \sa DataArrayInt::findIdInRangeForEachTuple
9769  */
9770 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9771 {
9772   if(!ranges)
9773     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9774   if(ranges->getNumberOfComponents()!=2)
9775     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9776   checkAllocated();
9777   if(getNumberOfComponents()!=1)
9778     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9779   int nbTuples=getNumberOfTuples();
9780   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9781   int nbOfRanges=ranges->getNumberOfTuples();
9782   const int *rangesPtr=ranges->getConstPointer();
9783   int *retPtr=ret->getPointer();
9784   const int *inPtr=getConstPointer();
9785   for(int i=0;i<nbTuples;i++,retPtr++)
9786     {
9787       int val=inPtr[i];
9788       bool found=false;
9789       for(int j=0;j<nbOfRanges && !found;j++)
9790         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9791           { *retPtr=j; found=true; }
9792       if(found)
9793         continue;
9794       else
9795         {
9796           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9797           throw INTERP_KERNEL::Exception(oss.str().c_str());
9798         }
9799     }
9800   return ret.retn();
9801 }
9802
9803 /*!
9804  * 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.
9805  * 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
9806  * in tuple **i** of returned DataArrayInt.
9807  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9808  *
9809  * 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)]
9810  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9811  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9812  * 
9813  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9814  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9815  * \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
9816  *        is thrown if no ranges in \a ranges contains value in \a this.
9817  * \sa DataArrayInt::findRangeIdForEachTuple
9818  */
9819 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9820 {
9821   if(!ranges)
9822     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9823   if(ranges->getNumberOfComponents()!=2)
9824     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9825   checkAllocated();
9826   if(getNumberOfComponents()!=1)
9827     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9828   int nbTuples=getNumberOfTuples();
9829   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9830   int nbOfRanges=ranges->getNumberOfTuples();
9831   const int *rangesPtr=ranges->getConstPointer();
9832   int *retPtr=ret->getPointer();
9833   const int *inPtr=getConstPointer();
9834   for(int i=0;i<nbTuples;i++,retPtr++)
9835     {
9836       int val=inPtr[i];
9837       bool found=false;
9838       for(int j=0;j<nbOfRanges && !found;j++)
9839         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9840           { *retPtr=val-rangesPtr[2*j]; found=true; }
9841       if(found)
9842         continue;
9843       else
9844         {
9845           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
9846           throw INTERP_KERNEL::Exception(oss.str().c_str());
9847         }
9848     }
9849   return ret.retn();
9850 }
9851
9852 /*!
9853  * 
9854  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
9855  *             \a nbTimes  should be at least equal to 1.
9856  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
9857  * \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.
9858  */
9859 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
9860 {
9861   checkAllocated();
9862   if(getNumberOfComponents()!=1)
9863     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
9864   if(nbTimes<1)
9865     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
9866   int nbTuples=getNumberOfTuples();
9867   const int *inPtr=getConstPointer();
9868   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
9869   int *retPtr=ret->getPointer();
9870   for(int i=0;i<nbTuples;i++,inPtr++)
9871     {
9872       int val=*inPtr;
9873       for(int j=0;j<nbTimes;j++,retPtr++)
9874         *retPtr=val;
9875     }
9876   ret->copyStringInfoFrom(*this);
9877   return ret.retn();
9878 }
9879
9880 /*!
9881  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
9882  * But the number of components can be different from one.
9883  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
9884  */
9885 DataArrayInt *DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception)
9886 {
9887   checkAllocated();
9888   std::set<int> ret;
9889   ret.insert(begin(),end());
9890   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
9891   std::copy(ret.begin(),ret.end(),ret2->getPointer());
9892   return ret2.retn();
9893 }
9894
9895 /*!
9896  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
9897  * them it tells which tuple id have this id.
9898  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
9899  * This method returns two arrays having same size.
9900  * 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.
9901  * 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]]
9902  */
9903 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception)
9904 {
9905   checkAllocated();
9906   if(getNumberOfComponents()!=1)
9907     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
9908   int id=0;
9909   std::map<int,int> m,m2,m3;
9910   for(const int *w=begin();w!=end();w++)
9911     m[*w]++;
9912   differentIds.resize(m.size());
9913   std::vector<DataArrayInt *> ret(m.size());
9914   std::vector<int *> retPtr(m.size());
9915   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
9916     {
9917       m2[(*it).first]=id;
9918       ret[id]=DataArrayInt::New();
9919       ret[id]->alloc((*it).second,1);
9920       retPtr[id]=ret[id]->getPointer();
9921       differentIds[id]=(*it).first;
9922     }
9923   id=0;
9924   for(const int *w=begin();w!=end();w++,id++)
9925     {
9926       retPtr[m2[*w]][m3[*w]++]=id;
9927     }
9928   return ret;
9929 }
9930
9931 /*!
9932  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
9933  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
9934  *
9935  * \param [in] nbOfSlices - number of slices expected.
9936  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
9937  * 
9938  * \sa DataArray::GetSlice
9939  * \throw If \a this is not allocated or not with exactly one component.
9940  * \throw If an element in \a this if < 0.
9941  */
9942 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const throw(INTERP_KERNEL::Exception)
9943 {
9944   if(!isAllocated() || getNumberOfComponents()!=1)
9945     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
9946   if(nbOfSlices<=0)
9947     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
9948   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
9949   int sumPerSlc(sum/nbOfSlices),pos(0);
9950   const int *w(begin());
9951   std::vector< std::pair<int,int> > ret(nbOfSlices);
9952   for(int i=0;i<nbOfSlices;i++)
9953     {
9954       std::pair<int,int> p(pos,-1);
9955       int locSum(0);
9956       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
9957       if(i!=nbOfSlices-1)
9958         p.second=pos;
9959       else
9960         p.second=nbOfTuples;
9961       ret[i]=p;
9962     }
9963   return ret;
9964 }
9965
9966 /*!
9967  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
9968  * valid cases.
9969  * 1.  The arrays have same number of tuples and components. Then each value of
9970  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
9971  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
9972  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9973  *   component. Then
9974  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
9975  * 3.  The arrays have same number of components and one array, say _a2_, has one
9976  *   tuple. Then
9977  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
9978  *
9979  * Info on components is copied either from the first array (in the first case) or from
9980  * the array with maximal number of elements (getNbOfElems()).
9981  *  \param [in] a1 - an array to sum up.
9982  *  \param [in] a2 - another array to sum up.
9983  *  \return DataArrayInt * - the new instance of DataArrayInt.
9984  *          The caller is to delete this result array using decrRef() as it is no more
9985  *          needed.
9986  *  \throw If either \a a1 or \a a2 is NULL.
9987  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9988  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9989  *         none of them has number of tuples or components equal to 1.
9990  */
9991 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9992 {
9993   if(!a1 || !a2)
9994     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
9995   int nbOfTuple=a1->getNumberOfTuples();
9996   int nbOfTuple2=a2->getNumberOfTuples();
9997   int nbOfComp=a1->getNumberOfComponents();
9998   int nbOfComp2=a2->getNumberOfComponents();
9999   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10000   if(nbOfTuple==nbOfTuple2)
10001     {
10002       if(nbOfComp==nbOfComp2)
10003         {
10004           ret=DataArrayInt::New();
10005           ret->alloc(nbOfTuple,nbOfComp);
10006           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10007           ret->copyStringInfoFrom(*a1);
10008         }
10009       else
10010         {
10011           int nbOfCompMin,nbOfCompMax;
10012           const DataArrayInt *aMin, *aMax;
10013           if(nbOfComp>nbOfComp2)
10014             {
10015               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10016               aMin=a2; aMax=a1;
10017             }
10018           else
10019             {
10020               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10021               aMin=a1; aMax=a2;
10022             }
10023           if(nbOfCompMin==1)
10024             {
10025               ret=DataArrayInt::New();
10026               ret->alloc(nbOfTuple,nbOfCompMax);
10027               const int *aMinPtr=aMin->getConstPointer();
10028               const int *aMaxPtr=aMax->getConstPointer();
10029               int *res=ret->getPointer();
10030               for(int i=0;i<nbOfTuple;i++)
10031                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10032               ret->copyStringInfoFrom(*aMax);
10033             }
10034           else
10035             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10036         }
10037     }
10038   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10039     {
10040       if(nbOfComp==nbOfComp2)
10041         {
10042           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10043           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10044           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10045           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10046           ret=DataArrayInt::New();
10047           ret->alloc(nbOfTupleMax,nbOfComp);
10048           int *res=ret->getPointer();
10049           for(int i=0;i<nbOfTupleMax;i++)
10050             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10051           ret->copyStringInfoFrom(*aMax);
10052         }
10053       else
10054         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10055     }
10056   else
10057     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10058   return ret.retn();
10059 }
10060
10061 /*!
10062  * Adds values of another DataArrayInt to values of \a this one. There are 3
10063  * valid cases.
10064  * 1.  The arrays have same number of tuples and components. Then each value of
10065  *   \a other array is added to the corresponding value of \a this array, i.e.:
10066  *   _a_ [ i, j ] += _other_ [ i, j ].
10067  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10068  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10069  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10070  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10071  *
10072  *  \param [in] other - an array to add to \a this one.
10073  *  \throw If \a other is NULL.
10074  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10075  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10076  *         \a other has number of both tuples and components not equal to 1.
10077  */
10078 void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10079 {
10080   if(!other)
10081     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10082   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10083   checkAllocated(); other->checkAllocated();
10084   int nbOfTuple=getNumberOfTuples();
10085   int nbOfTuple2=other->getNumberOfTuples();
10086   int nbOfComp=getNumberOfComponents();
10087   int nbOfComp2=other->getNumberOfComponents();
10088   if(nbOfTuple==nbOfTuple2)
10089     {
10090       if(nbOfComp==nbOfComp2)
10091         {
10092           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10093         }
10094       else if(nbOfComp2==1)
10095         {
10096           int *ptr=getPointer();
10097           const int *ptrc=other->getConstPointer();
10098           for(int i=0;i<nbOfTuple;i++)
10099             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10100         }
10101       else
10102         throw INTERP_KERNEL::Exception(msg);
10103     }
10104   else if(nbOfTuple2==1)
10105     {
10106       if(nbOfComp2==nbOfComp)
10107         {
10108           int *ptr=getPointer();
10109           const int *ptrc=other->getConstPointer();
10110           for(int i=0;i<nbOfTuple;i++)
10111             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
10112         }
10113       else
10114         throw INTERP_KERNEL::Exception(msg);
10115     }
10116   else
10117     throw INTERP_KERNEL::Exception(msg);
10118   declareAsNew();
10119 }
10120
10121 /*!
10122  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
10123  * valid cases.
10124  * 1.  The arrays have same number of tuples and components. Then each value of
10125  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
10126  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
10127  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10128  *   component. Then
10129  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
10130  * 3.  The arrays have same number of components and one array, say _a2_, has one
10131  *   tuple. Then
10132  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
10133  *
10134  * Info on components is copied either from the first array (in the first case) or from
10135  * the array with maximal number of elements (getNbOfElems()).
10136  *  \param [in] a1 - an array to subtract from.
10137  *  \param [in] a2 - an array to subtract.
10138  *  \return DataArrayInt * - the new instance of DataArrayInt.
10139  *          The caller is to delete this result array using decrRef() as it is no more
10140  *          needed.
10141  *  \throw If either \a a1 or \a a2 is NULL.
10142  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10143  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10144  *         none of them has number of tuples or components equal to 1.
10145  */
10146 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10147 {
10148   if(!a1 || !a2)
10149     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
10150   int nbOfTuple1=a1->getNumberOfTuples();
10151   int nbOfTuple2=a2->getNumberOfTuples();
10152   int nbOfComp1=a1->getNumberOfComponents();
10153   int nbOfComp2=a2->getNumberOfComponents();
10154   if(nbOfTuple2==nbOfTuple1)
10155     {
10156       if(nbOfComp1==nbOfComp2)
10157         {
10158           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10159           ret->alloc(nbOfTuple2,nbOfComp1);
10160           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
10161           ret->copyStringInfoFrom(*a1);
10162           return ret.retn();
10163         }
10164       else if(nbOfComp2==1)
10165         {
10166           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10167           ret->alloc(nbOfTuple1,nbOfComp1);
10168           const int *a2Ptr=a2->getConstPointer();
10169           const int *a1Ptr=a1->getConstPointer();
10170           int *res=ret->getPointer();
10171           for(int i=0;i<nbOfTuple1;i++)
10172             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
10173           ret->copyStringInfoFrom(*a1);
10174           return ret.retn();
10175         }
10176       else
10177         {
10178           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10179           return 0;
10180         }
10181     }
10182   else if(nbOfTuple2==1)
10183     {
10184       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10185       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10186       ret->alloc(nbOfTuple1,nbOfComp1);
10187       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10188       int *pt=ret->getPointer();
10189       for(int i=0;i<nbOfTuple1;i++)
10190         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
10191       ret->copyStringInfoFrom(*a1);
10192       return ret.retn();
10193     }
10194   else
10195     {
10196       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
10197       return 0;
10198     }
10199 }
10200
10201 /*!
10202  * Subtract values of another DataArrayInt from values of \a this one. There are 3
10203  * valid cases.
10204  * 1.  The arrays have same number of tuples and components. Then each value of
10205  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
10206  *   _a_ [ i, j ] -= _other_ [ i, j ].
10207  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10208  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
10209  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10210  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
10211  *
10212  *  \param [in] other - an array to subtract from \a this one.
10213  *  \throw If \a other is NULL.
10214  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10215  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10216  *         \a other has number of both tuples and components not equal to 1.
10217  */
10218 void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10219 {
10220   if(!other)
10221     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
10222   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
10223   checkAllocated(); other->checkAllocated();
10224   int nbOfTuple=getNumberOfTuples();
10225   int nbOfTuple2=other->getNumberOfTuples();
10226   int nbOfComp=getNumberOfComponents();
10227   int nbOfComp2=other->getNumberOfComponents();
10228   if(nbOfTuple==nbOfTuple2)
10229     {
10230       if(nbOfComp==nbOfComp2)
10231         {
10232           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
10233         }
10234       else if(nbOfComp2==1)
10235         {
10236           int *ptr=getPointer();
10237           const int *ptrc=other->getConstPointer();
10238           for(int i=0;i<nbOfTuple;i++)
10239             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
10240         }
10241       else
10242         throw INTERP_KERNEL::Exception(msg);
10243     }
10244   else if(nbOfTuple2==1)
10245     {
10246       int *ptr=getPointer();
10247       const int *ptrc=other->getConstPointer();
10248       for(int i=0;i<nbOfTuple;i++)
10249         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
10250     }
10251   else
10252     throw INTERP_KERNEL::Exception(msg);
10253   declareAsNew();
10254 }
10255
10256 /*!
10257  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
10258  * valid cases.
10259  * 1.  The arrays have same number of tuples and components. Then each value of
10260  *   the result array (_a_) is a product of the corresponding values of \a a1 and
10261  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
10262  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10263  *   component. Then
10264  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
10265  * 3.  The arrays have same number of components and one array, say _a2_, has one
10266  *   tuple. Then
10267  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
10268  *
10269  * Info on components is copied either from the first array (in the first case) or from
10270  * the array with maximal number of elements (getNbOfElems()).
10271  *  \param [in] a1 - a factor array.
10272  *  \param [in] a2 - another factor array.
10273  *  \return DataArrayInt * - the new instance of DataArrayInt.
10274  *          The caller is to delete this result array using decrRef() as it is no more
10275  *          needed.
10276  *  \throw If either \a a1 or \a a2 is NULL.
10277  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10278  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10279  *         none of them has number of tuples or components equal to 1.
10280  */
10281 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10282 {
10283   if(!a1 || !a2)
10284     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
10285   int nbOfTuple=a1->getNumberOfTuples();
10286   int nbOfTuple2=a2->getNumberOfTuples();
10287   int nbOfComp=a1->getNumberOfComponents();
10288   int nbOfComp2=a2->getNumberOfComponents();
10289   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10290   if(nbOfTuple==nbOfTuple2)
10291     {
10292       if(nbOfComp==nbOfComp2)
10293         {
10294           ret=DataArrayInt::New();
10295           ret->alloc(nbOfTuple,nbOfComp);
10296           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
10297           ret->copyStringInfoFrom(*a1);
10298         }
10299       else
10300         {
10301           int nbOfCompMin,nbOfCompMax;
10302           const DataArrayInt *aMin, *aMax;
10303           if(nbOfComp>nbOfComp2)
10304             {
10305               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10306               aMin=a2; aMax=a1;
10307             }
10308           else
10309             {
10310               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10311               aMin=a1; aMax=a2;
10312             }
10313           if(nbOfCompMin==1)
10314             {
10315               ret=DataArrayInt::New();
10316               ret->alloc(nbOfTuple,nbOfCompMax);
10317               const int *aMinPtr=aMin->getConstPointer();
10318               const int *aMaxPtr=aMax->getConstPointer();
10319               int *res=ret->getPointer();
10320               for(int i=0;i<nbOfTuple;i++)
10321                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
10322               ret->copyStringInfoFrom(*aMax);
10323             }
10324           else
10325             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10326         }
10327     }
10328   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10329     {
10330       if(nbOfComp==nbOfComp2)
10331         {
10332           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10333           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10334           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10335           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10336           ret=DataArrayInt::New();
10337           ret->alloc(nbOfTupleMax,nbOfComp);
10338           int *res=ret->getPointer();
10339           for(int i=0;i<nbOfTupleMax;i++)
10340             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
10341           ret->copyStringInfoFrom(*aMax);
10342         }
10343       else
10344         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10345     }
10346   else
10347     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
10348   return ret.retn();
10349 }
10350
10351
10352 /*!
10353  * Multiply values of another DataArrayInt to values of \a this one. There are 3
10354  * valid cases.
10355  * 1.  The arrays have same number of tuples and components. Then each value of
10356  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
10357  *   _a_ [ i, j ] *= _other_ [ i, j ].
10358  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10359  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
10360  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10361  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
10362  *
10363  *  \param [in] other - an array to multiply to \a this one.
10364  *  \throw If \a other is NULL.
10365  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10366  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10367  *         \a other has number of both tuples and components not equal to 1.
10368  */
10369 void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10370 {
10371   if(!other)
10372     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
10373   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
10374   checkAllocated(); other->checkAllocated();
10375   int nbOfTuple=getNumberOfTuples();
10376   int nbOfTuple2=other->getNumberOfTuples();
10377   int nbOfComp=getNumberOfComponents();
10378   int nbOfComp2=other->getNumberOfComponents();
10379   if(nbOfTuple==nbOfTuple2)
10380     {
10381       if(nbOfComp==nbOfComp2)
10382         {
10383           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
10384         }
10385       else if(nbOfComp2==1)
10386         {
10387           int *ptr=getPointer();
10388           const int *ptrc=other->getConstPointer();
10389           for(int i=0;i<nbOfTuple;i++)
10390             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10391         }
10392       else
10393         throw INTERP_KERNEL::Exception(msg);
10394     }
10395   else if(nbOfTuple2==1)
10396     {
10397       if(nbOfComp2==nbOfComp)
10398         {
10399           int *ptr=getPointer();
10400           const int *ptrc=other->getConstPointer();
10401           for(int i=0;i<nbOfTuple;i++)
10402             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10403         }
10404       else
10405         throw INTERP_KERNEL::Exception(msg);
10406     }
10407   else
10408     throw INTERP_KERNEL::Exception(msg);
10409   declareAsNew();
10410 }
10411
10412
10413 /*!
10414  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10415  * valid cases.
10416  * 1.  The arrays have same number of tuples and components. Then each value of
10417  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10418  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10419  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10420  *   component. Then
10421  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10422  * 3.  The arrays have same number of components and one array, say _a2_, has one
10423  *   tuple. Then
10424  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10425  *
10426  * Info on components is copied either from the first array (in the first case) or from
10427  * the array with maximal number of elements (getNbOfElems()).
10428  *  \warning No check of division by zero is performed!
10429  *  \param [in] a1 - a numerator array.
10430  *  \param [in] a2 - a denominator array.
10431  *  \return DataArrayInt * - the new instance of DataArrayInt.
10432  *          The caller is to delete this result array using decrRef() as it is no more
10433  *          needed.
10434  *  \throw If either \a a1 or \a a2 is NULL.
10435  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10436  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10437  *         none of them has number of tuples or components equal to 1.
10438  */
10439 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10440 {
10441   if(!a1 || !a2)
10442     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10443   int nbOfTuple1=a1->getNumberOfTuples();
10444   int nbOfTuple2=a2->getNumberOfTuples();
10445   int nbOfComp1=a1->getNumberOfComponents();
10446   int nbOfComp2=a2->getNumberOfComponents();
10447   if(nbOfTuple2==nbOfTuple1)
10448     {
10449       if(nbOfComp1==nbOfComp2)
10450         {
10451           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10452           ret->alloc(nbOfTuple2,nbOfComp1);
10453           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10454           ret->copyStringInfoFrom(*a1);
10455           return ret.retn();
10456         }
10457       else if(nbOfComp2==1)
10458         {
10459           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10460           ret->alloc(nbOfTuple1,nbOfComp1);
10461           const int *a2Ptr=a2->getConstPointer();
10462           const int *a1Ptr=a1->getConstPointer();
10463           int *res=ret->getPointer();
10464           for(int i=0;i<nbOfTuple1;i++)
10465             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10466           ret->copyStringInfoFrom(*a1);
10467           return ret.retn();
10468         }
10469       else
10470         {
10471           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10472           return 0;
10473         }
10474     }
10475   else if(nbOfTuple2==1)
10476     {
10477       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10478       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10479       ret->alloc(nbOfTuple1,nbOfComp1);
10480       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10481       int *pt=ret->getPointer();
10482       for(int i=0;i<nbOfTuple1;i++)
10483         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10484       ret->copyStringInfoFrom(*a1);
10485       return ret.retn();
10486     }
10487   else
10488     {
10489       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10490       return 0;
10491     }
10492 }
10493
10494 /*!
10495  * Divide values of \a this array by values of another DataArrayInt. There are 3
10496  * valid cases.
10497  * 1.  The arrays have same number of tuples and components. Then each value of
10498  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10499  *   _a_ [ i, j ] /= _other_ [ i, j ].
10500  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10501  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10502  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10503  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10504  *
10505  *  \warning No check of division by zero is performed!
10506  *  \param [in] other - an array to divide \a this one by.
10507  *  \throw If \a other is NULL.
10508  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10509  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10510  *         \a other has number of both tuples and components not equal to 1.
10511  */
10512 void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10513 {
10514   if(!other)
10515     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10516   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10517   checkAllocated(); other->checkAllocated();
10518   int nbOfTuple=getNumberOfTuples();
10519   int nbOfTuple2=other->getNumberOfTuples();
10520   int nbOfComp=getNumberOfComponents();
10521   int nbOfComp2=other->getNumberOfComponents();
10522   if(nbOfTuple==nbOfTuple2)
10523     {
10524       if(nbOfComp==nbOfComp2)
10525         {
10526           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10527         }
10528       else if(nbOfComp2==1)
10529         {
10530           int *ptr=getPointer();
10531           const int *ptrc=other->getConstPointer();
10532           for(int i=0;i<nbOfTuple;i++)
10533             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10534         }
10535       else
10536         throw INTERP_KERNEL::Exception(msg);
10537     }
10538   else if(nbOfTuple2==1)
10539     {
10540       if(nbOfComp2==nbOfComp)
10541         {
10542           int *ptr=getPointer();
10543           const int *ptrc=other->getConstPointer();
10544           for(int i=0;i<nbOfTuple;i++)
10545             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10546         }
10547       else
10548         throw INTERP_KERNEL::Exception(msg);
10549     }
10550   else
10551     throw INTERP_KERNEL::Exception(msg);
10552   declareAsNew();
10553 }
10554
10555
10556 /*!
10557  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10558  * valid cases.
10559  * 1.  The arrays have same number of tuples and components. Then each value of
10560  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10561  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10562  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10563  *   component. Then
10564  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10565  * 3.  The arrays have same number of components and one array, say _a2_, has one
10566  *   tuple. Then
10567  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10568  *
10569  * Info on components is copied either from the first array (in the first case) or from
10570  * the array with maximal number of elements (getNbOfElems()).
10571  *  \warning No check of division by zero is performed!
10572  *  \param [in] a1 - a dividend array.
10573  *  \param [in] a2 - a divisor array.
10574  *  \return DataArrayInt * - the new instance of DataArrayInt.
10575  *          The caller is to delete this result array using decrRef() as it is no more
10576  *          needed.
10577  *  \throw If either \a a1 or \a a2 is NULL.
10578  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10579  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10580  *         none of them has number of tuples or components equal to 1.
10581  */
10582 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10583 {
10584     if(!a1 || !a2)
10585     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10586   int nbOfTuple1=a1->getNumberOfTuples();
10587   int nbOfTuple2=a2->getNumberOfTuples();
10588   int nbOfComp1=a1->getNumberOfComponents();
10589   int nbOfComp2=a2->getNumberOfComponents();
10590   if(nbOfTuple2==nbOfTuple1)
10591     {
10592       if(nbOfComp1==nbOfComp2)
10593         {
10594           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10595           ret->alloc(nbOfTuple2,nbOfComp1);
10596           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
10597           ret->copyStringInfoFrom(*a1);
10598           return ret.retn();
10599         }
10600       else if(nbOfComp2==1)
10601         {
10602           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10603           ret->alloc(nbOfTuple1,nbOfComp1);
10604           const int *a2Ptr=a2->getConstPointer();
10605           const int *a1Ptr=a1->getConstPointer();
10606           int *res=ret->getPointer();
10607           for(int i=0;i<nbOfTuple1;i++)
10608             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
10609           ret->copyStringInfoFrom(*a1);
10610           return ret.retn();
10611         }
10612       else
10613         {
10614           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10615           return 0;
10616         }
10617     }
10618   else if(nbOfTuple2==1)
10619     {
10620       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10621       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10622       ret->alloc(nbOfTuple1,nbOfComp1);
10623       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10624       int *pt=ret->getPointer();
10625       for(int i=0;i<nbOfTuple1;i++)
10626         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
10627       ret->copyStringInfoFrom(*a1);
10628       return ret.retn();
10629     }
10630   else
10631     {
10632       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
10633       return 0;
10634     }
10635 }
10636
10637 /*!
10638  * Modify \a this array so that each value becomes a modulus of division of this value by
10639  * a value of another DataArrayInt. There are 3 valid cases.
10640  * 1.  The arrays have same number of tuples and components. Then each value of
10641  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10642  *   _a_ [ i, j ] %= _other_ [ i, j ].
10643  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10644  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
10645  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10646  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
10647  *
10648  *  \warning No check of division by zero is performed!
10649  *  \param [in] other - a divisor array.
10650  *  \throw If \a other is NULL.
10651  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10652  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10653  *         \a other has number of both tuples and components not equal to 1.
10654  */
10655 void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10656 {
10657   if(!other)
10658     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
10659   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
10660   checkAllocated(); other->checkAllocated();
10661   int nbOfTuple=getNumberOfTuples();
10662   int nbOfTuple2=other->getNumberOfTuples();
10663   int nbOfComp=getNumberOfComponents();
10664   int nbOfComp2=other->getNumberOfComponents();
10665   if(nbOfTuple==nbOfTuple2)
10666     {
10667       if(nbOfComp==nbOfComp2)
10668         {
10669           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
10670         }
10671       else if(nbOfComp2==1)
10672         {
10673           if(nbOfComp2==nbOfComp)
10674             {
10675               int *ptr=getPointer();
10676               const int *ptrc=other->getConstPointer();
10677               for(int i=0;i<nbOfTuple;i++)
10678                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
10679             }
10680           else
10681             throw INTERP_KERNEL::Exception(msg);
10682         }
10683       else
10684         throw INTERP_KERNEL::Exception(msg);
10685     }
10686   else if(nbOfTuple2==1)
10687     {
10688       int *ptr=getPointer();
10689       const int *ptrc=other->getConstPointer();
10690       for(int i=0;i<nbOfTuple;i++)
10691         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
10692     }
10693   else
10694     throw INTERP_KERNEL::Exception(msg);
10695   declareAsNew();
10696 }
10697
10698 /*!
10699  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
10700  * valid cases.
10701  *
10702  *  \param [in] a1 - an array to pow up.
10703  *  \param [in] a2 - another array to sum up.
10704  *  \return DataArrayInt * - the new instance of DataArrayInt.
10705  *          The caller is to delete this result array using decrRef() as it is no more
10706  *          needed.
10707  *  \throw If either \a a1 or \a a2 is NULL.
10708  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
10709  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
10710  *  \throw If there is a negative value in \a a2.
10711  */
10712 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10713 {
10714   if(!a1 || !a2)
10715     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
10716   int nbOfTuple=a1->getNumberOfTuples();
10717   int nbOfTuple2=a2->getNumberOfTuples();
10718   int nbOfComp=a1->getNumberOfComponents();
10719   int nbOfComp2=a2->getNumberOfComponents();
10720   if(nbOfTuple!=nbOfTuple2)
10721     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
10722   if(nbOfComp!=1 || nbOfComp2!=1)
10723     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
10724   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
10725   const int *ptr1(a1->begin()),*ptr2(a2->begin());
10726   int *ptr=ret->getPointer();
10727   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
10728     {
10729       if(*ptr2>=0)
10730         {
10731           int tmp=1;
10732           for(int j=0;j<*ptr2;j++)
10733             tmp*=*ptr1;
10734           *ptr=tmp;
10735         }
10736       else
10737         {
10738           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
10739           throw INTERP_KERNEL::Exception(oss.str().c_str());
10740         }
10741     }
10742   return ret.retn();
10743 }
10744
10745 /*!
10746  * Apply pow on values of another DataArrayInt to values of \a this one.
10747  *
10748  *  \param [in] other - an array to pow to \a this one.
10749  *  \throw If \a other is NULL.
10750  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
10751  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
10752  *  \throw If there is a negative value in \a other.
10753  */
10754 void DataArrayInt::powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10755 {
10756   if(!other)
10757     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
10758   int nbOfTuple=getNumberOfTuples();
10759   int nbOfTuple2=other->getNumberOfTuples();
10760   int nbOfComp=getNumberOfComponents();
10761   int nbOfComp2=other->getNumberOfComponents();
10762   if(nbOfTuple!=nbOfTuple2)
10763     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
10764   if(nbOfComp!=1 || nbOfComp2!=1)
10765     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
10766   int *ptr=getPointer();
10767   const int *ptrc=other->begin();
10768   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
10769     {
10770       if(*ptrc>=0)
10771         {
10772           int tmp=1;
10773           for(int j=0;j<*ptrc;j++)
10774             tmp*=*ptr;
10775           *ptr=tmp;
10776         }
10777       else
10778         {
10779           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
10780           throw INTERP_KERNEL::Exception(oss.str().c_str());
10781         }
10782     }
10783   declareAsNew();
10784 }
10785
10786 /*!
10787  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10788  * This map, if applied to \a start array, would make it sorted. For example, if
10789  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10790  * [5,6,0,3,2,7,1,4].
10791  *  \param [in] start - pointer to the first element of the array for which the
10792  *         permutation map is computed.
10793  *  \param [in] end - pointer specifying the end of the array \a start, so that
10794  *         the last value of \a start is \a end[ -1 ].
10795  *  \return int * - the result permutation array that the caller is to delete as it is no
10796  *         more needed.
10797  *  \throw If there are equal values in the input array.
10798  */
10799 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10800 {
10801   std::size_t sz=std::distance(start,end);
10802   int *ret=(int *)malloc(sz*sizeof(int));
10803   int *work=new int[sz];
10804   std::copy(start,end,work);
10805   std::sort(work,work+sz);
10806   if(std::unique(work,work+sz)!=work+sz)
10807     {
10808       delete [] work;
10809       free(ret);
10810       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10811     }
10812   std::map<int,int> m;
10813   for(int *workPt=work;workPt!=work+sz;workPt++)
10814     m[*workPt]=(int)std::distance(work,workPt);
10815   int *iter2=ret;
10816   for(const int *iter=start;iter!=end;iter++,iter2++)
10817     *iter2=m[*iter];
10818   delete [] work;
10819   return ret;
10820 }
10821
10822 /*!
10823  * Returns a new DataArrayInt containing an arithmetic progression
10824  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10825  * function.
10826  *  \param [in] begin - the start value of the result sequence.
10827  *  \param [in] end - limiting value, so that every value of the result array is less than
10828  *              \a end.
10829  *  \param [in] step - specifies the increment or decrement.
10830  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10831  *          array using decrRef() as it is no more needed.
10832  *  \throw If \a step == 0.
10833  *  \throw If \a end < \a begin && \a step > 0.
10834  *  \throw If \a end > \a begin && \a step < 0.
10835  */
10836 DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception)
10837 {
10838   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10839   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10840   ret->alloc(nbOfTuples,1);
10841   int *ptr=ret->getPointer();
10842   if(step>0)
10843     {
10844       for(int i=begin;i<end;i+=step,ptr++)
10845         *ptr=i;
10846     }
10847   else
10848     {
10849       for(int i=begin;i>end;i+=step,ptr++)
10850         *ptr=i;
10851     }
10852   return ret.retn();
10853 }
10854
10855 /*!
10856  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10857  * Server side.
10858  */
10859 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
10860 {
10861   tinyInfo.resize(2);
10862   if(isAllocated())
10863     {
10864       tinyInfo[0]=getNumberOfTuples();
10865       tinyInfo[1]=getNumberOfComponents();
10866     }
10867   else
10868     {
10869       tinyInfo[0]=-1;
10870       tinyInfo[1]=-1;
10871     }
10872 }
10873
10874 /*!
10875  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10876  * Server side.
10877  */
10878 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
10879 {
10880   if(isAllocated())
10881     {
10882       int nbOfCompo=getNumberOfComponents();
10883       tinyInfo.resize(nbOfCompo+1);
10884       tinyInfo[0]=getName();
10885       for(int i=0;i<nbOfCompo;i++)
10886         tinyInfo[i+1]=getInfoOnComponent(i);
10887     }
10888   else
10889     {
10890       tinyInfo.resize(1);
10891       tinyInfo[0]=getName();
10892     }
10893 }
10894
10895 /*!
10896  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10897  * This method returns if a feeding is needed.
10898  */
10899 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
10900 {
10901   int nbOfTuple=tinyInfoI[0];
10902   int nbOfComp=tinyInfoI[1];
10903   if(nbOfTuple!=-1 || nbOfComp!=-1)
10904     {
10905       alloc(nbOfTuple,nbOfComp);
10906       return true;
10907     }
10908   return false;
10909 }
10910
10911 /*!
10912  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10913  * This method returns if a feeding is needed.
10914  */
10915 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
10916 {
10917   setName(tinyInfoS[0].c_str());
10918   if(isAllocated())
10919     {
10920       int nbOfCompo=tinyInfoI[1];
10921       for(int i=0;i<nbOfCompo;i++)
10922         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
10923     }
10924 }
10925
10926 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
10927 {
10928   if(_da)
10929     {
10930       _da->incrRef();
10931       if(_da->isAllocated())
10932         {
10933           _nb_comp=da->getNumberOfComponents();
10934           _nb_tuple=da->getNumberOfTuples();
10935           _pt=da->getPointer();
10936         }
10937     }
10938 }
10939
10940 DataArrayIntIterator::~DataArrayIntIterator()
10941 {
10942   if(_da)
10943     _da->decrRef();
10944 }
10945
10946 DataArrayIntTuple *DataArrayIntIterator::nextt() throw(INTERP_KERNEL::Exception)
10947 {
10948   if(_tuple_id<_nb_tuple)
10949     {
10950       _tuple_id++;
10951       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
10952       _pt+=_nb_comp;
10953       return ret;
10954     }
10955   else
10956     return 0;
10957 }
10958
10959 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
10960 {
10961 }
10962
10963 std::string DataArrayIntTuple::repr() const throw(INTERP_KERNEL::Exception)
10964 {
10965   std::ostringstream oss; oss << "(";
10966   for(int i=0;i<_nb_of_compo-1;i++)
10967     oss << _pt[i] << ", ";
10968   oss << _pt[_nb_of_compo-1] << ")";
10969   return oss.str();
10970 }
10971
10972 int DataArrayIntTuple::intValue() const throw(INTERP_KERNEL::Exception)
10973 {
10974   if(_nb_of_compo==1)
10975     return *_pt;
10976   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
10977 }
10978
10979 /*!
10980  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
10981  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
10982  * 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
10983  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
10984  */
10985 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
10986 {
10987   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
10988     {
10989       DataArrayInt *ret=DataArrayInt::New();
10990       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
10991       return ret;
10992     }
10993   else
10994     {
10995       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
10996       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
10997       throw INTERP_KERNEL::Exception(oss.str().c_str());
10998     }
10999 }