Salome HOME
MEDReader : End of debugging session.
[modules/med.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 "GenMathFormulae.hxx"
25 #include "InterpKernelExprParser.hxx"
26
27 #include <set>
28 #include <cmath>
29 #include <limits>
30 #include <numeric>
31 #include <algorithm>
32 #include <functional>
33
34 typedef double (*MYFUNCPTR)(double);
35
36 using namespace ParaMEDMEM;
37
38 template<int SPACEDIM>
39 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
40 {
41   const double *coordsPtr=getConstPointer();
42   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
43   std::vector<bool> isDone(nbNodes);
44   for(int i=0;i<nbNodes;i++)
45     {
46       if(!isDone[i])
47         {
48           std::vector<int> intersectingElems;
49           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
50           if(intersectingElems.size()>1)
51             {
52               std::vector<int> commonNodes;
53               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
54                 if(*it!=i)
55                   if(*it>=limitNodeId)
56                     {
57                       commonNodes.push_back(*it);
58                       isDone[*it]=true;
59                     }
60               if(!commonNodes.empty())
61                 {
62                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
63                   c->pushBackSilent(i);
64                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
65                 }
66             }
67         }
68     }
69 }
70
71 template<int SPACEDIM>
72 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
73                                                 DataArrayInt *c, DataArrayInt *cI)
74 {
75   for(int i=0;i<nbOfTuples;i++)
76     {
77       std::vector<int> intersectingElems;
78       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
79       std::vector<int> commonNodes;
80       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
81         commonNodes.push_back(*it);
82       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
83       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
84     }
85 }
86
87 template<int SPACEDIM>
88 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
89 {
90   double distOpt(dist);
91   const double *p(pos);
92   int *r(res);
93   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
94     {
95       while(true)
96         {
97           int elem=-1;
98           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
99           if(ret!=std::numeric_limits<double>::max())
100             {
101               distOpt=std::max(ret,1e-4);
102               *r=elem;
103               break;
104             }
105           else
106             { distOpt=2*distOpt; continue; }
107         }
108     }
109 }
110
111 std::size_t DataArray::getHeapMemorySize() const
112 {
113   std::size_t sz1=_name.capacity();
114   std::size_t sz2=_info_on_compo.capacity();
115   std::size_t sz3=0;
116   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
117     sz3+=(*it).capacity();
118   return sz1+sz2+sz3;
119 }
120
121 /*!
122  * Sets the attribute \a _name of \a this array.
123  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
124  *  \param [in] name - new array name
125  */
126 void DataArray::setName(const char *name)
127 {
128   _name=name;
129 }
130
131 /*!
132  * Copies textual data from an \a other DataArray. The copied data are
133  * - the name attribute,
134  * - the information of components.
135  *
136  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
137  *
138  *  \param [in] other - another instance of DataArray to copy the textual data from.
139  *  \throw If number of components of \a this array differs from that of the \a other.
140  */
141 void DataArray::copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception)
142 {
143   if(_info_on_compo.size()!=other._info_on_compo.size())
144     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
145   _name=other._name;
146   _info_on_compo=other._info_on_compo;
147 }
148
149 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
150 {
151   int nbOfCompoOth=other.getNumberOfComponents();
152   std::size_t newNbOfCompo=compoIds.size();
153   for(std::size_t i=0;i<newNbOfCompo;i++)
154     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
155       {
156         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
157         throw INTERP_KERNEL::Exception(oss.str().c_str());
158       }
159   for(std::size_t i=0;i<newNbOfCompo;i++)
160     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]).c_str());
161 }
162
163 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception)
164 {
165   int nbOfCompo=getNumberOfComponents();
166   std::size_t partOfCompoToSet=compoIds.size();
167   if((int)partOfCompoToSet!=other.getNumberOfComponents())
168     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
169   for(std::size_t i=0;i<partOfCompoToSet;i++)
170     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
171       {
172         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
173         throw INTERP_KERNEL::Exception(oss.str().c_str());
174       }
175   for(std::size_t i=0;i<partOfCompoToSet;i++)
176     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i).c_str());
177 }
178
179 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
180 {
181   std::ostringstream oss;
182   if(_name!=other._name)
183     {
184       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
185       reason=oss.str();
186       return false;
187     }
188   if(_info_on_compo!=other._info_on_compo)
189     {
190       oss << "Components DataArray mismatch : \nThis components=";
191       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
192         oss << "\"" << *it << "\",";
193       oss << "\nOther components=";
194       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
195         oss << "\"" << *it << "\",";
196       reason=oss.str();
197       return false;
198     }
199   return true;
200 }
201
202 /*!
203  * Compares textual information of \a this DataArray with that of an \a other one.
204  * The compared data are
205  * - the name attribute,
206  * - the information of components.
207  *
208  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
209  *  \param [in] other - another instance of DataArray to compare the textual data of.
210  *  \return bool - \a true if the textual information is same, \a false else.
211  */
212 bool DataArray::areInfoEquals(const DataArray& other) const throw(INTERP_KERNEL::Exception)
213 {
214   std::string tmp;
215   return areInfoEqualsIfNotWhy(other,tmp);
216 }
217
218 void DataArray::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
219 {
220   stream << "Number of components : "<< getNumberOfComponents() << "\n";
221   stream << "Info of these components : ";
222   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
223     stream << "\"" << *iter << "\"   ";
224   stream << "\n";
225 }
226
227 std::string DataArray::cppRepr(const char *varName) const throw(INTERP_KERNEL::Exception)
228 {
229   std::ostringstream ret;
230   reprCppStream(varName,ret);
231   return ret.str();
232 }
233
234 /*!
235  * Sets information on all components. To know more on format of this information
236  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
237  *  \param [in] info - a vector of strings.
238  *  \throw If size of \a info differs from the number of components of \a this.
239  */
240 void DataArray::setInfoOnComponents(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
241 {
242   if(getNumberOfComponents()!=(int)info.size())
243     {
244       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
245       throw INTERP_KERNEL::Exception(oss.str().c_str());
246     }
247   _info_on_compo=info;
248 }
249
250 /*!
251  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
252  * type of \a this and \a aBase.
253  *
254  * \throw If \a aBase and \a this do not have the same type.
255  *
256  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
257  */
258 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
259 {
260   if(!aBase)
261     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
262   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
263   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
264   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
265   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
266   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
267   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
268   if(this1 && a1)
269     {
270       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
271       return ;
272     }
273   if(this2 && a2)
274     {
275       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
276       return ;
277     }
278   if(this3 && a3)
279     {
280       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
281       return ;
282     }
283   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
284 }
285
286 std::vector<std::string> DataArray::getVarsOnComponent() const throw(INTERP_KERNEL::Exception)
287 {
288   int nbOfCompo=(int)_info_on_compo.size();
289   std::vector<std::string> ret(nbOfCompo);
290   for(int i=0;i<nbOfCompo;i++)
291     ret[i]=getVarOnComponent(i);
292   return ret;
293 }
294
295 std::vector<std::string> DataArray::getUnitsOnComponent() const throw(INTERP_KERNEL::Exception)
296 {
297   int nbOfCompo=(int)_info_on_compo.size();
298   std::vector<std::string> ret(nbOfCompo);
299   for(int i=0;i<nbOfCompo;i++)
300     ret[i]=getUnitOnComponent(i);
301   return ret;
302 }
303
304 /*!
305  * Returns information on a component specified by an index.
306  * To know more on format of this information
307  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
308  *  \param [in] i - the index (zero based) of the component of interest.
309  *  \return std::string - a string containing the information on \a i-th component.
310  *  \throw If \a i is not a valid component index.
311  */
312 std::string DataArray::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception)
313 {
314   if(i<(int)_info_on_compo.size() && i>=0)
315     return _info_on_compo[i];
316   else
317     {
318       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();
319       throw INTERP_KERNEL::Exception(oss.str().c_str());
320     }
321 }
322
323 /*!
324  * Returns the var part of the full information of the \a i-th component.
325  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
326  * \c getVarOnComponent(0) returns "SIGXY".
327  * If a unit part of information is not detected by presence of
328  * two square brackets, then the full information is returned.
329  * To read more about the component information format, see
330  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
331  *  \param [in] i - the index (zero based) of the component of interest.
332  *  \return std::string - a string containing the var information, or the full info.
333  *  \throw If \a i is not a valid component index.
334  */
335 std::string DataArray::getVarOnComponent(int i) const throw(INTERP_KERNEL::Exception)
336 {
337   if(i<(int)_info_on_compo.size() && i>=0)
338     {
339       return GetVarNameFromInfo(_info_on_compo[i]);
340     }
341   else
342     {
343       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();
344       throw INTERP_KERNEL::Exception(oss.str().c_str());
345     }
346 }
347
348 /*!
349  * Returns the unit part of the full information of the \a i-th component.
350  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
351  * \c getUnitOnComponent(0) returns " N/m^2".
352  * If a unit part of information is not detected by presence of
353  * two square brackets, then an empty string is returned.
354  * To read more about the component information format, see
355  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
356  *  \param [in] i - the index (zero based) of the component of interest.
357  *  \return std::string - a string containing the unit information, if any, or "".
358  *  \throw If \a i is not a valid component index.
359  */
360 std::string DataArray::getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception)
361 {
362   if(i<(int)_info_on_compo.size() && i>=0)
363     {
364       return GetUnitFromInfo(_info_on_compo[i]);
365     }
366   else
367     {
368       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();
369       throw INTERP_KERNEL::Exception(oss.str().c_str());
370     }
371 }
372
373 /*!
374  * Returns the var part of the full component information.
375  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
376  * If a unit part of information is not detected by presence of
377  * two square brackets, then the whole \a info is returned.
378  * To read more about the component information format, see
379  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
380  *  \param [in] info - the full component information.
381  *  \return std::string - a string containing only var information, or the \a info.
382  */
383 std::string DataArray::GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
384 {
385   std::size_t p1=info.find_last_of('[');
386   std::size_t p2=info.find_last_of(']');
387   if(p1==std::string::npos || p2==std::string::npos)
388     return info;
389   if(p1>p2)
390     return info;
391   if(p1==0)
392     return std::string();
393   std::size_t p3=info.find_last_not_of(' ',p1-1);
394   return info.substr(0,p3+1);
395 }
396
397 /*!
398  * Returns the unit part of the full component information.
399  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
400  * If a unit part of information is not detected by presence of
401  * two square brackets, then an empty string is returned.
402  * To read more about the component information format, see
403  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
404  *  \param [in] info - the full component information.
405  *  \return std::string - a string containing only unit information, if any, or "".
406  */
407 std::string DataArray::GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception)
408 {
409   std::size_t p1=info.find_last_of('[');
410   std::size_t p2=info.find_last_of(']');
411   if(p1==std::string::npos || p2==std::string::npos)
412     return std::string();
413   if(p1>p2)
414     return std::string();
415   return info.substr(p1+1,p2-p1-1);
416 }
417
418 /*!
419  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
420  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
421  * the number of component in the result array is same as that of each of given arrays.
422  * Info on components is copied from the first of the given arrays. Number of components
423  * in the given arrays must be  the same.
424  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
425  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
426  *          The caller is to delete this result array using decrRef() as it is no more
427  *          needed.
428  *  \throw If all arrays within \a arrs are NULL.
429  *  \throw If all not null arrays in \a arrs have not the same type.
430  *  \throw If getNumberOfComponents() of arrays within \a arrs.
431  */
432 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs) throw(INTERP_KERNEL::Exception)
433 {
434   std::vector<const DataArray *> arr2;
435   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
436     if(*it)
437       arr2.push_back(*it);
438   if(arr2.empty())
439     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
440   std::vector<const DataArrayDouble *> arrd;
441   std::vector<const DataArrayInt *> arri;
442   std::vector<const DataArrayChar *> arrc;
443   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
444     {
445       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
446       if(a)
447         { arrd.push_back(a); continue; }
448       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
449       if(b)
450         { arri.push_back(b); continue; }
451       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
452       if(c)
453         { arrc.push_back(c); continue; }
454       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
455     }
456   if(arr2.size()==arrd.size())
457     return DataArrayDouble::Aggregate(arrd);
458   if(arr2.size()==arri.size())
459     return DataArrayInt::Aggregate(arri);
460   if(arr2.size()==arrc.size())
461     return DataArrayChar::Aggregate(arrc);
462   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
463 }
464
465 /*!
466  * Sets information on a component specified by an index.
467  * To know more on format of this information
468  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
469  *  \warning Don't pass NULL as \a info!
470  *  \param [in] i - the index (zero based) of the component of interest.
471  *  \param [in] info - the string containing the information.
472  *  \throw If \a i is not a valid component index.
473  */
474 void DataArray::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception)
475 {
476   if(i<(int)_info_on_compo.size() && i>=0)
477     _info_on_compo[i]=info;
478   else
479     {
480       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();
481       throw INTERP_KERNEL::Exception(oss.str().c_str());
482     }
483 }
484
485 /*!
486  * Sets information on all components. This method can change number of components
487  * at certain conditions; if the conditions are not respected, an exception is thrown.
488  * The number of components can be changed in \a this only if \a this is not allocated.
489  * The condition of number of components must not be changed.
490  *
491  * To know more on format of the component information see
492  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
493  *  \param [in] info - a vector of component infos.
494  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
495  */
496 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
497 {
498   if(getNumberOfComponents()!=(int)info.size())
499     {
500       if(!isAllocated())
501         _info_on_compo=info;
502       else
503         {
504           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 !";
505           throw INTERP_KERNEL::Exception(oss.str().c_str());
506         }
507     }
508   else
509     _info_on_compo=info;
510 }
511
512 void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const throw(INTERP_KERNEL::Exception)
513 {
514   if(getNumberOfTuples()!=nbOfTuples)
515     {
516       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
517       throw INTERP_KERNEL::Exception(oss.str().c_str());
518     }
519 }
520
521 void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
522 {
523   if(getNumberOfComponents()!=nbOfCompo)
524     {
525       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
526       throw INTERP_KERNEL::Exception(oss.str().c_str());
527     }
528 }
529
530 void DataArray::checkNbOfElems(std::size_t nbOfElems, const char *msg) const throw(INTERP_KERNEL::Exception)
531 {
532   if(getNbOfElems()!=nbOfElems)
533     {
534       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
535       throw INTERP_KERNEL::Exception(oss.str().c_str());
536     }
537 }
538
539 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception)
540 {
541    if(getNumberOfTuples()!=other.getNumberOfTuples())
542     {
543       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
544       throw INTERP_KERNEL::Exception(oss.str().c_str());
545     }
546   if(getNumberOfComponents()!=other.getNumberOfComponents())
547     {
548       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
549       throw INTERP_KERNEL::Exception(oss.str().c_str());
550     }
551 }
552
553 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception)
554 {
555   checkNbOfTuples(nbOfTuples,msg);
556   checkNbOfComps(nbOfCompo,msg);
557 }
558
559 /*!
560  * Simply this method checks that \b value is in [0,\b ref).
561  */
562 void DataArray::CheckValueInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
563 {
564   if(value<0 || value>=ref)
565     {
566       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
567       throw INTERP_KERNEL::Exception(oss.str().c_str());
568     }
569 }
570
571 /*!
572  * This method checks that [\b start, \b end) is compliant with ref length \b value.
573  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
574  */
575 void DataArray::CheckValueInRangeEx(int value, int start, int end, const char *msg) throw(INTERP_KERNEL::Exception)
576 {
577   if(start<0 || start>=value)
578     {
579       if(value!=start || end!=start)
580         {
581           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
582           throw INTERP_KERNEL::Exception(oss.str().c_str());
583         }
584     }
585   if(end<0 || end>value)
586     {
587       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
588       throw INTERP_KERNEL::Exception(oss.str().c_str());
589     }
590 }
591
592 void DataArray::CheckClosingParInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception)
593 {
594   if(value<0 || value>ref)
595     {
596       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
597       throw INTERP_KERNEL::Exception(oss.str().c_str());
598     }
599 }
600
601 /*!
602  * 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, 
603  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
604  *
605  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
606  *
607  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
608  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
609  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
610  * \param [in] sliceId - the slice id considered
611  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
612  * \param [out] startSlice - the start of the slice considered
613  * \param [out] stopSlice - the stop of the slice consided
614  * 
615  * \throw If \a step == 0
616  * \throw If \a nbOfSlices not > 0
617  * \throw If \a sliceId not in [0,nbOfSlices)
618  */
619 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice) throw(INTERP_KERNEL::Exception)
620 {
621   if(nbOfSlices<=0)
622     {
623       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
624       throw INTERP_KERNEL::Exception(oss.str().c_str());
625     }
626   if(sliceId<0 || sliceId>=nbOfSlices)
627     {
628       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
629       throw INTERP_KERNEL::Exception(oss.str().c_str());
630     }
631   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
632   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
633   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
634   if(sliceId<nbOfSlices-1)
635     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
636   else
637     stopSlice=stop;
638 }
639
640 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
641 {
642   if(end<begin)
643     {
644       std::ostringstream oss; oss << msg << " : end before begin !";
645       throw INTERP_KERNEL::Exception(oss.str().c_str());
646     }
647   if(end==begin)
648     return 0;
649   if(step<=0)
650     {
651       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
652       throw INTERP_KERNEL::Exception(oss.str().c_str());
653     }
654   return (end-1-begin)/step+1;
655 }
656
657 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception)
658 {
659   if(step==0)
660     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
661   if(end<begin && step>0)
662     {
663       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
664       throw INTERP_KERNEL::Exception(oss.str().c_str());
665     }
666   if(begin<end && step<0)
667     {
668       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
669       throw INTERP_KERNEL::Exception(oss.str().c_str());
670     }
671   if(begin!=end)
672     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
673   else
674     return 0;
675 }
676
677 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) throw(INTERP_KERNEL::Exception)
678 {
679   if(step!=0)
680     {
681       if(step>0)
682         {
683           if(begin<=value && value<end)
684             {
685               if((value-begin)%step==0)
686                 return (value-begin)/step;
687               else
688                 return -1;
689             }
690           else
691             return -1;
692         }
693       else
694         {
695           if(begin>=value && value>end)
696             {
697               if((begin-value)%(-step)==0)
698                 return (begin-value)/(-step);
699               else
700                 return -1;
701             }
702           else
703             return -1;
704         }
705     }
706   else
707     return -1;
708 }
709
710 /*!
711  * Returns a new instance of DataArrayDouble. The caller is to delete this array
712  * using decrRef() as it is no more needed. 
713  */
714 DataArrayDouble *DataArrayDouble::New()
715 {
716   return new DataArrayDouble;
717 }
718
719 /*!
720  * Checks if raw data is allocated. Read more on the raw data
721  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
722  *  \return bool - \a true if the raw data is allocated, \a false else.
723  */
724 bool DataArrayDouble::isAllocated() const throw(INTERP_KERNEL::Exception)
725 {
726   return getConstPointer()!=0;
727 }
728
729 /*!
730  * Checks if raw data is allocated and throws an exception if it is not the case.
731  *  \throw If the raw data is not allocated.
732  */
733 void DataArrayDouble::checkAllocated() const throw(INTERP_KERNEL::Exception)
734 {
735   if(!isAllocated())
736     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
737 }
738
739 /*!
740  * This method desallocated \a this without modification of informations relative to the components.
741  * After call of this method, DataArrayDouble::isAllocated will return false.
742  * If \a this is already not allocated, \a this is let unchanged.
743  */
744 void DataArrayDouble::desallocate() throw(INTERP_KERNEL::Exception)
745 {
746   _mem.destroy();
747 }
748
749 std::size_t DataArrayDouble::getHeapMemorySize() const
750 {
751   std::size_t sz=_mem.getNbOfElemAllocated();
752   sz*=sizeof(double);
753   return DataArray::getHeapMemorySize()+sz;
754 }
755
756 /*!
757  * Returns the only one value in \a this, if and only if number of elements
758  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
759  *  \return double - the sole value stored in \a this array.
760  *  \throw If at least one of conditions stated above is not fulfilled.
761  */
762 double DataArrayDouble::doubleValue() const throw(INTERP_KERNEL::Exception)
763 {
764   if(isAllocated())
765     {
766       if(getNbOfElems()==1)
767         {
768           return *getConstPointer();
769         }
770       else
771         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
772     }
773   else
774     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
775 }
776
777 /*!
778  * Checks the number of tuples.
779  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
780  *  \throw If \a this is not allocated.
781  */
782 bool DataArrayDouble::empty() const throw(INTERP_KERNEL::Exception)
783 {
784   checkAllocated();
785   return getNumberOfTuples()==0;
786 }
787
788 /*!
789  * Returns a full copy of \a this. For more info on copying data arrays see
790  * \ref MEDCouplingArrayBasicsCopyDeep.
791  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
792  *          delete this array using decrRef() as it is no more needed. 
793  */
794 DataArrayDouble *DataArrayDouble::deepCpy() const throw(INTERP_KERNEL::Exception)
795 {
796   return new DataArrayDouble(*this);
797 }
798
799 /*!
800  * Returns either a \a deep or \a shallow copy of this array. For more info see
801  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
802  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
803  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
804  *          == \a true) or \a this instance (if \a dCpy == \a false).
805  */
806 DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
807 {
808   if(dCpy)
809     return deepCpy();
810   else
811     {
812       incrRef();
813       return const_cast<DataArrayDouble *>(this);
814     }
815 }
816
817 /*!
818  * Copies all the data from another DataArrayDouble. For more info see
819  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
820  *  \param [in] other - another instance of DataArrayDouble to copy data from.
821  *  \throw If the \a other is not allocated.
822  */
823 void DataArrayDouble::cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL::Exception)
824 {
825   other.checkAllocated();
826   int nbOfTuples=other.getNumberOfTuples();
827   int nbOfComp=other.getNumberOfComponents();
828   allocIfNecessary(nbOfTuples,nbOfComp);
829   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
830   double *pt=getPointer();
831   const double *ptI=other.getConstPointer();
832   for(std::size_t i=0;i<nbOfElems;i++)
833     pt[i]=ptI[i];
834   copyStringInfoFrom(other);
835 }
836
837 /*!
838  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
839  * 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.
840  * If \a this has not already been allocated, number of components is set to one.
841  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
842  * 
843  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
844  */
845 void DataArrayDouble::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
846 {
847   int nbCompo=getNumberOfComponents();
848   if(nbCompo==1)
849     {
850       _mem.reserve(nbOfElems);
851     }
852   else if(nbCompo==0)
853     {
854       _mem.reserve(nbOfElems);
855       _info_on_compo.resize(1);
856     }
857   else
858     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
859 }
860
861 /*!
862  * 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
863  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
864  *
865  * \param [in] val the value to be added in \a this
866  * \throw If \a this has already been allocated with number of components different from one.
867  * \sa DataArrayDouble::pushBackValsSilent
868  */
869 void DataArrayDouble::pushBackSilent(double val) throw(INTERP_KERNEL::Exception)
870 {
871   int nbCompo=getNumberOfComponents();
872   if(nbCompo==1)
873     _mem.pushBack(val);
874   else if(nbCompo==0)
875     {
876       _info_on_compo.resize(1);
877       _mem.pushBack(val);
878     }
879   else
880     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
881 }
882
883 /*!
884  * 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
885  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
886  *
887  *  \param [in] valsBg - an array of values to push at the end of \this.
888  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
889  *              the last value of \a valsBg is \a valsEnd[ -1 ].
890  * \throw If \a this has already been allocated with number of components different from one.
891  * \sa DataArrayDouble::pushBackSilent
892  */
893 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd) throw(INTERP_KERNEL::Exception)
894 {
895   int nbCompo=getNumberOfComponents();
896   if(nbCompo==1)
897     _mem.insertAtTheEnd(valsBg,valsEnd);
898   else if(nbCompo==0)
899     {
900       _info_on_compo.resize(1);
901       _mem.insertAtTheEnd(valsBg,valsEnd);
902     }
903   else
904     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
905 }
906
907 /*!
908  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
909  * \throw If \a this is already empty.
910  * \throw If \a this has number of components different from one.
911  */
912 double DataArrayDouble::popBackSilent() throw(INTERP_KERNEL::Exception)
913 {
914   if(getNumberOfComponents()==1)
915     return _mem.popBack();
916   else
917     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
918 }
919
920 /*!
921  * 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.
922  *
923  * \sa DataArrayDouble::getHeapMemorySize, DataArrayDouble::reserve
924  */
925 void DataArrayDouble::pack() const throw(INTERP_KERNEL::Exception)
926 {
927   _mem.pack();
928 }
929
930 /*!
931  * Allocates the raw data in memory. If exactly same memory as needed already
932  * allocated, it is not re-allocated.
933  *  \param [in] nbOfTuple - number of tuples of data to allocate.
934  *  \param [in] nbOfCompo - number of components of data to allocate.
935  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
936  */
937 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
938 {
939   if(isAllocated())
940     {
941       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
942         alloc(nbOfTuple,nbOfCompo);
943     }
944   else
945     alloc(nbOfTuple,nbOfCompo);
946 }
947
948 /*!
949  * Allocates the raw data in memory. If the memory was already allocated, then it is
950  * freed and re-allocated. See an example of this method use
951  * \ref MEDCouplingArraySteps1WC "here".
952  *  \param [in] nbOfTuple - number of tuples of data to allocate.
953  *  \param [in] nbOfCompo - number of components of data to allocate.
954  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
955  */
956 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
957 {
958   if(nbOfTuple<0 || nbOfCompo<0)
959     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
960   _info_on_compo.resize(nbOfCompo);
961   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
962   declareAsNew();
963 }
964
965 /*!
966  * Assign zero to all values in \a this array. To know more on filling arrays see
967  * \ref MEDCouplingArrayFill.
968  * \throw If \a this is not allocated.
969  */
970 void DataArrayDouble::fillWithZero() throw(INTERP_KERNEL::Exception)
971 {
972   checkAllocated();
973   _mem.fillWithValue(0.);
974   declareAsNew();
975 }
976
977 /*!
978  * Assign \a val to all values in \a this array. To know more on filling arrays see
979  * \ref MEDCouplingArrayFill.
980  *  \param [in] val - the value to fill with.
981  *  \throw If \a this is not allocated.
982  */
983 void DataArrayDouble::fillWithValue(double val) throw(INTERP_KERNEL::Exception)
984 {
985   checkAllocated();
986   _mem.fillWithValue(val);
987   declareAsNew();
988 }
989
990 /*!
991  * Set all values in \a this array so that the i-th element equals to \a init + i
992  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
993  *  \param [in] init - value to assign to the first element of array.
994  *  \throw If \a this->getNumberOfComponents() != 1
995  *  \throw If \a this is not allocated.
996  */
997 void DataArrayDouble::iota(double init) throw(INTERP_KERNEL::Exception)
998 {
999   checkAllocated();
1000   if(getNumberOfComponents()!=1)
1001     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
1002   double *ptr=getPointer();
1003   int ntuples=getNumberOfTuples();
1004   for(int i=0;i<ntuples;i++)
1005     ptr[i]=init+double(i);
1006   declareAsNew();
1007 }
1008
1009 /*!
1010  * Checks if all values in \a this array are equal to \a val at precision \a eps.
1011  *  \param [in] val - value to check equality of array values to.
1012  *  \param [in] eps - precision to check the equality.
1013  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
1014  *                 \a false else.
1015  *  \throw If \a this->getNumberOfComponents() != 1
1016  *  \throw If \a this is not allocated.
1017  */
1018 bool DataArrayDouble::isUniform(double val, double eps) const throw(INTERP_KERNEL::Exception)
1019 {
1020   checkAllocated();
1021   if(getNumberOfComponents()!=1)
1022     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1023   int nbOfTuples=getNumberOfTuples();
1024   const double *w=getConstPointer();
1025   const double *end2=w+nbOfTuples;
1026   const double vmin=val-eps;
1027   const double vmax=val+eps;
1028   for(;w!=end2;w++)
1029     if(*w<vmin || *w>vmax)
1030       return false;
1031   return true;
1032 }
1033
1034 /*!
1035  * Sorts values of the array.
1036  *  \param [in] asc - \a true means ascending order, \a false, descending.
1037  *  \throw If \a this is not allocated.
1038  *  \throw If \a this->getNumberOfComponents() != 1.
1039  */
1040 void DataArrayDouble::sort(bool asc) throw(INTERP_KERNEL::Exception)
1041 {
1042   checkAllocated();
1043   if(getNumberOfComponents()!=1)
1044     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
1045   _mem.sort(asc);
1046   declareAsNew();
1047 }
1048
1049 /*!
1050  * Reverse the array values.
1051  *  \throw If \a this->getNumberOfComponents() < 1.
1052  *  \throw If \a this is not allocated.
1053  */
1054 void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception)
1055 {
1056   checkAllocated();
1057   _mem.reverse(getNumberOfComponents());
1058   declareAsNew();
1059 }
1060
1061 /*!
1062  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1063  * with at least absolute difference value of |\a eps| at each step.
1064  * If not an exception is thrown.
1065  *  \param [in] increasing - if \a true, the array values should be increasing.
1066  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1067  *                    the values are considered different.
1068  *  \throw If sequence of values is not strictly monotonic in agreement with \a
1069  *         increasing arg.
1070  *  \throw If \a this->getNumberOfComponents() != 1.
1071  *  \throw If \a this is not allocated.
1072  */
1073 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
1074 {
1075   if(!isMonotonic(increasing,eps))
1076     {
1077       if (increasing)
1078         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
1079       else
1080         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
1081     }
1082 }
1083
1084 /*!
1085  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1086  * with at least absolute difference value of |\a eps| at each step.
1087  *  \param [in] increasing - if \a true, array values should be increasing.
1088  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1089  *                    the values are considered different.
1090  *  \return bool - \a true if values change in accordance with \a increasing arg.
1091  *  \throw If \a this->getNumberOfComponents() != 1.
1092  *  \throw If \a this is not allocated.
1093  */
1094 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
1095 {
1096   checkAllocated();
1097   if(getNumberOfComponents()!=1)
1098     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
1099   int nbOfElements=getNumberOfTuples();
1100   const double *ptr=getConstPointer();
1101   if(nbOfElements==0)
1102     return true;
1103   double ref=ptr[0];
1104   double absEps=fabs(eps);
1105   if(increasing)
1106     {
1107       for(int i=1;i<nbOfElements;i++)
1108         {
1109           if(ptr[i]<(ref+absEps))
1110             return false;
1111           ref=ptr[i];
1112         }
1113       return true;
1114     }
1115   else
1116     {
1117       for(int i=1;i<nbOfElements;i++)
1118         {
1119           if(ptr[i]>(ref-absEps))
1120             return false;
1121           ref=ptr[i];
1122         }
1123       return true;
1124     }
1125 }
1126
1127 /*!
1128  * Returns a textual and human readable representation of \a this instance of
1129  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
1130  *  \return std::string - text describing \a this DataArrayDouble.
1131  */
1132 std::string DataArrayDouble::repr() const throw(INTERP_KERNEL::Exception)
1133 {
1134   std::ostringstream ret;
1135   reprStream(ret);
1136   return ret.str();
1137 }
1138
1139 std::string DataArrayDouble::reprZip() const throw(INTERP_KERNEL::Exception)
1140 {
1141   std::ostringstream ret;
1142   reprZipStream(ret);
1143   return ret.str();
1144 }
1145
1146 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
1147 {
1148   std::string idt(indent,' ');
1149   ofs.precision(17);
1150   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1151   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
1152   std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1153   ofs << std::endl << idt << "</DataArray>\n";
1154 }
1155
1156 void DataArrayDouble::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1157 {
1158   stream << "Name of double array : \"" << _name << "\"\n";
1159   reprWithoutNameStream(stream);
1160 }
1161
1162 void DataArrayDouble::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1163 {
1164   stream << "Name of double array : \"" << _name << "\"\n";
1165   reprZipWithoutNameStream(stream);
1166 }
1167
1168 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1169 {
1170   DataArray::reprWithoutNameStream(stream);
1171   stream.precision(17);
1172   _mem.repr(getNumberOfComponents(),stream);
1173 }
1174
1175 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1176 {
1177   DataArray::reprWithoutNameStream(stream);
1178   stream.precision(17);
1179   _mem.reprZip(getNumberOfComponents(),stream);
1180 }
1181
1182 void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1183 {
1184   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1185   const double *data=getConstPointer();
1186   stream.precision(17);
1187   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1188   if(nbTuples*nbComp>=1)
1189     {
1190       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1191       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1192       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1193       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1194     }
1195   else
1196     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1197   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1198 }
1199
1200 /*!
1201  * Method that gives a quick overvien of \a this for python.
1202  */
1203 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1204 {
1205   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1206   stream << "DataArrayDouble C++ instance at " << this << ". ";
1207   if(isAllocated())
1208     {
1209       int nbOfCompo=(int)_info_on_compo.size();
1210       if(nbOfCompo>=1)
1211         {
1212           int nbOfTuples=getNumberOfTuples();
1213           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1214           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1215         }
1216       else
1217         stream << "Number of components : 0.";
1218     }
1219   else
1220     stream << "*** No data allocated ****";
1221 }
1222
1223 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
1224 {
1225   const double *data=begin();
1226   int nbOfTuples=getNumberOfTuples();
1227   int nbOfCompo=(int)_info_on_compo.size();
1228   std::ostringstream oss2; oss2 << "[";
1229   oss2.precision(17);
1230   std::string oss2Str(oss2.str());
1231   bool isFinished=true;
1232   for(int i=0;i<nbOfTuples && isFinished;i++)
1233     {
1234       if(nbOfCompo>1)
1235         {
1236           oss2 << "(";
1237           for(int j=0;j<nbOfCompo;j++,data++)
1238             {
1239               oss2 << *data;
1240               if(j!=nbOfCompo-1) oss2 << ", ";
1241             }
1242           oss2 << ")";
1243         }
1244       else
1245         oss2 << *data++;
1246       if(i!=nbOfTuples-1) oss2 << ", ";
1247       std::string oss3Str(oss2.str());
1248       if(oss3Str.length()<maxNbOfByteInRepr)
1249         oss2Str=oss3Str;
1250       else
1251         isFinished=false;
1252     }
1253   stream << oss2Str;
1254   if(!isFinished)
1255     stream << "... ";
1256   stream << "]";
1257 }
1258
1259 /*!
1260  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1261  * mismatch is given.
1262  * 
1263  * \param [in] other the instance to be compared with \a this
1264  * \param [in] prec the precision to compare numeric data of the arrays.
1265  * \param [out] reason In case of inequality returns the reason.
1266  * \sa DataArrayDouble::isEqual
1267  */
1268 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1269 {
1270   if(!areInfoEqualsIfNotWhy(other,reason))
1271     return false;
1272   return _mem.isEqual(other._mem,prec,reason);
1273 }
1274
1275 /*!
1276  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1277  * \ref MEDCouplingArrayBasicsCompare.
1278  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1279  *  \param [in] prec - precision value to compare numeric data of the arrays.
1280  *  \return bool - \a true if the two arrays are equal, \a false else.
1281  */
1282 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1283 {
1284   std::string tmp;
1285   return isEqualIfNotWhy(other,prec,tmp);
1286 }
1287
1288 /*!
1289  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1290  * \ref MEDCouplingArrayBasicsCompare.
1291  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1292  *  \param [in] prec - precision value to compare numeric data of the arrays.
1293  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1294  */
1295 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception)
1296 {
1297   std::string tmp;
1298   return _mem.isEqual(other._mem,prec,tmp);
1299 }
1300
1301 /*!
1302  * Changes number of tuples in the array. If the new number of tuples is smaller
1303  * than the current number the array is truncated, otherwise the array is extended.
1304  *  \param [in] nbOfTuples - new number of tuples. 
1305  *  \throw If \a this is not allocated.
1306  *  \throw If \a nbOfTuples is negative.
1307  */
1308 void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
1309 {
1310   if(nbOfTuples<0)
1311     throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
1312   checkAllocated();
1313   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1314   declareAsNew();
1315 }
1316
1317 /*!
1318  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1319  * array to the new one.
1320  *  \return DataArrayInt * - the new instance of DataArrayInt.
1321  */
1322 DataArrayInt *DataArrayDouble::convertToIntArr() const
1323 {
1324   DataArrayInt *ret=DataArrayInt::New();
1325   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1326   std::size_t nbOfVals=getNbOfElems();
1327   const double *src=getConstPointer();
1328   int *dest=ret->getPointer();
1329   std::copy(src,src+nbOfVals,dest);
1330   ret->copyStringInfoFrom(*this);
1331   return ret;
1332 }
1333
1334 /*!
1335  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1336  * arranged in memory. If \a this array holds 2 components of 3 values:
1337  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1338  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1339  *  \warning Do not confuse this method with transpose()!
1340  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1341  *          is to delete using decrRef() as it is no more needed.
1342  *  \throw If \a this is not allocated.
1343  */
1344 DataArrayDouble *DataArrayDouble::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
1345 {
1346   if(_mem.isNull())
1347     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1348   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1349   DataArrayDouble *ret=DataArrayDouble::New();
1350   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1351   return ret;
1352 }
1353
1354 /*!
1355  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1356  * arranged in memory. If \a this array holds 2 components of 3 values:
1357  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1358  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1359  *  \warning Do not confuse this method with transpose()!
1360  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1361  *          is to delete using decrRef() as it is no more needed.
1362  *  \throw If \a this is not allocated.
1363  */
1364 DataArrayDouble *DataArrayDouble::toNoInterlace() const throw(INTERP_KERNEL::Exception)
1365 {
1366   if(_mem.isNull())
1367     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1368   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1369   DataArrayDouble *ret=DataArrayDouble::New();
1370   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1371   return ret;
1372 }
1373
1374 /*!
1375  * Permutes values of \a this array as required by \a old2New array. The values are
1376  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1377  * the same as in \this one.
1378  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1379  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1380  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1381  *     giving a new position for i-th old value.
1382  */
1383 void DataArrayDouble::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
1384 {
1385   checkAllocated();
1386   int nbTuples=getNumberOfTuples();
1387   int nbOfCompo=getNumberOfComponents();
1388   double *tmp=new double[nbTuples*nbOfCompo];
1389   const double *iptr=getConstPointer();
1390   for(int i=0;i<nbTuples;i++)
1391     {
1392       int v=old2New[i];
1393       if(v>=0 && v<nbTuples)
1394         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1395       else
1396         {
1397           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1398           throw INTERP_KERNEL::Exception(oss.str().c_str());
1399         }
1400     }
1401   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1402   delete [] tmp;
1403   declareAsNew();
1404 }
1405
1406 /*!
1407  * Permutes values of \a this array as required by \a new2Old array. The values are
1408  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1409  * the same as in \this one.
1410  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1411  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1412  *     giving a previous position of i-th new value.
1413  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1414  *          is to delete using decrRef() as it is no more needed.
1415  */
1416 void DataArrayDouble::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
1417 {
1418   checkAllocated();
1419   int nbTuples=getNumberOfTuples();
1420   int nbOfCompo=getNumberOfComponents();
1421   double *tmp=new double[nbTuples*nbOfCompo];
1422   const double *iptr=getConstPointer();
1423   for(int i=0;i<nbTuples;i++)
1424     {
1425       int v=new2Old[i];
1426       if(v>=0 && v<nbTuples)
1427         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1428       else
1429         {
1430           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1431           throw INTERP_KERNEL::Exception(oss.str().c_str());
1432         }
1433     }
1434   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1435   delete [] tmp;
1436   declareAsNew();
1437 }
1438
1439 /*!
1440  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1441  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1442  * Number of tuples in the result array remains the same as in \this one.
1443  * If a permutation reduction is needed, renumberAndReduce() should be used.
1444  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1445  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1446  *          giving a new position for i-th old value.
1447  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1448  *          is to delete using decrRef() as it is no more needed.
1449  *  \throw If \a this is not allocated.
1450  */
1451 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
1452 {
1453   checkAllocated();
1454   int nbTuples=getNumberOfTuples();
1455   int nbOfCompo=getNumberOfComponents();
1456   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1457   ret->alloc(nbTuples,nbOfCompo);
1458   ret->copyStringInfoFrom(*this);
1459   const double *iptr=getConstPointer();
1460   double *optr=ret->getPointer();
1461   for(int i=0;i<nbTuples;i++)
1462     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1463   ret->copyStringInfoFrom(*this);
1464   return ret.retn();
1465 }
1466
1467 /*!
1468  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1469  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1470  * tuples in the result array remains the same as in \this one.
1471  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1472  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1473  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1474  *     giving a previous position of i-th new value.
1475  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1476  *          is to delete using decrRef() as it is no more needed.
1477  */
1478 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
1479 {
1480   checkAllocated();
1481   int nbTuples=getNumberOfTuples();
1482   int nbOfCompo=getNumberOfComponents();
1483   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1484   ret->alloc(nbTuples,nbOfCompo);
1485   ret->copyStringInfoFrom(*this);
1486   const double *iptr=getConstPointer();
1487   double *optr=ret->getPointer();
1488   for(int i=0;i<nbTuples;i++)
1489     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1490   ret->copyStringInfoFrom(*this);
1491   return ret.retn();
1492 }
1493
1494 /*!
1495  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1496  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1497  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1498  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1499  * \a old2New[ i ] is negative, is missing from the result array.
1500  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1501  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1502  *     giving a new position for i-th old tuple and giving negative position for
1503  *     for i-th old tuple that should be omitted.
1504  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1505  *          is to delete using decrRef() as it is no more needed.
1506  */
1507 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
1508 {
1509   checkAllocated();
1510   int nbTuples=getNumberOfTuples();
1511   int nbOfCompo=getNumberOfComponents();
1512   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1513   ret->alloc(newNbOfTuple,nbOfCompo);
1514   const double *iptr=getConstPointer();
1515   double *optr=ret->getPointer();
1516   for(int i=0;i<nbTuples;i++)
1517     {
1518       int w=old2New[i];
1519       if(w>=0)
1520         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1521     }
1522   ret->copyStringInfoFrom(*this);
1523   return ret.retn();
1524 }
1525
1526 /*!
1527  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1528  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1529  * \a new2OldBg array.
1530  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1531  * This method is equivalent to renumberAndReduce() except that convention in input is
1532  * \c new2old and \b not \c old2new.
1533  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1534  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1535  *              tuple index in \a this array to fill the i-th tuple in the new array.
1536  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1537  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1538  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1539  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1540  *          is to delete using decrRef() as it is no more needed.
1541  */
1542 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1543 {
1544   checkAllocated();
1545   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1546   int nbComp=getNumberOfComponents();
1547   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1548   ret->copyStringInfoFrom(*this);
1549   double *pt=ret->getPointer();
1550   const double *srcPt=getConstPointer();
1551   int i=0;
1552   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1553     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1554   ret->copyStringInfoFrom(*this);
1555   return ret.retn();
1556 }
1557
1558 /*!
1559  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1560  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1561  * \a new2OldBg array.
1562  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1563  * This method is equivalent to renumberAndReduce() except that convention in input is
1564  * \c new2old and \b not \c old2new.
1565  * This method is equivalent to selectByTupleId() except that it prevents coping data
1566  * from behind the end of \a this array.
1567  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1568  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1569  *              tuple index in \a this array to fill the i-th tuple in the new array.
1570  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1571  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1572  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1573  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1574  *          is to delete using decrRef() as it is no more needed.
1575  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1576  */
1577 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
1578 {
1579   checkAllocated();
1580   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1581   int nbComp=getNumberOfComponents();
1582   int oldNbOfTuples=getNumberOfTuples();
1583   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1584   ret->copyStringInfoFrom(*this);
1585   double *pt=ret->getPointer();
1586   const double *srcPt=getConstPointer();
1587   int i=0;
1588   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1589     if(*w>=0 && *w<oldNbOfTuples)
1590       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1591     else
1592       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1593   ret->copyStringInfoFrom(*this);
1594   return ret.retn();
1595 }
1596
1597 /*!
1598  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1599  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1600  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1601  * command \c range( \a bg, \a end2, \a step ).
1602  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1603  * not constructed explicitly.
1604  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1605  *  \param [in] bg - index of the first tuple to copy from \a this array.
1606  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1607  *  \param [in] step - index increment to get index of the next tuple to copy.
1608  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1609  *          is to delete using decrRef() as it is no more needed.
1610  *  \sa DataArrayDouble::substr.
1611  */
1612 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
1613 {
1614   checkAllocated();
1615   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1616   int nbComp=getNumberOfComponents();
1617   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1618   ret->alloc(newNbOfTuples,nbComp);
1619   double *pt=ret->getPointer();
1620   const double *srcPt=getConstPointer()+bg*nbComp;
1621   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1622     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1623   ret->copyStringInfoFrom(*this);
1624   return ret.retn();
1625 }
1626
1627 /*!
1628  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1629  * of tuples specified by \a ranges parameter.
1630  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1631  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1632  *              of tuples in [\c begin,\c end) format.
1633  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1634  *          is to delete using decrRef() as it is no more needed.
1635  *  \throw If \a end < \a begin.
1636  *  \throw If \a end > \a this->getNumberOfTuples().
1637  *  \throw If \a this is not allocated.
1638  */
1639 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
1640 {
1641   checkAllocated();
1642   int nbOfComp=getNumberOfComponents();
1643   int nbOfTuplesThis=getNumberOfTuples();
1644   if(ranges.empty())
1645     {
1646       DataArrayDouble *ret=DataArrayDouble::New();
1647       ret->alloc(0,nbOfComp);
1648       ret->copyStringInfoFrom(*this);
1649       return ret;
1650     }
1651   int ref=ranges.front().first;
1652   int nbOfTuples=0;
1653   bool isIncreasing=true;
1654   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1655     {
1656       if((*it).first<=(*it).second)
1657         {
1658           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1659             {
1660               nbOfTuples+=(*it).second-(*it).first;
1661               if(isIncreasing)
1662                 isIncreasing=ref<=(*it).first;
1663               ref=(*it).second;
1664             }
1665           else
1666             {
1667               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1668               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1669               throw INTERP_KERNEL::Exception(oss.str().c_str());
1670             }
1671         }
1672       else
1673         {
1674           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1675           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1676           throw INTERP_KERNEL::Exception(oss.str().c_str());
1677         }
1678     }
1679   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1680     return deepCpy();
1681   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1682   ret->alloc(nbOfTuples,nbOfComp);
1683   ret->copyStringInfoFrom(*this);
1684   const double *src=getConstPointer();
1685   double *work=ret->getPointer();
1686   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1687     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1688   return ret.retn();
1689 }
1690
1691 /*!
1692  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1693  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1694  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1695  * This method is a specialization of selectByTupleId2().
1696  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1697  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1698  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1699  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1700  *          is to delete using decrRef() as it is no more needed.
1701  *  \throw If \a tupleIdBg < 0.
1702  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1703     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1704  *  \sa DataArrayDouble::selectByTupleId2
1705  */
1706 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
1707 {
1708   checkAllocated();
1709   int nbt=getNumberOfTuples();
1710   if(tupleIdBg<0)
1711     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1712   if(tupleIdBg>nbt)
1713     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1714   int trueEnd=tupleIdEnd;
1715   if(tupleIdEnd!=-1)
1716     {
1717       if(tupleIdEnd>nbt)
1718         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1719     }
1720   else
1721     trueEnd=nbt;
1722   int nbComp=getNumberOfComponents();
1723   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1724   ret->alloc(trueEnd-tupleIdBg,nbComp);
1725   ret->copyStringInfoFrom(*this);
1726   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1727   return ret.retn();
1728 }
1729
1730 /*!
1731  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1732  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1733  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1734  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1735  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1736  * components.  
1737  *  \param [in] newNbOfComp - number of components for the new array to have.
1738  *  \param [in] dftValue - value assigned to new values added to the new array.
1739  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1740  *          is to delete using decrRef() as it is no more needed.
1741  *  \throw If \a this is not allocated.
1742  */
1743 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception)
1744 {
1745   checkAllocated();
1746   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1747   ret->alloc(getNumberOfTuples(),newNbOfComp);
1748   const double *oldc=getConstPointer();
1749   double *nc=ret->getPointer();
1750   int nbOfTuples=getNumberOfTuples();
1751   int oldNbOfComp=getNumberOfComponents();
1752   int dim=std::min(oldNbOfComp,newNbOfComp);
1753   for(int i=0;i<nbOfTuples;i++)
1754     {
1755       int j=0;
1756       for(;j<dim;j++)
1757         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1758       for(;j<newNbOfComp;j++)
1759         nc[newNbOfComp*i+j]=dftValue;
1760     }
1761   ret->setName(getName().c_str());
1762   for(int i=0;i<dim;i++)
1763     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
1764   ret->setName(getName().c_str());
1765   return ret.retn();
1766 }
1767
1768 /*!
1769  * Changes the number of components within \a this array so that its raw data **does
1770  * not** change, instead splitting this data into tuples changes.
1771  *  \warning This method erases all (name and unit) component info set before!
1772  *  \param [in] newNbOfComp - number of components for \a this array to have.
1773  *  \throw If \a this is not allocated
1774  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1775  *  \throw If \a newNbOfCompo is lower than 1.
1776  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1777  *  \warning This method erases all (name and unit) component info set before!
1778  */
1779 void DataArrayDouble::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
1780 {
1781   checkAllocated();
1782   if(newNbOfCompo<1)
1783     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1784   std::size_t nbOfElems=getNbOfElems();
1785   if(nbOfElems%newNbOfCompo!=0)
1786     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1787   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1788     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1789   _info_on_compo.clear();
1790   _info_on_compo.resize(newNbOfCompo);
1791   declareAsNew();
1792 }
1793
1794 /*!
1795  * Changes the number of components within \a this array to be equal to its number
1796  * of tuples, and inversely its number of tuples to become equal to its number of 
1797  * components. So that its raw data **does not** change, instead splitting this
1798  * data into tuples changes.
1799  *  \warning This method erases all (name and unit) component info set before!
1800  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1801  *  \throw If \a this is not allocated.
1802  *  \sa rearrange()
1803  */
1804 void DataArrayDouble::transpose() throw(INTERP_KERNEL::Exception)
1805 {
1806   checkAllocated();
1807   int nbOfTuples=getNumberOfTuples();
1808   rearrange(nbOfTuples);
1809 }
1810
1811 /*!
1812  * Returns a copy of \a this array composed of selected components.
1813  * The new DataArrayDouble has the same number of tuples but includes components
1814  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1815  * can be either less, same or more than \a this->getNbOfElems().
1816  *  \param [in] compoIds - sequence of zero based indices of components to include
1817  *              into the new array.
1818  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1819  *          is to delete using decrRef() as it is no more needed.
1820  *  \throw If \a this is not allocated.
1821  *  \throw If a component index (\a i) is not valid: 
1822  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1823  *
1824  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1825  */
1826 DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
1827 {
1828   checkAllocated();
1829   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1830   std::size_t newNbOfCompo=compoIds.size();
1831   int oldNbOfCompo=getNumberOfComponents();
1832   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1833     if((*it)<0 || (*it)>=oldNbOfCompo)
1834       {
1835         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1836         throw INTERP_KERNEL::Exception(oss.str().c_str());
1837       }
1838   int nbOfTuples=getNumberOfTuples();
1839   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1840   ret->copyPartOfStringInfoFrom(*this,compoIds);
1841   const double *oldc=getConstPointer();
1842   double *nc=ret->getPointer();
1843   for(int i=0;i<nbOfTuples;i++)
1844     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1845       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1846   return ret.retn();
1847 }
1848
1849 /*!
1850  * Appends components of another array to components of \a this one, tuple by tuple.
1851  * So that the number of tuples of \a this array remains the same and the number of 
1852  * components increases.
1853  *  \param [in] other - the DataArrayDouble to append to \a this one.
1854  *  \throw If \a this is not allocated.
1855  *  \throw If \a this and \a other arrays have different number of tuples.
1856  *
1857  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1858  *
1859  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1860  */
1861 void DataArrayDouble::meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
1862 {
1863   checkAllocated();
1864   other->checkAllocated();
1865   int nbOfTuples=getNumberOfTuples();
1866   if(nbOfTuples!=other->getNumberOfTuples())
1867     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1868   int nbOfComp1=getNumberOfComponents();
1869   int nbOfComp2=other->getNumberOfComponents();
1870   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1871   double *w=newArr;
1872   const double *inp1=getConstPointer();
1873   const double *inp2=other->getConstPointer();
1874   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1875     {
1876       w=std::copy(inp1,inp1+nbOfComp1,w);
1877       w=std::copy(inp2,inp2+nbOfComp2,w);
1878     }
1879   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1880   std::vector<int> compIds(nbOfComp2);
1881   for(int i=0;i<nbOfComp2;i++)
1882     compIds[i]=nbOfComp1+i;
1883   copyPartOfStringInfoFrom2(compIds,*other);
1884 }
1885
1886 /*!
1887  * This method checks that all tuples in \a other are in \a this.
1888  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1889  * 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.
1890  *
1891  * \param [in] other - the array having the same number of components than \a this.
1892  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1893  * \sa DataArrayDouble::findCommonTuples
1894  */
1895 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const throw(INTERP_KERNEL::Exception)
1896 {
1897   if(!other)
1898     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1899   checkAllocated(); other->checkAllocated();
1900   if(getNumberOfComponents()!=other->getNumberOfComponents())
1901     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1902   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1903   DataArrayInt *c=0,*ci=0;
1904   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1905   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1906   int newNbOfTuples=-1;
1907   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1908   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1909   tupleIds=ret1.retn();
1910   return newNbOfTuples==getNumberOfTuples();
1911 }
1912
1913 /*!
1914  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1915  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1916  * distance separating two points is computed with the infinite norm.
1917  *
1918  * Indices of coincident tuples are stored in output arrays.
1919  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1920  *
1921  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1922  * MEDCouplingUMesh::mergeNodes().
1923  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1924  *              considered not coincident.
1925  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1926  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1927  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1928  *               \a comm->getNumberOfComponents() == 1. 
1929  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1930  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1931  *               groups of (indices of) coincident tuples. Its every value is a tuple
1932  *               index where a next group of tuples begins. For example the second
1933  *               group of tuples in \a comm is described by following range of indices:
1934  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1935  *               gives the number of groups of coincident tuples.
1936  *  \throw If \a this is not allocated.
1937  *  \throw If the number of components is not in [1,2,3].
1938  *
1939  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1940  *
1941  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1942  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
1943  */
1944 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception)
1945 {
1946   checkAllocated();
1947   int nbOfCompo=getNumberOfComponents();
1948   if ((nbOfCompo<1) || (nbOfCompo>3)) //test before work
1949     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
1950   
1951   int nbOfTuples=getNumberOfTuples();
1952   //
1953   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1954   switch(nbOfCompo)
1955     {
1956     case 3:
1957       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1958       break;
1959     case 2:
1960       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1961       break;
1962     case 1:
1963       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1964       break;
1965     default:
1966       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
1967     }
1968   comm=c.retn();
1969   commIndex=cI.retn();
1970 }
1971
1972 /*!
1973  * 
1974  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1975  *             \a nbTimes  should be at least equal to 1.
1976  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1977  * \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.
1978  */
1979 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
1980 {
1981   checkAllocated();
1982   if(getNumberOfComponents()!=1)
1983     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1984   if(nbTimes<1)
1985     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1986   int nbTuples=getNumberOfTuples();
1987   const double *inPtr=getConstPointer();
1988   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1989   double *retPtr=ret->getPointer();
1990   for(int i=0;i<nbTuples;i++,inPtr++)
1991     {
1992       double val=*inPtr;
1993       for(int j=0;j<nbTimes;j++,retPtr++)
1994         *retPtr=val;
1995     }
1996   ret->copyStringInfoFrom(*this);
1997   return ret.retn();
1998 }
1999
2000 /*!
2001  * This methods returns the minimal distance between the two set of points \a this and \a other.
2002  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2003  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2004  *
2005  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2006  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2007  * \return the minimal distance between the two set of points \a this and \a other.
2008  * \sa DataArrayDouble::findClosestTupleId
2009  */
2010 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const throw(INTERP_KERNEL::Exception)
2011 {
2012   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
2013   int nbOfCompo(getNumberOfComponents());
2014   int otherNbTuples(other->getNumberOfTuples());
2015   const double *thisPt(begin()),*otherPt(other->begin());
2016   const int *part1Pt(part1->begin());
2017   double ret=std::numeric_limits<double>::max();
2018   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2019     {
2020       double tmp(0.);
2021       for(int j=0;j<nbOfCompo;j++)
2022         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2023       if(tmp<ret)
2024         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2025     }
2026   return sqrt(ret);
2027 }
2028
2029 /*!
2030  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2031  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2032  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2033  *
2034  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2035  * \sa DataArrayDouble::minimalDistanceTo
2036  */
2037 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
2038 {
2039   if(!other)
2040     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2041   checkAllocated(); other->checkAllocated();
2042   int nbOfCompo=getNumberOfComponents();
2043   if(nbOfCompo!=other->getNumberOfComponents())
2044     {
2045       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2046       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2047       throw INTERP_KERNEL::Exception(oss.str().c_str());
2048     }
2049   int nbOfTuples=other->getNumberOfTuples();
2050   int thisNbOfTuples=getNumberOfTuples();
2051   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2052   double bounds[6];
2053   getMinMaxPerComponent(bounds);
2054   switch(nbOfCompo)
2055     {
2056     case 3:
2057       {
2058         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2059         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2060         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2061         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2062         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2063         break;
2064       }
2065     case 2:
2066       {
2067         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2068         double delta=std::max(xDelta,yDelta);
2069         double characSize=sqrt(delta/(double)thisNbOfTuples);
2070         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2071         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2072         break;
2073       }
2074     case 1:
2075       {
2076         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2077         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2078         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2079         break;
2080       }
2081     default:
2082       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2083     }
2084   return ret.retn();
2085 }
2086
2087 /*!
2088  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2089  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2090  * space. The distance between tuples is computed using norm2. If several tuples are
2091  * not far each from other than \a prec, only one of them remains in the result
2092  * array. The order of tuples in the result array is same as in \a this one except
2093  * that coincident tuples are excluded.
2094  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2095  *              considered not coincident.
2096  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2097  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2098  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2099  *          is to delete using decrRef() as it is no more needed.
2100  *  \throw If \a this is not allocated.
2101  *  \throw If the number of components is not in [1,2,3].
2102  *
2103  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2104  */
2105 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception)
2106 {
2107   checkAllocated();
2108   DataArrayInt *c0=0,*cI0=0;
2109   findCommonTuples(prec,limitTupleId,c0,cI0);
2110   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2111   int newNbOfTuples=-1;
2112   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2113   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2114 }
2115
2116 /*!
2117  * Copy all components in a specified order from another DataArrayDouble.
2118  * Both numerical and textual data is copied. The number of tuples in \a this and
2119  * the other array can be different.
2120  *  \param [in] a - the array to copy data from.
2121  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2122  *              to be copied.
2123  *  \throw If \a a is NULL.
2124  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2125  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2126  *
2127  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2128  */
2129 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
2130 {
2131   if(!a)
2132     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2133   checkAllocated();
2134   copyPartOfStringInfoFrom2(compoIds,*a);
2135   std::size_t partOfCompoSz=compoIds.size();
2136   int nbOfCompo=getNumberOfComponents();
2137   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2138   const double *ac=a->getConstPointer();
2139   double *nc=getPointer();
2140   for(int i=0;i<nbOfTuples;i++)
2141     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2142       nc[nbOfCompo*i+compoIds[j]]=*ac;
2143 }
2144
2145 /*!
2146  * Copy all values from another DataArrayDouble into specified tuples and components
2147  * of \a this array. Textual data is not copied.
2148  * The tree parameters defining set of indices of tuples and components are similar to
2149  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2150  *  \param [in] a - the array to copy values from.
2151  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2152  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2153  *              are located.
2154  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2155  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2156  *  \param [in] endComp - index of the component before which the components to assign
2157  *              to are located.
2158  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2159  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2160  *              must be equal to the number of columns to assign to, else an
2161  *              exception is thrown; if \a false, then it is only required that \a
2162  *              a->getNbOfElems() equals to number of values to assign to (this condition
2163  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2164  *              values to assign to is given by following Python expression:
2165  *              \a nbTargetValues = 
2166  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2167  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2168  *  \throw If \a a is NULL.
2169  *  \throw If \a a is not allocated.
2170  *  \throw If \a this is not allocated.
2171  *  \throw If parameters specifying tuples and components to assign to do not give a
2172  *            non-empty range of increasing indices.
2173  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2174  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2175  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2176  *
2177  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2178  */
2179 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2180 {
2181   if(!a)
2182     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2183   const char msg[]="DataArrayDouble::setPartOfValues1";
2184   checkAllocated();
2185   a->checkAllocated();
2186   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2187   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2188   int nbComp=getNumberOfComponents();
2189   int nbOfTuples=getNumberOfTuples();
2190   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2191   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2192   bool assignTech=true;
2193   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2194     {
2195       if(strictCompoCompare)
2196         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2197     }
2198   else
2199     {
2200       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2201       assignTech=false;
2202     }
2203   const double *srcPt=a->getConstPointer();
2204   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2205   if(assignTech)
2206     {
2207       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2208         for(int j=0;j<newNbOfComp;j++,srcPt++)
2209           pt[j*stepComp]=*srcPt;
2210     }
2211   else
2212     {
2213       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2214         {
2215           const double *srcPt2=srcPt;
2216           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2217             pt[j*stepComp]=*srcPt2;
2218         }
2219     }
2220 }
2221
2222 /*!
2223  * Assign a given value to values at specified tuples and components of \a this array.
2224  * The tree parameters defining set of indices of tuples and components are similar to
2225  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2226  *  \param [in] a - the value to assign.
2227  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2228  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2229  *              are located.
2230  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2231  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2232  *  \param [in] endComp - index of the component before which the components to assign
2233  *              to are located.
2234  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2235  *  \throw If \a this is not allocated.
2236  *  \throw If parameters specifying tuples and components to assign to, do not give a
2237  *            non-empty range of increasing indices or indices are out of a valid range
2238  *            for \this array.
2239  *
2240  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2241  */
2242 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2243 {
2244   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2245   checkAllocated();
2246   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2247   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2248   int nbComp=getNumberOfComponents();
2249   int nbOfTuples=getNumberOfTuples();
2250   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2251   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2252   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2253   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2254     for(int j=0;j<newNbOfComp;j++)
2255       pt[j*stepComp]=a;
2256 }
2257
2258 /*!
2259  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2260  * components of \a this array. Textual data is not copied.
2261  * The tuples and components to assign to are defined by C arrays of indices.
2262  * There are two *modes of usage*:
2263  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2264  *   of \a a is assigned to its own location within \a this array. 
2265  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2266  *   components of every specified tuple of \a this array. In this mode it is required
2267  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2268  *
2269  *  \param [in] a - the array to copy values from.
2270  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2271  *              assign values of \a a to.
2272  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2273  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2274  *              \a bgTuples <= \a pi < \a endTuples.
2275  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2276  *              assign values of \a a to.
2277  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2278  *              pointer to a component index <em>(pi)</em> varies as this: 
2279  *              \a bgComp <= \a pi < \a endComp.
2280  *  \param [in] strictCompoCompare - this parameter is checked only if the
2281  *               *mode of usage* is the first; if it is \a true (default), 
2282  *               then \a a->getNumberOfComponents() must be equal 
2283  *               to the number of specified columns, else this is not required.
2284  *  \throw If \a a is NULL.
2285  *  \throw If \a a is not allocated.
2286  *  \throw If \a this is not allocated.
2287  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2288  *         out of a valid range for \a this array.
2289  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2290  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2291  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2292  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2293  *
2294  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2295  */
2296 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2297 {
2298   if(!a)
2299     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2300   const char msg[]="DataArrayDouble::setPartOfValues2";
2301   checkAllocated();
2302   a->checkAllocated();
2303   int nbComp=getNumberOfComponents();
2304   int nbOfTuples=getNumberOfTuples();
2305   for(const int *z=bgComp;z!=endComp;z++)
2306     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2307   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2308   int newNbOfComp=(int)std::distance(bgComp,endComp);
2309   bool assignTech=true;
2310   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2311     {
2312       if(strictCompoCompare)
2313         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2314     }
2315   else
2316     {
2317       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2318       assignTech=false;
2319     }
2320   double *pt=getPointer();
2321   const double *srcPt=a->getConstPointer();
2322   if(assignTech)
2323     {    
2324       for(const int *w=bgTuples;w!=endTuples;w++)
2325         {
2326           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2327           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2328             {    
2329               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2330             }
2331         }
2332     }
2333   else
2334     {
2335       for(const int *w=bgTuples;w!=endTuples;w++)
2336         {
2337           const double *srcPt2=srcPt;
2338           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2339           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2340             {    
2341               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2342             }
2343         }
2344     }
2345 }
2346
2347 /*!
2348  * Assign a given value to values at specified tuples and components of \a this array.
2349  * The tuples and components to assign to are defined by C arrays of indices.
2350  *  \param [in] a - the value to assign.
2351  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2352  *              assign \a a to.
2353  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2354  *              pointer to a tuple index (\a pi) varies as this: 
2355  *              \a bgTuples <= \a pi < \a endTuples.
2356  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2357  *              assign \a a to.
2358  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2359  *              pointer to a component index (\a pi) varies as this: 
2360  *              \a bgComp <= \a pi < \a endComp.
2361  *  \throw If \a this is not allocated.
2362  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2363  *         out of a valid range for \a this array.
2364  *
2365  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2366  */
2367 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2368 {
2369   checkAllocated();
2370   int nbComp=getNumberOfComponents();
2371   int nbOfTuples=getNumberOfTuples();
2372   for(const int *z=bgComp;z!=endComp;z++)
2373     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2374   double *pt=getPointer();
2375   for(const int *w=bgTuples;w!=endTuples;w++)
2376     for(const int *z=bgComp;z!=endComp;z++)
2377       {
2378         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2379         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2380       }
2381 }
2382
2383 /*!
2384  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2385  * components of \a this array. Textual data is not copied.
2386  * The tuples to assign to are defined by a C array of indices.
2387  * The components to assign to are defined by three values similar to parameters of
2388  * the Python function \c range(\c start,\c stop,\c step).
2389  * There are two *modes of usage*:
2390  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2391  *   of \a a is assigned to its own location within \a this array. 
2392  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2393  *   components of every specified tuple of \a this array. In this mode it is required
2394  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2395  *
2396  *  \param [in] a - the array to copy values from.
2397  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2398  *              assign values of \a a to.
2399  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2400  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2401  *              \a bgTuples <= \a pi < \a endTuples.
2402  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2403  *  \param [in] endComp - index of the component before which the components to assign
2404  *              to are located.
2405  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2406  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2407  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2408  *               then \a a->getNumberOfComponents() must be equal 
2409  *               to the number of specified columns, else this is not required.
2410  *  \throw If \a a is NULL.
2411  *  \throw If \a a is not allocated.
2412  *  \throw If \a this is not allocated.
2413  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2414  *         \a this array.
2415  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2416  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2417  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2418  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2419  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2420  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2421  *  \throw If parameters specifying components to assign to, do not give a
2422  *            non-empty range of increasing indices or indices are out of a valid range
2423  *            for \this array.
2424  *
2425  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2426  */
2427 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2428 {
2429   if(!a)
2430     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2431   const char msg[]="DataArrayDouble::setPartOfValues3";
2432   checkAllocated();
2433   a->checkAllocated();
2434   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2435   int nbComp=getNumberOfComponents();
2436   int nbOfTuples=getNumberOfTuples();
2437   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2438   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2439   bool assignTech=true;
2440   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2441     {
2442       if(strictCompoCompare)
2443         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2444     }
2445   else
2446     {
2447       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2448       assignTech=false;
2449     }
2450   double *pt=getPointer()+bgComp;
2451   const double *srcPt=a->getConstPointer();
2452   if(assignTech)
2453     {
2454       for(const int *w=bgTuples;w!=endTuples;w++)
2455         for(int j=0;j<newNbOfComp;j++,srcPt++)
2456           {
2457             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2458             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2459           }
2460     }
2461   else
2462     {
2463       for(const int *w=bgTuples;w!=endTuples;w++)
2464         {
2465           const double *srcPt2=srcPt;
2466           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2467             {
2468               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2469               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2470             }
2471         }
2472     }
2473 }
2474
2475 /*!
2476  * Assign a given value to values at specified tuples and components of \a this array.
2477  * The tuples to assign to are defined by a C array of indices.
2478  * The components to assign to are defined by three values similar to parameters of
2479  * the Python function \c range(\c start,\c stop,\c step).
2480  *  \param [in] a - the value to assign.
2481  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2482  *              assign \a a to.
2483  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2484  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2485  *              \a bgTuples <= \a pi < \a endTuples.
2486  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2487  *  \param [in] endComp - index of the component before which the components to assign
2488  *              to are located.
2489  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2490  *  \throw If \a this is not allocated.
2491  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2492  *         \a this array.
2493  *  \throw If parameters specifying components to assign to, do not give a
2494  *            non-empty range of increasing indices or indices are out of a valid range
2495  *            for \this array.
2496  *
2497  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2498  */
2499 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
2500 {
2501   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2502   checkAllocated();
2503   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2504   int nbComp=getNumberOfComponents();
2505   int nbOfTuples=getNumberOfTuples();
2506   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2507   double *pt=getPointer()+bgComp;
2508   for(const int *w=bgTuples;w!=endTuples;w++)
2509     for(int j=0;j<newNbOfComp;j++)
2510       {
2511         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2512         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2513       }
2514 }
2515
2516 /*!
2517  * Copy all values from another DataArrayDouble into specified tuples and components
2518  * of \a this array. Textual data is not copied.
2519  * The tree parameters defining set of indices of tuples and components are similar to
2520  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2521  *  \param [in] a - the array to copy values from.
2522  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2523  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2524  *              are located.
2525  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2526  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2527  *              assign \a a to.
2528  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2529  *              pointer to a component index (\a pi) varies as this: 
2530  *              \a bgComp <= \a pi < \a endComp.
2531  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2532  *              must be equal to the number of columns to assign to, else an
2533  *              exception is thrown; if \a false, then it is only required that \a
2534  *              a->getNbOfElems() equals to number of values to assign to (this condition
2535  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2536  *              values to assign to is given by following Python expression:
2537  *              \a nbTargetValues = 
2538  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2539  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2540  *  \throw If \a a is NULL.
2541  *  \throw If \a a is not allocated.
2542  *  \throw If \a this is not allocated.
2543  *  \throw If parameters specifying tuples and components to assign to do not give a
2544  *            non-empty range of increasing indices.
2545  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2546  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2547  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2548  *
2549  */
2550 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
2551 {
2552   if(!a)
2553     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2554   const char msg[]="DataArrayDouble::setPartOfValues4";
2555   checkAllocated();
2556   a->checkAllocated();
2557   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2558   int newNbOfComp=(int)std::distance(bgComp,endComp);
2559   int nbComp=getNumberOfComponents();
2560   for(const int *z=bgComp;z!=endComp;z++)
2561     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2562   int nbOfTuples=getNumberOfTuples();
2563   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2564   bool assignTech=true;
2565   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2566     {
2567       if(strictCompoCompare)
2568         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2569     }
2570   else
2571     {
2572       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2573       assignTech=false;
2574     }
2575   const double *srcPt=a->getConstPointer();
2576   double *pt=getPointer()+bgTuples*nbComp;
2577   if(assignTech)
2578     {
2579       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2580         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2581           pt[*z]=*srcPt;
2582     }
2583   else
2584     {
2585       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2586         {
2587           const double *srcPt2=srcPt;
2588           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2589             pt[*z]=*srcPt2;
2590         }
2591     }
2592 }
2593
2594 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
2595 {
2596   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2597   checkAllocated();
2598   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2599   int nbComp=getNumberOfComponents();
2600   for(const int *z=bgComp;z!=endComp;z++)
2601     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2602   int nbOfTuples=getNumberOfTuples();
2603   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2604   double *pt=getPointer()+bgTuples*nbComp;
2605   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2606     for(const int *z=bgComp;z!=endComp;z++)
2607       pt[*z]=a;
2608 }
2609
2610 /*!
2611  * Copy some tuples from another DataArrayDouble into specified tuples
2612  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2613  * components.
2614  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2615  * All components of selected tuples are copied.
2616  *  \param [in] a - the array to copy values from.
2617  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2618  *              target tuples of \a this. \a tuplesSelec has two components, and the
2619  *              first component specifies index of the source tuple and the second
2620  *              one specifies index of the target tuple.
2621  *  \throw If \a this is not allocated.
2622  *  \throw If \a a is NULL.
2623  *  \throw If \a a is not allocated.
2624  *  \throw If \a tuplesSelec is NULL.
2625  *  \throw If \a tuplesSelec is not allocated.
2626  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2627  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2628  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2629  *         the corresponding (\a this or \a a) array.
2630  */
2631 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2632 {
2633   if(!a || !tuplesSelec)
2634     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2635   checkAllocated();
2636   a->checkAllocated();
2637   tuplesSelec->checkAllocated();
2638   int nbOfComp=getNumberOfComponents();
2639   if(nbOfComp!=a->getNumberOfComponents())
2640     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2641   if(tuplesSelec->getNumberOfComponents()!=2)
2642     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2643   int thisNt=getNumberOfTuples();
2644   int aNt=a->getNumberOfTuples();
2645   double *valsToSet=getPointer();
2646   const double *valsSrc=a->getConstPointer();
2647   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2648     {
2649       if(tuple[1]>=0 && tuple[1]<aNt)
2650         {
2651           if(tuple[0]>=0 && tuple[0]<thisNt)
2652             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2653           else
2654             {
2655               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2656               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2657               throw INTERP_KERNEL::Exception(oss.str().c_str());
2658             }
2659         }
2660       else
2661         {
2662           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2663           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2664           throw INTERP_KERNEL::Exception(oss.str().c_str());
2665         }
2666     }
2667 }
2668
2669 /*!
2670  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2671  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2672  * components.
2673  * The tuples to assign to are defined by index of the first tuple, and
2674  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2675  * The tuples to copy are defined by values of a DataArrayInt.
2676  * All components of selected tuples are copied.
2677  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2678  *              values to.
2679  *  \param [in] aBase - the array to copy values from.
2680  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2681  *  \throw If \a this is not allocated.
2682  *  \throw If \a aBase is NULL.
2683  *  \throw If \a aBase is not allocated.
2684  *  \throw If \a tuplesSelec is NULL.
2685  *  \throw If \a tuplesSelec is not allocated.
2686  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2687  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2688  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2689  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2690  *         \a aBase array.
2691  */
2692 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
2693 {
2694   if(!aBase || !tuplesSelec)
2695     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2696   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2697   if(!a)
2698     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2699   checkAllocated();
2700   a->checkAllocated();
2701   tuplesSelec->checkAllocated();
2702   int nbOfComp=getNumberOfComponents();
2703   if(nbOfComp!=a->getNumberOfComponents())
2704     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2705   if(tuplesSelec->getNumberOfComponents()!=1)
2706     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2707   int thisNt=getNumberOfTuples();
2708   int aNt=a->getNumberOfTuples();
2709   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2710   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2711   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2712     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2713   const double *valsSrc=a->getConstPointer();
2714   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2715     {
2716       if(*tuple>=0 && *tuple<aNt)
2717         {
2718           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2719         }
2720       else
2721         {
2722           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2723           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2724           throw INTERP_KERNEL::Exception(oss.str().c_str());
2725         }
2726     }
2727 }
2728
2729 /*!
2730  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2731  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2732  * components.
2733  * The tuples to copy are defined by three values similar to parameters of
2734  * the Python function \c range(\c start,\c stop,\c step).
2735  * The tuples to assign to are defined by index of the first tuple, and
2736  * their number is defined by number of tuples to copy.
2737  * All components of selected tuples are copied.
2738  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2739  *              values to.
2740  *  \param [in] aBase - the array to copy values from.
2741  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2742  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2743  *              are located.
2744  *  \param [in] step - index increment to get index of the next tuple to copy.
2745  *  \throw If \a this is not allocated.
2746  *  \throw If \a aBase is NULL.
2747  *  \throw If \a aBase is not allocated.
2748  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2749  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2750  *  \throw If parameters specifying tuples to copy, do not give a
2751  *            non-empty range of increasing indices or indices are out of a valid range
2752  *            for the array \a aBase.
2753  */
2754 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
2755 {
2756   if(!aBase)
2757     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2758   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2759   if(!a)
2760     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2761   checkAllocated();
2762   a->checkAllocated();
2763   int nbOfComp=getNumberOfComponents();
2764   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2765   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2766   if(nbOfComp!=a->getNumberOfComponents())
2767     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2768   int thisNt=getNumberOfTuples();
2769   int aNt=a->getNumberOfTuples();
2770   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2771   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2772     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2773   if(end2>aNt)
2774     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2775   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2776   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2777     {
2778       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2779     }
2780 }
2781
2782 /*!
2783  * Returns a value located at specified tuple and component.
2784  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2785  * parameters is checked. So this method is safe but expensive if used to go through
2786  * all values of \a this.
2787  *  \param [in] tupleId - index of tuple of interest.
2788  *  \param [in] compoId - index of component of interest.
2789  *  \return double - value located by \a tupleId and \a compoId.
2790  *  \throw If \a this is not allocated.
2791  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2792  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2793  */
2794 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
2795 {
2796   checkAllocated();
2797   if(tupleId<0 || tupleId>=getNumberOfTuples())
2798     {
2799       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2800       throw INTERP_KERNEL::Exception(oss.str().c_str());
2801     }
2802   if(compoId<0 || compoId>=getNumberOfComponents())
2803     {
2804       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2805       throw INTERP_KERNEL::Exception(oss.str().c_str());
2806     }
2807   return _mem[tupleId*_info_on_compo.size()+compoId];
2808 }
2809
2810 /*!
2811  * Returns the first value of \a this. 
2812  *  \return double - the last value of \a this array.
2813  *  \throw If \a this is not allocated.
2814  *  \throw If \a this->getNumberOfComponents() != 1.
2815  *  \throw If \a this->getNumberOfTuples() < 1.
2816  */
2817 double DataArrayDouble::front() const throw(INTERP_KERNEL::Exception)
2818 {
2819   checkAllocated();
2820   if(getNumberOfComponents()!=1)
2821     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2822   int nbOfTuples=getNumberOfTuples();
2823   if(nbOfTuples<1)
2824     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2825   return *(getConstPointer());
2826 }
2827
2828 /*!
2829  * Returns the last value of \a this. 
2830  *  \return double - the last value of \a this array.
2831  *  \throw If \a this is not allocated.
2832  *  \throw If \a this->getNumberOfComponents() != 1.
2833  *  \throw If \a this->getNumberOfTuples() < 1.
2834  */
2835 double DataArrayDouble::back() const throw(INTERP_KERNEL::Exception)
2836 {
2837   checkAllocated();
2838   if(getNumberOfComponents()!=1)
2839     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2840   int nbOfTuples=getNumberOfTuples();
2841   if(nbOfTuples<1)
2842     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2843   return *(getConstPointer()+nbOfTuples-1);
2844 }
2845
2846 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2847 {
2848   if(newArray!=arrayToSet)
2849     {
2850       if(arrayToSet)
2851         arrayToSet->decrRef();
2852       arrayToSet=newArray;
2853       if(arrayToSet)
2854         arrayToSet->incrRef();
2855     }
2856 }
2857
2858 /*!
2859  * Sets a C array to be used as raw data of \a this. The previously set info
2860  *  of components is retained and re-sized. 
2861  * For more info see \ref MEDCouplingArraySteps1.
2862  *  \param [in] array - the C array to be used as raw data of \a this.
2863  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2864  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2865  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2866  *                     \c free(\c array ) will be called.
2867  *  \param [in] nbOfTuple - new number of tuples in \a this.
2868  *  \param [in] nbOfCompo - new number of components in \a this.
2869  */
2870 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2871 {
2872   _info_on_compo.resize(nbOfCompo);
2873   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2874   declareAsNew();
2875 }
2876
2877 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
2878 {
2879   _info_on_compo.resize(nbOfCompo);
2880   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
2881   declareAsNew();
2882 }
2883
2884 /*!
2885  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
2886  * is thrown.
2887  * \throw If zero is found in \a this array.
2888  */
2889 void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception)
2890 {
2891   const double *tmp=getConstPointer();
2892   std::size_t nbOfElems=getNbOfElems();
2893   const double *where=std::find(tmp,tmp+nbOfElems,0.);
2894   if(where!=tmp+nbOfElems)
2895     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
2896 }
2897
2898 /*!
2899  * Computes minimal and maximal value in each component. An output array is filled
2900  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
2901  * enough memory before calling this method.
2902  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
2903  *               It is filled as follows:<br>
2904  *               \a bounds[0] = \c min_of_component_0 <br>
2905  *               \a bounds[1] = \c max_of_component_0 <br>
2906  *               \a bounds[2] = \c min_of_component_1 <br>
2907  *               \a bounds[3] = \c max_of_component_1 <br>
2908  *               ...
2909  */
2910 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const throw(INTERP_KERNEL::Exception)
2911 {
2912   checkAllocated();
2913   int dim=getNumberOfComponents();
2914   for (int idim=0; idim<dim; idim++)
2915     {
2916       bounds[idim*2]=std::numeric_limits<double>::max();
2917       bounds[idim*2+1]=-std::numeric_limits<double>::max();
2918     } 
2919   const double *ptr=getConstPointer();
2920   int nbOfTuples=getNumberOfTuples();
2921   for(int i=0;i<nbOfTuples;i++)
2922     {
2923       for(int idim=0;idim<dim;idim++)
2924         {
2925           if(bounds[idim*2]>ptr[i*dim+idim])
2926             {
2927               bounds[idim*2]=ptr[i*dim+idim];
2928             }
2929           if(bounds[idim*2+1]<ptr[i*dim+idim])
2930             {
2931               bounds[idim*2+1]=ptr[i*dim+idim];
2932             }
2933         }
2934     }
2935 }
2936
2937 /*!
2938  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
2939  * to store both the min and max per component of each tuples. 
2940  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
2941  *
2942  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
2943  *
2944  * \throw If \a this is not allocated yet.
2945  */
2946 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw(INTERP_KERNEL::Exception)
2947 {
2948   checkAllocated();
2949   const double *dataPtr=getConstPointer();
2950   int nbOfCompo=getNumberOfComponents();
2951   int nbTuples=getNumberOfTuples();
2952   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
2953   bbox->alloc(nbTuples,2*nbOfCompo);
2954   double *bboxPtr=bbox->getPointer();
2955   for(int i=0;i<nbTuples;i++)
2956     {
2957       for(int j=0;j<nbOfCompo;j++)
2958         {
2959           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
2960           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
2961         }
2962     }
2963   return bbox.retn();
2964 }
2965
2966 /*!
2967  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
2968  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
2969  * 
2970  * \param [in] other a DataArrayDouble having same number of components than \a this.
2971  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
2972  * \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.
2973  *             \a cI allows to extract information in \a c.
2974  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
2975  *
2976  * \throw In case of:
2977  *  - \a this is not allocated
2978  *  - \a other is not allocated or null
2979  *  - \a this and \a other do not have the same number of components
2980  *  - if number of components of \a this is not in [1,2,3]
2981  *
2982  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
2983  */
2984 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception)
2985 {
2986   if(!other)
2987     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
2988   checkAllocated();
2989   other->checkAllocated();
2990   int nbOfCompo=getNumberOfComponents();
2991   int otherNbOfCompo=other->getNumberOfComponents();
2992   if(nbOfCompo!=otherNbOfCompo)
2993     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
2994   int nbOfTuplesOther=other->getNumberOfTuples();
2995   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
2996   switch(nbOfCompo)
2997     {
2998     case 3:
2999       {
3000         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3001         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3002         break;
3003       }
3004     case 2:
3005       {
3006         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3007         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3008         break;
3009       }
3010     case 1:
3011       {
3012         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3013         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3014         break;
3015       }
3016     default:
3017       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3018     }
3019   c=cArr.retn(); cI=cIArr.retn();
3020 }
3021
3022 /*!
3023  * 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
3024  * around origin of 'radius' 1.
3025  * 
3026  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3027  */
3028 void DataArrayDouble::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception)
3029 {
3030   checkAllocated();
3031   int dim=getNumberOfComponents();
3032   std::vector<double> bounds(2*dim);
3033   getMinMaxPerComponent(&bounds[0]);
3034   for(int i=0;i<dim;i++)
3035     {
3036       double delta=bounds[2*i+1]-bounds[2*i];
3037       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3038       if(delta>eps)
3039         applyLin(1./delta,-offset/delta,i);
3040       else
3041         applyLin(1.,-offset,i);
3042     }
3043 }
3044
3045 /*!
3046  * Returns the maximal value and its location within \a this one-dimensional array.
3047  *  \param [out] tupleId - index of the tuple holding the maximal value.
3048  *  \return double - the maximal value among all values of \a this array.
3049  *  \throw If \a this->getNumberOfComponents() != 1
3050  *  \throw If \a this->getNumberOfTuples() < 1
3051  */
3052 double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
3053 {
3054   checkAllocated();
3055   if(getNumberOfComponents()!=1)
3056     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 !");
3057   int nbOfTuples=getNumberOfTuples();
3058   if(nbOfTuples<=0)
3059     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3060   const double *vals=getConstPointer();
3061   const double *loc=std::max_element(vals,vals+nbOfTuples);
3062   tupleId=(int)std::distance(vals,loc);
3063   return *loc;
3064 }
3065
3066 /*!
3067  * Returns the maximal value within \a this array that is allowed to have more than
3068  *  one component.
3069  *  \return double - the maximal value among all values of \a this array.
3070  *  \throw If \a this is not allocated.
3071  */
3072 double DataArrayDouble::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
3073 {
3074   checkAllocated();
3075   const double *loc=std::max_element(begin(),end());
3076   return *loc;
3077 }
3078
3079 /*!
3080  * Returns the maximal value and all its locations within \a this one-dimensional array.
3081  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3082  *               tuples holding the maximal value. The caller is to delete it using
3083  *               decrRef() as it is no more needed.
3084  *  \return double - the maximal value among all values of \a this array.
3085  *  \throw If \a this->getNumberOfComponents() != 1
3086  *  \throw If \a this->getNumberOfTuples() < 1
3087  */
3088 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
3089 {
3090   int tmp;
3091   tupleIds=0;
3092   double ret=getMaxValue(tmp);
3093   tupleIds=getIdsInRange(ret,ret);
3094   return ret;
3095 }
3096
3097 /*!
3098  * Returns the minimal value and its location within \a this one-dimensional array.
3099  *  \param [out] tupleId - index of the tuple holding the minimal value.
3100  *  \return double - the minimal value among all values of \a this array.
3101  *  \throw If \a this->getNumberOfComponents() != 1
3102  *  \throw If \a this->getNumberOfTuples() < 1
3103  */
3104 double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
3105 {
3106   checkAllocated();
3107   if(getNumberOfComponents()!=1)
3108     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3109   int nbOfTuples=getNumberOfTuples();
3110   if(nbOfTuples<=0)
3111     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3112   const double *vals=getConstPointer();
3113   const double *loc=std::min_element(vals,vals+nbOfTuples);
3114   tupleId=(int)std::distance(vals,loc);
3115   return *loc;
3116 }
3117
3118 /*!
3119  * Returns the minimal value within \a this array that is allowed to have more than
3120  *  one component.
3121  *  \return double - the minimal value among all values of \a this array.
3122  *  \throw If \a this is not allocated.
3123  */
3124 double DataArrayDouble::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
3125 {
3126   checkAllocated();
3127   const double *loc=std::min_element(begin(),end());
3128   return *loc;
3129 }
3130
3131 /*!
3132  * Returns the minimal value and all its locations within \a this one-dimensional array.
3133  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3134  *               tuples holding the minimal value. The caller is to delete it using
3135  *               decrRef() as it is no more needed.
3136  *  \return double - the minimal value among all values of \a this array.
3137  *  \throw If \a this->getNumberOfComponents() != 1
3138  *  \throw If \a this->getNumberOfTuples() < 1
3139  */
3140 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception)
3141 {
3142   int tmp;
3143   tupleIds=0;
3144   double ret=getMinValue(tmp);
3145   tupleIds=getIdsInRange(ret,ret);
3146   return ret;
3147 }
3148
3149 /*!
3150  * 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.
3151  * This method only works for single component array.
3152  *
3153  * \return a value in [ 0, \c this->getNumberOfTuples() )
3154  *
3155  * \throw If \a this is not allocated
3156  *
3157  */
3158 int DataArrayDouble::count(double value, double eps) const throw(INTERP_KERNEL::Exception)
3159 {
3160   int ret=0;
3161   checkAllocated();
3162   if(getNumberOfComponents()!=1)
3163     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3164   const double *vals=begin();
3165   int nbOfTuples=getNumberOfTuples();
3166   for(int i=0;i<nbOfTuples;i++,vals++)
3167     if(fabs(*vals-value)<=eps)
3168       ret++;
3169   return ret;
3170 }
3171
3172 /*!
3173  * Returns the average value of \a this one-dimensional array.
3174  *  \return double - the average value over all values of \a this array.
3175  *  \throw If \a this->getNumberOfComponents() != 1
3176  *  \throw If \a this->getNumberOfTuples() < 1
3177  */
3178 double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception)
3179 {
3180   if(getNumberOfComponents()!=1)
3181     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3182   int nbOfTuples=getNumberOfTuples();
3183   if(nbOfTuples<=0)
3184     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3185   const double *vals=getConstPointer();
3186   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3187   return ret/nbOfTuples;
3188 }
3189
3190 /*!
3191  * Returns the Euclidean norm of the vector defined by \a this array.
3192  *  \return double - the value of the Euclidean norm, i.e.
3193  *          the square root of the inner product of vector.
3194  *  \throw If \a this is not allocated.
3195  */
3196 double DataArrayDouble::norm2() const throw(INTERP_KERNEL::Exception)
3197 {
3198   checkAllocated();
3199   double ret=0.;
3200   std::size_t nbOfElems=getNbOfElems();
3201   const double *pt=getConstPointer();
3202   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3203     ret+=(*pt)*(*pt);
3204   return sqrt(ret);
3205 }
3206
3207 /*!
3208  * Returns the maximum norm of the vector defined by \a this array.
3209  *  \return double - the value of the maximum norm, i.e.
3210  *          the maximal absolute value among values of \a this array.
3211  *  \throw If \a this is not allocated.
3212  */
3213 double DataArrayDouble::normMax() const throw(INTERP_KERNEL::Exception)
3214 {
3215   checkAllocated();
3216   double ret=-1.;
3217   std::size_t nbOfElems=getNbOfElems();
3218   const double *pt=getConstPointer();
3219   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3220     {
3221       double val=std::abs(*pt);
3222       if(val>ret)
3223         ret=val;
3224     }
3225   return ret;
3226 }
3227
3228 /*!
3229  * Accumulates values of each component of \a this array.
3230  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3231  *         by the caller, that is filled by this method with sum value for each
3232  *         component.
3233  *  \throw If \a this is not allocated.
3234  */
3235 void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Exception)
3236 {
3237   checkAllocated();
3238   const double *ptr=getConstPointer();
3239   int nbTuple=getNumberOfTuples();
3240   int nbComps=getNumberOfComponents();
3241   std::fill(res,res+nbComps,0.);
3242   for(int i=0;i<nbTuple;i++)
3243     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3244 }
3245
3246 /*!
3247  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3248  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3249  *
3250  *
3251  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3252  * \a tupleEnd. If not an exception will be thrown.
3253  *
3254  * \param [in] tupleBg start pointer (included) of input external tuple
3255  * \param [in] tupleEnd end pointer (not included) of input external tuple
3256  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3257  * \return the min distance.
3258  * \sa MEDCouplingUMesh::distanceToPoint
3259  */
3260 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception)
3261 {
3262   checkAllocated();
3263   int nbTuple=getNumberOfTuples();
3264   int nbComps=getNumberOfComponents();
3265   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3266     { 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()); }
3267   if(nbTuple==0)
3268     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3269   double ret0=std::numeric_limits<double>::max();
3270   tupleId=-1;
3271   const double *work=getConstPointer();
3272   for(int i=0;i<nbTuple;i++)
3273     {
3274       double val=0.;
3275       for(int j=0;j<nbComps;j++,work++) 
3276         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3277       if(val>=ret0)
3278         continue;
3279       else
3280         { ret0=val; tupleId=i; }
3281     }
3282   return sqrt(ret0);
3283 }
3284
3285 /*!
3286  * Accumulate values of the given component of \a this array.
3287  *  \param [in] compId - the index of the component of interest.
3288  *  \return double - a sum value of \a compId-th component.
3289  *  \throw If \a this is not allocated.
3290  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3291  *         not respected.
3292  */
3293 double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
3294 {
3295   checkAllocated();
3296   const double *ptr=getConstPointer();
3297   int nbTuple=getNumberOfTuples();
3298   int nbComps=getNumberOfComponents();
3299   if(compId<0 || compId>=nbComps)
3300     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3301   double ret=0.;
3302   for(int i=0;i<nbTuple;i++)
3303     ret+=ptr[i*nbComps+compId];
3304   return ret;
3305 }
3306
3307 /*!
3308  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3309  * The returned array will have same number of components than \a this and number of tuples equal to
3310  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3311  *
3312  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3313  * 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.
3314  *
3315  * \param [in] bgOfIndex - begin (included) of the input index array.
3316  * \param [in] endOfIndex - end (excluded) of the input index array.
3317  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3318  * 
3319  * \throw If bgOfIndex or end is NULL.
3320  * \throw If input index array is not ascendingly sorted.
3321  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3322  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3323  */
3324 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
3325 {
3326   if(!bgOfIndex || !endOfIndex)
3327     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3328   checkAllocated();
3329   int nbCompo=getNumberOfComponents();
3330   int nbOfTuples=getNumberOfTuples();
3331   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3332   if(sz<1)
3333     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3334   sz--;
3335   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3336   const int *w=bgOfIndex;
3337   if(*w<0 || *w>=nbOfTuples)
3338     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3339   const double *srcPt=begin()+(*w)*nbCompo;
3340   double *tmp=ret->getPointer();
3341   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3342     {
3343       std::fill(tmp,tmp+nbCompo,0.);
3344       if(w[1]>=w[0])
3345         {
3346           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3347             {
3348               if(j>=0 && j<nbOfTuples)
3349                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3350               else
3351                 {
3352                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3353                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3354                 }
3355             }
3356         }
3357       else
3358         {
3359           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3360           throw INTERP_KERNEL::Exception(oss.str().c_str());
3361         }
3362     }
3363   ret->copyStringInfoFrom(*this);
3364   return ret.retn();
3365 }
3366
3367 /*!
3368  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3369  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3370  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3371  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3372  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3373  *          is to delete this array using decrRef() as it is no more needed. The array
3374  *          does not contain any textual info on components.
3375  *  \throw If \a this->getNumberOfComponents() != 2.
3376  */
3377 DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::Exception)
3378 {
3379   checkAllocated();
3380   int nbOfComp=getNumberOfComponents();
3381   if(nbOfComp!=2)
3382     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3383   int nbOfTuple=getNumberOfTuples();
3384   DataArrayDouble *ret=DataArrayDouble::New();
3385   ret->alloc(nbOfTuple,2);
3386   double *w=ret->getPointer();
3387   const double *wIn=getConstPointer();
3388   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3389     {
3390       w[0]=wIn[0]*cos(wIn[1]);
3391       w[1]=wIn[0]*sin(wIn[1]);
3392     }
3393   return ret;
3394 }
3395
3396 /*!
3397  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3398  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3399  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3400  * the Cylindrical CS.
3401  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3402  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3403  *          on the third component is copied from \a this array. The caller
3404  *          is to delete this array using decrRef() as it is no more needed. 
3405  *  \throw If \a this->getNumberOfComponents() != 3.
3406  */
3407 DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exception)
3408 {
3409   checkAllocated();
3410   int nbOfComp=getNumberOfComponents();
3411   if(nbOfComp!=3)
3412     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3413   int nbOfTuple=getNumberOfTuples();
3414   DataArrayDouble *ret=DataArrayDouble::New();
3415   ret->alloc(getNumberOfTuples(),3);
3416   double *w=ret->getPointer();
3417   const double *wIn=getConstPointer();
3418   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3419     {
3420       w[0]=wIn[0]*cos(wIn[1]);
3421       w[1]=wIn[0]*sin(wIn[1]);
3422       w[2]=wIn[2];
3423     }
3424   ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
3425   return ret;
3426 }
3427
3428 /*!
3429  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3430  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3431  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3432  * point in the Cylindrical CS.
3433  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3434  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3435  *          on the third component is copied from \a this array. The caller
3436  *          is to delete this array using decrRef() as it is no more needed.
3437  *  \throw If \a this->getNumberOfComponents() != 3.
3438  */
3439 DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::Exception)
3440 {
3441   checkAllocated();
3442   int nbOfComp=getNumberOfComponents();
3443   if(nbOfComp!=3)
3444     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3445   int nbOfTuple=getNumberOfTuples();
3446   DataArrayDouble *ret=DataArrayDouble::New();
3447   ret->alloc(getNumberOfTuples(),3);
3448   double *w=ret->getPointer();
3449   const double *wIn=getConstPointer();
3450   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3451     {
3452       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3453       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3454       w[2]=wIn[0]*cos(wIn[1]);
3455     }
3456   return ret;
3457 }
3458
3459 /*!
3460  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3461  * array contating 6 components.
3462  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3463  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3464  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3465  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3466  *  \throw If \a this->getNumberOfComponents() != 6.
3467  */
3468 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
3469 {
3470   checkAllocated();
3471   int nbOfComp=getNumberOfComponents();
3472   if(nbOfComp!=6)
3473     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3474   DataArrayDouble *ret=DataArrayDouble::New();
3475   int nbOfTuple=getNumberOfTuples();
3476   ret->alloc(nbOfTuple,1);
3477   const double *src=getConstPointer();
3478   double *dest=ret->getPointer();
3479   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3480     *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];
3481   return ret;
3482 }
3483
3484 /*!
3485  * Computes the determinant of every square matrix defined by the tuple of \a this
3486  * array, which contains either 4, 6 or 9 components. The case of 6 components
3487  * corresponds to that of the upper triangular matrix.
3488  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3489  *          is the determinant of matrix of the corresponding tuple of \a this array.
3490  *          The caller is to delete this result array using decrRef() as it is no more
3491  *          needed. 
3492  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3493  */
3494 DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Exception)
3495 {
3496   checkAllocated();
3497   DataArrayDouble *ret=DataArrayDouble::New();
3498   int nbOfTuple=getNumberOfTuples();
3499   ret->alloc(nbOfTuple,1);
3500   const double *src=getConstPointer();
3501   double *dest=ret->getPointer();
3502   switch(getNumberOfComponents())
3503     {
3504     case 6:
3505       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3506         *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];
3507       return ret;
3508     case 4:
3509       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3510         *dest=src[0]*src[3]-src[1]*src[2];
3511       return ret;
3512     case 9:
3513       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3514         *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];
3515       return ret;
3516     default:
3517       ret->decrRef();
3518       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3519     }
3520 }
3521
3522 /*!
3523  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3524  * \a this array, which contains 6 components.
3525  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3526  *          components, whose each tuple contains the eigenvalues of the matrix of
3527  *          corresponding tuple of \a this array. 
3528  *          The caller is to delete this result array using decrRef() as it is no more
3529  *          needed. 
3530  *  \throw If \a this->getNumberOfComponents() != 6.
3531  */
3532 DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
3533 {
3534   checkAllocated();
3535   int nbOfComp=getNumberOfComponents();
3536   if(nbOfComp!=6)
3537     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3538   DataArrayDouble *ret=DataArrayDouble::New();
3539   int nbOfTuple=getNumberOfTuples();
3540   ret->alloc(nbOfTuple,3);
3541   const double *src=getConstPointer();
3542   double *dest=ret->getPointer();
3543   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3544     INTERP_KERNEL::computeEigenValues6(src,dest);
3545   return ret;
3546 }
3547
3548 /*!
3549  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3550  * \a this array, which contains 6 components.
3551  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3552  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3553  *          corresponding tuple of \a this array.
3554  *          The caller is to delete this result array using decrRef() as it is no more
3555  *          needed.
3556  *  \throw If \a this->getNumberOfComponents() != 6.
3557  */
3558 DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
3559 {
3560   checkAllocated();
3561   int nbOfComp=getNumberOfComponents();
3562   if(nbOfComp!=6)
3563     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3564   DataArrayDouble *ret=DataArrayDouble::New();
3565   int nbOfTuple=getNumberOfTuples();
3566   ret->alloc(nbOfTuple,9);
3567   const double *src=getConstPointer();
3568   double *dest=ret->getPointer();
3569   for(int i=0;i<nbOfTuple;i++,src+=6)
3570     {
3571       double tmp[3];
3572       INTERP_KERNEL::computeEigenValues6(src,tmp);
3573       for(int j=0;j<3;j++,dest+=3)
3574         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3575     }
3576   return ret;
3577 }
3578
3579 /*!
3580  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3581  * array, which contains either 4, 6 or 9 components. The case of 6 components
3582  * corresponds to that of the upper triangular matrix.
3583  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3584  *          same number of components as \a this one, whose each tuple is the inverse
3585  *          matrix of the matrix of corresponding tuple of \a this array. 
3586  *          The caller is to delete this result array using decrRef() as it is no more
3587  *          needed. 
3588  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3589  */
3590 DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception)
3591 {
3592   checkAllocated();
3593   int nbOfComp=getNumberOfComponents();
3594   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3595     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3596   DataArrayDouble *ret=DataArrayDouble::New();
3597   int nbOfTuple=getNumberOfTuples();
3598   ret->alloc(nbOfTuple,nbOfComp);
3599   const double *src=getConstPointer();
3600   double *dest=ret->getPointer();
3601 if(nbOfComp==6)
3602     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3603       {
3604         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];
3605         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3606         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3607         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3608         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3609         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3610         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3611       }
3612   else if(nbOfComp==4)
3613     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3614       {
3615         double det=src[0]*src[3]-src[1]*src[2];
3616         dest[0]=src[3]/det;
3617         dest[1]=-src[1]/det;
3618         dest[2]=-src[2]/det;
3619         dest[3]=src[0]/det;
3620       }
3621   else
3622     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3623       {
3624         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];
3625         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3626         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3627         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3628         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3629         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3630         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3631         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3632         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3633         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3634       }
3635   return ret;
3636 }
3637
3638 /*!
3639  * Computes the trace of every matrix defined by the tuple of \a this
3640  * array, which contains either 4, 6 or 9 components. The case of 6 components
3641  * corresponds to that of the upper triangular matrix.
3642  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3643  *          1 component, whose each tuple is the trace of
3644  *          the matrix of corresponding tuple of \a this array. 
3645  *          The caller is to delete this result array using decrRef() as it is no more
3646  *          needed. 
3647  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3648  */
3649 DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception)
3650 {
3651   checkAllocated();
3652   int nbOfComp=getNumberOfComponents();
3653   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3654     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3655   DataArrayDouble *ret=DataArrayDouble::New();
3656   int nbOfTuple=getNumberOfTuples();
3657   ret->alloc(nbOfTuple,1);
3658   const double *src=getConstPointer();
3659   double *dest=ret->getPointer();
3660   if(nbOfComp==6)
3661     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3662       *dest=src[0]+src[1]+src[2];
3663   else if(nbOfComp==4)
3664     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3665       *dest=src[0]+src[3];
3666   else
3667     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3668       *dest=src[0]+src[4]+src[8];
3669   return ret;
3670 }
3671
3672 /*!
3673  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3674  * \a this array, which contains 6 components.
3675  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3676  *          same number of components and tuples as \a this array.
3677  *          The caller is to delete this result array using decrRef() as it is no more
3678  *          needed.
3679  *  \throw If \a this->getNumberOfComponents() != 6.
3680  */
3681 DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception)
3682 {
3683   checkAllocated();
3684   int nbOfComp=getNumberOfComponents();
3685   if(nbOfComp!=6)
3686     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3687   DataArrayDouble *ret=DataArrayDouble::New();
3688   int nbOfTuple=getNumberOfTuples();
3689   ret->alloc(nbOfTuple,6);
3690   const double *src=getConstPointer();
3691   double *dest=ret->getPointer();
3692   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3693     {
3694       double tr=(src[0]+src[1]+src[2])/3.;
3695       dest[0]=src[0]-tr;
3696       dest[1]=src[1]-tr;
3697       dest[2]=src[2]-tr;
3698       dest[3]=src[3];
3699       dest[4]=src[4];
3700       dest[5]=src[5];
3701     }
3702   return ret;
3703 }
3704
3705 /*!
3706  * Computes the magnitude of every vector defined by the tuple of
3707  * \a this array.
3708  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3709  *          same number of tuples as \a this array and one component.
3710  *          The caller is to delete this result array using decrRef() as it is no more
3711  *          needed.
3712  *  \throw If \a this is not allocated.
3713  */
3714 DataArrayDouble *DataArrayDouble::magnitude() const throw(INTERP_KERNEL::Exception)
3715 {
3716   checkAllocated();
3717   int nbOfComp=getNumberOfComponents();
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   for(int i=0;i<nbOfTuple;i++,dest++)
3724     {
3725       double sum=0.;
3726       for(int j=0;j<nbOfComp;j++,src++)
3727         sum+=(*src)*(*src);
3728       *dest=sqrt(sum);
3729     }
3730   return ret;
3731 }
3732
3733 /*!
3734  * Computes the maximal value within every tuple of \a this array.
3735  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3736  *          same number of tuples as \a this array and one component.
3737  *          The caller is to delete this result array using decrRef() as it is no more
3738  *          needed.
3739  *  \throw If \a this is not allocated.
3740  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3741  */
3742 DataArrayDouble *DataArrayDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception)
3743 {
3744   checkAllocated();
3745   int nbOfComp=getNumberOfComponents();
3746   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3747   int nbOfTuple=getNumberOfTuples();
3748   ret->alloc(nbOfTuple,1);
3749   const double *src=getConstPointer();
3750   double *dest=ret->getPointer();
3751   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3752     *dest=*std::max_element(src,src+nbOfComp);
3753   return ret.retn();
3754 }
3755
3756 /*!
3757  * Computes the maximal value within every tuple of \a this array and it returns the first component
3758  * id for each tuple that corresponds to the maximal value within the tuple.
3759  * 
3760  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3761  *          same number of tuples and only one component.
3762  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3763  *          same number of tuples as \a this array and one component.
3764  *          The caller is to delete this result array using decrRef() as it is no more
3765  *          needed.
3766  *  \throw If \a this is not allocated.
3767  *  \sa DataArrayDouble::maxPerTuple
3768  */
3769 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const throw(INTERP_KERNEL::Exception)
3770 {
3771   checkAllocated();
3772   int nbOfComp=getNumberOfComponents();
3773   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3774   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3775   int nbOfTuple=getNumberOfTuples();
3776   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3777   const double *src=getConstPointer();
3778   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3779   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3780     {
3781       const double *loc=std::max_element(src,src+nbOfComp);
3782       *dest=*loc;
3783       *dest1=(int)std::distance(src,loc);
3784     }
3785   compoIdOfMaxPerTuple=ret1.retn();
3786   return ret0.retn();
3787 }
3788
3789 /*!
3790  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3791  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3792  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3793  * \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)
3794  *
3795  * \warning use this method with care because it can leads to big amount of consumed memory !
3796  * 
3797  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3798  *
3799  * \throw If \a this is not allocated.
3800  *
3801  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3802  */
3803 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception)
3804 {
3805   checkAllocated();
3806   int nbOfComp=getNumberOfComponents();
3807   int nbOfTuples=getNumberOfTuples();
3808   const double *inData=getConstPointer();
3809   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3810   ret->alloc(nbOfTuples*nbOfTuples,1);
3811   double *outData=ret->getPointer();
3812   for(int i=0;i<nbOfTuples;i++)
3813     {
3814       outData[i*nbOfTuples+i]=0.;
3815       for(int j=i+1;j<nbOfTuples;j++)
3816         {
3817           double dist=0.;
3818           for(int k=0;k<nbOfComp;k++)
3819             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3820           dist=sqrt(dist);
3821           outData[i*nbOfTuples+j]=dist;
3822           outData[j*nbOfTuples+i]=dist;
3823         }
3824     }
3825   return ret.retn();
3826 }
3827
3828 /*!
3829  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
3830  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
3831  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
3832  * \n Output rectangular matrix is sorted along rows.
3833  * \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)
3834  *
3835  * \warning use this method with care because it can leads to big amount of consumed memory !
3836  * 
3837  * \param [in] other DataArrayDouble instance having same number of components than \a this.
3838  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3839  *
3840  * \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.
3841  *
3842  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
3843  */
3844 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception)
3845 {
3846   if(!other)
3847     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
3848   checkAllocated();
3849   other->checkAllocated();
3850   int nbOfComp=getNumberOfComponents();
3851   int otherNbOfComp=other->getNumberOfComponents();
3852   if(nbOfComp!=otherNbOfComp)
3853     {
3854       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
3855       throw INTERP_KERNEL::Exception(oss.str().c_str());
3856     }
3857   int nbOfTuples=getNumberOfTuples();
3858   int otherNbOfTuples=other->getNumberOfTuples();
3859   const double *inData=getConstPointer();
3860   const double *inDataOther=other->getConstPointer();
3861   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3862   ret->alloc(otherNbOfTuples*nbOfTuples,1);
3863   double *outData=ret->getPointer();
3864   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
3865     {
3866       for(int j=0;j<nbOfTuples;j++)
3867         {
3868           double dist=0.;
3869           for(int k=0;k<nbOfComp;k++)
3870             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3871           dist=sqrt(dist);
3872           outData[i*nbOfTuples+j]=dist;
3873         }
3874     }
3875   return ret.retn();
3876 }
3877
3878 /*!
3879  * Sorts value within every tuple of \a this array.
3880  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
3881  *              in descending order.
3882  *  \throw If \a this is not allocated.
3883  */
3884 void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
3885 {
3886   checkAllocated();
3887   double *pt=getPointer();
3888   int nbOfTuple=getNumberOfTuples();
3889   int nbOfComp=getNumberOfComponents();
3890   if(asc)
3891     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3892       std::sort(pt,pt+nbOfComp);
3893   else
3894     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
3895       std::sort(pt,pt+nbOfComp,std::greater<double>());
3896   declareAsNew();
3897 }
3898
3899 /*!
3900  * Converts every value of \a this array to its absolute value.
3901  *  \throw If \a this is not allocated.
3902  */
3903 void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception)
3904 {
3905   checkAllocated();
3906   double *ptr=getPointer();
3907   std::size_t nbOfElems=getNbOfElems();
3908   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
3909   declareAsNew();
3910 }
3911
3912 /*!
3913  * Apply a liner function to a given component of \a this array, so that
3914  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
3915  *  \param [in] a - the first coefficient of the function.
3916  *  \param [in] b - the second coefficient of the function.
3917  *  \param [in] compoId - the index of component to modify.
3918  *  \throw If \a this is not allocated.
3919  */
3920 void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception)
3921 {
3922   checkAllocated();
3923   double *ptr=getPointer()+compoId;
3924   int nbOfComp=getNumberOfComponents();
3925   int nbOfTuple=getNumberOfTuples();
3926   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
3927     *ptr=a*(*ptr)+b;
3928   declareAsNew();
3929 }
3930
3931 /*!
3932  * Apply a liner function to all elements of \a this array, so that
3933  * an element _x_ becomes \f$ a * x + b \f$.
3934  *  \param [in] a - the first coefficient of the function.
3935  *  \param [in] b - the second coefficient of the function.
3936  *  \throw If \a this is not allocated.
3937  */
3938 void DataArrayDouble::applyLin(double a, double b) throw(INTERP_KERNEL::Exception)
3939 {
3940   checkAllocated();
3941   double *ptr=getPointer();
3942   std::size_t nbOfElems=getNbOfElems();
3943   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3944     *ptr=a*(*ptr)+b;
3945   declareAsNew();
3946 }
3947
3948 /*!
3949  * Modify all elements of \a this array, so that
3950  * an element _x_ becomes \f$ numerator / x \f$.
3951  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
3952  *           array, all elements processed before detection of the zero element remain
3953  *           modified.
3954  *  \param [in] numerator - the numerator used to modify array elements.
3955  *  \throw If \a this is not allocated.
3956  *  \throw If there is an element equal to 0.0 in \a this array.
3957  */
3958 void DataArrayDouble::applyInv(double numerator) throw(INTERP_KERNEL::Exception)
3959 {
3960   checkAllocated();
3961   double *ptr=getPointer();
3962   std::size_t nbOfElems=getNbOfElems();
3963   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
3964     {
3965       if(std::abs(*ptr)>std::numeric_limits<double>::min())
3966         {
3967           *ptr=numerator/(*ptr);
3968         }
3969       else
3970         {
3971           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
3972           oss << " !";
3973           throw INTERP_KERNEL::Exception(oss.str().c_str());
3974         }
3975     }
3976   declareAsNew();
3977 }
3978
3979 /*!
3980  * Returns a full copy of \a this array except that sign of all elements is reversed.
3981  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3982  *          same number of tuples and component as \a this array.
3983  *          The caller is to delete this result array using decrRef() as it is no more
3984  *          needed.
3985  *  \throw If \a this is not allocated.
3986  */
3987 DataArrayDouble *DataArrayDouble::negate() const throw(INTERP_KERNEL::Exception)
3988 {
3989   checkAllocated();
3990   DataArrayDouble *newArr=DataArrayDouble::New();
3991   int nbOfTuples=getNumberOfTuples();
3992   int nbOfComp=getNumberOfComponents();
3993   newArr->alloc(nbOfTuples,nbOfComp);
3994   const double *cptr=getConstPointer();
3995   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
3996   newArr->copyStringInfoFrom(*this);
3997   return newArr;
3998 }
3999
4000 /*!
4001  * Modify all elements of \a this array, so that
4002  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4003  * all values in \a this have to be >= 0 if val is \b not integer.
4004  *  \param [in] val - the value used to apply pow on all array elements.
4005  *  \throw If \a this is not allocated.
4006  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4007  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4008  *           modified.
4009  */
4010 void DataArrayDouble::applyPow(double val) throw(INTERP_KERNEL::Exception)
4011 {
4012   checkAllocated();
4013   double *ptr=getPointer();
4014   std::size_t nbOfElems=getNbOfElems();
4015   int val2=(int)val;
4016   bool isInt=((double)val2)==val;
4017   if(!isInt)
4018     {
4019       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4020         {
4021           if(*ptr>=0)
4022             *ptr=pow(*ptr,val);
4023           else
4024             {
4025               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4026               throw INTERP_KERNEL::Exception(oss.str().c_str());
4027             }
4028         }
4029     }
4030   else
4031     {
4032       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4033         *ptr=pow(*ptr,val2);
4034     }
4035   declareAsNew();
4036 }
4037
4038 /*!
4039  * Modify all elements of \a this array, so that
4040  * an element _x_ becomes \f$ val ^ x \f$.
4041  *  \param [in] val - the value used to apply pow on all array elements.
4042  *  \throw If \a this is not allocated.
4043  *  \throw If \a val < 0.
4044  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4045  *           array, all elements processed before detection of the zero element remain
4046  *           modified.
4047  */
4048 void DataArrayDouble::applyRPow(double val) throw(INTERP_KERNEL::Exception)
4049 {
4050   checkAllocated();
4051   if(val<0.)
4052     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4053   double *ptr=getPointer();
4054   std::size_t nbOfElems=getNbOfElems();
4055   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4056     *ptr=pow(val,*ptr);
4057   declareAsNew();
4058 }
4059
4060 /*!
4061  * Returns a new DataArrayDouble created from \a this one by applying \a
4062  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4063  * For more info see \ref MEDCouplingArrayApplyFunc
4064  *  \param [in] nbOfComp - number of components in the result array.
4065  *  \param [in] func - the \a FunctionToEvaluate declared as 
4066  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4067  *              where \a pos points to the first component of a tuple of \a this array
4068  *              and \a res points to the first component of a tuple of the result array.
4069  *              Note that length (number of components) of \a pos can differ from
4070  *              that of \a res.
4071  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4072  *          same number of tuples as \a this array.
4073  *          The caller is to delete this result array using decrRef() as it is no more
4074  *          needed.
4075  *  \throw If \a this is not allocated.
4076  *  \throw If \a func returns \a false.
4077  */
4078 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception)
4079 {
4080   checkAllocated();
4081   DataArrayDouble *newArr=DataArrayDouble::New();
4082   int nbOfTuples=getNumberOfTuples();
4083   int oldNbOfComp=getNumberOfComponents();
4084   newArr->alloc(nbOfTuples,nbOfComp);
4085   const double *ptr=getConstPointer();
4086   double *ptrToFill=newArr->getPointer();
4087   for(int i=0;i<nbOfTuples;i++)
4088     {
4089       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4090         {
4091           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4092           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4093           oss << ") : Evaluation of function failed !";
4094           newArr->decrRef();
4095           throw INTERP_KERNEL::Exception(oss.str().c_str());
4096         }
4097     }
4098   return newArr;
4099 }
4100
4101 /*!
4102  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4103  * tuple of \a this array. Textual data is not copied.
4104  * For more info see \ref MEDCouplingArrayApplyFunc1.
4105  *  \param [in] nbOfComp - number of components in the result array.
4106  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4107  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4108  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4109  *          same number of tuples as \a this array and \a nbOfComp components.
4110  *          The caller is to delete this result array using decrRef() as it is no more
4111  *          needed.
4112  *  \throw If \a this is not allocated.
4113  *  \throw If computing \a func fails.
4114  */
4115 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
4116 {
4117   checkAllocated();
4118   INTERP_KERNEL::ExprParser expr(func);
4119   expr.parse();
4120   std::set<std::string> vars;
4121   expr.getTrueSetOfVars(vars);
4122   int oldNbOfComp=getNumberOfComponents();
4123   if((int)vars.size()>oldNbOfComp)
4124     {
4125       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4126       oss << vars.size() << " variables : ";
4127       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4128       throw INTERP_KERNEL::Exception(oss.str().c_str());
4129     }
4130   std::vector<std::string> varsV(vars.begin(),vars.end());
4131   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
4132   //
4133   DataArrayDouble *newArr=DataArrayDouble::New();
4134   int nbOfTuples=getNumberOfTuples();
4135   newArr->alloc(nbOfTuples,nbOfComp);
4136   const double *ptr=getConstPointer();
4137   double *ptrToFill=newArr->getPointer();
4138   for(int i=0;i<nbOfTuples;i++)
4139     {
4140       try
4141         {
4142           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4143         }
4144       catch(INTERP_KERNEL::Exception& e)
4145         {
4146           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4147           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4148           oss << ") : Evaluation of function failed !" << e.what();
4149           newArr->decrRef();
4150           throw INTERP_KERNEL::Exception(oss.str().c_str());
4151         }
4152     }
4153   return newArr;
4154 }
4155
4156 /*!
4157  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4158  * tuple of \a this array. Textual data is not copied.
4159  * For more info see \ref MEDCouplingArrayApplyFunc0.
4160  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4161  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4162  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4163  *          same number of tuples and components as \a this array.
4164  *          The caller is to delete this result array using decrRef() as it is no more
4165  *          needed.
4166  *  \throw If \a this is not allocated.
4167  *  \throw If computing \a func fails.
4168  */
4169 DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception)
4170 {
4171   checkAllocated();
4172   INTERP_KERNEL::ExprParser expr(func);
4173   expr.parse();
4174   expr.prepareExprEvaluationVec();
4175   //
4176   DataArrayDouble *newArr=DataArrayDouble::New();
4177   int nbOfTuples=getNumberOfTuples();
4178   int nbOfComp=getNumberOfComponents();
4179   newArr->alloc(nbOfTuples,nbOfComp);
4180   const double *ptr=getConstPointer();
4181   double *ptrToFill=newArr->getPointer();
4182   for(int i=0;i<nbOfTuples;i++)
4183     {
4184       try
4185         {
4186           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
4187         }
4188       catch(INTERP_KERNEL::Exception& e)
4189         {
4190           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4191           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4192           oss << ") : Evaluation of function failed ! " << e.what();
4193           newArr->decrRef();
4194           throw INTERP_KERNEL::Exception(oss.str().c_str());
4195         }
4196     }
4197   return newArr;
4198 }
4199
4200 /*!
4201  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4202  * tuple of \a this array. Textual data is not copied.
4203  * For more info see \ref MEDCouplingArrayApplyFunc2.
4204  *  \param [in] nbOfComp - number of components in the result array.
4205  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4206  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4207  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4208  *          same number of tuples as \a this array.
4209  *          The caller is to delete this result array using decrRef() as it is no more
4210  *          needed.
4211  *  \throw If \a this is not allocated.
4212  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4213  *  \throw If computing \a func fails.
4214  */
4215 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception)
4216 {
4217   checkAllocated();
4218   INTERP_KERNEL::ExprParser expr(func);
4219   expr.parse();
4220   std::set<std::string> vars;
4221   expr.getTrueSetOfVars(vars);
4222   int oldNbOfComp=getNumberOfComponents();
4223   if((int)vars.size()>oldNbOfComp)
4224     {
4225       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4226       oss << vars.size() << " variables : ";
4227       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4228       throw INTERP_KERNEL::Exception(oss.str().c_str());
4229     }
4230   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
4231   //
4232   DataArrayDouble *newArr=DataArrayDouble::New();
4233   int nbOfTuples=getNumberOfTuples();
4234   newArr->alloc(nbOfTuples,nbOfComp);
4235   const double *ptr=getConstPointer();
4236   double *ptrToFill=newArr->getPointer();
4237   for(int i=0;i<nbOfTuples;i++)
4238     {
4239       try
4240         {
4241           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4242         }
4243       catch(INTERP_KERNEL::Exception& e)
4244         {
4245           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4246           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4247           oss << ") : Evaluation of function failed !" << e.what();
4248           newArr->decrRef();
4249           throw INTERP_KERNEL::Exception(oss.str().c_str());
4250         }
4251     }
4252   return newArr;
4253 }
4254
4255 /*!
4256  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4257  * tuple of \a this array. Textual data is not copied.
4258  * For more info see \ref MEDCouplingArrayApplyFunc3.
4259  *  \param [in] nbOfComp - number of components in the result array.
4260  *  \param [in] varsOrder - sequence of vars defining their order.
4261  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4262  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4263  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4264  *          same number of tuples as \a this array.
4265  *          The caller is to delete this result array using decrRef() as it is no more
4266  *          needed.
4267  *  \throw If \a this is not allocated.
4268  *  \throw If \a func contains vars not in \a varsOrder.
4269  *  \throw If computing \a func fails.
4270  */
4271 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const throw(INTERP_KERNEL::Exception)
4272 {
4273   checkAllocated();
4274   INTERP_KERNEL::ExprParser expr(func);
4275   expr.parse();
4276   std::set<std::string> vars;
4277   expr.getTrueSetOfVars(vars);
4278   int oldNbOfComp=getNumberOfComponents();
4279   if((int)vars.size()>oldNbOfComp)
4280     {
4281       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4282       oss << vars.size() << " variables : ";
4283       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4284       throw INTERP_KERNEL::Exception(oss.str().c_str());
4285     }
4286   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
4287   //
4288   DataArrayDouble *newArr=DataArrayDouble::New();
4289   int nbOfTuples=getNumberOfTuples();
4290   newArr->alloc(nbOfTuples,nbOfComp);
4291   const double *ptr=getConstPointer();
4292   double *ptrToFill=newArr->getPointer();
4293   for(int i=0;i<nbOfTuples;i++)
4294     {
4295       try
4296         {
4297           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4298         }
4299       catch(INTERP_KERNEL::Exception& e)
4300         {
4301           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4302           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4303           oss << ") : Evaluation of function failed !" << e.what();
4304           newArr->decrRef();
4305           throw INTERP_KERNEL::Exception(oss.str().c_str());
4306         }
4307     }
4308   return newArr;
4309 }
4310
4311 void DataArrayDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception)
4312 {
4313   checkAllocated();
4314   INTERP_KERNEL::ExprParser expr(func);
4315   expr.parse();
4316   char *funcStr=expr.compileX86();
4317   MYFUNCPTR funcPtr;
4318   *((void **)&funcPtr)=funcStr;//he he...
4319   //
4320   double *ptr=getPointer();
4321   int nbOfComp=getNumberOfComponents();
4322   int nbOfTuples=getNumberOfTuples();
4323   int nbOfElems=nbOfTuples*nbOfComp;
4324   for(int i=0;i<nbOfElems;i++,ptr++)
4325     *ptr=funcPtr(*ptr);
4326   declareAsNew();
4327 }
4328
4329 void DataArrayDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception)
4330 {
4331   checkAllocated();
4332   INTERP_KERNEL::ExprParser expr(func);
4333   expr.parse();
4334   char *funcStr=expr.compileX86_64();
4335   MYFUNCPTR funcPtr;
4336   *((void **)&funcPtr)=funcStr;//he he...
4337   //
4338   double *ptr=getPointer();
4339   int nbOfComp=getNumberOfComponents();
4340   int nbOfTuples=getNumberOfTuples();
4341   int nbOfElems=nbOfTuples*nbOfComp;
4342   for(int i=0;i<nbOfElems;i++,ptr++)
4343     *ptr=funcPtr(*ptr);
4344   declareAsNew();
4345 }
4346
4347 DataArrayDoubleIterator *DataArrayDouble::iterator() throw(INTERP_KERNEL::Exception)
4348 {
4349   return new DataArrayDoubleIterator(this);
4350 }
4351
4352 /*!
4353  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4354  * array whose values are within a given range. Textual data is not copied.
4355  *  \param [in] vmin - a lowest acceptable value (included).
4356  *  \param [in] vmax - a greatest acceptable value (included).
4357  *  \return DataArrayInt * - the new instance of DataArrayInt.
4358  *          The caller is to delete this result array using decrRef() as it is no more
4359  *          needed.
4360  *  \throw If \a this->getNumberOfComponents() != 1.
4361  *
4362  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4363  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4364  */
4365 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
4366 {
4367   checkAllocated();
4368   if(getNumberOfComponents()!=1)
4369     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4370   const double *cptr=getConstPointer();
4371   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
4372   int nbOfTuples=getNumberOfTuples();
4373   for(int i=0;i<nbOfTuples;i++,cptr++)
4374     if(*cptr>=vmin && *cptr<=vmax)
4375       ret->pushBackSilent(i);
4376   return ret.retn();
4377 }
4378
4379 /*!
4380  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4381  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4382  * the number of component in the result array is same as that of each of given arrays.
4383  * Info on components is copied from the first of the given arrays. Number of components
4384  * in the given arrays must be  the same.
4385  *  \param [in] a1 - an array to include in the result array.
4386  *  \param [in] a2 - another array to include in the result array.
4387  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4388  *          The caller is to delete this result array using decrRef() as it is no more
4389  *          needed.
4390  *  \throw If both \a a1 and \a a2 are NULL.
4391  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4392  */
4393 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4394 {
4395   std::vector<const DataArrayDouble *> tmp(2);
4396   tmp[0]=a1; tmp[1]=a2;
4397   return Aggregate(tmp);
4398 }
4399
4400 /*!
4401  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4402  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4403  * the number of component in the result array is same as that of each of given arrays.
4404  * Info on components is copied from the first of the given arrays. Number of components
4405  * in the given arrays must be  the same.
4406  *  \param [in] arr - a sequence of arrays to include in the result array.
4407  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4408  *          The caller is to delete this result array using decrRef() as it is no more
4409  *          needed.
4410  *  \throw If all arrays within \a arr are NULL.
4411  *  \throw If getNumberOfComponents() of arrays within \a arr.
4412  */
4413 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4414 {
4415   std::vector<const DataArrayDouble *> a;
4416   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4417     if(*it4)
4418       a.push_back(*it4);
4419   if(a.empty())
4420     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4421   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4422   int nbOfComp=(*it)->getNumberOfComponents();
4423   int nbt=(*it++)->getNumberOfTuples();
4424   for(int i=1;it!=a.end();it++,i++)
4425     {
4426       if((*it)->getNumberOfComponents()!=nbOfComp)
4427         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4428       nbt+=(*it)->getNumberOfTuples();
4429     }
4430   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4431   ret->alloc(nbt,nbOfComp);
4432   double *pt=ret->getPointer();
4433   for(it=a.begin();it!=a.end();it++)
4434     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4435   ret->copyStringInfoFrom(*(a[0]));
4436   return ret.retn();
4437 }
4438
4439 /*!
4440  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4441  * of components in the result array is a sum of the number of components of given arrays
4442  * and (2) the number of tuples in the result array is same as that of each of given
4443  * arrays. In other words the i-th tuple of result array includes all components of
4444  * i-th tuples of all given arrays.
4445  * Number of tuples in the given arrays must be  the same.
4446  *  \param [in] a1 - an array to include in the result array.
4447  *  \param [in] a2 - another array to include in the result array.
4448  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4449  *          The caller is to delete this result array using decrRef() as it is no more
4450  *          needed.
4451  *  \throw If both \a a1 and \a a2 are NULL.
4452  *  \throw If any given array is not allocated.
4453  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4454  */
4455 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4456 {
4457   std::vector<const DataArrayDouble *> arr(2);
4458   arr[0]=a1; arr[1]=a2;
4459   return Meld(arr);
4460 }
4461
4462 /*!
4463  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4464  * of components in the result array is a sum of the number of components of given arrays
4465  * and (2) the number of tuples in the result array is same as that of each of given
4466  * arrays. In other words the i-th tuple of result array includes all components of
4467  * i-th tuples of all given arrays.
4468  * Number of tuples 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 any given array is not allocated.
4475  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4476  */
4477 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr) throw(INTERP_KERNEL::Exception)
4478 {
4479   std::vector<const DataArrayDouble *> a;
4480   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4481     if(*it4)
4482       a.push_back(*it4);
4483   if(a.empty())
4484     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4485   std::vector<const DataArrayDouble *>::const_iterator it;
4486   for(it=a.begin();it!=a.end();it++)
4487     (*it)->checkAllocated();
4488   it=a.begin();
4489   int nbOfTuples=(*it)->getNumberOfTuples();
4490   std::vector<int> nbc(a.size());
4491   std::vector<const double *> pts(a.size());
4492   nbc[0]=(*it)->getNumberOfComponents();
4493   pts[0]=(*it++)->getConstPointer();
4494   for(int i=1;it!=a.end();it++,i++)
4495     {
4496       if(nbOfTuples!=(*it)->getNumberOfTuples())
4497         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4498       nbc[i]=(*it)->getNumberOfComponents();
4499       pts[i]=(*it)->getConstPointer();
4500     }
4501   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4502   DataArrayDouble *ret=DataArrayDouble::New();
4503   ret->alloc(nbOfTuples,totalNbOfComp);
4504   double *retPtr=ret->getPointer();
4505   for(int i=0;i<nbOfTuples;i++)
4506     for(int j=0;j<(int)a.size();j++)
4507       {
4508         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4509         pts[j]+=nbc[j];
4510       }
4511   int k=0;
4512   for(int i=0;i<(int)a.size();i++)
4513     for(int j=0;j<nbc[i];j++,k++)
4514       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
4515   return ret;
4516 }
4517
4518 /*!
4519  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4520  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4521  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4522  * Info on components and name is copied from the first of the given arrays.
4523  * Number of tuples and components in the given arrays must be the same.
4524  *  \param [in] a1 - a given array.
4525  *  \param [in] a2 - another given array.
4526  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4527  *          The caller is to delete this result array using decrRef() as it is no more
4528  *          needed.
4529  *  \throw If either \a a1 or \a a2 is NULL.
4530  *  \throw If any given array is not allocated.
4531  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4532  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4533  */
4534 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4535 {
4536   if(!a1 || !a2)
4537     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4538   a1->checkAllocated();
4539   a2->checkAllocated();
4540   int nbOfComp=a1->getNumberOfComponents();
4541   if(nbOfComp!=a2->getNumberOfComponents())
4542     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4543   int nbOfTuple=a1->getNumberOfTuples();
4544   if(nbOfTuple!=a2->getNumberOfTuples())
4545     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4546   DataArrayDouble *ret=DataArrayDouble::New();
4547   ret->alloc(nbOfTuple,1);
4548   double *retPtr=ret->getPointer();
4549   const double *a1Ptr=a1->getConstPointer();
4550   const double *a2Ptr=a2->getConstPointer();
4551   for(int i=0;i<nbOfTuple;i++)
4552     {
4553       double sum=0.;
4554       for(int j=0;j<nbOfComp;j++)
4555         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4556       retPtr[i]=sum;
4557     }
4558   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
4559   ret->setName(a1->getName().c_str());
4560   return ret;
4561 }
4562
4563 /*!
4564  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4565  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4566  * product of two vectors defined by the i-th tuples of given arrays.
4567  * Info on components is copied from the first of the given arrays.
4568  * Number of tuples in the given arrays must be the same.
4569  * Number of components in the given arrays must be 3.
4570  *  \param [in] a1 - a given array.
4571  *  \param [in] a2 - another given array.
4572  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4573  *          The caller is to delete this result array using decrRef() as it is no more
4574  *          needed.
4575  *  \throw If either \a a1 or \a a2 is NULL.
4576  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4577  *  \throw If \a a1->getNumberOfComponents() != 3
4578  *  \throw If \a a2->getNumberOfComponents() != 3
4579  */
4580 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4581 {
4582   if(!a1 || !a2)
4583     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4584   int nbOfComp=a1->getNumberOfComponents();
4585   if(nbOfComp!=a2->getNumberOfComponents())
4586     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4587   if(nbOfComp!=3)
4588     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4589   int nbOfTuple=a1->getNumberOfTuples();
4590   if(nbOfTuple!=a2->getNumberOfTuples())
4591     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4592   DataArrayDouble *ret=DataArrayDouble::New();
4593   ret->alloc(nbOfTuple,3);
4594   double *retPtr=ret->getPointer();
4595   const double *a1Ptr=a1->getConstPointer();
4596   const double *a2Ptr=a2->getConstPointer();
4597   for(int i=0;i<nbOfTuple;i++)
4598     {
4599       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4600       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4601       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4602     }
4603   ret->copyStringInfoFrom(*a1);
4604   return ret;
4605 }
4606
4607 /*!
4608  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4609  * Info on components is copied from the first of the given arrays.
4610  * Number of tuples and components in the given arrays must be the same.
4611  *  \param [in] a1 - an array to compare values with another one.
4612  *  \param [in] a2 - another array to compare values with the first one.
4613  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4614  *          The caller is to delete this result array using decrRef() as it is no more
4615  *          needed.
4616  *  \throw If either \a a1 or \a a2 is NULL.
4617  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4618  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4619  */
4620 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4621 {
4622   if(!a1 || !a2)
4623     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4624   int nbOfComp=a1->getNumberOfComponents();
4625   if(nbOfComp!=a2->getNumberOfComponents())
4626     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4627   int nbOfTuple=a1->getNumberOfTuples();
4628   if(nbOfTuple!=a2->getNumberOfTuples())
4629     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4630   DataArrayDouble *ret=DataArrayDouble::New();
4631   ret->alloc(nbOfTuple,nbOfComp);
4632   double *retPtr=ret->getPointer();
4633   const double *a1Ptr=a1->getConstPointer();
4634   const double *a2Ptr=a2->getConstPointer();
4635   int nbElem=nbOfTuple*nbOfComp;
4636   for(int i=0;i<nbElem;i++)
4637     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4638   ret->copyStringInfoFrom(*a1);
4639   return ret;
4640 }
4641
4642 /*!
4643  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4644  * Info on components is copied from the first of the given arrays.
4645  * Number of tuples and components in the given arrays must be the same.
4646  *  \param [in] a1 - an array to compare values with another one.
4647  *  \param [in] a2 - another array to compare values with the first one.
4648  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4649  *          The caller is to delete this result array using decrRef() as it is no more
4650  *          needed.
4651  *  \throw If either \a a1 or \a a2 is NULL.
4652  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4653  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4654  */
4655 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4656 {
4657   if(!a1 || !a2)
4658     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4659   int nbOfComp=a1->getNumberOfComponents();
4660   if(nbOfComp!=a2->getNumberOfComponents())
4661     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4662   int nbOfTuple=a1->getNumberOfTuples();
4663   if(nbOfTuple!=a2->getNumberOfTuples())
4664     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4665   DataArrayDouble *ret=DataArrayDouble::New();
4666   ret->alloc(nbOfTuple,nbOfComp);
4667   double *retPtr=ret->getPointer();
4668   const double *a1Ptr=a1->getConstPointer();
4669   const double *a2Ptr=a2->getConstPointer();
4670   int nbElem=nbOfTuple*nbOfComp;
4671   for(int i=0;i<nbElem;i++)
4672     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4673   ret->copyStringInfoFrom(*a1);
4674   return ret;
4675 }
4676
4677 /*!
4678  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4679  * valid cases.
4680  * 1.  The arrays have same number of tuples and components. Then each value of
4681  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4682  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4683  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4684  *   component. Then
4685  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4686  * 3.  The arrays have same number of components and one array, say _a2_, has one
4687  *   tuple. Then
4688  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4689  *
4690  * Info on components is copied either from the first array (in the first case) or from
4691  * the array with maximal number of elements (getNbOfElems()).
4692  *  \param [in] a1 - an array to sum up.
4693  *  \param [in] a2 - another array to sum up.
4694  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4695  *          The caller is to delete this result array using decrRef() as it is no more
4696  *          needed.
4697  *  \throw If either \a a1 or \a a2 is NULL.
4698  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4699  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4700  *         none of them has number of tuples or components equal to 1.
4701  */
4702 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4703 {
4704   if(!a1 || !a2)
4705     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4706   int nbOfTuple=a1->getNumberOfTuples();
4707   int nbOfTuple2=a2->getNumberOfTuples();
4708   int nbOfComp=a1->getNumberOfComponents();
4709   int nbOfComp2=a2->getNumberOfComponents();
4710   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4711   if(nbOfTuple==nbOfTuple2)
4712     {
4713       if(nbOfComp==nbOfComp2)
4714         {
4715           ret=DataArrayDouble::New();
4716           ret->alloc(nbOfTuple,nbOfComp);
4717           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4718           ret->copyStringInfoFrom(*a1);
4719         }
4720       else
4721         {
4722           int nbOfCompMin,nbOfCompMax;
4723           const DataArrayDouble *aMin, *aMax;
4724           if(nbOfComp>nbOfComp2)
4725             {
4726               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4727               aMin=a2; aMax=a1;
4728             }
4729           else
4730             {
4731               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4732               aMin=a1; aMax=a2;
4733             }
4734           if(nbOfCompMin==1)
4735             {
4736               ret=DataArrayDouble::New();
4737               ret->alloc(nbOfTuple,nbOfCompMax);
4738               const double *aMinPtr=aMin->getConstPointer();
4739               const double *aMaxPtr=aMax->getConstPointer();
4740               double *res=ret->getPointer();
4741               for(int i=0;i<nbOfTuple;i++)
4742                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4743               ret->copyStringInfoFrom(*aMax);
4744             }
4745           else
4746             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4747         }
4748     }
4749   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4750     {
4751       if(nbOfComp==nbOfComp2)
4752         {
4753           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4754           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4755           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4756           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4757           ret=DataArrayDouble::New();
4758           ret->alloc(nbOfTupleMax,nbOfComp);
4759           double *res=ret->getPointer();
4760           for(int i=0;i<nbOfTupleMax;i++)
4761             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4762           ret->copyStringInfoFrom(*aMax);
4763         }
4764       else
4765         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4766     }
4767   else
4768     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4769   return ret.retn();
4770 }
4771
4772 /*!
4773  * Adds values of another DataArrayDouble to values of \a this one. There are 3
4774  * valid cases.
4775  * 1.  The arrays have same number of tuples and components. Then each value of
4776  *   \a other array is added to the corresponding value of \a this array, i.e.:
4777  *   _a_ [ i, j ] += _other_ [ i, j ].
4778  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4779  *   _a_ [ i, j ] += _other_ [ i, 0 ].
4780  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4781  *   _a_ [ i, j ] += _a2_ [ 0, j ].
4782  *
4783  *  \param [in] other - an array to add to \a this one.
4784  *  \throw If \a other is NULL.
4785  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4786  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4787  *         \a other has number of both tuples and components not equal to 1.
4788  */
4789 void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4790 {
4791   if(!other)
4792     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
4793   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
4794   checkAllocated();
4795   other->checkAllocated();
4796   int nbOfTuple=getNumberOfTuples();
4797   int nbOfTuple2=other->getNumberOfTuples();
4798   int nbOfComp=getNumberOfComponents();
4799   int nbOfComp2=other->getNumberOfComponents();
4800   if(nbOfTuple==nbOfTuple2)
4801     {
4802       if(nbOfComp==nbOfComp2)
4803         {
4804           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
4805         }
4806       else if(nbOfComp2==1)
4807         {
4808           double *ptr=getPointer();
4809           const double *ptrc=other->getConstPointer();
4810           for(int i=0;i<nbOfTuple;i++)
4811             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
4812         }
4813       else
4814         throw INTERP_KERNEL::Exception(msg);
4815     }
4816   else if(nbOfTuple2==1)
4817     {
4818       if(nbOfComp2==nbOfComp)
4819         {
4820           double *ptr=getPointer();
4821           const double *ptrc=other->getConstPointer();
4822           for(int i=0;i<nbOfTuple;i++)
4823             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
4824         }
4825       else
4826         throw INTERP_KERNEL::Exception(msg);
4827     }
4828   else
4829     throw INTERP_KERNEL::Exception(msg);
4830   declareAsNew();
4831 }
4832
4833 /*!
4834  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
4835  * valid cases.
4836  * 1.  The arrays have same number of tuples and components. Then each value of
4837  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
4838  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
4839  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4840  *   component. Then
4841  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
4842  * 3.  The arrays have same number of components and one array, say _a2_, has one
4843  *   tuple. Then
4844  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
4845  *
4846  * Info on components is copied either from the first array (in the first case) or from
4847  * the array with maximal number of elements (getNbOfElems()).
4848  *  \param [in] a1 - an array to subtract from.
4849  *  \param [in] a2 - an array to subtract.
4850  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4851  *          The caller is to delete this result array using decrRef() as it is no more
4852  *          needed.
4853  *  \throw If either \a a1 or \a a2 is NULL.
4854  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4855  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4856  *         none of them has number of tuples or components equal to 1.
4857  */
4858 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
4859 {
4860   if(!a1 || !a2)
4861     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
4862   int nbOfTuple1=a1->getNumberOfTuples();
4863   int nbOfTuple2=a2->getNumberOfTuples();
4864   int nbOfComp1=a1->getNumberOfComponents();
4865   int nbOfComp2=a2->getNumberOfComponents();
4866   if(nbOfTuple2==nbOfTuple1)
4867     {
4868       if(nbOfComp1==nbOfComp2)
4869         {
4870           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4871           ret->alloc(nbOfTuple2,nbOfComp1);
4872           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
4873           ret->copyStringInfoFrom(*a1);
4874           return ret.retn();
4875         }
4876       else if(nbOfComp2==1)
4877         {
4878           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4879           ret->alloc(nbOfTuple1,nbOfComp1);
4880           const double *a2Ptr=a2->getConstPointer();
4881           const double *a1Ptr=a1->getConstPointer();
4882           double *res=ret->getPointer();
4883           for(int i=0;i<nbOfTuple1;i++)
4884             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
4885           ret->copyStringInfoFrom(*a1);
4886           return ret.retn();
4887         }
4888       else
4889         {
4890           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4891           return 0;
4892         }
4893     }
4894   else if(nbOfTuple2==1)
4895     {
4896       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
4897       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4898       ret->alloc(nbOfTuple1,nbOfComp1);
4899       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4900       double *pt=ret->getPointer();
4901       for(int i=0;i<nbOfTuple1;i++)
4902         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
4903       ret->copyStringInfoFrom(*a1);
4904       return ret.retn();
4905     }
4906   else
4907     {
4908       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
4909       return 0;
4910     }
4911 }
4912
4913 /*!
4914  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
4915  * valid cases.
4916  * 1.  The arrays have same number of tuples and components. Then each value of
4917  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
4918  *   _a_ [ i, j ] -= _other_ [ i, j ].
4919  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4920  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
4921  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4922  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
4923  *
4924  *  \param [in] other - an array to subtract from \a this one.
4925  *  \throw If \a other is NULL.
4926  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4927  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4928  *         \a other has number of both tuples and components not equal to 1.
4929  */
4930 void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
4931 {
4932   if(!other)
4933     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
4934   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
4935   checkAllocated();
4936   other->checkAllocated();
4937   int nbOfTuple=getNumberOfTuples();
4938   int nbOfTuple2=other->getNumberOfTuples();
4939   int nbOfComp=getNumberOfComponents();
4940   int nbOfComp2=other->getNumberOfComponents();
4941   if(nbOfTuple==nbOfTuple2)
4942     {
4943       if(nbOfComp==nbOfComp2)
4944         {
4945           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
4946         }
4947       else if(nbOfComp2==1)
4948         {
4949           double *ptr=getPointer();
4950           const double *ptrc=other->getConstPointer();
4951           for(int i=0;i<nbOfTuple;i++)
4952             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
4953         }
4954       else
4955         throw INTERP_KERNEL::Exception(msg);
4956     }
4957   else if(nbOfTuple2==1)
4958     {
4959       if(nbOfComp2==nbOfComp)
4960         {
4961           double *ptr=getPointer();
4962           const double *ptrc=other->getConstPointer();
4963           for(int i=0;i<nbOfTuple;i++)
4964             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
4965         }
4966       else
4967         throw INTERP_KERNEL::Exception(msg);
4968     }
4969   else
4970     throw INTERP_KERNEL::Exception(msg);
4971   declareAsNew();
4972 }
4973
4974 /*!
4975  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
4976  * valid cases.
4977  * 1.  The arrays have same number of tuples and components. Then each value of
4978  *   the result array (_a_) is a product of the corresponding values of \a a1 and
4979  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
4980  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4981  *   component. Then
4982  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
4983  * 3.  The arrays have same number of components and one array, say _a2_, has one
4984  *   tuple. Then
4985  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
4986  *
4987  * Info on components is copied either from the first array (in the first case) or from
4988  * the array with maximal number of elements (getNbOfElems()).
4989  *  \param [in] a1 - a factor array.
4990  *  \param [in] a2 - another factor array.
4991  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4992  *          The caller is to delete this result array using decrRef() as it is no more
4993  *          needed.
4994  *  \throw If either \a a1 or \a a2 is NULL.
4995  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4996  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4997  *         none of them has number of tuples or components equal to 1.
4998  */
4999 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5000 {
5001   if(!a1 || !a2)
5002     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5003   int nbOfTuple=a1->getNumberOfTuples();
5004   int nbOfTuple2=a2->getNumberOfTuples();
5005   int nbOfComp=a1->getNumberOfComponents();
5006   int nbOfComp2=a2->getNumberOfComponents();
5007   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5008   if(nbOfTuple==nbOfTuple2)
5009     {
5010       if(nbOfComp==nbOfComp2)
5011         {
5012           ret=DataArrayDouble::New();
5013           ret->alloc(nbOfTuple,nbOfComp);
5014           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5015           ret->copyStringInfoFrom(*a1);
5016         }
5017       else
5018         {
5019           int nbOfCompMin,nbOfCompMax;
5020           const DataArrayDouble *aMin, *aMax;
5021           if(nbOfComp>nbOfComp2)
5022             {
5023               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5024               aMin=a2; aMax=a1;
5025             }
5026           else
5027             {
5028               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5029               aMin=a1; aMax=a2;
5030             }
5031           if(nbOfCompMin==1)
5032             {
5033               ret=DataArrayDouble::New();
5034               ret->alloc(nbOfTuple,nbOfCompMax);
5035               const double *aMinPtr=aMin->getConstPointer();
5036               const double *aMaxPtr=aMax->getConstPointer();
5037               double *res=ret->getPointer();
5038               for(int i=0;i<nbOfTuple;i++)
5039                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5040               ret->copyStringInfoFrom(*aMax);
5041             }
5042           else
5043             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5044         }
5045     }
5046   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5047     {
5048       if(nbOfComp==nbOfComp2)
5049         {
5050           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5051           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5052           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5053           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5054           ret=DataArrayDouble::New();
5055           ret->alloc(nbOfTupleMax,nbOfComp);
5056           double *res=ret->getPointer();
5057           for(int i=0;i<nbOfTupleMax;i++)
5058             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5059           ret->copyStringInfoFrom(*aMax);
5060         }
5061       else
5062         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5063     }
5064   else
5065     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5066   return ret.retn();
5067 }
5068
5069 /*!
5070  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5071  * valid cases.
5072  * 1.  The arrays have same number of tuples and components. Then each value of
5073  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5074  *   _this_ [ i, j ] *= _other_ [ i, j ].
5075  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5076  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5077  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5078  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5079  *
5080  *  \param [in] other - an array to multiply to \a this one.
5081  *  \throw If \a other is NULL.
5082  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5083  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5084  *         \a other has number of both tuples and components not equal to 1.
5085  */
5086 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5087 {
5088   if(!other)
5089     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5090   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5091   checkAllocated();
5092   other->checkAllocated();
5093   int nbOfTuple=getNumberOfTuples();
5094   int nbOfTuple2=other->getNumberOfTuples();
5095   int nbOfComp=getNumberOfComponents();
5096   int nbOfComp2=other->getNumberOfComponents();
5097   if(nbOfTuple==nbOfTuple2)
5098     {
5099       if(nbOfComp==nbOfComp2)
5100         {
5101           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5102         }
5103       else if(nbOfComp2==1)
5104         {
5105           double *ptr=getPointer();
5106           const double *ptrc=other->getConstPointer();
5107           for(int i=0;i<nbOfTuple;i++)
5108             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5109         }
5110       else
5111         throw INTERP_KERNEL::Exception(msg);
5112     }
5113   else if(nbOfTuple2==1)
5114     {
5115       if(nbOfComp2==nbOfComp)
5116         {
5117           double *ptr=getPointer();
5118           const double *ptrc=other->getConstPointer();
5119           for(int i=0;i<nbOfTuple;i++)
5120             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5121         }
5122       else
5123         throw INTERP_KERNEL::Exception(msg);
5124     }
5125   else
5126     throw INTERP_KERNEL::Exception(msg);
5127   declareAsNew();
5128 }
5129
5130 /*!
5131  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5132  * valid cases.
5133  * 1.  The arrays have same number of tuples and components. Then each value of
5134  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5135  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5136  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5137  *   component. Then
5138  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5139  * 3.  The arrays have same number of components and one array, say _a2_, has one
5140  *   tuple. Then
5141  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5142  *
5143  * Info on components is copied either from the first array (in the first case) or from
5144  * the array with maximal number of elements (getNbOfElems()).
5145  *  \warning No check of division by zero is performed!
5146  *  \param [in] a1 - a numerator array.
5147  *  \param [in] a2 - a denominator array.
5148  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5149  *          The caller is to delete this result array using decrRef() as it is no more
5150  *          needed.
5151  *  \throw If either \a a1 or \a a2 is NULL.
5152  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5153  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5154  *         none of them has number of tuples or components equal to 1.
5155  */
5156 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5157 {
5158   if(!a1 || !a2)
5159     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5160   int nbOfTuple1=a1->getNumberOfTuples();
5161   int nbOfTuple2=a2->getNumberOfTuples();
5162   int nbOfComp1=a1->getNumberOfComponents();
5163   int nbOfComp2=a2->getNumberOfComponents();
5164   if(nbOfTuple2==nbOfTuple1)
5165     {
5166       if(nbOfComp1==nbOfComp2)
5167         {
5168           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5169           ret->alloc(nbOfTuple2,nbOfComp1);
5170           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5171           ret->copyStringInfoFrom(*a1);
5172           return ret.retn();
5173         }
5174       else if(nbOfComp2==1)
5175         {
5176           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5177           ret->alloc(nbOfTuple1,nbOfComp1);
5178           const double *a2Ptr=a2->getConstPointer();
5179           const double *a1Ptr=a1->getConstPointer();
5180           double *res=ret->getPointer();
5181           for(int i=0;i<nbOfTuple1;i++)
5182             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5183           ret->copyStringInfoFrom(*a1);
5184           return ret.retn();
5185         }
5186       else
5187         {
5188           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5189           return 0;
5190         }
5191     }
5192   else if(nbOfTuple2==1)
5193     {
5194       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5195       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5196       ret->alloc(nbOfTuple1,nbOfComp1);
5197       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5198       double *pt=ret->getPointer();
5199       for(int i=0;i<nbOfTuple1;i++)
5200         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5201       ret->copyStringInfoFrom(*a1);
5202       return ret.retn();
5203     }
5204   else
5205     {
5206       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5207       return 0;
5208     }
5209 }
5210
5211 /*!
5212  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5213  * valid cases.
5214  * 1.  The arrays have same number of tuples and components. Then each value of
5215  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5216  *   _a_ [ i, j ] /= _other_ [ i, j ].
5217  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5218  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5219  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5220  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5221  *
5222  *  \warning No check of division by zero is performed!
5223  *  \param [in] other - an array to divide \a this one by.
5224  *  \throw If \a other is NULL.
5225  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5226  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5227  *         \a other has number of both tuples and components not equal to 1.
5228  */
5229 void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5230 {
5231   if(!other)
5232     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5233   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5234   checkAllocated();
5235   other->checkAllocated();
5236   int nbOfTuple=getNumberOfTuples();
5237   int nbOfTuple2=other->getNumberOfTuples();
5238   int nbOfComp=getNumberOfComponents();
5239   int nbOfComp2=other->getNumberOfComponents();
5240   if(nbOfTuple==nbOfTuple2)
5241     {
5242       if(nbOfComp==nbOfComp2)
5243         {
5244           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5245         }
5246       else if(nbOfComp2==1)
5247         {
5248           double *ptr=getPointer();
5249           const double *ptrc=other->getConstPointer();
5250           for(int i=0;i<nbOfTuple;i++)
5251             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5252         }
5253       else
5254         throw INTERP_KERNEL::Exception(msg);
5255     }
5256   else if(nbOfTuple2==1)
5257     {
5258       if(nbOfComp2==nbOfComp)
5259         {
5260           double *ptr=getPointer();
5261           const double *ptrc=other->getConstPointer();
5262           for(int i=0;i<nbOfTuple;i++)
5263             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5264         }
5265       else
5266         throw INTERP_KERNEL::Exception(msg);
5267     }
5268   else
5269     throw INTERP_KERNEL::Exception(msg);
5270   declareAsNew();
5271 }
5272
5273 /*!
5274  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5275  * valid cases.
5276  *
5277  *  \param [in] a1 - an array to pow up.
5278  *  \param [in] a2 - another array to sum up.
5279  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5280  *          The caller is to delete this result array using decrRef() as it is no more
5281  *          needed.
5282  *  \throw If either \a a1 or \a a2 is NULL.
5283  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5284  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5285  *  \throw If there is a negative value in \a a1.
5286  */
5287 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception)
5288 {
5289   if(!a1 || !a2)
5290     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5291   int nbOfTuple=a1->getNumberOfTuples();
5292   int nbOfTuple2=a2->getNumberOfTuples();
5293   int nbOfComp=a1->getNumberOfComponents();
5294   int nbOfComp2=a2->getNumberOfComponents();
5295   if(nbOfTuple!=nbOfTuple2)
5296     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5297   if(nbOfComp!=1 || nbOfComp2!=1)
5298     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5299   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5300   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5301   double *ptr=ret->getPointer();
5302   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5303     {
5304       if(*ptr1>=0)
5305         {
5306           *ptr=pow(*ptr1,*ptr2);
5307         }
5308       else
5309         {
5310           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5311           throw INTERP_KERNEL::Exception(oss.str().c_str());
5312         }
5313     }
5314   return ret.retn();
5315 }
5316
5317 /*!
5318  * Apply pow on values of another DataArrayDouble to values of \a this one.
5319  *
5320  *  \param [in] other - an array to pow to \a this one.
5321  *  \throw If \a other is NULL.
5322  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5323  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5324  *  \throw If there is a negative value in \a this.
5325  */
5326 void DataArrayDouble::powEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
5327 {
5328   if(!other)
5329     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5330   int nbOfTuple=getNumberOfTuples();
5331   int nbOfTuple2=other->getNumberOfTuples();
5332   int nbOfComp=getNumberOfComponents();
5333   int nbOfComp2=other->getNumberOfComponents();
5334   if(nbOfTuple!=nbOfTuple2)
5335     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5336   if(nbOfComp!=1 || nbOfComp2!=1)
5337     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5338   double *ptr=getPointer();
5339   const double *ptrc=other->begin();
5340   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5341     {
5342       if(*ptr>=0)
5343         *ptr=pow(*ptr,*ptrc);
5344       else
5345         {
5346           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5347           throw INTERP_KERNEL::Exception(oss.str().c_str());
5348         }
5349     }
5350   declareAsNew();
5351 }
5352
5353 /*!
5354  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5355  * Server side.
5356  */
5357 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5358 {
5359   tinyInfo.resize(2);
5360   if(isAllocated())
5361     {
5362       tinyInfo[0]=getNumberOfTuples();
5363       tinyInfo[1]=getNumberOfComponents();
5364     }
5365   else
5366     {
5367       tinyInfo[0]=-1;
5368       tinyInfo[1]=-1;
5369     }
5370 }
5371
5372 /*!
5373  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5374  * Server side.
5375  */
5376 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5377 {
5378   if(isAllocated())
5379     {
5380       int nbOfCompo=getNumberOfComponents();
5381       tinyInfo.resize(nbOfCompo+1);
5382       tinyInfo[0]=getName();
5383       for(int i=0;i<nbOfCompo;i++)
5384         tinyInfo[i+1]=getInfoOnComponent(i);
5385     }
5386   else
5387     {
5388       tinyInfo.resize(1);
5389       tinyInfo[0]=getName();
5390     }
5391 }
5392
5393 /*!
5394  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5395  * This method returns if a feeding is needed.
5396  */
5397 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5398 {
5399   int nbOfTuple=tinyInfoI[0];
5400   int nbOfComp=tinyInfoI[1];
5401   if(nbOfTuple!=-1 || nbOfComp!=-1)
5402     {
5403       alloc(nbOfTuple,nbOfComp);
5404       return true;
5405     }
5406   return false;
5407 }
5408
5409 /*!
5410  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5411  */
5412 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5413 {
5414   setName(tinyInfoS[0].c_str());
5415   if(isAllocated())
5416     {
5417       int nbOfCompo=getNumberOfComponents();
5418       for(int i=0;i<nbOfCompo;i++)
5419         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
5420     }
5421 }
5422
5423 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5424 {
5425   if(_da)
5426     {
5427       _da->incrRef();
5428       if(_da->isAllocated())
5429         {
5430           _nb_comp=da->getNumberOfComponents();
5431           _nb_tuple=da->getNumberOfTuples();
5432           _pt=da->getPointer();
5433         }
5434     }
5435 }
5436
5437 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5438 {
5439   if(_da)
5440     _da->decrRef();
5441 }
5442
5443 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() throw(INTERP_KERNEL::Exception)
5444 {
5445   if(_tuple_id<_nb_tuple)
5446     {
5447       _tuple_id++;
5448       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5449       _pt+=_nb_comp;
5450       return ret;
5451     }
5452   else
5453     return 0;
5454 }
5455
5456 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5457 {
5458 }
5459
5460
5461 std::string DataArrayDoubleTuple::repr() const throw(INTERP_KERNEL::Exception)
5462 {
5463   std::ostringstream oss; oss.precision(17); oss << "(";
5464   for(int i=0;i<_nb_of_compo-1;i++)
5465     oss << _pt[i] << ", ";
5466   oss << _pt[_nb_of_compo-1] << ")";
5467   return oss.str();
5468 }
5469
5470 double DataArrayDoubleTuple::doubleValue() const throw(INTERP_KERNEL::Exception)
5471 {
5472   if(_nb_of_compo==1)
5473     return *_pt;
5474   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5475 }
5476
5477 /*!
5478  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5479  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5480  * 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
5481  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5482  */
5483 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
5484 {
5485   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5486     {
5487       DataArrayDouble *ret=DataArrayDouble::New();
5488       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5489       return ret;
5490     }
5491   else
5492     {
5493       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5494       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5495       throw INTERP_KERNEL::Exception(oss.str().c_str());
5496     }
5497 }
5498
5499 /*!
5500  * Returns a new instance of DataArrayInt. The caller is to delete this array
5501  * using decrRef() as it is no more needed. 
5502  */
5503 DataArrayInt *DataArrayInt::New()
5504 {
5505   return new DataArrayInt;
5506 }
5507
5508 /*!
5509  * Checks if raw data is allocated. Read more on the raw data
5510  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5511  *  \return bool - \a true if the raw data is allocated, \a false else.
5512  */
5513 bool DataArrayInt::isAllocated() const throw(INTERP_KERNEL::Exception)
5514 {
5515   return getConstPointer()!=0;
5516 }
5517
5518 /*!
5519  * Checks if raw data is allocated and throws an exception if it is not the case.
5520  *  \throw If the raw data is not allocated.
5521  */
5522 void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception)
5523 {
5524   if(!isAllocated())
5525     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5526 }
5527
5528 /*!
5529  * This method desallocated \a this without modification of informations relative to the components.
5530  * After call of this method, DataArrayInt::isAllocated will return false.
5531  * If \a this is already not allocated, \a this is let unchanged.
5532  */
5533 void DataArrayInt::desallocate() throw(INTERP_KERNEL::Exception)
5534 {
5535   _mem.destroy();
5536 }
5537
5538 std::size_t DataArrayInt::getHeapMemorySize() const
5539 {
5540   std::size_t sz=_mem.getNbOfElemAllocated();
5541   sz*=sizeof(int);
5542   return DataArray::getHeapMemorySize()+sz;
5543 }
5544
5545 /*!
5546  * Returns the only one value in \a this, if and only if number of elements
5547  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5548  *  \return double - the sole value stored in \a this array.
5549  *  \throw If at least one of conditions stated above is not fulfilled.
5550  */
5551 int DataArrayInt::intValue() const throw(INTERP_KERNEL::Exception)
5552 {
5553   if(isAllocated())
5554     {
5555       if(getNbOfElems()==1)
5556         {
5557           return *getConstPointer();
5558         }
5559       else
5560         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5561     }
5562   else
5563     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5564 }
5565
5566 /*!
5567  * Returns an integer value characterizing \a this array, which is useful for a quick
5568  * comparison of many instances of DataArrayInt.
5569  *  \return int - the hash value.
5570  *  \throw If \a this is not allocated.
5571  */
5572 int DataArrayInt::getHashCode() const throw(INTERP_KERNEL::Exception)
5573 {
5574   checkAllocated();
5575   std::size_t nbOfElems=getNbOfElems();
5576   int ret=nbOfElems*65536;
5577   int delta=3;
5578   if(nbOfElems>48)
5579     delta=nbOfElems/8;
5580   int ret0=0;
5581   const int *pt=begin();
5582   for(std::size_t i=0;i<nbOfElems;i+=delta)
5583     ret0+=pt[i] & 0x1FFF;
5584   return ret+ret0;
5585 }
5586
5587 /*!
5588  * Checks the number of tuples.
5589  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5590  *  \throw If \a this is not allocated.
5591  */
5592 bool DataArrayInt::empty() const throw(INTERP_KERNEL::Exception)
5593 {
5594   checkAllocated();
5595   return getNumberOfTuples()==0;
5596 }
5597
5598 /*!
5599  * Returns a full copy of \a this. For more info on copying data arrays see
5600  * \ref MEDCouplingArrayBasicsCopyDeep.
5601  *  \return DataArrayInt * - a new instance of DataArrayInt.
5602  */
5603 DataArrayInt *DataArrayInt::deepCpy() const throw(INTERP_KERNEL::Exception)
5604 {
5605   return new DataArrayInt(*this);
5606 }
5607
5608 /*!
5609  * Returns either a \a deep or \a shallow copy of this array. For more info see
5610  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5611  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5612  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5613  *          == \a true) or \a this instance (if \a dCpy == \a false).
5614  */
5615 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const throw(INTERP_KERNEL::Exception)
5616 {
5617   if(dCpy)
5618     return deepCpy();
5619   else
5620     {
5621       incrRef();
5622       return const_cast<DataArrayInt *>(this);
5623     }
5624 }
5625
5626 /*!
5627  * Copies all the data from another DataArrayInt. For more info see
5628  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5629  *  \param [in] other - another instance of DataArrayInt to copy data from.
5630  *  \throw If the \a other is not allocated.
5631  */
5632 void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception)
5633 {
5634   other.checkAllocated();
5635   int nbOfTuples=other.getNumberOfTuples();
5636   int nbOfComp=other.getNumberOfComponents();
5637   allocIfNecessary(nbOfTuples,nbOfComp);
5638   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5639   int *pt=getPointer();
5640   const int *ptI=other.getConstPointer();
5641   for(std::size_t i=0;i<nbOfElems;i++)
5642     pt[i]=ptI[i];
5643   copyStringInfoFrom(other);
5644 }
5645
5646 /*!
5647  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5648  * 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.
5649  * If \a this has not already been allocated, number of components is set to one.
5650  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5651  * 
5652  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5653  */
5654 void DataArrayInt::reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception)
5655 {
5656   int nbCompo=getNumberOfComponents();
5657   if(nbCompo==1)
5658     {
5659       _mem.reserve(nbOfElems);
5660     }
5661   else if(nbCompo==0)
5662     {
5663       _mem.reserve(nbOfElems);
5664       _info_on_compo.resize(1);
5665     }
5666   else
5667     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5668 }
5669
5670 /*!
5671  * 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
5672  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5673  *
5674  * \param [in] val the value to be added in \a this
5675  * \throw If \a this has already been allocated with number of components different from one.
5676  * \sa DataArrayInt::pushBackValsSilent
5677  */
5678 void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception)
5679 {
5680   int nbCompo=getNumberOfComponents();
5681   if(nbCompo==1)
5682     _mem.pushBack(val);
5683   else if(nbCompo==0)
5684     {
5685       _info_on_compo.resize(1);
5686       _mem.pushBack(val);
5687     }
5688   else
5689     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5690 }
5691
5692 /*!
5693  * 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
5694  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5695  *
5696  *  \param [in] valsBg - an array of values to push at the end of \this.
5697  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5698  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5699  * \throw If \a this has already been allocated with number of components different from one.
5700  * \sa DataArrayInt::pushBackSilent
5701  */
5702 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd) throw(INTERP_KERNEL::Exception)
5703 {
5704   int nbCompo=getNumberOfComponents();
5705   if(nbCompo==1)
5706     _mem.insertAtTheEnd(valsBg,valsEnd);
5707   else if(nbCompo==0)
5708     {
5709       _info_on_compo.resize(1);
5710       _mem.insertAtTheEnd(valsBg,valsEnd);
5711     }
5712   else
5713     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5714 }
5715
5716 /*!
5717  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5718  * \throw If \a this is already empty.
5719  * \throw If \a this has number of components different from one.
5720  */
5721 int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception)
5722 {
5723   if(getNumberOfComponents()==1)
5724     return _mem.popBack();
5725   else
5726     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5727 }
5728
5729 /*!
5730  * 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.
5731  *
5732  * \sa DataArrayInt::getHeapMemorySize, DataArrayInt::reserve
5733  */
5734 void DataArrayInt::pack() const throw(INTERP_KERNEL::Exception)
5735 {
5736   _mem.pack();
5737 }
5738
5739 /*!
5740  * Allocates the raw data in memory. If exactly as same memory as needed already
5741  * allocated, it is not re-allocated.
5742  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5743  *  \param [in] nbOfCompo - number of components of data to allocate.
5744  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5745  */
5746 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5747 {
5748   if(isAllocated())
5749     {
5750       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5751         alloc(nbOfTuple,nbOfCompo);
5752     }
5753   else
5754     alloc(nbOfTuple,nbOfCompo);
5755 }
5756
5757 /*!
5758  * Allocates the raw data in memory. If the memory was already allocated, then it is
5759  * freed and re-allocated. See an example of this method use
5760  * \ref MEDCouplingArraySteps1WC "here".
5761  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5762  *  \param [in] nbOfCompo - number of components of data to allocate.
5763  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5764  */
5765 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
5766 {
5767   if(nbOfTuple<0 || nbOfCompo<0)
5768     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5769   _info_on_compo.resize(nbOfCompo);
5770   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
5771   declareAsNew();
5772 }
5773
5774 /*!
5775  * Assign zero to all values in \a this array. To know more on filling arrays see
5776  * \ref MEDCouplingArrayFill.
5777  * \throw If \a this is not allocated.
5778  */
5779 void DataArrayInt::fillWithZero() throw(INTERP_KERNEL::Exception)
5780 {
5781   checkAllocated();
5782   _mem.fillWithValue(0);
5783   declareAsNew();
5784 }
5785
5786 /*!
5787  * Assign \a val to all values in \a this array. To know more on filling arrays see
5788  * \ref MEDCouplingArrayFill.
5789  *  \param [in] val - the value to fill with.
5790  *  \throw If \a this is not allocated.
5791  */
5792 void DataArrayInt::fillWithValue(int val) throw(INTERP_KERNEL::Exception)
5793 {
5794   checkAllocated();
5795   _mem.fillWithValue(val);
5796   declareAsNew();
5797 }
5798
5799 /*!
5800  * Set all values in \a this array so that the i-th element equals to \a init + i
5801  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
5802  *  \param [in] init - value to assign to the first element of array.
5803  *  \throw If \a this->getNumberOfComponents() != 1
5804  *  \throw If \a this is not allocated.
5805  */
5806 void DataArrayInt::iota(int init) throw(INTERP_KERNEL::Exception)
5807 {
5808   checkAllocated();
5809   if(getNumberOfComponents()!=1)
5810     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
5811   int *ptr=getPointer();
5812   int ntuples=getNumberOfTuples();
5813   for(int i=0;i<ntuples;i++)
5814     ptr[i]=init+i;
5815   declareAsNew();
5816 }
5817
5818 /*!
5819  * Returns a textual and human readable representation of \a this instance of
5820  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
5821  *  \return std::string - text describing \a this DataArrayInt.
5822  */
5823 std::string DataArrayInt::repr() const throw(INTERP_KERNEL::Exception)
5824 {
5825   std::ostringstream ret;
5826   reprStream(ret);
5827   return ret.str();
5828 }
5829
5830 std::string DataArrayInt::reprZip() const throw(INTERP_KERNEL::Exception)
5831 {
5832   std::ostringstream ret;
5833   reprZipStream(ret);
5834   return ret.str();
5835 }
5836
5837 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
5838 {
5839   checkAllocated();
5840   std::string idt(indent,' ');
5841   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
5842   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
5843   std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
5844   ofs << std::endl << idt << "</DataArray>\n";
5845 }
5846
5847 void DataArrayInt::reprStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5848 {
5849   stream << "Name of int array : \"" << _name << "\"\n";
5850   reprWithoutNameStream(stream);
5851 }
5852
5853 void DataArrayInt::reprZipStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5854 {
5855   stream << "Name of int array : \"" << _name << "\"\n";
5856   reprZipWithoutNameStream(stream);
5857 }
5858
5859 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5860 {
5861   DataArray::reprWithoutNameStream(stream);
5862   _mem.repr(getNumberOfComponents(),stream);
5863 }
5864
5865 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5866 {
5867   DataArray::reprWithoutNameStream(stream);
5868   _mem.reprZip(getNumberOfComponents(),stream);
5869 }
5870
5871 void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5872 {
5873   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
5874   const int *data=getConstPointer();
5875   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
5876   if(nbTuples*nbComp>=1)
5877     {
5878       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
5879       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
5880       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
5881       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
5882     }
5883   else
5884     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
5885   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
5886 }
5887
5888 /*!
5889  * Method that gives a quick overvien of \a this for python.
5890  */
5891 void DataArrayInt::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
5892 {
5893   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
5894   stream << "DataArrayInt C++ instance at " << this << ". ";
5895   if(isAllocated())
5896     {
5897       int nbOfCompo=(int)_info_on_compo.size();
5898       if(nbOfCompo>=1)
5899         {
5900           int nbOfTuples=getNumberOfTuples();
5901           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
5902           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
5903         }
5904       else
5905         stream << "Number of components : 0.";
5906     }
5907   else
5908     stream << "*** No data allocated ****";
5909 }
5910
5911 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const throw(INTERP_KERNEL::Exception)
5912 {
5913   const int *data=begin();
5914   int nbOfTuples=getNumberOfTuples();
5915   int nbOfCompo=(int)_info_on_compo.size();
5916   std::ostringstream oss2; oss2 << "[";
5917   std::string oss2Str(oss2.str());
5918   bool isFinished=true;
5919   for(int i=0;i<nbOfTuples && isFinished;i++)
5920     {
5921       if(nbOfCompo>1)
5922         {
5923           oss2 << "(";
5924           for(int j=0;j<nbOfCompo;j++,data++)
5925             {
5926               oss2 << *data;
5927               if(j!=nbOfCompo-1) oss2 << ", ";
5928             }
5929           oss2 << ")";
5930         }
5931       else
5932         oss2 << *data++;
5933       if(i!=nbOfTuples-1) oss2 << ", ";
5934       std::string oss3Str(oss2.str());
5935       if(oss3Str.length()<maxNbOfByteInRepr)
5936         oss2Str=oss3Str;
5937       else
5938         isFinished=false;
5939     }
5940   stream << oss2Str;
5941   if(!isFinished)
5942     stream << "... ";
5943   stream << "]";
5944 }
5945
5946 /*!
5947  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
5948  * i.e. a current value is used as in index to get a new value from \a indArrBg.
5949  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
5950  *         to \a this array.
5951  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5952  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5953  *  \throw If \a this->getNumberOfComponents() != 1
5954  *  \throw If any value of \a this can't be used as a valid index for 
5955  *         [\a indArrBg, \a indArrEnd).
5956  */
5957 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception)
5958 {
5959   checkAllocated();
5960   if(getNumberOfComponents()!=1)
5961     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5962   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5963   int nbOfTuples=getNumberOfTuples();
5964   int *pt=getPointer();
5965   for(int i=0;i<nbOfTuples;i++,pt++)
5966     {
5967       if(*pt>=0 && *pt<nbElemsIn)
5968         *pt=indArrBg[*pt];
5969       else
5970         {
5971           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
5972           throw INTERP_KERNEL::Exception(oss.str().c_str());
5973         }
5974     }
5975   declareAsNew();
5976 }
5977
5978 /*!
5979  * Computes distribution of values of \a this one-dimensional array between given value
5980  * ranges (casts). This method is typically useful for entity number spliting by types,
5981  * for example. 
5982  *  \warning The values contained in \a arrBg should be sorted ascendently. No
5983  *           check of this is be done. If not, the result is not warranted. 
5984  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
5985  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
5986  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
5987  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
5988  *         should be more than every value in \a this array.
5989  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
5990  *              the last value of \a arrBg is \a arrEnd[ -1 ].
5991  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
5992  *         (same number of tuples and components), the caller is to delete 
5993  *         using decrRef() as it is no more needed.
5994  *         This array contains indices of ranges for every value of \a this array. I.e.
5995  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
5996  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
5997  *         this in which cast it holds.
5998  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
5999  *         array, the caller is to delete using decrRef() as it is no more needed.
6000  *         This array contains ranks of values of \a this array within ranges
6001  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6002  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6003  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6004  *         for each tuple its rank inside its cast. The rank is computed as difference
6005  *         between the value and the lowest value of range.
6006  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6007  *         ranges (casts) to which at least one value of \a this array belongs.
6008  *         Or, in other words, this param contains the casts that \a this contains.
6009  *         The caller is to delete this array using decrRef() as it is no more needed.
6010  *
6011  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6012  *            the output of this method will be : 
6013  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6014  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6015  * - \a castsPresent  : [0,1]
6016  *
6017  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6018  * range #1 and its rank within this range is 2; etc.
6019  *
6020  *  \throw If \a this->getNumberOfComponents() != 1.
6021  *  \throw If \a arrEnd - arrBg < 2.
6022  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6023  */
6024 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6025                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
6026 {
6027   checkAllocated();
6028   if(getNumberOfComponents()!=1)
6029     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6030   int nbOfTuples=getNumberOfTuples();
6031   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6032   if(nbOfCast<2)
6033     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6034   nbOfCast--;
6035   const int *work=getConstPointer();
6036   typedef std::reverse_iterator<const int *> rintstart;
6037   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6038   rintstart end2(arrBg);
6039   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6040   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6041   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6042   ret1->alloc(nbOfTuples,1);
6043   ret2->alloc(nbOfTuples,1);
6044   int *ret1Ptr=ret1->getPointer();
6045   int *ret2Ptr=ret2->getPointer();
6046   std::set<std::size_t> castsDetected;
6047   for(int i=0;i<nbOfTuples;i++)
6048     {
6049       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6050       std::size_t pos=std::distance(bg,res);
6051       std::size_t pos2=nbOfCast-pos;
6052       if(pos2<nbOfCast)
6053         {
6054           ret1Ptr[i]=(int)pos2;
6055           ret2Ptr[i]=work[i]-arrBg[pos2];
6056           castsDetected.insert(pos2);
6057         }
6058       else
6059         {
6060           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6061           throw INTERP_KERNEL::Exception(oss.str().c_str());
6062         }
6063     }
6064   ret3->alloc((int)castsDetected.size(),1);
6065   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6066   castArr=ret1.retn();
6067   rankInsideCast=ret2.retn();
6068   castsPresent=ret3.retn();
6069 }
6070
6071 /*!
6072  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6073  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6074  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6075  * new value in place \a indArr[ \a v ] is i.
6076  *  \param [in] indArrBg - the array holding indices within the result array to assign
6077  *         indices of values of \a this array pointing to values of \a indArrBg.
6078  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6079  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6080  *  \return DataArrayInt * - the new instance of DataArrayInt.
6081  *          The caller is to delete this result array using decrRef() as it is no more
6082  *          needed.
6083  *  \throw If \a this->getNumberOfComponents() != 1.
6084  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6085  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6086  */
6087 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception)
6088 {
6089   checkAllocated();
6090   if(getNumberOfComponents()!=1)
6091     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6092   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6093   int nbOfTuples=getNumberOfTuples();
6094   const int *pt=getConstPointer();
6095   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6096   ret->alloc(nbOfTuples,1);
6097   ret->fillWithValue(-1);
6098   int *tmp=ret->getPointer();
6099   for(int i=0;i<nbOfTuples;i++,pt++)
6100     {
6101       if(*pt>=0 && *pt<nbElemsIn)
6102         {
6103           int pos=indArrBg[*pt];
6104           if(pos>=0 && pos<nbOfTuples)
6105             tmp[pos]=i;
6106           else
6107             {
6108               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6109               throw INTERP_KERNEL::Exception(oss.str().c_str());
6110             }
6111         }
6112       else
6113         {
6114           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6115           throw INTERP_KERNEL::Exception(oss.str().c_str());
6116         }
6117     }
6118   return ret.retn();
6119 }
6120
6121 /*!
6122  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6123  * from values of \a this array, which is supposed to contain a renumbering map in 
6124  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6125  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6126  *  \param [in] newNbOfElem - the number of tuples in the result array.
6127  *  \return DataArrayInt * - the new instance of DataArrayInt.
6128  *          The caller is to delete this result array using decrRef() as it is no more
6129  *          needed.
6130  * 
6131  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6132  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6133  */
6134 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6135 {
6136   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6137   ret->alloc(newNbOfElem,1);
6138   int nbOfOldNodes=getNumberOfTuples();
6139   const int *old2New=getConstPointer();
6140   int *pt=ret->getPointer();
6141   for(int i=0;i!=nbOfOldNodes;i++)
6142     if(old2New[i]!=-1)
6143       pt[old2New[i]]=i;
6144   return ret.retn();
6145 }
6146
6147 /*!
6148  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6149  * 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]
6150  */
6151 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception)
6152 {
6153   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6154   ret->alloc(newNbOfElem,1);
6155   int nbOfOldNodes=getNumberOfTuples();
6156   const int *old2New=getConstPointer();
6157   int *pt=ret->getPointer();
6158   for(int i=nbOfOldNodes-1;i>=0;i--)
6159     if(old2New[i]!=-1)
6160       pt[old2New[i]]=i;
6161   return ret.retn();
6162 }
6163
6164 /*!
6165  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6166  * from values of \a this array, which is supposed to contain a renumbering map in 
6167  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6168  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6169  *  \param [in] newNbOfElem - the number of tuples in the result array.
6170  *  \return DataArrayInt * - the new instance of DataArrayInt.
6171  *          The caller is to delete this result array using decrRef() as it is no more
6172  *          needed.
6173  * 
6174  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6175  *
6176  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6177  */
6178 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6179 {
6180   checkAllocated();
6181   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6182   ret->alloc(oldNbOfElem,1);
6183   const int *new2Old=getConstPointer();
6184   int *pt=ret->getPointer();
6185   std::fill(pt,pt+oldNbOfElem,-1);
6186   int nbOfNewElems=getNumberOfTuples();
6187   for(int i=0;i<nbOfNewElems;i++)
6188     {
6189       int v(new2Old[i]);
6190       if(v>=0 && v<oldNbOfElem)
6191          pt[v]=i;
6192       else
6193         {
6194           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6195           throw INTERP_KERNEL::Exception(oss.str().c_str());
6196         }
6197     }
6198   return ret.retn();
6199 }
6200
6201 /*!
6202  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6203  * mismatch is given.
6204  * 
6205  * \param [in] other the instance to be compared with \a this
6206  * \param [out] reason In case of inequality returns the reason.
6207  * \sa DataArrayInt::isEqual
6208  */
6209 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const throw(INTERP_KERNEL::Exception)
6210 {
6211   if(!areInfoEqualsIfNotWhy(other,reason))
6212     return false;
6213   return _mem.isEqual(other._mem,0,reason);
6214 }
6215
6216 /*!
6217  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6218  * \ref MEDCouplingArrayBasicsCompare.
6219  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6220  *  \return bool - \a true if the two arrays are equal, \a false else.
6221  */
6222 bool DataArrayInt::isEqual(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6223 {
6224   std::string tmp;
6225   return isEqualIfNotWhy(other,tmp);
6226 }
6227
6228 /*!
6229  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6230  * \ref MEDCouplingArrayBasicsCompare.
6231  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6232  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6233  */
6234 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6235 {
6236   std::string tmp;
6237   return _mem.isEqual(other._mem,0,tmp);
6238 }
6239
6240 /*!
6241  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6242  * performed on sorted value sequences.
6243  * For more info see\ref MEDCouplingArrayBasicsCompare.
6244  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6245  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6246  */
6247 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6248 {
6249   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6250   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6251   a->sort();
6252   b->sort();
6253   return a->isEqualWithoutConsideringStr(*b);
6254 }
6255
6256 /*!
6257  * This method compares content of input vector \a v and \a this.
6258  * 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.
6259  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6260  *
6261  * \param [in] v - the vector of 'flags' to be compared with \a this.
6262  *
6263  * \throw If \a this is not sorted ascendingly.
6264  * \throw If \a this has not exactly one component.
6265  * \throw If \a this is not allocated.
6266  */
6267 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const throw(INTERP_KERNEL::Exception)
6268 {
6269   checkAllocated();
6270   if(getNumberOfComponents()!=1)
6271     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6272   int nbOfTuples(getNumberOfTuples());
6273   const int *w(begin()),*end2(end());
6274   int refVal=-std::numeric_limits<int>::max();
6275   int i=0;
6276   std::vector<bool>::const_iterator it(v.begin());
6277   for(;it!=v.end();it++,i++)
6278     {
6279       if(*it)
6280         {
6281           if(w!=end2)
6282             {
6283               if(*w++==i)
6284                 {
6285                   if(i>refVal)
6286                     refVal=i;
6287                   else
6288                     {
6289                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6290                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6291                     }
6292                 }
6293               else
6294                 return false;
6295             }
6296           else
6297             return false;
6298         }
6299     }
6300   return w==end2;
6301 }
6302
6303 /*!
6304  * Sorts values of the array.
6305  *  \param [in] asc - \a true means ascending order, \a false, descending.
6306  *  \throw If \a this is not allocated.
6307  *  \throw If \a this->getNumberOfComponents() != 1.
6308  */
6309 void DataArrayInt::sort(bool asc) throw(INTERP_KERNEL::Exception)
6310 {
6311   checkAllocated();
6312   if(getNumberOfComponents()!=1)
6313     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6314   _mem.sort(asc);
6315   declareAsNew();
6316 }
6317
6318 /*!
6319  * Reverse the array values.
6320  *  \throw If \a this->getNumberOfComponents() < 1.
6321  *  \throw If \a this is not allocated.
6322  */
6323 void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
6324 {
6325   checkAllocated();
6326   _mem.reverse(getNumberOfComponents());
6327   declareAsNew();
6328 }
6329
6330 /*!
6331  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6332  * If not an exception is thrown.
6333  *  \param [in] increasing - if \a true, the array values should be increasing.
6334  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6335  *         increasing arg.
6336  *  \throw If \a this->getNumberOfComponents() != 1.
6337  *  \throw If \a this is not allocated.
6338  */
6339 void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6340 {
6341   if(!isMonotonic(increasing))
6342     {
6343       if (increasing)
6344         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6345       else
6346         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6347     }
6348 }
6349
6350 /*!
6351  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6352  *  \param [in] increasing - if \a true, array values should be increasing.
6353  *  \return bool - \a true if values change in accordance with \a increasing arg.
6354  *  \throw If \a this->getNumberOfComponents() != 1.
6355  *  \throw If \a this is not allocated.
6356  */
6357 bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6358 {
6359   checkAllocated();
6360   if(getNumberOfComponents()!=1)
6361     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6362   int nbOfElements=getNumberOfTuples();
6363   const int *ptr=getConstPointer();
6364   if(nbOfElements==0)
6365     return true;
6366   int ref=ptr[0];
6367   if(increasing)
6368     {
6369       for(int i=1;i<nbOfElements;i++)
6370         {
6371           if(ptr[i]>=ref)
6372             ref=ptr[i];
6373           else
6374             return false;
6375         }
6376     }
6377   else
6378     {
6379       for(int i=1;i<nbOfElements;i++)
6380         {
6381           if(ptr[i]<=ref)
6382             ref=ptr[i];
6383           else
6384             return false;
6385         }
6386     }
6387   return true;
6388 }
6389
6390 /*!
6391  * This method check that array consistently INCREASING or DECREASING in value.
6392  */
6393 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6394 {
6395   checkAllocated();
6396   if(getNumberOfComponents()!=1)
6397     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6398   int nbOfElements=getNumberOfTuples();
6399   const int *ptr=getConstPointer();
6400   if(nbOfElements==0)
6401     return true;
6402   int ref=ptr[0];
6403   if(increasing)
6404     {
6405       for(int i=1;i<nbOfElements;i++)
6406         {
6407           if(ptr[i]>ref)
6408             ref=ptr[i];
6409           else
6410             return false;
6411         }
6412     }
6413   else
6414     {
6415       for(int i=1;i<nbOfElements;i++)
6416         {
6417           if(ptr[i]<ref)
6418             ref=ptr[i];
6419           else
6420             return false;
6421         }
6422     }
6423   return true;
6424 }
6425
6426 /*!
6427  * This method check that array consistently INCREASING or DECREASING in value.
6428  */
6429 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
6430 {
6431   if(!isStrictlyMonotonic(increasing))
6432     {
6433       if (increasing)
6434         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6435       else
6436         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6437     }
6438 }
6439
6440 /*!
6441  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6442  * one-dimensional arrays that must be of the same length. The result array describes
6443  * correspondence between \a this and \a other arrays, so that 
6444  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6445  * not possible because some element in \a other is not in \a this, an exception is thrown.
6446  *  \param [in] other - an array to compute permutation to.
6447  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6448  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6449  * no more needed.
6450  *  \throw If \a this->getNumberOfComponents() != 1.
6451  *  \throw If \a other->getNumberOfComponents() != 1.
6452  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6453  *  \throw If \a other includes a value which is not in \a this array.
6454  * 
6455  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6456  *
6457  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6458  */
6459 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
6460 {
6461   checkAllocated();
6462   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6463     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6464   int nbTuple=getNumberOfTuples();
6465   other.checkAllocated();
6466   if(nbTuple!=other.getNumberOfTuples())
6467     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6468   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6469   ret->alloc(nbTuple,1);
6470   ret->fillWithValue(-1);
6471   const int *pt=getConstPointer();
6472   std::map<int,int> mm;
6473   for(int i=0;i<nbTuple;i++)
6474     mm[pt[i]]=i;
6475   pt=other.getConstPointer();
6476   int *retToFill=ret->getPointer();
6477   for(int i=0;i<nbTuple;i++)
6478     {
6479       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6480       if(it==mm.end())
6481         {
6482           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6483           throw INTERP_KERNEL::Exception(oss.str().c_str());
6484         }
6485       retToFill[i]=(*it).second;
6486     }
6487   return ret.retn();
6488 }
6489
6490 /*!
6491  * Sets a C array to be used as raw data of \a this. The previously set info
6492  *  of components is retained and re-sized. 
6493  * For more info see \ref MEDCouplingArraySteps1.
6494  *  \param [in] array - the C array to be used as raw data of \a this.
6495  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6496  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6497  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6498  *                     \c free(\c array ) will be called.
6499  *  \param [in] nbOfTuple - new number of tuples in \a this.
6500  *  \param [in] nbOfCompo - new number of components in \a this.
6501  */
6502 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6503 {
6504   _info_on_compo.resize(nbOfCompo);
6505   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6506   declareAsNew();
6507 }
6508
6509 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
6510 {
6511   _info_on_compo.resize(nbOfCompo);
6512   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6513   declareAsNew();
6514 }
6515
6516 /*!
6517  * Returns a new DataArrayInt holding the same values as \a this array but differently
6518  * arranged in memory. If \a this array holds 2 components of 3 values:
6519  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6520  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6521  *  \warning Do not confuse this method with transpose()!
6522  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6523  *          is to delete using decrRef() as it is no more needed.
6524  *  \throw If \a this is not allocated.
6525  */
6526 DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
6527 {
6528   checkAllocated();
6529   if(_mem.isNull())
6530     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6531   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6532   DataArrayInt *ret=DataArrayInt::New();
6533   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6534   return ret;
6535 }
6536
6537 /*!
6538  * Returns a new DataArrayInt holding the same values as \a this array but differently
6539  * arranged in memory. If \a this array holds 2 components of 3 values:
6540  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6541  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6542  *  \warning Do not confuse this method with transpose()!
6543  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6544  *          is to delete using decrRef() as it is no more needed.
6545  *  \throw If \a this is not allocated.
6546  */
6547 DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception)
6548 {
6549   checkAllocated();
6550   if(_mem.isNull())
6551     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6552   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6553   DataArrayInt *ret=DataArrayInt::New();
6554   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6555   return ret;
6556 }
6557
6558 /*!
6559  * Permutes values of \a this array as required by \a old2New array. The values are
6560  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6561  * the same as in \this one.
6562  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6563  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6564  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6565  *     giving a new position for i-th old value.
6566  */
6567 void DataArrayInt::renumberInPlace(const int *old2New) throw(INTERP_KERNEL::Exception)
6568 {
6569   checkAllocated();
6570   int nbTuples=getNumberOfTuples();
6571   int nbOfCompo=getNumberOfComponents();
6572   int *tmp=new int[nbTuples*nbOfCompo];
6573   const int *iptr=getConstPointer();
6574   for(int i=0;i<nbTuples;i++)
6575     {
6576       int v=old2New[i];
6577       if(v>=0 && v<nbTuples)
6578         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6579       else
6580         {
6581           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6582           throw INTERP_KERNEL::Exception(oss.str().c_str());
6583         }
6584     }
6585   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6586   delete [] tmp;
6587   declareAsNew();
6588 }
6589
6590 /*!
6591  * Permutes values of \a this array as required by \a new2Old array. The values are
6592  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6593  * the same as in \this one.
6594  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6595  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6596  *     giving a previous position of i-th new value.
6597  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6598  *          is to delete using decrRef() as it is no more needed.
6599  */
6600 void DataArrayInt::renumberInPlaceR(const int *new2Old) throw(INTERP_KERNEL::Exception)
6601 {
6602   checkAllocated();
6603   int nbTuples=getNumberOfTuples();
6604   int nbOfCompo=getNumberOfComponents();
6605   int *tmp=new int[nbTuples*nbOfCompo];
6606   const int *iptr=getConstPointer();
6607   for(int i=0;i<nbTuples;i++)
6608     {
6609       int v=new2Old[i];
6610       if(v>=0 && v<nbTuples)
6611         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6612       else
6613         {
6614           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6615           throw INTERP_KERNEL::Exception(oss.str().c_str());
6616         }
6617     }
6618   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6619   delete [] tmp;
6620   declareAsNew();
6621 }
6622
6623 /*!
6624  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6625  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6626  * Number of tuples in the result array remains the same as in \this one.
6627  * If a permutation reduction is needed, renumberAndReduce() should be used.
6628  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6629  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6630  *          giving a new position for i-th old value.
6631  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6632  *          is to delete using decrRef() as it is no more needed.
6633  *  \throw If \a this is not allocated.
6634  */
6635 DataArrayInt *DataArrayInt::renumber(const int *old2New) const throw(INTERP_KERNEL::Exception)
6636 {
6637   checkAllocated();
6638   int nbTuples=getNumberOfTuples();
6639   int nbOfCompo=getNumberOfComponents();
6640   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6641   ret->alloc(nbTuples,nbOfCompo);
6642   ret->copyStringInfoFrom(*this);
6643   const int *iptr=getConstPointer();
6644   int *optr=ret->getPointer();
6645   for(int i=0;i<nbTuples;i++)
6646     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6647   ret->copyStringInfoFrom(*this);
6648   return ret.retn();
6649 }
6650
6651 /*!
6652  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6653  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6654  * tuples in the result array remains the same as in \this one.
6655  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6656  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6657  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6658  *     giving a previous position of i-th new value.
6659  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6660  *          is to delete using decrRef() as it is no more needed.
6661  */
6662 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception)
6663 {
6664   checkAllocated();
6665   int nbTuples=getNumberOfTuples();
6666   int nbOfCompo=getNumberOfComponents();
6667   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6668   ret->alloc(nbTuples,nbOfCompo);
6669   ret->copyStringInfoFrom(*this);
6670   const int *iptr=getConstPointer();
6671   int *optr=ret->getPointer();
6672   for(int i=0;i<nbTuples;i++)
6673     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6674   ret->copyStringInfoFrom(*this);
6675   return ret.retn();
6676 }
6677
6678 /*!
6679  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6680  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6681  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6682  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6683  * \a old2New[ i ] is negative, is missing from the result array.
6684  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6685  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6686  *     giving a new position for i-th old tuple and giving negative position for
6687  *     for i-th old tuple that should be omitted.
6688  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6689  *          is to delete using decrRef() as it is no more needed.
6690  */
6691 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const throw(INTERP_KERNEL::Exception)
6692 {
6693   checkAllocated();
6694   int nbTuples=getNumberOfTuples();
6695   int nbOfCompo=getNumberOfComponents();
6696   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6697   ret->alloc(newNbOfTuple,nbOfCompo);
6698   const int *iptr=getConstPointer();
6699   int *optr=ret->getPointer();
6700   for(int i=0;i<nbTuples;i++)
6701     {
6702       int w=old2New[i];
6703       if(w>=0)
6704         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
6705     }
6706   ret->copyStringInfoFrom(*this);
6707   return ret.retn();
6708 }
6709
6710 /*!
6711  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6712  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6713  * \a new2OldBg array.
6714  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6715  * This method is equivalent to renumberAndReduce() except that convention in input is
6716  * \c new2old and \b not \c old2new.
6717  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6718  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6719  *              tuple index in \a this array to fill the i-th tuple in the new array.
6720  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6721  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6722  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6723  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6724  *          is to delete using decrRef() as it is no more needed.
6725  */
6726 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
6727 {
6728   checkAllocated();
6729   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6730   int nbComp=getNumberOfComponents();
6731   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6732   ret->copyStringInfoFrom(*this);
6733   int *pt=ret->getPointer();
6734   const int *srcPt=getConstPointer();
6735   int i=0;
6736   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6737     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6738   ret->copyStringInfoFrom(*this);
6739   return ret.retn();
6740 }
6741
6742 /*!
6743  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6744  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
6745  * \a new2OldBg array.
6746  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
6747  * This method is equivalent to renumberAndReduce() except that convention in input is
6748  * \c new2old and \b not \c old2new.
6749  * This method is equivalent to selectByTupleId() except that it prevents coping data
6750  * from behind the end of \a this array.
6751  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6752  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
6753  *              tuple index in \a this array to fill the i-th tuple in the new array.
6754  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
6755  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
6756  *              \a new2OldBg <= \a pi < \a new2OldEnd.
6757  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6758  *          is to delete using decrRef() as it is no more needed.
6759  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
6760  */
6761 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
6762 {
6763   checkAllocated();
6764   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6765   int nbComp=getNumberOfComponents();
6766   int oldNbOfTuples=getNumberOfTuples();
6767   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
6768   ret->copyStringInfoFrom(*this);
6769   int *pt=ret->getPointer();
6770   const int *srcPt=getConstPointer();
6771   int i=0;
6772   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
6773     if(*w>=0 && *w<oldNbOfTuples)
6774       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
6775     else
6776       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
6777   ret->copyStringInfoFrom(*this);
6778   return ret.retn();
6779 }
6780
6781 /*!
6782  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
6783  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
6784  * tuple. Indices of the selected tuples are the same as ones returned by the Python
6785  * command \c range( \a bg, \a end2, \a step ).
6786  * This method is equivalent to selectByTupleIdSafe() except that the input array is
6787  * not constructed explicitly.
6788  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6789  *  \param [in] bg - index of the first tuple to copy from \a this array.
6790  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
6791  *  \param [in] step - index increment to get index of the next tuple to copy.
6792  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6793  *          is to delete using decrRef() as it is no more needed.
6794  *  \sa DataArrayInt::substr.
6795  */
6796 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
6797 {
6798   checkAllocated();
6799   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6800   int nbComp=getNumberOfComponents();
6801   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
6802   ret->alloc(newNbOfTuples,nbComp);
6803   int *pt=ret->getPointer();
6804   const int *srcPt=getConstPointer()+bg*nbComp;
6805   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
6806     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
6807   ret->copyStringInfoFrom(*this);
6808   return ret.retn();
6809 }
6810
6811 /*!
6812  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
6813  * of tuples specified by \a ranges parameter.
6814  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6815  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
6816  *              of tuples in [\c begin,\c end) format.
6817  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6818  *          is to delete using decrRef() as it is no more needed.
6819  *  \throw If \a end < \a begin.
6820  *  \throw If \a end > \a this->getNumberOfTuples().
6821  *  \throw If \a this is not allocated.
6822  */
6823 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception)
6824 {
6825   checkAllocated();
6826   int nbOfComp=getNumberOfComponents();
6827   int nbOfTuplesThis=getNumberOfTuples();
6828   if(ranges.empty())
6829     {
6830       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6831       ret->alloc(0,nbOfComp);
6832       ret->copyStringInfoFrom(*this);
6833       return ret.retn();
6834     }
6835   int ref=ranges.front().first;
6836   int nbOfTuples=0;
6837   bool isIncreasing=true;
6838   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6839     {
6840       if((*it).first<=(*it).second)
6841         {
6842           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
6843             {
6844               nbOfTuples+=(*it).second-(*it).first;
6845               if(isIncreasing)
6846                 isIncreasing=ref<=(*it).first;
6847               ref=(*it).second;
6848             }
6849           else
6850             {
6851               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6852               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
6853               throw INTERP_KERNEL::Exception(oss.str().c_str());
6854             }
6855         }
6856       else
6857         {
6858           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
6859           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
6860           throw INTERP_KERNEL::Exception(oss.str().c_str());
6861         }
6862     }
6863   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
6864     return deepCpy();
6865   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6866   ret->alloc(nbOfTuples,nbOfComp);
6867   ret->copyStringInfoFrom(*this);
6868   const int *src=getConstPointer();
6869   int *work=ret->getPointer();
6870   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
6871     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
6872   return ret.retn();
6873 }
6874
6875 /*!
6876  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
6877  * This map, if applied to \a this array, would make it sorted. For example, if
6878  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
6879  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
6880  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
6881  * This method is useful for renumbering (in MED file for example). For more info
6882  * on renumbering see \ref MEDCouplingArrayRenumbering.
6883  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6884  *          array using decrRef() as it is no more needed.
6885  *  \throw If \a this is not allocated.
6886  *  \throw If \a this->getNumberOfComponents() != 1.
6887  *  \throw If there are equal values in \a this array.
6888  */
6889 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception)
6890 {
6891   checkAllocated();
6892   if(getNumberOfComponents()!=1)
6893     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
6894   int nbTuples=getNumberOfTuples();
6895   const int *pt=getConstPointer();
6896   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
6897   DataArrayInt *ret=DataArrayInt::New();
6898   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
6899   return ret;
6900 }
6901
6902 /*!
6903  * 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
6904  * input array \a ids2.
6905  * \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.
6906  * 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
6907  * inversely.
6908  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
6909  *
6910  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6911  *          array using decrRef() as it is no more needed.
6912  * \throw If either ids1 or ids2 is null not allocated or not with one components.
6913  * 
6914  */
6915 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2) throw(INTERP_KERNEL::Exception)
6916 {
6917   if(!ids1 || !ids2)
6918     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
6919   if(!ids1->isAllocated() || !ids2->isAllocated())
6920     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
6921   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
6922     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
6923   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
6924     {
6925       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 !";
6926       throw INTERP_KERNEL::Exception(oss.str().c_str());
6927     }
6928   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
6929   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
6930   p1->sort(true); p2->sort(true);
6931   if(!p1->isEqualWithoutConsideringStr(*p2))
6932     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
6933   p1=ids1->checkAndPreparePermutation();
6934   p2=ids2->checkAndPreparePermutation();
6935   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
6936   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
6937   return p2.retn();
6938 }
6939
6940 /*!
6941  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
6942  * onto a set of values of size \a targetNb (\a B). The surjective function is 
6943  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
6944  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
6945  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
6946  * The first of out arrays returns indices of elements of \a this array, grouped by their
6947  * place in the set \a B. The second out array is the index of the first one; it shows how
6948  * many elements of \a A are mapped into each element of \a B. <br>
6949  * For more info on
6950  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
6951  * \b Example:
6952  * - \a this: [0,3,2,3,2,2,1,2]
6953  * - \a targetNb: 4
6954  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
6955  * - \a arrI: [0,1,2,6,8]
6956  *
6957  * This result means: <br>
6958  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
6959  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
6960  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
6961  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
6962  * \a arrI[ 2+1 ]]); <br> etc.
6963  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
6964  *         than the maximal value of \a A.
6965  *  \param [out] arr - a new instance of DataArrayInt returning indices of
6966  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
6967  *         this array using decrRef() as it is no more needed.
6968  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
6969  *         elements of \a this. The caller is to delete this array using decrRef() as it
6970  *         is no more needed.
6971  *  \throw If \a this is not allocated.
6972  *  \throw If \a this->getNumberOfComponents() != 1.
6973  *  \throw If any value in \a this is more or equal to \a targetNb.
6974  */
6975 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception)
6976 {
6977   checkAllocated();
6978   if(getNumberOfComponents()!=1)
6979     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
6980   int nbOfTuples=getNumberOfTuples();
6981   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6982   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
6983   retI->alloc(targetNb+1,1);
6984   const int *input=getConstPointer();
6985   std::vector< std::vector<int> > tmp(targetNb);
6986   for(int i=0;i<nbOfTuples;i++)
6987     {
6988       int tmp2=input[i];
6989       if(tmp2>=0 && tmp2<targetNb)
6990         tmp[tmp2].push_back(i);
6991       else
6992         {
6993           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
6994           throw INTERP_KERNEL::Exception(oss.str().c_str());
6995         }
6996     }
6997   int *retIPtr=retI->getPointer();
6998   *retIPtr=0;
6999   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7000     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7001   if(nbOfTuples!=retI->getIJ(targetNb,0))
7002     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7003   ret->alloc(nbOfTuples,1);
7004   int *retPtr=ret->getPointer();
7005   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7006     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7007   arr=ret.retn();
7008   arrI=retI.retn();
7009 }
7010
7011
7012 /*!
7013  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7014  * from a zip representation of a surjective format (returned e.g. by
7015  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7016  * for example). The result array minimizes the permutation. <br>
7017  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7018  * \b Example: <br>
7019  * - \a nbOfOldTuples: 10 
7020  * - \a arr          : [0,3, 5,7,9]
7021  * - \a arrIBg       : [0,2,5]
7022  * - \a newNbOfTuples: 7
7023  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7024  *
7025  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7026  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7027  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7028  *         (indices of) equal values. Its every element (except the last one) points to
7029  *         the first element of a group of equal values.
7030  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7031  *          arrIBg is \a arrIEnd[ -1 ].
7032  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7033  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7034  *          array using decrRef() as it is no more needed.
7035  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7036  */
7037 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
7038 {
7039   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7040   ret->alloc(nbOfOldTuples,1);
7041   int *pt=ret->getPointer();
7042   std::fill(pt,pt+nbOfOldTuples,-1);
7043   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7044   const int *cIPtr=arrIBg;
7045   for(int i=0;i<nbOfGrps;i++)
7046     pt[arr[cIPtr[i]]]=-(i+2);
7047   int newNb=0;
7048   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7049     {
7050       if(pt[iNode]<0)
7051         {
7052           if(pt[iNode]==-1)
7053             pt[iNode]=newNb++;
7054           else
7055             {
7056               int grpId=-(pt[iNode]+2);
7057               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7058                 {
7059                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7060                     pt[arr[j]]=newNb;
7061                   else
7062                     {
7063                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7064                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7065                     }
7066                 }
7067               newNb++;
7068             }
7069         }
7070     }
7071   newNbOfTuples=newNb;
7072   return ret.retn();
7073 }
7074
7075 /*!
7076  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7077  * which if applied to \a this array would make it sorted ascendingly.
7078  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7079  * \b Example: <br>
7080  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7081  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7082  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7083  *
7084  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7085  *          array using decrRef() as it is no more needed.
7086  *  \throw If \a this is not allocated.
7087  *  \throw If \a this->getNumberOfComponents() != 1.
7088  */
7089 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception)
7090 {
7091   checkAllocated();
7092   if(getNumberOfComponents()!=1)
7093     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7094   int nbOfTuples=getNumberOfTuples();
7095   const int *pt=getConstPointer();
7096   std::map<int,int> m;
7097   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7098   ret->alloc(nbOfTuples,1);
7099   int *opt=ret->getPointer();
7100   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7101     {
7102       int val=*pt;
7103       std::map<int,int>::iterator it=m.find(val);
7104       if(it!=m.end())
7105         {
7106           *opt=(*it).second;
7107           (*it).second++;
7108         }
7109       else
7110         {
7111           *opt=0;
7112           m.insert(std::pair<int,int>(val,1));
7113         }
7114     }
7115   int sum=0;
7116   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7117     {
7118       int vt=(*it).second;
7119       (*it).second=sum;
7120       sum+=vt;
7121     }
7122   pt=getConstPointer();
7123   opt=ret->getPointer();
7124   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7125     *opt+=m[*pt];
7126   //
7127   return ret.retn();
7128 }
7129
7130 /*!
7131  * Checks if contents of \a this array are equal to that of an array filled with
7132  * iota(). This method is particularly useful for DataArrayInt instances that represent
7133  * a renumbering array to check the real need in renumbering. 
7134  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7135  *  \throw If \a this is not allocated.
7136  *  \throw If \a this->getNumberOfComponents() != 1.
7137  */
7138 bool DataArrayInt::isIdentity() const throw(INTERP_KERNEL::Exception)
7139 {
7140   checkAllocated();
7141   if(getNumberOfComponents()!=1)
7142     return false;
7143   int nbOfTuples=getNumberOfTuples();
7144   const int *pt=getConstPointer();
7145   for(int i=0;i<nbOfTuples;i++,pt++)
7146     if(*pt!=i)
7147       return false;
7148   return true;
7149 }
7150
7151 /*!
7152  * Checks if all values in \a this array are equal to \a val.
7153  *  \param [in] val - value to check equality of array values to.
7154  *  \return bool - \a true if all values are \a val.
7155  *  \throw If \a this is not allocated.
7156  *  \throw If \a this->getNumberOfComponents() != 1
7157  */
7158 bool DataArrayInt::isUniform(int val) const throw(INTERP_KERNEL::Exception)
7159 {
7160   checkAllocated();
7161   if(getNumberOfComponents()!=1)
7162     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7163   int nbOfTuples=getNumberOfTuples();
7164   const int *w=getConstPointer();
7165   const int *end2=w+nbOfTuples;
7166   for(;w!=end2;w++)
7167     if(*w!=val)
7168       return false;
7169   return true;
7170 }
7171
7172 /*!
7173  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7174  * array to the new one.
7175  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7176  */
7177 DataArrayDouble *DataArrayInt::convertToDblArr() const
7178 {
7179   checkAllocated();
7180   DataArrayDouble *ret=DataArrayDouble::New();
7181   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7182   std::size_t nbOfVals=getNbOfElems();
7183   const int *src=getConstPointer();
7184   double *dest=ret->getPointer();
7185   std::copy(src,src+nbOfVals,dest);
7186   ret->copyStringInfoFrom(*this);
7187   return ret;
7188 }
7189
7190 /*!
7191  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7192  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7193  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7194  * This method is a specialization of selectByTupleId2().
7195  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7196  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7197  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7198  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7199  *          is to delete using decrRef() as it is no more needed.
7200  *  \throw If \a tupleIdBg < 0.
7201  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7202     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7203  *  \sa DataArrayInt::selectByTupleId2
7204  */
7205 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
7206 {
7207   checkAllocated();
7208   int nbt=getNumberOfTuples();
7209   if(tupleIdBg<0)
7210     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7211   if(tupleIdBg>nbt)
7212     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7213   int trueEnd=tupleIdEnd;
7214   if(tupleIdEnd!=-1)
7215     {
7216       if(tupleIdEnd>nbt)
7217         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7218     }
7219   else
7220     trueEnd=nbt;
7221   int nbComp=getNumberOfComponents();
7222   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7223   ret->alloc(trueEnd-tupleIdBg,nbComp);
7224   ret->copyStringInfoFrom(*this);
7225   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7226   return ret.retn();
7227 }
7228
7229 /*!
7230  * Changes the number of components within \a this array so that its raw data **does
7231  * not** change, instead splitting this data into tuples changes.
7232  *  \warning This method erases all (name and unit) component info set before!
7233  *  \param [in] newNbOfComp - number of components for \a this array to have.
7234  *  \throw If \a this is not allocated
7235  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7236  *  \throw If \a newNbOfCompo is lower than 1.
7237  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7238  *  \warning This method erases all (name and unit) component info set before!
7239  */
7240 void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
7241 {
7242   checkAllocated();
7243   if(newNbOfCompo<1)
7244     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7245   std::size_t nbOfElems=getNbOfElems();
7246   if(nbOfElems%newNbOfCompo!=0)
7247     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7248   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7249     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7250   _info_on_compo.clear();
7251   _info_on_compo.resize(newNbOfCompo);
7252   declareAsNew();
7253 }
7254
7255 /*!
7256  * Changes the number of components within \a this array to be equal to its number
7257  * of tuples, and inversely its number of tuples to become equal to its number of 
7258  * components. So that its raw data **does not** change, instead splitting this
7259  * data into tuples changes.
7260  *  \warning This method erases all (name and unit) component info set before!
7261  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7262  *  \throw If \a this is not allocated.
7263  *  \sa rearrange()
7264  */
7265 void DataArrayInt::transpose() throw(INTERP_KERNEL::Exception)
7266 {
7267   checkAllocated();
7268   int nbOfTuples=getNumberOfTuples();
7269   rearrange(nbOfTuples);
7270 }
7271
7272 /*!
7273  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7274  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7275  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7276  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7277  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7278  * components.  
7279  *  \param [in] newNbOfComp - number of components for the new array to have.
7280  *  \param [in] dftValue - value assigned to new values added to the new array.
7281  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7282  *          is to delete using decrRef() as it is no more needed.
7283  *  \throw If \a this is not allocated.
7284  */
7285 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception)
7286 {
7287   checkAllocated();
7288   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7289   ret->alloc(getNumberOfTuples(),newNbOfComp);
7290   const int *oldc=getConstPointer();
7291   int *nc=ret->getPointer();
7292   int nbOfTuples=getNumberOfTuples();
7293   int oldNbOfComp=getNumberOfComponents();
7294   int dim=std::min(oldNbOfComp,newNbOfComp);
7295   for(int i=0;i<nbOfTuples;i++)
7296     {
7297       int j=0;
7298       for(;j<dim;j++)
7299         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7300       for(;j<newNbOfComp;j++)
7301         nc[newNbOfComp*i+j]=dftValue;
7302     }
7303   ret->setName(getName().c_str());
7304   for(int i=0;i<dim;i++)
7305     ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
7306   ret->setName(getName().c_str());
7307   return ret.retn();
7308 }
7309
7310 /*!
7311  * Changes number of tuples in the array. If the new number of tuples is smaller
7312  * than the current number the array is truncated, otherwise the array is extended.
7313  *  \param [in] nbOfTuples - new number of tuples. 
7314  *  \throw If \a this is not allocated.
7315  *  \throw If \a nbOfTuples is negative.
7316  */
7317 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
7318 {
7319   if(nbOfTuples<0)
7320     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7321   checkAllocated();
7322   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7323   declareAsNew();
7324 }
7325
7326
7327 /*!
7328  * Returns a copy of \a this array composed of selected components.
7329  * The new DataArrayInt has the same number of tuples but includes components
7330  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7331  * can be either less, same or more than \a this->getNbOfElems().
7332  *  \param [in] compoIds - sequence of zero based indices of components to include
7333  *              into the new array.
7334  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7335  *          is to delete using decrRef() as it is no more needed.
7336  *  \throw If \a this is not allocated.
7337  *  \throw If a component index (\a i) is not valid: 
7338  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7339  *
7340  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7341  */
7342 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const throw(INTERP_KERNEL::Exception)
7343 {
7344   checkAllocated();
7345   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7346   int newNbOfCompo=(int)compoIds.size();
7347   int oldNbOfCompo=getNumberOfComponents();
7348   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7349     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7350   int nbOfTuples=getNumberOfTuples();
7351   ret->alloc(nbOfTuples,newNbOfCompo);
7352   ret->copyPartOfStringInfoFrom(*this,compoIds);
7353   const int *oldc=getConstPointer();
7354   int *nc=ret->getPointer();
7355   for(int i=0;i<nbOfTuples;i++)
7356     for(int j=0;j<newNbOfCompo;j++,nc++)
7357       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7358   return ret.retn();
7359 }
7360
7361 /*!
7362  * Appends components of another array to components of \a this one, tuple by tuple.
7363  * So that the number of tuples of \a this array remains the same and the number of 
7364  * components increases.
7365  *  \param [in] other - the DataArrayInt to append to \a this one.
7366  *  \throw If \a this is not allocated.
7367  *  \throw If \a this and \a other arrays have different number of tuples.
7368  *
7369  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7370  *
7371  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7372  */
7373 void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
7374 {
7375   if(!other)
7376     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7377   checkAllocated();
7378   other->checkAllocated();
7379   int nbOfTuples=getNumberOfTuples();
7380   if(nbOfTuples!=other->getNumberOfTuples())
7381     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7382   int nbOfComp1=getNumberOfComponents();
7383   int nbOfComp2=other->getNumberOfComponents();
7384   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7385   int *w=newArr;
7386   const int *inp1=getConstPointer();
7387   const int *inp2=other->getConstPointer();
7388   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7389     {
7390       w=std::copy(inp1,inp1+nbOfComp1,w);
7391       w=std::copy(inp2,inp2+nbOfComp2,w);
7392     }
7393   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7394   std::vector<int> compIds(nbOfComp2);
7395   for(int i=0;i<nbOfComp2;i++)
7396     compIds[i]=nbOfComp1+i;
7397   copyPartOfStringInfoFrom2(compIds,*other);
7398 }
7399
7400 /*!
7401  * Copy all components in a specified order from another DataArrayInt.
7402  * The specified components become the first ones in \a this array.
7403  * Both numerical and textual data is copied. The number of tuples in \a this and
7404  * the other array can be different.
7405  *  \param [in] a - the array to copy data from.
7406  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7407  *              to be copied.
7408  *  \throw If \a a is NULL.
7409  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7410  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7411  *
7412  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7413  */
7414 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
7415 {
7416   if(!a)
7417     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7418   checkAllocated();
7419   a->checkAllocated();
7420   copyPartOfStringInfoFrom2(compoIds,*a);
7421   std::size_t partOfCompoSz=compoIds.size();
7422   int nbOfCompo=getNumberOfComponents();
7423   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7424   const int *ac=a->getConstPointer();
7425   int *nc=getPointer();
7426   for(int i=0;i<nbOfTuples;i++)
7427     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7428       nc[nbOfCompo*i+compoIds[j]]=*ac;
7429 }
7430
7431 /*!
7432  * Copy all values from another DataArrayInt into specified tuples and components
7433  * of \a this array. Textual data is not copied.
7434  * The tree parameters defining set of indices of tuples and components are similar to
7435  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7436  *  \param [in] a - the array to copy values from.
7437  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7438  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7439  *              are located.
7440  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7441  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7442  *  \param [in] endComp - index of the component before which the components to assign
7443  *              to are located.
7444  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7445  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7446  *              must be equal to the number of columns to assign to, else an
7447  *              exception is thrown; if \a false, then it is only required that \a
7448  *              a->getNbOfElems() equals to number of values to assign to (this condition
7449  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7450  *              values to assign to is given by following Python expression:
7451  *              \a nbTargetValues = 
7452  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7453  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7454  *  \throw If \a a is NULL.
7455  *  \throw If \a a is not allocated.
7456  *  \throw If \a this is not allocated.
7457  *  \throw If parameters specifying tuples and components to assign to do not give a
7458  *            non-empty range of increasing indices.
7459  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7460  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7461  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7462  *
7463  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7464  */
7465 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7466 {
7467   if(!a)
7468     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7469   const char msg[]="DataArrayInt::setPartOfValues1";
7470   checkAllocated();
7471   a->checkAllocated();
7472   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7473   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7474   int nbComp=getNumberOfComponents();
7475   int nbOfTuples=getNumberOfTuples();
7476   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7477   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7478   bool assignTech=true;
7479   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7480     {
7481       if(strictCompoCompare)
7482         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7483     }
7484   else
7485     {
7486       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7487       assignTech=false;
7488     }
7489   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7490   const int *srcPt=a->getConstPointer();
7491   if(assignTech)
7492     {
7493       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7494         for(int j=0;j<newNbOfComp;j++,srcPt++)
7495           pt[j*stepComp]=*srcPt;
7496     }
7497   else
7498     {
7499       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7500         {
7501           const int *srcPt2=srcPt;
7502           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7503             pt[j*stepComp]=*srcPt2;
7504         }
7505     }
7506 }
7507
7508 /*!
7509  * Assign a given value to values at specified tuples and components of \a this array.
7510  * The tree parameters defining set of indices of tuples and components are similar to
7511  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7512  *  \param [in] a - the value to assign.
7513  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7514  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7515  *              are located.
7516  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7517  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7518  *  \param [in] endComp - index of the component before which the components to assign
7519  *              to are located.
7520  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7521  *  \throw If \a this is not allocated.
7522  *  \throw If parameters specifying tuples and components to assign to, do not give a
7523  *            non-empty range of increasing indices or indices are out of a valid range
7524  *            for \this array.
7525  *
7526  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7527  */
7528 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7529 {
7530   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7531   checkAllocated();
7532   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7533   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7534   int nbComp=getNumberOfComponents();
7535   int nbOfTuples=getNumberOfTuples();
7536   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7537   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7538   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7539   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7540     for(int j=0;j<newNbOfComp;j++)
7541       pt[j*stepComp]=a;
7542 }
7543
7544
7545 /*!
7546  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7547  * components of \a this array. Textual data is not copied.
7548  * The tuples and components to assign to are defined by C arrays of indices.
7549  * There are two *modes of usage*:
7550  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7551  *   of \a a is assigned to its own location within \a this array. 
7552  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7553  *   components of every specified tuple of \a this array. In this mode it is required
7554  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7555  * 
7556  *  \param [in] a - the array to copy values from.
7557  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7558  *              assign values of \a a to.
7559  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7560  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7561  *              \a bgTuples <= \a pi < \a endTuples.
7562  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7563  *              assign values of \a a to.
7564  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7565  *              pointer to a component index <em>(pi)</em> varies as this: 
7566  *              \a bgComp <= \a pi < \a endComp.
7567  *  \param [in] strictCompoCompare - this parameter is checked only if the
7568  *               *mode of usage* is the first; if it is \a true (default), 
7569  *               then \a a->getNumberOfComponents() must be equal 
7570  *               to the number of specified columns, else this is not required.
7571  *  \throw If \a a is NULL.
7572  *  \throw If \a a is not allocated.
7573  *  \throw If \a this is not allocated.
7574  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7575  *         out of a valid range for \a this array.
7576  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7577  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7578  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7579  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7580  *
7581  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7582  */
7583 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7584 {
7585   if(!a)
7586     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7587   const char msg[]="DataArrayInt::setPartOfValues2";
7588   checkAllocated();
7589   a->checkAllocated();
7590   int nbComp=getNumberOfComponents();
7591   int nbOfTuples=getNumberOfTuples();
7592   for(const int *z=bgComp;z!=endComp;z++)
7593     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7594   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7595   int newNbOfComp=(int)std::distance(bgComp,endComp);
7596   bool assignTech=true;
7597   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7598     {
7599       if(strictCompoCompare)
7600         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7601     }
7602   else
7603     {
7604       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7605       assignTech=false;
7606     }
7607   int *pt=getPointer();
7608   const int *srcPt=a->getConstPointer();
7609   if(assignTech)
7610     {    
7611       for(const int *w=bgTuples;w!=endTuples;w++)
7612         {
7613           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7614           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7615             {    
7616               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7617             }
7618         }
7619     }
7620   else
7621     {
7622       for(const int *w=bgTuples;w!=endTuples;w++)
7623         {
7624           const int *srcPt2=srcPt;
7625           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7626           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7627             {    
7628               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7629             }
7630         }
7631     }
7632 }
7633
7634 /*!
7635  * Assign a given value to values at specified tuples and components of \a this array.
7636  * The tuples and components to assign to are defined by C arrays of indices.
7637  *  \param [in] a - the value to assign.
7638  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7639  *              assign \a a to.
7640  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7641  *              pointer to a tuple index (\a pi) varies as this: 
7642  *              \a bgTuples <= \a pi < \a endTuples.
7643  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7644  *              assign \a a to.
7645  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7646  *              pointer to a component index (\a pi) varies as this: 
7647  *              \a bgComp <= \a pi < \a endComp.
7648  *  \throw If \a this is not allocated.
7649  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7650  *         out of a valid range for \a this array.
7651  *
7652  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7653  */
7654 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7655 {
7656   checkAllocated();
7657   int nbComp=getNumberOfComponents();
7658   int nbOfTuples=getNumberOfTuples();
7659   for(const int *z=bgComp;z!=endComp;z++)
7660     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7661   int *pt=getPointer();
7662   for(const int *w=bgTuples;w!=endTuples;w++)
7663     for(const int *z=bgComp;z!=endComp;z++)
7664       {
7665         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7666         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7667       }
7668 }
7669
7670 /*!
7671  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7672  * components of \a this array. Textual data is not copied.
7673  * The tuples to assign to are defined by a C array of indices.
7674  * The components to assign to are defined by three values similar to parameters of
7675  * the Python function \c range(\c start,\c stop,\c step).
7676  * There are two *modes of usage*:
7677  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7678  *   of \a a is assigned to its own location within \a this array. 
7679  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7680  *   components of every specified tuple of \a this array. In this mode it is required
7681  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7682  *
7683  *  \param [in] a - the array to copy values from.
7684  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7685  *              assign values of \a a to.
7686  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7687  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7688  *              \a bgTuples <= \a pi < \a endTuples.
7689  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7690  *  \param [in] endComp - index of the component before which the components to assign
7691  *              to are located.
7692  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7693  *  \param [in] strictCompoCompare - this parameter is checked only in the first
7694  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
7695  *               then \a a->getNumberOfComponents() must be equal 
7696  *               to the number of specified columns, else this is not required.
7697  *  \throw If \a a is NULL.
7698  *  \throw If \a a is not allocated.
7699  *  \throw If \a this is not allocated.
7700  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7701  *         \a this array.
7702  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7703  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
7704  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7705  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7706  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
7707  *         defined by <em>(bgComp,endComp,stepComp)</em>.
7708  *  \throw If parameters specifying components to assign to, do not give a
7709  *            non-empty range of increasing indices or indices are out of a valid range
7710  *            for \this array.
7711  *
7712  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
7713  */
7714 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7715 {
7716   if(!a)
7717     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
7718   const char msg[]="DataArrayInt::setPartOfValues3";
7719   checkAllocated();
7720   a->checkAllocated();
7721   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7722   int nbComp=getNumberOfComponents();
7723   int nbOfTuples=getNumberOfTuples();
7724   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7725   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7726   bool assignTech=true;
7727   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7728     {
7729       if(strictCompoCompare)
7730         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7731     }
7732   else
7733     {
7734       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7735       assignTech=false;
7736     }
7737   int *pt=getPointer()+bgComp;
7738   const int *srcPt=a->getConstPointer();
7739   if(assignTech)
7740     {
7741       for(const int *w=bgTuples;w!=endTuples;w++)
7742         for(int j=0;j<newNbOfComp;j++,srcPt++)
7743           {
7744             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7745             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
7746           }
7747     }
7748   else
7749     {
7750       for(const int *w=bgTuples;w!=endTuples;w++)
7751         {
7752           const int *srcPt2=srcPt;
7753           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7754             {
7755               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7756               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
7757             }
7758         }
7759     }
7760 }
7761
7762 /*!
7763  * Assign a given value to values at specified tuples and components of \a this array.
7764  * The tuples to assign to are defined by a C array of indices.
7765  * The components to assign to are defined by three values similar to parameters of
7766  * the Python function \c range(\c start,\c stop,\c step).
7767  *  \param [in] a - the value to assign.
7768  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7769  *              assign \a a to.
7770  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7771  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7772  *              \a bgTuples <= \a pi < \a endTuples.
7773  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7774  *  \param [in] endComp - index of the component before which the components to assign
7775  *              to are located.
7776  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7777  *  \throw If \a this is not allocated.
7778  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
7779  *         \a this array.
7780  *  \throw If parameters specifying components to assign to, do not give a
7781  *            non-empty range of increasing indices or indices are out of a valid range
7782  *            for \this array.
7783  *
7784  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
7785  */
7786 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception)
7787 {
7788   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
7789   checkAllocated();
7790   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7791   int nbComp=getNumberOfComponents();
7792   int nbOfTuples=getNumberOfTuples();
7793   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7794   int *pt=getPointer()+bgComp;
7795   for(const int *w=bgTuples;w!=endTuples;w++)
7796     for(int j=0;j<newNbOfComp;j++)
7797       {
7798         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7799         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
7800       }
7801 }
7802
7803 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
7804 {
7805   if(!a)
7806     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
7807   const char msg[]="DataArrayInt::setPartOfValues4";
7808   checkAllocated();
7809   a->checkAllocated();
7810   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7811   int newNbOfComp=(int)std::distance(bgComp,endComp);
7812   int nbComp=getNumberOfComponents();
7813   for(const int *z=bgComp;z!=endComp;z++)
7814     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7815   int nbOfTuples=getNumberOfTuples();
7816   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7817   bool assignTech=true;
7818   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7819     {
7820       if(strictCompoCompare)
7821         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7822     }
7823   else
7824     {
7825       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7826       assignTech=false;
7827     }
7828   const int *srcPt=a->getConstPointer();
7829   int *pt=getPointer()+bgTuples*nbComp;
7830   if(assignTech)
7831     {
7832       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7833         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7834           pt[*z]=*srcPt;
7835     }
7836   else
7837     {
7838       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7839         {
7840           const int *srcPt2=srcPt;
7841           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7842             pt[*z]=*srcPt2;
7843         }
7844     }
7845 }
7846
7847 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
7848 {
7849   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
7850   checkAllocated();
7851   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7852   int nbComp=getNumberOfComponents();
7853   for(const int *z=bgComp;z!=endComp;z++)
7854     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7855   int nbOfTuples=getNumberOfTuples();
7856   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7857   int *pt=getPointer()+bgTuples*nbComp;
7858   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7859     for(const int *z=bgComp;z!=endComp;z++)
7860       pt[*z]=a;
7861 }
7862
7863 /*!
7864  * Copy some tuples from another DataArrayInt into specified tuples
7865  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7866  * components.
7867  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
7868  * All components of selected tuples are copied.
7869  *  \param [in] a - the array to copy values from.
7870  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
7871  *              target tuples of \a this. \a tuplesSelec has two components, and the
7872  *              first component specifies index of the source tuple and the second
7873  *              one specifies index of the target tuple.
7874  *  \throw If \a this is not allocated.
7875  *  \throw If \a a is NULL.
7876  *  \throw If \a a is not allocated.
7877  *  \throw If \a tuplesSelec is NULL.
7878  *  \throw If \a tuplesSelec is not allocated.
7879  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7880  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
7881  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7882  *         the corresponding (\a this or \a a) array.
7883  */
7884 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7885 {
7886   if(!a || !tuplesSelec)
7887     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
7888   checkAllocated();
7889   a->checkAllocated();
7890   tuplesSelec->checkAllocated();
7891   int nbOfComp=getNumberOfComponents();
7892   if(nbOfComp!=a->getNumberOfComponents())
7893     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
7894   if(tuplesSelec->getNumberOfComponents()!=2)
7895     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
7896   int thisNt=getNumberOfTuples();
7897   int aNt=a->getNumberOfTuples();
7898   int *valsToSet=getPointer();
7899   const int *valsSrc=a->getConstPointer();
7900   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
7901     {
7902       if(tuple[1]>=0 && tuple[1]<aNt)
7903         {
7904           if(tuple[0]>=0 && tuple[0]<thisNt)
7905             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
7906           else
7907             {
7908               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7909               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
7910               throw INTERP_KERNEL::Exception(oss.str().c_str());
7911             }
7912         }
7913       else
7914         {
7915           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
7916           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
7917           throw INTERP_KERNEL::Exception(oss.str().c_str());
7918         }
7919     }
7920 }
7921
7922 /*!
7923  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
7924  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7925  * components.
7926  * The tuples to assign to are defined by index of the first tuple, and
7927  * their number is defined by \a tuplesSelec->getNumberOfTuples().
7928  * The tuples to copy are defined by values of a DataArrayInt.
7929  * All components of selected tuples are copied.
7930  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7931  *              values to.
7932  *  \param [in] aBase - the array to copy values from.
7933  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
7934  *  \throw If \a this is not allocated.
7935  *  \throw If \a aBase is NULL.
7936  *  \throw If \a aBase is not allocated.
7937  *  \throw If \a tuplesSelec is NULL.
7938  *  \throw If \a tuplesSelec is not allocated.
7939  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
7940  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
7941  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
7942  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
7943  *         \a aBase array.
7944  */
7945 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
7946 {
7947   if(!aBase || !tuplesSelec)
7948     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
7949   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
7950   if(!a)
7951     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
7952   checkAllocated();
7953   a->checkAllocated();
7954   tuplesSelec->checkAllocated();
7955   int nbOfComp=getNumberOfComponents();
7956   if(nbOfComp!=a->getNumberOfComponents())
7957     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
7958   if(tuplesSelec->getNumberOfComponents()!=1)
7959     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
7960   int thisNt=getNumberOfTuples();
7961   int aNt=a->getNumberOfTuples();
7962   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
7963   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
7964   if(tupleIdStart+nbOfTupleToWrite>thisNt)
7965     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
7966   const int *valsSrc=a->getConstPointer();
7967   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
7968     {
7969       if(*tuple>=0 && *tuple<aNt)
7970         {
7971           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
7972         }
7973       else
7974         {
7975           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
7976           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
7977           throw INTERP_KERNEL::Exception(oss.str().c_str());
7978         }
7979     }
7980 }
7981
7982 /*!
7983  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
7984  * of \a this array. Textual data is not copied. Both arrays must have equal number of
7985  * components.
7986  * The tuples to copy are defined by three values similar to parameters of
7987  * the Python function \c range(\c start,\c stop,\c step).
7988  * The tuples to assign to are defined by index of the first tuple, and
7989  * their number is defined by number of tuples to copy.
7990  * All components of selected tuples are copied.
7991  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
7992  *              values to.
7993  *  \param [in] aBase - the array to copy values from.
7994  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
7995  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
7996  *              are located.
7997  *  \param [in] step - index increment to get index of the next tuple to copy.
7998  *  \throw If \a this is not allocated.
7999  *  \throw If \a aBase is NULL.
8000  *  \throw If \a aBase is not allocated.
8001  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8002  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8003  *  \throw If parameters specifying tuples to copy, do not give a
8004  *            non-empty range of increasing indices or indices are out of a valid range
8005  *            for the array \a aBase.
8006  */
8007 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception)
8008 {
8009   if(!aBase)
8010     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8011   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8012   if(!a)
8013     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8014   checkAllocated();
8015   a->checkAllocated();
8016   int nbOfComp=getNumberOfComponents();
8017   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8018   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8019   if(nbOfComp!=a->getNumberOfComponents())
8020     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8021   int thisNt=getNumberOfTuples();
8022   int aNt=a->getNumberOfTuples();
8023   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8024   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8025     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8026   if(end2>aNt)
8027     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8028   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8029   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8030     {
8031       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8032     }
8033 }
8034
8035 /*!
8036  * Returns a value located at specified tuple and component.
8037  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8038  * parameters is checked. So this method is safe but expensive if used to go through
8039  * all values of \a this.
8040  *  \param [in] tupleId - index of tuple of interest.
8041  *  \param [in] compoId - index of component of interest.
8042  *  \return double - value located by \a tupleId and \a compoId.
8043  *  \throw If \a this is not allocated.
8044  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8045  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8046  */
8047 int DataArrayInt::getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception)
8048 {
8049   checkAllocated();
8050   if(tupleId<0 || tupleId>=getNumberOfTuples())
8051     {
8052       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8053       throw INTERP_KERNEL::Exception(oss.str().c_str());
8054     }
8055   if(compoId<0 || compoId>=getNumberOfComponents())
8056     {
8057       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8058       throw INTERP_KERNEL::Exception(oss.str().c_str());
8059     }
8060   return _mem[tupleId*_info_on_compo.size()+compoId];
8061 }
8062
8063 /*!
8064  * Returns the first value of \a this. 
8065  *  \return int - the last value of \a this array.
8066  *  \throw If \a this is not allocated.
8067  *  \throw If \a this->getNumberOfComponents() != 1.
8068  *  \throw If \a this->getNumberOfTuples() < 1.
8069  */
8070 int DataArrayInt::front() const throw(INTERP_KERNEL::Exception)
8071 {
8072   checkAllocated();
8073   if(getNumberOfComponents()!=1)
8074     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8075   int nbOfTuples=getNumberOfTuples();
8076   if(nbOfTuples<1)
8077     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8078   return *(getConstPointer());
8079 }
8080
8081 /*!
8082  * Returns the last value of \a this. 
8083  *  \return int - the last value of \a this array.
8084  *  \throw If \a this is not allocated.
8085  *  \throw If \a this->getNumberOfComponents() != 1.
8086  *  \throw If \a this->getNumberOfTuples() < 1.
8087  */
8088 int DataArrayInt::back() const throw(INTERP_KERNEL::Exception)
8089 {
8090   checkAllocated();
8091   if(getNumberOfComponents()!=1)
8092     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8093   int nbOfTuples=getNumberOfTuples();
8094   if(nbOfTuples<1)
8095     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8096   return *(getConstPointer()+nbOfTuples-1);
8097 }
8098
8099 /*!
8100  * Assign pointer to one array to a pointer to another appay. Reference counter of
8101  * \a arrayToSet is incremented / decremented.
8102  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8103  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8104  */
8105 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8106 {
8107   if(newArray!=arrayToSet)
8108     {
8109       if(arrayToSet)
8110         arrayToSet->decrRef();
8111       arrayToSet=newArray;
8112       if(arrayToSet)
8113         arrayToSet->incrRef();
8114     }
8115 }
8116
8117 DataArrayIntIterator *DataArrayInt::iterator() throw(INTERP_KERNEL::Exception)
8118 {
8119   return new DataArrayIntIterator(this);
8120 }
8121
8122 /*!
8123  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8124  * given one.
8125  *  \param [in] val - the value to find within \a this.
8126  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8127  *          array using decrRef() as it is no more needed.
8128  *  \throw If \a this is not allocated.
8129  *  \throw If \a this->getNumberOfComponents() != 1.
8130  */
8131 DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception)
8132 {
8133   checkAllocated();
8134   if(getNumberOfComponents()!=1)
8135     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8136   const int *cptr=getConstPointer();
8137   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8138   int nbOfTuples=getNumberOfTuples();
8139   for(int i=0;i<nbOfTuples;i++,cptr++)
8140     if(*cptr==val)
8141       ret->pushBackSilent(i);
8142   return ret.retn();
8143 }
8144
8145 /*!
8146  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8147  * equal to a given one. 
8148  *  \param [in] val - the value to ignore within \a this.
8149  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8150  *          array using decrRef() as it is no more needed.
8151  *  \throw If \a this is not allocated.
8152  *  \throw If \a this->getNumberOfComponents() != 1.
8153  */
8154 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception)
8155 {
8156   checkAllocated();
8157   if(getNumberOfComponents()!=1)
8158     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8159   const int *cptr=getConstPointer();
8160   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8161   int nbOfTuples=getNumberOfTuples();
8162   for(int i=0;i<nbOfTuples;i++,cptr++)
8163     if(*cptr!=val)
8164       ret->pushBackSilent(i);
8165   return ret.retn();
8166 }
8167
8168
8169 /*!
8170  * Assigns \a newValue to all elements holding \a oldValue within \a this
8171  * one-dimensional array.
8172  *  \param [in] oldValue - the value to replace.
8173  *  \param [in] newValue - the value to assign.
8174  *  \return int - number of replacements performed.
8175  *  \throw If \a this is not allocated.
8176  *  \throw If \a this->getNumberOfComponents() != 1.
8177  */
8178 int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception)
8179 {
8180   checkAllocated();
8181   if(getNumberOfComponents()!=1)
8182     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8183   int *start=getPointer();
8184   int *end2=start+getNbOfElems();
8185   int ret=0;
8186   for(int *val=start;val!=end2;val++)
8187     {
8188       if(*val==oldValue)
8189         {
8190           *val=newValue;
8191           ret++;
8192         }
8193     }
8194   return ret;
8195 }
8196
8197 /*!
8198  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8199  * one of given values.
8200  *  \param [in] valsBg - an array of values to find within \a this array.
8201  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8202  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8203  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8204  *          array using decrRef() as it is no more needed.
8205  *  \throw If \a this->getNumberOfComponents() != 1.
8206  */
8207 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
8208 {
8209   if(getNumberOfComponents()!=1)
8210     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8211   std::set<int> vals2(valsBg,valsEnd);
8212   const int *cptr=getConstPointer();
8213   std::vector<int> res;
8214   int nbOfTuples=getNumberOfTuples();
8215   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8216   for(int i=0;i<nbOfTuples;i++,cptr++)
8217     if(vals2.find(*cptr)!=vals2.end())
8218       ret->pushBackSilent(i);
8219   return ret.retn();
8220 }
8221
8222 /*!
8223  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8224  * equal to any of given values.
8225  *  \param [in] valsBg - an array of values to ignore within \a this array.
8226  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8227  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8228  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8229  *          array using decrRef() as it is no more needed.
8230  *  \throw If \a this->getNumberOfComponents() != 1.
8231  */
8232 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const throw(INTERP_KERNEL::Exception)
8233 {
8234   if(getNumberOfComponents()!=1)
8235     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8236   std::set<int> vals2(valsBg,valsEnd);
8237   const int *cptr=getConstPointer();
8238   std::vector<int> res;
8239   int nbOfTuples=getNumberOfTuples();
8240   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8241   for(int i=0;i<nbOfTuples;i++,cptr++)
8242     if(vals2.find(*cptr)==vals2.end())
8243       ret->pushBackSilent(i);
8244   return ret.retn();
8245 }
8246
8247 /*!
8248  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8249  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8250  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8251  * If any the tuple id is returned. If not -1 is returned.
8252  * 
8253  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8254  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8255  *
8256  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8257  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8258  */
8259 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8260 {
8261   checkAllocated();
8262   int nbOfCompo=getNumberOfComponents();
8263   if(nbOfCompo==0)
8264     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8265   if(nbOfCompo!=(int)tupl.size())
8266     {
8267       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8268       throw INTERP_KERNEL::Exception(oss.str().c_str());
8269     }
8270   const int *cptr=getConstPointer();
8271   std::size_t nbOfVals=getNbOfElems();
8272   for(const int *work=cptr;work!=cptr+nbOfVals;)
8273     {
8274       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8275       if(work!=cptr+nbOfVals)
8276         {
8277           if(std::distance(cptr,work)%nbOfCompo!=0)
8278             work++;
8279           else
8280             return std::distance(cptr,work)/nbOfCompo;
8281         }
8282     }
8283   return -1;
8284 }
8285
8286 /*!
8287  * This method searches the sequence specified in input parameter \b vals in \b this.
8288  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8289  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8290  * \sa DataArrayInt::locateTuple
8291  */
8292 int DataArrayInt::search(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8293 {
8294   checkAllocated();
8295   int nbOfCompo=getNumberOfComponents();
8296   if(nbOfCompo!=1)
8297     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8298   const int *cptr=getConstPointer();
8299   std::size_t nbOfVals=getNbOfElems();
8300   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8301   if(loc!=cptr+nbOfVals)
8302     return std::distance(cptr,loc);
8303   return -1;
8304 }
8305
8306 /*!
8307  * This method expects to be called when number of components of this is equal to one.
8308  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8309  * If not any tuple contains \b value -1 is returned.
8310  * \sa DataArrayInt::presenceOfValue
8311  */
8312 int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception)
8313 {
8314   checkAllocated();
8315   if(getNumberOfComponents()!=1)
8316     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8317   const int *cptr=getConstPointer();
8318   int nbOfTuples=getNumberOfTuples();
8319   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8320   if(ret!=cptr+nbOfTuples)
8321     return std::distance(cptr,ret);
8322   return -1;
8323 }
8324
8325 /*!
8326  * This method expects to be called when number of components of this is equal to one.
8327  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8328  * If not any tuple contains one of the values contained in 'vals' false is returned.
8329  * \sa DataArrayInt::presenceOfValue
8330  */
8331 int DataArrayInt::locateValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8332 {
8333   checkAllocated();
8334   if(getNumberOfComponents()!=1)
8335     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8336   std::set<int> vals2(vals.begin(),vals.end());
8337   const int *cptr=getConstPointer();
8338   int nbOfTuples=getNumberOfTuples();
8339   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8340     if(vals2.find(*w)!=vals2.end())
8341       return std::distance(cptr,w);
8342   return -1;
8343 }
8344
8345 /*!
8346  * This method returns the number of values in \a this that are equals to input parameter \a value.
8347  * This method only works for single component array.
8348  *
8349  * \return a value in [ 0, \c this->getNumberOfTuples() )
8350  *
8351  * \throw If \a this is not allocated
8352  *
8353  */
8354 int DataArrayInt::count(int value) const throw(INTERP_KERNEL::Exception)
8355 {
8356   int ret=0;
8357   checkAllocated();
8358   if(getNumberOfComponents()!=1)
8359     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8360   const int *vals=begin();
8361   int nbOfTuples=getNumberOfTuples();
8362   for(int i=0;i<nbOfTuples;i++,vals++)
8363     if(*vals==value)
8364       ret++;
8365   return ret;
8366 }
8367
8368 /*!
8369  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8370  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8371  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8372  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8373  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8374  * \sa DataArrayInt::locateTuple
8375  */
8376 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
8377 {
8378   return locateTuple(tupl)!=-1;
8379 }
8380
8381
8382 /*!
8383  * Returns \a true if a given value is present within \a this one-dimensional array.
8384  *  \param [in] value - the value to find within \a this array.
8385  *  \return bool - \a true in case if \a value is present within \a this array.
8386  *  \throw If \a this is not allocated.
8387  *  \throw If \a this->getNumberOfComponents() != 1.
8388  *  \sa locateValue()
8389  */
8390 bool DataArrayInt::presenceOfValue(int value) const throw(INTERP_KERNEL::Exception)
8391 {
8392   return locateValue(value)!=-1;
8393 }
8394
8395 /*!
8396  * This method expects to be called when number of components of this is equal to one.
8397  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8398  * If not any tuple contains one of the values contained in 'vals' false is returned.
8399  * \sa DataArrayInt::locateValue
8400  */
8401 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
8402 {
8403   return locateValue(vals)!=-1;
8404 }
8405
8406 /*!
8407  * Accumulates values of each component of \a this array.
8408  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8409  *         by the caller, that is filled by this method with sum value for each
8410  *         component.
8411  *  \throw If \a this is not allocated.
8412  */
8413 void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception)
8414 {
8415   checkAllocated();
8416   const int *ptr=getConstPointer();
8417   int nbTuple=getNumberOfTuples();
8418   int nbComps=getNumberOfComponents();
8419   std::fill(res,res+nbComps,0);
8420   for(int i=0;i<nbTuple;i++)
8421     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8422 }
8423
8424 int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
8425 {
8426   checkAllocated();
8427   const int *ptr=getConstPointer();
8428   int nbTuple=getNumberOfTuples();
8429   int nbComps=getNumberOfComponents();
8430   if(compId<0 || compId>=nbComps)
8431     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8432   int ret=0;
8433   for(int i=0;i<nbTuple;i++)
8434     ret+=ptr[i*nbComps+compId];
8435   return ret;
8436 }
8437
8438 /*!
8439  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8440  * The returned array will have same number of components than \a this and number of tuples equal to
8441  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8442  *
8443  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8444  *
8445  * \param [in] bgOfIndex - begin (included) of the input index array.
8446  * \param [in] endOfIndex - end (excluded) of the input index array.
8447  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8448  * 
8449  * \throw If bgOfIndex or end is NULL.
8450  * \throw If input index array is not ascendingly sorted.
8451  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8452  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8453  */
8454 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const throw(INTERP_KERNEL::Exception)
8455 {
8456   if(!bgOfIndex || !endOfIndex)
8457     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8458   checkAllocated();
8459   int nbCompo=getNumberOfComponents();
8460   int nbOfTuples=getNumberOfTuples();
8461   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8462   if(sz<1)
8463     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8464   sz--;
8465   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8466   const int *w=bgOfIndex;
8467   if(*w<0 || *w>=nbOfTuples)
8468     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8469   const int *srcPt=begin()+(*w)*nbCompo;
8470   int *tmp=ret->getPointer();
8471   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8472     {
8473       std::fill(tmp,tmp+nbCompo,0.);
8474       if(w[1]>=w[0])
8475         {
8476           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8477             {
8478               if(j>=0 && j<nbOfTuples)
8479                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8480               else
8481                 {
8482                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8483                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8484                 }
8485             }
8486         }
8487       else
8488         {
8489           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8490           throw INTERP_KERNEL::Exception(oss.str().c_str());
8491         }
8492     }
8493   ret->copyStringInfoFrom(*this);
8494   return ret.retn();
8495 }
8496
8497 /*!
8498  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8499  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8500  * offsetA2</em> and (2)
8501  * the number of component in the result array is same as that of each of given arrays.
8502  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8503  * Info on components is copied from the first of the given arrays. Number of components
8504  * in the given arrays must be the same.
8505  *  \param [in] a1 - an array to include in the result array.
8506  *  \param [in] a2 - another array to include in the result array.
8507  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8508  *  \return DataArrayInt * - the new instance of DataArrayInt.
8509  *          The caller is to delete this result array using decrRef() as it is no more
8510  *          needed.
8511  *  \throw If either \a a1 or \a a2 is NULL.
8512  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8513  */
8514 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8515 {
8516   if(!a1 || !a2)
8517     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8518   int nbOfComp=a1->getNumberOfComponents();
8519   if(nbOfComp!=a2->getNumberOfComponents())
8520     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8521   int nbOfTuple1=a1->getNumberOfTuples();
8522   int nbOfTuple2=a2->getNumberOfTuples();
8523   DataArrayInt *ret=DataArrayInt::New();
8524   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8525   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8526   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8527   ret->copyStringInfoFrom(*a1);
8528   return ret;
8529 }
8530
8531 /*!
8532  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8533  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8534  * the number of component in the result array is same as that of each of given arrays.
8535  * Info on components is copied from the first of the given arrays. Number of components
8536  * in the given arrays must be  the same.
8537  *  \param [in] arr - a sequence of arrays to include in the result array.
8538  *  \return DataArrayInt * - the new instance of DataArrayInt.
8539  *          The caller is to delete this result array using decrRef() as it is no more
8540  *          needed.
8541  *  \throw If all arrays within \a arr are NULL.
8542  *  \throw If getNumberOfComponents() of arrays within \a arr.
8543  */
8544 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
8545 {
8546   std::vector<const DataArrayInt *> a;
8547   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8548     if(*it4)
8549       a.push_back(*it4);
8550   if(a.empty())
8551     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8552   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8553   int nbOfComp=(*it)->getNumberOfComponents();
8554   int nbt=(*it++)->getNumberOfTuples();
8555   for(int i=1;it!=a.end();it++,i++)
8556     {
8557       if((*it)->getNumberOfComponents()!=nbOfComp)
8558         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8559       nbt+=(*it)->getNumberOfTuples();
8560     }
8561   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8562   ret->alloc(nbt,nbOfComp);
8563   int *pt=ret->getPointer();
8564   for(it=a.begin();it!=a.end();it++)
8565     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8566   ret->copyStringInfoFrom(*(a[0]));
8567   return ret.retn();
8568 }
8569
8570 /*!
8571  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8572  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8573  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8574  * 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.
8575  * 
8576  * \return DataArrayInt * - a new object to be managed by the caller.
8577  */
8578 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs) throw(INTERP_KERNEL::Exception)
8579 {
8580   int retSz=1;
8581   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8582     {
8583       if(*it4)
8584         {
8585           (*it4)->checkAllocated();
8586           if((*it4)->getNumberOfComponents()!=1)
8587             {
8588               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8589               throw INTERP_KERNEL::Exception(oss.str().c_str());
8590             }
8591           int nbTupl=(*it4)->getNumberOfTuples();
8592           if(nbTupl<1)
8593             {
8594               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8595               throw INTERP_KERNEL::Exception(oss.str().c_str());
8596             }
8597           if((*it4)->front()!=0)
8598             {
8599               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
8600               throw INTERP_KERNEL::Exception(oss.str().c_str());
8601             }
8602           retSz+=nbTupl-1;
8603         }
8604       else
8605         {
8606           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
8607           throw INTERP_KERNEL::Exception(oss.str().c_str());
8608         }
8609     }
8610   if(arrs.empty())
8611     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
8612   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8613   ret->alloc(retSz,1);
8614   int *pt=ret->getPointer(); *pt++=0;
8615   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
8616     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
8617   ret->copyStringInfoFrom(*(arrs[0]));
8618   return ret.retn();
8619 }
8620
8621 /*!
8622  * Returns the maximal value and its location within \a this one-dimensional array.
8623  *  \param [out] tupleId - index of the tuple holding the maximal value.
8624  *  \return int - the maximal value among all values of \a this array.
8625  *  \throw If \a this->getNumberOfComponents() != 1
8626  *  \throw If \a this->getNumberOfTuples() < 1
8627  */
8628 int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8629 {
8630   checkAllocated();
8631   if(getNumberOfComponents()!=1)
8632     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8633   int nbOfTuples=getNumberOfTuples();
8634   if(nbOfTuples<=0)
8635     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8636   const int *vals=getConstPointer();
8637   const int *loc=std::max_element(vals,vals+nbOfTuples);
8638   tupleId=(int)std::distance(vals,loc);
8639   return *loc;
8640 }
8641
8642 /*!
8643  * Returns the maximal value within \a this array that is allowed to have more than
8644  *  one component.
8645  *  \return int - the maximal value among all values of \a this array.
8646  *  \throw If \a this is not allocated.
8647  */
8648 int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
8649 {
8650   checkAllocated();
8651   const int *loc=std::max_element(begin(),end());
8652   return *loc;
8653 }
8654
8655 /*!
8656  * Returns the minimal value and its location within \a this one-dimensional array.
8657  *  \param [out] tupleId - index of the tuple holding the minimal value.
8658  *  \return int - the minimal value among all values of \a this array.
8659  *  \throw If \a this->getNumberOfComponents() != 1
8660  *  \throw If \a this->getNumberOfTuples() < 1
8661  */
8662 int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
8663 {
8664   checkAllocated();
8665   if(getNumberOfComponents()!=1)
8666     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
8667   int nbOfTuples=getNumberOfTuples();
8668   if(nbOfTuples<=0)
8669     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
8670   const int *vals=getConstPointer();
8671   const int *loc=std::min_element(vals,vals+nbOfTuples);
8672   tupleId=(int)std::distance(vals,loc);
8673   return *loc;
8674 }
8675
8676 /*!
8677  * Returns the minimal value within \a this array that is allowed to have more than
8678  *  one component.
8679  *  \return int - the minimal value among all values of \a this array.
8680  *  \throw If \a this is not allocated.
8681  */
8682 int DataArrayInt::getMinValueInArray() const throw(INTERP_KERNEL::Exception)
8683 {
8684   checkAllocated();
8685   const int *loc=std::min_element(begin(),end());
8686   return *loc;
8687 }
8688
8689 /*!
8690  * Converts every value of \a this array to its absolute value.
8691  *  \throw If \a this is not allocated.
8692  */
8693 void DataArrayInt::abs() throw(INTERP_KERNEL::Exception)
8694 {
8695   checkAllocated();
8696   int *ptr=getPointer();
8697   std::size_t nbOfElems=getNbOfElems();
8698   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
8699   declareAsNew();
8700 }
8701
8702 /*!
8703  * Apply a liner function to a given component of \a this array, so that
8704  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
8705  *  \param [in] a - the first coefficient of the function.
8706  *  \param [in] b - the second coefficient of the function.
8707  *  \param [in] compoId - the index of component to modify.
8708  *  \throw If \a this is not allocated.
8709  */
8710 void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception)
8711 {
8712   checkAllocated();
8713   int *ptr=getPointer()+compoId;
8714   int nbOfComp=getNumberOfComponents();
8715   int nbOfTuple=getNumberOfTuples();
8716   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
8717     *ptr=a*(*ptr)+b;
8718   declareAsNew();
8719 }
8720
8721 /*!
8722  * Apply a liner function to all elements of \a this array, so that
8723  * an element _x_ becomes \f$ a * x + b \f$.
8724  *  \param [in] a - the first coefficient of the function.
8725  *  \param [in] b - the second coefficient of the function.
8726  *  \throw If \a this is not allocated.
8727  */
8728 void DataArrayInt::applyLin(int a, int b) throw(INTERP_KERNEL::Exception)
8729 {
8730   checkAllocated();
8731   int *ptr=getPointer();
8732   std::size_t nbOfElems=getNbOfElems();
8733   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8734     *ptr=a*(*ptr)+b;
8735   declareAsNew();
8736 }
8737
8738 /*!
8739  * Returns a full copy of \a this array except that sign of all elements is reversed.
8740  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
8741  *          same number of tuples and component as \a this array.
8742  *          The caller is to delete this result array using decrRef() as it is no more
8743  *          needed.
8744  *  \throw If \a this is not allocated.
8745  */
8746 DataArrayInt *DataArrayInt::negate() const throw(INTERP_KERNEL::Exception)
8747 {
8748   checkAllocated();
8749   DataArrayInt *newArr=DataArrayInt::New();
8750   int nbOfTuples=getNumberOfTuples();
8751   int nbOfComp=getNumberOfComponents();
8752   newArr->alloc(nbOfTuples,nbOfComp);
8753   const int *cptr=getConstPointer();
8754   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
8755   newArr->copyStringInfoFrom(*this);
8756   return newArr;
8757 }
8758
8759 /*!
8760  * Modify all elements of \a this array, so that
8761  * an element _x_ becomes \f$ numerator / x \f$.
8762  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8763  *           array, all elements processed before detection of the zero element remain
8764  *           modified.
8765  *  \param [in] numerator - the numerator used to modify array elements.
8766  *  \throw If \a this is not allocated.
8767  *  \throw If there is an element equal to 0 in \a this array.
8768  */
8769 void DataArrayInt::applyInv(int numerator) throw(INTERP_KERNEL::Exception)
8770 {
8771   checkAllocated();
8772   int *ptr=getPointer();
8773   std::size_t nbOfElems=getNbOfElems();
8774   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8775     {
8776       if(*ptr!=0)
8777         {
8778           *ptr=numerator/(*ptr);
8779         }
8780       else
8781         {
8782           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8783           oss << " !";
8784           throw INTERP_KERNEL::Exception(oss.str().c_str());
8785         }
8786     }
8787   declareAsNew();
8788 }
8789
8790 /*!
8791  * Modify all elements of \a this array, so that
8792  * an element _x_ becomes \f$ x / val \f$.
8793  *  \param [in] val - the denominator used to modify array elements.
8794  *  \throw If \a this is not allocated.
8795  *  \throw If \a val == 0.
8796  */
8797 void DataArrayInt::applyDivideBy(int val) throw(INTERP_KERNEL::Exception)
8798 {
8799   if(val==0)
8800     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
8801   checkAllocated();
8802   int *ptr=getPointer();
8803   std::size_t nbOfElems=getNbOfElems();
8804   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
8805   declareAsNew();
8806 }
8807
8808 /*!
8809  * Modify all elements of \a this array, so that
8810  * an element _x_ becomes  <em> x % val </em>.
8811  *  \param [in] val - the divisor used to modify array elements.
8812  *  \throw If \a this is not allocated.
8813  *  \throw If \a val <= 0.
8814  */
8815 void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception)
8816 {
8817   if(val<=0)
8818     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
8819   checkAllocated();
8820   int *ptr=getPointer();
8821   std::size_t nbOfElems=getNbOfElems();
8822   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
8823   declareAsNew();
8824 }
8825
8826 /*!
8827  * This method works only on data array with one component.
8828  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
8829  * this[*id] in [\b vmin,\b vmax)
8830  * 
8831  * \param [in] vmin begin of range. This value is included in range (included).
8832  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8833  * \return a newly allocated data array that the caller should deal with.
8834  */
8835 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8836 {
8837   checkAllocated();
8838   if(getNumberOfComponents()!=1)
8839     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
8840   const int *cptr=getConstPointer();
8841   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
8842   int nbOfTuples=getNumberOfTuples();
8843   for(int i=0;i<nbOfTuples;i++,cptr++)
8844     if(*cptr>=vmin && *cptr<vmax)
8845       ret->pushBackSilent(i);
8846   return ret.retn();
8847 }
8848
8849 /*!
8850  * This method works only on data array with one component.
8851  * 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.
8852  * 
8853  * \param [in] vmin begin of range. This value is included in range (included).
8854  * \param [in] vmax end of range. This value is \b not included in range (excluded).
8855  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ).
8856  */
8857 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
8858 {
8859   checkAllocated();
8860   if(getNumberOfComponents()!=1)
8861     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
8862   int nbOfTuples=getNumberOfTuples();
8863   bool ret=true;
8864   const int *cptr=getConstPointer();
8865   for(int i=0;i<nbOfTuples;i++,cptr++)
8866     {
8867       if(*cptr>=vmin && *cptr<vmax)
8868         { ret=ret && *cptr==i; }
8869       else
8870         {
8871           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
8872           throw INTERP_KERNEL::Exception(oss.str().c_str());
8873         }
8874     }
8875   return ret;
8876 }
8877
8878 /*!
8879  * Modify all elements of \a this array, so that
8880  * an element _x_ becomes <em> val % x </em>.
8881  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
8882  *           array, all elements processed before detection of the zero element remain
8883  *           modified.
8884  *  \param [in] val - the divident used to modify array elements.
8885  *  \throw If \a this is not allocated.
8886  *  \throw If there is an element equal to or less than 0 in \a this array.
8887  */
8888 void DataArrayInt::applyRModulus(int val) throw(INTERP_KERNEL::Exception)
8889 {
8890   checkAllocated();
8891   int *ptr=getPointer();
8892   std::size_t nbOfElems=getNbOfElems();
8893   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8894     {
8895       if(*ptr>0)
8896         {
8897           *ptr=val%(*ptr);
8898         }
8899       else
8900         {
8901           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8902           oss << " !";
8903           throw INTERP_KERNEL::Exception(oss.str().c_str());
8904         }
8905     }
8906   declareAsNew();
8907 }
8908
8909 /*!
8910  * Modify all elements of \a this array, so that
8911  * an element _x_ becomes <em> val ^ x </em>.
8912  *  \param [in] val - the value used to apply pow on all array elements.
8913  *  \throw If \a this is not allocated.
8914  *  \throw If \a val < 0.
8915  */
8916 void DataArrayInt::applyPow(int val) throw(INTERP_KERNEL::Exception)
8917 {
8918   checkAllocated();
8919   if(val<0)
8920     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
8921   int *ptr=getPointer();
8922   std::size_t nbOfElems=getNbOfElems();
8923   if(val==0)
8924     {
8925       std::fill(ptr,ptr+nbOfElems,1.);
8926       return ;
8927     }
8928   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8929     {
8930       int tmp=1;
8931       for(int j=0;j<val;j++)
8932         tmp*=*ptr;
8933       *ptr=tmp;
8934     }
8935   declareAsNew();
8936 }
8937
8938 /*!
8939  * Modify all elements of \a this array, so that
8940  * an element _x_ becomes \f$ val ^ x \f$.
8941  *  \param [in] val - the value used to apply pow on all array elements.
8942  *  \throw If \a this is not allocated.
8943  *  \throw If there is an element < 0 in \a this array.
8944  *  \warning If an exception is thrown because of presence of 0 element in \a this 
8945  *           array, all elements processed before detection of the zero element remain
8946  *           modified.
8947  */
8948 void DataArrayInt::applyRPow(int val) throw(INTERP_KERNEL::Exception)
8949 {
8950   checkAllocated();
8951   int *ptr=getPointer();
8952   std::size_t nbOfElems=getNbOfElems();
8953   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
8954     {
8955       if(*ptr>=0)
8956         {
8957           int tmp=1;
8958           for(int j=0;j<*ptr;j++)
8959             tmp*=val;
8960           *ptr=tmp;
8961         }
8962       else
8963         {
8964           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
8965           oss << " !";
8966           throw INTERP_KERNEL::Exception(oss.str().c_str());
8967         }
8968     }
8969   declareAsNew();
8970 }
8971
8972 /*!
8973  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
8974  * of components in the result array is a sum of the number of components of given arrays
8975  * and (2) the number of tuples in the result array is same as that of each of given
8976  * arrays. In other words the i-th tuple of result array includes all components of
8977  * i-th tuples of all given arrays.
8978  * Number of tuples in the given arrays must be the same.
8979  *  \param [in] a1 - an array to include in the result array.
8980  *  \param [in] a2 - another array to include in the result array.
8981  *  \return DataArrayInt * - the new instance of DataArrayInt.
8982  *          The caller is to delete this result array using decrRef() as it is no more
8983  *          needed.
8984  *  \throw If both \a a1 and \a a2 are NULL.
8985  *  \throw If any given array is not allocated.
8986  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8987  */
8988 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
8989 {
8990   std::vector<const DataArrayInt *> arr(2);
8991   arr[0]=a1; arr[1]=a2;
8992   return Meld(arr);
8993 }
8994
8995 /*!
8996  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
8997  * of components in the result array is a sum of the number of components of given arrays
8998  * and (2) the number of tuples in the result array is same as that of each of given
8999  * arrays. In other words the i-th tuple of result array includes all components of
9000  * i-th tuples of all given arrays.
9001  * Number of tuples in the given arrays must be  the same.
9002  *  \param [in] arr - a sequence of arrays to include in the result array.
9003  *  \return DataArrayInt * - the new instance of DataArrayInt.
9004  *          The caller is to delete this result array using decrRef() as it is no more
9005  *          needed.
9006  *  \throw If all arrays within \a arr are NULL.
9007  *  \throw If any given array is not allocated.
9008  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9009  */
9010 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
9011 {
9012   std::vector<const DataArrayInt *> a;
9013   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9014     if(*it4)
9015       a.push_back(*it4);
9016   if(a.empty())
9017     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9018   std::vector<const DataArrayInt *>::const_iterator it;
9019   for(it=a.begin();it!=a.end();it++)
9020     (*it)->checkAllocated();
9021   it=a.begin();
9022   int nbOfTuples=(*it)->getNumberOfTuples();
9023   std::vector<int> nbc(a.size());
9024   std::vector<const int *> pts(a.size());
9025   nbc[0]=(*it)->getNumberOfComponents();
9026   pts[0]=(*it++)->getConstPointer();
9027   for(int i=1;it!=a.end();it++,i++)
9028     {
9029       if(nbOfTuples!=(*it)->getNumberOfTuples())
9030         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9031       nbc[i]=(*it)->getNumberOfComponents();
9032       pts[i]=(*it)->getConstPointer();
9033     }
9034   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9035   DataArrayInt *ret=DataArrayInt::New();
9036   ret->alloc(nbOfTuples,totalNbOfComp);
9037   int *retPtr=ret->getPointer();
9038   for(int i=0;i<nbOfTuples;i++)
9039     for(int j=0;j<(int)a.size();j++)
9040       {
9041         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9042         pts[j]+=nbc[j];
9043       }
9044   int k=0;
9045   for(int i=0;i<(int)a.size();i++)
9046     for(int j=0;j<nbc[i];j++,k++)
9047       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
9048   return ret;
9049 }
9050
9051 /*!
9052  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9053  * The i-th item of the result array is an ID of a set of elements belonging to a
9054  * unique set of groups, which the i-th element is a part of. This set of elements
9055  * belonging to a unique set of groups is called \a family, so the result array contains
9056  * IDs of families each element belongs to.
9057  *
9058  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9059  * then there are 3 families:
9060  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9061  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9062  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9063  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9064  * stands for the element #3 which is in none of groups.
9065  *
9066  *  \param [in] groups - sequence of groups of element IDs.
9067  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9068  *         in \a groups.
9069  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9070  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9071  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9072  *         delete this array using decrRef() as it is no more needed.
9073  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9074  */
9075 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) throw(INTERP_KERNEL::Exception)
9076 {
9077   std::vector<const DataArrayInt *> groups2;
9078   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9079     if(*it4)
9080       groups2.push_back(*it4);
9081   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9082   ret->alloc(newNb,1);
9083   int *retPtr=ret->getPointer();
9084   std::fill(retPtr,retPtr+newNb,0);
9085   int fid=1;
9086   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9087     {
9088       const int *ptr=(*iter)->getConstPointer();
9089       std::size_t nbOfElem=(*iter)->getNbOfElems();
9090       int sfid=fid;
9091       for(int j=0;j<sfid;j++)
9092         {
9093           bool found=false;
9094           for(std::size_t i=0;i<nbOfElem;i++)
9095             {
9096               if(ptr[i]>=0 && ptr[i]<newNb)
9097                 {
9098                   if(retPtr[ptr[i]]==j)
9099                     {
9100                       retPtr[ptr[i]]=fid;
9101                       found=true;
9102                     }
9103                 }
9104               else
9105                 {
9106                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9107                   oss << ") !";
9108                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9109                 }
9110             }
9111           if(found)
9112             fid++;
9113         }
9114     }
9115   fidsOfGroups.clear();
9116   fidsOfGroups.resize(groups2.size());
9117   int grId=0;
9118   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9119     {
9120       std::set<int> tmp;
9121       const int *ptr=(*iter)->getConstPointer();
9122       std::size_t nbOfElem=(*iter)->getNbOfElems();
9123       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9124         tmp.insert(retPtr[*p]);
9125       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9126     }
9127   return ret.retn();
9128 }
9129
9130 /*!
9131  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9132  * arrays. The result array does not contain any duplicates and its values
9133  * are sorted in ascending order.
9134  *  \param [in] arr - sequence of DataArrayInt's to unite.
9135  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9136  *         array using decrRef() as it is no more needed.
9137  *  \throw If any \a arr[i] is not allocated.
9138  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9139  */
9140 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
9141 {
9142   std::vector<const DataArrayInt *> a;
9143   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9144     if(*it4)
9145       a.push_back(*it4);
9146   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9147     {
9148       (*it)->checkAllocated();
9149       if((*it)->getNumberOfComponents()!=1)
9150         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9151     }
9152   //
9153   std::set<int> r;
9154   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9155     {
9156       const int *pt=(*it)->getConstPointer();
9157       int nbOfTuples=(*it)->getNumberOfTuples();
9158       r.insert(pt,pt+nbOfTuples);
9159     }
9160   DataArrayInt *ret=DataArrayInt::New();
9161   ret->alloc((int)r.size(),1);
9162   std::copy(r.begin(),r.end(),ret->getPointer());
9163   return ret;
9164 }
9165
9166 /*!
9167  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9168  * arrays. The result array does not contain any duplicates and its values
9169  * are sorted in ascending order.
9170  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9171  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9172  *         array using decrRef() as it is no more needed.
9173  *  \throw If any \a arr[i] is not allocated.
9174  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9175  */
9176 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
9177 {
9178   std::vector<const DataArrayInt *> a;
9179   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9180     if(*it4)
9181       a.push_back(*it4);
9182   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9183     {
9184       (*it)->checkAllocated();
9185       if((*it)->getNumberOfComponents()!=1)
9186         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9187     }
9188   //
9189   std::set<int> r;
9190   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9191     {
9192       const int *pt=(*it)->getConstPointer();
9193       int nbOfTuples=(*it)->getNumberOfTuples();
9194       std::set<int> s1(pt,pt+nbOfTuples);
9195       if(it!=a.begin())
9196         {
9197           std::set<int> r2;
9198           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9199           r=r2;
9200         }
9201       else
9202         r=s1;
9203     }
9204   DataArrayInt *ret=DataArrayInt::New();
9205   ret->alloc((int)r.size(),1);
9206   std::copy(r.begin(),r.end(),ret->getPointer());
9207   return ret;
9208 }
9209
9210 /*!
9211  * Returns a new DataArrayInt which contains a complement of elements of \a this
9212  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9213  * \a nbOfElement) not present in \a this array.
9214  *  \param [in] nbOfElement - maximal size of the result array.
9215  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9216  *         array using decrRef() as it is no more needed.
9217  *  \throw If \a this is not allocated.
9218  *  \throw If \a this->getNumberOfComponents() != 1.
9219  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9220  *         nbOfElement ).
9221  */
9222 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception)
9223 {
9224    checkAllocated();
9225    if(getNumberOfComponents()!=1)
9226      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9227    std::vector<bool> tmp(nbOfElement);
9228    const int *pt=getConstPointer();
9229    int nbOfTuples=getNumberOfTuples();
9230    for(const int *w=pt;w!=pt+nbOfTuples;w++)
9231      if(*w>=0 && *w<nbOfElement)
9232        tmp[*w]=true;
9233      else
9234        throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9235    int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9236    DataArrayInt *ret=DataArrayInt::New();
9237    ret->alloc(nbOfRetVal,1);
9238    int j=0;
9239    int *retPtr=ret->getPointer();
9240    for(int i=0;i<nbOfElement;i++)
9241      if(!tmp[i])
9242        retPtr[j++]=i;
9243    return ret;
9244 }
9245
9246 /*!
9247  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9248  * from an \a other one-dimensional array.
9249  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9250  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9251  *         caller is to delete this array using decrRef() as it is no more needed.
9252  *  \throw If \a other is NULL.
9253  *  \throw If \a other is not allocated.
9254  *  \throw If \a other->getNumberOfComponents() != 1.
9255  *  \throw If \a this is not allocated.
9256  *  \throw If \a this->getNumberOfComponents() != 1.
9257  *  \sa DataArrayInt::buildSubstractionOptimized()
9258  */
9259 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9260 {
9261   if(!other)
9262     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9263   checkAllocated();
9264   other->checkAllocated();
9265   if(getNumberOfComponents()!=1)
9266      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9267   if(other->getNumberOfComponents()!=1)
9268      throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9269   const int *pt=getConstPointer();
9270   int nbOfTuples=getNumberOfTuples();
9271   std::set<int> s1(pt,pt+nbOfTuples);
9272   pt=other->getConstPointer();
9273   nbOfTuples=other->getNumberOfTuples();
9274   std::set<int> s2(pt,pt+nbOfTuples);
9275   std::vector<int> r;
9276   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9277   DataArrayInt *ret=DataArrayInt::New();
9278   ret->alloc((int)r.size(),1);
9279   std::copy(r.begin(),r.end(),ret->getPointer());
9280   return ret;
9281 }
9282
9283 /*!
9284  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9285  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9286  * 
9287  * \param [in] other an array with one component and expected to be sorted ascendingly.
9288  * \ret list of ids in \a this but not in \a other.
9289  * \sa DataArrayInt::buildSubstraction
9290  */
9291 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9292 {
9293   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9294   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9295   checkAllocated(); other->checkAllocated();
9296   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9297   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9298   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
9299   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9300   for(;work1!=pt1End;work1++)
9301     {
9302       if(work2!=pt2End && *work1==*work2)
9303         work2++;
9304       else
9305         ret->pushBackSilent(*work1);
9306     }
9307   return ret.retn();
9308 }
9309
9310
9311 /*!
9312  * Returns a new DataArrayInt which contains all elements of \a this and a given
9313  * one-dimensional arrays. The result array does not contain any duplicates
9314  * and its values are sorted in ascending order.
9315  *  \param [in] other - an array to unite with \a this one.
9316  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9317  *         array using decrRef() as it is no more needed.
9318  *  \throw If \a this or \a other is not allocated.
9319  *  \throw If \a this->getNumberOfComponents() != 1.
9320  *  \throw If \a other->getNumberOfComponents() != 1.
9321  */
9322 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9323 {
9324   std::vector<const DataArrayInt *>arrs(2);
9325   arrs[0]=this; arrs[1]=other;
9326   return BuildUnion(arrs);
9327 }
9328
9329
9330 /*!
9331  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9332  * one-dimensional arrays. The result array does not contain any duplicates
9333  * and its values are sorted in ascending order.
9334  *  \param [in] other - an array to intersect with \a this one.
9335  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9336  *         array using decrRef() as it is no more needed.
9337  *  \throw If \a this or \a other is not allocated.
9338  *  \throw If \a this->getNumberOfComponents() != 1.
9339  *  \throw If \a other->getNumberOfComponents() != 1.
9340  */
9341 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
9342 {
9343   std::vector<const DataArrayInt *>arrs(2);
9344   arrs[0]=this; arrs[1]=other;
9345   return BuildIntersection(arrs);
9346 }
9347
9348 /*!
9349  * This method can be applied on allocated with one component DataArrayInt instance.
9350  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9351  * 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]
9352  * 
9353  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9354  * \throw if \a this is not allocated or if \a this has not exactly one component.
9355  */
9356 DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
9357 {
9358   checkAllocated();
9359   if(getNumberOfComponents()!=1)
9360      throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9361   int nbOfTuples=getNumberOfTuples();
9362   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9363   int *data=tmp->getPointer();
9364   int *last=std::unique(data,data+nbOfTuples);
9365   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9366   ret->alloc(std::distance(data,last),1);
9367   std::copy(data,last,ret->getPointer());
9368   return ret.retn();
9369 }
9370
9371 /*!
9372  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9373  * "index" array. Such "index" array is returned for example by 
9374  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9375  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9376  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9377  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9378  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
9379  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9380  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9381  *          The caller is to delete this array using decrRef() as it is no more needed. 
9382  *  \throw If \a this is not allocated.
9383  *  \throw If \a this->getNumberOfComponents() != 1.
9384  *  \throw If \a this->getNumberOfTuples() < 2.
9385  *
9386  *  \b Example: <br> 
9387  *         - this contains [1,3,6,7,7,9,15]
9388  *         - result array contains [2,3,1,0,2,6],
9389  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9390  *
9391  * \sa DataArrayInt::computeOffsets2
9392  */
9393 DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception)
9394 {
9395   checkAllocated();
9396   if(getNumberOfComponents()!=1)
9397      throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9398   int nbOfTuples=getNumberOfTuples();
9399   if(nbOfTuples<2)
9400     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9401   const int *ptr=getConstPointer();
9402   DataArrayInt *ret=DataArrayInt::New();
9403   ret->alloc(nbOfTuples-1,1);
9404   int *out=ret->getPointer();
9405   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9406   return ret;
9407 }
9408
9409 /*!
9410  * Modifies \a this one-dimensional array so that value of each element \a x
9411  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9412  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9413  * and components remains the same.<br>
9414  * This method is useful for allToAllV in MPI with contiguous policy. This method
9415  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9416  * this one.
9417  *  \throw If \a this is not allocated.
9418  *  \throw If \a this->getNumberOfComponents() != 1.
9419  *
9420  *  \b Example: <br>
9421  *          - Before \a this contains [3,5,1,2,0,8]
9422  *          - After \a this contains  [0,3,8,9,11,11]<br>
9423  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9424  *          array is retained and thus there is no space to store the last element.
9425  */
9426 void DataArrayInt::computeOffsets() throw(INTERP_KERNEL::Exception)
9427 {
9428   checkAllocated();
9429   if(getNumberOfComponents()!=1)
9430      throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9431   int nbOfTuples=getNumberOfTuples();
9432   if(nbOfTuples==0)
9433     return ;
9434   int *work=getPointer();
9435   int tmp=work[0];
9436   work[0]=0;
9437   for(int i=1;i<nbOfTuples;i++)
9438     {
9439       int tmp2=work[i];
9440       work[i]=work[i-1]+tmp;
9441       tmp=tmp2;
9442     }
9443   declareAsNew();
9444 }
9445
9446
9447 /*!
9448  * Modifies \a this one-dimensional array so that value of each element \a x
9449  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9450  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9451  * components remains the same and number of tuples is inceamented by one.<br>
9452  * This method is useful for allToAllV in MPI with contiguous policy. This method
9453  * differs from computeOffsets() in that the number of tuples is changed by this one.
9454  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9455  *  \throw If \a this is not allocated.
9456  *  \throw If \a this->getNumberOfComponents() != 1.
9457  *
9458  *  \b Example: <br>
9459  *          - Before \a this contains [3,5,1,2,0,8]
9460  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9461  * \sa DataArrayInt::deltaShiftIndex
9462  */
9463 void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
9464 {
9465   checkAllocated();
9466   if(getNumberOfComponents()!=1)
9467     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9468   int nbOfTuples=getNumberOfTuples();
9469   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9470   if(nbOfTuples==0)
9471     return ;
9472   const int *work=getConstPointer();
9473   ret[0]=0;
9474   for(int i=0;i<nbOfTuples;i++)
9475     ret[i+1]=work[i]+ret[i];
9476   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9477   declareAsNew();
9478 }
9479
9480 /*!
9481  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9482  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9483  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9484  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9485  * filling completely one of the ranges in \a this.
9486  *
9487  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9488  * \param [out] rangeIdsFetched the range ids fetched
9489  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9490  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9491  *
9492  * \sa DataArrayInt::computeOffsets2
9493  *
9494  *  \b Example: <br>
9495  *          - \a this : [0,3,7,9,15,18]
9496  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9497  *          - \a rangeIdsFetched result array: [0,2,4]
9498  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9499  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9500  * <br>
9501  */
9502 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const throw(INTERP_KERNEL::Exception)
9503 {
9504   if(!listOfIds)
9505     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
9506   listOfIds->checkAllocated(); checkAllocated();
9507   if(listOfIds->getNumberOfComponents()!=1)
9508     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
9509   if(getNumberOfComponents()!=1)
9510     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
9511   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
9512   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
9513   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
9514   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
9515   while(tupPtr!=tupEnd && offPtr!=offEnd)
9516     {
9517       if(*tupPtr==*offPtr)
9518         {
9519           int i=offPtr[0];
9520           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
9521           if(i==offPtr[1])
9522             {
9523               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
9524               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
9525               offPtr++;
9526             }
9527         }
9528       else
9529         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
9530     }
9531   rangeIdsFetched=ret0.retn();
9532   idsInInputListThatFetch=ret1.retn();
9533 }
9534
9535 /*!
9536  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
9537  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
9538  * "index" array of a "iota" array, thus, whose each element gives an index of a group
9539  * beginning within the "iota" array. And \a this is a one-dimensional array
9540  * considered as a selector of groups described by \a offsets to include into the result array.
9541  *  \throw If \a offsets is NULL.
9542  *  \throw If \a offsets is not allocated.
9543  *  \throw If \a offsets->getNumberOfComponents() != 1.
9544  *  \throw If \a offsets is not monotonically increasing.
9545  *  \throw If \a this is not allocated.
9546  *  \throw If \a this->getNumberOfComponents() != 1.
9547  *  \throw If any element of \a this is not a valid index for \a offsets array.
9548  *
9549  *  \b Example: <br>
9550  *          - \a this: [0,2,3]
9551  *          - \a offsets: [0,3,6,10,14,20]
9552  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
9553  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
9554  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
9555  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
9556  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
9557  */
9558 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception)
9559 {
9560   if(!offsets)
9561     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
9562   checkAllocated();
9563   if(getNumberOfComponents()!=1)
9564      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
9565   offsets->checkAllocated();
9566   if(offsets->getNumberOfComponents()!=1)
9567      throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
9568   int othNbTuples=offsets->getNumberOfTuples()-1;
9569   int nbOfTuples=getNumberOfTuples();
9570   int retNbOftuples=0;
9571   const int *work=getConstPointer();
9572   const int *offPtr=offsets->getConstPointer();
9573   for(int i=0;i<nbOfTuples;i++)
9574     {
9575       int val=work[i];
9576       if(val>=0 && val<othNbTuples)
9577         {
9578           int delta=offPtr[val+1]-offPtr[val];
9579           if(delta>=0)
9580             retNbOftuples+=delta;
9581           else
9582             {
9583               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
9584               throw INTERP_KERNEL::Exception(oss.str().c_str());
9585             }
9586         }
9587       else
9588         {
9589           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
9590           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
9591           throw INTERP_KERNEL::Exception(oss.str().c_str());
9592         }
9593     }
9594   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9595   ret->alloc(retNbOftuples,1);
9596   int *retPtr=ret->getPointer();
9597   for(int i=0;i<nbOfTuples;i++)
9598     {
9599       int val=work[i];
9600       int start=offPtr[val];
9601       int off=offPtr[val+1]-start;
9602       for(int j=0;j<off;j++,retPtr++)
9603         *retPtr=start+j;
9604     }
9605   return ret.retn();
9606 }
9607
9608 /*!
9609  * 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.
9610  * 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
9611  * in tuple **i** of returned DataArrayInt.
9612  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
9613  *
9614  * 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)]
9615  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
9616  * 
9617  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9618  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9619  * \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
9620  *        is thrown if no ranges in \a ranges contains value in \a this.
9621  * 
9622  * \sa DataArrayInt::findIdInRangeForEachTuple
9623  */
9624 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9625 {
9626   if(!ranges)
9627     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
9628   if(ranges->getNumberOfComponents()!=2)
9629     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
9630   checkAllocated();
9631   if(getNumberOfComponents()!=1)
9632     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
9633   int nbTuples=getNumberOfTuples();
9634   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9635   int nbOfRanges=ranges->getNumberOfTuples();
9636   const int *rangesPtr=ranges->getConstPointer();
9637   int *retPtr=ret->getPointer();
9638   const int *inPtr=getConstPointer();
9639   for(int i=0;i<nbTuples;i++,retPtr++)
9640     {
9641       int val=inPtr[i];
9642       bool found=false;
9643       for(int j=0;j<nbOfRanges && !found;j++)
9644         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9645           { *retPtr=j; found=true; }
9646       if(found)
9647         continue;
9648       else
9649         {
9650           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
9651           throw INTERP_KERNEL::Exception(oss.str().c_str());
9652         }
9653     }
9654   return ret.retn();
9655 }
9656
9657 /*!
9658  * 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.
9659  * 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
9660  * in tuple **i** of returned DataArrayInt.
9661  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
9662  *
9663  * 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)]
9664  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
9665  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
9666  * 
9667  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
9668  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
9669  * \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
9670  *        is thrown if no ranges in \a ranges contains value in \a this.
9671  * \sa DataArrayInt::findRangeIdForEachTuple
9672  */
9673 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception)
9674 {
9675   if(!ranges)
9676     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
9677   if(ranges->getNumberOfComponents()!=2)
9678     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
9679   checkAllocated();
9680   if(getNumberOfComponents()!=1)
9681     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
9682   int nbTuples=getNumberOfTuples();
9683   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
9684   int nbOfRanges=ranges->getNumberOfTuples();
9685   const int *rangesPtr=ranges->getConstPointer();
9686   int *retPtr=ret->getPointer();
9687   const int *inPtr=getConstPointer();
9688   for(int i=0;i<nbTuples;i++,retPtr++)
9689     {
9690       int val=inPtr[i];
9691       bool found=false;
9692       for(int j=0;j<nbOfRanges && !found;j++)
9693         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
9694           { *retPtr=val-rangesPtr[2*j]; found=true; }
9695       if(found)
9696         continue;
9697       else
9698         {
9699           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
9700           throw INTERP_KERNEL::Exception(oss.str().c_str());
9701         }
9702     }
9703   return ret.retn();
9704 }
9705
9706 /*!
9707  * 
9708  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
9709  *             \a nbTimes  should be at least equal to 1.
9710  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
9711  * \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.
9712  */
9713 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception)
9714 {
9715   checkAllocated();
9716   if(getNumberOfComponents()!=1)
9717     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
9718   if(nbTimes<1)
9719     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
9720   int nbTuples=getNumberOfTuples();
9721   const int *inPtr=getConstPointer();
9722   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
9723   int *retPtr=ret->getPointer();
9724   for(int i=0;i<nbTuples;i++,inPtr++)
9725     {
9726       int val=*inPtr;
9727       for(int j=0;j<nbTimes;j++,retPtr++)
9728         *retPtr=val;
9729     }
9730   ret->copyStringInfoFrom(*this);
9731   return ret.retn();
9732 }
9733
9734 /*!
9735  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
9736  * But the number of components can be different from one.
9737  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
9738  */
9739 DataArrayInt *DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception)
9740 {
9741   checkAllocated();
9742   std::set<int> ret;
9743   ret.insert(begin(),end());
9744   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
9745   std::copy(ret.begin(),ret.end(),ret2->getPointer());
9746   return ret2.retn();
9747 }
9748
9749 /*!
9750  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
9751  * them it tells which tuple id have this id.
9752  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
9753  * This method returns two arrays having same size.
9754  * 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.
9755  * 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]]
9756  */
9757 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception)
9758 {
9759   checkAllocated();
9760   if(getNumberOfComponents()!=1)
9761     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
9762   int id=0;
9763   std::map<int,int> m,m2,m3;
9764   for(const int *w=begin();w!=end();w++)
9765     m[*w]++;
9766   differentIds.resize(m.size());
9767   std::vector<DataArrayInt *> ret(m.size());
9768   std::vector<int *> retPtr(m.size());
9769   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
9770     {
9771       m2[(*it).first]=id;
9772       ret[id]=DataArrayInt::New();
9773       ret[id]->alloc((*it).second,1);
9774       retPtr[id]=ret[id]->getPointer();
9775       differentIds[id]=(*it).first;
9776     }
9777   id=0;
9778   for(const int *w=begin();w!=end();w++,id++)
9779     {
9780       retPtr[m2[*w]][m3[*w]++]=id;
9781     }
9782   return ret;
9783 }
9784
9785 /*!
9786  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
9787  * valid cases.
9788  * 1.  The arrays have same number of tuples and components. Then each value of
9789  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
9790  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
9791  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9792  *   component. Then
9793  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
9794  * 3.  The arrays have same number of components and one array, say _a2_, has one
9795  *   tuple. Then
9796  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
9797  *
9798  * Info on components is copied either from the first array (in the first case) or from
9799  * the array with maximal number of elements (getNbOfElems()).
9800  *  \param [in] a1 - an array to sum up.
9801  *  \param [in] a2 - another array to sum up.
9802  *  \return DataArrayInt * - the new instance of DataArrayInt.
9803  *          The caller is to delete this result array using decrRef() as it is no more
9804  *          needed.
9805  *  \throw If either \a a1 or \a a2 is NULL.
9806  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9807  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9808  *         none of them has number of tuples or components equal to 1.
9809  */
9810 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9811 {
9812   if(!a1 || !a2)
9813     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
9814   int nbOfTuple=a1->getNumberOfTuples();
9815   int nbOfTuple2=a2->getNumberOfTuples();
9816   int nbOfComp=a1->getNumberOfComponents();
9817   int nbOfComp2=a2->getNumberOfComponents();
9818   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
9819   if(nbOfTuple==nbOfTuple2)
9820     {
9821       if(nbOfComp==nbOfComp2)
9822         {
9823           ret=DataArrayInt::New();
9824           ret->alloc(nbOfTuple,nbOfComp);
9825           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
9826           ret->copyStringInfoFrom(*a1);
9827         }
9828       else
9829         {
9830           int nbOfCompMin,nbOfCompMax;
9831           const DataArrayInt *aMin, *aMax;
9832           if(nbOfComp>nbOfComp2)
9833             {
9834               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
9835               aMin=a2; aMax=a1;
9836             }
9837           else
9838             {
9839               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
9840               aMin=a1; aMax=a2;
9841             }
9842           if(nbOfCompMin==1)
9843             {
9844               ret=DataArrayInt::New();
9845               ret->alloc(nbOfTuple,nbOfCompMax);
9846               const int *aMinPtr=aMin->getConstPointer();
9847               const int *aMaxPtr=aMax->getConstPointer();
9848               int *res=ret->getPointer();
9849               for(int i=0;i<nbOfTuple;i++)
9850                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
9851               ret->copyStringInfoFrom(*aMax);
9852             }
9853           else
9854             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9855         }
9856     }
9857   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
9858     {
9859       if(nbOfComp==nbOfComp2)
9860         {
9861           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
9862           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
9863           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
9864           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
9865           ret=DataArrayInt::New();
9866           ret->alloc(nbOfTupleMax,nbOfComp);
9867           int *res=ret->getPointer();
9868           for(int i=0;i<nbOfTupleMax;i++)
9869             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
9870           ret->copyStringInfoFrom(*aMax);
9871         }
9872       else
9873         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
9874     }
9875   else
9876     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
9877   return ret.retn();
9878 }
9879
9880 /*!
9881  * Adds values of another DataArrayInt to values of \a this one. There are 3
9882  * valid cases.
9883  * 1.  The arrays have same number of tuples and components. Then each value of
9884  *   \a other array is added to the corresponding value of \a this array, i.e.:
9885  *   _a_ [ i, j ] += _other_ [ i, j ].
9886  * 2.  The arrays have same number of tuples and \a other array has one component. Then
9887  *   _a_ [ i, j ] += _other_ [ i, 0 ].
9888  * 3.  The arrays have same number of components and \a other array has one tuple. Then
9889  *   _a_ [ i, j ] += _a2_ [ 0, j ].
9890  *
9891  *  \param [in] other - an array to add to \a this one.
9892  *  \throw If \a other is NULL.
9893  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
9894  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
9895  *         \a other has number of both tuples and components not equal to 1.
9896  */
9897 void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
9898 {
9899   if(!other)
9900     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
9901   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
9902   checkAllocated(); other->checkAllocated();
9903   int nbOfTuple=getNumberOfTuples();
9904   int nbOfTuple2=other->getNumberOfTuples();
9905   int nbOfComp=getNumberOfComponents();
9906   int nbOfComp2=other->getNumberOfComponents();
9907   if(nbOfTuple==nbOfTuple2)
9908     {
9909       if(nbOfComp==nbOfComp2)
9910         {
9911           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
9912         }
9913       else if(nbOfComp2==1)
9914         {
9915           int *ptr=getPointer();
9916           const int *ptrc=other->getConstPointer();
9917           for(int i=0;i<nbOfTuple;i++)
9918             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
9919         }
9920       else
9921         throw INTERP_KERNEL::Exception(msg);
9922     }
9923   else if(nbOfTuple2==1)
9924     {
9925       if(nbOfComp2==nbOfComp)
9926         {
9927           int *ptr=getPointer();
9928           const int *ptrc=other->getConstPointer();
9929           for(int i=0;i<nbOfTuple;i++)
9930             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
9931         }
9932       else
9933         throw INTERP_KERNEL::Exception(msg);
9934     }
9935   else
9936     throw INTERP_KERNEL::Exception(msg);
9937   declareAsNew();
9938 }
9939
9940 /*!
9941  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
9942  * valid cases.
9943  * 1.  The arrays have same number of tuples and components. Then each value of
9944  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
9945  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
9946  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
9947  *   component. Then
9948  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
9949  * 3.  The arrays have same number of components and one array, say _a2_, has one
9950  *   tuple. Then
9951  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
9952  *
9953  * Info on components is copied either from the first array (in the first case) or from
9954  * the array with maximal number of elements (getNbOfElems()).
9955  *  \param [in] a1 - an array to subtract from.
9956  *  \param [in] a2 - an array to subtract.
9957  *  \return DataArrayInt * - the new instance of DataArrayInt.
9958  *          The caller is to delete this result array using decrRef() as it is no more
9959  *          needed.
9960  *  \throw If either \a a1 or \a a2 is NULL.
9961  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
9962  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
9963  *         none of them has number of tuples or components equal to 1.
9964  */
9965 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
9966 {
9967   if(!a1 || !a2)
9968     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
9969   int nbOfTuple1=a1->getNumberOfTuples();
9970   int nbOfTuple2=a2->getNumberOfTuples();
9971   int nbOfComp1=a1->getNumberOfComponents();
9972   int nbOfComp2=a2->getNumberOfComponents();
9973   if(nbOfTuple2==nbOfTuple1)
9974     {
9975       if(nbOfComp1==nbOfComp2)
9976         {
9977           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9978           ret->alloc(nbOfTuple2,nbOfComp1);
9979           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
9980           ret->copyStringInfoFrom(*a1);
9981           return ret.retn();
9982         }
9983       else if(nbOfComp2==1)
9984         {
9985           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9986           ret->alloc(nbOfTuple1,nbOfComp1);
9987           const int *a2Ptr=a2->getConstPointer();
9988           const int *a1Ptr=a1->getConstPointer();
9989           int *res=ret->getPointer();
9990           for(int i=0;i<nbOfTuple1;i++)
9991             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
9992           ret->copyStringInfoFrom(*a1);
9993           return ret.retn();
9994         }
9995       else
9996         {
9997           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
9998           return 0;
9999         }
10000     }
10001   else if(nbOfTuple2==1)
10002     {
10003       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10004       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10005       ret->alloc(nbOfTuple1,nbOfComp1);
10006       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10007       int *pt=ret->getPointer();
10008       for(int i=0;i<nbOfTuple1;i++)
10009         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
10010       ret->copyStringInfoFrom(*a1);
10011       return ret.retn();
10012     }
10013   else
10014     {
10015       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
10016       return 0;
10017     }
10018 }
10019
10020 /*!
10021  * Subtract values of another DataArrayInt from values of \a this one. There are 3
10022  * valid cases.
10023  * 1.  The arrays have same number of tuples and components. Then each value of
10024  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
10025  *   _a_ [ i, j ] -= _other_ [ i, j ].
10026  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10027  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
10028  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10029  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
10030  *
10031  *  \param [in] other - an array to subtract from \a this one.
10032  *  \throw If \a other is NULL.
10033  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10034  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10035  *         \a other has number of both tuples and components not equal to 1.
10036  */
10037 void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10038 {
10039   if(!other)
10040     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
10041   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
10042   checkAllocated(); other->checkAllocated();
10043   int nbOfTuple=getNumberOfTuples();
10044   int nbOfTuple2=other->getNumberOfTuples();
10045   int nbOfComp=getNumberOfComponents();
10046   int nbOfComp2=other->getNumberOfComponents();
10047   if(nbOfTuple==nbOfTuple2)
10048     {
10049       if(nbOfComp==nbOfComp2)
10050         {
10051           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
10052         }
10053       else if(nbOfComp2==1)
10054         {
10055           int *ptr=getPointer();
10056           const int *ptrc=other->getConstPointer();
10057           for(int i=0;i<nbOfTuple;i++)
10058             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
10059         }
10060       else
10061         throw INTERP_KERNEL::Exception(msg);
10062     }
10063   else if(nbOfTuple2==1)
10064     {
10065       int *ptr=getPointer();
10066       const int *ptrc=other->getConstPointer();
10067       for(int i=0;i<nbOfTuple;i++)
10068         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
10069     }
10070   else
10071     throw INTERP_KERNEL::Exception(msg);
10072   declareAsNew();
10073 }
10074
10075 /*!
10076  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
10077  * valid cases.
10078  * 1.  The arrays have same number of tuples and components. Then each value of
10079  *   the result array (_a_) is a product of the corresponding values of \a a1 and
10080  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
10081  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10082  *   component. Then
10083  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
10084  * 3.  The arrays have same number of components and one array, say _a2_, has one
10085  *   tuple. Then
10086  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
10087  *
10088  * Info on components is copied either from the first array (in the first case) or from
10089  * the array with maximal number of elements (getNbOfElems()).
10090  *  \param [in] a1 - a factor array.
10091  *  \param [in] a2 - another factor array.
10092  *  \return DataArrayInt * - the new instance of DataArrayInt.
10093  *          The caller is to delete this result array using decrRef() as it is no more
10094  *          needed.
10095  *  \throw If either \a a1 or \a a2 is NULL.
10096  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10097  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10098  *         none of them has number of tuples or components equal to 1.
10099  */
10100 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10101 {
10102   if(!a1 || !a2)
10103     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
10104   int nbOfTuple=a1->getNumberOfTuples();
10105   int nbOfTuple2=a2->getNumberOfTuples();
10106   int nbOfComp=a1->getNumberOfComponents();
10107   int nbOfComp2=a2->getNumberOfComponents();
10108   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10109   if(nbOfTuple==nbOfTuple2)
10110     {
10111       if(nbOfComp==nbOfComp2)
10112         {
10113           ret=DataArrayInt::New();
10114           ret->alloc(nbOfTuple,nbOfComp);
10115           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
10116           ret->copyStringInfoFrom(*a1);
10117         }
10118       else
10119         {
10120           int nbOfCompMin,nbOfCompMax;
10121           const DataArrayInt *aMin, *aMax;
10122           if(nbOfComp>nbOfComp2)
10123             {
10124               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10125               aMin=a2; aMax=a1;
10126             }
10127           else
10128             {
10129               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10130               aMin=a1; aMax=a2;
10131             }
10132           if(nbOfCompMin==1)
10133             {
10134               ret=DataArrayInt::New();
10135               ret->alloc(nbOfTuple,nbOfCompMax);
10136               const int *aMinPtr=aMin->getConstPointer();
10137               const int *aMaxPtr=aMax->getConstPointer();
10138               int *res=ret->getPointer();
10139               for(int i=0;i<nbOfTuple;i++)
10140                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
10141               ret->copyStringInfoFrom(*aMax);
10142             }
10143           else
10144             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10145         }
10146     }
10147   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10148     {
10149       if(nbOfComp==nbOfComp2)
10150         {
10151           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10152           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10153           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10154           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10155           ret=DataArrayInt::New();
10156           ret->alloc(nbOfTupleMax,nbOfComp);
10157           int *res=ret->getPointer();
10158           for(int i=0;i<nbOfTupleMax;i++)
10159             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
10160           ret->copyStringInfoFrom(*aMax);
10161         }
10162       else
10163         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10164     }
10165   else
10166     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
10167   return ret.retn();
10168 }
10169
10170
10171 /*!
10172  * Multiply values of another DataArrayInt to values of \a this one. There are 3
10173  * valid cases.
10174  * 1.  The arrays have same number of tuples and components. Then each value of
10175  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
10176  *   _a_ [ i, j ] *= _other_ [ i, j ].
10177  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10178  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
10179  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10180  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
10181  *
10182  *  \param [in] other - an array to multiply to \a this one.
10183  *  \throw If \a other is NULL.
10184  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10185  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10186  *         \a other has number of both tuples and components not equal to 1.
10187  */
10188 void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10189 {
10190   if(!other)
10191     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
10192   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
10193   checkAllocated(); other->checkAllocated();
10194   int nbOfTuple=getNumberOfTuples();
10195   int nbOfTuple2=other->getNumberOfTuples();
10196   int nbOfComp=getNumberOfComponents();
10197   int nbOfComp2=other->getNumberOfComponents();
10198   if(nbOfTuple==nbOfTuple2)
10199     {
10200       if(nbOfComp==nbOfComp2)
10201         {
10202           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
10203         }
10204       else if(nbOfComp2==1)
10205         {
10206           int *ptr=getPointer();
10207           const int *ptrc=other->getConstPointer();
10208           for(int i=0;i<nbOfTuple;i++)
10209             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10210         }
10211       else
10212         throw INTERP_KERNEL::Exception(msg);
10213     }
10214   else if(nbOfTuple2==1)
10215     {
10216       if(nbOfComp2==nbOfComp)
10217         {
10218           int *ptr=getPointer();
10219           const int *ptrc=other->getConstPointer();
10220           for(int i=0;i<nbOfTuple;i++)
10221             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10222         }
10223       else
10224         throw INTERP_KERNEL::Exception(msg);
10225     }
10226   else
10227     throw INTERP_KERNEL::Exception(msg);
10228   declareAsNew();
10229 }
10230
10231
10232 /*!
10233  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10234  * valid cases.
10235  * 1.  The arrays have same number of tuples and components. Then each value of
10236  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10237  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10238  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10239  *   component. Then
10240  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10241  * 3.  The arrays have same number of components and one array, say _a2_, has one
10242  *   tuple. Then
10243  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10244  *
10245  * Info on components is copied either from the first array (in the first case) or from
10246  * the array with maximal number of elements (getNbOfElems()).
10247  *  \warning No check of division by zero is performed!
10248  *  \param [in] a1 - a numerator array.
10249  *  \param [in] a2 - a denominator array.
10250  *  \return DataArrayInt * - the new instance of DataArrayInt.
10251  *          The caller is to delete this result array using decrRef() as it is no more
10252  *          needed.
10253  *  \throw If either \a a1 or \a a2 is NULL.
10254  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10255  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10256  *         none of them has number of tuples or components equal to 1.
10257  */
10258 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10259 {
10260   if(!a1 || !a2)
10261     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10262   int nbOfTuple1=a1->getNumberOfTuples();
10263   int nbOfTuple2=a2->getNumberOfTuples();
10264   int nbOfComp1=a1->getNumberOfComponents();
10265   int nbOfComp2=a2->getNumberOfComponents();
10266   if(nbOfTuple2==nbOfTuple1)
10267     {
10268       if(nbOfComp1==nbOfComp2)
10269         {
10270           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10271           ret->alloc(nbOfTuple2,nbOfComp1);
10272           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10273           ret->copyStringInfoFrom(*a1);
10274           return ret.retn();
10275         }
10276       else if(nbOfComp2==1)
10277         {
10278           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10279           ret->alloc(nbOfTuple1,nbOfComp1);
10280           const int *a2Ptr=a2->getConstPointer();
10281           const int *a1Ptr=a1->getConstPointer();
10282           int *res=ret->getPointer();
10283           for(int i=0;i<nbOfTuple1;i++)
10284             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10285           ret->copyStringInfoFrom(*a1);
10286           return ret.retn();
10287         }
10288       else
10289         {
10290           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10291           return 0;
10292         }
10293     }
10294   else if(nbOfTuple2==1)
10295     {
10296       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10297       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10298       ret->alloc(nbOfTuple1,nbOfComp1);
10299       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10300       int *pt=ret->getPointer();
10301       for(int i=0;i<nbOfTuple1;i++)
10302         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10303       ret->copyStringInfoFrom(*a1);
10304       return ret.retn();
10305     }
10306   else
10307     {
10308       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10309       return 0;
10310     }
10311 }
10312
10313 /*!
10314  * Divide values of \a this array by values of another DataArrayInt. There are 3
10315  * valid cases.
10316  * 1.  The arrays have same number of tuples and components. Then each value of
10317  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10318  *   _a_ [ i, j ] /= _other_ [ i, j ].
10319  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10320  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10321  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10322  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10323  *
10324  *  \warning No check of division by zero is performed!
10325  *  \param [in] other - an array to divide \a this one by.
10326  *  \throw If \a other is NULL.
10327  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10328  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10329  *         \a other has number of both tuples and components not equal to 1.
10330  */
10331 void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10332 {
10333   if(!other)
10334     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10335   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10336   checkAllocated(); other->checkAllocated();
10337   int nbOfTuple=getNumberOfTuples();
10338   int nbOfTuple2=other->getNumberOfTuples();
10339   int nbOfComp=getNumberOfComponents();
10340   int nbOfComp2=other->getNumberOfComponents();
10341   if(nbOfTuple==nbOfTuple2)
10342     {
10343       if(nbOfComp==nbOfComp2)
10344         {
10345           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10346         }
10347       else if(nbOfComp2==1)
10348         {
10349           int *ptr=getPointer();
10350           const int *ptrc=other->getConstPointer();
10351           for(int i=0;i<nbOfTuple;i++)
10352             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10353         }
10354       else
10355         throw INTERP_KERNEL::Exception(msg);
10356     }
10357   else if(nbOfTuple2==1)
10358     {
10359       if(nbOfComp2==nbOfComp)
10360         {
10361           int *ptr=getPointer();
10362           const int *ptrc=other->getConstPointer();
10363           for(int i=0;i<nbOfTuple;i++)
10364             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10365         }
10366       else
10367         throw INTERP_KERNEL::Exception(msg);
10368     }
10369   else
10370     throw INTERP_KERNEL::Exception(msg);
10371   declareAsNew();
10372 }
10373
10374
10375 /*!
10376  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10377  * valid cases.
10378  * 1.  The arrays have same number of tuples and components. Then each value of
10379  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10380  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10381  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10382  *   component. Then
10383  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10384  * 3.  The arrays have same number of components and one array, say _a2_, has one
10385  *   tuple. Then
10386  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10387  *
10388  * Info on components is copied either from the first array (in the first case) or from
10389  * the array with maximal number of elements (getNbOfElems()).
10390  *  \warning No check of division by zero is performed!
10391  *  \param [in] a1 - a dividend array.
10392  *  \param [in] a2 - a divisor array.
10393  *  \return DataArrayInt * - the new instance of DataArrayInt.
10394  *          The caller is to delete this result array using decrRef() as it is no more
10395  *          needed.
10396  *  \throw If either \a a1 or \a a2 is NULL.
10397  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10398  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10399  *         none of them has number of tuples or components equal to 1.
10400  */
10401 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10402 {
10403     if(!a1 || !a2)
10404     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10405   int nbOfTuple1=a1->getNumberOfTuples();
10406   int nbOfTuple2=a2->getNumberOfTuples();
10407   int nbOfComp1=a1->getNumberOfComponents();
10408   int nbOfComp2=a2->getNumberOfComponents();
10409   if(nbOfTuple2==nbOfTuple1)
10410     {
10411       if(nbOfComp1==nbOfComp2)
10412         {
10413           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10414           ret->alloc(nbOfTuple2,nbOfComp1);
10415           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
10416           ret->copyStringInfoFrom(*a1);
10417           return ret.retn();
10418         }
10419       else if(nbOfComp2==1)
10420         {
10421           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10422           ret->alloc(nbOfTuple1,nbOfComp1);
10423           const int *a2Ptr=a2->getConstPointer();
10424           const int *a1Ptr=a1->getConstPointer();
10425           int *res=ret->getPointer();
10426           for(int i=0;i<nbOfTuple1;i++)
10427             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
10428           ret->copyStringInfoFrom(*a1);
10429           return ret.retn();
10430         }
10431       else
10432         {
10433           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10434           return 0;
10435         }
10436     }
10437   else if(nbOfTuple2==1)
10438     {
10439       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
10440       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10441       ret->alloc(nbOfTuple1,nbOfComp1);
10442       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10443       int *pt=ret->getPointer();
10444       for(int i=0;i<nbOfTuple1;i++)
10445         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
10446       ret->copyStringInfoFrom(*a1);
10447       return ret.retn();
10448     }
10449   else
10450     {
10451       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
10452       return 0;
10453     }
10454 }
10455
10456 /*!
10457  * Modify \a this array so that each value becomes a modulus of division of this value by
10458  * a value of another DataArrayInt. There are 3 valid cases.
10459  * 1.  The arrays have same number of tuples and components. Then each value of
10460  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10461  *   _a_ [ i, j ] %= _other_ [ i, j ].
10462  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10463  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
10464  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10465  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
10466  *
10467  *  \warning No check of division by zero is performed!
10468  *  \param [in] other - a divisor array.
10469  *  \throw If \a other is NULL.
10470  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10471  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10472  *         \a other has number of both tuples and components not equal to 1.
10473  */
10474 void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10475 {
10476   if(!other)
10477     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
10478   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
10479   checkAllocated(); other->checkAllocated();
10480   int nbOfTuple=getNumberOfTuples();
10481   int nbOfTuple2=other->getNumberOfTuples();
10482   int nbOfComp=getNumberOfComponents();
10483   int nbOfComp2=other->getNumberOfComponents();
10484   if(nbOfTuple==nbOfTuple2)
10485     {
10486       if(nbOfComp==nbOfComp2)
10487         {
10488           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
10489         }
10490       else if(nbOfComp2==1)
10491         {
10492           if(nbOfComp2==nbOfComp)
10493             {
10494               int *ptr=getPointer();
10495               const int *ptrc=other->getConstPointer();
10496               for(int i=0;i<nbOfTuple;i++)
10497                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
10498             }
10499           else
10500             throw INTERP_KERNEL::Exception(msg);
10501         }
10502       else
10503         throw INTERP_KERNEL::Exception(msg);
10504     }
10505   else if(nbOfTuple2==1)
10506     {
10507       int *ptr=getPointer();
10508       const int *ptrc=other->getConstPointer();
10509       for(int i=0;i<nbOfTuple;i++)
10510         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
10511     }
10512   else
10513     throw INTERP_KERNEL::Exception(msg);
10514   declareAsNew();
10515 }
10516
10517 /*!
10518  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
10519  * valid cases.
10520  *
10521  *  \param [in] a1 - an array to pow up.
10522  *  \param [in] a2 - another array to sum up.
10523  *  \return DataArrayInt * - the new instance of DataArrayInt.
10524  *          The caller is to delete this result array using decrRef() as it is no more
10525  *          needed.
10526  *  \throw If either \a a1 or \a a2 is NULL.
10527  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
10528  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
10529  *  \throw If there is a negative value in \a a2.
10530  */
10531 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception)
10532 {
10533   if(!a1 || !a2)
10534     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
10535   int nbOfTuple=a1->getNumberOfTuples();
10536   int nbOfTuple2=a2->getNumberOfTuples();
10537   int nbOfComp=a1->getNumberOfComponents();
10538   int nbOfComp2=a2->getNumberOfComponents();
10539   if(nbOfTuple!=nbOfTuple2)
10540     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
10541   if(nbOfComp!=1 || nbOfComp2!=1)
10542     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
10543   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
10544   const int *ptr1(a1->begin()),*ptr2(a2->begin());
10545   int *ptr=ret->getPointer();
10546   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
10547     {
10548       if(*ptr2>=0)
10549         {
10550           int tmp=1;
10551           for(int j=0;j<*ptr2;j++)
10552             tmp*=*ptr1;
10553           *ptr=tmp;
10554         }
10555       else
10556         {
10557           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
10558           throw INTERP_KERNEL::Exception(oss.str().c_str());
10559         }
10560     }
10561   return ret.retn();
10562 }
10563
10564 /*!
10565  * Apply pow on values of another DataArrayInt to values of \a this one.
10566  *
10567  *  \param [in] other - an array to pow to \a this one.
10568  *  \throw If \a other is NULL.
10569  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
10570  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
10571  *  \throw If there is a negative value in \a other.
10572  */
10573 void DataArrayInt::powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
10574 {
10575   if(!other)
10576     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
10577   int nbOfTuple=getNumberOfTuples();
10578   int nbOfTuple2=other->getNumberOfTuples();
10579   int nbOfComp=getNumberOfComponents();
10580   int nbOfComp2=other->getNumberOfComponents();
10581   if(nbOfTuple!=nbOfTuple2)
10582     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
10583   if(nbOfComp!=1 || nbOfComp2!=1)
10584     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
10585   int *ptr=getPointer();
10586   const int *ptrc=other->begin();
10587   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
10588     {
10589       if(*ptrc>=0)
10590         {
10591           int tmp=1;
10592           for(int j=0;j<*ptrc;j++)
10593             tmp*=*ptr;
10594           *ptr=tmp;
10595         }
10596       else
10597         {
10598           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
10599           throw INTERP_KERNEL::Exception(oss.str().c_str());
10600         }
10601     }
10602   declareAsNew();
10603 }
10604
10605 /*!
10606  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
10607  * This map, if applied to \a start array, would make it sorted. For example, if
10608  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
10609  * [5,6,0,3,2,7,1,4].
10610  *  \param [in] start - pointer to the first element of the array for which the
10611  *         permutation map is computed.
10612  *  \param [in] end - pointer specifying the end of the array \a start, so that
10613  *         the last value of \a start is \a end[ -1 ].
10614  *  \return int * - the result permutation array that the caller is to delete as it is no
10615  *         more needed.
10616  *  \throw If there are equal values in the input array.
10617  */
10618 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
10619 {
10620   std::size_t sz=std::distance(start,end);
10621   int *ret=(int *)malloc(sz*sizeof(int));
10622   int *work=new int[sz];
10623   std::copy(start,end,work);
10624   std::sort(work,work+sz);
10625   if(std::unique(work,work+sz)!=work+sz)
10626     {
10627       delete [] work;
10628       free(ret);
10629       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
10630     }
10631   std::map<int,int> m;
10632   for(int *workPt=work;workPt!=work+sz;workPt++)
10633     m[*workPt]=(int)std::distance(work,workPt);
10634   int *iter2=ret;
10635   for(const int *iter=start;iter!=end;iter++,iter2++)
10636     *iter2=m[*iter];
10637   delete [] work;
10638   return ret;
10639 }
10640
10641 /*!
10642  * Returns a new DataArrayInt containing an arithmetic progression
10643  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
10644  * function.
10645  *  \param [in] begin - the start value of the result sequence.
10646  *  \param [in] end - limiting value, so that every value of the result array is less than
10647  *              \a end.
10648  *  \param [in] step - specifies the increment or decrement.
10649  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
10650  *          array using decrRef() as it is no more needed.
10651  *  \throw If \a step == 0.
10652  *  \throw If \a end < \a begin && \a step > 0.
10653  *  \throw If \a end > \a begin && \a step < 0.
10654  */
10655 DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception)
10656 {
10657   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
10658   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10659   ret->alloc(nbOfTuples,1);
10660   int *ptr=ret->getPointer();
10661   if(step>0)
10662     {
10663       for(int i=begin;i<end;i+=step,ptr++)
10664         *ptr=i;
10665     }
10666   else
10667     {
10668       for(int i=begin;i>end;i+=step,ptr++)
10669         *ptr=i;
10670     }
10671   return ret.retn();
10672 }
10673
10674 /*!
10675  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10676  * Server side.
10677  */
10678 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
10679 {
10680   tinyInfo.resize(2);
10681   if(isAllocated())
10682     {
10683       tinyInfo[0]=getNumberOfTuples();
10684       tinyInfo[1]=getNumberOfComponents();
10685     }
10686   else
10687     {
10688       tinyInfo[0]=-1;
10689       tinyInfo[1]=-1;
10690     }
10691 }
10692
10693 /*!
10694  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10695  * Server side.
10696  */
10697 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
10698 {
10699   if(isAllocated())
10700     {
10701       int nbOfCompo=getNumberOfComponents();
10702       tinyInfo.resize(nbOfCompo+1);
10703       tinyInfo[0]=getName();
10704       for(int i=0;i<nbOfCompo;i++)
10705         tinyInfo[i+1]=getInfoOnComponent(i);
10706     }
10707   else
10708     {
10709       tinyInfo.resize(1);
10710       tinyInfo[0]=getName();
10711     }
10712 }
10713
10714 /*!
10715  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10716  * This method returns if a feeding is needed.
10717  */
10718 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
10719 {
10720   int nbOfTuple=tinyInfoI[0];
10721   int nbOfComp=tinyInfoI[1];
10722   if(nbOfTuple!=-1 || nbOfComp!=-1)
10723     {
10724       alloc(nbOfTuple,nbOfComp);
10725       return true;
10726     }
10727   return false;
10728 }
10729
10730 /*!
10731  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
10732  * This method returns if a feeding is needed.
10733  */
10734 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
10735 {
10736   setName(tinyInfoS[0].c_str());
10737   if(isAllocated())
10738     {
10739       int nbOfCompo=getNumberOfComponents();
10740       for(int i=0;i<nbOfCompo;i++)
10741         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
10742     }
10743 }
10744
10745 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
10746 {
10747   if(_da)
10748     {
10749       _da->incrRef();
10750       if(_da->isAllocated())
10751         {
10752           _nb_comp=da->getNumberOfComponents();
10753           _nb_tuple=da->getNumberOfTuples();
10754           _pt=da->getPointer();
10755         }
10756     }
10757 }
10758
10759 DataArrayIntIterator::~DataArrayIntIterator()
10760 {
10761   if(_da)
10762     _da->decrRef();
10763 }
10764
10765 DataArrayIntTuple *DataArrayIntIterator::nextt() throw(INTERP_KERNEL::Exception)
10766 {
10767   if(_tuple_id<_nb_tuple)
10768     {
10769       _tuple_id++;
10770       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
10771       _pt+=_nb_comp;
10772       return ret;
10773     }
10774   else
10775     return 0;
10776 }
10777
10778 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
10779 {
10780 }
10781
10782 std::string DataArrayIntTuple::repr() const throw(INTERP_KERNEL::Exception)
10783 {
10784   std::ostringstream oss; oss << "(";
10785   for(int i=0;i<_nb_of_compo-1;i++)
10786     oss << _pt[i] << ", ";
10787   oss << _pt[_nb_of_compo-1] << ")";
10788   return oss.str();
10789 }
10790
10791 int DataArrayIntTuple::intValue() const throw(INTERP_KERNEL::Exception)
10792 {
10793   if(_nb_of_compo==1)
10794     return *_pt;
10795   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
10796 }
10797
10798 /*!
10799  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
10800  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
10801  * 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
10802  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
10803  */
10804 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception)
10805 {
10806   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
10807     {
10808       DataArrayInt *ret=DataArrayInt::New();
10809       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
10810       return ret;
10811     }
10812   else
10813     {
10814       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
10815       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
10816       throw INTERP_KERNEL::Exception(oss.str().c_str());
10817     }
10818 }