Salome HOME
Windows compilation.
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2014  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingMemArray.txx"
22 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
23
24 #include "BBTree.txx"
25 #include "GenMathFormulae.hxx"
26 #include "InterpKernelAutoPtr.hxx"
27 #include "InterpKernelExprParser.hxx"
28
29 #include <set>
30 #include <cmath>
31 #include <limits>
32 #include <numeric>
33 #include <algorithm>
34 #include <functional>
35
36 typedef double (*MYFUNCPTR)(double);
37
38 using namespace ParaMEDMEM;
39
40 template<int SPACEDIM>
41 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
42 {
43   const double *coordsPtr=getConstPointer();
44   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
45   std::vector<bool> isDone(nbNodes);
46   for(int i=0;i<nbNodes;i++)
47     {
48       if(!isDone[i])
49         {
50           std::vector<int> intersectingElems;
51           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
52           if(intersectingElems.size()>1)
53             {
54               std::vector<int> commonNodes;
55               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
56                 if(*it!=i)
57                   if(*it>=limitNodeId)
58                     {
59                       commonNodes.push_back(*it);
60                       isDone[*it]=true;
61                     }
62               if(!commonNodes.empty())
63                 {
64                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
65                   c->pushBackSilent(i);
66                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
67                 }
68             }
69         }
70     }
71 }
72
73 template<int SPACEDIM>
74 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
75                                                 DataArrayInt *c, DataArrayInt *cI)
76 {
77   for(int i=0;i<nbOfTuples;i++)
78     {
79       std::vector<int> intersectingElems;
80       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
81       std::vector<int> commonNodes;
82       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
83         commonNodes.push_back(*it);
84       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
85       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
86     }
87 }
88
89 template<int SPACEDIM>
90 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
91 {
92   double distOpt(dist);
93   const double *p(pos);
94   int *r(res);
95   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
96     {
97       while(true)
98         {
99           int elem=-1;
100           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
101           if(ret!=std::numeric_limits<double>::max())
102             {
103               distOpt=std::max(ret,1e-4);
104               *r=elem;
105               break;
106             }
107           else
108             { distOpt=2*distOpt; continue; }
109         }
110     }
111 }
112
113 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
114 {
115   std::size_t sz1=_name.capacity();
116   std::size_t sz2=_info_on_compo.capacity();
117   std::size_t sz3=0;
118   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
119     sz3+=(*it).capacity();
120   return sz1+sz2+sz3;
121 }
122
123 std::vector<const BigMemoryObject *> DataArray::getDirectChildren() const
124 {
125   return std::vector<const BigMemoryObject *>();
126 }
127
128 /*!
129  * Sets the attribute \a _name of \a this array.
130  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
131  *  \param [in] name - new array name
132  */
133 void DataArray::setName(const std::string& name)
134 {
135   _name=name;
136 }
137
138 /*!
139  * Copies textual data from an \a other DataArray. The copied data are
140  * - the name attribute,
141  * - the information of components.
142  *
143  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
144  *
145  *  \param [in] other - another instance of DataArray to copy the textual data from.
146  *  \throw If number of components of \a this array differs from that of the \a other.
147  */
148 void DataArray::copyStringInfoFrom(const DataArray& other)
149 {
150   if(_info_on_compo.size()!=other._info_on_compo.size())
151     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
152   _name=other._name;
153   _info_on_compo=other._info_on_compo;
154 }
155
156 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
157 {
158   int nbOfCompoOth=other.getNumberOfComponents();
159   std::size_t newNbOfCompo=compoIds.size();
160   for(std::size_t i=0;i<newNbOfCompo;i++)
161     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
162       {
163         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
164         throw INTERP_KERNEL::Exception(oss.str().c_str());
165       }
166   for(std::size_t i=0;i<newNbOfCompo;i++)
167     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
168 }
169
170 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
171 {
172   int nbOfCompo=getNumberOfComponents();
173   std::size_t partOfCompoToSet=compoIds.size();
174   if((int)partOfCompoToSet!=other.getNumberOfComponents())
175     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
176   for(std::size_t i=0;i<partOfCompoToSet;i++)
177     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
178       {
179         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
180         throw INTERP_KERNEL::Exception(oss.str().c_str());
181       }
182   for(std::size_t i=0;i<partOfCompoToSet;i++)
183     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
184 }
185
186 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
187 {
188   std::ostringstream oss;
189   if(_name!=other._name)
190     {
191       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
192       reason=oss.str();
193       return false;
194     }
195   if(_info_on_compo!=other._info_on_compo)
196     {
197       oss << "Components DataArray mismatch : \nThis components=";
198       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
199         oss << "\"" << *it << "\",";
200       oss << "\nOther components=";
201       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
202         oss << "\"" << *it << "\",";
203       reason=oss.str();
204       return false;
205     }
206   return true;
207 }
208
209 /*!
210  * Compares textual information of \a this DataArray with that of an \a other one.
211  * The compared data are
212  * - the name attribute,
213  * - the information of components.
214  *
215  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
216  *  \param [in] other - another instance of DataArray to compare the textual data of.
217  *  \return bool - \a true if the textual information is same, \a false else.
218  */
219 bool DataArray::areInfoEquals(const DataArray& other) const
220 {
221   std::string tmp;
222   return areInfoEqualsIfNotWhy(other,tmp);
223 }
224
225 void DataArray::reprWithoutNameStream(std::ostream& stream) const
226 {
227   stream << "Number of components : "<< getNumberOfComponents() << "\n";
228   stream << "Info of these components : ";
229   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
230     stream << "\"" << *iter << "\"   ";
231   stream << "\n";
232 }
233
234 std::string DataArray::cppRepr(const std::string& varName) const
235 {
236   std::ostringstream ret;
237   reprCppStream(varName,ret);
238   return ret.str();
239 }
240
241 /*!
242  * Sets information on all components. To know more on format of this information
243  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
244  *  \param [in] info - a vector of strings.
245  *  \throw If size of \a info differs from the number of components of \a this.
246  */
247 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
248 {
249   if(getNumberOfComponents()!=(int)info.size())
250     {
251       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
252       throw INTERP_KERNEL::Exception(oss.str().c_str());
253     }
254   _info_on_compo=info;
255 }
256
257 /*!
258  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
259  * type of \a this and \a aBase.
260  *
261  * \throw If \a aBase and \a this do not have the same type.
262  *
263  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
264  */
265 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
266 {
267   if(!aBase)
268     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
269   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
270   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
271   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
272   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
273   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
274   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
275   if(this1 && a1)
276     {
277       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
278       return ;
279     }
280   if(this2 && a2)
281     {
282       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
283       return ;
284     }
285   if(this3 && a3)
286     {
287       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
288       return ;
289     }
290   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
291 }
292
293 std::vector<std::string> DataArray::getVarsOnComponent() const
294 {
295   int nbOfCompo=(int)_info_on_compo.size();
296   std::vector<std::string> ret(nbOfCompo);
297   for(int i=0;i<nbOfCompo;i++)
298     ret[i]=getVarOnComponent(i);
299   return ret;
300 }
301
302 std::vector<std::string> DataArray::getUnitsOnComponent() const
303 {
304   int nbOfCompo=(int)_info_on_compo.size();
305   std::vector<std::string> ret(nbOfCompo);
306   for(int i=0;i<nbOfCompo;i++)
307     ret[i]=getUnitOnComponent(i);
308   return ret;
309 }
310
311 /*!
312  * Returns information on a component specified by an index.
313  * To know more on format of this information
314  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
315  *  \param [in] i - the index (zero based) of the component of interest.
316  *  \return std::string - a string containing the information on \a i-th component.
317  *  \throw If \a i is not a valid component index.
318  */
319 std::string DataArray::getInfoOnComponent(int i) const
320 {
321   if(i<(int)_info_on_compo.size() && i>=0)
322     return _info_on_compo[i];
323   else
324     {
325       std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
326       throw INTERP_KERNEL::Exception(oss.str().c_str());
327     }
328 }
329
330 /*!
331  * Returns the var part of the full information of the \a i-th component.
332  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
333  * \c getVarOnComponent(0) returns "SIGXY".
334  * If a unit part of information is not detected by presence of
335  * two square brackets, then the full information is returned.
336  * To read more about the component information format, see
337  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
338  *  \param [in] i - the index (zero based) of the component of interest.
339  *  \return std::string - a string containing the var information, or the full info.
340  *  \throw If \a i is not a valid component index.
341  */
342 std::string DataArray::getVarOnComponent(int i) const
343 {
344   if(i<(int)_info_on_compo.size() && i>=0)
345     {
346       return GetVarNameFromInfo(_info_on_compo[i]);
347     }
348   else
349     {
350       std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
351       throw INTERP_KERNEL::Exception(oss.str().c_str());
352     }
353 }
354
355 /*!
356  * Returns the unit part of the full information of the \a i-th component.
357  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
358  * \c getUnitOnComponent(0) returns " N/m^2".
359  * If a unit part of information is not detected by presence of
360  * two square brackets, then an empty string is returned.
361  * To read more about the component information format, see
362  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
363  *  \param [in] i - the index (zero based) of the component of interest.
364  *  \return std::string - a string containing the unit information, if any, or "".
365  *  \throw If \a i is not a valid component index.
366  */
367 std::string DataArray::getUnitOnComponent(int i) const
368 {
369   if(i<(int)_info_on_compo.size() && i>=0)
370     {
371       return GetUnitFromInfo(_info_on_compo[i]);
372     }
373   else
374     {
375       std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
376       throw INTERP_KERNEL::Exception(oss.str().c_str());
377     }
378 }
379
380 /*!
381  * Returns the var part of the full component information.
382  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
383  * If a unit part of information is not detected by presence of
384  * two square brackets, then the whole \a info is returned.
385  * To read more about the component information format, see
386  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
387  *  \param [in] info - the full component information.
388  *  \return std::string - a string containing only var information, or the \a info.
389  */
390 std::string DataArray::GetVarNameFromInfo(const std::string& info)
391 {
392   std::size_t p1=info.find_last_of('[');
393   std::size_t p2=info.find_last_of(']');
394   if(p1==std::string::npos || p2==std::string::npos)
395     return info;
396   if(p1>p2)
397     return info;
398   if(p1==0)
399     return std::string();
400   std::size_t p3=info.find_last_not_of(' ',p1-1);
401   return info.substr(0,p3+1);
402 }
403
404 /*!
405  * Returns the unit part of the full component information.
406  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
407  * If a unit part of information is not detected by presence of
408  * two square brackets, then an empty string is returned.
409  * To read more about the component information format, see
410  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
411  *  \param [in] info - the full component information.
412  *  \return std::string - a string containing only unit information, if any, or "".
413  */
414 std::string DataArray::GetUnitFromInfo(const std::string& info)
415 {
416   std::size_t p1=info.find_last_of('[');
417   std::size_t p2=info.find_last_of(']');
418   if(p1==std::string::npos || p2==std::string::npos)
419     return std::string();
420   if(p1>p2)
421     return std::string();
422   return info.substr(p1+1,p2-p1-1);
423 }
424
425 /*!
426  * This method put in info format the result of the merge of \a var and \a unit.
427  * The standard format for that is "var [unit]".
428  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
429  */
430 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
431 {
432   std::ostringstream oss;
433   oss << var << " [" << unit << "]";
434   return oss.str();
435 }
436
437 /*!
438  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
439  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
440  * the number of component in the result array is same as that of each of given arrays.
441  * Info on components is copied from the first of the given arrays. Number of components
442  * in the given arrays must be  the same.
443  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
444  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
445  *          The caller is to delete this result array using decrRef() as it is no more
446  *          needed.
447  *  \throw If all arrays within \a arrs are NULL.
448  *  \throw If all not null arrays in \a arrs have not the same type.
449  *  \throw If getNumberOfComponents() of arrays within \a arrs.
450  */
451 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
452 {
453   std::vector<const DataArray *> arr2;
454   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
455     if(*it)
456       arr2.push_back(*it);
457   if(arr2.empty())
458     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
459   std::vector<const DataArrayDouble *> arrd;
460   std::vector<const DataArrayInt *> arri;
461   std::vector<const DataArrayChar *> arrc;
462   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
463     {
464       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
465       if(a)
466         { arrd.push_back(a); continue; }
467       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
468       if(b)
469         { arri.push_back(b); continue; }
470       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
471       if(c)
472         { arrc.push_back(c); continue; }
473       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
474     }
475   if(arr2.size()==arrd.size())
476     return DataArrayDouble::Aggregate(arrd);
477   if(arr2.size()==arri.size())
478     return DataArrayInt::Aggregate(arri);
479   if(arr2.size()==arrc.size())
480     return DataArrayChar::Aggregate(arrc);
481   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
482 }
483
484 /*!
485  * Sets information on a component specified by an index.
486  * To know more on format of this information
487  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
488  *  \warning Don't pass NULL as \a info!
489  *  \param [in] i - the index (zero based) of the component of interest.
490  *  \param [in] info - the string containing the information.
491  *  \throw If \a i is not a valid component index.
492  */
493 void DataArray::setInfoOnComponent(int i, const std::string& info)
494 {
495   if(i<(int)_info_on_compo.size() && i>=0)
496     _info_on_compo[i]=info;
497   else
498     {
499       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();
500       throw INTERP_KERNEL::Exception(oss.str().c_str());
501     }
502 }
503
504 /*!
505  * Sets information on all components. This method can change number of components
506  * at certain conditions; if the conditions are not respected, an exception is thrown.
507  * The number of components can be changed in \a this only if \a this is not allocated.
508  * The condition of number of components must not be changed.
509  *
510  * To know more on format of the component information see
511  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
512  *  \param [in] info - a vector of component infos.
513  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
514  */
515 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
516 {
517   if(getNumberOfComponents()!=(int)info.size())
518     {
519       if(!isAllocated())
520         _info_on_compo=info;
521       else
522         {
523           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 !";
524           throw INTERP_KERNEL::Exception(oss.str().c_str());
525         }
526     }
527   else
528     _info_on_compo=info;
529 }
530
531 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
532 {
533   if(getNumberOfTuples()!=nbOfTuples)
534     {
535       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
536       throw INTERP_KERNEL::Exception(oss.str().c_str());
537     }
538 }
539
540 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
541 {
542   if(getNumberOfComponents()!=nbOfCompo)
543     {
544       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
545       throw INTERP_KERNEL::Exception(oss.str().c_str());
546     }
547 }
548
549 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
550 {
551   if(getNbOfElems()!=nbOfElems)
552     {
553       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
554       throw INTERP_KERNEL::Exception(oss.str().c_str());
555     }
556 }
557
558 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
559 {
560   if(getNumberOfTuples()!=other.getNumberOfTuples())
561     {
562       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
563       throw INTERP_KERNEL::Exception(oss.str().c_str());
564     }
565   if(getNumberOfComponents()!=other.getNumberOfComponents())
566     {
567       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
568       throw INTERP_KERNEL::Exception(oss.str().c_str());
569     }
570 }
571
572 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
573 {
574   checkNbOfTuples(nbOfTuples,msg);
575   checkNbOfComps(nbOfCompo,msg);
576 }
577
578 /*!
579  * Simply this method checks that \b value is in [0,\b ref).
580  */
581 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
582 {
583   if(value<0 || value>=ref)
584     {
585       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
586       throw INTERP_KERNEL::Exception(oss.str().c_str());
587     }
588 }
589
590 /*!
591  * This method checks that [\b start, \b end) is compliant with ref length \b value.
592  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
593  */
594 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
595 {
596   if(start<0 || start>=value)
597     {
598       if(value!=start || end!=start)
599         {
600           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
601           throw INTERP_KERNEL::Exception(oss.str().c_str());
602         }
603     }
604   if(end<0 || end>value)
605     {
606       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
607       throw INTERP_KERNEL::Exception(oss.str().c_str());
608     }
609 }
610
611 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
612 {
613   if(value<0 || value>ref)
614     {
615       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
616       throw INTERP_KERNEL::Exception(oss.str().c_str());
617     }
618 }
619
620 /*!
621  * 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, 
622  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
623  *
624  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
625  *
626  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
627  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
628  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
629  * \param [in] sliceId - the slice id considered
630  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
631  * \param [out] startSlice - the start of the slice considered
632  * \param [out] stopSlice - the stop of the slice consided
633  * 
634  * \throw If \a step == 0
635  * \throw If \a nbOfSlices not > 0
636  * \throw If \a sliceId not in [0,nbOfSlices)
637  */
638 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
639 {
640   if(nbOfSlices<=0)
641     {
642       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
643       throw INTERP_KERNEL::Exception(oss.str().c_str());
644     }
645   if(sliceId<0 || sliceId>=nbOfSlices)
646     {
647       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
648       throw INTERP_KERNEL::Exception(oss.str().c_str());
649     }
650   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
651   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
652   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
653   if(sliceId<nbOfSlices-1)
654     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
655   else
656     stopSlice=stop;
657 }
658
659 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
660 {
661   if(end<begin)
662     {
663       std::ostringstream oss; oss << msg << " : end before begin !";
664       throw INTERP_KERNEL::Exception(oss.str().c_str());
665     }
666   if(end==begin)
667     return 0;
668   if(step<=0)
669     {
670       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
671       throw INTERP_KERNEL::Exception(oss.str().c_str());
672     }
673   return (end-1-begin)/step+1;
674 }
675
676 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
677 {
678   if(step==0)
679     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
680   if(end<begin && step>0)
681     {
682       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
683       throw INTERP_KERNEL::Exception(oss.str().c_str());
684     }
685   if(begin<end && step<0)
686     {
687       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
688       throw INTERP_KERNEL::Exception(oss.str().c_str());
689     }
690   if(begin!=end)
691     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
692   else
693     return 0;
694 }
695
696 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
697 {
698   if(step!=0)
699     {
700       if(step>0)
701         {
702           if(begin<=value && value<end)
703             {
704               if((value-begin)%step==0)
705                 return (value-begin)/step;
706               else
707                 return -1;
708             }
709           else
710             return -1;
711         }
712       else
713         {
714           if(begin>=value && value>end)
715             {
716               if((begin-value)%(-step)==0)
717                 return (begin-value)/(-step);
718               else
719                 return -1;
720             }
721           else
722             return -1;
723         }
724     }
725   else
726     return -1;
727 }
728
729 /*!
730  * Returns a new instance of DataArrayDouble. The caller is to delete this array
731  * using decrRef() as it is no more needed. 
732  */
733 DataArrayDouble *DataArrayDouble::New()
734 {
735   return new DataArrayDouble;
736 }
737
738 /*!
739  * Checks if raw data is allocated. Read more on the raw data
740  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
741  *  \return bool - \a true if the raw data is allocated, \a false else.
742  */
743 bool DataArrayDouble::isAllocated() const
744 {
745   return getConstPointer()!=0;
746 }
747
748 /*!
749  * Checks if raw data is allocated and throws an exception if it is not the case.
750  *  \throw If the raw data is not allocated.
751  */
752 void DataArrayDouble::checkAllocated() const
753 {
754   if(!isAllocated())
755     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
756 }
757
758 /*!
759  * This method desallocated \a this without modification of informations relative to the components.
760  * After call of this method, DataArrayDouble::isAllocated will return false.
761  * If \a this is already not allocated, \a this is let unchanged.
762  */
763 void DataArrayDouble::desallocate()
764 {
765   _mem.destroy();
766 }
767
768 std::size_t DataArrayDouble::getHeapMemorySizeWithoutChildren() const
769 {
770   std::size_t sz(_mem.getNbOfElemAllocated());
771   sz*=sizeof(double);
772   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
773 }
774
775 /*!
776  * Returns the only one value in \a this, if and only if number of elements
777  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
778  *  \return double - the sole value stored in \a this array.
779  *  \throw If at least one of conditions stated above is not fulfilled.
780  */
781 double DataArrayDouble::doubleValue() const
782 {
783   if(isAllocated())
784     {
785       if(getNbOfElems()==1)
786         {
787           return *getConstPointer();
788         }
789       else
790         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
791     }
792   else
793     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
794 }
795
796 /*!
797  * Checks the number of tuples.
798  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
799  *  \throw If \a this is not allocated.
800  */
801 bool DataArrayDouble::empty() const
802 {
803   checkAllocated();
804   return getNumberOfTuples()==0;
805 }
806
807 /*!
808  * Returns a full copy of \a this. For more info on copying data arrays see
809  * \ref MEDCouplingArrayBasicsCopyDeep.
810  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
811  *          delete this array using decrRef() as it is no more needed. 
812  */
813 DataArrayDouble *DataArrayDouble::deepCpy() const
814 {
815   return new DataArrayDouble(*this);
816 }
817
818 /*!
819  * Returns either a \a deep or \a shallow copy of this array. For more info see
820  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
821  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
822  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
823  *          == \a true) or \a this instance (if \a dCpy == \a false).
824  */
825 DataArrayDouble *DataArrayDouble::performCpy(bool dCpy) const
826 {
827   if(dCpy)
828     return deepCpy();
829   else
830     {
831       incrRef();
832       return const_cast<DataArrayDouble *>(this);
833     }
834 }
835
836 /*!
837  * Copies all the data from another DataArrayDouble. For more info see
838  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
839  *  \param [in] other - another instance of DataArrayDouble to copy data from.
840  *  \throw If the \a other is not allocated.
841  */
842 void DataArrayDouble::cpyFrom(const DataArrayDouble& other)
843 {
844   other.checkAllocated();
845   int nbOfTuples=other.getNumberOfTuples();
846   int nbOfComp=other.getNumberOfComponents();
847   allocIfNecessary(nbOfTuples,nbOfComp);
848   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
849   double *pt=getPointer();
850   const double *ptI=other.getConstPointer();
851   for(std::size_t i=0;i<nbOfElems;i++)
852     pt[i]=ptI[i];
853   copyStringInfoFrom(other);
854 }
855
856 /*!
857  * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
858  * 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.
859  * If \a this has not already been allocated, number of components is set to one.
860  * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
861  * 
862  * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
863  */
864 void DataArrayDouble::reserve(std::size_t nbOfElems)
865 {
866   int nbCompo=getNumberOfComponents();
867   if(nbCompo==1)
868     {
869       _mem.reserve(nbOfElems);
870     }
871   else if(nbCompo==0)
872     {
873       _mem.reserve(nbOfElems);
874       _info_on_compo.resize(1);
875     }
876   else
877     throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
878 }
879
880 /*!
881  * 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
882  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
883  *
884  * \param [in] val the value to be added in \a this
885  * \throw If \a this has already been allocated with number of components different from one.
886  * \sa DataArrayDouble::pushBackValsSilent
887  */
888 void DataArrayDouble::pushBackSilent(double val)
889 {
890   int nbCompo=getNumberOfComponents();
891   if(nbCompo==1)
892     _mem.pushBack(val);
893   else if(nbCompo==0)
894     {
895       _info_on_compo.resize(1);
896       _mem.pushBack(val);
897     }
898   else
899     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
900 }
901
902 /*!
903  * 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
904  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
905  *
906  *  \param [in] valsBg - an array of values to push at the end of \this.
907  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
908  *              the last value of \a valsBg is \a valsEnd[ -1 ].
909  * \throw If \a this has already been allocated with number of components different from one.
910  * \sa DataArrayDouble::pushBackSilent
911  */
912 void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd)
913 {
914   int nbCompo=getNumberOfComponents();
915   if(nbCompo==1)
916     _mem.insertAtTheEnd(valsBg,valsEnd);
917   else if(nbCompo==0)
918     {
919       _info_on_compo.resize(1);
920       _mem.insertAtTheEnd(valsBg,valsEnd);
921     }
922   else
923     throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
924 }
925
926 /*!
927  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
928  * \throw If \a this is already empty.
929  * \throw If \a this has number of components different from one.
930  */
931 double DataArrayDouble::popBackSilent()
932 {
933   if(getNumberOfComponents()==1)
934     return _mem.popBack();
935   else
936     throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
937 }
938
939 /*!
940  * 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.
941  *
942  * \sa DataArrayDouble::getHeapMemorySizeWithoutChildren, DataArrayDouble::reserve
943  */
944 void DataArrayDouble::pack() const
945 {
946   _mem.pack();
947 }
948
949 /*!
950  * Allocates the raw data in memory. If exactly same memory as needed already
951  * allocated, it is not re-allocated.
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::allocIfNecessary(int nbOfTuple, int nbOfCompo)
957 {
958   if(isAllocated())
959     {
960       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
961         alloc(nbOfTuple,nbOfCompo);
962     }
963   else
964     alloc(nbOfTuple,nbOfCompo);
965 }
966
967 /*!
968  * Allocates the raw data in memory. If the memory was already allocated, then it is
969  * freed and re-allocated. See an example of this method use
970  * \ref MEDCouplingArraySteps1WC "here".
971  *  \param [in] nbOfTuple - number of tuples of data to allocate.
972  *  \param [in] nbOfCompo - number of components of data to allocate.
973  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
974  */
975 void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo)
976 {
977   if(nbOfTuple<0 || nbOfCompo<0)
978     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
979   _info_on_compo.resize(nbOfCompo);
980   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
981   declareAsNew();
982 }
983
984 /*!
985  * Assign zero to all values in \a this array. To know more on filling arrays see
986  * \ref MEDCouplingArrayFill.
987  * \throw If \a this is not allocated.
988  */
989 void DataArrayDouble::fillWithZero()
990 {
991   checkAllocated();
992   _mem.fillWithValue(0.);
993   declareAsNew();
994 }
995
996 /*!
997  * Assign \a val to all values in \a this array. To know more on filling arrays see
998  * \ref MEDCouplingArrayFill.
999  *  \param [in] val - the value to fill with.
1000  *  \throw If \a this is not allocated.
1001  */
1002 void DataArrayDouble::fillWithValue(double val)
1003 {
1004   checkAllocated();
1005   _mem.fillWithValue(val);
1006   declareAsNew();
1007 }
1008
1009 /*!
1010  * Set all values in \a this array so that the i-th element equals to \a init + i
1011  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
1012  *  \param [in] init - value to assign to the first element of array.
1013  *  \throw If \a this->getNumberOfComponents() != 1
1014  *  \throw If \a this is not allocated.
1015  */
1016 void DataArrayDouble::iota(double init)
1017 {
1018   checkAllocated();
1019   if(getNumberOfComponents()!=1)
1020     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
1021   double *ptr=getPointer();
1022   int ntuples=getNumberOfTuples();
1023   for(int i=0;i<ntuples;i++)
1024     ptr[i]=init+double(i);
1025   declareAsNew();
1026 }
1027
1028 /*!
1029  * Checks if all values in \a this array are equal to \a val at precision \a eps.
1030  *  \param [in] val - value to check equality of array values to.
1031  *  \param [in] eps - precision to check the equality.
1032  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
1033  *                 \a false else.
1034  *  \throw If \a this->getNumberOfComponents() != 1
1035  *  \throw If \a this is not allocated.
1036  */
1037 bool DataArrayDouble::isUniform(double val, double eps) const
1038 {
1039   checkAllocated();
1040   if(getNumberOfComponents()!=1)
1041     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1042   int nbOfTuples=getNumberOfTuples();
1043   const double *w=getConstPointer();
1044   const double *end2=w+nbOfTuples;
1045   const double vmin=val-eps;
1046   const double vmax=val+eps;
1047   for(;w!=end2;w++)
1048     if(*w<vmin || *w>vmax)
1049       return false;
1050   return true;
1051 }
1052
1053 /*!
1054  * Sorts values of the array.
1055  *  \param [in] asc - \a true means ascending order, \a false, descending.
1056  *  \throw If \a this is not allocated.
1057  *  \throw If \a this->getNumberOfComponents() != 1.
1058  */
1059 void DataArrayDouble::sort(bool asc)
1060 {
1061   checkAllocated();
1062   if(getNumberOfComponents()!=1)
1063     throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
1064   _mem.sort(asc);
1065   declareAsNew();
1066 }
1067
1068 /*!
1069  * Reverse the array values.
1070  *  \throw If \a this->getNumberOfComponents() < 1.
1071  *  \throw If \a this is not allocated.
1072  */
1073 void DataArrayDouble::reverse()
1074 {
1075   checkAllocated();
1076   _mem.reverse(getNumberOfComponents());
1077   declareAsNew();
1078 }
1079
1080 /*!
1081  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1082  * with at least absolute difference value of |\a eps| at each step.
1083  * If not an exception is thrown.
1084  *  \param [in] increasing - if \a true, the array values should be increasing.
1085  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1086  *                    the values are considered different.
1087  *  \throw If sequence of values is not strictly monotonic in agreement with \a
1088  *         increasing arg.
1089  *  \throw If \a this->getNumberOfComponents() != 1.
1090  *  \throw If \a this is not allocated.
1091  */
1092 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
1093 {
1094   if(!isMonotonic(increasing,eps))
1095     {
1096       if (increasing)
1097         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
1098       else
1099         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
1100     }
1101 }
1102
1103 /*!
1104  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
1105  * with at least absolute difference value of |\a eps| at each step.
1106  *  \param [in] increasing - if \a true, array values should be increasing.
1107  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
1108  *                    the values are considered different.
1109  *  \return bool - \a true if values change in accordance with \a increasing arg.
1110  *  \throw If \a this->getNumberOfComponents() != 1.
1111  *  \throw If \a this is not allocated.
1112  */
1113 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
1114 {
1115   checkAllocated();
1116   if(getNumberOfComponents()!=1)
1117     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
1118   int nbOfElements=getNumberOfTuples();
1119   const double *ptr=getConstPointer();
1120   if(nbOfElements==0)
1121     return true;
1122   double ref=ptr[0];
1123   double absEps=fabs(eps);
1124   if(increasing)
1125     {
1126       for(int i=1;i<nbOfElements;i++)
1127         {
1128           if(ptr[i]<(ref+absEps))
1129             return false;
1130           ref=ptr[i];
1131         }
1132       return true;
1133     }
1134   else
1135     {
1136       for(int i=1;i<nbOfElements;i++)
1137         {
1138           if(ptr[i]>(ref-absEps))
1139             return false;
1140           ref=ptr[i];
1141         }
1142       return true;
1143     }
1144 }
1145
1146 /*!
1147  * Returns a textual and human readable representation of \a this instance of
1148  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
1149  *  \return std::string - text describing \a this DataArrayDouble.
1150  */
1151 std::string DataArrayDouble::repr() const
1152 {
1153   std::ostringstream ret;
1154   reprStream(ret);
1155   return ret.str();
1156 }
1157
1158 std::string DataArrayDouble::reprZip() const
1159 {
1160   std::ostringstream ret;
1161   reprZipStream(ret);
1162   return ret.str();
1163 }
1164
1165 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
1166 {
1167   static const char SPACE[4]={' ',' ',' ',' '};
1168   checkAllocated();
1169   std::string idt(indent,' ');
1170   ofs.precision(17);
1171   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
1172   if(byteArr)
1173     {
1174       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
1175       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
1176       float *pt(tmp);
1177       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
1178       for(const double *src=begin();src!=end();src++,pt++)
1179         *pt=float(*src);
1180       const char *data(reinterpret_cast<const char *>((float *)tmp));
1181       std::size_t sz(getNbOfElems()*sizeof(float));
1182       byteArr->insertAtTheEnd(data,data+sz);
1183       byteArr->insertAtTheEnd(SPACE,SPACE+4);
1184     }
1185   else
1186     {
1187       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
1188       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1189     }
1190   ofs << std::endl << idt << "</DataArray>\n";
1191 }
1192
1193 void DataArrayDouble::reprStream(std::ostream& stream) const
1194 {
1195   stream << "Name of double array : \"" << _name << "\"\n";
1196   reprWithoutNameStream(stream);
1197 }
1198
1199 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1200 {
1201   stream << "Name of double array : \"" << _name << "\"\n";
1202   reprZipWithoutNameStream(stream);
1203 }
1204
1205 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1206 {
1207   DataArray::reprWithoutNameStream(stream);
1208   stream.precision(17);
1209   _mem.repr(getNumberOfComponents(),stream);
1210 }
1211
1212 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1213 {
1214   DataArray::reprWithoutNameStream(stream);
1215   stream.precision(17);
1216   _mem.reprZip(getNumberOfComponents(),stream);
1217 }
1218
1219 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1220 {
1221   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1222   const double *data=getConstPointer();
1223   stream.precision(17);
1224   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1225   if(nbTuples*nbComp>=1)
1226     {
1227       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1228       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1229       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1230       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1231     }
1232   else
1233     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1234   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1235 }
1236
1237 /*!
1238  * Method that gives a quick overvien of \a this for python.
1239  */
1240 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1241 {
1242   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1243   stream << "DataArrayDouble C++ instance at " << this << ". ";
1244   if(isAllocated())
1245     {
1246       int nbOfCompo=(int)_info_on_compo.size();
1247       if(nbOfCompo>=1)
1248         {
1249           int nbOfTuples=getNumberOfTuples();
1250           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1251           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1252         }
1253       else
1254         stream << "Number of components : 0.";
1255     }
1256   else
1257     stream << "*** No data allocated ****";
1258 }
1259
1260 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1261 {
1262   const double *data=begin();
1263   int nbOfTuples=getNumberOfTuples();
1264   int nbOfCompo=(int)_info_on_compo.size();
1265   std::ostringstream oss2; oss2 << "[";
1266   oss2.precision(17);
1267   std::string oss2Str(oss2.str());
1268   bool isFinished=true;
1269   for(int i=0;i<nbOfTuples && isFinished;i++)
1270     {
1271       if(nbOfCompo>1)
1272         {
1273           oss2 << "(";
1274           for(int j=0;j<nbOfCompo;j++,data++)
1275             {
1276               oss2 << *data;
1277               if(j!=nbOfCompo-1) oss2 << ", ";
1278             }
1279           oss2 << ")";
1280         }
1281       else
1282         oss2 << *data++;
1283       if(i!=nbOfTuples-1) oss2 << ", ";
1284       std::string oss3Str(oss2.str());
1285       if(oss3Str.length()<maxNbOfByteInRepr)
1286         oss2Str=oss3Str;
1287       else
1288         isFinished=false;
1289     }
1290   stream << oss2Str;
1291   if(!isFinished)
1292     stream << "... ";
1293   stream << "]";
1294 }
1295
1296 /*!
1297  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1298  * mismatch is given.
1299  * 
1300  * \param [in] other the instance to be compared with \a this
1301  * \param [in] prec the precision to compare numeric data of the arrays.
1302  * \param [out] reason In case of inequality returns the reason.
1303  * \sa DataArrayDouble::isEqual
1304  */
1305 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1306 {
1307   if(!areInfoEqualsIfNotWhy(other,reason))
1308     return false;
1309   return _mem.isEqual(other._mem,prec,reason);
1310 }
1311
1312 /*!
1313  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1314  * \ref MEDCouplingArrayBasicsCompare.
1315  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1316  *  \param [in] prec - precision value to compare numeric data of the arrays.
1317  *  \return bool - \a true if the two arrays are equal, \a false else.
1318  */
1319 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1320 {
1321   std::string tmp;
1322   return isEqualIfNotWhy(other,prec,tmp);
1323 }
1324
1325 /*!
1326  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1327  * \ref MEDCouplingArrayBasicsCompare.
1328  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1329  *  \param [in] prec - precision value to compare numeric data of the arrays.
1330  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1331  */
1332 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1333 {
1334   std::string tmp;
1335   return _mem.isEqual(other._mem,prec,tmp);
1336 }
1337
1338 /*!
1339  * Changes number of tuples in the array. If the new number of tuples is smaller
1340  * than the current number the array is truncated, otherwise the array is extended.
1341  *  \param [in] nbOfTuples - new number of tuples. 
1342  *  \throw If \a this is not allocated.
1343  *  \throw If \a nbOfTuples is negative.
1344  */
1345 void DataArrayDouble::reAlloc(int nbOfTuples)
1346 {
1347   if(nbOfTuples<0)
1348     throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
1349   checkAllocated();
1350   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
1351   declareAsNew();
1352 }
1353
1354 /*!
1355  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1356  * array to the new one.
1357  *  \return DataArrayInt * - the new instance of DataArrayInt.
1358  */
1359 DataArrayInt *DataArrayDouble::convertToIntArr() const
1360 {
1361   DataArrayInt *ret=DataArrayInt::New();
1362   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1363   int *dest=ret->getPointer();
1364   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1365   for(const double *src=begin();src!=end();src++,dest++)
1366     *dest=(int)*src;
1367   ret->copyStringInfoFrom(*this);
1368   return ret;
1369 }
1370
1371 /*!
1372  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1373  * arranged in memory. If \a this array holds 2 components of 3 values:
1374  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1375  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1376  *  \warning Do not confuse this method with transpose()!
1377  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1378  *          is to delete using decrRef() as it is no more needed.
1379  *  \throw If \a this is not allocated.
1380  */
1381 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1382 {
1383   if(_mem.isNull())
1384     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1385   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1386   DataArrayDouble *ret=DataArrayDouble::New();
1387   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1388   return ret;
1389 }
1390
1391 /*!
1392  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1393  * arranged in memory. If \a this array holds 2 components of 3 values:
1394  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1395  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1396  *  \warning Do not confuse this method with transpose()!
1397  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1398  *          is to delete using decrRef() as it is no more needed.
1399  *  \throw If \a this is not allocated.
1400  */
1401 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1402 {
1403   if(_mem.isNull())
1404     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1405   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1406   DataArrayDouble *ret=DataArrayDouble::New();
1407   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1408   return ret;
1409 }
1410
1411 /*!
1412  * Permutes values of \a this array as required by \a old2New array. The values are
1413  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
1414  * the same as in \this one.
1415  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1416  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1417  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1418  *     giving a new position for i-th old value.
1419  */
1420 void DataArrayDouble::renumberInPlace(const int *old2New)
1421 {
1422   checkAllocated();
1423   int nbTuples=getNumberOfTuples();
1424   int nbOfCompo=getNumberOfComponents();
1425   double *tmp=new double[nbTuples*nbOfCompo];
1426   const double *iptr=getConstPointer();
1427   for(int i=0;i<nbTuples;i++)
1428     {
1429       int v=old2New[i];
1430       if(v>=0 && v<nbTuples)
1431         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
1432       else
1433         {
1434           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1435           throw INTERP_KERNEL::Exception(oss.str().c_str());
1436         }
1437     }
1438   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1439   delete [] tmp;
1440   declareAsNew();
1441 }
1442
1443 /*!
1444  * Permutes values of \a this array as required by \a new2Old array. The values are
1445  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
1446  * the same as in \this one.
1447  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1448  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1449  *     giving a previous position of i-th new value.
1450  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1451  *          is to delete using decrRef() as it is no more needed.
1452  */
1453 void DataArrayDouble::renumberInPlaceR(const int *new2Old)
1454 {
1455   checkAllocated();
1456   int nbTuples=getNumberOfTuples();
1457   int nbOfCompo=getNumberOfComponents();
1458   double *tmp=new double[nbTuples*nbOfCompo];
1459   const double *iptr=getConstPointer();
1460   for(int i=0;i<nbTuples;i++)
1461     {
1462       int v=new2Old[i];
1463       if(v>=0 && v<nbTuples)
1464         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
1465       else
1466         {
1467           std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
1468           throw INTERP_KERNEL::Exception(oss.str().c_str());
1469         }
1470     }
1471   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
1472   delete [] tmp;
1473   declareAsNew();
1474 }
1475
1476 /*!
1477  * Returns a copy of \a this array with values permuted as required by \a old2New array.
1478  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
1479  * Number of tuples in the result array remains the same as in \this one.
1480  * If a permutation reduction is needed, renumberAndReduce() should be used.
1481  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1482  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1483  *          giving a new position for i-th old value.
1484  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1485  *          is to delete using decrRef() as it is no more needed.
1486  *  \throw If \a this is not allocated.
1487  */
1488 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
1489 {
1490   checkAllocated();
1491   int nbTuples=getNumberOfTuples();
1492   int nbOfCompo=getNumberOfComponents();
1493   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1494   ret->alloc(nbTuples,nbOfCompo);
1495   ret->copyStringInfoFrom(*this);
1496   const double *iptr=getConstPointer();
1497   double *optr=ret->getPointer();
1498   for(int i=0;i<nbTuples;i++)
1499     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
1500   ret->copyStringInfoFrom(*this);
1501   return ret.retn();
1502 }
1503
1504 /*!
1505  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
1506  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
1507  * tuples in the result array remains the same as in \this one.
1508  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
1509  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1510  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
1511  *     giving a previous position of i-th new value.
1512  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1513  *          is to delete using decrRef() as it is no more needed.
1514  */
1515 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
1516 {
1517   checkAllocated();
1518   int nbTuples=getNumberOfTuples();
1519   int nbOfCompo=getNumberOfComponents();
1520   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1521   ret->alloc(nbTuples,nbOfCompo);
1522   ret->copyStringInfoFrom(*this);
1523   const double *iptr=getConstPointer();
1524   double *optr=ret->getPointer();
1525   for(int i=0;i<nbTuples;i++)
1526     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo);
1527   ret->copyStringInfoFrom(*this);
1528   return ret.retn();
1529 }
1530
1531 /*!
1532  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1533  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
1534  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
1535  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
1536  * \a old2New[ i ] is negative, is missing from the result array.
1537  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1538  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
1539  *     giving a new position for i-th old tuple and giving negative position for
1540  *     for i-th old tuple that should be omitted.
1541  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1542  *          is to delete using decrRef() as it is no more needed.
1543  */
1544 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
1545 {
1546   checkAllocated();
1547   int nbTuples=getNumberOfTuples();
1548   int nbOfCompo=getNumberOfComponents();
1549   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1550   ret->alloc(newNbOfTuple,nbOfCompo);
1551   const double *iptr=getConstPointer();
1552   double *optr=ret->getPointer();
1553   for(int i=0;i<nbTuples;i++)
1554     {
1555       int w=old2New[i];
1556       if(w>=0)
1557         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
1558     }
1559   ret->copyStringInfoFrom(*this);
1560   return ret.retn();
1561 }
1562
1563 /*!
1564  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1565  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1566  * \a new2OldBg array.
1567  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1568  * This method is equivalent to renumberAndReduce() except that convention in input is
1569  * \c new2old and \b not \c old2new.
1570  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1571  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1572  *              tuple index in \a this array to fill the i-th tuple in the new array.
1573  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1574  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1575  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1576  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1577  *          is to delete using decrRef() as it is no more needed.
1578  */
1579 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
1580 {
1581   checkAllocated();
1582   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1583   int nbComp=getNumberOfComponents();
1584   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1585   ret->copyStringInfoFrom(*this);
1586   double *pt=ret->getPointer();
1587   const double *srcPt=getConstPointer();
1588   int i=0;
1589   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1590     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1591   ret->copyStringInfoFrom(*this);
1592   return ret.retn();
1593 }
1594
1595 /*!
1596  * Returns a shorten and permuted copy of \a this array. The new DataArrayDouble is
1597  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
1598  * \a new2OldBg array.
1599  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
1600  * This method is equivalent to renumberAndReduce() except that convention in input is
1601  * \c new2old and \b not \c old2new.
1602  * This method is equivalent to selectByTupleId() except that it prevents coping data
1603  * from behind the end of \a this array.
1604  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1605  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
1606  *              tuple index in \a this array to fill the i-th tuple in the new array.
1607  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
1608  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
1609  *              \a new2OldBg <= \a pi < \a new2OldEnd.
1610  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1611  *          is to delete using decrRef() as it is no more needed.
1612  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
1613  */
1614 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
1615 {
1616   checkAllocated();
1617   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1618   int nbComp=getNumberOfComponents();
1619   int oldNbOfTuples=getNumberOfTuples();
1620   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
1621   ret->copyStringInfoFrom(*this);
1622   double *pt=ret->getPointer();
1623   const double *srcPt=getConstPointer();
1624   int i=0;
1625   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
1626     if(*w>=0 && *w<oldNbOfTuples)
1627       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
1628     else
1629       throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
1630   ret->copyStringInfoFrom(*this);
1631   return ret.retn();
1632 }
1633
1634 /*!
1635  * Returns a shorten copy of \a this array. The new DataArrayDouble contains every
1636  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
1637  * tuple. Indices of the selected tuples are the same as ones returned by the Python
1638  * command \c range( \a bg, \a end2, \a step ).
1639  * This method is equivalent to selectByTupleIdSafe() except that the input array is
1640  * not constructed explicitly.
1641  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1642  *  \param [in] bg - index of the first tuple to copy from \a this array.
1643  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
1644  *  \param [in] step - index increment to get index of the next tuple to copy.
1645  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1646  *          is to delete using decrRef() as it is no more needed.
1647  *  \sa DataArrayDouble::substr.
1648  */
1649 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const
1650 {
1651   checkAllocated();
1652   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1653   int nbComp=getNumberOfComponents();
1654   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
1655   ret->alloc(newNbOfTuples,nbComp);
1656   double *pt=ret->getPointer();
1657   const double *srcPt=getConstPointer()+bg*nbComp;
1658   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
1659     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
1660   ret->copyStringInfoFrom(*this);
1661   return ret.retn();
1662 }
1663
1664 /*!
1665  * Returns a shorten copy of \a this array. The new DataArrayDouble contains ranges
1666  * of tuples specified by \a ranges parameter.
1667  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
1668  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1669  *              of tuples in [\c begin,\c end) format.
1670  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1671  *          is to delete using decrRef() as it is no more needed.
1672  *  \throw If \a end < \a begin.
1673  *  \throw If \a end > \a this->getNumberOfTuples().
1674  *  \throw If \a this is not allocated.
1675  */
1676 DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
1677 {
1678   checkAllocated();
1679   int nbOfComp=getNumberOfComponents();
1680   int nbOfTuplesThis=getNumberOfTuples();
1681   if(ranges.empty())
1682     {
1683       DataArrayDouble *ret=DataArrayDouble::New();
1684       ret->alloc(0,nbOfComp);
1685       ret->copyStringInfoFrom(*this);
1686       return ret;
1687     }
1688   int ref=ranges.front().first;
1689   int nbOfTuples=0;
1690   bool isIncreasing=true;
1691   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1692     {
1693       if((*it).first<=(*it).second)
1694         {
1695           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1696             {
1697               nbOfTuples+=(*it).second-(*it).first;
1698               if(isIncreasing)
1699                 isIncreasing=ref<=(*it).first;
1700               ref=(*it).second;
1701             }
1702           else
1703             {
1704               std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1705               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1706               throw INTERP_KERNEL::Exception(oss.str().c_str());
1707             }
1708         }
1709       else
1710         {
1711           std::ostringstream oss; oss << "DataArrayDouble::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1712           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1713           throw INTERP_KERNEL::Exception(oss.str().c_str());
1714         }
1715     }
1716   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1717     return deepCpy();
1718   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1719   ret->alloc(nbOfTuples,nbOfComp);
1720   ret->copyStringInfoFrom(*this);
1721   const double *src=getConstPointer();
1722   double *work=ret->getPointer();
1723   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1724     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1725   return ret.retn();
1726 }
1727
1728 /*!
1729  * Returns a shorten copy of \a this array. The new DataArrayDouble contains all
1730  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
1731  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
1732  * This method is a specialization of selectByTupleId2().
1733  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
1734  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
1735  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
1736  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1737  *          is to delete using decrRef() as it is no more needed.
1738  *  \throw If \a tupleIdBg < 0.
1739  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
1740     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
1741  *  \sa DataArrayDouble::selectByTupleId2
1742  */
1743 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const
1744 {
1745   checkAllocated();
1746   int nbt=getNumberOfTuples();
1747   if(tupleIdBg<0)
1748     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
1749   if(tupleIdBg>nbt)
1750     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !");
1751   int trueEnd=tupleIdEnd;
1752   if(tupleIdEnd!=-1)
1753     {
1754       if(tupleIdEnd>nbt)
1755         throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
1756     }
1757   else
1758     trueEnd=nbt;
1759   int nbComp=getNumberOfComponents();
1760   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1761   ret->alloc(trueEnd-tupleIdBg,nbComp);
1762   ret->copyStringInfoFrom(*this);
1763   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
1764   return ret.retn();
1765 }
1766
1767 /*!
1768  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
1769  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
1770  * is truncated to have \a newNbOfComp components, keeping first components. If \a
1771  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
1772  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
1773  * components.  
1774  *  \param [in] newNbOfComp - number of components for the new array to have.
1775  *  \param [in] dftValue - value assigned to new values added to the new array.
1776  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1777  *          is to delete using decrRef() as it is no more needed.
1778  *  \throw If \a this is not allocated.
1779  */
1780 DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const
1781 {
1782   checkAllocated();
1783   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
1784   ret->alloc(getNumberOfTuples(),newNbOfComp);
1785   const double *oldc=getConstPointer();
1786   double *nc=ret->getPointer();
1787   int nbOfTuples=getNumberOfTuples();
1788   int oldNbOfComp=getNumberOfComponents();
1789   int dim=std::min(oldNbOfComp,newNbOfComp);
1790   for(int i=0;i<nbOfTuples;i++)
1791     {
1792       int j=0;
1793       for(;j<dim;j++)
1794         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
1795       for(;j<newNbOfComp;j++)
1796         nc[newNbOfComp*i+j]=dftValue;
1797     }
1798   ret->setName(getName());
1799   for(int i=0;i<dim;i++)
1800     ret->setInfoOnComponent(i,getInfoOnComponent(i));
1801   ret->setName(getName());
1802   return ret.retn();
1803 }
1804
1805 /*!
1806  * Changes the number of components within \a this array so that its raw data **does
1807  * not** change, instead splitting this data into tuples changes.
1808  *  \warning This method erases all (name and unit) component info set before!
1809  *  \param [in] newNbOfComp - number of components for \a this array to have.
1810  *  \throw If \a this is not allocated
1811  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
1812  *  \throw If \a newNbOfCompo is lower than 1.
1813  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
1814  *  \warning This method erases all (name and unit) component info set before!
1815  */
1816 void DataArrayDouble::rearrange(int newNbOfCompo)
1817 {
1818   checkAllocated();
1819   if(newNbOfCompo<1)
1820     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : input newNbOfCompo must be > 0 !");
1821   std::size_t nbOfElems=getNbOfElems();
1822   if(nbOfElems%newNbOfCompo!=0)
1823     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
1824   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
1825     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
1826   _info_on_compo.clear();
1827   _info_on_compo.resize(newNbOfCompo);
1828   declareAsNew();
1829 }
1830
1831 /*!
1832  * Changes the number of components within \a this array to be equal to its number
1833  * of tuples, and inversely its number of tuples to become equal to its number of 
1834  * components. So that its raw data **does not** change, instead splitting this
1835  * data into tuples changes.
1836  *  \warning This method erases all (name and unit) component info set before!
1837  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
1838  *  \throw If \a this is not allocated.
1839  *  \sa rearrange()
1840  */
1841 void DataArrayDouble::transpose()
1842 {
1843   checkAllocated();
1844   int nbOfTuples=getNumberOfTuples();
1845   rearrange(nbOfTuples);
1846 }
1847
1848 /*!
1849  * Returns a copy of \a this array composed of selected components.
1850  * The new DataArrayDouble has the same number of tuples but includes components
1851  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
1852  * can be either less, same or more than \a this->getNbOfElems().
1853  *  \param [in] compoIds - sequence of zero based indices of components to include
1854  *              into the new array.
1855  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1856  *          is to delete using decrRef() as it is no more needed.
1857  *  \throw If \a this is not allocated.
1858  *  \throw If a component index (\a i) is not valid: 
1859  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
1860  *
1861  *  \if ENABLE_EXAMPLES
1862  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
1863  *  \endif
1864  */
1865 DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
1866 {
1867   checkAllocated();
1868   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
1869   std::size_t newNbOfCompo=compoIds.size();
1870   int oldNbOfCompo=getNumberOfComponents();
1871   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
1872     if((*it)<0 || (*it)>=oldNbOfCompo)
1873       {
1874         std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !";
1875         throw INTERP_KERNEL::Exception(oss.str().c_str());
1876       }
1877   int nbOfTuples=getNumberOfTuples();
1878   ret->alloc(nbOfTuples,(int)newNbOfCompo);
1879   ret->copyPartOfStringInfoFrom(*this,compoIds);
1880   const double *oldc=getConstPointer();
1881   double *nc=ret->getPointer();
1882   for(int i=0;i<nbOfTuples;i++)
1883     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
1884       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
1885   return ret.retn();
1886 }
1887
1888 /*!
1889  * Appends components of another array to components of \a this one, tuple by tuple.
1890  * So that the number of tuples of \a this array remains the same and the number of 
1891  * components increases.
1892  *  \param [in] other - the DataArrayDouble to append to \a this one.
1893  *  \throw If \a this is not allocated.
1894  *  \throw If \a this and \a other arrays have different number of tuples.
1895  *
1896  *  \if ENABLE_EXAMPLES
1897  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1898  *
1899  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1900  *  \endif
1901  */
1902 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1903 {
1904   checkAllocated();
1905   other->checkAllocated();
1906   int nbOfTuples=getNumberOfTuples();
1907   if(nbOfTuples!=other->getNumberOfTuples())
1908     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1909   int nbOfComp1=getNumberOfComponents();
1910   int nbOfComp2=other->getNumberOfComponents();
1911   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1912   double *w=newArr;
1913   const double *inp1=getConstPointer();
1914   const double *inp2=other->getConstPointer();
1915   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1916     {
1917       w=std::copy(inp1,inp1+nbOfComp1,w);
1918       w=std::copy(inp2,inp2+nbOfComp2,w);
1919     }
1920   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1921   std::vector<int> compIds(nbOfComp2);
1922   for(int i=0;i<nbOfComp2;i++)
1923     compIds[i]=nbOfComp1+i;
1924   copyPartOfStringInfoFrom2(compIds,*other);
1925 }
1926
1927 /*!
1928  * This method checks that all tuples in \a other are in \a this.
1929  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1930  * 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.
1931  *
1932  * \param [in] other - the array having the same number of components than \a this.
1933  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1934  * \sa DataArrayDouble::findCommonTuples
1935  */
1936 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1937 {
1938   if(!other)
1939     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1940   checkAllocated(); other->checkAllocated();
1941   if(getNumberOfComponents()!=other->getNumberOfComponents())
1942     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1943   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1944   DataArrayInt *c=0,*ci=0;
1945   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1946   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
1947   int newNbOfTuples=-1;
1948   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1949   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
1950   tupleIds=ret1.retn();
1951   return newNbOfTuples==getNumberOfTuples();
1952 }
1953
1954 /*!
1955  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1956  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1957  * distance separating two points is computed with the infinite norm.
1958  *
1959  * Indices of coincident tuples are stored in output arrays.
1960  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1961  *
1962  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1963  * MEDCouplingUMesh::mergeNodes().
1964  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1965  *              considered not coincident.
1966  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1967  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1968  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1969  *               \a comm->getNumberOfComponents() == 1. 
1970  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1971  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1972  *               groups of (indices of) coincident tuples. Its every value is a tuple
1973  *               index where a next group of tuples begins. For example the second
1974  *               group of tuples in \a comm is described by following range of indices:
1975  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1976  *               gives the number of groups of coincident tuples.
1977  *  \throw If \a this is not allocated.
1978  *  \throw If the number of components is not in [1,2,3,4].
1979  *
1980  *  \if ENABLE_EXAMPLES
1981  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1982  *
1983  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1984  *  \endif
1985  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
1986  */
1987 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1988 {
1989   checkAllocated();
1990   int nbOfCompo=getNumberOfComponents();
1991   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1992     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1993
1994   int nbOfTuples=getNumberOfTuples();
1995   //
1996   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1997   switch(nbOfCompo)
1998   {
1999     case 4:
2000       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2001       break;
2002     case 3:
2003       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2004       break;
2005     case 2:
2006       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2007       break;
2008     case 1:
2009       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
2010       break;
2011     default:
2012       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
2013   }
2014   comm=c.retn();
2015   commIndex=cI.retn();
2016 }
2017
2018 /*!
2019  * 
2020  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
2021  *             \a nbTimes  should be at least equal to 1.
2022  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
2023  * \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.
2024  */
2025 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
2026 {
2027   checkAllocated();
2028   if(getNumberOfComponents()!=1)
2029     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
2030   if(nbTimes<1)
2031     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
2032   int nbTuples=getNumberOfTuples();
2033   const double *inPtr=getConstPointer();
2034   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
2035   double *retPtr=ret->getPointer();
2036   for(int i=0;i<nbTuples;i++,inPtr++)
2037     {
2038       double val=*inPtr;
2039       for(int j=0;j<nbTimes;j++,retPtr++)
2040         *retPtr=val;
2041     }
2042   ret->copyStringInfoFrom(*this);
2043   return ret.retn();
2044 }
2045
2046 /*!
2047  * This methods returns the minimal distance between the two set of points \a this and \a other.
2048  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2049  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2050  *
2051  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
2052  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
2053  * \return the minimal distance between the two set of points \a this and \a other.
2054  * \sa DataArrayDouble::findClosestTupleId
2055  */
2056 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
2057 {
2058   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part1=findClosestTupleId(other);
2059   int nbOfCompo(getNumberOfComponents());
2060   int otherNbTuples(other->getNumberOfTuples());
2061   const double *thisPt(begin()),*otherPt(other->begin());
2062   const int *part1Pt(part1->begin());
2063   double ret=std::numeric_limits<double>::max();
2064   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
2065     {
2066       double tmp(0.);
2067       for(int j=0;j<nbOfCompo;j++)
2068         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
2069       if(tmp<ret)
2070         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
2071     }
2072   return sqrt(ret);
2073 }
2074
2075 /*!
2076  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
2077  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
2078  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
2079  *
2080  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
2081  * \sa DataArrayDouble::minimalDistanceTo
2082  */
2083 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
2084 {
2085   if(!other)
2086     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
2087   checkAllocated(); other->checkAllocated();
2088   int nbOfCompo=getNumberOfComponents();
2089   if(nbOfCompo!=other->getNumberOfComponents())
2090     {
2091       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
2092       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
2093       throw INTERP_KERNEL::Exception(oss.str().c_str());
2094     }
2095   int nbOfTuples=other->getNumberOfTuples();
2096   int thisNbOfTuples=getNumberOfTuples();
2097   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2098   double bounds[6];
2099   getMinMaxPerComponent(bounds);
2100   switch(nbOfCompo)
2101   {
2102     case 3:
2103       {
2104         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
2105         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
2106         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
2107         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2108         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2109         break;
2110       }
2111     case 2:
2112       {
2113         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
2114         double delta=std::max(xDelta,yDelta);
2115         double characSize=sqrt(delta/(double)thisNbOfTuples);
2116         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2117         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2118         break;
2119       }
2120     case 1:
2121       {
2122         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
2123         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
2124         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
2125         break;
2126       }
2127     default:
2128       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
2129   }
2130   return ret.retn();
2131 }
2132
2133 /*!
2134  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
2135  * This method will return a DataArrayInt array having the same number of tuples than \a this. This returned array tells for each cell in \a this
2136  * how many bounding boxes in \a otherBBoxFrmt.
2137  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
2138  *
2139  * \param [in] otherBBoxFrmt - It is an array .
2140  * \param [in] eps - the absolute precision of the detection. when eps < 0 the bboxes are enlarged so more interactions are detected. Inversely when > 0 the bboxes are stretched.
2141  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
2142  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
2143  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
2144  */
2145 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
2146 {
2147   if(!otherBBoxFrmt)
2148     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
2149   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
2150     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
2151   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
2152   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
2153     {
2154       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
2155       throw INTERP_KERNEL::Exception(oss.str().c_str());
2156     }
2157   if(nbOfComp%2!=0)
2158     {
2159       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
2160       throw INTERP_KERNEL::Exception(oss.str().c_str());
2161     }
2162   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
2163   const double *thisBBPtr(begin());
2164   int *retPtr(ret->getPointer());
2165   switch(nbOfComp/2)
2166   {
2167     case 3:
2168       {
2169         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2170         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2171           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2172         break;
2173       }
2174     case 2:
2175       {
2176         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2177         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2178           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2179         break;
2180       }
2181     case 1:
2182       {
2183         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
2184         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
2185           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
2186         break;
2187       }
2188     default:
2189       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
2190   }
2191
2192   return ret.retn();
2193 }
2194
2195 /*!
2196  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
2197  * considered as coordinates of a point in getNumberOfComponents()-dimensional
2198  * space. The distance between tuples is computed using norm2. If several tuples are
2199  * not far each from other than \a prec, only one of them remains in the result
2200  * array. The order of tuples in the result array is same as in \a this one except
2201  * that coincident tuples are excluded.
2202  *  \param [in] prec - minimal absolute distance between two tuples at which they are
2203  *              considered not coincident.
2204  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
2205  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
2206  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
2207  *          is to delete using decrRef() as it is no more needed.
2208  *  \throw If \a this is not allocated.
2209  *  \throw If the number of components is not in [1,2,3,4].
2210  *
2211  *  \if ENABLE_EXAMPLES
2212  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
2213  *  \endif
2214  */
2215 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
2216 {
2217   checkAllocated();
2218   DataArrayInt *c0=0,*cI0=0;
2219   findCommonTuples(prec,limitTupleId,c0,cI0);
2220   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
2221   int newNbOfTuples=-1;
2222   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
2223   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
2224 }
2225
2226 /*!
2227  * Copy all components in a specified order from another DataArrayDouble.
2228  * Both numerical and textual data is copied. The number of tuples in \a this and
2229  * the other array can be different.
2230  *  \param [in] a - the array to copy data from.
2231  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
2232  *              to be copied.
2233  *  \throw If \a a is NULL.
2234  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
2235  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
2236  *
2237  *  \if ENABLE_EXAMPLES
2238  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
2239  *  \endif
2240  */
2241 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
2242 {
2243   if(!a)
2244     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
2245   checkAllocated();
2246   copyPartOfStringInfoFrom2(compoIds,*a);
2247   std::size_t partOfCompoSz=compoIds.size();
2248   int nbOfCompo=getNumberOfComponents();
2249   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
2250   const double *ac=a->getConstPointer();
2251   double *nc=getPointer();
2252   for(int i=0;i<nbOfTuples;i++)
2253     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
2254       nc[nbOfCompo*i+compoIds[j]]=*ac;
2255 }
2256
2257 /*!
2258  * Copy all values from another DataArrayDouble into specified tuples and components
2259  * of \a this array. Textual data is not copied.
2260  * The tree parameters defining set of indices of tuples and components are similar to
2261  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2262  *  \param [in] a - the array to copy values from.
2263  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2264  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2265  *              are located.
2266  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2267  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
2268  *  \param [in] endComp - index of the component before which the components to assign
2269  *              to are located.
2270  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2271  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2272  *              must be equal to the number of columns to assign to, else an
2273  *              exception is thrown; if \a false, then it is only required that \a
2274  *              a->getNbOfElems() equals to number of values to assign to (this condition
2275  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2276  *              values to assign to is given by following Python expression:
2277  *              \a nbTargetValues = 
2278  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2279  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2280  *  \throw If \a a is NULL.
2281  *  \throw If \a a is not allocated.
2282  *  \throw If \a this is not allocated.
2283  *  \throw If parameters specifying tuples and components to assign to do not give a
2284  *            non-empty range of increasing indices.
2285  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2286  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2287  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2288  *
2289  *  \if ENABLE_EXAMPLES
2290  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
2291  *  \endif
2292  */
2293 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2294 {
2295   if(!a)
2296     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !");
2297   const char msg[]="DataArrayDouble::setPartOfValues1";
2298   checkAllocated();
2299   a->checkAllocated();
2300   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2301   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2302   int nbComp=getNumberOfComponents();
2303   int nbOfTuples=getNumberOfTuples();
2304   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2305   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2306   bool assignTech=true;
2307   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2308     {
2309       if(strictCompoCompare)
2310         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2311     }
2312   else
2313     {
2314       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2315       assignTech=false;
2316     }
2317   const double *srcPt=a->getConstPointer();
2318   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2319   if(assignTech)
2320     {
2321       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2322         for(int j=0;j<newNbOfComp;j++,srcPt++)
2323           pt[j*stepComp]=*srcPt;
2324     }
2325   else
2326     {
2327       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2328         {
2329           const double *srcPt2=srcPt;
2330           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2331             pt[j*stepComp]=*srcPt2;
2332         }
2333     }
2334 }
2335
2336 /*!
2337  * Assign a given value to values at specified tuples and components of \a this array.
2338  * The tree parameters defining set of indices of tuples and components are similar to
2339  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
2340  *  \param [in] a - the value to assign.
2341  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
2342  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2343  *              are located.
2344  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2345  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2346  *  \param [in] endComp - index of the component before which the components to assign
2347  *              to are located.
2348  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2349  *  \throw If \a this is not allocated.
2350  *  \throw If parameters specifying tuples and components to assign to, do not give a
2351  *            non-empty range of increasing indices or indices are out of a valid range
2352  *            for \this array.
2353  *
2354  *  \if ENABLE_EXAMPLES
2355  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
2356  *  \endif
2357  */
2358 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
2359 {
2360   const char msg[]="DataArrayDouble::setPartOfValuesSimple1";
2361   checkAllocated();
2362   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2363   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2364   int nbComp=getNumberOfComponents();
2365   int nbOfTuples=getNumberOfTuples();
2366   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2367   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2368   double *pt=getPointer()+bgTuples*nbComp+bgComp;
2369   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2370     for(int j=0;j<newNbOfComp;j++)
2371       pt[j*stepComp]=a;
2372 }
2373
2374 /*!
2375  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2376  * components of \a this array. Textual data is not copied.
2377  * The tuples and components to assign to are defined by C arrays of indices.
2378  * There are two *modes of usage*:
2379  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2380  *   of \a a is assigned to its own location within \a this array. 
2381  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2382  *   components of every specified tuple of \a this array. In this mode it is required
2383  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2384  *
2385  *  \param [in] a - the array to copy values from.
2386  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2387  *              assign values of \a a to.
2388  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2389  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2390  *              \a bgTuples <= \a pi < \a endTuples.
2391  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2392  *              assign values of \a a to.
2393  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2394  *              pointer to a component index <em>(pi)</em> varies as this: 
2395  *              \a bgComp <= \a pi < \a endComp.
2396  *  \param [in] strictCompoCompare - this parameter is checked only if the
2397  *               *mode of usage* is the first; if it is \a true (default), 
2398  *               then \a a->getNumberOfComponents() must be equal 
2399  *               to the number of specified columns, else this is not required.
2400  *  \throw If \a a is NULL.
2401  *  \throw If \a a is not allocated.
2402  *  \throw If \a this is not allocated.
2403  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2404  *         out of a valid range for \a this array.
2405  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2406  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
2407  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2408  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
2409  *
2410  *  \if ENABLE_EXAMPLES
2411  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
2412  *  \endif
2413  */
2414 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2415 {
2416   if(!a)
2417     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !");
2418   const char msg[]="DataArrayDouble::setPartOfValues2";
2419   checkAllocated();
2420   a->checkAllocated();
2421   int nbComp=getNumberOfComponents();
2422   int nbOfTuples=getNumberOfTuples();
2423   for(const int *z=bgComp;z!=endComp;z++)
2424     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2425   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2426   int newNbOfComp=(int)std::distance(bgComp,endComp);
2427   bool assignTech=true;
2428   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2429     {
2430       if(strictCompoCompare)
2431         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2432     }
2433   else
2434     {
2435       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2436       assignTech=false;
2437     }
2438   double *pt=getPointer();
2439   const double *srcPt=a->getConstPointer();
2440   if(assignTech)
2441     {    
2442       for(const int *w=bgTuples;w!=endTuples;w++)
2443         {
2444           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2445           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2446             {    
2447               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
2448             }
2449         }
2450     }
2451   else
2452     {
2453       for(const int *w=bgTuples;w!=endTuples;w++)
2454         {
2455           const double *srcPt2=srcPt;
2456           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2457           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2458             {    
2459               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
2460             }
2461         }
2462     }
2463 }
2464
2465 /*!
2466  * Assign a given value to values at specified tuples and components of \a this array.
2467  * The tuples and components to assign to are defined by C arrays of indices.
2468  *  \param [in] a - the value to assign.
2469  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2470  *              assign \a a to.
2471  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2472  *              pointer to a tuple index (\a pi) varies as this: 
2473  *              \a bgTuples <= \a pi < \a endTuples.
2474  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2475  *              assign \a a to.
2476  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2477  *              pointer to a component index (\a pi) varies as this: 
2478  *              \a bgComp <= \a pi < \a endComp.
2479  *  \throw If \a this is not allocated.
2480  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
2481  *         out of a valid range for \a this array.
2482  *
2483  *  \if ENABLE_EXAMPLES
2484  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
2485  *  \endif
2486  */
2487 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
2488 {
2489   checkAllocated();
2490   int nbComp=getNumberOfComponents();
2491   int nbOfTuples=getNumberOfTuples();
2492   for(const int *z=bgComp;z!=endComp;z++)
2493     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2494   double *pt=getPointer();
2495   for(const int *w=bgTuples;w!=endTuples;w++)
2496     for(const int *z=bgComp;z!=endComp;z++)
2497       {
2498         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2499         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
2500       }
2501 }
2502
2503 /*!
2504  * Copy all values from another DataArrayDouble (\a a) into specified tuples and 
2505  * components of \a this array. Textual data is not copied.
2506  * The tuples to assign to are defined by a C array of indices.
2507  * The components to assign to are defined by three values similar to parameters of
2508  * the Python function \c range(\c start,\c stop,\c step).
2509  * There are two *modes of usage*:
2510  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
2511  *   of \a a is assigned to its own location within \a this array. 
2512  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
2513  *   components of every specified tuple of \a this array. In this mode it is required
2514  *   that \a a->getNumberOfComponents() equals to the number of specified components.
2515  *
2516  *  \param [in] a - the array to copy values from.
2517  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2518  *              assign values of \a a to.
2519  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2520  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2521  *              \a bgTuples <= \a pi < \a endTuples.
2522  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2523  *  \param [in] endComp - index of the component before which the components to assign
2524  *              to are located.
2525  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2526  *  \param [in] strictCompoCompare - this parameter is checked only in the first
2527  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
2528  *               then \a a->getNumberOfComponents() must be equal 
2529  *               to the number of specified columns, else this is not required.
2530  *  \throw If \a a is NULL.
2531  *  \throw If \a a is not allocated.
2532  *  \throw If \a this is not allocated.
2533  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2534  *         \a this array.
2535  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
2536  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
2537  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2538  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
2539  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
2540  *         defined by <em>(bgComp,endComp,stepComp)</em>.
2541  *  \throw If parameters specifying components to assign to, do not give a
2542  *            non-empty range of increasing indices or indices are out of a valid range
2543  *            for \this array.
2544  *
2545  *  \if ENABLE_EXAMPLES
2546  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
2547  *  \endif
2548  */
2549 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
2550 {
2551   if(!a)
2552     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !");
2553   const char msg[]="DataArrayDouble::setPartOfValues3";
2554   checkAllocated();
2555   a->checkAllocated();
2556   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2557   int nbComp=getNumberOfComponents();
2558   int nbOfTuples=getNumberOfTuples();
2559   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2560   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
2561   bool assignTech=true;
2562   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2563     {
2564       if(strictCompoCompare)
2565         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2566     }
2567   else
2568     {
2569       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2570       assignTech=false;
2571     }
2572   double *pt=getPointer()+bgComp;
2573   const double *srcPt=a->getConstPointer();
2574   if(assignTech)
2575     {
2576       for(const int *w=bgTuples;w!=endTuples;w++)
2577         for(int j=0;j<newNbOfComp;j++,srcPt++)
2578           {
2579             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2580             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
2581           }
2582     }
2583   else
2584     {
2585       for(const int *w=bgTuples;w!=endTuples;w++)
2586         {
2587           const double *srcPt2=srcPt;
2588           for(int j=0;j<newNbOfComp;j++,srcPt2++)
2589             {
2590               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2591               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
2592             }
2593         }
2594     }
2595 }
2596
2597 /*!
2598  * Assign a given value to values at specified tuples and components of \a this array.
2599  * The tuples to assign to are defined by a C array of indices.
2600  * The components to assign to are defined by three values similar to parameters of
2601  * the Python function \c range(\c start,\c stop,\c step).
2602  *  \param [in] a - the value to assign.
2603  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
2604  *              assign \a a to.
2605  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
2606  *              pointer to a tuple index <em>(pi)</em> varies as this: 
2607  *              \a bgTuples <= \a pi < \a endTuples.
2608  *  \param [in] bgComp - index of the first component of \a this array to assign to.
2609  *  \param [in] endComp - index of the component before which the components to assign
2610  *              to are located.
2611  *  \param [in] stepComp - index increment to get index of the next component to assign to.
2612  *  \throw If \a this is not allocated.
2613  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
2614  *         \a this array.
2615  *  \throw If parameters specifying components to assign to, do not give a
2616  *            non-empty range of increasing indices or indices are out of a valid range
2617  *            for \this array.
2618  *
2619  *  \if ENABLE_EXAMPLES
2620  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
2621  *  \endif
2622  */
2623 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
2624 {
2625   const char msg[]="DataArrayDouble::setPartOfValuesSimple3";
2626   checkAllocated();
2627   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
2628   int nbComp=getNumberOfComponents();
2629   int nbOfTuples=getNumberOfTuples();
2630   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
2631   double *pt=getPointer()+bgComp;
2632   for(const int *w=bgTuples;w!=endTuples;w++)
2633     for(int j=0;j<newNbOfComp;j++)
2634       {
2635         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
2636         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
2637       }
2638 }
2639
2640 /*!
2641  * Copy all values from another DataArrayDouble into specified tuples and components
2642  * of \a this array. Textual data is not copied.
2643  * The tree parameters defining set of indices of tuples and components are similar to
2644  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
2645  *  \param [in] a - the array to copy values from.
2646  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
2647  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
2648  *              are located.
2649  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
2650  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
2651  *              assign \a a to.
2652  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
2653  *              pointer to a component index (\a pi) varies as this: 
2654  *              \a bgComp <= \a pi < \a endComp.
2655  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
2656  *              must be equal to the number of columns to assign to, else an
2657  *              exception is thrown; if \a false, then it is only required that \a
2658  *              a->getNbOfElems() equals to number of values to assign to (this condition
2659  *              must be respected even if \a strictCompoCompare is \a true). The number of 
2660  *              values to assign to is given by following Python expression:
2661  *              \a nbTargetValues = 
2662  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
2663  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2664  *  \throw If \a a is NULL.
2665  *  \throw If \a a is not allocated.
2666  *  \throw If \a this is not allocated.
2667  *  \throw If parameters specifying tuples and components to assign to do not give a
2668  *            non-empty range of increasing indices.
2669  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
2670  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
2671  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
2672  *
2673  */
2674 void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
2675 {
2676   if(!a)
2677     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
2678   const char msg[]="DataArrayDouble::setPartOfValues4";
2679   checkAllocated();
2680   a->checkAllocated();
2681   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2682   int newNbOfComp=(int)std::distance(bgComp,endComp);
2683   int nbComp=getNumberOfComponents();
2684   for(const int *z=bgComp;z!=endComp;z++)
2685     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2686   int nbOfTuples=getNumberOfTuples();
2687   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2688   bool assignTech=true;
2689   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
2690     {
2691       if(strictCompoCompare)
2692         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
2693     }
2694   else
2695     {
2696       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
2697       assignTech=false;
2698     }
2699   const double *srcPt=a->getConstPointer();
2700   double *pt=getPointer()+bgTuples*nbComp;
2701   if(assignTech)
2702     {
2703       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2704         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
2705           pt[*z]=*srcPt;
2706     }
2707   else
2708     {
2709       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2710         {
2711           const double *srcPt2=srcPt;
2712           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
2713             pt[*z]=*srcPt2;
2714         }
2715     }
2716 }
2717
2718 void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
2719 {
2720   const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
2721   checkAllocated();
2722   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
2723   int nbComp=getNumberOfComponents();
2724   for(const int *z=bgComp;z!=endComp;z++)
2725     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
2726   int nbOfTuples=getNumberOfTuples();
2727   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
2728   double *pt=getPointer()+bgTuples*nbComp;
2729   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
2730     for(const int *z=bgComp;z!=endComp;z++)
2731       pt[*z]=a;
2732 }
2733
2734 /*!
2735  * Copy some tuples from another DataArrayDouble into specified tuples
2736  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2737  * components.
2738  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
2739  * All components of selected tuples are copied.
2740  *  \param [in] a - the array to copy values from.
2741  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
2742  *              target tuples of \a this. \a tuplesSelec has two components, and the
2743  *              first component specifies index of the source tuple and the second
2744  *              one specifies index of the target tuple.
2745  *  \throw If \a this is not allocated.
2746  *  \throw If \a a is NULL.
2747  *  \throw If \a a is not allocated.
2748  *  \throw If \a tuplesSelec is NULL.
2749  *  \throw If \a tuplesSelec is not allocated.
2750  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
2751  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
2752  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2753  *         the corresponding (\a this or \a a) array.
2754  */
2755 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec)
2756 {
2757   if(!a || !tuplesSelec)
2758     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
2759   checkAllocated();
2760   a->checkAllocated();
2761   tuplesSelec->checkAllocated();
2762   int nbOfComp=getNumberOfComponents();
2763   if(nbOfComp!=a->getNumberOfComponents())
2764     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !");
2765   if(tuplesSelec->getNumberOfComponents()!=2)
2766     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
2767   int thisNt=getNumberOfTuples();
2768   int aNt=a->getNumberOfTuples();
2769   double *valsToSet=getPointer();
2770   const double *valsSrc=a->getConstPointer();
2771   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
2772     {
2773       if(tuple[1]>=0 && tuple[1]<aNt)
2774         {
2775           if(tuple[0]>=0 && tuple[0]<thisNt)
2776             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
2777           else
2778             {
2779               std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2780               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
2781               throw INTERP_KERNEL::Exception(oss.str().c_str());
2782             }
2783         }
2784       else
2785         {
2786           std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
2787           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
2788           throw INTERP_KERNEL::Exception(oss.str().c_str());
2789         }
2790     }
2791 }
2792
2793 /*!
2794  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2795  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2796  * components.
2797  * The tuples to assign to are defined by index of the first tuple, and
2798  * their number is defined by \a tuplesSelec->getNumberOfTuples().
2799  * The tuples to copy are defined by values of a DataArrayInt.
2800  * All components of selected tuples are copied.
2801  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2802  *              values to.
2803  *  \param [in] aBase - the array to copy values from.
2804  *  \param [in] tuplesSelec - the array specifying tuples of \a a to copy.
2805  *  \throw If \a this is not allocated.
2806  *  \throw If \a aBase is NULL.
2807  *  \throw If \a aBase is not allocated.
2808  *  \throw If \a tuplesSelec is NULL.
2809  *  \throw If \a tuplesSelec is not allocated.
2810  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2811  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
2812  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
2813  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
2814  *         \a aBase array.
2815  */
2816 void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
2817 {
2818   if(!aBase || !tuplesSelec)
2819     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !");
2820   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2821   if(!a)
2822     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !");
2823   checkAllocated();
2824   a->checkAllocated();
2825   tuplesSelec->checkAllocated();
2826   int nbOfComp=getNumberOfComponents();
2827   if(nbOfComp!=a->getNumberOfComponents())
2828     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !");
2829   if(tuplesSelec->getNumberOfComponents()!=1)
2830     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
2831   int thisNt=getNumberOfTuples();
2832   int aNt=a->getNumberOfTuples();
2833   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
2834   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2835   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2836     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !");
2837   const double *valsSrc=a->getConstPointer();
2838   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
2839     {
2840       if(*tuple>=0 && *tuple<aNt)
2841         {
2842           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
2843         }
2844       else
2845         {
2846           std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
2847           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
2848           throw INTERP_KERNEL::Exception(oss.str().c_str());
2849         }
2850     }
2851 }
2852
2853 /*!
2854  * Copy some tuples from another DataArrayDouble (\a aBase) into contiguous tuples
2855  * of \a this array. Textual data is not copied. Both arrays must have equal number of
2856  * components.
2857  * The tuples to copy are defined by three values similar to parameters of
2858  * the Python function \c range(\c start,\c stop,\c step).
2859  * The tuples to assign to are defined by index of the first tuple, and
2860  * their number is defined by number of tuples to copy.
2861  * All components of selected tuples are copied.
2862  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
2863  *              values to.
2864  *  \param [in] aBase - the array to copy values from.
2865  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
2866  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
2867  *              are located.
2868  *  \param [in] step - index increment to get index of the next tuple to copy.
2869  *  \throw If \a this is not allocated.
2870  *  \throw If \a aBase is NULL.
2871  *  \throw If \a aBase is not allocated.
2872  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
2873  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
2874  *  \throw If parameters specifying tuples to copy, do not give a
2875  *            non-empty range of increasing indices or indices are out of a valid range
2876  *            for the array \a aBase.
2877  */
2878 void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
2879 {
2880   if(!aBase)
2881     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !");
2882   const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase);
2883   if(!a)
2884     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !");
2885   checkAllocated();
2886   a->checkAllocated();
2887   int nbOfComp=getNumberOfComponents();
2888   const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2";
2889   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
2890   if(nbOfComp!=a->getNumberOfComponents())
2891     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
2892   int thisNt=getNumberOfTuples();
2893   int aNt=a->getNumberOfTuples();
2894   double *valsToSet=getPointer()+tupleIdStart*nbOfComp;
2895   if(tupleIdStart+nbOfTupleToWrite>thisNt)
2896     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !");
2897   if(end2>aNt)
2898     throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !");
2899   const double *valsSrc=a->getConstPointer()+bg*nbOfComp;
2900   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
2901     {
2902       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
2903     }
2904 }
2905
2906 /*!
2907  * Returns a value located at specified tuple and component.
2908  * This method is equivalent to DataArrayDouble::getIJ() except that validity of
2909  * parameters is checked. So this method is safe but expensive if used to go through
2910  * all values of \a this.
2911  *  \param [in] tupleId - index of tuple of interest.
2912  *  \param [in] compoId - index of component of interest.
2913  *  \return double - value located by \a tupleId and \a compoId.
2914  *  \throw If \a this is not allocated.
2915  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
2916  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
2917  */
2918 double DataArrayDouble::getIJSafe(int tupleId, int compoId) const
2919 {
2920   checkAllocated();
2921   if(tupleId<0 || tupleId>=getNumberOfTuples())
2922     {
2923       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
2924       throw INTERP_KERNEL::Exception(oss.str().c_str());
2925     }
2926   if(compoId<0 || compoId>=getNumberOfComponents())
2927     {
2928       std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
2929       throw INTERP_KERNEL::Exception(oss.str().c_str());
2930     }
2931   return _mem[tupleId*_info_on_compo.size()+compoId];
2932 }
2933
2934 /*!
2935  * Returns the first value of \a this. 
2936  *  \return double - the last value of \a this array.
2937  *  \throw If \a this is not allocated.
2938  *  \throw If \a this->getNumberOfComponents() != 1.
2939  *  \throw If \a this->getNumberOfTuples() < 1.
2940  */
2941 double DataArrayDouble::front() const
2942 {
2943   checkAllocated();
2944   if(getNumberOfComponents()!=1)
2945     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
2946   int nbOfTuples=getNumberOfTuples();
2947   if(nbOfTuples<1)
2948     throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
2949   return *(getConstPointer());
2950 }
2951
2952 /*!
2953  * Returns the last value of \a this. 
2954  *  \return double - the last value of \a this array.
2955  *  \throw If \a this is not allocated.
2956  *  \throw If \a this->getNumberOfComponents() != 1.
2957  *  \throw If \a this->getNumberOfTuples() < 1.
2958  */
2959 double DataArrayDouble::back() const
2960 {
2961   checkAllocated();
2962   if(getNumberOfComponents()!=1)
2963     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !");
2964   int nbOfTuples=getNumberOfTuples();
2965   if(nbOfTuples<1)
2966     throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !");
2967   return *(getConstPointer()+nbOfTuples-1);
2968 }
2969
2970 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
2971 {
2972   if(newArray!=arrayToSet)
2973     {
2974       if(arrayToSet)
2975         arrayToSet->decrRef();
2976       arrayToSet=newArray;
2977       if(arrayToSet)
2978         arrayToSet->incrRef();
2979     }
2980 }
2981
2982 /*!
2983  * Sets a C array to be used as raw data of \a this. The previously set info
2984  *  of components is retained and re-sized. 
2985  * For more info see \ref MEDCouplingArraySteps1.
2986  *  \param [in] array - the C array to be used as raw data of \a this.
2987  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
2988  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
2989  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
2990  *                     \c free(\c array ) will be called.
2991  *  \param [in] nbOfTuple - new number of tuples in \a this.
2992  *  \param [in] nbOfCompo - new number of components in \a this.
2993  */
2994 void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
2995 {
2996   _info_on_compo.resize(nbOfCompo);
2997   _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
2998   declareAsNew();
2999 }
3000
3001 void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo)
3002 {
3003   _info_on_compo.resize(nbOfCompo);
3004   _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
3005   declareAsNew();
3006 }
3007
3008 /*!
3009  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
3010  * is thrown.
3011  * \throw If zero is found in \a this array.
3012  */
3013 void DataArrayDouble::checkNoNullValues() const
3014 {
3015   const double *tmp=getConstPointer();
3016   std::size_t nbOfElems=getNbOfElems();
3017   const double *where=std::find(tmp,tmp+nbOfElems,0.);
3018   if(where!=tmp+nbOfElems)
3019     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
3020 }
3021
3022 /*!
3023  * Computes minimal and maximal value in each component. An output array is filled
3024  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
3025  * enough memory before calling this method.
3026  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
3027  *               It is filled as follows:<br>
3028  *               \a bounds[0] = \c min_of_component_0 <br>
3029  *               \a bounds[1] = \c max_of_component_0 <br>
3030  *               \a bounds[2] = \c min_of_component_1 <br>
3031  *               \a bounds[3] = \c max_of_component_1 <br>
3032  *               ...
3033  */
3034 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
3035 {
3036   checkAllocated();
3037   int dim=getNumberOfComponents();
3038   for (int idim=0; idim<dim; idim++)
3039     {
3040       bounds[idim*2]=std::numeric_limits<double>::max();
3041       bounds[idim*2+1]=-std::numeric_limits<double>::max();
3042     } 
3043   const double *ptr=getConstPointer();
3044   int nbOfTuples=getNumberOfTuples();
3045   for(int i=0;i<nbOfTuples;i++)
3046     {
3047       for(int idim=0;idim<dim;idim++)
3048         {
3049           if(bounds[idim*2]>ptr[i*dim+idim])
3050             {
3051               bounds[idim*2]=ptr[i*dim+idim];
3052             }
3053           if(bounds[idim*2+1]<ptr[i*dim+idim])
3054             {
3055               bounds[idim*2+1]=ptr[i*dim+idim];
3056             }
3057         }
3058     }
3059 }
3060
3061 /*!
3062  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
3063  * to store both the min and max per component of each tuples. 
3064  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
3065  *
3066  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
3067  *
3068  * \throw If \a this is not allocated yet.
3069  */
3070 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
3071 {
3072   checkAllocated();
3073   const double *dataPtr=getConstPointer();
3074   int nbOfCompo=getNumberOfComponents();
3075   int nbTuples=getNumberOfTuples();
3076   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New();
3077   bbox->alloc(nbTuples,2*nbOfCompo);
3078   double *bboxPtr=bbox->getPointer();
3079   for(int i=0;i<nbTuples;i++)
3080     {
3081       for(int j=0;j<nbOfCompo;j++)
3082         {
3083           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
3084           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
3085         }
3086     }
3087   return bbox.retn();
3088 }
3089
3090 /*!
3091  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
3092  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
3093  * 
3094  * \param [in] other a DataArrayDouble having same number of components than \a this.
3095  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
3096  * \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.
3097  *             \a cI allows to extract information in \a c.
3098  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
3099  *
3100  * \throw In case of:
3101  *  - \a this is not allocated
3102  *  - \a other is not allocated or null
3103  *  - \a this and \a other do not have the same number of components
3104  *  - if number of components of \a this is not in [1,2,3]
3105  *
3106  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
3107  */
3108 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
3109 {
3110   if(!other)
3111     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
3112   checkAllocated();
3113   other->checkAllocated();
3114   int nbOfCompo=getNumberOfComponents();
3115   int otherNbOfCompo=other->getNumberOfComponents();
3116   if(nbOfCompo!=otherNbOfCompo)
3117     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
3118   int nbOfTuplesOther=other->getNumberOfTuples();
3119   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
3120   switch(nbOfCompo)
3121   {
3122     case 3:
3123       {
3124         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3125         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3126         break;
3127       }
3128     case 2:
3129       {
3130         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3131         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3132         break;
3133       }
3134     case 1:
3135       {
3136         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
3137         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
3138         break;
3139       }
3140     default:
3141       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
3142   }
3143   c=cArr.retn(); cI=cIArr.retn();
3144 }
3145
3146 /*!
3147  * 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
3148  * around origin of 'radius' 1.
3149  * 
3150  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
3151  */
3152 void DataArrayDouble::recenterForMaxPrecision(double eps)
3153 {
3154   checkAllocated();
3155   int dim=getNumberOfComponents();
3156   std::vector<double> bounds(2*dim);
3157   getMinMaxPerComponent(&bounds[0]);
3158   for(int i=0;i<dim;i++)
3159     {
3160       double delta=bounds[2*i+1]-bounds[2*i];
3161       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
3162       if(delta>eps)
3163         applyLin(1./delta,-offset/delta,i);
3164       else
3165         applyLin(1.,-offset,i);
3166     }
3167 }
3168
3169 /*!
3170  * Returns the maximal value and its location within \a this one-dimensional array.
3171  *  \param [out] tupleId - index of the tuple holding the maximal value.
3172  *  \return double - the maximal value among all values of \a this array.
3173  *  \throw If \a this->getNumberOfComponents() != 1
3174  *  \throw If \a this->getNumberOfTuples() < 1
3175  */
3176 double DataArrayDouble::getMaxValue(int& tupleId) const
3177 {
3178   checkAllocated();
3179   if(getNumberOfComponents()!=1)
3180     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 !");
3181   int nbOfTuples=getNumberOfTuples();
3182   if(nbOfTuples<=0)
3183     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !");
3184   const double *vals=getConstPointer();
3185   const double *loc=std::max_element(vals,vals+nbOfTuples);
3186   tupleId=(int)std::distance(vals,loc);
3187   return *loc;
3188 }
3189
3190 /*!
3191  * Returns the maximal value within \a this array that is allowed to have more than
3192  *  one component.
3193  *  \return double - the maximal value among all values of \a this array.
3194  *  \throw If \a this is not allocated.
3195  */
3196 double DataArrayDouble::getMaxValueInArray() const
3197 {
3198   checkAllocated();
3199   const double *loc=std::max_element(begin(),end());
3200   return *loc;
3201 }
3202
3203 /*!
3204  * Returns the maximal value and all its locations within \a this one-dimensional array.
3205  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3206  *               tuples holding the maximal value. The caller is to delete it using
3207  *               decrRef() as it is no more needed.
3208  *  \return double - the maximal value among all values of \a this array.
3209  *  \throw If \a this->getNumberOfComponents() != 1
3210  *  \throw If \a this->getNumberOfTuples() < 1
3211  */
3212 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
3213 {
3214   int tmp;
3215   tupleIds=0;
3216   double ret=getMaxValue(tmp);
3217   tupleIds=getIdsInRange(ret,ret);
3218   return ret;
3219 }
3220
3221 /*!
3222  * Returns the minimal value and its location within \a this one-dimensional array.
3223  *  \param [out] tupleId - index of the tuple holding the minimal value.
3224  *  \return double - the minimal value among all values of \a this array.
3225  *  \throw If \a this->getNumberOfComponents() != 1
3226  *  \throw If \a this->getNumberOfTuples() < 1
3227  */
3228 double DataArrayDouble::getMinValue(int& tupleId) const
3229 {
3230   checkAllocated();
3231   if(getNumberOfComponents()!=1)
3232     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
3233   int nbOfTuples=getNumberOfTuples();
3234   if(nbOfTuples<=0)
3235     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !");
3236   const double *vals=getConstPointer();
3237   const double *loc=std::min_element(vals,vals+nbOfTuples);
3238   tupleId=(int)std::distance(vals,loc);
3239   return *loc;
3240 }
3241
3242 /*!
3243  * Returns the minimal value within \a this array that is allowed to have more than
3244  *  one component.
3245  *  \return double - the minimal value among all values of \a this array.
3246  *  \throw If \a this is not allocated.
3247  */
3248 double DataArrayDouble::getMinValueInArray() const
3249 {
3250   checkAllocated();
3251   const double *loc=std::min_element(begin(),end());
3252   return *loc;
3253 }
3254
3255 /*!
3256  * Returns the minimal value and all its locations within \a this one-dimensional array.
3257  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
3258  *               tuples holding the minimal value. The caller is to delete it using
3259  *               decrRef() as it is no more needed.
3260  *  \return double - the minimal value among all values of \a this array.
3261  *  \throw If \a this->getNumberOfComponents() != 1
3262  *  \throw If \a this->getNumberOfTuples() < 1
3263  */
3264 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
3265 {
3266   int tmp;
3267   tupleIds=0;
3268   double ret=getMinValue(tmp);
3269   tupleIds=getIdsInRange(ret,ret);
3270   return ret;
3271 }
3272
3273 /*!
3274  * 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.
3275  * This method only works for single component array.
3276  *
3277  * \return a value in [ 0, \c this->getNumberOfTuples() )
3278  *
3279  * \throw If \a this is not allocated
3280  *
3281  */
3282 int DataArrayDouble::count(double value, double eps) const
3283 {
3284   int ret=0;
3285   checkAllocated();
3286   if(getNumberOfComponents()!=1)
3287     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3288   const double *vals=begin();
3289   int nbOfTuples=getNumberOfTuples();
3290   for(int i=0;i<nbOfTuples;i++,vals++)
3291     if(fabs(*vals-value)<=eps)
3292       ret++;
3293   return ret;
3294 }
3295
3296 /*!
3297  * Returns the average value of \a this one-dimensional array.
3298  *  \return double - the average value over all values of \a this array.
3299  *  \throw If \a this->getNumberOfComponents() != 1
3300  *  \throw If \a this->getNumberOfTuples() < 1
3301  */
3302 double DataArrayDouble::getAverageValue() const
3303 {
3304   if(getNumberOfComponents()!=1)
3305     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
3306   int nbOfTuples=getNumberOfTuples();
3307   if(nbOfTuples<=0)
3308     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
3309   const double *vals=getConstPointer();
3310   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
3311   return ret/nbOfTuples;
3312 }
3313
3314 /*!
3315  * Returns the Euclidean norm of the vector defined by \a this array.
3316  *  \return double - the value of the Euclidean norm, i.e.
3317  *          the square root of the inner product of vector.
3318  *  \throw If \a this is not allocated.
3319  */
3320 double DataArrayDouble::norm2() const
3321 {
3322   checkAllocated();
3323   double ret=0.;
3324   std::size_t nbOfElems=getNbOfElems();
3325   const double *pt=getConstPointer();
3326   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3327     ret+=(*pt)*(*pt);
3328   return sqrt(ret);
3329 }
3330
3331 /*!
3332  * Returns the maximum norm of the vector defined by \a this array.
3333  * This method works even if the number of components is diferent from one.
3334  * If the number of elements in \a this is 0, -1. is returned.
3335  *  \return double - the value of the maximum norm, i.e.
3336  *          the maximal absolute value among values of \a this array (whatever its number of components).
3337  *  \throw If \a this is not allocated.
3338  */
3339 double DataArrayDouble::normMax() const
3340 {
3341   checkAllocated();
3342   double ret(-1.);
3343   std::size_t nbOfElems(getNbOfElems());
3344   const double *pt(getConstPointer());
3345   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3346     {
3347       double val(std::abs(*pt));
3348       if(val>ret)
3349         ret=val;
3350     }
3351   return ret;
3352 }
3353
3354 /*!
3355  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
3356  * This method works even if the number of components is diferent from one.
3357  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
3358  *  \return double - the value of the minimum norm, i.e.
3359  *          the minimal absolute value among values of \a this array (whatever its number of components).
3360  *  \throw If \a this is not allocated.
3361  */
3362 double DataArrayDouble::normMin() const
3363 {
3364   checkAllocated();
3365   double ret(std::numeric_limits<double>::max());
3366   std::size_t nbOfElems(getNbOfElems());
3367   const double *pt(getConstPointer());
3368   for(std::size_t i=0;i<nbOfElems;i++,pt++)
3369     {
3370       double val(std::abs(*pt));
3371       if(val<ret)
3372         ret=val;
3373     }
3374   return ret;
3375 }
3376
3377 /*!
3378  * Accumulates values of each component of \a this array.
3379  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
3380  *         by the caller, that is filled by this method with sum value for each
3381  *         component.
3382  *  \throw If \a this is not allocated.
3383  */
3384 void DataArrayDouble::accumulate(double *res) const
3385 {
3386   checkAllocated();
3387   const double *ptr=getConstPointer();
3388   int nbTuple=getNumberOfTuples();
3389   int nbComps=getNumberOfComponents();
3390   std::fill(res,res+nbComps,0.);
3391   for(int i=0;i<nbTuple;i++)
3392     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
3393 }
3394
3395 /*!
3396  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
3397  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
3398  *
3399  *
3400  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
3401  * \a tupleEnd. If not an exception will be thrown.
3402  *
3403  * \param [in] tupleBg start pointer (included) of input external tuple
3404  * \param [in] tupleEnd end pointer (not included) of input external tuple
3405  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
3406  * \return the min distance.
3407  * \sa MEDCouplingUMesh::distanceToPoint
3408  */
3409 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
3410 {
3411   checkAllocated();
3412   int nbTuple=getNumberOfTuples();
3413   int nbComps=getNumberOfComponents();
3414   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
3415     { 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()); }
3416   if(nbTuple==0)
3417     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
3418   double ret0=std::numeric_limits<double>::max();
3419   tupleId=-1;
3420   const double *work=getConstPointer();
3421   for(int i=0;i<nbTuple;i++)
3422     {
3423       double val=0.;
3424       for(int j=0;j<nbComps;j++,work++) 
3425         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
3426       if(val>=ret0)
3427         continue;
3428       else
3429         { ret0=val; tupleId=i; }
3430     }
3431   return sqrt(ret0);
3432 }
3433
3434 /*!
3435  * Accumulate values of the given component of \a this array.
3436  *  \param [in] compId - the index of the component of interest.
3437  *  \return double - a sum value of \a compId-th component.
3438  *  \throw If \a this is not allocated.
3439  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
3440  *         not respected.
3441  */
3442 double DataArrayDouble::accumulate(int compId) const
3443 {
3444   checkAllocated();
3445   const double *ptr=getConstPointer();
3446   int nbTuple=getNumberOfTuples();
3447   int nbComps=getNumberOfComponents();
3448   if(compId<0 || compId>=nbComps)
3449     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
3450   double ret=0.;
3451   for(int i=0;i<nbTuple;i++)
3452     ret+=ptr[i*nbComps+compId];
3453   return ret;
3454 }
3455
3456 /*!
3457  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
3458  * The returned array will have same number of components than \a this and number of tuples equal to
3459  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
3460  *
3461  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
3462  * 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.
3463  *
3464  * \param [in] bgOfIndex - begin (included) of the input index array.
3465  * \param [in] endOfIndex - end (excluded) of the input index array.
3466  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
3467  * 
3468  * \throw If bgOfIndex or end is NULL.
3469  * \throw If input index array is not ascendingly sorted.
3470  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
3471  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
3472  */
3473 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
3474 {
3475   if(!bgOfIndex || !endOfIndex)
3476     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
3477   checkAllocated();
3478   int nbCompo=getNumberOfComponents();
3479   int nbOfTuples=getNumberOfTuples();
3480   int sz=(int)std::distance(bgOfIndex,endOfIndex);
3481   if(sz<1)
3482     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
3483   sz--;
3484   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
3485   const int *w=bgOfIndex;
3486   if(*w<0 || *w>=nbOfTuples)
3487     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
3488   const double *srcPt=begin()+(*w)*nbCompo;
3489   double *tmp=ret->getPointer();
3490   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
3491     {
3492       std::fill(tmp,tmp+nbCompo,0.);
3493       if(w[1]>=w[0])
3494         {
3495           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
3496             {
3497               if(j>=0 && j<nbOfTuples)
3498                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
3499               else
3500                 {
3501                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
3502                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3503                 }
3504             }
3505         }
3506       else
3507         {
3508           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
3509           throw INTERP_KERNEL::Exception(oss.str().c_str());
3510         }
3511     }
3512   ret->copyStringInfoFrom(*this);
3513   return ret.retn();
3514 }
3515
3516 /*!
3517  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
3518  * Cartesian coordinate system. The two components of the tuple of \a this array are 
3519  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
3520  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3521  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
3522  *          is to delete this array using decrRef() as it is no more needed. The array
3523  *          does not contain any textual info on components.
3524  *  \throw If \a this->getNumberOfComponents() != 2.
3525  */
3526 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
3527 {
3528   checkAllocated();
3529   int nbOfComp=getNumberOfComponents();
3530   if(nbOfComp!=2)
3531     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
3532   int nbOfTuple=getNumberOfTuples();
3533   DataArrayDouble *ret=DataArrayDouble::New();
3534   ret->alloc(nbOfTuple,2);
3535   double *w=ret->getPointer();
3536   const double *wIn=getConstPointer();
3537   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
3538     {
3539       w[0]=wIn[0]*cos(wIn[1]);
3540       w[1]=wIn[0]*sin(wIn[1]);
3541     }
3542   return ret;
3543 }
3544
3545 /*!
3546  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
3547  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3548  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
3549  * the Cylindrical CS.
3550  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3551  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3552  *          on the third component is copied from \a this array. The caller
3553  *          is to delete this array using decrRef() as it is no more needed. 
3554  *  \throw If \a this->getNumberOfComponents() != 3.
3555  */
3556 DataArrayDouble *DataArrayDouble::fromCylToCart() const
3557 {
3558   checkAllocated();
3559   int nbOfComp=getNumberOfComponents();
3560   if(nbOfComp!=3)
3561     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
3562   int nbOfTuple=getNumberOfTuples();
3563   DataArrayDouble *ret=DataArrayDouble::New();
3564   ret->alloc(getNumberOfTuples(),3);
3565   double *w=ret->getPointer();
3566   const double *wIn=getConstPointer();
3567   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3568     {
3569       w[0]=wIn[0]*cos(wIn[1]);
3570       w[1]=wIn[0]*sin(wIn[1]);
3571       w[2]=wIn[2];
3572     }
3573   ret->setInfoOnComponent(2,getInfoOnComponent(2));
3574   return ret;
3575 }
3576
3577 /*!
3578  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
3579  * the Cartesian coordinate system. The three components of the tuple of \a this array 
3580  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
3581  * point in the Cylindrical CS.
3582  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3583  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
3584  *          on the third component is copied from \a this array. The caller
3585  *          is to delete this array using decrRef() as it is no more needed.
3586  *  \throw If \a this->getNumberOfComponents() != 3.
3587  */
3588 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
3589 {
3590   checkAllocated();
3591   int nbOfComp=getNumberOfComponents();
3592   if(nbOfComp!=3)
3593     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
3594   int nbOfTuple=getNumberOfTuples();
3595   DataArrayDouble *ret=DataArrayDouble::New();
3596   ret->alloc(getNumberOfTuples(),3);
3597   double *w=ret->getPointer();
3598   const double *wIn=getConstPointer();
3599   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
3600     {
3601       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
3602       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
3603       w[2]=wIn[0]*cos(wIn[1]);
3604     }
3605   return ret;
3606 }
3607
3608 /*!
3609  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
3610  * array contating 6 components.
3611  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3612  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
3613  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
3614  *         The caller is to delete this result array using decrRef() as it is no more needed. 
3615  *  \throw If \a this->getNumberOfComponents() != 6.
3616  */
3617 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
3618 {
3619   checkAllocated();
3620   int nbOfComp=getNumberOfComponents();
3621   if(nbOfComp!=6)
3622     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
3623   DataArrayDouble *ret=DataArrayDouble::New();
3624   int nbOfTuple=getNumberOfTuples();
3625   ret->alloc(nbOfTuple,1);
3626   const double *src=getConstPointer();
3627   double *dest=ret->getPointer();
3628   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3629     *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];
3630   return ret;
3631 }
3632
3633 /*!
3634  * Computes the determinant of every square matrix defined by the tuple of \a this
3635  * array, which contains either 4, 6 or 9 components. The case of 6 components
3636  * corresponds to that of the upper triangular matrix.
3637  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
3638  *          is the determinant of matrix of the corresponding tuple of \a this array.
3639  *          The caller is to delete this result array using decrRef() as it is no more
3640  *          needed. 
3641  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3642  */
3643 DataArrayDouble *DataArrayDouble::determinant() const
3644 {
3645   checkAllocated();
3646   DataArrayDouble *ret=DataArrayDouble::New();
3647   int nbOfTuple=getNumberOfTuples();
3648   ret->alloc(nbOfTuple,1);
3649   const double *src=getConstPointer();
3650   double *dest=ret->getPointer();
3651   switch(getNumberOfComponents())
3652   {
3653     case 6:
3654       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3655         *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];
3656       return ret;
3657     case 4:
3658       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3659         *dest=src[0]*src[3]-src[1]*src[2];
3660       return ret;
3661     case 9:
3662       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3663         *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];
3664       return ret;
3665     default:
3666       ret->decrRef();
3667       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
3668   }
3669 }
3670
3671 /*!
3672  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
3673  * \a this array, which contains 6 components.
3674  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
3675  *          components, whose each tuple contains the eigenvalues of the matrix of
3676  *          corresponding tuple of \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::eigenValues() const
3682 {
3683   checkAllocated();
3684   int nbOfComp=getNumberOfComponents();
3685   if(nbOfComp!=6)
3686     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
3687   DataArrayDouble *ret=DataArrayDouble::New();
3688   int nbOfTuple=getNumberOfTuples();
3689   ret->alloc(nbOfTuple,3);
3690   const double *src=getConstPointer();
3691   double *dest=ret->getPointer();
3692   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
3693     INTERP_KERNEL::computeEigenValues6(src,dest);
3694   return ret;
3695 }
3696
3697 /*!
3698  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
3699  * \a this array, which contains 6 components.
3700  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
3701  *          components, whose each tuple contains 3 eigenvectors of the matrix of
3702  *          corresponding tuple of \a this array.
3703  *          The caller is to delete this result array using decrRef() as it is no more
3704  *          needed.
3705  *  \throw If \a this->getNumberOfComponents() != 6.
3706  */
3707 DataArrayDouble *DataArrayDouble::eigenVectors() const
3708 {
3709   checkAllocated();
3710   int nbOfComp=getNumberOfComponents();
3711   if(nbOfComp!=6)
3712     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
3713   DataArrayDouble *ret=DataArrayDouble::New();
3714   int nbOfTuple=getNumberOfTuples();
3715   ret->alloc(nbOfTuple,9);
3716   const double *src=getConstPointer();
3717   double *dest=ret->getPointer();
3718   for(int i=0;i<nbOfTuple;i++,src+=6)
3719     {
3720       double tmp[3];
3721       INTERP_KERNEL::computeEigenValues6(src,tmp);
3722       for(int j=0;j<3;j++,dest+=3)
3723         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
3724     }
3725   return ret;
3726 }
3727
3728 /*!
3729  * Computes the inverse matrix of every matrix defined by the tuple of \a this
3730  * array, which contains either 4, 6 or 9 components. The case of 6 components
3731  * corresponds to that of the upper triangular matrix.
3732  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3733  *          same number of components as \a this one, whose each tuple is the inverse
3734  *          matrix of the matrix of corresponding tuple of \a this array. 
3735  *          The caller is to delete this result array using decrRef() as it is no more
3736  *          needed. 
3737  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3738  */
3739 DataArrayDouble *DataArrayDouble::inverse() const
3740 {
3741   checkAllocated();
3742   int nbOfComp=getNumberOfComponents();
3743   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3744     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
3745   DataArrayDouble *ret=DataArrayDouble::New();
3746   int nbOfTuple=getNumberOfTuples();
3747   ret->alloc(nbOfTuple,nbOfComp);
3748   const double *src=getConstPointer();
3749   double *dest=ret->getPointer();
3750   if(nbOfComp==6)
3751     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3752       {
3753         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];
3754         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
3755         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
3756         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
3757         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
3758         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
3759         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
3760       }
3761   else if(nbOfComp==4)
3762     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
3763       {
3764         double det=src[0]*src[3]-src[1]*src[2];
3765         dest[0]=src[3]/det;
3766         dest[1]=-src[1]/det;
3767         dest[2]=-src[2]/det;
3768         dest[3]=src[0]/det;
3769       }
3770   else
3771     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
3772       {
3773         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];
3774         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
3775         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
3776         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
3777         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
3778         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
3779         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
3780         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
3781         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
3782         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
3783       }
3784   return ret;
3785 }
3786
3787 /*!
3788  * Computes the trace of every matrix defined by the tuple of \a this
3789  * array, which contains either 4, 6 or 9 components. The case of 6 components
3790  * corresponds to that of the upper triangular matrix.
3791  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
3792  *          1 component, whose each tuple is the trace of
3793  *          the matrix of corresponding tuple of \a this array. 
3794  *          The caller is to delete this result array using decrRef() as it is no more
3795  *          needed. 
3796  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
3797  */
3798 DataArrayDouble *DataArrayDouble::trace() const
3799 {
3800   checkAllocated();
3801   int nbOfComp=getNumberOfComponents();
3802   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
3803     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
3804   DataArrayDouble *ret=DataArrayDouble::New();
3805   int nbOfTuple=getNumberOfTuples();
3806   ret->alloc(nbOfTuple,1);
3807   const double *src=getConstPointer();
3808   double *dest=ret->getPointer();
3809   if(nbOfComp==6)
3810     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
3811       *dest=src[0]+src[1]+src[2];
3812   else if(nbOfComp==4)
3813     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
3814       *dest=src[0]+src[3];
3815   else
3816     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
3817       *dest=src[0]+src[4]+src[8];
3818   return ret;
3819 }
3820
3821 /*!
3822  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
3823  * \a this array, which contains 6 components.
3824  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3825  *          same number of components and tuples as \a this array.
3826  *          The caller is to delete this result array using decrRef() as it is no more
3827  *          needed.
3828  *  \throw If \a this->getNumberOfComponents() != 6.
3829  */
3830 DataArrayDouble *DataArrayDouble::deviator() const
3831 {
3832   checkAllocated();
3833   int nbOfComp=getNumberOfComponents();
3834   if(nbOfComp!=6)
3835     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
3836   DataArrayDouble *ret=DataArrayDouble::New();
3837   int nbOfTuple=getNumberOfTuples();
3838   ret->alloc(nbOfTuple,6);
3839   const double *src=getConstPointer();
3840   double *dest=ret->getPointer();
3841   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
3842     {
3843       double tr=(src[0]+src[1]+src[2])/3.;
3844       dest[0]=src[0]-tr;
3845       dest[1]=src[1]-tr;
3846       dest[2]=src[2]-tr;
3847       dest[3]=src[3];
3848       dest[4]=src[4];
3849       dest[5]=src[5];
3850     }
3851   return ret;
3852 }
3853
3854 /*!
3855  * Computes the magnitude of every vector defined by the tuple of
3856  * \a this array.
3857  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3858  *          same number of tuples as \a this array and one component.
3859  *          The caller is to delete this result array using decrRef() as it is no more
3860  *          needed.
3861  *  \throw If \a this is not allocated.
3862  */
3863 DataArrayDouble *DataArrayDouble::magnitude() const
3864 {
3865   checkAllocated();
3866   int nbOfComp=getNumberOfComponents();
3867   DataArrayDouble *ret=DataArrayDouble::New();
3868   int nbOfTuple=getNumberOfTuples();
3869   ret->alloc(nbOfTuple,1);
3870   const double *src=getConstPointer();
3871   double *dest=ret->getPointer();
3872   for(int i=0;i<nbOfTuple;i++,dest++)
3873     {
3874       double sum=0.;
3875       for(int j=0;j<nbOfComp;j++,src++)
3876         sum+=(*src)*(*src);
3877       *dest=sqrt(sum);
3878     }
3879   return ret;
3880 }
3881
3882 /*!
3883  * Computes for each tuple the sum of number of components values in the tuple and return it.
3884  * 
3885  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3886  *          same number of tuples as \a this array and one component.
3887  *          The caller is to delete this result array using decrRef() as it is no more
3888  *          needed.
3889  *  \throw If \a this is not allocated.
3890  */
3891 DataArrayDouble *DataArrayDouble::sumPerTuple() const
3892 {
3893   checkAllocated();
3894   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
3895   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
3896   ret->alloc(nbOfTuple,1);
3897   const double *src(getConstPointer());
3898   double *dest(ret->getPointer());
3899   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3900     *dest=std::accumulate(src,src+nbOfComp,0.);
3901   return ret.retn();
3902 }
3903
3904 /*!
3905  * Computes the maximal value within every tuple of \a this array.
3906  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3907  *          same number of tuples as \a this array and one component.
3908  *          The caller is to delete this result array using decrRef() as it is no more
3909  *          needed.
3910  *  \throw If \a this is not allocated.
3911  *  \sa DataArrayDouble::maxPerTupleWithCompoId
3912  */
3913 DataArrayDouble *DataArrayDouble::maxPerTuple() const
3914 {
3915   checkAllocated();
3916   int nbOfComp=getNumberOfComponents();
3917   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3918   int nbOfTuple=getNumberOfTuples();
3919   ret->alloc(nbOfTuple,1);
3920   const double *src=getConstPointer();
3921   double *dest=ret->getPointer();
3922   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
3923     *dest=*std::max_element(src,src+nbOfComp);
3924   return ret.retn();
3925 }
3926
3927 /*!
3928  * Computes the maximal value within every tuple of \a this array and it returns the first component
3929  * id for each tuple that corresponds to the maximal value within the tuple.
3930  * 
3931  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
3932  *          same number of tuples and only one component.
3933  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3934  *          same number of tuples as \a this array and one component.
3935  *          The caller is to delete this result array using decrRef() as it is no more
3936  *          needed.
3937  *  \throw If \a this is not allocated.
3938  *  \sa DataArrayDouble::maxPerTuple
3939  */
3940 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
3941 {
3942   checkAllocated();
3943   int nbOfComp=getNumberOfComponents();
3944   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New();
3945   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
3946   int nbOfTuple=getNumberOfTuples();
3947   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
3948   const double *src=getConstPointer();
3949   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
3950   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
3951     {
3952       const double *loc=std::max_element(src,src+nbOfComp);
3953       *dest=*loc;
3954       *dest1=(int)std::distance(src,loc);
3955     }
3956   compoIdOfMaxPerTuple=ret1.retn();
3957   return ret0.retn();
3958 }
3959
3960 /*!
3961  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
3962  * \n This returned array contains the euclidian distance for each tuple in \a this. 
3963  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
3964  * \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)
3965  *
3966  * \warning use this method with care because it can leads to big amount of consumed memory !
3967  * 
3968  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
3969  *
3970  * \throw If \a this is not allocated.
3971  *
3972  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
3973  */
3974 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
3975 {
3976   checkAllocated();
3977   int nbOfComp=getNumberOfComponents();
3978   int nbOfTuples=getNumberOfTuples();
3979   const double *inData=getConstPointer();
3980   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
3981   ret->alloc(nbOfTuples*nbOfTuples,1);
3982   double *outData=ret->getPointer();
3983   for(int i=0;i<nbOfTuples;i++)
3984     {
3985       outData[i*nbOfTuples+i]=0.;
3986       for(int j=i+1;j<nbOfTuples;j++)
3987         {
3988           double dist=0.;
3989           for(int k=0;k<nbOfComp;k++)
3990             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
3991           dist=sqrt(dist);
3992           outData[i*nbOfTuples+j]=dist;
3993           outData[j*nbOfTuples+i]=dist;
3994         }
3995     }
3996   return ret.retn();
3997 }
3998
3999 /*!
4000  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
4001  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
4002  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
4003  * \n Output rectangular matrix is sorted along rows.
4004  * \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)
4005  *
4006  * \warning use this method with care because it can leads to big amount of consumed memory !
4007  * 
4008  * \param [in] other DataArrayDouble instance having same number of components than \a this.
4009  * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with.
4010  *
4011  * \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.
4012  *
4013  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
4014  */
4015 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
4016 {
4017   if(!other)
4018     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
4019   checkAllocated();
4020   other->checkAllocated();
4021   int nbOfComp=getNumberOfComponents();
4022   int otherNbOfComp=other->getNumberOfComponents();
4023   if(nbOfComp!=otherNbOfComp)
4024     {
4025       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
4026       throw INTERP_KERNEL::Exception(oss.str().c_str());
4027     }
4028   int nbOfTuples=getNumberOfTuples();
4029   int otherNbOfTuples=other->getNumberOfTuples();
4030   const double *inData=getConstPointer();
4031   const double *inDataOther=other->getConstPointer();
4032   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4033   ret->alloc(otherNbOfTuples*nbOfTuples,1);
4034   double *outData=ret->getPointer();
4035   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
4036     {
4037       for(int j=0;j<nbOfTuples;j++)
4038         {
4039           double dist=0.;
4040           for(int k=0;k<nbOfComp;k++)
4041             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
4042           dist=sqrt(dist);
4043           outData[i*nbOfTuples+j]=dist;
4044         }
4045     }
4046   return ret.retn();
4047 }
4048
4049 /*!
4050  * Sorts value within every tuple of \a this array.
4051  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
4052  *              in descending order.
4053  *  \throw If \a this is not allocated.
4054  */
4055 void DataArrayDouble::sortPerTuple(bool asc)
4056 {
4057   checkAllocated();
4058   double *pt=getPointer();
4059   int nbOfTuple=getNumberOfTuples();
4060   int nbOfComp=getNumberOfComponents();
4061   if(asc)
4062     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4063       std::sort(pt,pt+nbOfComp);
4064   else
4065     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
4066       std::sort(pt,pt+nbOfComp,std::greater<double>());
4067   declareAsNew();
4068 }
4069
4070 /*!
4071  * Converts every value of \a this array to its absolute value.
4072  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
4073  * should be called instead.
4074  *
4075  * \throw If \a this is not allocated.
4076  * \sa DataArrayDouble::computeAbs
4077  */
4078 void DataArrayDouble::abs()
4079 {
4080   checkAllocated();
4081   double *ptr(getPointer());
4082   std::size_t nbOfElems(getNbOfElems());
4083   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
4084   declareAsNew();
4085 }
4086
4087 /*!
4088  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
4089  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
4090  *
4091  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4092  *         same number of tuples and component as \a this array.
4093  *         The caller is to delete this result array using decrRef() as it is no more
4094  *         needed.
4095  * \throw If \a this is not allocated.
4096  * \sa DataArrayDouble::abs
4097  */
4098 DataArrayDouble *DataArrayDouble::computeAbs() const
4099 {
4100   checkAllocated();
4101   DataArrayDouble *newArr(DataArrayDouble::New());
4102   int nbOfTuples(getNumberOfTuples());
4103   int nbOfComp(getNumberOfComponents());
4104   newArr->alloc(nbOfTuples,nbOfComp);
4105   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
4106   newArr->copyStringInfoFrom(*this);
4107   return newArr;
4108 }
4109
4110 /*!
4111  * Apply a liner function to a given component of \a this array, so that
4112  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
4113  *  \param [in] a - the first coefficient of the function.
4114  *  \param [in] b - the second coefficient of the function.
4115  *  \param [in] compoId - the index of component to modify.
4116  *  \throw If \a this is not allocated.
4117  */
4118 void DataArrayDouble::applyLin(double a, double b, int compoId)
4119 {
4120   checkAllocated();
4121   double *ptr=getPointer()+compoId;
4122   int nbOfComp=getNumberOfComponents();
4123   int nbOfTuple=getNumberOfTuples();
4124   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
4125     *ptr=a*(*ptr)+b;
4126   declareAsNew();
4127 }
4128
4129 /*!
4130  * Apply a liner function to all elements of \a this array, so that
4131  * an element _x_ becomes \f$ a * x + b \f$.
4132  *  \param [in] a - the first coefficient of the function.
4133  *  \param [in] b - the second coefficient of the function.
4134  *  \throw If \a this is not allocated.
4135  */
4136 void DataArrayDouble::applyLin(double a, double b)
4137 {
4138   checkAllocated();
4139   double *ptr=getPointer();
4140   std::size_t nbOfElems=getNbOfElems();
4141   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4142     *ptr=a*(*ptr)+b;
4143   declareAsNew();
4144 }
4145
4146 /*!
4147  * Modify all elements of \a this array, so that
4148  * an element _x_ becomes \f$ numerator / x \f$.
4149  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
4150  *           array, all elements processed before detection of the zero element remain
4151  *           modified.
4152  *  \param [in] numerator - the numerator used to modify array elements.
4153  *  \throw If \a this is not allocated.
4154  *  \throw If there is an element equal to 0.0 in \a this array.
4155  */
4156 void DataArrayDouble::applyInv(double numerator)
4157 {
4158   checkAllocated();
4159   double *ptr=getPointer();
4160   std::size_t nbOfElems=getNbOfElems();
4161   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4162     {
4163       if(std::abs(*ptr)>std::numeric_limits<double>::min())
4164         {
4165           *ptr=numerator/(*ptr);
4166         }
4167       else
4168         {
4169           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
4170           oss << " !";
4171           throw INTERP_KERNEL::Exception(oss.str().c_str());
4172         }
4173     }
4174   declareAsNew();
4175 }
4176
4177 /*!
4178  * Returns a full copy of \a this array except that sign of all elements is reversed.
4179  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4180  *          same number of tuples and component as \a this array.
4181  *          The caller is to delete this result array using decrRef() as it is no more
4182  *          needed.
4183  *  \throw If \a this is not allocated.
4184  */
4185 DataArrayDouble *DataArrayDouble::negate() const
4186 {
4187   checkAllocated();
4188   DataArrayDouble *newArr=DataArrayDouble::New();
4189   int nbOfTuples=getNumberOfTuples();
4190   int nbOfComp=getNumberOfComponents();
4191   newArr->alloc(nbOfTuples,nbOfComp);
4192   const double *cptr=getConstPointer();
4193   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
4194   newArr->copyStringInfoFrom(*this);
4195   return newArr;
4196 }
4197
4198 /*!
4199  * Modify all elements of \a this array, so that
4200  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
4201  * all values in \a this have to be >= 0 if val is \b not integer.
4202  *  \param [in] val - the value used to apply pow on all array elements.
4203  *  \throw If \a this is not allocated.
4204  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4205  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
4206  *           modified.
4207  */
4208 void DataArrayDouble::applyPow(double val)
4209 {
4210   checkAllocated();
4211   double *ptr=getPointer();
4212   std::size_t nbOfElems=getNbOfElems();
4213   int val2=(int)val;
4214   bool isInt=((double)val2)==val;
4215   if(!isInt)
4216     {
4217       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4218         {
4219           if(*ptr>=0)
4220             *ptr=pow(*ptr,val);
4221           else
4222             {
4223               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
4224               throw INTERP_KERNEL::Exception(oss.str().c_str());
4225             }
4226         }
4227     }
4228   else
4229     {
4230       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4231         *ptr=pow(*ptr,val2);
4232     }
4233   declareAsNew();
4234 }
4235
4236 /*!
4237  * Modify all elements of \a this array, so that
4238  * an element _x_ becomes \f$ val ^ x \f$.
4239  *  \param [in] val - the value used to apply pow on all array elements.
4240  *  \throw If \a this is not allocated.
4241  *  \throw If \a val < 0.
4242  *  \warning If an exception is thrown because of presence of 0 element in \a this 
4243  *           array, all elements processed before detection of the zero element remain
4244  *           modified.
4245  */
4246 void DataArrayDouble::applyRPow(double val)
4247 {
4248   checkAllocated();
4249   if(val<0.)
4250     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
4251   double *ptr=getPointer();
4252   std::size_t nbOfElems=getNbOfElems();
4253   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
4254     *ptr=pow(val,*ptr);
4255   declareAsNew();
4256 }
4257
4258 /*!
4259  * Returns a new DataArrayDouble created from \a this one by applying \a
4260  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
4261  * For more info see \ref MEDCouplingArrayApplyFunc
4262  *  \param [in] nbOfComp - number of components in the result array.
4263  *  \param [in] func - the \a FunctionToEvaluate declared as 
4264  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
4265  *              where \a pos points to the first component of a tuple of \a this array
4266  *              and \a res points to the first component of a tuple of the result array.
4267  *              Note that length (number of components) of \a pos can differ from
4268  *              that of \a res.
4269  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4270  *          same number of tuples as \a this array.
4271  *          The caller is to delete this result array using decrRef() as it is no more
4272  *          needed.
4273  *  \throw If \a this is not allocated.
4274  *  \throw If \a func returns \a false.
4275  */
4276 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
4277 {
4278   checkAllocated();
4279   DataArrayDouble *newArr=DataArrayDouble::New();
4280   int nbOfTuples=getNumberOfTuples();
4281   int oldNbOfComp=getNumberOfComponents();
4282   newArr->alloc(nbOfTuples,nbOfComp);
4283   const double *ptr=getConstPointer();
4284   double *ptrToFill=newArr->getPointer();
4285   for(int i=0;i<nbOfTuples;i++)
4286     {
4287       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
4288         {
4289           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4290           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4291           oss << ") : Evaluation of function failed !";
4292           newArr->decrRef();
4293           throw INTERP_KERNEL::Exception(oss.str().c_str());
4294         }
4295     }
4296   return newArr;
4297 }
4298
4299 /*!
4300  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4301  * tuple of \a this array. Textual data is not copied.
4302  * For more info see \ref MEDCouplingArrayApplyFunc1.
4303  *  \param [in] nbOfComp - number of components in the result array.
4304  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4305  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4306  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4307  *          same number of tuples as \a this array and \a nbOfComp components.
4308  *          The caller is to delete this result array using decrRef() as it is no more
4309  *          needed.
4310  *  \throw If \a this is not allocated.
4311  *  \throw If computing \a func fails.
4312  */
4313 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func) const
4314 {
4315   checkAllocated();
4316   INTERP_KERNEL::ExprParser expr(func);
4317   expr.parse();
4318   std::set<std::string> vars;
4319   expr.getTrueSetOfVars(vars);
4320   int oldNbOfComp=getNumberOfComponents();
4321   if((int)vars.size()>oldNbOfComp)
4322     {
4323       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4324       oss << vars.size() << " variables : ";
4325       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4326       throw INTERP_KERNEL::Exception(oss.str().c_str());
4327     }
4328   std::vector<std::string> varsV(vars.begin(),vars.end());
4329   expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
4330   //
4331   DataArrayDouble *newArr=DataArrayDouble::New();
4332   int nbOfTuples=getNumberOfTuples();
4333   newArr->alloc(nbOfTuples,nbOfComp);
4334   const double *ptr=getConstPointer();
4335   double *ptrToFill=newArr->getPointer();
4336   for(int i=0;i<nbOfTuples;i++)
4337     {
4338       try
4339       {
4340           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4341       }
4342       catch(INTERP_KERNEL::Exception& e)
4343       {
4344           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4345           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4346           oss << ") : Evaluation of function failed !" << e.what();
4347           newArr->decrRef();
4348           throw INTERP_KERNEL::Exception(oss.str().c_str());
4349       }
4350     }
4351   return newArr;
4352 }
4353
4354 /*!
4355  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4356  * tuple of \a this array. Textual data is not copied.
4357  * For more info see \ref MEDCouplingArrayApplyFunc0.
4358  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4359  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4360  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4361  *          same number of tuples and components as \a this array.
4362  *          The caller is to delete this result array using decrRef() as it is no more
4363  *          needed.
4364  *  \throw If \a this is not allocated.
4365  *  \throw If computing \a func fails.
4366  */
4367 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func) const
4368 {
4369   checkAllocated();
4370   INTERP_KERNEL::ExprParser expr(func);
4371   expr.parse();
4372   expr.prepareExprEvaluationVec();
4373   //
4374   DataArrayDouble *newArr=DataArrayDouble::New();
4375   int nbOfTuples=getNumberOfTuples();
4376   int nbOfComp=getNumberOfComponents();
4377   newArr->alloc(nbOfTuples,nbOfComp);
4378   const double *ptr=getConstPointer();
4379   double *ptrToFill=newArr->getPointer();
4380   for(int i=0;i<nbOfTuples;i++)
4381     {
4382       try
4383       {
4384           expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
4385       }
4386       catch(INTERP_KERNEL::Exception& e)
4387       {
4388           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4389           std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4390           oss << ") : Evaluation of function failed ! " << e.what();
4391           newArr->decrRef();
4392           throw INTERP_KERNEL::Exception(oss.str().c_str());
4393       }
4394     }
4395   return newArr;
4396 }
4397
4398 /*!
4399  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4400  * tuple of \a this array. Textual data is not copied.
4401  * For more info see \ref MEDCouplingArrayApplyFunc2.
4402  *  \param [in] nbOfComp - number of components in the result array.
4403  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4404  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4405  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4406  *          same number of tuples as \a this array.
4407  *          The caller is to delete this result array using decrRef() as it is no more
4408  *          needed.
4409  *  \throw If \a this is not allocated.
4410  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
4411  *  \throw If computing \a func fails.
4412  */
4413 DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const std::string& func) const
4414 {
4415   checkAllocated();
4416   INTERP_KERNEL::ExprParser expr(func);
4417   expr.parse();
4418   std::set<std::string> vars;
4419   expr.getTrueSetOfVars(vars);
4420   int oldNbOfComp=getNumberOfComponents();
4421   if((int)vars.size()>oldNbOfComp)
4422     {
4423       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4424       oss << vars.size() << " variables : ";
4425       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4426       throw INTERP_KERNEL::Exception(oss.str().c_str());
4427     }
4428   expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
4429   //
4430   DataArrayDouble *newArr=DataArrayDouble::New();
4431   int nbOfTuples=getNumberOfTuples();
4432   newArr->alloc(nbOfTuples,nbOfComp);
4433   const double *ptr=getConstPointer();
4434   double *ptrToFill=newArr->getPointer();
4435   for(int i=0;i<nbOfTuples;i++)
4436     {
4437       try
4438       {
4439           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4440       }
4441       catch(INTERP_KERNEL::Exception& e)
4442       {
4443           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4444           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4445           oss << ") : Evaluation of function failed !" << e.what();
4446           newArr->decrRef();
4447           throw INTERP_KERNEL::Exception(oss.str().c_str());
4448       }
4449     }
4450   return newArr;
4451 }
4452
4453 /*!
4454  * Returns a new DataArrayDouble created from \a this one by applying a function to every
4455  * tuple of \a this array. Textual data is not copied.
4456  * For more info see \ref MEDCouplingArrayApplyFunc3.
4457  *  \param [in] nbOfComp - number of components in the result array.
4458  *  \param [in] varsOrder - sequence of vars defining their order.
4459  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
4460  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
4461  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
4462  *          same number of tuples as \a this array.
4463  *          The caller is to delete this result array using decrRef() as it is no more
4464  *          needed.
4465  *  \throw If \a this is not allocated.
4466  *  \throw If \a func contains vars not in \a varsOrder.
4467  *  \throw If computing \a func fails.
4468  */
4469 DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func) const
4470 {
4471   checkAllocated();
4472   INTERP_KERNEL::ExprParser expr(func);
4473   expr.parse();
4474   std::set<std::string> vars;
4475   expr.getTrueSetOfVars(vars);
4476   int oldNbOfComp=getNumberOfComponents();
4477   if((int)vars.size()>oldNbOfComp)
4478     {
4479       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
4480       oss << vars.size() << " variables : ";
4481       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
4482       throw INTERP_KERNEL::Exception(oss.str().c_str());
4483     }
4484   expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
4485   //
4486   DataArrayDouble *newArr=DataArrayDouble::New();
4487   int nbOfTuples=getNumberOfTuples();
4488   newArr->alloc(nbOfTuples,nbOfComp);
4489   const double *ptr=getConstPointer();
4490   double *ptrToFill=newArr->getPointer();
4491   for(int i=0;i<nbOfTuples;i++)
4492     {
4493       try
4494       {
4495           expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
4496       }
4497       catch(INTERP_KERNEL::Exception& e)
4498       {
4499           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
4500           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
4501           oss << ") : Evaluation of function failed !" << e.what();
4502           newArr->decrRef();
4503           throw INTERP_KERNEL::Exception(oss.str().c_str());
4504       }
4505     }
4506   return newArr;
4507 }
4508
4509 void DataArrayDouble::applyFuncFast32(const std::string& func)
4510 {
4511   checkAllocated();
4512   INTERP_KERNEL::ExprParser expr(func);
4513   expr.parse();
4514   char *funcStr=expr.compileX86();
4515   MYFUNCPTR funcPtr;
4516   *((void **)&funcPtr)=funcStr;//he he...
4517   //
4518   double *ptr=getPointer();
4519   int nbOfComp=getNumberOfComponents();
4520   int nbOfTuples=getNumberOfTuples();
4521   int nbOfElems=nbOfTuples*nbOfComp;
4522   for(int i=0;i<nbOfElems;i++,ptr++)
4523     *ptr=funcPtr(*ptr);
4524   declareAsNew();
4525 }
4526
4527 void DataArrayDouble::applyFuncFast64(const std::string& func)
4528 {
4529   checkAllocated();
4530   INTERP_KERNEL::ExprParser expr(func);
4531   expr.parse();
4532   char *funcStr=expr.compileX86_64();
4533   MYFUNCPTR funcPtr;
4534   *((void **)&funcPtr)=funcStr;//he he...
4535   //
4536   double *ptr=getPointer();
4537   int nbOfComp=getNumberOfComponents();
4538   int nbOfTuples=getNumberOfTuples();
4539   int nbOfElems=nbOfTuples*nbOfComp;
4540   for(int i=0;i<nbOfElems;i++,ptr++)
4541     *ptr=funcPtr(*ptr);
4542   declareAsNew();
4543 }
4544
4545 DataArrayDoubleIterator *DataArrayDouble::iterator()
4546 {
4547   return new DataArrayDoubleIterator(this);
4548 }
4549
4550 /*!
4551  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4552  * array whose values are within a given range. Textual data is not copied.
4553  *  \param [in] vmin - a lowest acceptable value (included).
4554  *  \param [in] vmax - a greatest acceptable value (included).
4555  *  \return DataArrayInt * - the new instance of DataArrayInt.
4556  *          The caller is to delete this result array using decrRef() as it is no more
4557  *          needed.
4558  *  \throw If \a this->getNumberOfComponents() != 1.
4559  *
4560  *  \sa DataArrayDouble::getIdsNotInRange
4561  *
4562  *  \if ENABLE_EXAMPLES
4563  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
4564  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
4565  *  \endif
4566  */
4567 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const
4568 {
4569   checkAllocated();
4570   if(getNumberOfComponents()!=1)
4571     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
4572   const double *cptr(begin());
4573   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4574   int nbOfTuples(getNumberOfTuples());
4575   for(int i=0;i<nbOfTuples;i++,cptr++)
4576     if(*cptr>=vmin && *cptr<=vmax)
4577       ret->pushBackSilent(i);
4578   return ret.retn();
4579 }
4580
4581 /*!
4582  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
4583  * array whose values are not within a given range. Textual data is not copied.
4584  *  \param [in] vmin - a lowest not acceptable value (excluded).
4585  *  \param [in] vmax - a greatest not acceptable value (excluded).
4586  *  \return DataArrayInt * - the new instance of DataArrayInt.
4587  *          The caller is to delete this result array using decrRef() as it is no more
4588  *          needed.
4589  *  \throw If \a this->getNumberOfComponents() != 1.
4590  *
4591  *  \sa DataArrayDouble::getIdsInRange
4592  */
4593 DataArrayInt *DataArrayDouble::getIdsNotInRange(double vmin, double vmax) const
4594 {
4595   checkAllocated();
4596   if(getNumberOfComponents()!=1)
4597     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsNotInRange : this must have exactly one component !");
4598   const double *cptr(begin());
4599   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4600   int nbOfTuples(getNumberOfTuples());
4601   for(int i=0;i<nbOfTuples;i++,cptr++)
4602     if(*cptr<vmin || *cptr>vmax)
4603       ret->pushBackSilent(i);
4604   return ret.retn();
4605 }
4606
4607 /*!
4608  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
4609  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4610  * the number of component in the result array is same as that of each of given arrays.
4611  * Info on components is copied from the first of the given arrays. Number of components
4612  * in the given arrays must be  the same.
4613  *  \param [in] a1 - an array to include in the result array.
4614  *  \param [in] a2 - another array to include in the result array.
4615  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4616  *          The caller is to delete this result array using decrRef() as it is no more
4617  *          needed.
4618  *  \throw If both \a a1 and \a a2 are NULL.
4619  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4620  */
4621 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
4622 {
4623   std::vector<const DataArrayDouble *> tmp(2);
4624   tmp[0]=a1; tmp[1]=a2;
4625   return Aggregate(tmp);
4626 }
4627
4628 /*!
4629  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
4630  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4631  * the number of component in the result array is same as that of each of given arrays.
4632  * Info on components is copied from the first of the given arrays. Number of components
4633  * in the given arrays must be  the same.
4634  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
4635  * not the object itself.
4636  *  \param [in] arr - a sequence of arrays to include in the result array.
4637  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4638  *          The caller is to delete this result array using decrRef() as it is no more
4639  *          needed.
4640  *  \throw If all arrays within \a arr are NULL.
4641  *  \throw If getNumberOfComponents() of arrays within \a arr.
4642  */
4643 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
4644 {
4645   std::vector<const DataArrayDouble *> a;
4646   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4647     if(*it4)
4648       a.push_back(*it4);
4649   if(a.empty())
4650     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
4651   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
4652   int nbOfComp=(*it)->getNumberOfComponents();
4653   int nbt=(*it++)->getNumberOfTuples();
4654   for(int i=1;it!=a.end();it++,i++)
4655     {
4656       if((*it)->getNumberOfComponents()!=nbOfComp)
4657         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
4658       nbt+=(*it)->getNumberOfTuples();
4659     }
4660   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
4661   ret->alloc(nbt,nbOfComp);
4662   double *pt=ret->getPointer();
4663   for(it=a.begin();it!=a.end();it++)
4664     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4665   ret->copyStringInfoFrom(*(a[0]));
4666   return ret.retn();
4667 }
4668
4669 /*!
4670  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
4671  * of components in the result array is a sum of the number of components of given arrays
4672  * and (2) the number of tuples in the result array is same as that of each of given
4673  * arrays. In other words the i-th tuple of result array includes all components of
4674  * i-th tuples of all given arrays.
4675  * Number of tuples in the given arrays must be  the same.
4676  *  \param [in] a1 - an array to include in the result array.
4677  *  \param [in] a2 - another array to include in the result array.
4678  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4679  *          The caller is to delete this result array using decrRef() as it is no more
4680  *          needed.
4681  *  \throw If both \a a1 and \a a2 are NULL.
4682  *  \throw If any given array is not allocated.
4683  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4684  */
4685 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
4686 {
4687   std::vector<const DataArrayDouble *> arr(2);
4688   arr[0]=a1; arr[1]=a2;
4689   return Meld(arr);
4690 }
4691
4692 /*!
4693  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
4694  * of components in the result array is a sum of the number of components of given arrays
4695  * and (2) the number of tuples in the result array is same as that of each of given
4696  * arrays. In other words the i-th tuple of result array includes all components of
4697  * i-th tuples of all given arrays.
4698  * Number of tuples in the given arrays must be  the same.
4699  *  \param [in] arr - a sequence of arrays to include in the result array.
4700  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4701  *          The caller is to delete this result array using decrRef() as it is no more
4702  *          needed.
4703  *  \throw If all arrays within \a arr are NULL.
4704  *  \throw If any given array is not allocated.
4705  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
4706  */
4707 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
4708 {
4709   std::vector<const DataArrayDouble *> a;
4710   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4711     if(*it4)
4712       a.push_back(*it4);
4713   if(a.empty())
4714     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
4715   std::vector<const DataArrayDouble *>::const_iterator it;
4716   for(it=a.begin();it!=a.end();it++)
4717     (*it)->checkAllocated();
4718   it=a.begin();
4719   int nbOfTuples=(*it)->getNumberOfTuples();
4720   std::vector<int> nbc(a.size());
4721   std::vector<const double *> pts(a.size());
4722   nbc[0]=(*it)->getNumberOfComponents();
4723   pts[0]=(*it++)->getConstPointer();
4724   for(int i=1;it!=a.end();it++,i++)
4725     {
4726       if(nbOfTuples!=(*it)->getNumberOfTuples())
4727         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
4728       nbc[i]=(*it)->getNumberOfComponents();
4729       pts[i]=(*it)->getConstPointer();
4730     }
4731   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
4732   DataArrayDouble *ret=DataArrayDouble::New();
4733   ret->alloc(nbOfTuples,totalNbOfComp);
4734   double *retPtr=ret->getPointer();
4735   for(int i=0;i<nbOfTuples;i++)
4736     for(int j=0;j<(int)a.size();j++)
4737       {
4738         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
4739         pts[j]+=nbc[j];
4740       }
4741   int k=0;
4742   for(int i=0;i<(int)a.size();i++)
4743     for(int j=0;j<nbc[i];j++,k++)
4744       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
4745   return ret;
4746 }
4747
4748 /*!
4749  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
4750  * the i-th tuple of the result array is a sum of products of j-th components of i-th
4751  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
4752  * Info on components and name is copied from the first of the given arrays.
4753  * Number of tuples and components in the given arrays must be the same.
4754  *  \param [in] a1 - a given array.
4755  *  \param [in] a2 - another given array.
4756  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4757  *          The caller is to delete this result array using decrRef() as it is no more
4758  *          needed.
4759  *  \throw If either \a a1 or \a a2 is NULL.
4760  *  \throw If any given array is not allocated.
4761  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4762  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4763  */
4764 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
4765 {
4766   if(!a1 || !a2)
4767     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
4768   a1->checkAllocated();
4769   a2->checkAllocated();
4770   int nbOfComp=a1->getNumberOfComponents();
4771   if(nbOfComp!=a2->getNumberOfComponents())
4772     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
4773   int nbOfTuple=a1->getNumberOfTuples();
4774   if(nbOfTuple!=a2->getNumberOfTuples())
4775     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
4776   DataArrayDouble *ret=DataArrayDouble::New();
4777   ret->alloc(nbOfTuple,1);
4778   double *retPtr=ret->getPointer();
4779   const double *a1Ptr=a1->getConstPointer();
4780   const double *a2Ptr=a2->getConstPointer();
4781   for(int i=0;i<nbOfTuple;i++)
4782     {
4783       double sum=0.;
4784       for(int j=0;j<nbOfComp;j++)
4785         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
4786       retPtr[i]=sum;
4787     }
4788   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
4789   ret->setName(a1->getName());
4790   return ret;
4791 }
4792
4793 /*!
4794  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
4795  * the i-th tuple of the result array contains 3 components of a vector which is a cross
4796  * product of two vectors defined by the i-th tuples of given arrays.
4797  * Info on components is copied from the first of the given arrays.
4798  * Number of tuples in the given arrays must be the same.
4799  * Number of components in the given arrays must be 3.
4800  *  \param [in] a1 - a given array.
4801  *  \param [in] a2 - another given array.
4802  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4803  *          The caller is to delete this result array using decrRef() as it is no more
4804  *          needed.
4805  *  \throw If either \a a1 or \a a2 is NULL.
4806  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4807  *  \throw If \a a1->getNumberOfComponents() != 3
4808  *  \throw If \a a2->getNumberOfComponents() != 3
4809  */
4810 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
4811 {
4812   if(!a1 || !a2)
4813     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
4814   int nbOfComp=a1->getNumberOfComponents();
4815   if(nbOfComp!=a2->getNumberOfComponents())
4816     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
4817   if(nbOfComp!=3)
4818     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
4819   int nbOfTuple=a1->getNumberOfTuples();
4820   if(nbOfTuple!=a2->getNumberOfTuples())
4821     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
4822   DataArrayDouble *ret=DataArrayDouble::New();
4823   ret->alloc(nbOfTuple,3);
4824   double *retPtr=ret->getPointer();
4825   const double *a1Ptr=a1->getConstPointer();
4826   const double *a2Ptr=a2->getConstPointer();
4827   for(int i=0;i<nbOfTuple;i++)
4828     {
4829       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
4830       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
4831       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
4832     }
4833   ret->copyStringInfoFrom(*a1);
4834   return ret;
4835 }
4836
4837 /*!
4838  * Returns a new DataArrayDouble containing maximal values of two given arrays.
4839  * Info on components is copied from the first of the given arrays.
4840  * Number of tuples and components in the given arrays must be the same.
4841  *  \param [in] a1 - an array to compare values with another one.
4842  *  \param [in] a2 - another array to compare values with the first one.
4843  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4844  *          The caller is to delete this result array using decrRef() as it is no more
4845  *          needed.
4846  *  \throw If either \a a1 or \a a2 is NULL.
4847  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4848  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4849  */
4850 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
4851 {
4852   if(!a1 || !a2)
4853     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
4854   int nbOfComp=a1->getNumberOfComponents();
4855   if(nbOfComp!=a2->getNumberOfComponents())
4856     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
4857   int nbOfTuple=a1->getNumberOfTuples();
4858   if(nbOfTuple!=a2->getNumberOfTuples())
4859     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
4860   DataArrayDouble *ret=DataArrayDouble::New();
4861   ret->alloc(nbOfTuple,nbOfComp);
4862   double *retPtr=ret->getPointer();
4863   const double *a1Ptr=a1->getConstPointer();
4864   const double *a2Ptr=a2->getConstPointer();
4865   int nbElem=nbOfTuple*nbOfComp;
4866   for(int i=0;i<nbElem;i++)
4867     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
4868   ret->copyStringInfoFrom(*a1);
4869   return ret;
4870 }
4871
4872 /*!
4873  * Returns a new DataArrayDouble containing minimal values of two given arrays.
4874  * Info on components is copied from the first of the given arrays.
4875  * Number of tuples and components in the given arrays must be the same.
4876  *  \param [in] a1 - an array to compare values with another one.
4877  *  \param [in] a2 - another array to compare values with the first one.
4878  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4879  *          The caller is to delete this result array using decrRef() as it is no more
4880  *          needed.
4881  *  \throw If either \a a1 or \a a2 is NULL.
4882  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4883  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
4884  */
4885 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
4886 {
4887   if(!a1 || !a2)
4888     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
4889   int nbOfComp=a1->getNumberOfComponents();
4890   if(nbOfComp!=a2->getNumberOfComponents())
4891     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
4892   int nbOfTuple=a1->getNumberOfTuples();
4893   if(nbOfTuple!=a2->getNumberOfTuples())
4894     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
4895   DataArrayDouble *ret=DataArrayDouble::New();
4896   ret->alloc(nbOfTuple,nbOfComp);
4897   double *retPtr=ret->getPointer();
4898   const double *a1Ptr=a1->getConstPointer();
4899   const double *a2Ptr=a2->getConstPointer();
4900   int nbElem=nbOfTuple*nbOfComp;
4901   for(int i=0;i<nbElem;i++)
4902     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
4903   ret->copyStringInfoFrom(*a1);
4904   return ret;
4905 }
4906
4907 /*!
4908  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
4909  * valid cases.
4910  * 1.  The arrays have same number of tuples and components. Then each value of
4911  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
4912  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
4913  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4914  *   component. Then
4915  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
4916  * 3.  The arrays have same number of components and one array, say _a2_, has one
4917  *   tuple. Then
4918  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
4919  *
4920  * Info on components is copied either from the first array (in the first case) or from
4921  * the array with maximal number of elements (getNbOfElems()).
4922  *  \param [in] a1 - an array to sum up.
4923  *  \param [in] a2 - another array to sum up.
4924  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4925  *          The caller is to delete this result array using decrRef() as it is no more
4926  *          needed.
4927  *  \throw If either \a a1 or \a a2 is NULL.
4928  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4929  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4930  *         none of them has number of tuples or components equal to 1.
4931  */
4932 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
4933 {
4934   if(!a1 || !a2)
4935     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
4936   int nbOfTuple=a1->getNumberOfTuples();
4937   int nbOfTuple2=a2->getNumberOfTuples();
4938   int nbOfComp=a1->getNumberOfComponents();
4939   int nbOfComp2=a2->getNumberOfComponents();
4940   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
4941   if(nbOfTuple==nbOfTuple2)
4942     {
4943       if(nbOfComp==nbOfComp2)
4944         {
4945           ret=DataArrayDouble::New();
4946           ret->alloc(nbOfTuple,nbOfComp);
4947           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
4948           ret->copyStringInfoFrom(*a1);
4949         }
4950       else
4951         {
4952           int nbOfCompMin,nbOfCompMax;
4953           const DataArrayDouble *aMin, *aMax;
4954           if(nbOfComp>nbOfComp2)
4955             {
4956               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4957               aMin=a2; aMax=a1;
4958             }
4959           else
4960             {
4961               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4962               aMin=a1; aMax=a2;
4963             }
4964           if(nbOfCompMin==1)
4965             {
4966               ret=DataArrayDouble::New();
4967               ret->alloc(nbOfTuple,nbOfCompMax);
4968               const double *aMinPtr=aMin->getConstPointer();
4969               const double *aMaxPtr=aMax->getConstPointer();
4970               double *res=ret->getPointer();
4971               for(int i=0;i<nbOfTuple;i++)
4972                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
4973               ret->copyStringInfoFrom(*aMax);
4974             }
4975           else
4976             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4977         }
4978     }
4979   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4980     {
4981       if(nbOfComp==nbOfComp2)
4982         {
4983           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4984           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4985           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4986           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4987           ret=DataArrayDouble::New();
4988           ret->alloc(nbOfTupleMax,nbOfComp);
4989           double *res=ret->getPointer();
4990           for(int i=0;i<nbOfTupleMax;i++)
4991             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
4992           ret->copyStringInfoFrom(*aMax);
4993         }
4994       else
4995         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
4996     }
4997   else
4998     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
4999   return ret.retn();
5000 }
5001
5002 /*!
5003  * Adds values of another DataArrayDouble to values of \a this one. There are 3
5004  * valid cases.
5005  * 1.  The arrays have same number of tuples and components. Then each value of
5006  *   \a other array is added to the corresponding value of \a this array, i.e.:
5007  *   _a_ [ i, j ] += _other_ [ i, j ].
5008  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5009  *   _a_ [ i, j ] += _other_ [ i, 0 ].
5010  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5011  *   _a_ [ i, j ] += _a2_ [ 0, j ].
5012  *
5013  *  \param [in] other - an array to add to \a this one.
5014  *  \throw If \a other is NULL.
5015  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5016  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5017  *         \a other has number of both tuples and components not equal to 1.
5018  */
5019 void DataArrayDouble::addEqual(const DataArrayDouble *other)
5020 {
5021   if(!other)
5022     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
5023   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
5024   checkAllocated();
5025   other->checkAllocated();
5026   int nbOfTuple=getNumberOfTuples();
5027   int nbOfTuple2=other->getNumberOfTuples();
5028   int nbOfComp=getNumberOfComponents();
5029   int nbOfComp2=other->getNumberOfComponents();
5030   if(nbOfTuple==nbOfTuple2)
5031     {
5032       if(nbOfComp==nbOfComp2)
5033         {
5034           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
5035         }
5036       else if(nbOfComp2==1)
5037         {
5038           double *ptr=getPointer();
5039           const double *ptrc=other->getConstPointer();
5040           for(int i=0;i<nbOfTuple;i++)
5041             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
5042         }
5043       else
5044         throw INTERP_KERNEL::Exception(msg);
5045     }
5046   else if(nbOfTuple2==1)
5047     {
5048       if(nbOfComp2==nbOfComp)
5049         {
5050           double *ptr=getPointer();
5051           const double *ptrc=other->getConstPointer();
5052           for(int i=0;i<nbOfTuple;i++)
5053             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
5054         }
5055       else
5056         throw INTERP_KERNEL::Exception(msg);
5057     }
5058   else
5059     throw INTERP_KERNEL::Exception(msg);
5060   declareAsNew();
5061 }
5062
5063 /*!
5064  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
5065  * valid cases.
5066  * 1.  The arrays have same number of tuples and components. Then each value of
5067  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
5068  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
5069  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5070  *   component. Then
5071  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
5072  * 3.  The arrays have same number of components and one array, say _a2_, has one
5073  *   tuple. Then
5074  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
5075  *
5076  * Info on components is copied either from the first array (in the first case) or from
5077  * the array with maximal number of elements (getNbOfElems()).
5078  *  \param [in] a1 - an array to subtract from.
5079  *  \param [in] a2 - an array to subtract.
5080  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5081  *          The caller is to delete this result array using decrRef() as it is no more
5082  *          needed.
5083  *  \throw If either \a a1 or \a a2 is NULL.
5084  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5085  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5086  *         none of them has number of tuples or components equal to 1.
5087  */
5088 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
5089 {
5090   if(!a1 || !a2)
5091     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
5092   int nbOfTuple1=a1->getNumberOfTuples();
5093   int nbOfTuple2=a2->getNumberOfTuples();
5094   int nbOfComp1=a1->getNumberOfComponents();
5095   int nbOfComp2=a2->getNumberOfComponents();
5096   if(nbOfTuple2==nbOfTuple1)
5097     {
5098       if(nbOfComp1==nbOfComp2)
5099         {
5100           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5101           ret->alloc(nbOfTuple2,nbOfComp1);
5102           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
5103           ret->copyStringInfoFrom(*a1);
5104           return ret.retn();
5105         }
5106       else if(nbOfComp2==1)
5107         {
5108           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5109           ret->alloc(nbOfTuple1,nbOfComp1);
5110           const double *a2Ptr=a2->getConstPointer();
5111           const double *a1Ptr=a1->getConstPointer();
5112           double *res=ret->getPointer();
5113           for(int i=0;i<nbOfTuple1;i++)
5114             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
5115           ret->copyStringInfoFrom(*a1);
5116           return ret.retn();
5117         }
5118       else
5119         {
5120           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5121           return 0;
5122         }
5123     }
5124   else if(nbOfTuple2==1)
5125     {
5126       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
5127       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5128       ret->alloc(nbOfTuple1,nbOfComp1);
5129       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5130       double *pt=ret->getPointer();
5131       for(int i=0;i<nbOfTuple1;i++)
5132         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
5133       ret->copyStringInfoFrom(*a1);
5134       return ret.retn();
5135     }
5136   else
5137     {
5138       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
5139       return 0;
5140     }
5141 }
5142
5143 /*!
5144  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
5145  * valid cases.
5146  * 1.  The arrays have same number of tuples and components. Then each value of
5147  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
5148  *   _a_ [ i, j ] -= _other_ [ i, j ].
5149  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5150  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
5151  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5152  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
5153  *
5154  *  \param [in] other - an array to subtract from \a this one.
5155  *  \throw If \a other is NULL.
5156  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5157  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5158  *         \a other has number of both tuples and components not equal to 1.
5159  */
5160 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
5161 {
5162   if(!other)
5163     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
5164   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
5165   checkAllocated();
5166   other->checkAllocated();
5167   int nbOfTuple=getNumberOfTuples();
5168   int nbOfTuple2=other->getNumberOfTuples();
5169   int nbOfComp=getNumberOfComponents();
5170   int nbOfComp2=other->getNumberOfComponents();
5171   if(nbOfTuple==nbOfTuple2)
5172     {
5173       if(nbOfComp==nbOfComp2)
5174         {
5175           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
5176         }
5177       else if(nbOfComp2==1)
5178         {
5179           double *ptr=getPointer();
5180           const double *ptrc=other->getConstPointer();
5181           for(int i=0;i<nbOfTuple;i++)
5182             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
5183         }
5184       else
5185         throw INTERP_KERNEL::Exception(msg);
5186     }
5187   else if(nbOfTuple2==1)
5188     {
5189       if(nbOfComp2==nbOfComp)
5190         {
5191           double *ptr=getPointer();
5192           const double *ptrc=other->getConstPointer();
5193           for(int i=0;i<nbOfTuple;i++)
5194             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
5195         }
5196       else
5197         throw INTERP_KERNEL::Exception(msg);
5198     }
5199   else
5200     throw INTERP_KERNEL::Exception(msg);
5201   declareAsNew();
5202 }
5203
5204 /*!
5205  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
5206  * valid cases.
5207  * 1.  The arrays have same number of tuples and components. Then each value of
5208  *   the result array (_a_) is a product of the corresponding values of \a a1 and
5209  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
5210  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5211  *   component. Then
5212  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
5213  * 3.  The arrays have same number of components and one array, say _a2_, has one
5214  *   tuple. Then
5215  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
5216  *
5217  * Info on components is copied either from the first array (in the first case) or from
5218  * the array with maximal number of elements (getNbOfElems()).
5219  *  \param [in] a1 - a factor array.
5220  *  \param [in] a2 - another factor array.
5221  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5222  *          The caller is to delete this result array using decrRef() as it is no more
5223  *          needed.
5224  *  \throw If either \a a1 or \a a2 is NULL.
5225  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5226  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5227  *         none of them has number of tuples or components equal to 1.
5228  */
5229 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
5230 {
5231   if(!a1 || !a2)
5232     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
5233   int nbOfTuple=a1->getNumberOfTuples();
5234   int nbOfTuple2=a2->getNumberOfTuples();
5235   int nbOfComp=a1->getNumberOfComponents();
5236   int nbOfComp2=a2->getNumberOfComponents();
5237   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0;
5238   if(nbOfTuple==nbOfTuple2)
5239     {
5240       if(nbOfComp==nbOfComp2)
5241         {
5242           ret=DataArrayDouble::New();
5243           ret->alloc(nbOfTuple,nbOfComp);
5244           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
5245           ret->copyStringInfoFrom(*a1);
5246         }
5247       else
5248         {
5249           int nbOfCompMin,nbOfCompMax;
5250           const DataArrayDouble *aMin, *aMax;
5251           if(nbOfComp>nbOfComp2)
5252             {
5253               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
5254               aMin=a2; aMax=a1;
5255             }
5256           else
5257             {
5258               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
5259               aMin=a1; aMax=a2;
5260             }
5261           if(nbOfCompMin==1)
5262             {
5263               ret=DataArrayDouble::New();
5264               ret->alloc(nbOfTuple,nbOfCompMax);
5265               const double *aMinPtr=aMin->getConstPointer();
5266               const double *aMaxPtr=aMax->getConstPointer();
5267               double *res=ret->getPointer();
5268               for(int i=0;i<nbOfTuple;i++)
5269                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
5270               ret->copyStringInfoFrom(*aMax);
5271             }
5272           else
5273             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5274         }
5275     }
5276   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
5277     {
5278       if(nbOfComp==nbOfComp2)
5279         {
5280           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
5281           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
5282           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
5283           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
5284           ret=DataArrayDouble::New();
5285           ret->alloc(nbOfTupleMax,nbOfComp);
5286           double *res=ret->getPointer();
5287           for(int i=0;i<nbOfTupleMax;i++)
5288             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
5289           ret->copyStringInfoFrom(*aMax);
5290         }
5291       else
5292         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
5293     }
5294   else
5295     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
5296   return ret.retn();
5297 }
5298
5299 /*!
5300  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
5301  * valid cases.
5302  * 1.  The arrays have same number of tuples and components. Then each value of
5303  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
5304  *   _this_ [ i, j ] *= _other_ [ i, j ].
5305  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5306  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
5307  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5308  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
5309  *
5310  *  \param [in] other - an array to multiply to \a this one.
5311  *  \throw If \a other is NULL.
5312  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5313  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5314  *         \a other has number of both tuples and components not equal to 1.
5315  */
5316 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
5317 {
5318   if(!other)
5319     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
5320   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
5321   checkAllocated();
5322   other->checkAllocated();
5323   int nbOfTuple=getNumberOfTuples();
5324   int nbOfTuple2=other->getNumberOfTuples();
5325   int nbOfComp=getNumberOfComponents();
5326   int nbOfComp2=other->getNumberOfComponents();
5327   if(nbOfTuple==nbOfTuple2)
5328     {
5329       if(nbOfComp==nbOfComp2)
5330         {
5331           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
5332         }
5333       else if(nbOfComp2==1)
5334         {
5335           double *ptr=getPointer();
5336           const double *ptrc=other->getConstPointer();
5337           for(int i=0;i<nbOfTuple;i++)
5338             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
5339         }
5340       else
5341         throw INTERP_KERNEL::Exception(msg);
5342     }
5343   else if(nbOfTuple2==1)
5344     {
5345       if(nbOfComp2==nbOfComp)
5346         {
5347           double *ptr=getPointer();
5348           const double *ptrc=other->getConstPointer();
5349           for(int i=0;i<nbOfTuple;i++)
5350             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
5351         }
5352       else
5353         throw INTERP_KERNEL::Exception(msg);
5354     }
5355   else
5356     throw INTERP_KERNEL::Exception(msg);
5357   declareAsNew();
5358 }
5359
5360 /*!
5361  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
5362  * valid cases.
5363  * 1.  The arrays have same number of tuples and components. Then each value of
5364  *   the result array (_a_) is a division of the corresponding values of \a a1 and
5365  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
5366  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
5367  *   component. Then
5368  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
5369  * 3.  The arrays have same number of components and one array, say _a2_, has one
5370  *   tuple. Then
5371  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
5372  *
5373  * Info on components is copied either from the first array (in the first case) or from
5374  * the array with maximal number of elements (getNbOfElems()).
5375  *  \warning No check of division by zero is performed!
5376  *  \param [in] a1 - a numerator array.
5377  *  \param [in] a2 - a denominator array.
5378  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5379  *          The caller is to delete this result array using decrRef() as it is no more
5380  *          needed.
5381  *  \throw If either \a a1 or \a a2 is NULL.
5382  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
5383  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
5384  *         none of them has number of tuples or components equal to 1.
5385  */
5386 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
5387 {
5388   if(!a1 || !a2)
5389     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
5390   int nbOfTuple1=a1->getNumberOfTuples();
5391   int nbOfTuple2=a2->getNumberOfTuples();
5392   int nbOfComp1=a1->getNumberOfComponents();
5393   int nbOfComp2=a2->getNumberOfComponents();
5394   if(nbOfTuple2==nbOfTuple1)
5395     {
5396       if(nbOfComp1==nbOfComp2)
5397         {
5398           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5399           ret->alloc(nbOfTuple2,nbOfComp1);
5400           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
5401           ret->copyStringInfoFrom(*a1);
5402           return ret.retn();
5403         }
5404       else if(nbOfComp2==1)
5405         {
5406           MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5407           ret->alloc(nbOfTuple1,nbOfComp1);
5408           const double *a2Ptr=a2->getConstPointer();
5409           const double *a1Ptr=a1->getConstPointer();
5410           double *res=ret->getPointer();
5411           for(int i=0;i<nbOfTuple1;i++)
5412             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
5413           ret->copyStringInfoFrom(*a1);
5414           return ret.retn();
5415         }
5416       else
5417         {
5418           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5419           return 0;
5420         }
5421     }
5422   else if(nbOfTuple2==1)
5423     {
5424       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
5425       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
5426       ret->alloc(nbOfTuple1,nbOfComp1);
5427       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
5428       double *pt=ret->getPointer();
5429       for(int i=0;i<nbOfTuple1;i++)
5430         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
5431       ret->copyStringInfoFrom(*a1);
5432       return ret.retn();
5433     }
5434   else
5435     {
5436       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
5437       return 0;
5438     }
5439 }
5440
5441 /*!
5442  * Divide values of \a this array by values of another DataArrayDouble. There are 3
5443  * valid cases.
5444  * 1.  The arrays have same number of tuples and components. Then each value of
5445  *    \a this array is divided by the corresponding value of \a other one, i.e.:
5446  *   _a_ [ i, j ] /= _other_ [ i, j ].
5447  * 2.  The arrays have same number of tuples and \a other array has one component. Then
5448  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
5449  * 3.  The arrays have same number of components and \a other array has one tuple. Then
5450  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
5451  *
5452  *  \warning No check of division by zero is performed!
5453  *  \param [in] other - an array to divide \a this one by.
5454  *  \throw If \a other is NULL.
5455  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
5456  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
5457  *         \a other has number of both tuples and components not equal to 1.
5458  */
5459 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
5460 {
5461   if(!other)
5462     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
5463   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
5464   checkAllocated();
5465   other->checkAllocated();
5466   int nbOfTuple=getNumberOfTuples();
5467   int nbOfTuple2=other->getNumberOfTuples();
5468   int nbOfComp=getNumberOfComponents();
5469   int nbOfComp2=other->getNumberOfComponents();
5470   if(nbOfTuple==nbOfTuple2)
5471     {
5472       if(nbOfComp==nbOfComp2)
5473         {
5474           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
5475         }
5476       else if(nbOfComp2==1)
5477         {
5478           double *ptr=getPointer();
5479           const double *ptrc=other->getConstPointer();
5480           for(int i=0;i<nbOfTuple;i++)
5481             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
5482         }
5483       else
5484         throw INTERP_KERNEL::Exception(msg);
5485     }
5486   else if(nbOfTuple2==1)
5487     {
5488       if(nbOfComp2==nbOfComp)
5489         {
5490           double *ptr=getPointer();
5491           const double *ptrc=other->getConstPointer();
5492           for(int i=0;i<nbOfTuple;i++)
5493             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
5494         }
5495       else
5496         throw INTERP_KERNEL::Exception(msg);
5497     }
5498   else
5499     throw INTERP_KERNEL::Exception(msg);
5500   declareAsNew();
5501 }
5502
5503 /*!
5504  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
5505  * valid cases.
5506  *
5507  *  \param [in] a1 - an array to pow up.
5508  *  \param [in] a2 - another array to sum up.
5509  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
5510  *          The caller is to delete this result array using decrRef() as it is no more
5511  *          needed.
5512  *  \throw If either \a a1 or \a a2 is NULL.
5513  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
5514  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
5515  *  \throw If there is a negative value in \a a1.
5516  */
5517 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
5518 {
5519   if(!a1 || !a2)
5520     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
5521   int nbOfTuple=a1->getNumberOfTuples();
5522   int nbOfTuple2=a2->getNumberOfTuples();
5523   int nbOfComp=a1->getNumberOfComponents();
5524   int nbOfComp2=a2->getNumberOfComponents();
5525   if(nbOfTuple!=nbOfTuple2)
5526     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
5527   if(nbOfComp!=1 || nbOfComp2!=1)
5528     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
5529   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
5530   const double *ptr1(a1->begin()),*ptr2(a2->begin());
5531   double *ptr=ret->getPointer();
5532   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
5533     {
5534       if(*ptr1>=0)
5535         {
5536           *ptr=pow(*ptr1,*ptr2);
5537         }
5538       else
5539         {
5540           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
5541           throw INTERP_KERNEL::Exception(oss.str().c_str());
5542         }
5543     }
5544   return ret.retn();
5545 }
5546
5547 /*!
5548  * Apply pow on values of another DataArrayDouble to values of \a this one.
5549  *
5550  *  \param [in] other - an array to pow to \a this one.
5551  *  \throw If \a other is NULL.
5552  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
5553  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
5554  *  \throw If there is a negative value in \a this.
5555  */
5556 void DataArrayDouble::powEqual(const DataArrayDouble *other)
5557 {
5558   if(!other)
5559     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
5560   int nbOfTuple=getNumberOfTuples();
5561   int nbOfTuple2=other->getNumberOfTuples();
5562   int nbOfComp=getNumberOfComponents();
5563   int nbOfComp2=other->getNumberOfComponents();
5564   if(nbOfTuple!=nbOfTuple2)
5565     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
5566   if(nbOfComp!=1 || nbOfComp2!=1)
5567     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
5568   double *ptr=getPointer();
5569   const double *ptrc=other->begin();
5570   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
5571     {
5572       if(*ptr>=0)
5573         *ptr=pow(*ptr,*ptrc);
5574       else
5575         {
5576           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
5577           throw INTERP_KERNEL::Exception(oss.str().c_str());
5578         }
5579     }
5580   declareAsNew();
5581 }
5582
5583 /*!
5584  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5585  * Server side.
5586  */
5587 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
5588 {
5589   tinyInfo.resize(2);
5590   if(isAllocated())
5591     {
5592       tinyInfo[0]=getNumberOfTuples();
5593       tinyInfo[1]=getNumberOfComponents();
5594     }
5595   else
5596     {
5597       tinyInfo[0]=-1;
5598       tinyInfo[1]=-1;
5599     }
5600 }
5601
5602 /*!
5603  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5604  * Server side.
5605  */
5606 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
5607 {
5608   if(isAllocated())
5609     {
5610       int nbOfCompo=getNumberOfComponents();
5611       tinyInfo.resize(nbOfCompo+1);
5612       tinyInfo[0]=getName();
5613       for(int i=0;i<nbOfCompo;i++)
5614         tinyInfo[i+1]=getInfoOnComponent(i);
5615     }
5616   else
5617     {
5618       tinyInfo.resize(1);
5619       tinyInfo[0]=getName();
5620     }
5621 }
5622
5623 /*!
5624  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5625  * This method returns if a feeding is needed.
5626  */
5627 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
5628 {
5629   int nbOfTuple=tinyInfoI[0];
5630   int nbOfComp=tinyInfoI[1];
5631   if(nbOfTuple!=-1 || nbOfComp!=-1)
5632     {
5633       alloc(nbOfTuple,nbOfComp);
5634       return true;
5635     }
5636   return false;
5637 }
5638
5639 /*!
5640  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
5641  */
5642 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
5643 {
5644   setName(tinyInfoS[0]);
5645   if(isAllocated())
5646     {
5647       int nbOfCompo=getNumberOfComponents();
5648       for(int i=0;i<nbOfCompo;i++)
5649         setInfoOnComponent(i,tinyInfoS[i+1]);
5650     }
5651 }
5652
5653 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
5654 {
5655   if(_da)
5656     {
5657       _da->incrRef();
5658       if(_da->isAllocated())
5659         {
5660           _nb_comp=da->getNumberOfComponents();
5661           _nb_tuple=da->getNumberOfTuples();
5662           _pt=da->getPointer();
5663         }
5664     }
5665 }
5666
5667 DataArrayDoubleIterator::~DataArrayDoubleIterator()
5668 {
5669   if(_da)
5670     _da->decrRef();
5671 }
5672
5673 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
5674 {
5675   if(_tuple_id<_nb_tuple)
5676     {
5677       _tuple_id++;
5678       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
5679       _pt+=_nb_comp;
5680       return ret;
5681     }
5682   else
5683     return 0;
5684 }
5685
5686 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
5687 {
5688 }
5689
5690
5691 std::string DataArrayDoubleTuple::repr() const
5692 {
5693   std::ostringstream oss; oss.precision(17); oss << "(";
5694   for(int i=0;i<_nb_of_compo-1;i++)
5695     oss << _pt[i] << ", ";
5696   oss << _pt[_nb_of_compo-1] << ")";
5697   return oss.str();
5698 }
5699
5700 double DataArrayDoubleTuple::doubleValue() const
5701 {
5702   if(_nb_of_compo==1)
5703     return *_pt;
5704   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
5705 }
5706
5707 /*!
5708  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef.
5709  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::useArray with ownership set to \b false.
5710  * 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
5711  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
5712  */
5713 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
5714 {
5715   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
5716     {
5717       DataArrayDouble *ret=DataArrayDouble::New();
5718       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
5719       return ret;
5720     }
5721   else
5722     {
5723       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
5724       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
5725       throw INTERP_KERNEL::Exception(oss.str().c_str());
5726     }
5727 }
5728
5729 /*!
5730  * Returns a new instance of DataArrayInt. The caller is to delete this array
5731  * using decrRef() as it is no more needed. 
5732  */
5733 DataArrayInt *DataArrayInt::New()
5734 {
5735   return new DataArrayInt;
5736 }
5737
5738 /*!
5739  * Checks if raw data is allocated. Read more on the raw data
5740  * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
5741  *  \return bool - \a true if the raw data is allocated, \a false else.
5742  */
5743 bool DataArrayInt::isAllocated() const
5744 {
5745   return getConstPointer()!=0;
5746 }
5747
5748 /*!
5749  * Checks if raw data is allocated and throws an exception if it is not the case.
5750  *  \throw If the raw data is not allocated.
5751  */
5752 void DataArrayInt::checkAllocated() const
5753 {
5754   if(!isAllocated())
5755     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
5756 }
5757
5758 /*!
5759  * This method desallocated \a this without modification of informations relative to the components.
5760  * After call of this method, DataArrayInt::isAllocated will return false.
5761  * If \a this is already not allocated, \a this is let unchanged.
5762  */
5763 void DataArrayInt::desallocate()
5764 {
5765   _mem.destroy();
5766 }
5767
5768 std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
5769 {
5770   std::size_t sz(_mem.getNbOfElemAllocated());
5771   sz*=sizeof(int);
5772   return DataArray::getHeapMemorySizeWithoutChildren()+sz;
5773 }
5774
5775 /*!
5776  * Returns the only one value in \a this, if and only if number of elements
5777  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
5778  *  \return double - the sole value stored in \a this array.
5779  *  \throw If at least one of conditions stated above is not fulfilled.
5780  */
5781 int DataArrayInt::intValue() const
5782 {
5783   if(isAllocated())
5784     {
5785       if(getNbOfElems()==1)
5786         {
5787           return *getConstPointer();
5788         }
5789       else
5790         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
5791     }
5792   else
5793     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
5794 }
5795
5796 /*!
5797  * Returns an integer value characterizing \a this array, which is useful for a quick
5798  * comparison of many instances of DataArrayInt.
5799  *  \return int - the hash value.
5800  *  \throw If \a this is not allocated.
5801  */
5802 int DataArrayInt::getHashCode() const
5803 {
5804   checkAllocated();
5805   std::size_t nbOfElems=getNbOfElems();
5806   int ret=nbOfElems*65536;
5807   int delta=3;
5808   if(nbOfElems>48)
5809     delta=nbOfElems/8;
5810   int ret0=0;
5811   const int *pt=begin();
5812   for(std::size_t i=0;i<nbOfElems;i+=delta)
5813     ret0+=pt[i] & 0x1FFF;
5814   return ret+ret0;
5815 }
5816
5817 /*!
5818  * Checks the number of tuples.
5819  *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
5820  *  \throw If \a this is not allocated.
5821  */
5822 bool DataArrayInt::empty() const
5823 {
5824   checkAllocated();
5825   return getNumberOfTuples()==0;
5826 }
5827
5828 /*!
5829  * Returns a full copy of \a this. For more info on copying data arrays see
5830  * \ref MEDCouplingArrayBasicsCopyDeep.
5831  *  \return DataArrayInt * - a new instance of DataArrayInt.
5832  */
5833 DataArrayInt *DataArrayInt::deepCpy() const
5834 {
5835   return new DataArrayInt(*this);
5836 }
5837
5838 /*!
5839  * Returns either a \a deep or \a shallow copy of this array. For more info see
5840  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
5841  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
5842  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
5843  *          == \a true) or \a this instance (if \a dCpy == \a false).
5844  */
5845 DataArrayInt *DataArrayInt::performCpy(bool dCpy) const
5846 {
5847   if(dCpy)
5848     return deepCpy();
5849   else
5850     {
5851       incrRef();
5852       return const_cast<DataArrayInt *>(this);
5853     }
5854 }
5855
5856 /*!
5857  * Copies all the data from another DataArrayInt. For more info see
5858  * \ref MEDCouplingArrayBasicsCopyDeepAssign.
5859  *  \param [in] other - another instance of DataArrayInt to copy data from.
5860  *  \throw If the \a other is not allocated.
5861  */
5862 void DataArrayInt::cpyFrom(const DataArrayInt& other)
5863 {
5864   other.checkAllocated();
5865   int nbOfTuples=other.getNumberOfTuples();
5866   int nbOfComp=other.getNumberOfComponents();
5867   allocIfNecessary(nbOfTuples,nbOfComp);
5868   std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
5869   int *pt=getPointer();
5870   const int *ptI=other.getConstPointer();
5871   for(std::size_t i=0;i<nbOfElems;i++)
5872     pt[i]=ptI[i];
5873   copyStringInfoFrom(other);
5874 }
5875
5876 /*!
5877  * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
5878  * 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.
5879  * If \a this has not already been allocated, number of components is set to one.
5880  * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
5881  * 
5882  * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
5883  */
5884 void DataArrayInt::reserve(std::size_t nbOfElems)
5885 {
5886   int nbCompo=getNumberOfComponents();
5887   if(nbCompo==1)
5888     {
5889       _mem.reserve(nbOfElems);
5890     }
5891   else if(nbCompo==0)
5892     {
5893       _mem.reserve(nbOfElems);
5894       _info_on_compo.resize(1);
5895     }
5896   else
5897     throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
5898 }
5899
5900 /*!
5901  * 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
5902  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5903  *
5904  * \param [in] val the value to be added in \a this
5905  * \throw If \a this has already been allocated with number of components different from one.
5906  * \sa DataArrayInt::pushBackValsSilent
5907  */
5908 void DataArrayInt::pushBackSilent(int val)
5909 {
5910   int nbCompo=getNumberOfComponents();
5911   if(nbCompo==1)
5912     _mem.pushBack(val);
5913   else if(nbCompo==0)
5914     {
5915       _info_on_compo.resize(1);
5916       _mem.pushBack(val);
5917     }
5918   else
5919     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
5920 }
5921
5922 /*!
5923  * 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
5924  * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
5925  *
5926  *  \param [in] valsBg - an array of values to push at the end of \this.
5927  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5928  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5929  * \throw If \a this has already been allocated with number of components different from one.
5930  * \sa DataArrayInt::pushBackSilent
5931  */
5932 void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd)
5933 {
5934   int nbCompo=getNumberOfComponents();
5935   if(nbCompo==1)
5936     _mem.insertAtTheEnd(valsBg,valsEnd);
5937   else if(nbCompo==0)
5938     {
5939       _info_on_compo.resize(1);
5940       _mem.insertAtTheEnd(valsBg,valsEnd);
5941     }
5942   else
5943     throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
5944 }
5945
5946 /*!
5947  * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
5948  * \throw If \a this is already empty.
5949  * \throw If \a this has number of components different from one.
5950  */
5951 int DataArrayInt::popBackSilent()
5952 {
5953   if(getNumberOfComponents()==1)
5954     return _mem.popBack();
5955   else
5956     throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
5957 }
5958
5959 /*!
5960  * 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.
5961  *
5962  * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
5963  */
5964 void DataArrayInt::pack() const
5965 {
5966   _mem.pack();
5967 }
5968
5969 /*!
5970  * Allocates the raw data in memory. If exactly as same memory as needed already
5971  * allocated, it is not re-allocated.
5972  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5973  *  \param [in] nbOfCompo - number of components of data to allocate.
5974  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5975  */
5976 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
5977 {
5978   if(isAllocated())
5979     {
5980       if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
5981         alloc(nbOfTuple,nbOfCompo);
5982     }
5983   else
5984     alloc(nbOfTuple,nbOfCompo);
5985 }
5986
5987 /*!
5988  * Allocates the raw data in memory. If the memory was already allocated, then it is
5989  * freed and re-allocated. See an example of this method use
5990  * \ref MEDCouplingArraySteps1WC "here".
5991  *  \param [in] nbOfTuple - number of tuples of data to allocate.
5992  *  \param [in] nbOfCompo - number of components of data to allocate.
5993  *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
5994  */
5995 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
5996 {
5997   if(nbOfTuple<0 || nbOfCompo<0)
5998     throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
5999   _info_on_compo.resize(nbOfCompo);
6000   _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
6001   declareAsNew();
6002 }
6003
6004 /*!
6005  * Assign zero to all values in \a this array. To know more on filling arrays see
6006  * \ref MEDCouplingArrayFill.
6007  * \throw If \a this is not allocated.
6008  */
6009 void DataArrayInt::fillWithZero()
6010 {
6011   checkAllocated();
6012   _mem.fillWithValue(0);
6013   declareAsNew();
6014 }
6015
6016 /*!
6017  * Assign \a val to all values in \a this array. To know more on filling arrays see
6018  * \ref MEDCouplingArrayFill.
6019  *  \param [in] val - the value to fill with.
6020  *  \throw If \a this is not allocated.
6021  */
6022 void DataArrayInt::fillWithValue(int val)
6023 {
6024   checkAllocated();
6025   _mem.fillWithValue(val);
6026   declareAsNew();
6027 }
6028
6029 /*!
6030  * Set all values in \a this array so that the i-th element equals to \a init + i
6031  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
6032  *  \param [in] init - value to assign to the first element of array.
6033  *  \throw If \a this->getNumberOfComponents() != 1
6034  *  \throw If \a this is not allocated.
6035  */
6036 void DataArrayInt::iota(int init)
6037 {
6038   checkAllocated();
6039   if(getNumberOfComponents()!=1)
6040     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
6041   int *ptr=getPointer();
6042   int ntuples=getNumberOfTuples();
6043   for(int i=0;i<ntuples;i++)
6044     ptr[i]=init+i;
6045   declareAsNew();
6046 }
6047
6048 /*!
6049  * Returns a textual and human readable representation of \a this instance of
6050  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
6051  *  \return std::string - text describing \a this DataArrayInt.
6052  */
6053 std::string DataArrayInt::repr() const
6054 {
6055   std::ostringstream ret;
6056   reprStream(ret);
6057   return ret.str();
6058 }
6059
6060 std::string DataArrayInt::reprZip() const
6061 {
6062   std::ostringstream ret;
6063   reprZipStream(ret);
6064   return ret.str();
6065 }
6066
6067 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
6068 {
6069   static const char SPACE[4]={' ',' ',' ',' '};
6070   checkAllocated();
6071   std::string idt(indent,' ');
6072   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
6073   if(byteArr)
6074     {
6075       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
6076       if(std::string(type)=="Int32")
6077         {
6078           const char *data(reinterpret_cast<const char *>(begin()));
6079           std::size_t sz(getNbOfElems()*sizeof(int));
6080           byteArr->insertAtTheEnd(data,data+sz);
6081           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6082         }
6083       else if(std::string(type)=="Int8")
6084         {
6085           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
6086           std::copy(begin(),end(),(char *)tmp);
6087           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
6088           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6089         }
6090       else if(std::string(type)=="UInt8")
6091         {
6092           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
6093           std::copy(begin(),end(),(unsigned char *)tmp);
6094           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
6095           byteArr->insertAtTheEnd(SPACE,SPACE+4);
6096         }
6097       else
6098         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
6099     }
6100   else
6101     {
6102       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
6103       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
6104     }
6105   ofs << std::endl << idt << "</DataArray>\n";
6106 }
6107
6108 void DataArrayInt::reprStream(std::ostream& stream) const
6109 {
6110   stream << "Name of int array : \"" << _name << "\"\n";
6111   reprWithoutNameStream(stream);
6112 }
6113
6114 void DataArrayInt::reprZipStream(std::ostream& stream) const
6115 {
6116   stream << "Name of int array : \"" << _name << "\"\n";
6117   reprZipWithoutNameStream(stream);
6118 }
6119
6120 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
6121 {
6122   DataArray::reprWithoutNameStream(stream);
6123   _mem.repr(getNumberOfComponents(),stream);
6124 }
6125
6126 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
6127 {
6128   DataArray::reprWithoutNameStream(stream);
6129   _mem.reprZip(getNumberOfComponents(),stream);
6130 }
6131
6132 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
6133 {
6134   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
6135   const int *data=getConstPointer();
6136   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
6137   if(nbTuples*nbComp>=1)
6138     {
6139       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
6140       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
6141       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
6142       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
6143     }
6144   else
6145     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
6146   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
6147 }
6148
6149 /*!
6150  * Method that gives a quick overvien of \a this for python.
6151  */
6152 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
6153 {
6154   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
6155   stream << "DataArrayInt C++ instance at " << this << ". ";
6156   if(isAllocated())
6157     {
6158       int nbOfCompo=(int)_info_on_compo.size();
6159       if(nbOfCompo>=1)
6160         {
6161           int nbOfTuples=getNumberOfTuples();
6162           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
6163           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
6164         }
6165       else
6166         stream << "Number of components : 0.";
6167     }
6168   else
6169     stream << "*** No data allocated ****";
6170 }
6171
6172 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
6173 {
6174   const int *data=begin();
6175   int nbOfTuples=getNumberOfTuples();
6176   int nbOfCompo=(int)_info_on_compo.size();
6177   std::ostringstream oss2; oss2 << "[";
6178   std::string oss2Str(oss2.str());
6179   bool isFinished=true;
6180   for(int i=0;i<nbOfTuples && isFinished;i++)
6181     {
6182       if(nbOfCompo>1)
6183         {
6184           oss2 << "(";
6185           for(int j=0;j<nbOfCompo;j++,data++)
6186             {
6187               oss2 << *data;
6188               if(j!=nbOfCompo-1) oss2 << ", ";
6189             }
6190           oss2 << ")";
6191         }
6192       else
6193         oss2 << *data++;
6194       if(i!=nbOfTuples-1) oss2 << ", ";
6195       std::string oss3Str(oss2.str());
6196       if(oss3Str.length()<maxNbOfByteInRepr)
6197         oss2Str=oss3Str;
6198       else
6199         isFinished=false;
6200     }
6201   stream << oss2Str;
6202   if(!isFinished)
6203     stream << "... ";
6204   stream << "]";
6205 }
6206
6207 /*!
6208  * Modifies \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
6209  * i.e. a current value is used as in index to get a new value from \a indArrBg.
6210  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
6211  *         to \a this array.
6212  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6213  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6214  *  \throw If \a this->getNumberOfComponents() != 1
6215  *  \throw If any value of \a this can't be used as a valid index for 
6216  *         [\a indArrBg, \a indArrEnd).
6217  */
6218 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
6219 {
6220   checkAllocated();
6221   if(getNumberOfComponents()!=1)
6222     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6223   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6224   int nbOfTuples=getNumberOfTuples();
6225   int *pt=getPointer();
6226   for(int i=0;i<nbOfTuples;i++,pt++)
6227     {
6228       if(*pt>=0 && *pt<nbElemsIn)
6229         *pt=indArrBg[*pt];
6230       else
6231         {
6232           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
6233           throw INTERP_KERNEL::Exception(oss.str().c_str());
6234         }
6235     }
6236   declareAsNew();
6237 }
6238
6239 /*!
6240  * Computes distribution of values of \a this one-dimensional array between given value
6241  * ranges (casts). This method is typically useful for entity number spliting by types,
6242  * for example. 
6243  *  \warning The values contained in \a arrBg should be sorted ascendently. No
6244  *           check of this is be done. If not, the result is not warranted. 
6245  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
6246  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
6247  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
6248  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
6249  *         should be more than every value in \a this array.
6250  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
6251  *              the last value of \a arrBg is \a arrEnd[ -1 ].
6252  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
6253  *         (same number of tuples and components), the caller is to delete 
6254  *         using decrRef() as it is no more needed.
6255  *         This array contains indices of ranges for every value of \a this array. I.e.
6256  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
6257  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
6258  *         this in which cast it holds.
6259  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
6260  *         array, the caller is to delete using decrRef() as it is no more needed.
6261  *         This array contains ranks of values of \a this array within ranges
6262  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
6263  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
6264  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
6265  *         for each tuple its rank inside its cast. The rank is computed as difference
6266  *         between the value and the lowest value of range.
6267  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
6268  *         ranges (casts) to which at least one value of \a this array belongs.
6269  *         Or, in other words, this param contains the casts that \a this contains.
6270  *         The caller is to delete this array using decrRef() as it is no more needed.
6271  *
6272  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
6273  *            the output of this method will be : 
6274  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
6275  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
6276  * - \a castsPresent  : [0,1]
6277  *
6278  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
6279  * range #1 and its rank within this range is 2; etc.
6280  *
6281  *  \throw If \a this->getNumberOfComponents() != 1.
6282  *  \throw If \a arrEnd - arrBg < 2.
6283  *  \throw If any value of \a this is not less than \a arrEnd[-1].
6284  */
6285 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
6286                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
6287     {
6288   checkAllocated();
6289   if(getNumberOfComponents()!=1)
6290     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6291   int nbOfTuples=getNumberOfTuples();
6292   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
6293   if(nbOfCast<2)
6294     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
6295   nbOfCast--;
6296   const int *work=getConstPointer();
6297   typedef std::reverse_iterator<const int *> rintstart;
6298   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
6299   rintstart end2(arrBg);
6300   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New();
6301   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New();
6302   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New();
6303   ret1->alloc(nbOfTuples,1);
6304   ret2->alloc(nbOfTuples,1);
6305   int *ret1Ptr=ret1->getPointer();
6306   int *ret2Ptr=ret2->getPointer();
6307   std::set<std::size_t> castsDetected;
6308   for(int i=0;i<nbOfTuples;i++)
6309     {
6310       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
6311       std::size_t pos=std::distance(bg,res);
6312       std::size_t pos2=nbOfCast-pos;
6313       if(pos2<nbOfCast)
6314         {
6315           ret1Ptr[i]=(int)pos2;
6316           ret2Ptr[i]=work[i]-arrBg[pos2];
6317           castsDetected.insert(pos2);
6318         }
6319       else
6320         {
6321           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
6322           throw INTERP_KERNEL::Exception(oss.str().c_str());
6323         }
6324     }
6325   ret3->alloc((int)castsDetected.size(),1);
6326   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
6327   castArr=ret1.retn();
6328   rankInsideCast=ret2.retn();
6329   castsPresent=ret3.retn();
6330     }
6331
6332 /*!
6333  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
6334  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
6335  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
6336  * new value in place \a indArr[ \a v ] is i.
6337  *  \param [in] indArrBg - the array holding indices within the result array to assign
6338  *         indices of values of \a this array pointing to values of \a indArrBg.
6339  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
6340  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
6341  *  \return DataArrayInt * - the new instance of DataArrayInt.
6342  *          The caller is to delete this result array using decrRef() as it is no more
6343  *          needed.
6344  *  \throw If \a this->getNumberOfComponents() != 1.
6345  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
6346  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
6347  */
6348 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
6349 {
6350   checkAllocated();
6351   if(getNumberOfComponents()!=1)
6352     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
6353   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
6354   int nbOfTuples=getNumberOfTuples();
6355   const int *pt=getConstPointer();
6356   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6357   ret->alloc(nbOfTuples,1);
6358   ret->fillWithValue(-1);
6359   int *tmp=ret->getPointer();
6360   for(int i=0;i<nbOfTuples;i++,pt++)
6361     {
6362       if(*pt>=0 && *pt<nbElemsIn)
6363         {
6364           int pos=indArrBg[*pt];
6365           if(pos>=0 && pos<nbOfTuples)
6366             tmp[pos]=i;
6367           else
6368             {
6369               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
6370               throw INTERP_KERNEL::Exception(oss.str().c_str());
6371             }
6372         }
6373       else
6374         {
6375           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
6376           throw INTERP_KERNEL::Exception(oss.str().c_str());
6377         }
6378     }
6379   return ret.retn();
6380 }
6381
6382 /*!
6383  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6384  * from values of \a this array, which is supposed to contain a renumbering map in 
6385  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
6386  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6387  *  \param [in] newNbOfElem - the number of tuples in the result array.
6388  *  \return DataArrayInt * - the new instance of DataArrayInt.
6389  *          The caller is to delete this result array using decrRef() as it is no more
6390  *          needed.
6391  * 
6392  *  \if ENABLE_EXAMPLES
6393  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
6394  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
6395  *  \endif
6396  */
6397 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
6398 {
6399   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6400   ret->alloc(newNbOfElem,1);
6401   int nbOfOldNodes=getNumberOfTuples();
6402   const int *old2New=getConstPointer();
6403   int *pt=ret->getPointer();
6404   for(int i=0;i!=nbOfOldNodes;i++)
6405     {
6406       int newp(old2New[i]);
6407       if(newp!=-1)
6408         {
6409           if(newp>=0 && newp<newNbOfElem)
6410             pt[newp]=i;
6411           else
6412             {
6413               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6414               throw INTERP_KERNEL::Exception(oss.str().c_str());
6415             }
6416         }
6417     }
6418   return ret.retn();
6419 }
6420
6421 /*!
6422  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
6423  * 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]
6424  */
6425 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
6426 {
6427   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6428   ret->alloc(newNbOfElem,1);
6429   int nbOfOldNodes=getNumberOfTuples();
6430   const int *old2New=getConstPointer();
6431   int *pt=ret->getPointer();
6432   for(int i=nbOfOldNodes-1;i>=0;i--)
6433     {
6434       int newp(old2New[i]);
6435       if(newp!=-1)
6436         {
6437           if(newp>=0 && newp<newNbOfElem)
6438             pt[newp]=i;
6439           else
6440             {
6441               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
6442               throw INTERP_KERNEL::Exception(oss.str().c_str());
6443             }
6444         }
6445     }
6446   return ret.retn();
6447 }
6448
6449 /*!
6450  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
6451  * from values of \a this array, which is supposed to contain a renumbering map in 
6452  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
6453  * To know how to use the renumbering maps see \ref MEDCouplingArrayRenumbering.
6454  *  \param [in] newNbOfElem - the number of tuples in the result array.
6455  *  \return DataArrayInt * - the new instance of DataArrayInt.
6456  *          The caller is to delete this result array using decrRef() as it is no more
6457  *          needed.
6458  * 
6459  *  \if ENABLE_EXAMPLES
6460  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
6461  *
6462  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
6463  *  \endif
6464  */
6465 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
6466 {
6467   checkAllocated();
6468   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6469   ret->alloc(oldNbOfElem,1);
6470   const int *new2Old=getConstPointer();
6471   int *pt=ret->getPointer();
6472   std::fill(pt,pt+oldNbOfElem,-1);
6473   int nbOfNewElems=getNumberOfTuples();
6474   for(int i=0;i<nbOfNewElems;i++)
6475     {
6476       int v(new2Old[i]);
6477       if(v>=0 && v<oldNbOfElem)
6478         pt[v]=i;
6479       else
6480         {
6481           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
6482           throw INTERP_KERNEL::Exception(oss.str().c_str());
6483         }
6484     }
6485   return ret.retn();
6486 }
6487
6488 /*!
6489  * Equivalent to DataArrayInt::isEqual except that if false the reason of
6490  * mismatch is given.
6491  * 
6492  * \param [in] other the instance to be compared with \a this
6493  * \param [out] reason In case of inequality returns the reason.
6494  * \sa DataArrayInt::isEqual
6495  */
6496 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
6497 {
6498   if(!areInfoEqualsIfNotWhy(other,reason))
6499     return false;
6500   return _mem.isEqual(other._mem,0,reason);
6501 }
6502
6503 /*!
6504  * Checks if \a this and another DataArrayInt are fully equal. For more info see
6505  * \ref MEDCouplingArrayBasicsCompare.
6506  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6507  *  \return bool - \a true if the two arrays are equal, \a false else.
6508  */
6509 bool DataArrayInt::isEqual(const DataArrayInt& other) const
6510 {
6511   std::string tmp;
6512   return isEqualIfNotWhy(other,tmp);
6513 }
6514
6515 /*!
6516  * Checks if values of \a this and another DataArrayInt are equal. For more info see
6517  * \ref MEDCouplingArrayBasicsCompare.
6518  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6519  *  \return bool - \a true if the values of two arrays are equal, \a false else.
6520  */
6521 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
6522 {
6523   std::string tmp;
6524   return _mem.isEqual(other._mem,0,tmp);
6525 }
6526
6527 /*!
6528  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
6529  * performed on sorted value sequences.
6530  * For more info see\ref MEDCouplingArrayBasicsCompare.
6531  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
6532  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
6533  */
6534 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
6535 {
6536   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy();
6537   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy();
6538   a->sort();
6539   b->sort();
6540   return a->isEqualWithoutConsideringStr(*b);
6541 }
6542
6543 /*!
6544  * This method compares content of input vector \a v and \a this.
6545  * 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.
6546  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
6547  *
6548  * \param [in] v - the vector of 'flags' to be compared with \a this.
6549  *
6550  * \throw If \a this is not sorted ascendingly.
6551  * \throw If \a this has not exactly one component.
6552  * \throw If \a this is not allocated.
6553  */
6554 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
6555 {
6556   checkAllocated();
6557   if(getNumberOfComponents()!=1)
6558     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
6559   const int *w(begin()),*end2(end());
6560   int refVal=-std::numeric_limits<int>::max();
6561   int i=0;
6562   std::vector<bool>::const_iterator it(v.begin());
6563   for(;it!=v.end();it++,i++)
6564     {
6565       if(*it)
6566         {
6567           if(w!=end2)
6568             {
6569               if(*w++==i)
6570                 {
6571                   if(i>refVal)
6572                     refVal=i;
6573                   else
6574                     {
6575                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
6576                       throw INTERP_KERNEL::Exception(oss.str().c_str());
6577                     }
6578                 }
6579               else
6580                 return false;
6581             }
6582           else
6583             return false;
6584         }
6585     }
6586   return w==end2;
6587 }
6588
6589 /*!
6590  * Sorts values of the array.
6591  *  \param [in] asc - \a true means ascending order, \a false, descending.
6592  *  \throw If \a this is not allocated.
6593  *  \throw If \a this->getNumberOfComponents() != 1.
6594  */
6595 void DataArrayInt::sort(bool asc)
6596 {
6597   checkAllocated();
6598   if(getNumberOfComponents()!=1)
6599     throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
6600   _mem.sort(asc);
6601   declareAsNew();
6602 }
6603
6604 /*!
6605  * Computes for each tuple the sum of number of components values in the tuple and return it.
6606  * 
6607  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6608  *          same number of tuples as \a this array and one component.
6609  *          The caller is to delete this result array using decrRef() as it is no more
6610  *          needed.
6611  *  \throw If \a this is not allocated.
6612  */
6613 DataArrayInt *DataArrayInt::sumPerTuple() const
6614 {
6615   checkAllocated();
6616   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
6617   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
6618   ret->alloc(nbOfTuple,1);
6619   const int *src(getConstPointer());
6620   int *dest(ret->getPointer());
6621   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
6622     *dest=std::accumulate(src,src+nbOfComp,0);
6623   return ret.retn();
6624 }
6625
6626 /*!
6627  * Reverse the array values.
6628  *  \throw If \a this->getNumberOfComponents() < 1.
6629  *  \throw If \a this is not allocated.
6630  */
6631 void DataArrayInt::reverse()
6632 {
6633   checkAllocated();
6634   _mem.reverse(getNumberOfComponents());
6635   declareAsNew();
6636 }
6637
6638 /*!
6639  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6640  * If not an exception is thrown.
6641  *  \param [in] increasing - if \a true, the array values should be increasing.
6642  *  \throw If sequence of values is not strictly monotonic in agreement with \a
6643  *         increasing arg.
6644  *  \throw If \a this->getNumberOfComponents() != 1.
6645  *  \throw If \a this is not allocated.
6646  */
6647 void DataArrayInt::checkMonotonic(bool increasing) const
6648 {
6649   if(!isMonotonic(increasing))
6650     {
6651       if (increasing)
6652         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
6653       else
6654         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
6655     }
6656 }
6657
6658 /*!
6659  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
6660  *  \param [in] increasing - if \a true, array values should be increasing.
6661  *  \return bool - \a true if values change in accordance with \a increasing arg.
6662  *  \throw If \a this->getNumberOfComponents() != 1.
6663  *  \throw If \a this is not allocated.
6664  */
6665 bool DataArrayInt::isMonotonic(bool increasing) const
6666 {
6667   checkAllocated();
6668   if(getNumberOfComponents()!=1)
6669     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
6670   int nbOfElements=getNumberOfTuples();
6671   const int *ptr=getConstPointer();
6672   if(nbOfElements==0)
6673     return true;
6674   int ref=ptr[0];
6675   if(increasing)
6676     {
6677       for(int i=1;i<nbOfElements;i++)
6678         {
6679           if(ptr[i]>=ref)
6680             ref=ptr[i];
6681           else
6682             return false;
6683         }
6684     }
6685   else
6686     {
6687       for(int i=1;i<nbOfElements;i++)
6688         {
6689           if(ptr[i]<=ref)
6690             ref=ptr[i];
6691           else
6692             return false;
6693         }
6694     }
6695   return true;
6696 }
6697
6698 /*!
6699  * This method check that array consistently INCREASING or DECREASING in value.
6700  */
6701 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
6702 {
6703   checkAllocated();
6704   if(getNumberOfComponents()!=1)
6705     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
6706   int nbOfElements=getNumberOfTuples();
6707   const int *ptr=getConstPointer();
6708   if(nbOfElements==0)
6709     return true;
6710   int ref=ptr[0];
6711   if(increasing)
6712     {
6713       for(int i=1;i<nbOfElements;i++)
6714         {
6715           if(ptr[i]>ref)
6716             ref=ptr[i];
6717           else
6718             return false;
6719         }
6720     }
6721   else
6722     {
6723       for(int i=1;i<nbOfElements;i++)
6724         {
6725           if(ptr[i]<ref)
6726             ref=ptr[i];
6727           else
6728             return false;
6729         }
6730     }
6731   return true;
6732 }
6733
6734 /*!
6735  * This method check that array consistently INCREASING or DECREASING in value.
6736  */
6737 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
6738 {
6739   if(!isStrictlyMonotonic(increasing))
6740     {
6741       if (increasing)
6742         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
6743       else
6744         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
6745     }
6746 }
6747
6748 /*!
6749  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
6750  * one-dimensional arrays that must be of the same length. The result array describes
6751  * correspondence between \a this and \a other arrays, so that 
6752  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
6753  * not possible because some element in \a other is not in \a this, an exception is thrown.
6754  *  \param [in] other - an array to compute permutation to.
6755  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
6756  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
6757  * no more needed.
6758  *  \throw If \a this->getNumberOfComponents() != 1.
6759  *  \throw If \a other->getNumberOfComponents() != 1.
6760  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
6761  *  \throw If \a other includes a value which is not in \a this array.
6762  * 
6763  *  \if ENABLE_EXAMPLES
6764  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
6765  *
6766  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
6767  *  \endif
6768  */
6769 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
6770 {
6771   checkAllocated();
6772   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
6773     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
6774   int nbTuple=getNumberOfTuples();
6775   other.checkAllocated();
6776   if(nbTuple!=other.getNumberOfTuples())
6777     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
6778   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6779   ret->alloc(nbTuple,1);
6780   ret->fillWithValue(-1);
6781   const int *pt=getConstPointer();
6782   std::map<int,int> mm;
6783   for(int i=0;i<nbTuple;i++)
6784     mm[pt[i]]=i;
6785   pt=other.getConstPointer();
6786   int *retToFill=ret->getPointer();
6787   for(int i=0;i<nbTuple;i++)
6788     {
6789       std::map<int,int>::const_iterator it=mm.find(pt[i]);
6790       if(it==mm.end())
6791         {
6792           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
6793           throw INTERP_KERNEL::Exception(oss.str().c_str());
6794         }
6795       retToFill[i]=(*it).second;
6796     }
6797   return ret.retn();
6798 }
6799
6800 /*!
6801  * Sets a C array to be used as raw data of \a this. The previously set info
6802  *  of components is retained and re-sized. 
6803  * For more info see \ref MEDCouplingArraySteps1.
6804  *  \param [in] array - the C array to be used as raw data of \a this.
6805  *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
6806  *  \param [in] type - specifies how to deallocate \a array. If \a type == ParaMEDMEM::CPP_DEALLOC,
6807  *                     \c delete [] \c array; will be called. If \a type == ParaMEDMEM::C_DEALLOC,
6808  *                     \c free(\c array ) will be called.
6809  *  \param [in] nbOfTuple - new number of tuples in \a this.
6810  *  \param [in] nbOfCompo - new number of components in \a this.
6811  */
6812 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
6813 {
6814   _info_on_compo.resize(nbOfCompo);
6815   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
6816   declareAsNew();
6817 }
6818
6819 void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
6820 {
6821   _info_on_compo.resize(nbOfCompo);
6822   _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
6823   declareAsNew();
6824 }
6825
6826 /*!
6827  * Returns a new DataArrayInt holding the same values as \a this array but differently
6828  * arranged in memory. If \a this array holds 2 components of 3 values:
6829  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
6830  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
6831  *  \warning Do not confuse this method with transpose()!
6832  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6833  *          is to delete using decrRef() as it is no more needed.
6834  *  \throw If \a this is not allocated.
6835  */
6836 DataArrayInt *DataArrayInt::fromNoInterlace() const
6837 {
6838   checkAllocated();
6839   if(_mem.isNull())
6840     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
6841   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
6842   DataArrayInt *ret=DataArrayInt::New();
6843   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6844   return ret;
6845 }
6846
6847 /*!
6848  * Returns a new DataArrayInt holding the same values as \a this array but differently
6849  * arranged in memory. If \a this array holds 2 components of 3 values:
6850  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
6851  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
6852  *  \warning Do not confuse this method with transpose()!
6853  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6854  *          is to delete using decrRef() as it is no more needed.
6855  *  \throw If \a this is not allocated.
6856  */
6857 DataArrayInt *DataArrayInt::toNoInterlace() const
6858 {
6859   checkAllocated();
6860   if(_mem.isNull())
6861     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
6862   int *tab=_mem.toNoInterlace(getNumberOfComponents());
6863   DataArrayInt *ret=DataArrayInt::New();
6864   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
6865   return ret;
6866 }
6867
6868 /*!
6869  * Permutes values of \a this array as required by \a old2New array. The values are
6870  * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
6871  * the same as in \this one.
6872  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6873  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6874  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6875  *     giving a new position for i-th old value.
6876  */
6877 void DataArrayInt::renumberInPlace(const int *old2New)
6878 {
6879   checkAllocated();
6880   int nbTuples=getNumberOfTuples();
6881   int nbOfCompo=getNumberOfComponents();
6882   int *tmp=new int[nbTuples*nbOfCompo];
6883   const int *iptr=getConstPointer();
6884   for(int i=0;i<nbTuples;i++)
6885     {
6886       int v=old2New[i];
6887       if(v>=0 && v<nbTuples)
6888         std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
6889       else
6890         {
6891           std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6892           throw INTERP_KERNEL::Exception(oss.str().c_str());
6893         }
6894     }
6895   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6896   delete [] tmp;
6897   declareAsNew();
6898 }
6899
6900 /*!
6901  * Permutes values of \a this array as required by \a new2Old array. The values are
6902  * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
6903  * the same as in \this one.
6904  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6905  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6906  *     giving a previous position of i-th new value.
6907  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6908  *          is to delete using decrRef() as it is no more needed.
6909  */
6910 void DataArrayInt::renumberInPlaceR(const int *new2Old)
6911 {
6912   checkAllocated();
6913   int nbTuples=getNumberOfTuples();
6914   int nbOfCompo=getNumberOfComponents();
6915   int *tmp=new int[nbTuples*nbOfCompo];
6916   const int *iptr=getConstPointer();
6917   for(int i=0;i<nbTuples;i++)
6918     {
6919       int v=new2Old[i];
6920       if(v>=0 && v<nbTuples)
6921         std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
6922       else
6923         {
6924           std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
6925           throw INTERP_KERNEL::Exception(oss.str().c_str());
6926         }
6927     }
6928   std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
6929   delete [] tmp;
6930   declareAsNew();
6931 }
6932
6933 /*!
6934  * Returns a copy of \a this array with values permuted as required by \a old2New array.
6935  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
6936  * Number of tuples in the result array remains the same as in \this one.
6937  * If a permutation reduction is needed, renumberAndReduce() should be used.
6938  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6939  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6940  *          giving a new position for i-th old value.
6941  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6942  *          is to delete using decrRef() as it is no more needed.
6943  *  \throw If \a this is not allocated.
6944  */
6945 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
6946 {
6947   checkAllocated();
6948   int nbTuples=getNumberOfTuples();
6949   int nbOfCompo=getNumberOfComponents();
6950   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6951   ret->alloc(nbTuples,nbOfCompo);
6952   ret->copyStringInfoFrom(*this);
6953   const int *iptr=getConstPointer();
6954   int *optr=ret->getPointer();
6955   for(int i=0;i<nbTuples;i++)
6956     std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
6957   ret->copyStringInfoFrom(*this);
6958   return ret.retn();
6959 }
6960
6961 /*!
6962  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
6963  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
6964  * tuples in the result array remains the same as in \this one.
6965  * If a permutation reduction is needed, substr() or selectByTupleId() should be used.
6966  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6967  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
6968  *     giving a previous position of i-th new value.
6969  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6970  *          is to delete using decrRef() as it is no more needed.
6971  */
6972 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
6973 {
6974   checkAllocated();
6975   int nbTuples=getNumberOfTuples();
6976   int nbOfCompo=getNumberOfComponents();
6977   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
6978   ret->alloc(nbTuples,nbOfCompo);
6979   ret->copyStringInfoFrom(*this);
6980   const int *iptr=getConstPointer();
6981   int *optr=ret->getPointer();
6982   for(int i=0;i<nbTuples;i++)
6983     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
6984   ret->copyStringInfoFrom(*this);
6985   return ret.retn();
6986 }
6987
6988 /*!
6989  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
6990  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
6991  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
6992  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
6993  * \a old2New[ i ] is negative, is missing from the result array.
6994  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
6995  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
6996  *     giving a new position for i-th old tuple and giving negative position for
6997  *     for i-th old tuple that should be omitted.
6998  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
6999  *          is to delete using decrRef() as it is no more needed.
7000  */
7001 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
7002 {
7003   checkAllocated();
7004   int nbTuples=getNumberOfTuples();
7005   int nbOfCompo=getNumberOfComponents();
7006   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7007   ret->alloc(newNbOfTuple,nbOfCompo);
7008   const int *iptr=getConstPointer();
7009   int *optr=ret->getPointer();
7010   for(int i=0;i<nbTuples;i++)
7011     {
7012       int w=old2New[i];
7013       if(w>=0)
7014         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
7015     }
7016   ret->copyStringInfoFrom(*this);
7017   return ret.retn();
7018 }
7019
7020 /*!
7021  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7022  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7023  * \a new2OldBg array.
7024  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7025  * This method is equivalent to renumberAndReduce() except that convention in input is
7026  * \c new2old and \b not \c old2new.
7027  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7028  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7029  *              tuple index in \a this array to fill the i-th tuple in the new array.
7030  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7031  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7032  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7033  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7034  *          is to delete using decrRef() as it is no more needed.
7035  */
7036 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
7037 {
7038   checkAllocated();
7039   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7040   int nbComp=getNumberOfComponents();
7041   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7042   ret->copyStringInfoFrom(*this);
7043   int *pt=ret->getPointer();
7044   const int *srcPt=getConstPointer();
7045   int i=0;
7046   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7047     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7048   ret->copyStringInfoFrom(*this);
7049   return ret.retn();
7050 }
7051
7052 /*!
7053  * Returns a shorten and permuted copy of \a this array. The new DataArrayInt is
7054  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
7055  * \a new2OldBg array.
7056  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
7057  * This method is equivalent to renumberAndReduce() except that convention in input is
7058  * \c new2old and \b not \c old2new.
7059  * This method is equivalent to selectByTupleId() except that it prevents coping data
7060  * from behind the end of \a this array.
7061  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7062  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
7063  *              tuple index in \a this array to fill the i-th tuple in the new array.
7064  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
7065  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
7066  *              \a new2OldBg <= \a pi < \a new2OldEnd.
7067  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7068  *          is to delete using decrRef() as it is no more needed.
7069  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
7070  */
7071 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
7072 {
7073   checkAllocated();
7074   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7075   int nbComp=getNumberOfComponents();
7076   int oldNbOfTuples=getNumberOfTuples();
7077   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
7078   ret->copyStringInfoFrom(*this);
7079   int *pt=ret->getPointer();
7080   const int *srcPt=getConstPointer();
7081   int i=0;
7082   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
7083     if(*w>=0 && *w<oldNbOfTuples)
7084       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
7085     else
7086       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
7087   ret->copyStringInfoFrom(*this);
7088   return ret.retn();
7089 }
7090
7091 /*!
7092  * Returns a shorten copy of \a this array. The new DataArrayInt contains every
7093  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
7094  * tuple. Indices of the selected tuples are the same as ones returned by the Python
7095  * command \c range( \a bg, \a end2, \a step ).
7096  * This method is equivalent to selectByTupleIdSafe() except that the input array is
7097  * not constructed explicitly.
7098  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7099  *  \param [in] bg - index of the first tuple to copy from \a this array.
7100  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
7101  *  \param [in] step - index increment to get index of the next tuple to copy.
7102  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7103  *          is to delete using decrRef() as it is no more needed.
7104  *  \sa DataArrayInt::substr.
7105  */
7106 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const
7107 {
7108   checkAllocated();
7109   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7110   int nbComp=getNumberOfComponents();
7111   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
7112   ret->alloc(newNbOfTuples,nbComp);
7113   int *pt=ret->getPointer();
7114   const int *srcPt=getConstPointer()+bg*nbComp;
7115   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
7116     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
7117   ret->copyStringInfoFrom(*this);
7118   return ret.retn();
7119 }
7120
7121 /*!
7122  * Returns a shorten copy of \a this array. The new DataArrayInt contains ranges
7123  * of tuples specified by \a ranges parameter.
7124  * For more info on renumbering see \ref MEDCouplingArrayRenumbering.
7125  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
7126  *              of tuples in [\c begin,\c end) format.
7127  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7128  *          is to delete using decrRef() as it is no more needed.
7129  *  \throw If \a end < \a begin.
7130  *  \throw If \a end > \a this->getNumberOfTuples().
7131  *  \throw If \a this is not allocated.
7132  */
7133 DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
7134 {
7135   checkAllocated();
7136   int nbOfComp=getNumberOfComponents();
7137   int nbOfTuplesThis=getNumberOfTuples();
7138   if(ranges.empty())
7139     {
7140       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7141       ret->alloc(0,nbOfComp);
7142       ret->copyStringInfoFrom(*this);
7143       return ret.retn();
7144     }
7145   int ref=ranges.front().first;
7146   int nbOfTuples=0;
7147   bool isIncreasing=true;
7148   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7149     {
7150       if((*it).first<=(*it).second)
7151         {
7152           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
7153             {
7154               nbOfTuples+=(*it).second-(*it).first;
7155               if(isIncreasing)
7156                 isIncreasing=ref<=(*it).first;
7157               ref=(*it).second;
7158             }
7159           else
7160             {
7161               std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7162               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
7163               throw INTERP_KERNEL::Exception(oss.str().c_str());
7164             }
7165         }
7166       else
7167         {
7168           std::ostringstream oss; oss << "DataArrayInt::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
7169           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
7170           throw INTERP_KERNEL::Exception(oss.str().c_str());
7171         }
7172     }
7173   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
7174     return deepCpy();
7175   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7176   ret->alloc(nbOfTuples,nbOfComp);
7177   ret->copyStringInfoFrom(*this);
7178   const int *src=getConstPointer();
7179   int *work=ret->getPointer();
7180   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
7181     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
7182   return ret.retn();
7183 }
7184
7185 /*!
7186  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
7187  * This map, if applied to \a this array, would make it sorted. For example, if
7188  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
7189  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
7190  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
7191  * This method is useful for renumbering (in MED file for example). For more info
7192  * on renumbering see \ref MEDCouplingArrayRenumbering.
7193  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7194  *          array using decrRef() as it is no more needed.
7195  *  \throw If \a this is not allocated.
7196  *  \throw If \a this->getNumberOfComponents() != 1.
7197  *  \throw If there are equal values in \a this array.
7198  */
7199 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
7200 {
7201   checkAllocated();
7202   if(getNumberOfComponents()!=1)
7203     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
7204   int nbTuples=getNumberOfTuples();
7205   const int *pt=getConstPointer();
7206   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
7207   DataArrayInt *ret=DataArrayInt::New();
7208   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
7209   return ret;
7210 }
7211
7212 /*!
7213  * 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
7214  * input array \a ids2.
7215  * \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.
7216  * 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
7217  * inversely.
7218  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
7219  *
7220  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7221  *          array using decrRef() as it is no more needed.
7222  * \throw If either ids1 or ids2 is null not allocated or not with one components.
7223  * 
7224  */
7225 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
7226 {
7227   if(!ids1 || !ids2)
7228     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
7229   if(!ids1->isAllocated() || !ids2->isAllocated())
7230     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
7231   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
7232     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
7233   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
7234     {
7235       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 !";
7236       throw INTERP_KERNEL::Exception(oss.str().c_str());
7237     }
7238   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
7239   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
7240   p1->sort(true); p2->sort(true);
7241   if(!p1->isEqualWithoutConsideringStr(*p2))
7242     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
7243   p1=ids1->checkAndPreparePermutation();
7244   p2=ids2->checkAndPreparePermutation();
7245   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
7246   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
7247   return p2.retn();
7248 }
7249
7250 /*!
7251  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
7252  * onto a set of values of size \a targetNb (\a B). The surjective function is 
7253  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
7254  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
7255  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
7256  * The first of out arrays returns indices of elements of \a this array, grouped by their
7257  * place in the set \a B. The second out array is the index of the first one; it shows how
7258  * many elements of \a A are mapped into each element of \a B. <br>
7259  * For more info on
7260  * mapping and its usage in renumbering see \ref MEDCouplingArrayRenumbering. <br>
7261  * \b Example:
7262  * - \a this: [0,3,2,3,2,2,1,2]
7263  * - \a targetNb: 4
7264  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
7265  * - \a arrI: [0,1,2,6,8]
7266  *
7267  * This result means: <br>
7268  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
7269  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
7270  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
7271  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
7272  * \a arrI[ 2+1 ]]); <br> etc.
7273  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
7274  *         than the maximal value of \a A.
7275  *  \param [out] arr - a new instance of DataArrayInt returning indices of
7276  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
7277  *         this array using decrRef() as it is no more needed.
7278  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
7279  *         elements of \a this. The caller is to delete this array using decrRef() as it
7280  *         is no more needed.
7281  *  \throw If \a this is not allocated.
7282  *  \throw If \a this->getNumberOfComponents() != 1.
7283  *  \throw If any value in \a this is more or equal to \a targetNb.
7284  */
7285 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
7286 {
7287   checkAllocated();
7288   if(getNumberOfComponents()!=1)
7289     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
7290   int nbOfTuples=getNumberOfTuples();
7291   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7292   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New());
7293   retI->alloc(targetNb+1,1);
7294   const int *input=getConstPointer();
7295   std::vector< std::vector<int> > tmp(targetNb);
7296   for(int i=0;i<nbOfTuples;i++)
7297     {
7298       int tmp2=input[i];
7299       if(tmp2>=0 && tmp2<targetNb)
7300         tmp[tmp2].push_back(i);
7301       else
7302         {
7303           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
7304           throw INTERP_KERNEL::Exception(oss.str().c_str());
7305         }
7306     }
7307   int *retIPtr=retI->getPointer();
7308   *retIPtr=0;
7309   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
7310     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
7311   if(nbOfTuples!=retI->getIJ(targetNb,0))
7312     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
7313   ret->alloc(nbOfTuples,1);
7314   int *retPtr=ret->getPointer();
7315   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
7316     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
7317   arr=ret.retn();
7318   arrI=retI.retn();
7319 }
7320
7321
7322 /*!
7323  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
7324  * from a zip representation of a surjective format (returned e.g. by
7325  * \ref ParaMEDMEM::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
7326  * for example). The result array minimizes the permutation. <br>
7327  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7328  * \b Example: <br>
7329  * - \a nbOfOldTuples: 10 
7330  * - \a arr          : [0,3, 5,7,9]
7331  * - \a arrIBg       : [0,2,5]
7332  * - \a newNbOfTuples: 7
7333  * - result array    : [0,1,2,0,3,4,5,4,6,4]
7334  *
7335  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
7336  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
7337  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
7338  *         (indices of) equal values. Its every element (except the last one) points to
7339  *         the first element of a group of equal values.
7340  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
7341  *          arrIBg is \a arrIEnd[ -1 ].
7342  *  \param [out] newNbOfTuples - number of tuples after surjection application.
7343  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7344  *          array using decrRef() as it is no more needed.
7345  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
7346  */
7347 DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
7348 {
7349   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7350   ret->alloc(nbOfOldTuples,1);
7351   int *pt=ret->getPointer();
7352   std::fill(pt,pt+nbOfOldTuples,-1);
7353   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
7354   const int *cIPtr=arrIBg;
7355   for(int i=0;i<nbOfGrps;i++)
7356     pt[arr[cIPtr[i]]]=-(i+2);
7357   int newNb=0;
7358   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
7359     {
7360       if(pt[iNode]<0)
7361         {
7362           if(pt[iNode]==-1)
7363             pt[iNode]=newNb++;
7364           else
7365             {
7366               int grpId=-(pt[iNode]+2);
7367               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
7368                 {
7369                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
7370                     pt[arr[j]]=newNb;
7371                   else
7372                     {
7373                       std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
7374                       throw INTERP_KERNEL::Exception(oss.str().c_str());
7375                     }
7376                 }
7377               newNb++;
7378             }
7379         }
7380     }
7381   newNbOfTuples=newNb;
7382   return ret.retn();
7383 }
7384
7385 /*!
7386  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
7387  * which if applied to \a this array would make it sorted ascendingly.
7388  * For more info on renumbering see \ref MEDCouplingArrayRenumbering. <br>
7389  * \b Example: <br>
7390  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
7391  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
7392  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
7393  *
7394  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7395  *          array using decrRef() as it is no more needed.
7396  *  \throw If \a this is not allocated.
7397  *  \throw If \a this->getNumberOfComponents() != 1.
7398  */
7399 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
7400 {
7401   checkAllocated();
7402   if(getNumberOfComponents()!=1)
7403     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
7404   int nbOfTuples=getNumberOfTuples();
7405   const int *pt=getConstPointer();
7406   std::map<int,int> m;
7407   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7408   ret->alloc(nbOfTuples,1);
7409   int *opt=ret->getPointer();
7410   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7411     {
7412       int val=*pt;
7413       std::map<int,int>::iterator it=m.find(val);
7414       if(it!=m.end())
7415         {
7416           *opt=(*it).second;
7417           (*it).second++;
7418         }
7419       else
7420         {
7421           *opt=0;
7422           m.insert(std::pair<int,int>(val,1));
7423         }
7424     }
7425   int sum=0;
7426   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
7427     {
7428       int vt=(*it).second;
7429       (*it).second=sum;
7430       sum+=vt;
7431     }
7432   pt=getConstPointer();
7433   opt=ret->getPointer();
7434   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
7435     *opt+=m[*pt];
7436   //
7437   return ret.retn();
7438 }
7439
7440 /*!
7441  * Checks if contents of \a this array are equal to that of an array filled with
7442  * iota(). This method is particularly useful for DataArrayInt instances that represent
7443  * a renumbering array to check the real need in renumbering. 
7444  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
7445  *  \throw If \a this is not allocated.
7446  *  \throw If \a this->getNumberOfComponents() != 1.
7447  */
7448 bool DataArrayInt::isIdentity() const
7449 {
7450   checkAllocated();
7451   if(getNumberOfComponents()!=1)
7452     return false;
7453   int nbOfTuples=getNumberOfTuples();
7454   const int *pt=getConstPointer();
7455   for(int i=0;i<nbOfTuples;i++,pt++)
7456     if(*pt!=i)
7457       return false;
7458   return true;
7459 }
7460
7461 /*!
7462  * Checks if all values in \a this array are equal to \a val.
7463  *  \param [in] val - value to check equality of array values to.
7464  *  \return bool - \a true if all values are \a val.
7465  *  \throw If \a this is not allocated.
7466  *  \throw If \a this->getNumberOfComponents() != 1
7467  */
7468 bool DataArrayInt::isUniform(int val) const
7469 {
7470   checkAllocated();
7471   if(getNumberOfComponents()!=1)
7472     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
7473   int nbOfTuples=getNumberOfTuples();
7474   const int *w=getConstPointer();
7475   const int *end2=w+nbOfTuples;
7476   for(;w!=end2;w++)
7477     if(*w!=val)
7478       return false;
7479   return true;
7480 }
7481
7482 /*!
7483  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
7484  * array to the new one.
7485  *  \return DataArrayDouble * - the new instance of DataArrayInt.
7486  */
7487 DataArrayDouble *DataArrayInt::convertToDblArr() const
7488 {
7489   checkAllocated();
7490   DataArrayDouble *ret=DataArrayDouble::New();
7491   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
7492   std::size_t nbOfVals=getNbOfElems();
7493   const int *src=getConstPointer();
7494   double *dest=ret->getPointer();
7495   std::copy(src,src+nbOfVals,dest);
7496   ret->copyStringInfoFrom(*this);
7497   return ret;
7498 }
7499
7500 /*!
7501  * Returns a shorten copy of \a this array. The new DataArrayInt contains all
7502  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
7503  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::substr().
7504  * This method is a specialization of selectByTupleId2().
7505  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
7506  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
7507  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
7508  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7509  *          is to delete using decrRef() as it is no more needed.
7510  *  \throw If \a tupleIdBg < 0.
7511  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
7512     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
7513  *  \sa DataArrayInt::selectByTupleId2
7514  */
7515 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const
7516 {
7517   checkAllocated();
7518   int nbt=getNumberOfTuples();
7519   if(tupleIdBg<0)
7520     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
7521   if(tupleIdBg>nbt)
7522     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !");
7523   int trueEnd=tupleIdEnd;
7524   if(tupleIdEnd!=-1)
7525     {
7526       if(tupleIdEnd>nbt)
7527         throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
7528     }
7529   else
7530     trueEnd=nbt;
7531   int nbComp=getNumberOfComponents();
7532   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7533   ret->alloc(trueEnd-tupleIdBg,nbComp);
7534   ret->copyStringInfoFrom(*this);
7535   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
7536   return ret.retn();
7537 }
7538
7539 /*!
7540  * Changes the number of components within \a this array so that its raw data **does
7541  * not** change, instead splitting this data into tuples changes.
7542  *  \warning This method erases all (name and unit) component info set before!
7543  *  \param [in] newNbOfComp - number of components for \a this array to have.
7544  *  \throw If \a this is not allocated
7545  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
7546  *  \throw If \a newNbOfCompo is lower than 1.
7547  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
7548  *  \warning This method erases all (name and unit) component info set before!
7549  */
7550 void DataArrayInt::rearrange(int newNbOfCompo)
7551 {
7552   checkAllocated();
7553   if(newNbOfCompo<1)
7554     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : input newNbOfCompo must be > 0 !");
7555   std::size_t nbOfElems=getNbOfElems();
7556   if(nbOfElems%newNbOfCompo!=0)
7557     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
7558   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
7559     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
7560   _info_on_compo.clear();
7561   _info_on_compo.resize(newNbOfCompo);
7562   declareAsNew();
7563 }
7564
7565 /*!
7566  * Changes the number of components within \a this array to be equal to its number
7567  * of tuples, and inversely its number of tuples to become equal to its number of 
7568  * components. So that its raw data **does not** change, instead splitting this
7569  * data into tuples changes.
7570  *  \warning This method erases all (name and unit) component info set before!
7571  *  \warning Do not confuse this method with fromNoInterlace() and toNoInterlace()!
7572  *  \throw If \a this is not allocated.
7573  *  \sa rearrange()
7574  */
7575 void DataArrayInt::transpose()
7576 {
7577   checkAllocated();
7578   int nbOfTuples=getNumberOfTuples();
7579   rearrange(nbOfTuples);
7580 }
7581
7582 /*!
7583  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
7584  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
7585  * is truncated to have \a newNbOfComp components, keeping first components. If \a
7586  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
7587  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
7588  * components.  
7589  *  \param [in] newNbOfComp - number of components for the new array to have.
7590  *  \param [in] dftValue - value assigned to new values added to the new array.
7591  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
7592  *          is to delete using decrRef() as it is no more needed.
7593  *  \throw If \a this is not allocated.
7594  */
7595 DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const
7596 {
7597   checkAllocated();
7598   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
7599   ret->alloc(getNumberOfTuples(),newNbOfComp);
7600   const int *oldc=getConstPointer();
7601   int *nc=ret->getPointer();
7602   int nbOfTuples=getNumberOfTuples();
7603   int oldNbOfComp=getNumberOfComponents();
7604   int dim=std::min(oldNbOfComp,newNbOfComp);
7605   for(int i=0;i<nbOfTuples;i++)
7606     {
7607       int j=0;
7608       for(;j<dim;j++)
7609         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
7610       for(;j<newNbOfComp;j++)
7611         nc[newNbOfComp*i+j]=dftValue;
7612     }
7613   ret->setName(getName());
7614   for(int i=0;i<dim;i++)
7615     ret->setInfoOnComponent(i,getInfoOnComponent(i));
7616   ret->setName(getName());
7617   return ret.retn();
7618 }
7619
7620 /*!
7621  * Changes number of tuples in the array. If the new number of tuples is smaller
7622  * than the current number the array is truncated, otherwise the array is extended.
7623  *  \param [in] nbOfTuples - new number of tuples. 
7624  *  \throw If \a this is not allocated.
7625  *  \throw If \a nbOfTuples is negative.
7626  */
7627 void DataArrayInt::reAlloc(int nbOfTuples)
7628 {
7629   if(nbOfTuples<0)
7630     throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
7631   checkAllocated();
7632   _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
7633   declareAsNew();
7634 }
7635
7636
7637 /*!
7638  * Returns a copy of \a this array composed of selected components.
7639  * The new DataArrayInt has the same number of tuples but includes components
7640  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
7641  * can be either less, same or more than \a this->getNbOfElems().
7642  *  \param [in] compoIds - sequence of zero based indices of components to include
7643  *              into the new array.
7644  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
7645  *          is to delete using decrRef() as it is no more needed.
7646  *  \throw If \a this is not allocated.
7647  *  \throw If a component index (\a i) is not valid: 
7648  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
7649  *
7650  *  \if ENABLE_EXAMPLES
7651  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
7652  *  \endif
7653  */
7654 DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
7655 {
7656   checkAllocated();
7657   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
7658   int newNbOfCompo=(int)compoIds.size();
7659   int oldNbOfCompo=getNumberOfComponents();
7660   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
7661     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
7662   int nbOfTuples=getNumberOfTuples();
7663   ret->alloc(nbOfTuples,newNbOfCompo);
7664   ret->copyPartOfStringInfoFrom(*this,compoIds);
7665   const int *oldc=getConstPointer();
7666   int *nc=ret->getPointer();
7667   for(int i=0;i<nbOfTuples;i++)
7668     for(int j=0;j<newNbOfCompo;j++,nc++)
7669       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
7670   return ret.retn();
7671 }
7672
7673 /*!
7674  * Appends components of another array to components of \a this one, tuple by tuple.
7675  * So that the number of tuples of \a this array remains the same and the number of 
7676  * components increases.
7677  *  \param [in] other - the DataArrayInt to append to \a this one.
7678  *  \throw If \a this is not allocated.
7679  *  \throw If \a this and \a other arrays have different number of tuples.
7680  *
7681  *  \if ENABLE_EXAMPLES
7682  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
7683  *
7684  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
7685  *  \endif
7686  */
7687 void DataArrayInt::meldWith(const DataArrayInt *other)
7688 {
7689   if(!other)
7690     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
7691   checkAllocated();
7692   other->checkAllocated();
7693   int nbOfTuples=getNumberOfTuples();
7694   if(nbOfTuples!=other->getNumberOfTuples())
7695     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
7696   int nbOfComp1=getNumberOfComponents();
7697   int nbOfComp2=other->getNumberOfComponents();
7698   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
7699   int *w=newArr;
7700   const int *inp1=getConstPointer();
7701   const int *inp2=other->getConstPointer();
7702   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
7703     {
7704       w=std::copy(inp1,inp1+nbOfComp1,w);
7705       w=std::copy(inp2,inp2+nbOfComp2,w);
7706     }
7707   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
7708   std::vector<int> compIds(nbOfComp2);
7709   for(int i=0;i<nbOfComp2;i++)
7710     compIds[i]=nbOfComp1+i;
7711   copyPartOfStringInfoFrom2(compIds,*other);
7712 }
7713
7714 /*!
7715  * Copy all components in a specified order from another DataArrayInt.
7716  * The specified components become the first ones in \a this array.
7717  * Both numerical and textual data is copied. The number of tuples in \a this and
7718  * the other array can be different.
7719  *  \param [in] a - the array to copy data from.
7720  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
7721  *              to be copied.
7722  *  \throw If \a a is NULL.
7723  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
7724  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
7725  *
7726  *  \if ENABLE_EXAMPLES
7727  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
7728  *  \endif
7729  */
7730 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
7731 {
7732   if(!a)
7733     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
7734   checkAllocated();
7735   a->checkAllocated();
7736   copyPartOfStringInfoFrom2(compoIds,*a);
7737   std::size_t partOfCompoSz=compoIds.size();
7738   int nbOfCompo=getNumberOfComponents();
7739   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
7740   const int *ac=a->getConstPointer();
7741   int *nc=getPointer();
7742   for(int i=0;i<nbOfTuples;i++)
7743     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
7744       nc[nbOfCompo*i+compoIds[j]]=*ac;
7745 }
7746
7747 /*!
7748  * Copy all values from another DataArrayInt into specified tuples and components
7749  * of \a this array. Textual data is not copied.
7750  * The tree parameters defining set of indices of tuples and components are similar to
7751  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
7752  *  \param [in] a - the array to copy values from.
7753  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
7754  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7755  *              are located.
7756  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7757  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
7758  *  \param [in] endComp - index of the component before which the components to assign
7759  *              to are located.
7760  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7761  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
7762  *              must be equal to the number of columns to assign to, else an
7763  *              exception is thrown; if \a false, then it is only required that \a
7764  *              a->getNbOfElems() equals to number of values to assign to (this condition
7765  *              must be respected even if \a strictCompoCompare is \a true). The number of 
7766  *              values to assign to is given by following Python expression:
7767  *              \a nbTargetValues = 
7768  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
7769  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7770  *  \throw If \a a is NULL.
7771  *  \throw If \a a is not allocated.
7772  *  \throw If \a this is not allocated.
7773  *  \throw If parameters specifying tuples and components to assign to do not give a
7774  *            non-empty range of increasing indices.
7775  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
7776  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
7777  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
7778  *
7779  *  \if ENABLE_EXAMPLES
7780  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
7781  *  \endif
7782  */
7783 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
7784 {
7785   if(!a)
7786     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !");
7787   const char msg[]="DataArrayInt::setPartOfValues1";
7788   checkAllocated();
7789   a->checkAllocated();
7790   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7791   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7792   int nbComp=getNumberOfComponents();
7793   int nbOfTuples=getNumberOfTuples();
7794   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7795   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7796   bool assignTech=true;
7797   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7798     {
7799       if(strictCompoCompare)
7800         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7801     }
7802   else
7803     {
7804       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7805       assignTech=false;
7806     }
7807   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7808   const int *srcPt=a->getConstPointer();
7809   if(assignTech)
7810     {
7811       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7812         for(int j=0;j<newNbOfComp;j++,srcPt++)
7813           pt[j*stepComp]=*srcPt;
7814     }
7815   else
7816     {
7817       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7818         {
7819           const int *srcPt2=srcPt;
7820           for(int j=0;j<newNbOfComp;j++,srcPt2++)
7821             pt[j*stepComp]=*srcPt2;
7822         }
7823     }
7824 }
7825
7826 /*!
7827  * Assign a given value to values at specified tuples and components of \a this array.
7828  * The tree parameters defining set of indices of tuples and components are similar to
7829  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
7830  *  \param [in] a - the value to assign.
7831  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
7832  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
7833  *              are located.
7834  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
7835  *  \param [in] bgComp - index of the first component of \a this array to assign to.
7836  *  \param [in] endComp - index of the component before which the components to assign
7837  *              to are located.
7838  *  \param [in] stepComp - index increment to get index of the next component to assign to.
7839  *  \throw If \a this is not allocated.
7840  *  \throw If parameters specifying tuples and components to assign to, do not give a
7841  *            non-empty range of increasing indices or indices are out of a valid range
7842  *            for \this array.
7843  *
7844  *  \if ENABLE_EXAMPLES
7845  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
7846  *  \endif
7847  */
7848 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
7849 {
7850   const char msg[]="DataArrayInt::setPartOfValuesSimple1";
7851   checkAllocated();
7852   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
7853   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
7854   int nbComp=getNumberOfComponents();
7855   int nbOfTuples=getNumberOfTuples();
7856   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
7857   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
7858   int *pt=getPointer()+bgTuples*nbComp+bgComp;
7859   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
7860     for(int j=0;j<newNbOfComp;j++)
7861       pt[j*stepComp]=a;
7862 }
7863
7864
7865 /*!
7866  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7867  * components of \a this array. Textual data is not copied.
7868  * The tuples and components to assign to are defined by C arrays of indices.
7869  * There are two *modes of usage*:
7870  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
7871  *   of \a a is assigned to its own location within \a this array. 
7872  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
7873  *   components of every specified tuple of \a this array. In this mode it is required
7874  *   that \a a->getNumberOfComponents() equals to the number of specified components.
7875  * 
7876  *  \param [in] a - the array to copy values from.
7877  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7878  *              assign values of \a a to.
7879  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7880  *              pointer to a tuple index <em>(pi)</em> varies as this: 
7881  *              \a bgTuples <= \a pi < \a endTuples.
7882  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7883  *              assign values of \a a to.
7884  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7885  *              pointer to a component index <em>(pi)</em> varies as this: 
7886  *              \a bgComp <= \a pi < \a endComp.
7887  *  \param [in] strictCompoCompare - this parameter is checked only if the
7888  *               *mode of usage* is the first; if it is \a true (default), 
7889  *               then \a a->getNumberOfComponents() must be equal 
7890  *               to the number of specified columns, else this is not required.
7891  *  \throw If \a a is NULL.
7892  *  \throw If \a a is not allocated.
7893  *  \throw If \a this is not allocated.
7894  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7895  *         out of a valid range for \a this array.
7896  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
7897  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
7898  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
7899  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
7900  *
7901  *  \if ENABLE_EXAMPLES
7902  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
7903  *  \endif
7904  */
7905 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
7906 {
7907   if(!a)
7908     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !");
7909   const char msg[]="DataArrayInt::setPartOfValues2";
7910   checkAllocated();
7911   a->checkAllocated();
7912   int nbComp=getNumberOfComponents();
7913   int nbOfTuples=getNumberOfTuples();
7914   for(const int *z=bgComp;z!=endComp;z++)
7915     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7916   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
7917   int newNbOfComp=(int)std::distance(bgComp,endComp);
7918   bool assignTech=true;
7919   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
7920     {
7921       if(strictCompoCompare)
7922         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
7923     }
7924   else
7925     {
7926       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
7927       assignTech=false;
7928     }
7929   int *pt=getPointer();
7930   const int *srcPt=a->getConstPointer();
7931   if(assignTech)
7932     {    
7933       for(const int *w=bgTuples;w!=endTuples;w++)
7934         {
7935           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7936           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
7937             {    
7938               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
7939             }
7940         }
7941     }
7942   else
7943     {
7944       for(const int *w=bgTuples;w!=endTuples;w++)
7945         {
7946           const int *srcPt2=srcPt;
7947           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7948           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
7949             {    
7950               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
7951             }
7952         }
7953     }
7954 }
7955
7956 /*!
7957  * Assign a given value to values at specified tuples and components of \a this array.
7958  * The tuples and components to assign to are defined by C arrays of indices.
7959  *  \param [in] a - the value to assign.
7960  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
7961  *              assign \a a to.
7962  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
7963  *              pointer to a tuple index (\a pi) varies as this: 
7964  *              \a bgTuples <= \a pi < \a endTuples.
7965  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
7966  *              assign \a a to.
7967  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
7968  *              pointer to a component index (\a pi) varies as this: 
7969  *              \a bgComp <= \a pi < \a endComp.
7970  *  \throw If \a this is not allocated.
7971  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
7972  *         out of a valid range for \a this array.
7973  *
7974  *  \if ENABLE_EXAMPLES
7975  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
7976  *  \endif
7977  */
7978 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
7979 {
7980   checkAllocated();
7981   int nbComp=getNumberOfComponents();
7982   int nbOfTuples=getNumberOfTuples();
7983   for(const int *z=bgComp;z!=endComp;z++)
7984     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
7985   int *pt=getPointer();
7986   for(const int *w=bgTuples;w!=endTuples;w++)
7987     for(const int *z=bgComp;z!=endComp;z++)
7988       {
7989         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
7990         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
7991       }
7992 }
7993
7994 /*!
7995  * Copy all values from another DataArrayInt (\a a) into specified tuples and 
7996  * components of \a this array. Textual data is not copied.
7997  * The tuples to assign to are defined by a C array of indices.
7998  * The components to assign to are defined by three values similar to parameters of
7999  * the Python function \c range(\c start,\c stop,\c step).
8000  * There are two *modes of usage*:
8001  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
8002  *   of \a a is assigned to its own location within \a this array. 
8003  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
8004  *   components of every specified tuple of \a this array. In this mode it is required
8005  *   that \a a->getNumberOfComponents() equals to the number of specified components.
8006  *
8007  *  \param [in] a - the array to copy values from.
8008  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8009  *              assign values of \a a to.
8010  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8011  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8012  *              \a bgTuples <= \a pi < \a endTuples.
8013  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8014  *  \param [in] endComp - index of the component before which the components to assign
8015  *              to are located.
8016  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8017  *  \param [in] strictCompoCompare - this parameter is checked only in the first
8018  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
8019  *               then \a a->getNumberOfComponents() must be equal 
8020  *               to the number of specified columns, else this is not required.
8021  *  \throw If \a a is NULL.
8022  *  \throw If \a a is not allocated.
8023  *  \throw If \a this is not allocated.
8024  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8025  *         \a this array.
8026  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
8027  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
8028  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8029  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
8030  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
8031  *         defined by <em>(bgComp,endComp,stepComp)</em>.
8032  *  \throw If parameters specifying components to assign to, do not give a
8033  *            non-empty range of increasing indices or indices are out of a valid range
8034  *            for \this array.
8035  *
8036  *  \if ENABLE_EXAMPLES
8037  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
8038  *  \endif
8039  */
8040 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
8041 {
8042   if(!a)
8043     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !");
8044   const char msg[]="DataArrayInt::setPartOfValues3";
8045   checkAllocated();
8046   a->checkAllocated();
8047   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8048   int nbComp=getNumberOfComponents();
8049   int nbOfTuples=getNumberOfTuples();
8050   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8051   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
8052   bool assignTech=true;
8053   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8054     {
8055       if(strictCompoCompare)
8056         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8057     }
8058   else
8059     {
8060       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8061       assignTech=false;
8062     }
8063   int *pt=getPointer()+bgComp;
8064   const int *srcPt=a->getConstPointer();
8065   if(assignTech)
8066     {
8067       for(const int *w=bgTuples;w!=endTuples;w++)
8068         for(int j=0;j<newNbOfComp;j++,srcPt++)
8069           {
8070             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8071             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
8072           }
8073     }
8074   else
8075     {
8076       for(const int *w=bgTuples;w!=endTuples;w++)
8077         {
8078           const int *srcPt2=srcPt;
8079           for(int j=0;j<newNbOfComp;j++,srcPt2++)
8080             {
8081               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8082               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
8083             }
8084         }
8085     }
8086 }
8087
8088 /*!
8089  * Assign a given value to values at specified tuples and components of \a this array.
8090  * The tuples to assign to are defined by a C array of indices.
8091  * The components to assign to are defined by three values similar to parameters of
8092  * the Python function \c range(\c start,\c stop,\c step).
8093  *  \param [in] a - the value to assign.
8094  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
8095  *              assign \a a to.
8096  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
8097  *              pointer to a tuple index <em>(pi)</em> varies as this: 
8098  *              \a bgTuples <= \a pi < \a endTuples.
8099  *  \param [in] bgComp - index of the first component of \a this array to assign to.
8100  *  \param [in] endComp - index of the component before which the components to assign
8101  *              to are located.
8102  *  \param [in] stepComp - index increment to get index of the next component to assign to.
8103  *  \throw If \a this is not allocated.
8104  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
8105  *         \a this array.
8106  *  \throw If parameters specifying components to assign to, do not give a
8107  *            non-empty range of increasing indices or indices are out of a valid range
8108  *            for \this array.
8109  *
8110  *  \if ENABLE_EXAMPLES
8111  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
8112  *  \endif
8113  */
8114 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
8115 {
8116   const char msg[]="DataArrayInt::setPartOfValuesSimple3";
8117   checkAllocated();
8118   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
8119   int nbComp=getNumberOfComponents();
8120   int nbOfTuples=getNumberOfTuples();
8121   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
8122   int *pt=getPointer()+bgComp;
8123   for(const int *w=bgTuples;w!=endTuples;w++)
8124     for(int j=0;j<newNbOfComp;j++)
8125       {
8126         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
8127         pt[(std::size_t)(*w)*nbComp+j*stepComp]=a;
8128       }
8129 }
8130
8131 void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
8132 {
8133   if(!a)
8134     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
8135   const char msg[]="DataArrayInt::setPartOfValues4";
8136   checkAllocated();
8137   a->checkAllocated();
8138   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8139   int newNbOfComp=(int)std::distance(bgComp,endComp);
8140   int nbComp=getNumberOfComponents();
8141   for(const int *z=bgComp;z!=endComp;z++)
8142     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8143   int nbOfTuples=getNumberOfTuples();
8144   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8145   bool assignTech=true;
8146   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
8147     {
8148       if(strictCompoCompare)
8149         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
8150     }
8151   else
8152     {
8153       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
8154       assignTech=false;
8155     }
8156   const int *srcPt=a->getConstPointer();
8157   int *pt=getPointer()+bgTuples*nbComp;
8158   if(assignTech)
8159     {
8160       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8161         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
8162           pt[*z]=*srcPt;
8163     }
8164   else
8165     {
8166       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8167         {
8168           const int *srcPt2=srcPt;
8169           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
8170             pt[*z]=*srcPt2;
8171         }
8172     }
8173 }
8174
8175 void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
8176 {
8177   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
8178   checkAllocated();
8179   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
8180   int nbComp=getNumberOfComponents();
8181   for(const int *z=bgComp;z!=endComp;z++)
8182     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
8183   int nbOfTuples=getNumberOfTuples();
8184   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
8185   int *pt=getPointer()+bgTuples*nbComp;
8186   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
8187     for(const int *z=bgComp;z!=endComp;z++)
8188       pt[*z]=a;
8189 }
8190
8191 /*!
8192  * Copy some tuples from another DataArrayInt into specified tuples
8193  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8194  * components.
8195  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt.
8196  * All components of selected tuples are copied.
8197  *  \param [in] a - the array to copy values from.
8198  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
8199  *              target tuples of \a this. \a tuplesSelec has two components, and the
8200  *              first component specifies index of the source tuple and the second
8201  *              one specifies index of the target tuple.
8202  *  \throw If \a this is not allocated.
8203  *  \throw If \a a is NULL.
8204  *  \throw If \a a is not allocated.
8205  *  \throw If \a tuplesSelec is NULL.
8206  *  \throw If \a tuplesSelec is not allocated.
8207  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8208  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
8209  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8210  *         the corresponding (\a this or \a a) array.
8211  */
8212 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec)
8213 {
8214   if(!a || !tuplesSelec)
8215     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
8216   checkAllocated();
8217   a->checkAllocated();
8218   tuplesSelec->checkAllocated();
8219   int nbOfComp=getNumberOfComponents();
8220   if(nbOfComp!=a->getNumberOfComponents())
8221     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !");
8222   if(tuplesSelec->getNumberOfComponents()!=2)
8223     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !");
8224   int thisNt=getNumberOfTuples();
8225   int aNt=a->getNumberOfTuples();
8226   int *valsToSet=getPointer();
8227   const int *valsSrc=a->getConstPointer();
8228   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
8229     {
8230       if(tuple[1]>=0 && tuple[1]<aNt)
8231         {
8232           if(tuple[0]>=0 && tuple[0]<thisNt)
8233             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
8234           else
8235             {
8236               std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8237               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
8238               throw INTERP_KERNEL::Exception(oss.str().c_str());
8239             }
8240         }
8241       else
8242         {
8243           std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
8244           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
8245           throw INTERP_KERNEL::Exception(oss.str().c_str());
8246         }
8247     }
8248 }
8249
8250 /*!
8251  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8252  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8253  * components.
8254  * The tuples to assign to are defined by index of the first tuple, and
8255  * their number is defined by \a tuplesSelec->getNumberOfTuples().
8256  * The tuples to copy are defined by values of a DataArrayInt.
8257  * All components of selected tuples are copied.
8258  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8259  *              values to.
8260  *  \param [in] aBase - the array to copy values from.
8261  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
8262  *  \throw If \a this is not allocated.
8263  *  \throw If \a aBase is NULL.
8264  *  \throw If \a aBase is not allocated.
8265  *  \throw If \a tuplesSelec is NULL.
8266  *  \throw If \a tuplesSelec is not allocated.
8267  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
8268  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
8269  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
8270  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
8271  *         \a aBase array.
8272  */
8273 void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
8274 {
8275   if(!aBase || !tuplesSelec)
8276     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !");
8277   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8278   if(!a)
8279     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !");
8280   checkAllocated();
8281   a->checkAllocated();
8282   tuplesSelec->checkAllocated();
8283   int nbOfComp=getNumberOfComponents();
8284   if(nbOfComp!=a->getNumberOfComponents())
8285     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !");
8286   if(tuplesSelec->getNumberOfComponents()!=1)
8287     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !");
8288   int thisNt=getNumberOfTuples();
8289   int aNt=a->getNumberOfTuples();
8290   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
8291   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8292   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8293     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !");
8294   const int *valsSrc=a->getConstPointer();
8295   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
8296     {
8297       if(*tuple>=0 && *tuple<aNt)
8298         {
8299           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
8300         }
8301       else
8302         {
8303           std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
8304           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
8305           throw INTERP_KERNEL::Exception(oss.str().c_str());
8306         }
8307     }
8308 }
8309
8310 /*!
8311  * Copy some tuples from another DataArrayInt (\a aBase) into contiguous tuples
8312  * of \a this array. Textual data is not copied. Both arrays must have equal number of
8313  * components.
8314  * The tuples to copy are defined by three values similar to parameters of
8315  * the Python function \c range(\c start,\c stop,\c step).
8316  * The tuples to assign to are defined by index of the first tuple, and
8317  * their number is defined by number of tuples to copy.
8318  * All components of selected tuples are copied.
8319  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
8320  *              values to.
8321  *  \param [in] aBase - the array to copy values from.
8322  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
8323  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
8324  *              are located.
8325  *  \param [in] step - index increment to get index of the next tuple to copy.
8326  *  \throw If \a this is not allocated.
8327  *  \throw If \a aBase is NULL.
8328  *  \throw If \a aBase is not allocated.
8329  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
8330  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
8331  *  \throw If parameters specifying tuples to copy, do not give a
8332  *            non-empty range of increasing indices or indices are out of a valid range
8333  *            for the array \a aBase.
8334  */
8335 void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
8336 {
8337   if(!aBase)
8338     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !");
8339   const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase);
8340   if(!a)
8341     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !");
8342   checkAllocated();
8343   a->checkAllocated();
8344   int nbOfComp=getNumberOfComponents();
8345   const char msg[]="DataArrayInt::setContigPartOfSelectedValues2";
8346   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
8347   if(nbOfComp!=a->getNumberOfComponents())
8348     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !");
8349   int thisNt=getNumberOfTuples();
8350   int aNt=a->getNumberOfTuples();
8351   int *valsToSet=getPointer()+tupleIdStart*nbOfComp;
8352   if(tupleIdStart+nbOfTupleToWrite>thisNt)
8353     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !");
8354   if(end2>aNt)
8355     throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !");
8356   const int *valsSrc=a->getConstPointer()+bg*nbOfComp;
8357   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
8358     {
8359       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
8360     }
8361 }
8362
8363 /*!
8364  * Returns a value located at specified tuple and component.
8365  * This method is equivalent to DataArrayInt::getIJ() except that validity of
8366  * parameters is checked. So this method is safe but expensive if used to go through
8367  * all values of \a this.
8368  *  \param [in] tupleId - index of tuple of interest.
8369  *  \param [in] compoId - index of component of interest.
8370  *  \return double - value located by \a tupleId and \a compoId.
8371  *  \throw If \a this is not allocated.
8372  *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
8373  *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
8374  */
8375 int DataArrayInt::getIJSafe(int tupleId, int compoId) const
8376 {
8377   checkAllocated();
8378   if(tupleId<0 || tupleId>=getNumberOfTuples())
8379     {
8380       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
8381       throw INTERP_KERNEL::Exception(oss.str().c_str());
8382     }
8383   if(compoId<0 || compoId>=getNumberOfComponents())
8384     {
8385       std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
8386       throw INTERP_KERNEL::Exception(oss.str().c_str());
8387     }
8388   return _mem[tupleId*_info_on_compo.size()+compoId];
8389 }
8390
8391 /*!
8392  * Returns the first value of \a this. 
8393  *  \return int - the last value of \a this array.
8394  *  \throw If \a this is not allocated.
8395  *  \throw If \a this->getNumberOfComponents() != 1.
8396  *  \throw If \a this->getNumberOfTuples() < 1.
8397  */
8398 int DataArrayInt::front() const
8399 {
8400   checkAllocated();
8401   if(getNumberOfComponents()!=1)
8402     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
8403   int nbOfTuples=getNumberOfTuples();
8404   if(nbOfTuples<1)
8405     throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
8406   return *(getConstPointer());
8407 }
8408
8409 /*!
8410  * Returns the last value of \a this. 
8411  *  \return int - the last value of \a this array.
8412  *  \throw If \a this is not allocated.
8413  *  \throw If \a this->getNumberOfComponents() != 1.
8414  *  \throw If \a this->getNumberOfTuples() < 1.
8415  */
8416 int DataArrayInt::back() const
8417 {
8418   checkAllocated();
8419   if(getNumberOfComponents()!=1)
8420     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !");
8421   int nbOfTuples=getNumberOfTuples();
8422   if(nbOfTuples<1)
8423     throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !");
8424   return *(getConstPointer()+nbOfTuples-1);
8425 }
8426
8427 /*!
8428  * Assign pointer to one array to a pointer to another appay. Reference counter of
8429  * \a arrayToSet is incremented / decremented.
8430  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
8431  *  \param [in,out] arrayToSet - the pointer to array to assign to.
8432  */
8433 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
8434 {
8435   if(newArray!=arrayToSet)
8436     {
8437       if(arrayToSet)
8438         arrayToSet->decrRef();
8439       arrayToSet=newArray;
8440       if(arrayToSet)
8441         arrayToSet->incrRef();
8442     }
8443 }
8444
8445 DataArrayIntIterator *DataArrayInt::iterator()
8446 {
8447   return new DataArrayIntIterator(this);
8448 }
8449
8450 /*!
8451  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
8452  * given one.
8453  *  \param [in] val - the value to find within \a this.
8454  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8455  *          array using decrRef() as it is no more needed.
8456  *  \throw If \a this is not allocated.
8457  *  \throw If \a this->getNumberOfComponents() != 1.
8458  *  \sa DataArrayInt::getIdsEqualTuple
8459  */
8460 DataArrayInt *DataArrayInt::getIdsEqual(int val) const
8461 {
8462   checkAllocated();
8463   if(getNumberOfComponents()!=1)
8464     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
8465   const int *cptr(getConstPointer());
8466   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8467   int nbOfTuples=getNumberOfTuples();
8468   for(int i=0;i<nbOfTuples;i++,cptr++)
8469     if(*cptr==val)
8470       ret->pushBackSilent(i);
8471   return ret.retn();
8472 }
8473
8474 /*!
8475  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
8476  * equal to a given one. 
8477  *  \param [in] val - the value to ignore within \a this.
8478  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8479  *          array using decrRef() as it is no more needed.
8480  *  \throw If \a this is not allocated.
8481  *  \throw If \a this->getNumberOfComponents() != 1.
8482  */
8483 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const
8484 {
8485   checkAllocated();
8486   if(getNumberOfComponents()!=1)
8487     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
8488   const int *cptr(getConstPointer());
8489   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8490   int nbOfTuples=getNumberOfTuples();
8491   for(int i=0;i<nbOfTuples;i++,cptr++)
8492     if(*cptr!=val)
8493       ret->pushBackSilent(i);
8494   return ret.retn();
8495 }
8496
8497 /*!
8498  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
8499  * This method is an extension of  DataArrayInt::getIdsEqual method.
8500  *
8501  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
8502  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
8503  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8504  *          array using decrRef() as it is no more needed.
8505  *  \throw If \a this is not allocated.
8506  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
8507  * \throw If \a this->getNumberOfComponents() is equal to 0.
8508  * \sa DataArrayInt::getIdsEqual
8509  */
8510 DataArrayInt *DataArrayInt::getIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
8511 {
8512   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
8513   checkAllocated();
8514   if(getNumberOfComponents()!=(int)nbOfCompoExp)
8515     {
8516       std::ostringstream oss; oss << "DataArrayInt::getIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
8517       throw INTERP_KERNEL::Exception(oss.str().c_str());
8518     }
8519   if(nbOfCompoExp==0)
8520     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualTuple : number of components should be > 0 !");
8521   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8522   const int *bg(begin()),*end2(end()),*work(begin());
8523   while(work!=end2)
8524     {
8525       work=std::search(work,end2,tupleBg,tupleEnd);
8526       if(work!=end2)
8527         {
8528           std::size_t pos(std::distance(bg,work));
8529           if(pos%nbOfCompoExp==0)
8530             ret->pushBackSilent(pos/nbOfCompoExp);
8531           work++;
8532         }
8533     }
8534   return ret.retn();
8535 }
8536
8537 /*!
8538  * Assigns \a newValue to all elements holding \a oldValue within \a this
8539  * one-dimensional array.
8540  *  \param [in] oldValue - the value to replace.
8541  *  \param [in] newValue - the value to assign.
8542  *  \return int - number of replacements performed.
8543  *  \throw If \a this is not allocated.
8544  *  \throw If \a this->getNumberOfComponents() != 1.
8545  */
8546 int DataArrayInt::changeValue(int oldValue, int newValue)
8547 {
8548   checkAllocated();
8549   if(getNumberOfComponents()!=1)
8550     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
8551   int *start=getPointer();
8552   int *end2=start+getNbOfElems();
8553   int ret=0;
8554   for(int *val=start;val!=end2;val++)
8555     {
8556       if(*val==oldValue)
8557         {
8558           *val=newValue;
8559           ret++;
8560         }
8561     }
8562   return ret;
8563 }
8564
8565 /*!
8566  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
8567  * one of given values.
8568  *  \param [in] valsBg - an array of values to find within \a this array.
8569  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8570  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8571  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8572  *          array using decrRef() as it is no more needed.
8573  *  \throw If \a this->getNumberOfComponents() != 1.
8574  */
8575 DataArrayInt *DataArrayInt::getIdsEqualList(const int *valsBg, const int *valsEnd) const
8576 {
8577   if(getNumberOfComponents()!=1)
8578     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
8579   std::set<int> vals2(valsBg,valsEnd);
8580   const int *cptr=getConstPointer();
8581   std::vector<int> res;
8582   int nbOfTuples=getNumberOfTuples();
8583   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8584   for(int i=0;i<nbOfTuples;i++,cptr++)
8585     if(vals2.find(*cptr)!=vals2.end())
8586       ret->pushBackSilent(i);
8587   return ret.retn();
8588 }
8589
8590 /*!
8591  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
8592  * equal to any of given values.
8593  *  \param [in] valsBg - an array of values to ignore within \a this array.
8594  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
8595  *              the last value of \a valsBg is \a valsEnd[ -1 ].
8596  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
8597  *          array using decrRef() as it is no more needed.
8598  *  \throw If \a this->getNumberOfComponents() != 1.
8599  */
8600 DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *valsEnd) const
8601 {
8602   if(getNumberOfComponents()!=1)
8603     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
8604   std::set<int> vals2(valsBg,valsEnd);
8605   const int *cptr=getConstPointer();
8606   std::vector<int> res;
8607   int nbOfTuples=getNumberOfTuples();
8608   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
8609   for(int i=0;i<nbOfTuples;i++,cptr++)
8610     if(vals2.find(*cptr)==vals2.end())
8611       ret->pushBackSilent(i);
8612   return ret.retn();
8613 }
8614
8615 /*!
8616  * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt with
8617  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8618  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8619  * If any the tuple id is returned. If not -1 is returned.
8620  * 
8621  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8622  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8623  *
8624  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
8625  * \sa DataArrayInt::search, DataArrayInt::presenceOfTuple.
8626  */
8627 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const
8628 {
8629   checkAllocated();
8630   int nbOfCompo=getNumberOfComponents();
8631   if(nbOfCompo==0)
8632     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
8633   if(nbOfCompo!=(int)tupl.size())
8634     {
8635       std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
8636       throw INTERP_KERNEL::Exception(oss.str().c_str());
8637     }
8638   const int *cptr=getConstPointer();
8639   std::size_t nbOfVals=getNbOfElems();
8640   for(const int *work=cptr;work!=cptr+nbOfVals;)
8641     {
8642       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
8643       if(work!=cptr+nbOfVals)
8644         {
8645           if(std::distance(cptr,work)%nbOfCompo!=0)
8646             work++;
8647           else
8648             return std::distance(cptr,work)/nbOfCompo;
8649         }
8650     }
8651   return -1;
8652 }
8653
8654 /*!
8655  * This method searches the sequence specified in input parameter \b vals in \b this.
8656  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
8657  * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple.
8658  * \sa DataArrayInt::locateTuple
8659  */
8660 int DataArrayInt::search(const std::vector<int>& vals) const
8661 {
8662   checkAllocated();
8663   int nbOfCompo=getNumberOfComponents();
8664   if(nbOfCompo!=1)
8665     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
8666   const int *cptr=getConstPointer();
8667   std::size_t nbOfVals=getNbOfElems();
8668   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
8669   if(loc!=cptr+nbOfVals)
8670     return std::distance(cptr,loc);
8671   return -1;
8672 }
8673
8674 /*!
8675  * This method expects to be called when number of components of this is equal to one.
8676  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
8677  * If not any tuple contains \b value -1 is returned.
8678  * \sa DataArrayInt::presenceOfValue
8679  */
8680 int DataArrayInt::locateValue(int value) const
8681 {
8682   checkAllocated();
8683   if(getNumberOfComponents()!=1)
8684     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8685   const int *cptr=getConstPointer();
8686   int nbOfTuples=getNumberOfTuples();
8687   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
8688   if(ret!=cptr+nbOfTuples)
8689     return std::distance(cptr,ret);
8690   return -1;
8691 }
8692
8693 /*!
8694  * This method expects to be called when number of components of this is equal to one.
8695  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
8696  * If not any tuple contains one of the values contained in 'vals' false is returned.
8697  * \sa DataArrayInt::presenceOfValue
8698  */
8699 int DataArrayInt::locateValue(const std::vector<int>& vals) const
8700 {
8701   checkAllocated();
8702   if(getNumberOfComponents()!=1)
8703     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
8704   std::set<int> vals2(vals.begin(),vals.end());
8705   const int *cptr=getConstPointer();
8706   int nbOfTuples=getNumberOfTuples();
8707   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
8708     if(vals2.find(*w)!=vals2.end())
8709       return std::distance(cptr,w);
8710   return -1;
8711 }
8712
8713 /*!
8714  * This method returns the number of values in \a this that are equals to input parameter \a value.
8715  * This method only works for single component array.
8716  *
8717  * \return a value in [ 0, \c this->getNumberOfTuples() )
8718  *
8719  * \throw If \a this is not allocated
8720  *
8721  */
8722 int DataArrayInt::count(int value) const
8723 {
8724   int ret=0;
8725   checkAllocated();
8726   if(getNumberOfComponents()!=1)
8727     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
8728   const int *vals=begin();
8729   int nbOfTuples=getNumberOfTuples();
8730   for(int i=0;i<nbOfTuples;i++,vals++)
8731     if(*vals==value)
8732       ret++;
8733   return ret;
8734 }
8735
8736 /*!
8737  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
8738  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
8739  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
8740  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
8741  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
8742  * \sa DataArrayInt::locateTuple
8743  */
8744 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
8745 {
8746   return locateTuple(tupl)!=-1;
8747 }
8748
8749
8750 /*!
8751  * Returns \a true if a given value is present within \a this one-dimensional array.
8752  *  \param [in] value - the value to find within \a this array.
8753  *  \return bool - \a true in case if \a value is present within \a this array.
8754  *  \throw If \a this is not allocated.
8755  *  \throw If \a this->getNumberOfComponents() != 1.
8756  *  \sa locateValue()
8757  */
8758 bool DataArrayInt::presenceOfValue(int value) const
8759 {
8760   return locateValue(value)!=-1;
8761 }
8762
8763 /*!
8764  * This method expects to be called when number of components of this is equal to one.
8765  * This method returns true if it exists a tuple so that the value is contained in \b vals.
8766  * If not any tuple contains one of the values contained in 'vals' false is returned.
8767  * \sa DataArrayInt::locateValue
8768  */
8769 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
8770 {
8771   return locateValue(vals)!=-1;
8772 }
8773
8774 /*!
8775  * Accumulates values of each component of \a this array.
8776  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
8777  *         by the caller, that is filled by this method with sum value for each
8778  *         component.
8779  *  \throw If \a this is not allocated.
8780  */
8781 void DataArrayInt::accumulate(int *res) const
8782 {
8783   checkAllocated();
8784   const int *ptr=getConstPointer();
8785   int nbTuple=getNumberOfTuples();
8786   int nbComps=getNumberOfComponents();
8787   std::fill(res,res+nbComps,0);
8788   for(int i=0;i<nbTuple;i++)
8789     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
8790 }
8791
8792 int DataArrayInt::accumulate(int compId) const
8793 {
8794   checkAllocated();
8795   const int *ptr=getConstPointer();
8796   int nbTuple=getNumberOfTuples();
8797   int nbComps=getNumberOfComponents();
8798   if(compId<0 || compId>=nbComps)
8799     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
8800   int ret=0;
8801   for(int i=0;i<nbTuple;i++)
8802     ret+=ptr[i*nbComps+compId];
8803   return ret;
8804 }
8805
8806 /*!
8807  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
8808  * The returned array will have same number of components than \a this and number of tuples equal to
8809  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
8810  *
8811  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
8812  *
8813  * \param [in] bgOfIndex - begin (included) of the input index array.
8814  * \param [in] endOfIndex - end (excluded) of the input index array.
8815  * \return DataArrayInt * - the new instance having the same number of components than \a this.
8816  * 
8817  * \throw If bgOfIndex or end is NULL.
8818  * \throw If input index array is not ascendingly sorted.
8819  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
8820  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
8821  */
8822 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
8823 {
8824   if(!bgOfIndex || !endOfIndex)
8825     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
8826   checkAllocated();
8827   int nbCompo=getNumberOfComponents();
8828   int nbOfTuples=getNumberOfTuples();
8829   int sz=(int)std::distance(bgOfIndex,endOfIndex);
8830   if(sz<1)
8831     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
8832   sz--;
8833   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
8834   const int *w=bgOfIndex;
8835   if(*w<0 || *w>=nbOfTuples)
8836     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
8837   const int *srcPt=begin()+(*w)*nbCompo;
8838   int *tmp=ret->getPointer();
8839   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
8840     {
8841       std::fill(tmp,tmp+nbCompo,0);
8842       if(w[1]>=w[0])
8843         {
8844           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
8845             {
8846               if(j>=0 && j<nbOfTuples)
8847                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
8848               else
8849                 {
8850                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
8851                   throw INTERP_KERNEL::Exception(oss.str().c_str());
8852                 }
8853             }
8854         }
8855       else
8856         {
8857           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
8858           throw INTERP_KERNEL::Exception(oss.str().c_str());
8859         }
8860     }
8861   ret->copyStringInfoFrom(*this);
8862   return ret.retn();
8863 }
8864
8865 /*!
8866  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
8867  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
8868  * offsetA2</em> and (2)
8869  * the number of component in the result array is same as that of each of given arrays.
8870  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
8871  * Info on components is copied from the first of the given arrays. Number of components
8872  * in the given arrays must be the same.
8873  *  \param [in] a1 - an array to include in the result array.
8874  *  \param [in] a2 - another array to include in the result array.
8875  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
8876  *  \return DataArrayInt * - the new instance of DataArrayInt.
8877  *          The caller is to delete this result array using decrRef() as it is no more
8878  *          needed.
8879  *  \throw If either \a a1 or \a a2 is NULL.
8880  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
8881  */
8882 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
8883 {
8884   if(!a1 || !a2)
8885     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
8886   int nbOfComp=a1->getNumberOfComponents();
8887   if(nbOfComp!=a2->getNumberOfComponents())
8888     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
8889   int nbOfTuple1=a1->getNumberOfTuples();
8890   int nbOfTuple2=a2->getNumberOfTuples();
8891   DataArrayInt *ret=DataArrayInt::New();
8892   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
8893   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
8894   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
8895   ret->copyStringInfoFrom(*a1);
8896   return ret;
8897 }
8898
8899 /*!
8900  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
8901  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
8902  * the number of component in the result array is same as that of each of given arrays.
8903  * Info on components is copied from the first of the given arrays. Number of components
8904  * in the given arrays must be  the same.
8905  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
8906  * not the object itself.
8907  *  \param [in] arr - a sequence of arrays to include in the result array.
8908  *  \return DataArrayInt * - the new instance of DataArrayInt.
8909  *          The caller is to delete this result array using decrRef() as it is no more
8910  *          needed.
8911  *  \throw If all arrays within \a arr are NULL.
8912  *  \throw If getNumberOfComponents() of arrays within \a arr.
8913  */
8914 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
8915 {
8916   std::vector<const DataArrayInt *> a;
8917   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
8918     if(*it4)
8919       a.push_back(*it4);
8920   if(a.empty())
8921     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
8922   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
8923   int nbOfComp=(*it)->getNumberOfComponents();
8924   int nbt=(*it++)->getNumberOfTuples();
8925   for(int i=1;it!=a.end();it++,i++)
8926     {
8927       if((*it)->getNumberOfComponents()!=nbOfComp)
8928         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
8929       nbt+=(*it)->getNumberOfTuples();
8930     }
8931   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8932   ret->alloc(nbt,nbOfComp);
8933   int *pt=ret->getPointer();
8934   for(it=a.begin();it!=a.end();it++)
8935     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
8936   ret->copyStringInfoFrom(*(a[0]));
8937   return ret.retn();
8938 }
8939
8940 /*!
8941  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
8942  * A packed index array is an allocated array with one component, and at least one tuple. The first element
8943  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
8944  * 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.
8945  * 
8946  * \return DataArrayInt * - a new object to be managed by the caller.
8947  */
8948 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
8949 {
8950   int retSz=1;
8951   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
8952     {
8953       if(*it4)
8954         {
8955           (*it4)->checkAllocated();
8956           if((*it4)->getNumberOfComponents()!=1)
8957             {
8958               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8959               throw INTERP_KERNEL::Exception(oss.str().c_str());
8960             }
8961           int nbTupl=(*it4)->getNumberOfTuples();
8962           if(nbTupl<1)
8963             {
8964               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
8965               throw INTERP_KERNEL::Exception(oss.str().c_str());
8966             }
8967           if((*it4)->front()!=0)
8968             {
8969               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
8970               throw INTERP_KERNEL::Exception(oss.str().c_str());
8971             }
8972           retSz+=nbTupl-1;
8973         }
8974       else
8975         {
8976           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
8977           throw INTERP_KERNEL::Exception(oss.str().c_str());
8978         }
8979     }
8980   if(arrs.empty())
8981     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
8982   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
8983   ret->alloc(retSz,1);
8984   int *pt=ret->getPointer(); *pt++=0;
8985   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
8986     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
8987   ret->copyStringInfoFrom(*(arrs[0]));
8988   return ret.retn();
8989 }
8990
8991 /*!
8992  * Returns the maximal value and its location within \a this one-dimensional array.
8993  *  \param [out] tupleId - index of the tuple holding the maximal value.
8994  *  \return int - the maximal value among all values of \a this array.
8995  *  \throw If \a this->getNumberOfComponents() != 1
8996  *  \throw If \a this->getNumberOfTuples() < 1
8997  */
8998 int DataArrayInt::getMaxValue(int& tupleId) const
8999 {
9000   checkAllocated();
9001   if(getNumberOfComponents()!=1)
9002     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9003   int nbOfTuples=getNumberOfTuples();
9004   if(nbOfTuples<=0)
9005     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9006   const int *vals=getConstPointer();
9007   const int *loc=std::max_element(vals,vals+nbOfTuples);
9008   tupleId=(int)std::distance(vals,loc);
9009   return *loc;
9010 }
9011
9012 /*!
9013  * Returns the maximal value within \a this array that is allowed to have more than
9014  *  one component.
9015  *  \return int - the maximal value among all values of \a this array.
9016  *  \throw If \a this is not allocated.
9017  */
9018 int DataArrayInt::getMaxValueInArray() const
9019 {
9020   checkAllocated();
9021   const int *loc=std::max_element(begin(),end());
9022   return *loc;
9023 }
9024
9025 /*!
9026  * Returns the minimal value and its location within \a this one-dimensional array.
9027  *  \param [out] tupleId - index of the tuple holding the minimal value.
9028  *  \return int - the minimal value among all values of \a this array.
9029  *  \throw If \a this->getNumberOfComponents() != 1
9030  *  \throw If \a this->getNumberOfTuples() < 1
9031  */
9032 int DataArrayInt::getMinValue(int& tupleId) const
9033 {
9034   checkAllocated();
9035   if(getNumberOfComponents()!=1)
9036     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
9037   int nbOfTuples=getNumberOfTuples();
9038   if(nbOfTuples<=0)
9039     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !");
9040   const int *vals=getConstPointer();
9041   const int *loc=std::min_element(vals,vals+nbOfTuples);
9042   tupleId=(int)std::distance(vals,loc);
9043   return *loc;
9044 }
9045
9046 /*!
9047  * Returns the minimal value within \a this array that is allowed to have more than
9048  *  one component.
9049  *  \return int - the minimal value among all values of \a this array.
9050  *  \throw If \a this is not allocated.
9051  */
9052 int DataArrayInt::getMinValueInArray() const
9053 {
9054   checkAllocated();
9055   const int *loc=std::min_element(begin(),end());
9056   return *loc;
9057 }
9058
9059 /*!
9060  * Converts every value of \a this array to its absolute value.
9061  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
9062  * should be called instead.
9063  *
9064  * \throw If \a this is not allocated.
9065  * \sa DataArrayInt::computeAbs
9066  */
9067 void DataArrayInt::abs()
9068 {
9069   checkAllocated();
9070   int *ptr(getPointer());
9071   std::size_t nbOfElems(getNbOfElems());
9072   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
9073   declareAsNew();
9074 }
9075
9076 /*!
9077  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
9078  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
9079  *
9080  * \return DataArrayInt * - the new instance of DataArrayInt containing the
9081  *         same number of tuples and component as \a this array.
9082  *         The caller is to delete this result array using decrRef() as it is no more
9083  *         needed.
9084  * \throw If \a this is not allocated.
9085  * \sa DataArrayInt::abs
9086  */
9087 DataArrayInt *DataArrayInt::computeAbs() const
9088 {
9089   checkAllocated();
9090   DataArrayInt *newArr(DataArrayInt::New());
9091   int nbOfTuples(getNumberOfTuples());
9092   int nbOfComp(getNumberOfComponents());
9093   newArr->alloc(nbOfTuples,nbOfComp);
9094   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
9095   newArr->copyStringInfoFrom(*this);
9096   return newArr;
9097 }
9098
9099 /*!
9100  * Apply a liner function to a given component of \a this array, so that
9101  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
9102  *  \param [in] a - the first coefficient of the function.
9103  *  \param [in] b - the second coefficient of the function.
9104  *  \param [in] compoId - the index of component to modify.
9105  *  \throw If \a this is not allocated.
9106  */
9107 void DataArrayInt::applyLin(int a, int b, int compoId)
9108 {
9109   checkAllocated();
9110   int *ptr=getPointer()+compoId;
9111   int nbOfComp=getNumberOfComponents();
9112   int nbOfTuple=getNumberOfTuples();
9113   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
9114     *ptr=a*(*ptr)+b;
9115   declareAsNew();
9116 }
9117
9118 /*!
9119  * Apply a liner function to all elements of \a this array, so that
9120  * an element _x_ becomes \f$ a * x + b \f$.
9121  *  \param [in] a - the first coefficient of the function.
9122  *  \param [in] b - the second coefficient of the function.
9123  *  \throw If \a this is not allocated.
9124  */
9125 void DataArrayInt::applyLin(int a, int b)
9126 {
9127   checkAllocated();
9128   int *ptr=getPointer();
9129   std::size_t nbOfElems=getNbOfElems();
9130   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9131     *ptr=a*(*ptr)+b;
9132   declareAsNew();
9133 }
9134
9135 /*!
9136  * Returns a full copy of \a this array except that sign of all elements is reversed.
9137  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
9138  *          same number of tuples and component as \a this array.
9139  *          The caller is to delete this result array using decrRef() as it is no more
9140  *          needed.
9141  *  \throw If \a this is not allocated.
9142  */
9143 DataArrayInt *DataArrayInt::negate() const
9144 {
9145   checkAllocated();
9146   DataArrayInt *newArr=DataArrayInt::New();
9147   int nbOfTuples=getNumberOfTuples();
9148   int nbOfComp=getNumberOfComponents();
9149   newArr->alloc(nbOfTuples,nbOfComp);
9150   const int *cptr=getConstPointer();
9151   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
9152   newArr->copyStringInfoFrom(*this);
9153   return newArr;
9154 }
9155
9156 /*!
9157  * Modify all elements of \a this array, so that
9158  * an element _x_ becomes \f$ numerator / x \f$.
9159  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9160  *           array, all elements processed before detection of the zero element remain
9161  *           modified.
9162  *  \param [in] numerator - the numerator used to modify array elements.
9163  *  \throw If \a this is not allocated.
9164  *  \throw If there is an element equal to 0 in \a this array.
9165  */
9166 void DataArrayInt::applyInv(int numerator)
9167 {
9168   checkAllocated();
9169   int *ptr=getPointer();
9170   std::size_t nbOfElems=getNbOfElems();
9171   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9172     {
9173       if(*ptr!=0)
9174         {
9175           *ptr=numerator/(*ptr);
9176         }
9177       else
9178         {
9179           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9180           oss << " !";
9181           throw INTERP_KERNEL::Exception(oss.str().c_str());
9182         }
9183     }
9184   declareAsNew();
9185 }
9186
9187 /*!
9188  * Modify all elements of \a this array, so that
9189  * an element _x_ becomes \f$ x / val \f$.
9190  *  \param [in] val - the denominator used to modify array elements.
9191  *  \throw If \a this is not allocated.
9192  *  \throw If \a val == 0.
9193  */
9194 void DataArrayInt::applyDivideBy(int val)
9195 {
9196   if(val==0)
9197     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
9198   checkAllocated();
9199   int *ptr=getPointer();
9200   std::size_t nbOfElems=getNbOfElems();
9201   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
9202   declareAsNew();
9203 }
9204
9205 /*!
9206  * Modify all elements of \a this array, so that
9207  * an element _x_ becomes  <em> x % val </em>.
9208  *  \param [in] val - the divisor used to modify array elements.
9209  *  \throw If \a this is not allocated.
9210  *  \throw If \a val <= 0.
9211  */
9212 void DataArrayInt::applyModulus(int val)
9213 {
9214   if(val<=0)
9215     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
9216   checkAllocated();
9217   int *ptr=getPointer();
9218   std::size_t nbOfElems=getNbOfElems();
9219   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
9220   declareAsNew();
9221 }
9222
9223 /*!
9224  * This method works only on data array with one component.
9225  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9226  * this[*id] in [\b vmin,\b vmax)
9227  * 
9228  * \param [in] vmin begin of range. This value is included in range (included).
9229  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9230  * \return a newly allocated data array that the caller should deal with.
9231  *
9232  * \sa DataArrayInt::getIdsNotInRange
9233  */
9234 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const
9235 {
9236   checkAllocated();
9237   if(getNumberOfComponents()!=1)
9238     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
9239   const int *cptr(begin());
9240   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9241   int nbOfTuples(getNumberOfTuples());
9242   for(int i=0;i<nbOfTuples;i++,cptr++)
9243     if(*cptr>=vmin && *cptr<vmax)
9244       ret->pushBackSilent(i);
9245   return ret.retn();
9246 }
9247
9248 /*!
9249  * This method works only on data array with one component.
9250  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
9251  * this[*id] \b not in [\b vmin,\b vmax)
9252  * 
9253  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
9254  * \param [in] vmax end of range. This value is included in range (included).
9255  * \return a newly allocated data array that the caller should deal with.
9256  * 
9257  * \sa DataArrayInt::getIdsInRange
9258  */
9259 DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const
9260 {
9261   checkAllocated();
9262   if(getNumberOfComponents()!=1)
9263     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotInRange : this must have exactly one component !");
9264   const int *cptr(getConstPointer());
9265   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9266   int nbOfTuples(getNumberOfTuples());
9267   for(int i=0;i<nbOfTuples;i++,cptr++)
9268     if(*cptr<vmin || *cptr>=vmax)
9269       ret->pushBackSilent(i);
9270   return ret.retn();
9271 }
9272
9273 /*!
9274  * This method works only on data array with one component.
9275  * 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.
9276  * 
9277  * \param [in] vmin begin of range. This value is included in range (included).
9278  * \param [in] vmax end of range. This value is \b not included in range (excluded).
9279  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
9280 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
9281 {
9282   checkAllocated();
9283   if(getNumberOfComponents()!=1)
9284     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
9285   int nbOfTuples=getNumberOfTuples();
9286   bool ret=true;
9287   const int *cptr=getConstPointer();
9288   for(int i=0;i<nbOfTuples;i++,cptr++)
9289     {
9290       if(*cptr>=vmin && *cptr<vmax)
9291         { ret=ret && *cptr==i; }
9292       else
9293         {
9294           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
9295           throw INTERP_KERNEL::Exception(oss.str().c_str());
9296         }
9297     }
9298   return ret;
9299 }
9300
9301 /*!
9302  * Modify all elements of \a this array, so that
9303  * an element _x_ becomes <em> val % x </em>.
9304  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
9305  *           array, all elements processed before detection of the zero element remain
9306  *           modified.
9307  *  \param [in] val - the divident used to modify array elements.
9308  *  \throw If \a this is not allocated.
9309  *  \throw If there is an element equal to or less than 0 in \a this array.
9310  */
9311 void DataArrayInt::applyRModulus(int val)
9312 {
9313   checkAllocated();
9314   int *ptr=getPointer();
9315   std::size_t nbOfElems=getNbOfElems();
9316   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9317     {
9318       if(*ptr>0)
9319         {
9320           *ptr=val%(*ptr);
9321         }
9322       else
9323         {
9324           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9325           oss << " !";
9326           throw INTERP_KERNEL::Exception(oss.str().c_str());
9327         }
9328     }
9329   declareAsNew();
9330 }
9331
9332 /*!
9333  * Modify all elements of \a this array, so that
9334  * an element _x_ becomes <em> val ^ x </em>.
9335  *  \param [in] val - the value used to apply pow on all array elements.
9336  *  \throw If \a this is not allocated.
9337  *  \throw If \a val < 0.
9338  */
9339 void DataArrayInt::applyPow(int val)
9340 {
9341   checkAllocated();
9342   if(val<0)
9343     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
9344   int *ptr=getPointer();
9345   std::size_t nbOfElems=getNbOfElems();
9346   if(val==0)
9347     {
9348       std::fill(ptr,ptr+nbOfElems,1);
9349       return ;
9350     }
9351   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9352     {
9353       int tmp=1;
9354       for(int j=0;j<val;j++)
9355         tmp*=*ptr;
9356       *ptr=tmp;
9357     }
9358   declareAsNew();
9359 }
9360
9361 /*!
9362  * Modify all elements of \a this array, so that
9363  * an element _x_ becomes \f$ val ^ x \f$.
9364  *  \param [in] val - the value used to apply pow on all array elements.
9365  *  \throw If \a this is not allocated.
9366  *  \throw If there is an element < 0 in \a this array.
9367  *  \warning If an exception is thrown because of presence of 0 element in \a this 
9368  *           array, all elements processed before detection of the zero element remain
9369  *           modified.
9370  */
9371 void DataArrayInt::applyRPow(int val)
9372 {
9373   checkAllocated();
9374   int *ptr=getPointer();
9375   std::size_t nbOfElems=getNbOfElems();
9376   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
9377     {
9378       if(*ptr>=0)
9379         {
9380           int tmp=1;
9381           for(int j=0;j<*ptr;j++)
9382             tmp*=val;
9383           *ptr=tmp;
9384         }
9385       else
9386         {
9387           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
9388           oss << " !";
9389           throw INTERP_KERNEL::Exception(oss.str().c_str());
9390         }
9391     }
9392   declareAsNew();
9393 }
9394
9395 /*!
9396  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
9397  * of components in the result array is a sum of the number of components of given arrays
9398  * and (2) the number of tuples in the result array is same as that of each of given
9399  * arrays. In other words the i-th tuple of result array includes all components of
9400  * i-th tuples of all given arrays.
9401  * Number of tuples in the given arrays must be the same.
9402  *  \param [in] a1 - an array to include in the result array.
9403  *  \param [in] a2 - another array to include in the result array.
9404  *  \return DataArrayInt * - the new instance of DataArrayInt.
9405  *          The caller is to delete this result array using decrRef() as it is no more
9406  *          needed.
9407  *  \throw If both \a a1 and \a a2 are NULL.
9408  *  \throw If any given array is not allocated.
9409  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9410  */
9411 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
9412 {
9413   std::vector<const DataArrayInt *> arr(2);
9414   arr[0]=a1; arr[1]=a2;
9415   return Meld(arr);
9416 }
9417
9418 /*!
9419  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
9420  * of components in the result array is a sum of the number of components of given arrays
9421  * and (2) the number of tuples in the result array is same as that of each of given
9422  * arrays. In other words the i-th tuple of result array includes all components of
9423  * i-th tuples of all given arrays.
9424  * Number of tuples in the given arrays must be  the same.
9425  *  \param [in] arr - a sequence of arrays to include in the result array.
9426  *  \return DataArrayInt * - the new instance of DataArrayInt.
9427  *          The caller is to delete this result array using decrRef() as it is no more
9428  *          needed.
9429  *  \throw If all arrays within \a arr are NULL.
9430  *  \throw If any given array is not allocated.
9431  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
9432  */
9433 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
9434 {
9435   std::vector<const DataArrayInt *> a;
9436   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9437     if(*it4)
9438       a.push_back(*it4);
9439   if(a.empty())
9440     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
9441   std::vector<const DataArrayInt *>::const_iterator it;
9442   for(it=a.begin();it!=a.end();it++)
9443     (*it)->checkAllocated();
9444   it=a.begin();
9445   int nbOfTuples=(*it)->getNumberOfTuples();
9446   std::vector<int> nbc(a.size());
9447   std::vector<const int *> pts(a.size());
9448   nbc[0]=(*it)->getNumberOfComponents();
9449   pts[0]=(*it++)->getConstPointer();
9450   for(int i=1;it!=a.end();it++,i++)
9451     {
9452       if(nbOfTuples!=(*it)->getNumberOfTuples())
9453         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
9454       nbc[i]=(*it)->getNumberOfComponents();
9455       pts[i]=(*it)->getConstPointer();
9456     }
9457   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
9458   DataArrayInt *ret=DataArrayInt::New();
9459   ret->alloc(nbOfTuples,totalNbOfComp);
9460   int *retPtr=ret->getPointer();
9461   for(int i=0;i<nbOfTuples;i++)
9462     for(int j=0;j<(int)a.size();j++)
9463       {
9464         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
9465         pts[j]+=nbc[j];
9466       }
9467   int k=0;
9468   for(int i=0;i<(int)a.size();i++)
9469     for(int j=0;j<nbc[i];j++,k++)
9470       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
9471   return ret;
9472 }
9473
9474 /*!
9475  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
9476  * The i-th item of the result array is an ID of a set of elements belonging to a
9477  * unique set of groups, which the i-th element is a part of. This set of elements
9478  * belonging to a unique set of groups is called \a family, so the result array contains
9479  * IDs of families each element belongs to.
9480  *
9481  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
9482  * then there are 3 families:
9483  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
9484  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
9485  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
9486  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
9487  * stands for the element #3 which is in none of groups.
9488  *
9489  *  \param [in] groups - sequence of groups of element IDs.
9490  *  \param [in] newNb - total number of elements; it must be more than max ID of element
9491  *         in \a groups.
9492  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
9493  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
9494  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
9495  *         delete this array using decrRef() as it is no more needed.
9496  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
9497  */
9498 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
9499 {
9500   std::vector<const DataArrayInt *> groups2;
9501   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
9502     if(*it4)
9503       groups2.push_back(*it4);
9504   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9505   ret->alloc(newNb,1);
9506   int *retPtr=ret->getPointer();
9507   std::fill(retPtr,retPtr+newNb,0);
9508   int fid=1;
9509   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
9510     {
9511       const int *ptr=(*iter)->getConstPointer();
9512       std::size_t nbOfElem=(*iter)->getNbOfElems();
9513       int sfid=fid;
9514       for(int j=0;j<sfid;j++)
9515         {
9516           bool found=false;
9517           for(std::size_t i=0;i<nbOfElem;i++)
9518             {
9519               if(ptr[i]>=0 && ptr[i]<newNb)
9520                 {
9521                   if(retPtr[ptr[i]]==j)
9522                     {
9523                       retPtr[ptr[i]]=fid;
9524                       found=true;
9525                     }
9526                 }
9527               else
9528                 {
9529                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
9530                   oss << ") !";
9531                   throw INTERP_KERNEL::Exception(oss.str().c_str());
9532                 }
9533             }
9534           if(found)
9535             fid++;
9536         }
9537     }
9538   fidsOfGroups.clear();
9539   fidsOfGroups.resize(groups2.size());
9540   int grId=0;
9541   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
9542     {
9543       std::set<int> tmp;
9544       const int *ptr=(*iter)->getConstPointer();
9545       std::size_t nbOfElem=(*iter)->getNbOfElems();
9546       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
9547         tmp.insert(retPtr[*p]);
9548       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
9549     }
9550   return ret.retn();
9551 }
9552
9553 /*!
9554  * Returns a new DataArrayInt which contains all elements of given one-dimensional
9555  * arrays. The result array does not contain any duplicates and its values
9556  * are sorted in ascending order.
9557  *  \param [in] arr - sequence of DataArrayInt's to unite.
9558  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9559  *         array using decrRef() as it is no more needed.
9560  *  \throw If any \a arr[i] is not allocated.
9561  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9562  */
9563 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
9564 {
9565   std::vector<const DataArrayInt *> a;
9566   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9567     if(*it4)
9568       a.push_back(*it4);
9569   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9570     {
9571       (*it)->checkAllocated();
9572       if((*it)->getNumberOfComponents()!=1)
9573         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
9574     }
9575   //
9576   std::set<int> r;
9577   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9578     {
9579       const int *pt=(*it)->getConstPointer();
9580       int nbOfTuples=(*it)->getNumberOfTuples();
9581       r.insert(pt,pt+nbOfTuples);
9582     }
9583   DataArrayInt *ret=DataArrayInt::New();
9584   ret->alloc((int)r.size(),1);
9585   std::copy(r.begin(),r.end(),ret->getPointer());
9586   return ret;
9587 }
9588
9589 /*!
9590  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
9591  * arrays. The result array does not contain any duplicates and its values
9592  * are sorted in ascending order.
9593  *  \param [in] arr - sequence of DataArrayInt's to intersect.
9594  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9595  *         array using decrRef() as it is no more needed.
9596  *  \throw If any \a arr[i] is not allocated.
9597  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
9598  */
9599 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
9600 {
9601   std::vector<const DataArrayInt *> a;
9602   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
9603     if(*it4)
9604       a.push_back(*it4);
9605   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9606     {
9607       (*it)->checkAllocated();
9608       if((*it)->getNumberOfComponents()!=1)
9609         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
9610     }
9611   //
9612   std::set<int> r;
9613   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
9614     {
9615       const int *pt=(*it)->getConstPointer();
9616       int nbOfTuples=(*it)->getNumberOfTuples();
9617       std::set<int> s1(pt,pt+nbOfTuples);
9618       if(it!=a.begin())
9619         {
9620           std::set<int> r2;
9621           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
9622           r=r2;
9623         }
9624       else
9625         r=s1;
9626     }
9627   DataArrayInt *ret(DataArrayInt::New());
9628   ret->alloc((int)r.size(),1);
9629   std::copy(r.begin(),r.end(),ret->getPointer());
9630   return ret;
9631 }
9632
9633 /// @cond INTERNAL
9634 namespace ParaMEDMEMImpl
9635 {
9636   class OpSwitchedOn
9637   {
9638   public:
9639     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
9640     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
9641   private:
9642     int *_pt;
9643     int _cnt;
9644   };
9645
9646   class OpSwitchedOff
9647   {
9648   public:
9649     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
9650     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
9651   private:
9652     int *_pt;
9653     int _cnt;
9654   };
9655 }
9656 /// @endcond
9657
9658 /*!
9659  * This method returns the list of ids in ascending mode so that v[id]==true.
9660  */
9661 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
9662 {
9663   int sz((int)std::count(v.begin(),v.end(),true));
9664   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9665   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOn(ret->getPointer()));
9666   return ret.retn();
9667 }
9668
9669 /*!
9670  * This method returns the list of ids in ascending mode so that v[id]==false.
9671  */
9672 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
9673 {
9674   int sz((int)std::count(v.begin(),v.end(),false));
9675   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
9676   std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOff(ret->getPointer()));
9677   return ret.retn();
9678 }
9679
9680 /*!
9681  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
9682  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
9683  *
9684  * \param [in] v the input data structure to be translate into skyline format.
9685  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
9686  * \param [out] dataIndex the second element of the skyline format.
9687  */
9688 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
9689 {
9690   int sz((int)v.size());
9691   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
9692   ret1->alloc(sz+1,1);
9693   int *pt(ret1->getPointer()); *pt=0;
9694   for(int i=0;i<sz;i++,pt++)
9695     pt[1]=pt[0]+(int)v[i].size();
9696   ret0->alloc(ret1->back(),1);
9697   pt=ret0->getPointer();
9698   for(int i=0;i<sz;i++)
9699     pt=std::copy(v[i].begin(),v[i].end(),pt);
9700   data=ret0.retn(); dataIndex=ret1.retn();
9701 }
9702
9703 /*!
9704  * Returns a new DataArrayInt which contains a complement of elements of \a this
9705  * one-dimensional array. I.e. the result array contains all elements from the range [0,
9706  * \a nbOfElement) not present in \a this array.
9707  *  \param [in] nbOfElement - maximal size of the result array.
9708  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9709  *         array using decrRef() as it is no more needed.
9710  *  \throw If \a this is not allocated.
9711  *  \throw If \a this->getNumberOfComponents() != 1.
9712  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
9713  *         nbOfElement ).
9714  */
9715 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
9716 {
9717   checkAllocated();
9718   if(getNumberOfComponents()!=1)
9719     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
9720   std::vector<bool> tmp(nbOfElement);
9721   const int *pt=getConstPointer();
9722   int nbOfTuples=getNumberOfTuples();
9723   for(const int *w=pt;w!=pt+nbOfTuples;w++)
9724     if(*w>=0 && *w<nbOfElement)
9725       tmp[*w]=true;
9726     else
9727       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
9728   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
9729   DataArrayInt *ret=DataArrayInt::New();
9730   ret->alloc(nbOfRetVal,1);
9731   int j=0;
9732   int *retPtr=ret->getPointer();
9733   for(int i=0;i<nbOfElement;i++)
9734     if(!tmp[i])
9735       retPtr[j++]=i;
9736   return ret;
9737 }
9738
9739 /*!
9740  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
9741  * from an \a other one-dimensional array.
9742  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
9743  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
9744  *         caller is to delete this array using decrRef() as it is no more needed.
9745  *  \throw If \a other is NULL.
9746  *  \throw If \a other is not allocated.
9747  *  \throw If \a other->getNumberOfComponents() != 1.
9748  *  \throw If \a this is not allocated.
9749  *  \throw If \a this->getNumberOfComponents() != 1.
9750  *  \sa DataArrayInt::buildSubstractionOptimized()
9751  */
9752 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
9753 {
9754   if(!other)
9755     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
9756   checkAllocated();
9757   other->checkAllocated();
9758   if(getNumberOfComponents()!=1)
9759     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
9760   if(other->getNumberOfComponents()!=1)
9761     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
9762   const int *pt=getConstPointer();
9763   int nbOfTuples=getNumberOfTuples();
9764   std::set<int> s1(pt,pt+nbOfTuples);
9765   pt=other->getConstPointer();
9766   nbOfTuples=other->getNumberOfTuples();
9767   std::set<int> s2(pt,pt+nbOfTuples);
9768   std::vector<int> r;
9769   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
9770   DataArrayInt *ret=DataArrayInt::New();
9771   ret->alloc((int)r.size(),1);
9772   std::copy(r.begin(),r.end(),ret->getPointer());
9773   return ret;
9774 }
9775
9776 /*!
9777  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
9778  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
9779  * 
9780  * \param [in] other an array with one component and expected to be sorted ascendingly.
9781  * \ret list of ids in \a this but not in \a other.
9782  * \sa DataArrayInt::buildSubstraction
9783  */
9784 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
9785 {
9786   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
9787   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
9788   checkAllocated(); other->checkAllocated();
9789   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9790   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
9791   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
9792   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
9793   for(;work1!=pt1End;work1++)
9794     {
9795       if(work2!=pt2End && *work1==*work2)
9796         work2++;
9797       else
9798         ret->pushBackSilent(*work1);
9799     }
9800   return ret.retn();
9801 }
9802
9803
9804 /*!
9805  * Returns a new DataArrayInt which contains all elements of \a this and a given
9806  * one-dimensional arrays. The result array does not contain any duplicates
9807  * and its values are sorted in ascending order.
9808  *  \param [in] other - an array to unite with \a this one.
9809  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9810  *         array using decrRef() as it is no more needed.
9811  *  \throw If \a this or \a other is not allocated.
9812  *  \throw If \a this->getNumberOfComponents() != 1.
9813  *  \throw If \a other->getNumberOfComponents() != 1.
9814  */
9815 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
9816 {
9817   std::vector<const DataArrayInt *>arrs(2);
9818   arrs[0]=this; arrs[1]=other;
9819   return BuildUnion(arrs);
9820 }
9821
9822
9823 /*!
9824  * Returns a new DataArrayInt which contains elements present in both \a this and a given
9825  * one-dimensional arrays. The result array does not contain any duplicates
9826  * and its values are sorted in ascending order.
9827  *  \param [in] other - an array to intersect with \a this one.
9828  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9829  *         array using decrRef() as it is no more needed.
9830  *  \throw If \a this or \a other is not allocated.
9831  *  \throw If \a this->getNumberOfComponents() != 1.
9832  *  \throw If \a other->getNumberOfComponents() != 1.
9833  */
9834 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
9835 {
9836   std::vector<const DataArrayInt *>arrs(2);
9837   arrs[0]=this; arrs[1]=other;
9838   return BuildIntersection(arrs);
9839 }
9840
9841 /*!
9842  * This method can be applied on allocated with one component DataArrayInt instance.
9843  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
9844  * 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]
9845  * 
9846  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
9847  * \throw if \a this is not allocated or if \a this has not exactly one component.
9848  */
9849 DataArrayInt *DataArrayInt::buildUnique() const
9850 {
9851   checkAllocated();
9852   if(getNumberOfComponents()!=1)
9853     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
9854   int nbOfTuples=getNumberOfTuples();
9855   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
9856   int *data=tmp->getPointer();
9857   int *last=std::unique(data,data+nbOfTuples);
9858   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
9859   ret->alloc(std::distance(data,last),1);
9860   std::copy(data,last,ret->getPointer());
9861   return ret.retn();
9862 }
9863
9864 /*!
9865  * Returns a new DataArrayInt which contains size of every of groups described by \a this
9866  * "index" array. Such "index" array is returned for example by 
9867  * \ref ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
9868  * "MEDCouplingUMesh::buildDescendingConnectivity" and
9869  * \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
9870  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
9871  * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
9872  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
9873  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
9874  *          The caller is to delete this array using decrRef() as it is no more needed. 
9875  *  \throw If \a this is not allocated.
9876  *  \throw If \a this->getNumberOfComponents() != 1.
9877  *  \throw If \a this->getNumberOfTuples() < 2.
9878  *
9879  *  \b Example: <br> 
9880  *         - this contains [1,3,6,7,7,9,15]
9881  *         - result array contains [2,3,1,0,2,6],
9882  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
9883  *
9884  * \sa DataArrayInt::computeOffsets2
9885  */
9886 DataArrayInt *DataArrayInt::deltaShiftIndex() const
9887 {
9888   checkAllocated();
9889   if(getNumberOfComponents()!=1)
9890     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
9891   int nbOfTuples=getNumberOfTuples();
9892   if(nbOfTuples<2)
9893     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
9894   const int *ptr=getConstPointer();
9895   DataArrayInt *ret=DataArrayInt::New();
9896   ret->alloc(nbOfTuples-1,1);
9897   int *out=ret->getPointer();
9898   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
9899   return ret;
9900 }
9901
9902 /*!
9903  * Modifies \a this one-dimensional array so that value of each element \a x
9904  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9905  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
9906  * and components remains the same.<br>
9907  * This method is useful for allToAllV in MPI with contiguous policy. This method
9908  * differs from computeOffsets2() in that the number of tuples is \b not changed by
9909  * this one.
9910  *  \throw If \a this is not allocated.
9911  *  \throw If \a this->getNumberOfComponents() != 1.
9912  *
9913  *  \b Example: <br>
9914  *          - Before \a this contains [3,5,1,2,0,8]
9915  *          - After \a this contains  [0,3,8,9,11,11]<br>
9916  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
9917  *          array is retained and thus there is no space to store the last element.
9918  */
9919 void DataArrayInt::computeOffsets()
9920 {
9921   checkAllocated();
9922   if(getNumberOfComponents()!=1)
9923     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
9924   int nbOfTuples=getNumberOfTuples();
9925   if(nbOfTuples==0)
9926     return ;
9927   int *work=getPointer();
9928   int tmp=work[0];
9929   work[0]=0;
9930   for(int i=1;i<nbOfTuples;i++)
9931     {
9932       int tmp2=work[i];
9933       work[i]=work[i-1]+tmp;
9934       tmp=tmp2;
9935     }
9936   declareAsNew();
9937 }
9938
9939
9940 /*!
9941  * Modifies \a this one-dimensional array so that value of each element \a x
9942  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
9943  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
9944  * components remains the same and number of tuples is inceamented by one.<br>
9945  * This method is useful for allToAllV in MPI with contiguous policy. This method
9946  * differs from computeOffsets() in that the number of tuples is changed by this one.
9947  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
9948  *  \throw If \a this is not allocated.
9949  *  \throw If \a this->getNumberOfComponents() != 1.
9950  *
9951  *  \b Example: <br>
9952  *          - Before \a this contains [3,5,1,2,0,8]
9953  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
9954  * \sa DataArrayInt::deltaShiftIndex
9955  */
9956 void DataArrayInt::computeOffsets2()
9957 {
9958   checkAllocated();
9959   if(getNumberOfComponents()!=1)
9960     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !");
9961   int nbOfTuples=getNumberOfTuples();
9962   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
9963   if(nbOfTuples==0)
9964     return ;
9965   const int *work=getConstPointer();
9966   ret[0]=0;
9967   for(int i=0;i<nbOfTuples;i++)
9968     ret[i+1]=work[i]+ret[i];
9969   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
9970   declareAsNew();
9971 }
9972
9973 /*!
9974  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
9975  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsets2 ) that is to say with one component
9976  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
9977  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
9978  * filling completely one of the ranges in \a this.
9979  *
9980  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
9981  * \param [out] rangeIdsFetched the range ids fetched
9982  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
9983  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
9984  *
9985  * \sa DataArrayInt::computeOffsets2
9986  *
9987  *  \b Example: <br>
9988  *          - \a this : [0,3,7,9,15,18]
9989  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
9990  *          - \a rangeIdsFetched result array: [0,2,4]
9991  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
9992  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
9993  * <br>
9994  */
9995 void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
9996 {
9997   if(!listOfIds)
9998     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids is null !");
9999   listOfIds->checkAllocated(); checkAllocated();
10000   if(listOfIds->getNumberOfComponents()!=1)
10001     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : input list of ids must have exactly one component !");
10002   if(getNumberOfComponents()!=1)
10003     throw INTERP_KERNEL::Exception("DataArrayInt::searchRangesInListOfIds : this must have exactly one component !");
10004   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
10005   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
10006   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
10007   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
10008   while(tupPtr!=tupEnd && offPtr!=offEnd)
10009     {
10010       if(*tupPtr==*offPtr)
10011         {
10012           int i=offPtr[0];
10013           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
10014           if(i==offPtr[1])
10015             {
10016               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
10017               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
10018               offPtr++;
10019             }
10020         }
10021       else
10022         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
10023     }
10024   rangeIdsFetched=ret0.retn();
10025   idsInInputListThatFetch=ret1.retn();
10026 }
10027
10028 /*!
10029  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
10030  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10031  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10032  * beginning within the "iota" array. And \a this is a one-dimensional array
10033  * considered as a selector of groups described by \a offsets to include into the result array.
10034  *  \throw If \a offsets is NULL.
10035  *  \throw If \a offsets is not allocated.
10036  *  \throw If \a offsets->getNumberOfComponents() != 1.
10037  *  \throw If \a offsets is not monotonically increasing.
10038  *  \throw If \a this is not allocated.
10039  *  \throw If \a this->getNumberOfComponents() != 1.
10040  *  \throw If any element of \a this is not a valid index for \a offsets array.
10041  *
10042  *  \b Example: <br>
10043  *          - \a this: [0,2,3]
10044  *          - \a offsets: [0,3,6,10,14,20]
10045  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
10046  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
10047  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
10048  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
10049  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
10050  */
10051 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
10052 {
10053   if(!offsets)
10054     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
10055   checkAllocated();
10056   if(getNumberOfComponents()!=1)
10057     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
10058   offsets->checkAllocated();
10059   if(offsets->getNumberOfComponents()!=1)
10060     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
10061   int othNbTuples=offsets->getNumberOfTuples()-1;
10062   int nbOfTuples=getNumberOfTuples();
10063   int retNbOftuples=0;
10064   const int *work=getConstPointer();
10065   const int *offPtr=offsets->getConstPointer();
10066   for(int i=0;i<nbOfTuples;i++)
10067     {
10068       int val=work[i];
10069       if(val>=0 && val<othNbTuples)
10070         {
10071           int delta=offPtr[val+1]-offPtr[val];
10072           if(delta>=0)
10073             retNbOftuples+=delta;
10074           else
10075             {
10076               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
10077               throw INTERP_KERNEL::Exception(oss.str().c_str());
10078             }
10079         }
10080       else
10081         {
10082           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
10083           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
10084           throw INTERP_KERNEL::Exception(oss.str().c_str());
10085         }
10086     }
10087   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10088   ret->alloc(retNbOftuples,1);
10089   int *retPtr=ret->getPointer();
10090   for(int i=0;i<nbOfTuples;i++)
10091     {
10092       int val=work[i];
10093       int start=offPtr[val];
10094       int off=offPtr[val+1]-start;
10095       for(int j=0;j<off;j++,retPtr++)
10096         *retPtr=start+j;
10097     }
10098   return ret.retn();
10099 }
10100
10101 /*!
10102  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
10103  * scaled array (monotonically increasing).
10104 from that of \a this and \a
10105  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
10106  * "index" array of a "iota" array, thus, whose each element gives an index of a group
10107  * beginning within the "iota" array. And \a this is a one-dimensional array
10108  * considered as a selector of groups described by \a offsets to include into the result array.
10109  *  \throw If \a  is NULL.
10110  *  \throw If \a this is not allocated.
10111  *  \throw If \a this->getNumberOfComponents() != 1.
10112  *  \throw If \a this->getNumberOfTuples() == 0.
10113  *  \throw If \a this is not monotonically increasing.
10114  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
10115  *
10116  *  \b Example: <br>
10117  *          - \a bg , \a stop and \a step : (0,5,2)
10118  *          - \a this: [0,3,6,10,14,20]
10119  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
10120  */
10121 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
10122 {
10123   if(!isAllocated())
10124     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
10125   if(getNumberOfComponents()!=1)
10126     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
10127   int nbOfTuples(getNumberOfTuples());
10128   if(nbOfTuples==0)
10129     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
10130   const int *ids(begin());
10131   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
10132   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10133     {
10134       if(pos>=0 && pos<nbOfTuples-1)
10135         {
10136           int delta(ids[pos+1]-ids[pos]);
10137           sz+=delta;
10138           if(delta<0)
10139             {
10140               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
10141               throw INTERP_KERNEL::Exception(oss.str().c_str());
10142             }          
10143         }
10144       else
10145         {
10146           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
10147           throw INTERP_KERNEL::Exception(oss.str().c_str());
10148         }
10149     }
10150   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
10151   int *retPtr(ret->getPointer());
10152   pos=bg;
10153   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
10154     {
10155       int delta(ids[pos+1]-ids[pos]);
10156       for(int j=0;j<delta;j++,retPtr++)
10157         *retPtr=pos;
10158     }
10159   return ret.retn();
10160 }
10161
10162 /*!
10163  * 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.
10164  * 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
10165  * in tuple **i** of returned DataArrayInt.
10166  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
10167  *
10168  * 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)]
10169  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
10170  * 
10171  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10172  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10173  * \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
10174  *        is thrown if no ranges in \a ranges contains value in \a this.
10175  * 
10176  * \sa DataArrayInt::findIdInRangeForEachTuple
10177  */
10178 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
10179 {
10180   if(!ranges)
10181     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
10182   if(ranges->getNumberOfComponents()!=2)
10183     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
10184   checkAllocated();
10185   if(getNumberOfComponents()!=1)
10186     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
10187   int nbTuples=getNumberOfTuples();
10188   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10189   int nbOfRanges=ranges->getNumberOfTuples();
10190   const int *rangesPtr=ranges->getConstPointer();
10191   int *retPtr=ret->getPointer();
10192   const int *inPtr=getConstPointer();
10193   for(int i=0;i<nbTuples;i++,retPtr++)
10194     {
10195       int val=inPtr[i];
10196       bool found=false;
10197       for(int j=0;j<nbOfRanges && !found;j++)
10198         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10199           { *retPtr=j; found=true; }
10200       if(found)
10201         continue;
10202       else
10203         {
10204           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
10205           throw INTERP_KERNEL::Exception(oss.str().c_str());
10206         }
10207     }
10208   return ret.retn();
10209 }
10210
10211 /*!
10212  * 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.
10213  * 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
10214  * in tuple **i** of returned DataArrayInt.
10215  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
10216  *
10217  * 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)]
10218  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
10219  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
10220  * 
10221  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
10222  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
10223  * \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
10224  *        is thrown if no ranges in \a ranges contains value in \a this.
10225  * \sa DataArrayInt::findRangeIdForEachTuple
10226  */
10227 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
10228 {
10229   if(!ranges)
10230     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
10231   if(ranges->getNumberOfComponents()!=2)
10232     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
10233   checkAllocated();
10234   if(getNumberOfComponents()!=1)
10235     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
10236   int nbTuples=getNumberOfTuples();
10237   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
10238   int nbOfRanges=ranges->getNumberOfTuples();
10239   const int *rangesPtr=ranges->getConstPointer();
10240   int *retPtr=ret->getPointer();
10241   const int *inPtr=getConstPointer();
10242   for(int i=0;i<nbTuples;i++,retPtr++)
10243     {
10244       int val=inPtr[i];
10245       bool found=false;
10246       for(int j=0;j<nbOfRanges && !found;j++)
10247         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
10248           { *retPtr=val-rangesPtr[2*j]; found=true; }
10249       if(found)
10250         continue;
10251       else
10252         {
10253           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
10254           throw INTERP_KERNEL::Exception(oss.str().c_str());
10255         }
10256     }
10257   return ret.retn();
10258 }
10259
10260 /*!
10261  * 
10262  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
10263  *             \a nbTimes  should be at least equal to 1.
10264  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
10265  * \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.
10266  */
10267 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
10268 {
10269   checkAllocated();
10270   if(getNumberOfComponents()!=1)
10271     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
10272   if(nbTimes<1)
10273     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
10274   int nbTuples=getNumberOfTuples();
10275   const int *inPtr=getConstPointer();
10276   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
10277   int *retPtr=ret->getPointer();
10278   for(int i=0;i<nbTuples;i++,inPtr++)
10279     {
10280       int val=*inPtr;
10281       for(int j=0;j<nbTimes;j++,retPtr++)
10282         *retPtr=val;
10283     }
10284   ret->copyStringInfoFrom(*this);
10285   return ret.retn();
10286 }
10287
10288 /*!
10289  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
10290  * But the number of components can be different from one.
10291  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
10292  */
10293 DataArrayInt *DataArrayInt::getDifferentValues() const
10294 {
10295   checkAllocated();
10296   std::set<int> ret;
10297   ret.insert(begin(),end());
10298   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
10299   std::copy(ret.begin(),ret.end(),ret2->getPointer());
10300   return ret2.retn();
10301 }
10302
10303 /*!
10304  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
10305  * them it tells which tuple id have this id.
10306  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
10307  * This method returns two arrays having same size.
10308  * 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.
10309  * 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]]
10310  */
10311 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
10312 {
10313   checkAllocated();
10314   if(getNumberOfComponents()!=1)
10315     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
10316   int id=0;
10317   std::map<int,int> m,m2,m3;
10318   for(const int *w=begin();w!=end();w++)
10319     m[*w]++;
10320   differentIds.resize(m.size());
10321   std::vector<DataArrayInt *> ret(m.size());
10322   std::vector<int *> retPtr(m.size());
10323   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
10324     {
10325       m2[(*it).first]=id;
10326       ret[id]=DataArrayInt::New();
10327       ret[id]->alloc((*it).second,1);
10328       retPtr[id]=ret[id]->getPointer();
10329       differentIds[id]=(*it).first;
10330     }
10331   id=0;
10332   for(const int *w=begin();w!=end();w++,id++)
10333     {
10334       retPtr[m2[*w]][m3[*w]++]=id;
10335     }
10336   return ret;
10337 }
10338
10339 /*!
10340  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
10341  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
10342  *
10343  * \param [in] nbOfSlices - number of slices expected.
10344  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
10345  * 
10346  * \sa DataArray::GetSlice
10347  * \throw If \a this is not allocated or not with exactly one component.
10348  * \throw If an element in \a this if < 0.
10349  */
10350 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
10351 {
10352   if(!isAllocated() || getNumberOfComponents()!=1)
10353     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
10354   if(nbOfSlices<=0)
10355     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
10356   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
10357   int sumPerSlc(sum/nbOfSlices),pos(0);
10358   const int *w(begin());
10359   std::vector< std::pair<int,int> > ret(nbOfSlices);
10360   for(int i=0;i<nbOfSlices;i++)
10361     {
10362       std::pair<int,int> p(pos,-1);
10363       int locSum(0);
10364       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
10365       if(i!=nbOfSlices-1)
10366         p.second=pos;
10367       else
10368         p.second=nbOfTuples;
10369       ret[i]=p;
10370     }
10371   return ret;
10372 }
10373
10374 /*!
10375  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
10376  * valid cases.
10377  * 1.  The arrays have same number of tuples and components. Then each value of
10378  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
10379  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
10380  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10381  *   component. Then
10382  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
10383  * 3.  The arrays have same number of components and one array, say _a2_, has one
10384  *   tuple. Then
10385  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
10386  *
10387  * Info on components is copied either from the first array (in the first case) or from
10388  * the array with maximal number of elements (getNbOfElems()).
10389  *  \param [in] a1 - an array to sum up.
10390  *  \param [in] a2 - another array to sum up.
10391  *  \return DataArrayInt * - the new instance of DataArrayInt.
10392  *          The caller is to delete this result array using decrRef() as it is no more
10393  *          needed.
10394  *  \throw If either \a a1 or \a a2 is NULL.
10395  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10396  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10397  *         none of them has number of tuples or components equal to 1.
10398  */
10399 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
10400 {
10401   if(!a1 || !a2)
10402     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
10403   int nbOfTuple=a1->getNumberOfTuples();
10404   int nbOfTuple2=a2->getNumberOfTuples();
10405   int nbOfComp=a1->getNumberOfComponents();
10406   int nbOfComp2=a2->getNumberOfComponents();
10407   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10408   if(nbOfTuple==nbOfTuple2)
10409     {
10410       if(nbOfComp==nbOfComp2)
10411         {
10412           ret=DataArrayInt::New();
10413           ret->alloc(nbOfTuple,nbOfComp);
10414           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
10415           ret->copyStringInfoFrom(*a1);
10416         }
10417       else
10418         {
10419           int nbOfCompMin,nbOfCompMax;
10420           const DataArrayInt *aMin, *aMax;
10421           if(nbOfComp>nbOfComp2)
10422             {
10423               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10424               aMin=a2; aMax=a1;
10425             }
10426           else
10427             {
10428               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10429               aMin=a1; aMax=a2;
10430             }
10431           if(nbOfCompMin==1)
10432             {
10433               ret=DataArrayInt::New();
10434               ret->alloc(nbOfTuple,nbOfCompMax);
10435               const int *aMinPtr=aMin->getConstPointer();
10436               const int *aMaxPtr=aMax->getConstPointer();
10437               int *res=ret->getPointer();
10438               for(int i=0;i<nbOfTuple;i++)
10439                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
10440               ret->copyStringInfoFrom(*aMax);
10441             }
10442           else
10443             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10444         }
10445     }
10446   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10447     {
10448       if(nbOfComp==nbOfComp2)
10449         {
10450           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10451           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10452           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10453           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10454           ret=DataArrayInt::New();
10455           ret->alloc(nbOfTupleMax,nbOfComp);
10456           int *res=ret->getPointer();
10457           for(int i=0;i<nbOfTupleMax;i++)
10458             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
10459           ret->copyStringInfoFrom(*aMax);
10460         }
10461       else
10462         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
10463     }
10464   else
10465     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
10466   return ret.retn();
10467 }
10468
10469 /*!
10470  * Adds values of another DataArrayInt to values of \a this one. There are 3
10471  * valid cases.
10472  * 1.  The arrays have same number of tuples and components. Then each value of
10473  *   \a other array is added to the corresponding value of \a this array, i.e.:
10474  *   _a_ [ i, j ] += _other_ [ i, j ].
10475  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10476  *   _a_ [ i, j ] += _other_ [ i, 0 ].
10477  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10478  *   _a_ [ i, j ] += _a2_ [ 0, j ].
10479  *
10480  *  \param [in] other - an array to add to \a this one.
10481  *  \throw If \a other is NULL.
10482  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10483  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10484  *         \a other has number of both tuples and components not equal to 1.
10485  */
10486 void DataArrayInt::addEqual(const DataArrayInt *other)
10487 {
10488   if(!other)
10489     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
10490   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
10491   checkAllocated(); other->checkAllocated();
10492   int nbOfTuple=getNumberOfTuples();
10493   int nbOfTuple2=other->getNumberOfTuples();
10494   int nbOfComp=getNumberOfComponents();
10495   int nbOfComp2=other->getNumberOfComponents();
10496   if(nbOfTuple==nbOfTuple2)
10497     {
10498       if(nbOfComp==nbOfComp2)
10499         {
10500           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
10501         }
10502       else if(nbOfComp2==1)
10503         {
10504           int *ptr=getPointer();
10505           const int *ptrc=other->getConstPointer();
10506           for(int i=0;i<nbOfTuple;i++)
10507             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
10508         }
10509       else
10510         throw INTERP_KERNEL::Exception(msg);
10511     }
10512   else if(nbOfTuple2==1)
10513     {
10514       if(nbOfComp2==nbOfComp)
10515         {
10516           int *ptr=getPointer();
10517           const int *ptrc=other->getConstPointer();
10518           for(int i=0;i<nbOfTuple;i++)
10519             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
10520         }
10521       else
10522         throw INTERP_KERNEL::Exception(msg);
10523     }
10524   else
10525     throw INTERP_KERNEL::Exception(msg);
10526   declareAsNew();
10527 }
10528
10529 /*!
10530  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
10531  * valid cases.
10532  * 1.  The arrays have same number of tuples and components. Then each value of
10533  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
10534  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
10535  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10536  *   component. Then
10537  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
10538  * 3.  The arrays have same number of components and one array, say _a2_, has one
10539  *   tuple. Then
10540  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
10541  *
10542  * Info on components is copied either from the first array (in the first case) or from
10543  * the array with maximal number of elements (getNbOfElems()).
10544  *  \param [in] a1 - an array to subtract from.
10545  *  \param [in] a2 - an array to subtract.
10546  *  \return DataArrayInt * - the new instance of DataArrayInt.
10547  *          The caller is to delete this result array using decrRef() as it is no more
10548  *          needed.
10549  *  \throw If either \a a1 or \a a2 is NULL.
10550  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10551  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10552  *         none of them has number of tuples or components equal to 1.
10553  */
10554 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
10555 {
10556   if(!a1 || !a2)
10557     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
10558   int nbOfTuple1=a1->getNumberOfTuples();
10559   int nbOfTuple2=a2->getNumberOfTuples();
10560   int nbOfComp1=a1->getNumberOfComponents();
10561   int nbOfComp2=a2->getNumberOfComponents();
10562   if(nbOfTuple2==nbOfTuple1)
10563     {
10564       if(nbOfComp1==nbOfComp2)
10565         {
10566           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10567           ret->alloc(nbOfTuple2,nbOfComp1);
10568           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
10569           ret->copyStringInfoFrom(*a1);
10570           return ret.retn();
10571         }
10572       else if(nbOfComp2==1)
10573         {
10574           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10575           ret->alloc(nbOfTuple1,nbOfComp1);
10576           const int *a2Ptr=a2->getConstPointer();
10577           const int *a1Ptr=a1->getConstPointer();
10578           int *res=ret->getPointer();
10579           for(int i=0;i<nbOfTuple1;i++)
10580             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
10581           ret->copyStringInfoFrom(*a1);
10582           return ret.retn();
10583         }
10584       else
10585         {
10586           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10587           return 0;
10588         }
10589     }
10590   else if(nbOfTuple2==1)
10591     {
10592       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
10593       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10594       ret->alloc(nbOfTuple1,nbOfComp1);
10595       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10596       int *pt=ret->getPointer();
10597       for(int i=0;i<nbOfTuple1;i++)
10598         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
10599       ret->copyStringInfoFrom(*a1);
10600       return ret.retn();
10601     }
10602   else
10603     {
10604       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
10605       return 0;
10606     }
10607 }
10608
10609 /*!
10610  * Subtract values of another DataArrayInt from values of \a this one. There are 3
10611  * valid cases.
10612  * 1.  The arrays have same number of tuples and components. Then each value of
10613  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
10614  *   _a_ [ i, j ] -= _other_ [ i, j ].
10615  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10616  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
10617  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10618  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
10619  *
10620  *  \param [in] other - an array to subtract from \a this one.
10621  *  \throw If \a other is NULL.
10622  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10623  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10624  *         \a other has number of both tuples and components not equal to 1.
10625  */
10626 void DataArrayInt::substractEqual(const DataArrayInt *other)
10627 {
10628   if(!other)
10629     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
10630   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
10631   checkAllocated(); other->checkAllocated();
10632   int nbOfTuple=getNumberOfTuples();
10633   int nbOfTuple2=other->getNumberOfTuples();
10634   int nbOfComp=getNumberOfComponents();
10635   int nbOfComp2=other->getNumberOfComponents();
10636   if(nbOfTuple==nbOfTuple2)
10637     {
10638       if(nbOfComp==nbOfComp2)
10639         {
10640           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
10641         }
10642       else if(nbOfComp2==1)
10643         {
10644           int *ptr=getPointer();
10645           const int *ptrc=other->getConstPointer();
10646           for(int i=0;i<nbOfTuple;i++)
10647             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
10648         }
10649       else
10650         throw INTERP_KERNEL::Exception(msg);
10651     }
10652   else if(nbOfTuple2==1)
10653     {
10654       int *ptr=getPointer();
10655       const int *ptrc=other->getConstPointer();
10656       for(int i=0;i<nbOfTuple;i++)
10657         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
10658     }
10659   else
10660     throw INTERP_KERNEL::Exception(msg);
10661   declareAsNew();
10662 }
10663
10664 /*!
10665  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
10666  * valid cases.
10667  * 1.  The arrays have same number of tuples and components. Then each value of
10668  *   the result array (_a_) is a product of the corresponding values of \a a1 and
10669  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
10670  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10671  *   component. Then
10672  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
10673  * 3.  The arrays have same number of components and one array, say _a2_, has one
10674  *   tuple. Then
10675  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
10676  *
10677  * Info on components is copied either from the first array (in the first case) or from
10678  * the array with maximal number of elements (getNbOfElems()).
10679  *  \param [in] a1 - a factor array.
10680  *  \param [in] a2 - another factor array.
10681  *  \return DataArrayInt * - the new instance of DataArrayInt.
10682  *          The caller is to delete this result array using decrRef() as it is no more
10683  *          needed.
10684  *  \throw If either \a a1 or \a a2 is NULL.
10685  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10686  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10687  *         none of them has number of tuples or components equal to 1.
10688  */
10689 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
10690 {
10691   if(!a1 || !a2)
10692     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
10693   int nbOfTuple=a1->getNumberOfTuples();
10694   int nbOfTuple2=a2->getNumberOfTuples();
10695   int nbOfComp=a1->getNumberOfComponents();
10696   int nbOfComp2=a2->getNumberOfComponents();
10697   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0;
10698   if(nbOfTuple==nbOfTuple2)
10699     {
10700       if(nbOfComp==nbOfComp2)
10701         {
10702           ret=DataArrayInt::New();
10703           ret->alloc(nbOfTuple,nbOfComp);
10704           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
10705           ret->copyStringInfoFrom(*a1);
10706         }
10707       else
10708         {
10709           int nbOfCompMin,nbOfCompMax;
10710           const DataArrayInt *aMin, *aMax;
10711           if(nbOfComp>nbOfComp2)
10712             {
10713               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
10714               aMin=a2; aMax=a1;
10715             }
10716           else
10717             {
10718               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
10719               aMin=a1; aMax=a2;
10720             }
10721           if(nbOfCompMin==1)
10722             {
10723               ret=DataArrayInt::New();
10724               ret->alloc(nbOfTuple,nbOfCompMax);
10725               const int *aMinPtr=aMin->getConstPointer();
10726               const int *aMaxPtr=aMax->getConstPointer();
10727               int *res=ret->getPointer();
10728               for(int i=0;i<nbOfTuple;i++)
10729                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
10730               ret->copyStringInfoFrom(*aMax);
10731             }
10732           else
10733             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10734         }
10735     }
10736   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
10737     {
10738       if(nbOfComp==nbOfComp2)
10739         {
10740           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
10741           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
10742           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
10743           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
10744           ret=DataArrayInt::New();
10745           ret->alloc(nbOfTupleMax,nbOfComp);
10746           int *res=ret->getPointer();
10747           for(int i=0;i<nbOfTupleMax;i++)
10748             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
10749           ret->copyStringInfoFrom(*aMax);
10750         }
10751       else
10752         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
10753     }
10754   else
10755     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
10756   return ret.retn();
10757 }
10758
10759
10760 /*!
10761  * Multiply values of another DataArrayInt to values of \a this one. There are 3
10762  * valid cases.
10763  * 1.  The arrays have same number of tuples and components. Then each value of
10764  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
10765  *   _a_ [ i, j ] *= _other_ [ i, j ].
10766  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10767  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
10768  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10769  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
10770  *
10771  *  \param [in] other - an array to multiply to \a this one.
10772  *  \throw If \a other is NULL.
10773  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10774  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10775  *         \a other has number of both tuples and components not equal to 1.
10776  */
10777 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
10778 {
10779   if(!other)
10780     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
10781   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
10782   checkAllocated(); other->checkAllocated();
10783   int nbOfTuple=getNumberOfTuples();
10784   int nbOfTuple2=other->getNumberOfTuples();
10785   int nbOfComp=getNumberOfComponents();
10786   int nbOfComp2=other->getNumberOfComponents();
10787   if(nbOfTuple==nbOfTuple2)
10788     {
10789       if(nbOfComp==nbOfComp2)
10790         {
10791           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
10792         }
10793       else if(nbOfComp2==1)
10794         {
10795           int *ptr=getPointer();
10796           const int *ptrc=other->getConstPointer();
10797           for(int i=0;i<nbOfTuple;i++)
10798             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
10799         }
10800       else
10801         throw INTERP_KERNEL::Exception(msg);
10802     }
10803   else if(nbOfTuple2==1)
10804     {
10805       if(nbOfComp2==nbOfComp)
10806         {
10807           int *ptr=getPointer();
10808           const int *ptrc=other->getConstPointer();
10809           for(int i=0;i<nbOfTuple;i++)
10810             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
10811         }
10812       else
10813         throw INTERP_KERNEL::Exception(msg);
10814     }
10815   else
10816     throw INTERP_KERNEL::Exception(msg);
10817   declareAsNew();
10818 }
10819
10820
10821 /*!
10822  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
10823  * valid cases.
10824  * 1.  The arrays have same number of tuples and components. Then each value of
10825  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10826  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
10827  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10828  *   component. Then
10829  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
10830  * 3.  The arrays have same number of components and one array, say _a2_, has one
10831  *   tuple. Then
10832  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
10833  *
10834  * Info on components is copied either from the first array (in the first case) or from
10835  * the array with maximal number of elements (getNbOfElems()).
10836  *  \warning No check of division by zero is performed!
10837  *  \param [in] a1 - a numerator array.
10838  *  \param [in] a2 - a denominator array.
10839  *  \return DataArrayInt * - the new instance of DataArrayInt.
10840  *          The caller is to delete this result array using decrRef() as it is no more
10841  *          needed.
10842  *  \throw If either \a a1 or \a a2 is NULL.
10843  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10844  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10845  *         none of them has number of tuples or components equal to 1.
10846  */
10847 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
10848 {
10849   if(!a1 || !a2)
10850     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
10851   int nbOfTuple1=a1->getNumberOfTuples();
10852   int nbOfTuple2=a2->getNumberOfTuples();
10853   int nbOfComp1=a1->getNumberOfComponents();
10854   int nbOfComp2=a2->getNumberOfComponents();
10855   if(nbOfTuple2==nbOfTuple1)
10856     {
10857       if(nbOfComp1==nbOfComp2)
10858         {
10859           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10860           ret->alloc(nbOfTuple2,nbOfComp1);
10861           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
10862           ret->copyStringInfoFrom(*a1);
10863           return ret.retn();
10864         }
10865       else if(nbOfComp2==1)
10866         {
10867           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10868           ret->alloc(nbOfTuple1,nbOfComp1);
10869           const int *a2Ptr=a2->getConstPointer();
10870           const int *a1Ptr=a1->getConstPointer();
10871           int *res=ret->getPointer();
10872           for(int i=0;i<nbOfTuple1;i++)
10873             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
10874           ret->copyStringInfoFrom(*a1);
10875           return ret.retn();
10876         }
10877       else
10878         {
10879           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10880           return 0;
10881         }
10882     }
10883   else if(nbOfTuple2==1)
10884     {
10885       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
10886       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
10887       ret->alloc(nbOfTuple1,nbOfComp1);
10888       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
10889       int *pt=ret->getPointer();
10890       for(int i=0;i<nbOfTuple1;i++)
10891         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
10892       ret->copyStringInfoFrom(*a1);
10893       return ret.retn();
10894     }
10895   else
10896     {
10897       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
10898       return 0;
10899     }
10900 }
10901
10902 /*!
10903  * Divide values of \a this array by values of another DataArrayInt. There are 3
10904  * valid cases.
10905  * 1.  The arrays have same number of tuples and components. Then each value of
10906  *    \a this array is divided by the corresponding value of \a other one, i.e.:
10907  *   _a_ [ i, j ] /= _other_ [ i, j ].
10908  * 2.  The arrays have same number of tuples and \a other array has one component. Then
10909  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
10910  * 3.  The arrays have same number of components and \a other array has one tuple. Then
10911  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
10912  *
10913  *  \warning No check of division by zero is performed!
10914  *  \param [in] other - an array to divide \a this one by.
10915  *  \throw If \a other is NULL.
10916  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
10917  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
10918  *         \a other has number of both tuples and components not equal to 1.
10919  */
10920 void DataArrayInt::divideEqual(const DataArrayInt *other)
10921 {
10922   if(!other)
10923     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
10924   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
10925   checkAllocated(); other->checkAllocated();
10926   int nbOfTuple=getNumberOfTuples();
10927   int nbOfTuple2=other->getNumberOfTuples();
10928   int nbOfComp=getNumberOfComponents();
10929   int nbOfComp2=other->getNumberOfComponents();
10930   if(nbOfTuple==nbOfTuple2)
10931     {
10932       if(nbOfComp==nbOfComp2)
10933         {
10934           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
10935         }
10936       else if(nbOfComp2==1)
10937         {
10938           int *ptr=getPointer();
10939           const int *ptrc=other->getConstPointer();
10940           for(int i=0;i<nbOfTuple;i++)
10941             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
10942         }
10943       else
10944         throw INTERP_KERNEL::Exception(msg);
10945     }
10946   else if(nbOfTuple2==1)
10947     {
10948       if(nbOfComp2==nbOfComp)
10949         {
10950           int *ptr=getPointer();
10951           const int *ptrc=other->getConstPointer();
10952           for(int i=0;i<nbOfTuple;i++)
10953             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
10954         }
10955       else
10956         throw INTERP_KERNEL::Exception(msg);
10957     }
10958   else
10959     throw INTERP_KERNEL::Exception(msg);
10960   declareAsNew();
10961 }
10962
10963
10964 /*!
10965  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
10966  * valid cases.
10967  * 1.  The arrays have same number of tuples and components. Then each value of
10968  *   the result array (_a_) is a division of the corresponding values of \a a1 and
10969  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
10970  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
10971  *   component. Then
10972  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
10973  * 3.  The arrays have same number of components and one array, say _a2_, has one
10974  *   tuple. Then
10975  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
10976  *
10977  * Info on components is copied either from the first array (in the first case) or from
10978  * the array with maximal number of elements (getNbOfElems()).
10979  *  \warning No check of division by zero is performed!
10980  *  \param [in] a1 - a dividend array.
10981  *  \param [in] a2 - a divisor array.
10982  *  \return DataArrayInt * - the new instance of DataArrayInt.
10983  *          The caller is to delete this result array using decrRef() as it is no more
10984  *          needed.
10985  *  \throw If either \a a1 or \a a2 is NULL.
10986  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
10987  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
10988  *         none of them has number of tuples or components equal to 1.
10989  */
10990 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
10991 {
10992   if(!a1 || !a2)
10993     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
10994   int nbOfTuple1=a1->getNumberOfTuples();
10995   int nbOfTuple2=a2->getNumberOfTuples();
10996   int nbOfComp1=a1->getNumberOfComponents();
10997   int nbOfComp2=a2->getNumberOfComponents();
10998   if(nbOfTuple2==nbOfTuple1)
10999     {
11000       if(nbOfComp1==nbOfComp2)
11001         {
11002           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11003           ret->alloc(nbOfTuple2,nbOfComp1);
11004           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
11005           ret->copyStringInfoFrom(*a1);
11006           return ret.retn();
11007         }
11008       else if(nbOfComp2==1)
11009         {
11010           MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11011           ret->alloc(nbOfTuple1,nbOfComp1);
11012           const int *a2Ptr=a2->getConstPointer();
11013           const int *a1Ptr=a1->getConstPointer();
11014           int *res=ret->getPointer();
11015           for(int i=0;i<nbOfTuple1;i++)
11016             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
11017           ret->copyStringInfoFrom(*a1);
11018           return ret.retn();
11019         }
11020       else
11021         {
11022           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11023           return 0;
11024         }
11025     }
11026   else if(nbOfTuple2==1)
11027     {
11028       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
11029       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11030       ret->alloc(nbOfTuple1,nbOfComp1);
11031       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
11032       int *pt=ret->getPointer();
11033       for(int i=0;i<nbOfTuple1;i++)
11034         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
11035       ret->copyStringInfoFrom(*a1);
11036       return ret.retn();
11037     }
11038   else
11039     {
11040       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
11041       return 0;
11042     }
11043 }
11044
11045 /*!
11046  * Modify \a this array so that each value becomes a modulus of division of this value by
11047  * a value of another DataArrayInt. There are 3 valid cases.
11048  * 1.  The arrays have same number of tuples and components. Then each value of
11049  *    \a this array is divided by the corresponding value of \a other one, i.e.:
11050  *   _a_ [ i, j ] %= _other_ [ i, j ].
11051  * 2.  The arrays have same number of tuples and \a other array has one component. Then
11052  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
11053  * 3.  The arrays have same number of components and \a other array has one tuple. Then
11054  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
11055  *
11056  *  \warning No check of division by zero is performed!
11057  *  \param [in] other - a divisor array.
11058  *  \throw If \a other is NULL.
11059  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
11060  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
11061  *         \a other has number of both tuples and components not equal to 1.
11062  */
11063 void DataArrayInt::modulusEqual(const DataArrayInt *other)
11064 {
11065   if(!other)
11066     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
11067   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
11068   checkAllocated(); other->checkAllocated();
11069   int nbOfTuple=getNumberOfTuples();
11070   int nbOfTuple2=other->getNumberOfTuples();
11071   int nbOfComp=getNumberOfComponents();
11072   int nbOfComp2=other->getNumberOfComponents();
11073   if(nbOfTuple==nbOfTuple2)
11074     {
11075       if(nbOfComp==nbOfComp2)
11076         {
11077           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
11078         }
11079       else if(nbOfComp2==1)
11080         {
11081           if(nbOfComp2==nbOfComp)
11082             {
11083               int *ptr=getPointer();
11084               const int *ptrc=other->getConstPointer();
11085               for(int i=0;i<nbOfTuple;i++)
11086                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
11087             }
11088           else
11089             throw INTERP_KERNEL::Exception(msg);
11090         }
11091       else
11092         throw INTERP_KERNEL::Exception(msg);
11093     }
11094   else if(nbOfTuple2==1)
11095     {
11096       int *ptr=getPointer();
11097       const int *ptrc=other->getConstPointer();
11098       for(int i=0;i<nbOfTuple;i++)
11099         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
11100     }
11101   else
11102     throw INTERP_KERNEL::Exception(msg);
11103   declareAsNew();
11104 }
11105
11106 /*!
11107  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
11108  * valid cases.
11109  *
11110  *  \param [in] a1 - an array to pow up.
11111  *  \param [in] a2 - another array to sum up.
11112  *  \return DataArrayInt * - the new instance of DataArrayInt.
11113  *          The caller is to delete this result array using decrRef() as it is no more
11114  *          needed.
11115  *  \throw If either \a a1 or \a a2 is NULL.
11116  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
11117  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
11118  *  \throw If there is a negative value in \a a2.
11119  */
11120 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
11121 {
11122   if(!a1 || !a2)
11123     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
11124   int nbOfTuple=a1->getNumberOfTuples();
11125   int nbOfTuple2=a2->getNumberOfTuples();
11126   int nbOfComp=a1->getNumberOfComponents();
11127   int nbOfComp2=a2->getNumberOfComponents();
11128   if(nbOfTuple!=nbOfTuple2)
11129     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
11130   if(nbOfComp!=1 || nbOfComp2!=1)
11131     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
11132   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
11133   const int *ptr1(a1->begin()),*ptr2(a2->begin());
11134   int *ptr=ret->getPointer();
11135   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
11136     {
11137       if(*ptr2>=0)
11138         {
11139           int tmp=1;
11140           for(int j=0;j<*ptr2;j++)
11141             tmp*=*ptr1;
11142           *ptr=tmp;
11143         }
11144       else
11145         {
11146           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
11147           throw INTERP_KERNEL::Exception(oss.str().c_str());
11148         }
11149     }
11150   return ret.retn();
11151 }
11152
11153 /*!
11154  * Apply pow on values of another DataArrayInt to values of \a this one.
11155  *
11156  *  \param [in] other - an array to pow to \a this one.
11157  *  \throw If \a other is NULL.
11158  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
11159  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
11160  *  \throw If there is a negative value in \a other.
11161  */
11162 void DataArrayInt::powEqual(const DataArrayInt *other)
11163 {
11164   if(!other)
11165     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
11166   int nbOfTuple=getNumberOfTuples();
11167   int nbOfTuple2=other->getNumberOfTuples();
11168   int nbOfComp=getNumberOfComponents();
11169   int nbOfComp2=other->getNumberOfComponents();
11170   if(nbOfTuple!=nbOfTuple2)
11171     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
11172   if(nbOfComp!=1 || nbOfComp2!=1)
11173     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
11174   int *ptr=getPointer();
11175   const int *ptrc=other->begin();
11176   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
11177     {
11178       if(*ptrc>=0)
11179         {
11180           int tmp=1;
11181           for(int j=0;j<*ptrc;j++)
11182             tmp*=*ptr;
11183           *ptr=tmp;
11184         }
11185       else
11186         {
11187           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
11188           throw INTERP_KERNEL::Exception(oss.str().c_str());
11189         }
11190     }
11191   declareAsNew();
11192 }
11193
11194 /*!
11195  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
11196  * This map, if applied to \a start array, would make it sorted. For example, if
11197  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
11198  * [5,6,0,3,2,7,1,4].
11199  *  \param [in] start - pointer to the first element of the array for which the
11200  *         permutation map is computed.
11201  *  \param [in] end - pointer specifying the end of the array \a start, so that
11202  *         the last value of \a start is \a end[ -1 ].
11203  *  \return int * - the result permutation array that the caller is to delete as it is no
11204  *         more needed.
11205  *  \throw If there are equal values in the input array.
11206  */
11207 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
11208 {
11209   std::size_t sz=std::distance(start,end);
11210   int *ret=(int *)malloc(sz*sizeof(int));
11211   int *work=new int[sz];
11212   std::copy(start,end,work);
11213   std::sort(work,work+sz);
11214   if(std::unique(work,work+sz)!=work+sz)
11215     {
11216       delete [] work;
11217       free(ret);
11218       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
11219     }
11220   std::map<int,int> m;
11221   for(int *workPt=work;workPt!=work+sz;workPt++)
11222     m[*workPt]=(int)std::distance(work,workPt);
11223   int *iter2=ret;
11224   for(const int *iter=start;iter!=end;iter++,iter2++)
11225     *iter2=m[*iter];
11226   delete [] work;
11227   return ret;
11228 }
11229
11230 /*!
11231  * Returns a new DataArrayInt containing an arithmetic progression
11232  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
11233  * function.
11234  *  \param [in] begin - the start value of the result sequence.
11235  *  \param [in] end - limiting value, so that every value of the result array is less than
11236  *              \a end.
11237  *  \param [in] step - specifies the increment or decrement.
11238  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
11239  *          array using decrRef() as it is no more needed.
11240  *  \throw If \a step == 0.
11241  *  \throw If \a end < \a begin && \a step > 0.
11242  *  \throw If \a end > \a begin && \a step < 0.
11243  */
11244 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
11245 {
11246   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
11247   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
11248   ret->alloc(nbOfTuples,1);
11249   int *ptr=ret->getPointer();
11250   if(step>0)
11251     {
11252       for(int i=begin;i<end;i+=step,ptr++)
11253         *ptr=i;
11254     }
11255   else
11256     {
11257       for(int i=begin;i>end;i+=step,ptr++)
11258         *ptr=i;
11259     }
11260   return ret.retn();
11261 }
11262
11263 /*!
11264  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11265  * Server side.
11266  */
11267 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
11268 {
11269   tinyInfo.resize(2);
11270   if(isAllocated())
11271     {
11272       tinyInfo[0]=getNumberOfTuples();
11273       tinyInfo[1]=getNumberOfComponents();
11274     }
11275   else
11276     {
11277       tinyInfo[0]=-1;
11278       tinyInfo[1]=-1;
11279     }
11280 }
11281
11282 /*!
11283  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11284  * Server side.
11285  */
11286 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
11287 {
11288   if(isAllocated())
11289     {
11290       int nbOfCompo=getNumberOfComponents();
11291       tinyInfo.resize(nbOfCompo+1);
11292       tinyInfo[0]=getName();
11293       for(int i=0;i<nbOfCompo;i++)
11294         tinyInfo[i+1]=getInfoOnComponent(i);
11295     }
11296   else
11297     {
11298       tinyInfo.resize(1);
11299       tinyInfo[0]=getName();
11300     }
11301 }
11302
11303 /*!
11304  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11305  * This method returns if a feeding is needed.
11306  */
11307 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
11308 {
11309   int nbOfTuple=tinyInfoI[0];
11310   int nbOfComp=tinyInfoI[1];
11311   if(nbOfTuple!=-1 || nbOfComp!=-1)
11312     {
11313       alloc(nbOfTuple,nbOfComp);
11314       return true;
11315     }
11316   return false;
11317 }
11318
11319 /*!
11320  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
11321  * This method returns if a feeding is needed.
11322  */
11323 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
11324 {
11325   setName(tinyInfoS[0]);
11326   if(isAllocated())
11327     {
11328       int nbOfCompo=tinyInfoI[1];
11329       for(int i=0;i<nbOfCompo;i++)
11330         setInfoOnComponent(i,tinyInfoS[i+1]);
11331     }
11332 }
11333
11334 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
11335 {
11336   if(_da)
11337     {
11338       _da->incrRef();
11339       if(_da->isAllocated())
11340         {
11341           _nb_comp=da->getNumberOfComponents();
11342           _nb_tuple=da->getNumberOfTuples();
11343           _pt=da->getPointer();
11344         }
11345     }
11346 }
11347
11348 DataArrayIntIterator::~DataArrayIntIterator()
11349 {
11350   if(_da)
11351     _da->decrRef();
11352 }
11353
11354 DataArrayIntTuple *DataArrayIntIterator::nextt()
11355 {
11356   if(_tuple_id<_nb_tuple)
11357     {
11358       _tuple_id++;
11359       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
11360       _pt+=_nb_comp;
11361       return ret;
11362     }
11363   else
11364     return 0;
11365 }
11366
11367 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
11368 {
11369 }
11370
11371 std::string DataArrayIntTuple::repr() const
11372 {
11373   std::ostringstream oss; oss << "(";
11374   for(int i=0;i<_nb_of_compo-1;i++)
11375     oss << _pt[i] << ", ";
11376   oss << _pt[_nb_of_compo-1] << ")";
11377   return oss.str();
11378 }
11379
11380 int DataArrayIntTuple::intValue() const
11381 {
11382   if(_nb_of_compo==1)
11383     return *_pt;
11384   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
11385 }
11386
11387 /*!
11388  * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef.
11389  * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::useArray with ownership set to \b false.
11390  * 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
11391  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
11392  */
11393 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
11394 {
11395   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
11396     {
11397       DataArrayInt *ret=DataArrayInt::New();
11398       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
11399       return ret;
11400     }
11401   else
11402     {
11403       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
11404       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
11405       throw INTERP_KERNEL::Exception(oss.str().c_str());
11406     }
11407 }